<template> 
 | 
  <div class="app-container"> 
 | 
    <div class="search_form"> 
 | 
      <el-form :model="searchForm" :inline="true"> 
 | 
        <el-form-item label="客户名称:"> 
 | 
          <el-input v-model="searchForm.customerName" placeholder="请输入" clearable prefix-icon="Search" 
 | 
            @change="handleQuery" /> 
 | 
        </el-form-item> 
 | 
        <el-form-item label="客户合同号:"> 
 | 
          <el-input v-model="searchForm.customerContractNo" placeholder="请输入" clearable prefix-icon="Search" 
 | 
            @change="handleQuery" /> 
 | 
        </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="录入日期:"> 
 | 
          <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange" 
 | 
            placeholder="请选择" clearable @change="changeDaterange" /> 
 | 
        </el-form-item> 
 | 
        <el-form-item> 
 | 
          <el-button type="primary" @click="handleQuery"> 搜索 </el-button> 
 | 
        </el-form-item> 
 | 
      </el-form> 
 | 
    </div> 
 | 
    <div class="table_list"> 
 | 
      <div class="actions"> 
 | 
        <div></div> 
 | 
        <div> 
 | 
          <el-button type="primary" @click="openForm('add')"> 
 | 
            新增台账 
 | 
          </el-button> 
 | 
          <el-button @click="handleOut">导出</el-button> 
 | 
          <el-button type="danger" plain @click="handleDelete">删除</el-button> 
 | 
          <el-button type="primary" plain @click="handlePrint">打印</el-button> 
 | 
        </div> 
 | 
      </div> 
 | 
      <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange" 
 | 
        :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary style="width: 100%" 
 | 
        :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 18.5em)"> 
 | 
        <el-table-column align="center" type="selection" width="55" /> 
 | 
        <el-table-column type="expand"> 
 | 
          <template #default="props"> 
 | 
            <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable"> 
 | 
              <el-table-column align="center" label="序号" type="index" width="60" /> 
 | 
              <el-table-column label="产品大类" prop="productCategory" /> 
 | 
              <el-table-column label="规格型号" prop="specificationModel" /> 
 | 
              <el-table-column label="单位" prop="unit" /> 
 | 
              <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> 
 | 
          </template> 
 | 
        </el-table-column> 
 | 
        <el-table-column align="center" label="序号" type="index" width="60" /> 
 | 
        <el-table-column label="销售合同号" prop="salesContractNo" width="180" show-overflow-tooltip /> 
 | 
        <el-table-column label="客户合同号" prop="customerContractNo" width="180" show-overflow-tooltip /> 
 | 
        <el-table-column label="客户名称" prop="customerName" width="300" show-overflow-tooltip /> 
 | 
        <el-table-column label="业务员" prop="salesman" width="100" show-overflow-tooltip /> 
 | 
        <el-table-column label="项目名称" prop="projectName" width="180" show-overflow-tooltip /> 
 | 
        <el-table-column label="付款方式" prop="paymentMethod" show-overflow-tooltip /> 
 | 
        <el-table-column label="合同金额(元)" prop="contractAmount" width="220" show-overflow-tooltip 
 | 
          :formatter="formattedNumber" /> 
 | 
        <el-table-column label="录入人" prop="entryPersonName" width="100" show-overflow-tooltip /> 
 | 
        <el-table-column label="录入日期" prop="entryDate" width="120" show-overflow-tooltip /> 
 | 
        <el-table-column label="签订日期" prop="executionDate" width="120" show-overflow-tooltip /> 
 | 
        <el-table-column fixed="right" label="操作" min-width="200" align="center"> 
 | 
          <template #default="scope"> 
 | 
            <el-button link type="primary" size="small" :disabled="scope.row.invoiceTotal>0 || scope.row.entryPersonName !== userStore.nickName" @click="openForm('edit', scope.row)">编辑</el-button> 
 | 
<!--            <el-button link type="primary" size="small" @click="openForm('view', scope.row)">详情</el-button>--> 
 | 
            <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">附件</el-button> 
 | 
            <el-button link type="primary" size="small" @click="openDeliveryForm(scope.row)">发货</el-button> 
 | 
          </template> 
 | 
        </el-table-column> 
 | 
      </el-table> 
 | 
      <pagination v-show="total > 0" :total="total" layout="total, sizes, prev, pager, next, jumper" 
 | 
        :page="page.current" :limit="page.size" @pagination="paginationChange" /> 
 | 
    </div> 
 | 
    <el-dialog v-model="dialogFormVisible" :title="operationType === 'add' ? '新增销售台账页面' : '编辑销售台账页面'" width="70%" 
 | 
      @close="closeDia"> 
 | 
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef"> 
 | 
        <el-row :gutter="30"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="销售合同号:" prop="salesContractNo"> 
 | 
              <el-input v-model="form.salesContractNo" placeholder="自动生成" clearable 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="operationType === 'view'"> 
 | 
                <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="customerContractNo"> 
 | 
              <el-input v-model="form.customerContractNo" placeholder="请输入" clearable :disabled="operationType === 'view'"/> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="客户名称:" prop="customerId"> 
 | 
              <el-select v-model="form.customerId" placeholder="请选择" clearable :disabled="operationType === 'view'"> 
 | 
                <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-row> 
 | 
        <el-row :gutter="30"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="项目名称:" prop="projectName"> 
 | 
              <el-input v-model="form.projectName" placeholder="请输入" clearable :disabled="operationType === 'view'" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
                    <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="operationType === 'view'" /> 
 | 
                        </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" placeholder="请选择" clearable @change="changs" disabled> 
 | 
                                <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 /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="30"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="付款方式"> 
 | 
              <el-input v-model="form.paymentMethod" placeholder="请输入" clearable :disabled="operationType === 'view'" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row> 
 | 
          <el-form-item label="产品信息:" prop="entryDate"> 
 | 
            <el-button v-if="operationType !== 'view'" type="primary" @click="openProductForm('add')">添加</el-button> 
 | 
            <el-button v-if="operationType !== 'view'" plain type="danger" @click="deleteProduct" >删除</el-button> 
 | 
          </el-form-item> 
 | 
        </el-row> 
 | 
        <el-table :data="productData" border @selection-change="productSelected" show-summary 
 | 
          :summary-method="summarizeMainTable"> 
 | 
          <el-table-column align="center" type="selection" width="55" v-if="operationType !== 'view'" /> 
 | 
          <el-table-column align="center" label="序号" type="index" width="60" /> 
 | 
          <el-table-column label="产品大类" prop="productCategory" /> 
 | 
          <el-table-column label="规格型号" prop="specificationModel" /> 
 | 
          <el-table-column label="单位" prop="unit" /> 
 | 
          <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 fixed="right" label="操作" min-width="60" align="center" v-if="operationType !== 'view'"> 
 | 
            <template #default="scope"> 
 | 
              <el-button link type="primary" size="small" @click="openProductForm('edit', scope.row,scope.$index)">编辑</el-button> 
 | 
            </template> 
 | 
          </el-table-column> 
 | 
        </el-table> 
 | 
        <el-row :gutter="30"> 
 | 
          <el-col :span="24"> 
 | 
            <el-form-item label="备注·:" prop="remark"> 
 | 
              <el-input v-model="form.remark" placeholder="请输入" clearable type="textarea" :rows="2" :disabled="operationType === 'view'" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="30"> 
 | 
          <el-col :span="24"> 
 | 
            <el-form-item label="附件材料:" prop="remark"> 
 | 
              <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" v-if="operationType !== 'view'">上传</el-button> 
 | 
                <template #tip v-if="operationType !== 'view'"> 
 | 
                  <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> 
 | 
      </el-form> 
 | 
      <template #footer> 
 | 
        <div class="dialog-footer"> 
 | 
          <el-button type="primary" @click="submitForm">确认</el-button> 
 | 
          <el-button @click="closeDia">取消</el-button> 
 | 
        </div> 
 | 
      </template> 
 | 
    </el-dialog> 
 | 
    <el-dialog v-model="productFormVisible" :title="productOperationType === 'add' ? '新增产品' : '编辑产品'" width="40%" 
 | 
      @close="closeProductDia"> 
 | 
      <el-form :model="productForm" label-width="140px" label-position="top" :rules="productRules" ref="productFormRef"> 
 | 
        <el-row :gutter="30"> 
 | 
          <el-col :span="24"> 
 | 
            <el-form-item label="产品大类:" prop="productCategory"> 
 | 
              <!-- <el-select v-model="productForm.productCategory" placeholder="请选择" clearable> 
 | 
                <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName" :value="item.nickName"/> 
 | 
              </el-select> --> 
 | 
              <el-tree-select v-model="productForm.productCategory" placeholder="请选择" clearable check-strictly 
 | 
                @change="getModels" :data="productOptions" :render-after-expand="false" style="width: 100%" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="30"> 
 | 
          <el-col :span="24"> 
 | 
            <el-form-item label="规格型号:" prop="productModelId"> 
 | 
              <el-select v-model="productForm.productModelId" placeholder="请选择" clearable @change="getProductModel"> 
 | 
                <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" /> 
 | 
              </el-select> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="30"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="单位:" prop="unit"> 
 | 
              <el-input v-model="productForm.unit" placeholder="请输入" clearable /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
                    <el-col :span="12"> 
 | 
                        <el-form-item label="税率(%):" prop="taxRate"> 
 | 
                            <el-select v-model="productForm.taxRate" placeholder="请选择" clearable @change="calculateFromTaxRate"> 
 | 
                                <el-option label="1" value="1" /> 
 | 
                                <el-option label="6" value="6" /> 
 | 
                                <el-option label="13" value="13" /> 
 | 
                            </el-select> 
 | 
                        </el-form-item> 
 | 
                    </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="30"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="含税单价(元):" prop="taxInclusiveUnitPrice"> 
 | 
              <el-input-number :step="0.01" :min="0" v-model="productForm.taxInclusiveUnitPrice" style="width: 100%" 
 | 
                                                             :precision="2" 
 | 
                                                             placeholder="请输入" clearable @change="calculateFromUnitPrice" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
                    <el-col :span="12"> 
 | 
                        <el-form-item label="数量:" prop="quantity"> 
 | 
                            <el-input-number  :step="0.1" :min="0" v-model="productForm.quantity" placeholder="请输入" clearable 
 | 
                                                                :precision="2" 
 | 
                                                                @change="calculateFromQuantity" style="width: 100%" /> 
 | 
                        </el-form-item> 
 | 
                    </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="30"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="含税总价(元):" prop="taxInclusiveTotalPrice"> 
 | 
              <el-input v-model="productForm.taxInclusiveTotalPrice" placeholder="请输入" clearable @change="calculateFromTotalPrice" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="不含税总价(元):" prop="taxExclusiveTotalPrice"> 
 | 
              <el-input v-model="productForm.taxExclusiveTotalPrice" placeholder="请输入" clearable @change="calculateFromExclusiveTotalPrice" /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="30"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="发票类型:" prop="invoiceType"> 
 | 
              <el-select v-model="productForm.invoiceType" placeholder="请选择" clearable> 
 | 
                <el-option label="增普票" value="增普票" /> 
 | 
                <el-option label="增专票" value="增专票" /> 
 | 
              </el-select> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
      </el-form> 
 | 
      <template #footer> 
 | 
        <div class="dialog-footer"> 
 | 
          <el-button type="primary" @click="submitProduct">确认</el-button> 
 | 
          <el-button @click="closeProductDia">取消</el-button> 
 | 
        </div> 
 | 
      </template> 
 | 
    </el-dialog> 
 | 
        <!-- 打印预览弹窗 --> 
 | 
        <el-dialog 
 | 
            v-model="printPreviewVisible" 
 | 
            title="打印预览" 
 | 
            width="90%" 
 | 
            :close-on-click-modal="false" 
 | 
            class="print-preview-dialog" 
 | 
        > 
 | 
            <div class="print-preview-container"> 
 | 
                <div class="print-preview-header"> 
 | 
                    <el-button type="primary" @click="executePrint">执行打印</el-button> 
 | 
                    <el-button @click="printPreviewVisible = false">关闭预览</el-button> 
 | 
                </div> 
 | 
                <div class="print-preview-content"> 
 | 
                    <div v-if="printData.length === 0" style="text-align: center; padding: 50px; color: #999;"> 
 | 
                        暂无打印数据 
 | 
                    </div> 
 | 
                    <div v-else style="text-align: center; padding: 10px; color: #666; font-size: 14px; background: #e8f4fd; margin-bottom: 10px;"> 
 | 
                        共 {{ printData.length }} 条数据待打印 
 | 
                    </div> 
 | 
                    <div v-for="(item, index) in printData" :key="index" class="print-page"> 
 | 
                        <div class="delivery-note"> 
 | 
                            <div class="header"> 
 | 
                                <div class="company-name">鼎诚瑞实业有限责任公司</div> 
 | 
                                <div class="document-title">零售发货单</div> 
 | 
                            </div> 
 | 
                             
 | 
                            <div class="info-section"> 
 | 
                                <div class="info-row"> 
 | 
                                    <div> 
 | 
                                        <span class="label">发货日期:</span> 
 | 
                                        <span class="value">{{ formatDate(item.createTime) }}</span> 
 | 
                                    </div> 
 | 
                                    <div> 
 | 
                                         
 | 
                                        <span class="label">客户名称:</span> 
 | 
                                        <span class="value">{{ item.customerName || '张爱有' }}</span> 
 | 
                                    </div> 
 | 
                                </div> 
 | 
                                <div class="info-row"> 
 | 
                                    <span class="label">单号:</span> 
 | 
                                    <span class="value">{{ item.salesContractNo }}</span> 
 | 
                                </div> 
 | 
                            </div> 
 | 
                             
 | 
                            <div class="table-section"> 
 | 
                                <table class="product-table"> 
 | 
                                    <thead> 
 | 
                                    <tr> 
 | 
                                        <th>产品名称</th> 
 | 
                                        <th>规格型号</th> 
 | 
                                        <th>单位</th> 
 | 
                                        <th>单价</th> 
 | 
                                        <th>零售数量</th> 
 | 
                                        <th>零售金额</th> 
 | 
                                    </tr> 
 | 
                                    </thead> 
 | 
                                    <tbody> 
 | 
                                    <tr v-for="product in item.products" :key="product.id"> 
 | 
                                        <td>{{ product.productCategory || '' }}</td> 
 | 
                                        <td>{{ product.specificationModel || '' }}</td> 
 | 
                                        <td>{{ product.unit || '' }}</td> 
 | 
                                        <td>{{ product.taxInclusiveUnitPrice || '0' }}</td> 
 | 
                                        <td>{{ product.quantity || '0' }}</td> 
 | 
                                        <td>{{ product.taxInclusiveTotalPrice || '0' }}</td> 
 | 
                                    </tr> 
 | 
                                    <tr v-if="!item.products || item.products.length === 0"> 
 | 
                                        <td colspan="6" style="text-align: center; color: #999;">暂无产品数据</td> 
 | 
                                    </tr> 
 | 
                                    </tbody> 
 | 
                                    <tfoot> 
 | 
                                    <tr> 
 | 
                                        <td class="label">合计</td> 
 | 
                                        <td class="total-value"></td> 
 | 
                                        <td class="total-value"></td> 
 | 
                                        <td class="total-value"></td> 
 | 
                                        <td class="total-value">{{ getTotalQuantity(item.products) }}</td> 
 | 
                                        <td class="total-value">{{ getTotalAmount(item.products) }}</td> 
 | 
                                    </tr> 
 | 
                                    </tfoot> 
 | 
                                </table> 
 | 
                            </div> 
 | 
                             
 | 
                            <div class="footer-section"> 
 | 
                                <div class="footer-row"> 
 | 
                                    <div class="footer-item"> 
 | 
                                        <span class="label">收货电话:</span> 
 | 
                                        <span class="value"></span> 
 | 
                                    </div> 
 | 
                                    <div class="footer-item"> 
 | 
                                        <span class="label">收货人:</span> 
 | 
                                        <span class="value"></span> 
 | 
                                    </div> 
 | 
                                    <div class="footer-item address-item"> 
 | 
                                        <span class="label">收货地址:</span> 
 | 
                                        <span class="value address-value"></span> 
 | 
                                    </div> 
 | 
                                </div> 
 | 
                                <div class="footer-row"> 
 | 
                                    <div class="footer-item"> 
 | 
                                        <span class="label">操作员:</span> 
 | 
                                        <span class="value">{{ userStore.nickName || '撕开前' }}</span> 
 | 
                                    </div> 
 | 
                                    <div class="footer-item"> 
 | 
                                        <span class="label">打印日期:</span> 
 | 
                                        <span class="value">{{ formatDateTime(new Date()) }}</span> 
 | 
                                    </div> 
 | 
                                </div> 
 | 
                            </div> 
 | 
                        </div> 
 | 
                    </div> 
 | 
                </div> 
 | 
            </div> 
 | 
        </el-dialog> 
 | 
        <!-- 发货弹框 --> 
 | 
        <el-dialog 
 | 
            v-model="deliveryFormVisible" 
 | 
            title="发货信息" 
 | 
            width="40%" 
 | 
            @close="closeDeliveryDia" 
 | 
        > 
 | 
            <el-form :model="deliveryForm" label-width="120px" label-position="top" :rules="deliveryRules" ref="deliveryFormRef"> 
 | 
                <el-row :gutter="30"> 
 | 
                    <el-col :span="24"> 
 | 
                        <el-form-item label="发货日期:" prop="shippingDate"> 
 | 
                            <el-date-picker 
 | 
                                style="width: 100%" 
 | 
                                v-model="deliveryForm.shippingDate" 
 | 
                                value-format="YYYY-MM-DD" 
 | 
                                format="YYYY-MM-DD" 
 | 
                                type="date" 
 | 
                                placeholder="请选择发货日期" 
 | 
                                clearable 
 | 
                            /> 
 | 
                        </el-form-item> 
 | 
                    </el-col> 
 | 
                </el-row> 
 | 
                <el-row :gutter="30"> 
 | 
                    <el-col :span="24"> 
 | 
                        <el-form-item label="发货车牌号:" prop="shippingCarNumber"> 
 | 
                            <el-input 
 | 
                                v-model="deliveryForm.shippingCarNumber" 
 | 
                                placeholder="请输入发货车牌号" 
 | 
                                clearable 
 | 
                            /> 
 | 
                        </el-form-item> 
 | 
                    </el-col> 
 | 
                </el-row> 
 | 
            </el-form> 
 | 
            <template #footer> 
 | 
                <div class="dialog-footer"> 
 | 
                    <el-button type="primary" @click="submitDelivery">确认发货</el-button> 
 | 
                    <el-button @click="closeDeliveryDia">取消</el-button> 
 | 
                </div> 
 | 
            </template> 
 | 
        </el-dialog> 
 | 
    <FileList ref="fileListRef" /> 
 | 
  </div> 
 | 
</template> 
 | 
  
 | 
<script setup> 
 | 
import { getToken } from "@/utils/auth"; 
 | 
import pagination from "@/components/PIMTable/Pagination.vue"; 
 | 
import {onMounted, ref} from "vue"; 
 | 
import { addShippingInfo } from "@/api/salesManagement/deliveryLedger.js"; 
 | 
import { ElMessageBox } from "element-plus"; 
 | 
import useUserStore from "@/store/modules/user"; 
 | 
import { userListNoPage } from "@/api/system/user.js"; 
 | 
import FileList from "./fileList.vue"; 
 | 
import { 
 | 
  ledgerListPage, 
 | 
  productList, 
 | 
  customerList, 
 | 
  addOrUpdateSalesLedger, 
 | 
  getSalesLedgerWithProducts, 
 | 
  delLedger, 
 | 
  addOrUpdateSalesLedgerProduct, 
 | 
  delProduct, 
 | 
  delLedgerFile, 
 | 
} from "@/api/salesManagement/salesLedger.js"; 
 | 
import { modelList, productTreeList } from "@/api/basicData/product.js"; 
 | 
import useFormData from "@/hooks/useFormData.js"; 
 | 
import dayjs from "dayjs"; 
 | 
  
 | 
const userStore = useUserStore(); 
 | 
const { proxy } = getCurrentInstance(); 
 | 
const tableData = ref([]); 
 | 
const productData = ref([]); 
 | 
const selectedRows = ref([]); 
 | 
const productSelectedRows = ref([]); 
 | 
const userList = ref([]); 
 | 
const customerOption = ref([]); 
 | 
const productOptions = ref([]); 
 | 
const modelOptions = ref([]); 
 | 
const tableLoading = ref(false); 
 | 
const page = reactive({ 
 | 
  current: 1, 
 | 
  size: 100, 
 | 
}); 
 | 
const total = ref(0); 
 | 
const fileList = ref([]); 
 | 
  
 | 
// 用户信息表单弹框数据 
 | 
const operationType = ref(""); 
 | 
const dialogFormVisible = ref(false); 
 | 
const data = reactive({ 
 | 
  searchForm: { 
 | 
    customerName: "", // 客户名称 
 | 
    customerContractNo: "", // 客户合同编号 
 | 
    salesContractNo: "", // 销售合同编号 
 | 
    projectName: "", // 项目名称 
 | 
    entryDate: null, // 录入日期 
 | 
    entryDateStart: undefined, 
 | 
    entryDateEnd: undefined, 
 | 
  }, 
 | 
  form: { 
 | 
    salesContractNo: "", 
 | 
    salesman: "", 
 | 
    customerContractNo: "", 
 | 
    customerId: "", 
 | 
    projectName: "", 
 | 
    entryPerson: "", 
 | 
    entryDate: "", 
 | 
    maintenanceTime: "", 
 | 
    productData: [], 
 | 
    executionDate: "", 
 | 
    paymentMethod: "", 
 | 
  }, 
 | 
  rules: { 
 | 
    salesman: [{ required: true, message: "请选择", trigger: "change" }], 
 | 
    customerContractNo: [ 
 | 
      { required: true, message: "请输入", trigger: "blur" }, 
 | 
    ], 
 | 
    customerId: [{ required: true, message: "请选择", trigger: "change" }], 
 | 
    projectName: [{ required: true, message: "请输入", trigger: "blur" }], 
 | 
    entryPerson: [{ required: true, message: "请选择", trigger: "change" }], 
 | 
    entryDate: [{ required: true, message: "请选择", trigger: "change" }], 
 | 
    executionDate: [{ required: true, message: "请选择", trigger: "change" }], 
 | 
  }, 
 | 
}); 
 | 
const { form, rules } = toRefs(data); 
 | 
const { form: searchForm } = useFormData(data.searchForm); 
 | 
// 产品表单弹框数据 
 | 
const productFormVisible = ref(false); 
 | 
const productOperationType = ref(""); 
 | 
const currentId = ref(""); 
 | 
const productFormData = reactive({ 
 | 
  productForm: { 
 | 
    productCategory: "", 
 | 
    specificationModel: "", 
 | 
    unit: "", 
 | 
    quantity: "", 
 | 
    taxInclusiveUnitPrice: "", 
 | 
    taxRate: "", 
 | 
    taxInclusiveTotalPrice: "", 
 | 
    taxExclusiveTotalPrice: "", 
 | 
    invoiceType: "", 
 | 
  }, 
 | 
  productRules: { 
 | 
    productCategory: [{ required: true, message: "请选择", trigger: "change" }], 
 | 
        productModelId: [{ required: true, message: "请选择", trigger: "change" }], 
 | 
    specificationModel: [ 
 | 
      { required: true, message: "请选择", trigger: "change" }, 
 | 
    ], 
 | 
    unit: [{ required: true, message: "请输入", trigger: "blur" }], 
 | 
    quantity: [{ required: true, message: "请输入", trigger: "blur" }], 
 | 
    taxInclusiveUnitPrice: [ 
 | 
      { required: true, message: "请输入", trigger: "blur" }, 
 | 
    ], 
 | 
    taxRate: [{ required: true, message: "请选择", trigger: "change" }], 
 | 
    taxInclusiveTotalPrice: [ 
 | 
      { required: true, message: "请输入", trigger: "blur" }, 
 | 
    ], 
 | 
    taxExclusiveTotalPrice: [ 
 | 
      { required: true, message: "请输入", trigger: "blur" }, 
 | 
    ], 
 | 
    invoiceType: [{ required: true, message: "请选择", trigger: "change" }], 
 | 
  }, 
 | 
}); 
 | 
const { productForm, productRules } = toRefs(productFormData); 
 | 
// 防止循环计算的标志 
 | 
const isCalculating = ref(false); 
 | 
const upload = reactive({ 
 | 
  // 上传的地址 
 | 
  url: import.meta.env.VITE_APP_BASE_API + "/file/upload", 
 | 
  // 设置上传的请求头部 
 | 
  headers: { Authorization: "Bearer " + getToken() }, 
 | 
}); 
 | 
// 打印相关 
 | 
const printPreviewVisible = ref(false); 
 | 
const printData = ref([]); 
 | 
  
 | 
// 发货相关 
 | 
const deliveryFormVisible = ref(false); 
 | 
const currentDeliveryRow = ref(null); 
 | 
const deliveryFormData = reactive({ 
 | 
  deliveryForm: { 
 | 
    shippingDate: "", 
 | 
    shippingCarNumber: "", 
 | 
  }, 
 | 
  deliveryRules: { 
 | 
    shippingDate: [ 
 | 
      { required: true, message: "请选择发货日期", trigger: "change" } 
 | 
    ], 
 | 
    shippingCarNumber: [ 
 | 
      { required: true, message: "请输入发货车牌号", trigger: "blur" } 
 | 
    ], 
 | 
  }, 
 | 
}); 
 | 
const { deliveryForm, deliveryRules } = toRefs(deliveryFormData); 
 | 
  
 | 
const changeDaterange = (value) => { 
 | 
  if (value) { 
 | 
    searchForm.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD"); 
 | 
    searchForm.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD"); 
 | 
  } else { 
 | 
    searchForm.entryDateStart = undefined; 
 | 
    searchForm.entryDateEnd = undefined; 
 | 
  } 
 | 
  handleQuery(); 
 | 
}; 
 | 
  
 | 
// 查询列表 
 | 
/** 搜索按钮操作 */ 
 | 
const handleQuery = () => { 
 | 
  page.current = 1; 
 | 
    expandedRowKeys.value = []; 
 | 
  getList(); 
 | 
}; 
 | 
const paginationChange = (obj) => { 
 | 
  page.current = obj.page; 
 | 
  page.size = obj.limit; 
 | 
  getList(); 
 | 
}; 
 | 
const getList = () => { 
 | 
  tableLoading.value = true; 
 | 
  const { entryDate, ...rest } = searchForm; 
 | 
  ledgerListPage({ ...rest, ...page }) 
 | 
    .then((res) => { 
 | 
      tableLoading.value = false; 
 | 
      tableData.value = res.records; 
 | 
      tableData.value.map((item) => { 
 | 
        item.children = []; 
 | 
      }); 
 | 
      total.value = res.total; 
 | 
    }) 
 | 
    .catch(() => { 
 | 
      tableLoading.value = false; 
 | 
    }); 
 | 
}; 
 | 
// 获取产品大类tree数据 
 | 
const getProductOptions = () => { 
 | 
  productTreeList().then((res) => { 
 | 
    productOptions.value = convertIdToValue(res); 
 | 
  }); 
 | 
}; 
 | 
const formattedNumber = (row, column, cellValue) => { 
 | 
  return parseFloat(cellValue).toFixed(2); 
 | 
}; 
 | 
// 获取tree子数据 
 | 
const getModels = (value) => { 
 | 
  productForm.value.productCategory = findNodeById(productOptions.value, value); 
 | 
  modelList({ id: value }).then((res) => { 
 | 
    modelOptions.value = res; 
 | 
  }); 
 | 
}; 
 | 
const getProductModel = (value) => { 
 | 
  console.log("value", value); 
 | 
  const index = modelOptions.value.findIndex((item) => item.id === value); 
 | 
  if (index !== -1) { 
 | 
    productForm.value.specificationModel = modelOptions.value[index].model; 
 | 
    productForm.value.unit = modelOptions.value[index].unit; 
 | 
  } else { 
 | 
    productForm.value.specificationModel = null; 
 | 
    productForm.value.unit = null; 
 | 
  } 
 | 
}; 
 | 
const findNodeById = (nodes, productId) => { 
 | 
  for (let i = 0; i < nodes.length; i++) { 
 | 
    if (nodes[i].value === productId) { 
 | 
      return nodes[i].label; // 找到节点,返回该节点 
 | 
    } 
 | 
    if (nodes[i].children && nodes[i].children.length > 0) { 
 | 
      const foundNode = findNodeById(nodes[i].children, productId); 
 | 
      if (foundNode) { 
 | 
        return foundNode; // 在子节点中找到,返回该节点 
 | 
      } 
 | 
    } 
 | 
  } 
 | 
  return null; // 没有找到节点,返回null 
 | 
}; 
 | 
function convertIdToValue(data) { 
 | 
  return data.map((item) => { 
 | 
    const { id, children, ...rest } = item; 
 | 
    const newItem = { 
 | 
      ...rest, 
 | 
      value: id, // 将 id 改为 value 
 | 
    }; 
 | 
    if (children && children.length > 0) { 
 | 
      newItem.children = convertIdToValue(children); 
 | 
    } 
 | 
  
 | 
    return newItem; 
 | 
  }); 
 | 
} 
 | 
// 表格选择数据 
 | 
const handleSelectionChange = (selection) => { 
 | 
  // 过滤掉子数据 
 | 
  selectedRows.value = selection.filter((item) => item.children !== undefined); 
 | 
  console.log("selection", selectedRows.value); 
 | 
}; 
 | 
const productSelected = (selectedRows) => { 
 | 
  productSelectedRows.value = selectedRows; 
 | 
}; 
 | 
const expandedRowKeys = ref([]); 
 | 
// 展开行 
 | 
const expandChange = (row, expandedRows) => { 
 | 
  if (expandedRows.length > 0) { 
 | 
    expandedRowKeys.value = []; 
 | 
    try { 
 | 
      productList({ salesLedgerId: row.id, type: 1 }).then((res) => { 
 | 
        const index = tableData.value.findIndex((item) => item.id === row.id); 
 | 
        if (index > -1) { 
 | 
          tableData.value[index].children = res.data; 
 | 
        } 
 | 
        expandedRowKeys.value.push(row.id); 
 | 
      }); 
 | 
    } catch (error) { 
 | 
      console.log(error); 
 | 
    } 
 | 
  } else { 
 | 
    expandedRowKeys.value = []; 
 | 
  } 
 | 
}; 
 | 
// 主表合计方法 
 | 
const summarizeMainTable = (param) => { 
 | 
  return proxy.summarizeTable(param, [ 
 | 
    "contractAmount", 
 | 
    "taxInclusiveTotalPrice", 
 | 
    "taxExclusiveTotalPrice", 
 | 
  ]); 
 | 
}; 
 | 
// 子表合计方法 
 | 
const summarizeChildrenTable = (param) => { 
 | 
  return proxy.summarizeTable(param, [ 
 | 
    "taxInclusiveUnitPrice", 
 | 
    "taxInclusiveTotalPrice", 
 | 
    "taxExclusiveTotalPrice", 
 | 
  ]); 
 | 
}; 
 | 
// 打开弹框 
 | 
const openForm = async (type, row) => { 
 | 
  operationType.value = type; 
 | 
  form.value = {}; 
 | 
  productData.value = []; 
 | 
  let userLists = await userListNoPage(); 
 | 
  userList.value = userLists.data; 
 | 
  customerList().then((res) => { 
 | 
    customerOption.value = res; 
 | 
  }); 
 | 
  form.value.entryPerson = userStore.id; 
 | 
  if (type !== "add") { 
 | 
    currentId.value = row.id; 
 | 
    getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => { 
 | 
      form.value = { ...res }; 
 | 
      form.value.entryPerson = Number(res.entryPerson); 
 | 
      productData.value = form.value.productData; 
 | 
      fileList.value = form.value.salesLedgerFiles; 
 | 
    }); 
 | 
  } 
 | 
  // let userAll = await userStore.getInfo() 
 | 
  // userList.value.forEach(element => { 
 | 
  //   if(userAll.user.nickName === element.nickName && userAll.user.userName === element.userName) { 
 | 
  //     form.value.entryPerson = userAll.user.userId // 设置默认业务员为当前用户 
 | 
  //   } 
 | 
  // }); 
 | 
  form.value.entryDate = getCurrentDate(); // 设置默认录入日期为当前日期 
 | 
  dialogFormVisible.value = true; 
 | 
}; 
 | 
function changs(val) { 
 | 
  console.log(val); 
 | 
} 
 | 
// 上传前校检 
 | 
function handleBeforeUpload(file) { 
 | 
  // 校检文件大小 
 | 
  // if (file.size > 1024 * 1024 * 10) { 
 | 
  //   proxy.$modal.msgError("上传文件大小不能超过10MB!"); 
 | 
  //   return false; 
 | 
  // } 
 | 
  proxy.$modal.loading("正在上传文件,请稍候..."); 
 | 
  return true; 
 | 
} 
 | 
// 上传失败 
 | 
function handleUploadError(err) { 
 | 
  proxy.$modal.msgError("上传文件失败"); 
 | 
  proxy.$modal.closeLoading(); 
 | 
} 
 | 
// 上传成功回调 
 | 
function handleUploadSuccess(res, file, uploadFiles) { 
 | 
  proxy.$modal.closeLoading(); 
 | 
  if (res.code === 200) { 
 | 
    file.tempId = res.data.tempId; 
 | 
    proxy.$modal.msgSuccess("上传成功"); 
 | 
  } else { 
 | 
    proxy.$modal.msgError(res.msg); 
 | 
    proxy.$refs.fileUpload.handleRemove(file); 
 | 
  } 
 | 
} 
 | 
// 移除文件 
 | 
function handleRemove(file) { 
 | 
  if (operationType.value === "edit") { 
 | 
    let ids = []; 
 | 
    ids.push(file.id); 
 | 
    delLedgerFile(ids).then((res) => { 
 | 
      proxy.$modal.msgSuccess("删除成功"); 
 | 
    }); 
 | 
  } 
 | 
} 
 | 
// 提交表单 
 | 
const submitForm = () => { 
 | 
  proxy.$refs["formRef"].validate((valid) => { 
 | 
    if (valid) { 
 | 
            console.log('productData.value--', productData.value) 
 | 
      if (productData.value !== null && productData.value.length > 0) { 
 | 
        form.value.productData = proxy.HaveJson(productData.value); 
 | 
      } else { 
 | 
        proxy.$modal.msgWarning("请添加产品信息"); 
 | 
        return; 
 | 
      } 
 | 
      let tempFileIds = []; 
 | 
      if (fileList.value !== null && fileList.value.length > 0) { 
 | 
        tempFileIds = fileList.value.map((item) => item.tempId); 
 | 
      } 
 | 
      form.value.tempFileIds = tempFileIds; 
 | 
      form.value.type = 1; 
 | 
      addOrUpdateSalesLedger(form.value).then((res) => { 
 | 
        proxy.$modal.msgSuccess("提交成功"); 
 | 
        closeDia(); 
 | 
        getList(); 
 | 
      }); 
 | 
    } 
 | 
  }); 
 | 
}; 
 | 
// 关闭弹框 
 | 
const closeDia = () => { 
 | 
  proxy.resetForm("formRef"); 
 | 
  dialogFormVisible.value = false; 
 | 
}; 
 | 
  
 | 
const productIndex = ref(0); 
 | 
// 打开产品弹框 
 | 
const openProductForm = (type, row,index) => { 
 | 
  productOperationType.value = type; 
 | 
  productForm.value = {}; 
 | 
  proxy.resetForm("productFormRef"); 
 | 
  if (type === "edit") { 
 | 
    productForm.value = { ...row }; 
 | 
    productIndex.value = index; 
 | 
  } 
 | 
  productFormVisible.value = true; 
 | 
  getProductOptions(); 
 | 
}; 
 | 
// 提交产品表单 
 | 
const submitProduct = () => { 
 | 
  proxy.$refs["productFormRef"].validate((valid) => { 
 | 
    if (valid) { 
 | 
      if (operationType.value === "edit") { 
 | 
        submitProductEdit(); 
 | 
      } else { 
 | 
        if(productOperationType.value === "add"){ 
 | 
          productData.value.push({ ...productForm.value }); 
 | 
        }else{ 
 | 
          productData.value[productIndex.value] = { ...productForm.value } 
 | 
        } 
 | 
        closeProductDia(); 
 | 
      } 
 | 
    } 
 | 
  }); 
 | 
}; 
 | 
const submitProductEdit = () => { 
 | 
  productForm.value.salesLedgerId = currentId.value; 
 | 
  productForm.value.type = 1 
 | 
  addOrUpdateSalesLedgerProduct(productForm.value).then((res) => { 
 | 
    proxy.$modal.msgSuccess("提交成功"); 
 | 
    closeProductDia(); 
 | 
    getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then((res) => { 
 | 
      productData.value = res.productData; 
 | 
    }); 
 | 
  }); 
 | 
}; 
 | 
// 删除产品 
 | 
const deleteProduct = () => { 
 | 
  if (productSelectedRows.value.length === 0) { 
 | 
    proxy.$modal.msgWarning("请选择数据"); 
 | 
    return; 
 | 
  } 
 | 
  if (operationType.value === "add") { 
 | 
    productSelectedRows.value.forEach((selectedRow) => { 
 | 
      const index = productData.value.findIndex( 
 | 
        (product) => product.id === selectedRow.id 
 | 
      ); 
 | 
      if (index !== -1) { 
 | 
        productData.value.splice(index, 1); 
 | 
      } 
 | 
    }); 
 | 
  } else { 
 | 
    let ids = []; 
 | 
    if (productSelectedRows.value.length > 0) { 
 | 
      ids = productSelectedRows.value.map((item) => item.id); 
 | 
    } 
 | 
    ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", { 
 | 
      confirmButtonText: "确认", 
 | 
      cancelButtonText: "取消", 
 | 
      type: "warning", 
 | 
    }) 
 | 
      .then(() => { 
 | 
        delProduct(ids).then((res) => { 
 | 
          proxy.$modal.msgSuccess("删除成功"); 
 | 
          closeProductDia(); 
 | 
          getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then( 
 | 
            (res) => { 
 | 
              productData.value = res.productData; 
 | 
            } 
 | 
          ); 
 | 
        }); 
 | 
      }) 
 | 
      .catch(() => { 
 | 
        proxy.$modal.msg("已取消"); 
 | 
      }); 
 | 
  } 
 | 
}; 
 | 
// 关闭产品弹框 
 | 
const closeProductDia = () => { 
 | 
  proxy.resetForm("productFormRef"); 
 | 
  productFormVisible.value = false; 
 | 
}; 
 | 
// 导出 
 | 
const handleOut = () => { 
 | 
  ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", { 
 | 
    confirmButtonText: "确认", 
 | 
    cancelButtonText: "取消", 
 | 
    type: "warning", 
 | 
  }) 
 | 
    .then(() => { 
 | 
      proxy.download("/sales/ledger/export", {}, "销售台账.xlsx"); 
 | 
    }) 
 | 
    .catch(() => { 
 | 
      proxy.$modal.msg("已取消"); 
 | 
    }); 
 | 
}; 
 | 
// 删除 
 | 
const handleDelete = () => { 
 | 
  let ids = []; 
 | 
  if (selectedRows.value.length > 0) { 
 | 
    ids = selectedRows.value.map((item) => item.id); 
 | 
  } else { 
 | 
    proxy.$modal.msgWarning("请选择数据"); 
 | 
    return; 
 | 
  } 
 | 
  ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", { 
 | 
    confirmButtonText: "确认", 
 | 
    cancelButtonText: "取消", 
 | 
    type: "warning", 
 | 
  }) 
 | 
    .then(() => { 
 | 
      delLedger(ids).then((res) => { 
 | 
        proxy.$modal.msgSuccess("删除成功"); 
 | 
        getList(); 
 | 
      }); 
 | 
    }) 
 | 
    .catch(() => { 
 | 
      proxy.$modal.msg("已取消"); 
 | 
    }); 
 | 
}; 
 | 
  
 | 
// 打印功能 
 | 
const handlePrint = async () => { 
 | 
    if (selectedRows.value.length === 0) { 
 | 
        proxy.$modal.msgWarning("请选择要打印的数据"); 
 | 
        return; 
 | 
    } 
 | 
     
 | 
    // 显示加载状态 
 | 
    proxy.$modal.loading("正在获取产品数据,请稍候..."); 
 | 
     
 | 
    try { 
 | 
        // 为每个选中的销售台账记录查询对应的产品数据 
 | 
        const printDataWithProducts = []; 
 | 
         
 | 
        for (const row of selectedRows.value) { 
 | 
            try { 
 | 
                // 调用productList接口查询产品数据 
 | 
                const productRes = await productList({ salesLedgerId: row.id, type: 1 }); 
 | 
                 
 | 
                // 将产品数据整合到销售台账记录中 
 | 
                const rowWithProducts = { 
 | 
                    ...row, 
 | 
                    products: productRes.data || [] 
 | 
                }; 
 | 
                 
 | 
                printDataWithProducts.push(rowWithProducts); 
 | 
            } catch (error) { 
 | 
                console.error(`获取销售台账 ${row.id} 的产品数据失败:`, error); 
 | 
                // 即使某个记录的产品数据获取失败,也要包含该记录 
 | 
                printDataWithProducts.push({ 
 | 
                    ...row, 
 | 
                    products: [] 
 | 
                }); 
 | 
            } 
 | 
        } 
 | 
         
 | 
        printData.value = printDataWithProducts; 
 | 
        console.log('打印数据(包含产品):', printData.value); 
 | 
        printPreviewVisible.value = true; 
 | 
         
 | 
    } catch (error) { 
 | 
        console.error('获取产品数据失败:', error); 
 | 
        proxy.$modal.msgError("获取产品数据失败,请重试"); 
 | 
    } finally { 
 | 
        proxy.$modal.closeLoading(); 
 | 
    } 
 | 
}; 
 | 
// 执行打印 
 | 
const executePrint = () => { 
 | 
    console.log('开始执行打印,数据条数:', printData.value.length); 
 | 
    console.log('打印数据:', printData.value); 
 | 
     
 | 
    // 创建一个新的打印窗口 
 | 
    const printWindow = window.open('', '_blank', 'width=800,height=600'); 
 | 
     
 | 
    // 构建打印内容 
 | 
    let printContent = ` 
 | 
    <!DOCTYPE html> 
 | 
    <html> 
 | 
    <head> 
 | 
      <meta charset="UTF-8"> 
 | 
      <title>打印预览</title> 
 | 
      <style> 
 | 
        body { 
 | 
          margin: 0; 
 | 
          padding: 0; 
 | 
          font-family: "SimSun", serif; 
 | 
          background: white; 
 | 
        } 
 | 
                                                     .print-page { 
 | 
            width: 200mm; 
 | 
            height: 75mm; 
 | 
            padding: 10mm; 
 | 
            padding-left: 20mm; 
 | 
            background: white; 
 | 
            box-sizing: border-box; 
 | 
            page-break-after: always; 
 | 
            page-break-inside: avoid; 
 | 
          } 
 | 
         .print-page:last-child { 
 | 
           page-break-after: avoid; 
 | 
         } 
 | 
        .delivery-note { 
 | 
          width: 100%; 
 | 
          height: 100%; 
 | 
          font-size: 12px; 
 | 
          line-height: 1.2; 
 | 
          display: flex; 
 | 
          flex-direction: column; 
 | 
          color: #000; 
 | 
        } 
 | 
        .header { 
 | 
          text-align: center; 
 | 
          margin-bottom: 8px; 
 | 
        } 
 | 
        .company-name { 
 | 
          font-size: 18px; 
 | 
          font-weight: bold; 
 | 
          margin-bottom: 4px; 
 | 
        } 
 | 
        .document-title { 
 | 
          font-size: 16px; 
 | 
          font-weight: bold; 
 | 
        } 
 | 
        .info-section { 
 | 
          margin-bottom: 8px; 
 | 
          display: flex; 
 | 
          justify-content: space-between; 
 | 
          align-items: center; 
 | 
        } 
 | 
        .info-row { 
 | 
          line-height: 20px; 
 | 
        } 
 | 
        .label { 
 | 
          font-weight: bold; 
 | 
          width: 60px; 
 | 
          font-size: 12px; 
 | 
        } 
 | 
        .value { 
 | 
          margin-right: 20px; 
 | 
          min-width: 80px; 
 | 
          font-size: 12px; 
 | 
        } 
 | 
                 .table-section { 
 | 
                 margin-bottom: 40px; 
 | 
          //  flex: 0.6; 
 | 
         } 
 | 
        .product-table { 
 | 
          width: 100%; 
 | 
          border-collapse: collapse; 
 | 
          border: 1px solid #000; 
 | 
        } 
 | 
                 .product-table th, .product-table td { 
 | 
           border: 1px solid #000; 
 | 
           padding: 6px; 
 | 
           text-align: center; 
 | 
           font-size: 12px; 
 | 
           line-height: 1.4; 
 | 
         } 
 | 
        .product-table th { 
 | 
          font-weight: bold; 
 | 
        } 
 | 
        .total-value { 
 | 
          font-weight: bold; 
 | 
        } 
 | 
        .footer-section { 
 | 
          margin-top: auto; 
 | 
        } 
 | 
        .footer-row { 
 | 
          display: flex; 
 | 
          margin-bottom: 3px; 
 | 
          line-height: 22px; 
 | 
          justify-content: space-between; 
 | 
        } 
 | 
        .footer-item { 
 | 
          display: flex; 
 | 
          margin-right: 20px; 
 | 
        } 
 | 
        .footer-item .label { 
 | 
          font-weight: bold; 
 | 
          width: 80px; 
 | 
          font-size: 12px; 
 | 
        } 
 | 
        .footer-item .value { 
 | 
          min-width: 80px; 
 | 
          font-size: 12px; 
 | 
        } 
 | 
        .address-item .address-value { 
 | 
          min-width: 200px; 
 | 
        } 
 | 
        @media print { 
 | 
          body { 
 | 
            margin: 0; 
 | 
            padding: 0; 
 | 
          } 
 | 
                     .print-page { 
 | 
             margin: 0; 
 | 
             padding: 10mm; 
 | 
             /* padding-left: 20mm; */ 
 | 
             page-break-inside: avoid; 
 | 
             page-break-after: always; 
 | 
           } 
 | 
           .print-page:last-child { 
 | 
             page-break-after: avoid; 
 | 
           } 
 | 
        } 
 | 
      </style> 
 | 
    </head> 
 | 
    <body> 
 | 
  `; 
 | 
     
 | 
    // 为每条数据生成打印页面 
 | 
    printData.value.forEach((item, index) => { 
 | 
        printContent += ` 
 | 
      <div class="print-page"> 
 | 
        <div class="delivery-note"> 
 | 
          <div class="header"> 
 | 
            <div class="company-name">鼎诚瑞实业有限责任公司</div> 
 | 
            <div class="document-title">零售发货单</div> 
 | 
          </div> 
 | 
           
 | 
          <div class="info-section"> 
 | 
            <div class="info-row"> 
 | 
              <div> 
 | 
                <span class="label">发货日期:</span> 
 | 
                <span class="value">${formatDate(item.createTime)}</span> 
 | 
              </div> 
 | 
              <div> 
 | 
                <span class="label">客户名称:</span> 
 | 
                <span class="value">${item.customerName || '张爱有'}</span> 
 | 
              </div> 
 | 
            </div> 
 | 
            <div class="info-row"> 
 | 
              <span class="label">单号:</span> 
 | 
              <span class="value">${item.salesContractNo || ''}</span> 
 | 
            </div> 
 | 
          </div> 
 | 
  
 | 
          <div class="table-section"> 
 | 
            <table class="product-table"> 
 | 
              <thead> 
 | 
                <tr> 
 | 
                  <th>产品名称</th> 
 | 
                  <th>规格型号</th> 
 | 
                  <th>单位</th> 
 | 
                  <th>单价</th> 
 | 
                  <th>零售数量</th> 
 | 
                  <th>零售金额</th> 
 | 
                </tr> 
 | 
              </thead> 
 | 
              <tbody> 
 | 
                ${item.products && item.products.length > 0 ?  
 | 
                  item.products.map(product => ` 
 | 
                    <tr> 
 | 
                      <td>${product.productCategory || ''}</td> 
 | 
                      <td>${product.specificationModel || ''}</td> 
 | 
                      <td>${product.unit || ''}</td> 
 | 
                      <td>${product.taxInclusiveUnitPrice || '0'}</td> 
 | 
                      <td>${product.quantity || '0'}</td> 
 | 
                      <td>${product.taxInclusiveTotalPrice || '0'}</td> 
 | 
                    </tr> 
 | 
                  `).join('') :  
 | 
                  '<tr><td colspan="6" style="text-align: center; color: #999;">暂无产品数据</td></tr>' 
 | 
                } 
 | 
              </tbody> 
 | 
              <tfoot> 
 | 
                <tr> 
 | 
                  <td class="label">合计</td> 
 | 
                  <td class="total-value"></td> 
 | 
                  <td class="total-value"></td> 
 | 
                  <td class="total-value"></td> 
 | 
                  <td class="total-value">${getTotalQuantityForPrint(item.products)}</td> 
 | 
                  <td class="total-value">${getTotalAmountForPrint(item.products)}</td> 
 | 
                </tr> 
 | 
              </tfoot> 
 | 
            </table> 
 | 
          </div> 
 | 
  
 | 
          <div class="footer-section"> 
 | 
            <div class="footer-row"> 
 | 
              <div class="footer-item"> 
 | 
                <span class="label">收货电话:</span> 
 | 
                <span class="value"></span> 
 | 
              </div> 
 | 
              <div class="footer-item"> 
 | 
                <span class="label">收货人:</span> 
 | 
                <span class="value"></span> 
 | 
              </div> 
 | 
              <div class="footer-item address-item"> 
 | 
                <span class="label">收货地址:</span> 
 | 
                <span class="value address-value"></span> 
 | 
              </div> 
 | 
            </div> 
 | 
            <div class="footer-row"> 
 | 
              <div class="footer-item"> 
 | 
                <span class="label">操作员:</span> 
 | 
                <span class="value">${userStore.nickName || '撕开前'}</span> 
 | 
              </div> 
 | 
              <div class="footer-item"> 
 | 
                <span class="label">打印日期:</span> 
 | 
                <span class="value">${formatDateTime(new Date())}</span> 
 | 
              </div> 
 | 
            </div> 
 | 
          </div> 
 | 
        </div> 
 | 
      </div> 
 | 
    `; 
 | 
    }); 
 | 
     
 | 
    printContent += ` 
 | 
    </body> 
 | 
    </html> 
 | 
  `; 
 | 
     
 | 
    // 写入内容到新窗口 
 | 
    printWindow.document.write(printContent); 
 | 
    printWindow.document.close(); 
 | 
     
 | 
    // 等待内容加载完成后打印 
 | 
    printWindow.onload = () => { 
 | 
        setTimeout(() => { 
 | 
            printWindow.print(); 
 | 
            printWindow.close(); 
 | 
            printPreviewVisible.value = false; 
 | 
        }, 500); 
 | 
    }; 
 | 
}; 
 | 
// 格式化日期 
 | 
const formatDate = (dateString) => { 
 | 
    if (!dateString) return getCurrentDate(); 
 | 
    const date = new Date(dateString); 
 | 
    const year = date.getFullYear(); 
 | 
    const month = String(date.getMonth() + 1).padStart(2, "0"); 
 | 
    const day = String(date.getDate()).padStart(2, "0"); 
 | 
    return `${year}/${month}/${day}`; 
 | 
}; 
 | 
// 格式化日期时间 
 | 
const formatDateTime = (date) => { 
 | 
    const year = date.getFullYear(); 
 | 
    const month = String(date.getMonth() + 1).padStart(2, "0"); 
 | 
    const day = String(date.getDate()).padStart(2, "0"); 
 | 
    const hours = String(date.getHours()).padStart(2, "0"); 
 | 
    const minutes = String(date.getMinutes()).padStart(2, "0"); 
 | 
    const seconds = String(date.getSeconds()).padStart(2, "0"); 
 | 
    return `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`; 
 | 
}; 
 | 
// 获取当前日期并格式化为 YYYY-MM-DD 
 | 
function getCurrentDate() { 
 | 
  const today = new Date(); 
 | 
  const year = today.getFullYear(); 
 | 
  const month = String(today.getMonth() + 1).padStart(2, "0"); // 月份从0开始 
 | 
  const day = String(today.getDate()).padStart(2, "0"); 
 | 
  return `${year}-${month}-${day}`; 
 | 
} 
 | 
  
 | 
// 计算产品总数量 
 | 
const getTotalQuantity = (products) => { 
 | 
  if (!products || products.length === 0) return '0'; 
 | 
  const total = products.reduce((sum, product) => { 
 | 
    return sum + (parseFloat(product.quantity) || 0); 
 | 
  }, 0); 
 | 
  return total.toFixed(2); 
 | 
}; 
 | 
  
 | 
// 计算产品总金额 
 | 
const getTotalAmount = (products) => { 
 | 
  if (!products || products.length === 0) return '0'; 
 | 
  const total = products.reduce((sum, product) => { 
 | 
    return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0); 
 | 
  }, 0); 
 | 
  return total.toFixed(2); 
 | 
}; 
 | 
  
 | 
// 用于打印的计算函数 
 | 
const getTotalQuantityForPrint = (products) => { 
 | 
  if (!products || products.length === 0) return '0'; 
 | 
  const total = products.reduce((sum, product) => { 
 | 
    return sum + (parseFloat(product.quantity) || 0); 
 | 
  }, 0); 
 | 
  return total.toFixed(2); 
 | 
}; 
 | 
  
 | 
const getTotalAmountForPrint = (products) => { 
 | 
  if (!products || products.length === 0) return '0'; 
 | 
  const total = products.reduce((sum, product) => { 
 | 
    return sum + (parseFloat(product.taxInclusiveTotalPrice) || 0); 
 | 
  }, 0); 
 | 
  return total.toFixed(2); 
 | 
}; 
 | 
  
 | 
const mathNum = () => { 
 | 
  console.log("productForm.value", productForm.value); 
 | 
  if (!productForm.value.taxInclusiveUnitPrice) { 
 | 
    return; 
 | 
  } 
 | 
  if (!productForm.value.quantity) { 
 | 
    return; 
 | 
  } 
 | 
  // 含税总价计算 
 | 
  productForm.value.taxInclusiveTotalPrice = 
 | 
    proxy.calculateTaxIncludeTotalPrice( 
 | 
      productForm.value.taxInclusiveUnitPrice, 
 | 
      productForm.value.quantity 
 | 
    ); 
 | 
  if (productForm.value.taxRate) { 
 | 
    // 不含税总价计算 
 | 
    productForm.value.taxExclusiveTotalPrice = 
 | 
      proxy.calculateTaxExclusiveTotalPrice( 
 | 
        productForm.value.taxInclusiveTotalPrice, 
 | 
        productForm.value.taxRate 
 | 
      ); 
 | 
  } 
 | 
}; 
 | 
  
 | 
// 根据含税总价计算含税单价和数量 
 | 
const calculateFromTotalPrice = () => { 
 | 
  if (isCalculating.value) return; 
 | 
   
 | 
  const totalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice); 
 | 
  const quantity = parseFloat(productForm.value.quantity); 
 | 
   
 | 
  if (!totalPrice || !quantity || quantity <= 0) { 
 | 
    return; 
 | 
  } 
 | 
   
 | 
  isCalculating.value = true; 
 | 
   
 | 
  // 计算含税单价 = 含税总价 / 数量 
 | 
  productForm.value.taxInclusiveUnitPrice = (totalPrice / quantity).toFixed(2); 
 | 
   
 | 
  // 如果有税率,计算不含税总价 
 | 
  if (productForm.value.taxRate) { 
 | 
    productForm.value.taxExclusiveTotalPrice = 
 | 
      proxy.calculateTaxExclusiveTotalPrice( 
 | 
        totalPrice, 
 | 
        productForm.value.taxRate 
 | 
      ); 
 | 
  } 
 | 
   
 | 
  isCalculating.value = false; 
 | 
}; 
 | 
  
 | 
// 根据不含税总价计算含税单价和数量 
 | 
const calculateFromExclusiveTotalPrice = () => { 
 | 
    if (!productForm.value.taxRate) { 
 | 
        proxy.$modal.msgWarning("请先选择税率"); 
 | 
        return; 
 | 
    } 
 | 
  if (isCalculating.value) return; 
 | 
   
 | 
  const exclusiveTotalPrice = parseFloat(productForm.value.taxExclusiveTotalPrice); 
 | 
  const quantity = parseFloat(productForm.value.quantity); 
 | 
  const taxRate = parseFloat(productForm.value.taxRate); 
 | 
   
 | 
  if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) { 
 | 
    return; 
 | 
  } 
 | 
   
 | 
  isCalculating.value = true; 
 | 
   
 | 
  // 先计算含税总价 = 不含税总价 / (1 - 税率/100) 
 | 
  const taxRateDecimal = taxRate / 100; 
 | 
  const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal); 
 | 
  productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2); 
 | 
   
 | 
  // 计算含税单价 = 含税总价 / 数量 
 | 
  productForm.value.taxInclusiveUnitPrice = (inclusiveTotalPrice / quantity).toFixed(2); 
 | 
   
 | 
  isCalculating.value = false; 
 | 
}; 
 | 
  
 | 
// 根据数量变化计算总价 
 | 
const calculateFromQuantity = () => { 
 | 
    if (!productForm.value.taxRate) { 
 | 
        proxy.$modal.msgWarning("请先选择税率"); 
 | 
        return; 
 | 
    } 
 | 
  if (isCalculating.value) return; 
 | 
   
 | 
  const quantity = parseFloat(productForm.value.quantity); 
 | 
  const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice); 
 | 
   
 | 
  if (!quantity || quantity <= 0 || !unitPrice) { 
 | 
    return; 
 | 
  } 
 | 
   
 | 
  isCalculating.value = true; 
 | 
   
 | 
  // 计算含税总价 
 | 
  productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2); 
 | 
   
 | 
  // 如果有税率,计算不含税总价 
 | 
  if (productForm.value.taxRate) { 
 | 
    productForm.value.taxExclusiveTotalPrice = 
 | 
      proxy.calculateTaxExclusiveTotalPrice( 
 | 
        productForm.value.taxInclusiveTotalPrice, 
 | 
        productForm.value.taxRate 
 | 
      ); 
 | 
  } 
 | 
   
 | 
  isCalculating.value = false; 
 | 
}; 
 | 
  
 | 
// 根据含税单价变化计算总价 
 | 
const calculateFromUnitPrice = () => { 
 | 
    if (!productForm.value.taxRate) { 
 | 
        proxy.$modal.msgWarning("请先选择税率"); 
 | 
        return; 
 | 
    } 
 | 
  if (isCalculating.value) return; 
 | 
   
 | 
  const quantity = parseFloat(productForm.value.quantity); 
 | 
  const unitPrice = parseFloat(productForm.value.taxInclusiveUnitPrice); 
 | 
   
 | 
  if (!quantity || quantity <= 0 || !unitPrice) { 
 | 
    return; 
 | 
  } 
 | 
   
 | 
  isCalculating.value = true; 
 | 
   
 | 
  // 计算含税总价 
 | 
  productForm.value.taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2); 
 | 
   
 | 
  // 如果有税率,计算不含税总价 
 | 
  if (productForm.value.taxRate) { 
 | 
    productForm.value.taxExclusiveTotalPrice = 
 | 
      proxy.calculateTaxExclusiveTotalPrice( 
 | 
        productForm.value.taxInclusiveTotalPrice, 
 | 
        productForm.value.taxRate 
 | 
      ); 
 | 
  } 
 | 
   
 | 
  isCalculating.value = false; 
 | 
}; 
 | 
  
 | 
// 根据税率变化计算不含税总价 
 | 
const calculateFromTaxRate = () => { 
 | 
    if (!productForm.value.taxRate) { 
 | 
        proxy.$modal.msgWarning("请先选择税率"); 
 | 
        return; 
 | 
    } 
 | 
  if (isCalculating.value) return; 
 | 
   
 | 
  const inclusiveTotalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice); 
 | 
  const taxRate = parseFloat(productForm.value.taxRate); 
 | 
   
 | 
  if (!inclusiveTotalPrice || !taxRate) { 
 | 
    return; 
 | 
  } 
 | 
   
 | 
  isCalculating.value = true; 
 | 
   
 | 
  // 计算不含税总价 
 | 
  productForm.value.taxExclusiveTotalPrice = 
 | 
    proxy.calculateTaxExclusiveTotalPrice( 
 | 
      inclusiveTotalPrice, 
 | 
      taxRate 
 | 
    ); 
 | 
   
 | 
  isCalculating.value = false; 
 | 
}; 
 | 
/** 
 | 
 * 下载文件 
 | 
 * 
 | 
 * @param row 下载文件的相关信息对象 
 | 
 */ 
 | 
const fileListRef = ref(null) 
 | 
const downLoadFile = (row) => { 
 | 
  getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => { 
 | 
    fileListRef.value.open(res.salesLedgerFiles) 
 | 
  }); 
 | 
} 
 | 
  
 | 
// 打开发货弹框 
 | 
const openDeliveryForm = (row) => { 
 | 
  currentDeliveryRow.value = row; 
 | 
  deliveryForm.value = { 
 | 
    shippingDate: getCurrentDate(), 
 | 
    shippingCarNumber: "", 
 | 
  }; 
 | 
  deliveryFormVisible.value = true; 
 | 
}; 
 | 
  
 | 
// 提交发货表单 
 | 
const submitDelivery = () => { 
 | 
  proxy.$refs["deliveryFormRef"].validate((valid) => { 
 | 
    if (valid) { 
 | 
      addShippingInfo({ 
 | 
        salesLedgerId: currentDeliveryRow.value.id, 
 | 
        shippingDate: deliveryForm.value.shippingDate, 
 | 
        shippingCarNumber: deliveryForm.value.shippingCarNumber, 
 | 
      }) 
 | 
        .then(() => { 
 | 
          proxy.$modal.msgSuccess("发货成功"); 
 | 
          closeDeliveryDia(); 
 | 
          getList(); 
 | 
        }) 
 | 
        .catch(() => { 
 | 
          proxy.$modal.msgError("发货失败,请重试"); 
 | 
        }); 
 | 
    } 
 | 
  }); 
 | 
}; 
 | 
  
 | 
// 关闭发货弹框 
 | 
const closeDeliveryDia = () => { 
 | 
  proxy.resetForm("deliveryFormRef"); 
 | 
  deliveryFormVisible.value = false; 
 | 
  currentDeliveryRow.value = null; 
 | 
}; 
 | 
  
 | 
onMounted(() => { 
 | 
    getList(); 
 | 
}); 
 | 
</script> 
 | 
  
 | 
<style scoped lang="scss"> 
 | 
.ml-10 { 
 | 
  margin-left: 10px; 
 | 
} 
 | 
  
 | 
.table_list { 
 | 
  margin-top: unset; 
 | 
} 
 | 
  
 | 
.actions { 
 | 
  display: flex; 
 | 
  justify-content: space-between; 
 | 
  margin-bottom: 10px; 
 | 
} 
 | 
.print-preview-dialog { 
 | 
    .el-dialog__body { 
 | 
        padding: 0; 
 | 
        max-height: 80vh; 
 | 
        overflow-y: auto; 
 | 
    } 
 | 
} 
 | 
  
 | 
.print-preview-container { 
 | 
    .print-preview-header { 
 | 
        padding: 15px; 
 | 
        border-bottom: 1px solid #e4e7ed; 
 | 
        text-align: center; 
 | 
         
 | 
        .el-button { 
 | 
            margin: 0 10px; 
 | 
        } 
 | 
    } 
 | 
     
 | 
    .print-preview-content { 
 | 
        padding: 20px; 
 | 
        background-color: #f5f5f5; 
 | 
        min-height: 400px; 
 | 
    } 
 | 
} 
 | 
  
 | 
.print-page { 
 | 
    width: 220mm; 
 | 
    height: 90mm; 
 | 
    padding: 10mm; 
 | 
    margin: 0 auto; 
 | 
    background: white; 
 | 
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); 
 | 
    margin-bottom: 10px; 
 | 
    box-sizing: border-box; 
 | 
} 
 | 
  
 | 
.delivery-note { 
 | 
    width: 100%; 
 | 
    height: 100%; 
 | 
    font-family: "SimSun", serif; 
 | 
    font-size: 10px; 
 | 
    line-height: 1.2; 
 | 
    display: flex; 
 | 
    flex-direction: column; 
 | 
} 
 | 
  
 | 
.header { 
 | 
    text-align: center; 
 | 
    margin-bottom: 8px; 
 | 
     
 | 
    .company-name { 
 | 
        font-size: 18px; 
 | 
        font-weight: bold; 
 | 
        margin-bottom: 4px; 
 | 
    } 
 | 
     
 | 
    .document-title { 
 | 
        font-size: 16px; 
 | 
        font-weight: bold; 
 | 
    } 
 | 
} 
 | 
  
 | 
.info-section { 
 | 
    margin-bottom: 8px; 
 | 
    display: flex; 
 | 
    justify-content: space-between; 
 | 
    align-items: center; 
 | 
     
 | 
    .info-row { 
 | 
        line-height: 20px; 
 | 
         
 | 
        .label { 
 | 
            font-weight: bold; 
 | 
            width: 60px; 
 | 
            font-size: 14px; 
 | 
        } 
 | 
         
 | 
        .value { 
 | 
            margin-right: 20px; 
 | 
            min-width: 80px; 
 | 
            font-size: 14px; 
 | 
        } 
 | 
    } 
 | 
} 
 | 
  
 | 
.table-section { 
 | 
    margin-bottom: 4px; 
 | 
    flex: 1; 
 | 
     
 | 
    .product-table { 
 | 
        width: 100%; 
 | 
        border-collapse: collapse; 
 | 
        border: 1px solid #000; 
 | 
         
 | 
        th, td { 
 | 
            border: 1px solid #000; 
 | 
            padding: 6px; 
 | 
            text-align: center; 
 | 
            font-size: 14px; 
 | 
            line-height: 1.4; 
 | 
        } 
 | 
         
 | 
        th { 
 | 
            font-weight: bold; 
 | 
        } 
 | 
         
 | 
        .total-label { 
 | 
            text-align: right; 
 | 
            font-weight: bold; 
 | 
        } 
 | 
         
 | 
        .total-value { 
 | 
            font-weight: bold; 
 | 
        } 
 | 
    } 
 | 
} 
 | 
  
 | 
.footer-section { 
 | 
    .footer-row { 
 | 
        display: flex; 
 | 
        margin-bottom: 3px; 
 | 
        line-height: 20px; 
 | 
        justify-content: space-between; 
 | 
         
 | 
        .footer-item { 
 | 
            display: flex; 
 | 
            margin-right: 20px; 
 | 
             
 | 
            .label { 
 | 
                font-weight: bold; 
 | 
                width: 80px; 
 | 
                font-size: 14px; 
 | 
            } 
 | 
             
 | 
            .value { 
 | 
                min-width: 80px; 
 | 
                font-size: 14px; 
 | 
            } 
 | 
             
 | 
            &.address-item { 
 | 
                .address-value { 
 | 
                    min-width: 200px; 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
    } 
 | 
} 
 | 
  
 | 
@media print { 
 | 
    .app-container { 
 | 
        display: none; 
 | 
    } 
 | 
     
 | 
    .print-page { 
 | 
        box-shadow: none; 
 | 
        margin: 0; 
 | 
        padding: 10mm; 
 | 
        padding-left: 20mm; 
 | 
        page-break-inside: avoid; 
 | 
        page-break-after: always; 
 | 
    } 
 | 
    .print-page:last-child { 
 | 
        page-break-after: avoid; 
 | 
    } 
 | 
} 
 | 
</style> 
 |