<template> 
 | 
  <div class="app-container"> 
 | 
    <div class="search_form"> 
 | 
      <div> 
 | 
        <el-form :model="searchForm" :inline="true"> 
 | 
          <el-form-item label="供应商名称:"> 
 | 
            <el-input v-model="searchForm.supplierName" placeholder="请输入" clearable prefix-icon="Search" 
 | 
                      @change="handleQuery" /> 
 | 
          </el-form-item> 
 | 
          <el-form-item label="采购合同号:"> 
 | 
            <el-input 
 | 
                v-model="searchForm.purchaseContractNumber" 
 | 
                style="width: 240px" 
 | 
                placeholder="请输入" 
 | 
                @change="handleQuery" 
 | 
                clearable 
 | 
                :prefix-icon="Search" 
 | 
            /> 
 | 
          </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> 
 | 
    <div class="table_list"> 
 | 
      <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;"> 
 | 
        <el-button type="primary" @click="openForm('add')">新增台账</el-button> 
 | 
        <el-button type="success" @click="openScanAddDialog">扫码新增</el-button> 
 | 
        <el-button @click="handleOut">导出</el-button> 
 | 
        <el-button type="danger" plain @click="handleDelete">删除</el-button> 
 | 
      </div> 
 | 
      <el-table 
 | 
        :data="tableData" 
 | 
        border 
 | 
        v-loading="tableLoading" 
 | 
        @selection-change="handleSelectionChange" 
 | 
        :expand-row-keys="expandedRowKeys" 
 | 
        :row-key="(row) => row.id" 
 | 
        show-summary 
 | 
        :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="purchaseContractNumber" 
 | 
          width="200" 
 | 
          show-overflow-tooltip 
 | 
        /> 
 | 
        <el-table-column 
 | 
          label="销售合同号" 
 | 
          prop="salesContractNo" 
 | 
          width="200" 
 | 
          show-overflow-tooltip 
 | 
        /> 
 | 
        <el-table-column 
 | 
          label="供应商名称" 
 | 
          width="240" 
 | 
          prop="supplierName" 
 | 
          show-overflow-tooltip 
 | 
        /> 
 | 
        <el-table-column 
 | 
          label="项目名称" 
 | 
          prop="projectName" 
 | 
          width="420" 
 | 
          show-overflow-tooltip 
 | 
        /> 
 | 
        <el-table-column 
 | 
          label="付款方式" 
 | 
          width="100" 
 | 
          prop="paymentMethod" 
 | 
          show-overflow-tooltip 
 | 
        /> 
 | 
        <el-table-column 
 | 
          label="合同金额(元)" 
 | 
          prop="contractAmount" 
 | 
           width="200" 
 | 
          show-overflow-tooltip 
 | 
          :formatter="formattedNumber" 
 | 
        /> 
 | 
        <el-table-column 
 | 
          label="录入人" 
 | 
          prop="recorderName" 
 | 
           width="100" 
 | 
          show-overflow-tooltip 
 | 
        /> 
 | 
        <el-table-column 
 | 
          label="录入日期" 
 | 
          prop="entryDate" 
 | 
           width="100" 
 | 
          show-overflow-tooltip 
 | 
        /> 
 | 
        <el-table-column 
 | 
          fixed="right" 
 | 
          label="操作" 
 | 
          min-width="150" 
 | 
          align="center" 
 | 
        > 
 | 
          <template #default="scope"> 
 | 
            <el-button 
 | 
              link 
 | 
              type="primary" 
 | 
              size="small" 
 | 
              @click="openForm('edit', scope.row)" 
 | 
                            :disabled="scope.row.receiptPaymentAmount>0 || scope.row.recorderName !== userStore.nickName" 
 | 
              >编辑</el-button 
 | 
            > 
 | 
            <el-button 
 | 
              link 
 | 
              type="success" 
 | 
              size="small" 
 | 
              @click="showQRCode(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="purchaseContractNumber"> 
 | 
              <el-input 
 | 
                v-model="form.purchaseContractNumber" 
 | 
                placeholder="请输入" 
 | 
                clearable 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="销售合同号:" prop="salesLedgerId"> 
 | 
              <el-select 
 | 
                v-model="form.salesLedgerId" 
 | 
                placeholder="请选择" 
 | 
                clearable 
 | 
                @change="salesLedgerChange" 
 | 
              > 
 | 
                <el-option 
 | 
                  v-for="item in salesContractList" 
 | 
                  :key="item.id" 
 | 
                  :label="item.salesContractNo" 
 | 
                  :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="supplierId"> 
 | 
              <el-select 
 | 
                v-model="form.supplierId" 
 | 
                placeholder="请选择" 
 | 
                clearable 
 | 
              > 
 | 
                <el-option 
 | 
                  v-for="item in supplierList" 
 | 
                  :key="item.id" 
 | 
                  :label="item.supplierName" 
 | 
                  :value="item.id" 
 | 
                /> 
 | 
              </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 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="30"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="录入人:" prop="recorderId"> 
 | 
              <el-select 
 | 
                v-model="form.recorderId" 
 | 
                placeholder="请选择" 
 | 
                clearable 
 | 
                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 
 | 
                disabled 
 | 
                style="width: 100%" 
 | 
                v-model="form.entryDate" 
 | 
                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="12"> 
 | 
            <el-form-item label="付款方式"> 
 | 
              <el-input 
 | 
                v-model="form.paymentMethod" 
 | 
                placeholder="请输入" 
 | 
                clearable 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row> 
 | 
          <el-form-item label="产品信息:" prop="entryDate"> 
 | 
            <el-button type="primary" @click="openProductForm('add')" 
 | 
              >添加</el-button 
 | 
            > 
 | 
            <el-button plain type="danger" @click="deleteProduct" 
 | 
              >删除</el-button 
 | 
            > 
 | 
          </el-form-item> 
 | 
        </el-row> 
 | 
        <el-table 
 | 
          :data="productData" 
 | 
          border 
 | 
          @selection-change="productSelected" 
 | 
          show-summary 
 | 
          :summary-method="summarizeProTable" 
 | 
        > 
 | 
          <el-table-column align="center" type="selection" width="55" /> 
 | 
          <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" width="70" /> 
 | 
          <el-table-column label="数量" prop="quantity" width="70" /> 
 | 
          <el-table-column label="税率(%)" prop="taxRate" width="80" /> 
 | 
          <el-table-column 
 | 
            label="含税单价(元)" 
 | 
            prop="taxInclusiveUnitPrice" 
 | 
            :formatter="formattedNumber" 
 | 
            width="150" 
 | 
          /> 
 | 
          <el-table-column 
 | 
            label="含税总价(元)" 
 | 
            prop="taxInclusiveTotalPrice" 
 | 
            :formatter="formattedNumber" 
 | 
            width="150" 
 | 
          /> 
 | 
          <el-table-column 
 | 
            label="不含税总价(元)" 
 | 
            prop="taxExclusiveTotalPrice" 
 | 
            :formatter="formattedNumber" 
 | 
            width="150" 
 | 
          /> 
 | 
          <el-table-column 
 | 
            fixed="right" 
 | 
            label="操作" 
 | 
            min-width="60" 
 | 
            align="center" 
 | 
          > 
 | 
            <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" 
 | 
              /> 
 | 
            </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">上传</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> 
 | 
      </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="productId"> 
 | 
              <el-tree-select 
 | 
                v-model="productForm.productId" 
 | 
                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="mathNum" 
 | 
                            > 
 | 
                                <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 
 | 
                v-model="productForm.taxInclusiveUnitPrice" 
 | 
                :precision="2" 
 | 
                :step="0.1" 
 | 
                clearable 
 | 
                style="width: 100%" 
 | 
                @change="mathNum" 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
                    <el-col :span="12"> 
 | 
                        <el-form-item label="数量:" prop="quantity"> 
 | 
                            <el-input-number 
 | 
                                :step="0.1" 
 | 
                                clearable 
 | 
                                :precision="2" 
 | 
                                style="width: 100%" 
 | 
                                v-model="productForm.quantity" 
 | 
                                placeholder="请输入" 
 | 
                                @change="mathNum" 
 | 
                            /> 
 | 
                        </el-form-item> 
 | 
                    </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="30"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="含税总价(元):" prop="taxInclusiveTotalPrice"> 
 | 
              <el-input-number 
 | 
                v-model="productForm.taxInclusiveTotalPrice" 
 | 
                :precision="2" 
 | 
                :step="0.1" 
 | 
                clearable 
 | 
                style="width: 100%" 
 | 
                @change="reverseMathNum('taxInclusiveTotalPrice')" 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item 
 | 
              label="不含税总价(元):" 
 | 
              prop="taxExclusiveTotalPrice" 
 | 
            > 
 | 
              <el-input  
 | 
                v-model="productForm.taxExclusiveTotalPrice" 
 | 
                @change="reverseMathNum('taxExclusiveTotalPrice')" 
 | 
              /> 
 | 
            </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="qrCodeDialogVisible" 
 | 
      title="采购合同号二维码" 
 | 
      width="400px" 
 | 
      center 
 | 
    > 
 | 
      <div style="text-align: center;"> 
 | 
        <img :src="qrCodeUrl" alt="二维码" style="width:200px;height:200px;" /> 
 | 
        <div style="margin: 20px;"> 
 | 
          <el-button type="primary" @click="downloadQRCode">下载二维码图片</el-button> 
 | 
        </div> 
 | 
      </div> 
 | 
    </el-dialog> 
 | 
  
 | 
    <!-- 扫码新增对话框 --> 
 | 
    <el-dialog 
 | 
      v-model="scanAddDialogVisible" 
 | 
      title="扫码新增采购台账" 
 | 
      width="70%" 
 | 
      @close="closeScanAddDialog" 
 | 
    > 
 | 
      <el-form 
 | 
        :model="scanAddForm" 
 | 
        label-width="140px" 
 | 
        label-position="top" 
 | 
        :rules="scanAddRules" 
 | 
        ref="scanAddFormRef" 
 | 
      > 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="24"> 
 | 
            <el-form-item label="扫码内容:"> 
 | 
              <el-input 
 | 
                v-model="scanAddForm.scanContent" 
 | 
                type="textarea" 
 | 
                :rows="3" 
 | 
                placeholder="请扫描二维码或手动输入采购合同信息" 
 | 
                @input="parseScanContent" 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="采购合同号:" prop="purchaseContractNumber"> 
 | 
              <el-input 
 | 
                v-model="scanAddForm.purchaseContractNumber" 
 | 
                placeholder="请输入" 
 | 
                clearable 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="供应商名称:" prop="supplierName"> 
 | 
              <el-input 
 | 
                v-model="scanAddForm.supplierName" 
 | 
                placeholder="请输入" 
 | 
                clearable 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="项目名称:" prop="projectName"> 
 | 
              <el-input 
 | 
                v-model="scanAddForm.projectName" 
 | 
                placeholder="请输入" 
 | 
                clearable 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="合同金额(元):" prop="contractAmount"> 
 | 
              <el-input-number 
 | 
                v-model="scanAddForm.contractAmount" 
 | 
                :precision="2" 
 | 
                :step="0.1" 
 | 
                clearable 
 | 
                style="width: 100%" 
 | 
                placeholder="请输入" 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="付款方式:"> 
 | 
              <el-input 
 | 
                v-model="scanAddForm.paymentMethod" 
 | 
                placeholder="请输入" 
 | 
                clearable 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="录入人:"> 
 | 
              <el-input v-model="scanAddForm.recorderName" disabled /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="24"> 
 | 
            <el-form-item label="备注:"> 
 | 
              <el-input 
 | 
                v-model="scanAddForm.remark" 
 | 
                type="textarea" 
 | 
                :rows="2" 
 | 
                placeholder="请输入备注信息" 
 | 
                clearable 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
      </el-form> 
 | 
      <template #footer> 
 | 
        <div class="dialog-footer"> 
 | 
          <el-button type="primary" @click="submitScanAdd">确认新增</el-button> 
 | 
          <el-button @click="closeScanAddDialog">取消</el-button> 
 | 
        </div> 
 | 
      </template> 
 | 
    </el-dialog> 
 | 
  
 | 
    <!-- 扫码登记对话框 --> 
 | 
    <el-dialog 
 | 
      v-model="scanDialogVisible" 
 | 
      title="扫码登记" 
 | 
      width="60%" 
 | 
      @close="closeScanDialog" 
 | 
    > 
 | 
      <el-form 
 | 
        :model="scanForm" 
 | 
        label-width="120px" 
 | 
        label-position="left" 
 | 
        :rules="scanRules" 
 | 
        ref="scanFormRef" 
 | 
      > 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="采购合同号:"> 
 | 
              <el-input v-model="scanForm.purchaseContractNumber" disabled /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="供应商名称:"> 
 | 
              <el-input v-model="scanForm.supplierName" disabled /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="项目名称:"> 
 | 
              <el-input v-model="scanForm.projectName" disabled /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="扫码时间:"> 
 | 
              <el-input v-model="scanForm.scanTime" disabled /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="扫码人:"> 
 | 
              <el-input v-model="scanForm.scannerName" disabled /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
          <el-col :span="12"> 
 | 
            <el-form-item label="扫码状态:"> 
 | 
              <el-tag :type="scanForm.scanStatus === '已扫码' ? 'success' : 'warning'"> 
 | 
                {{ scanForm.scanStatus }} 
 | 
              </el-tag> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="24"> 
 | 
            <el-form-item label="扫码备注:"> 
 | 
              <el-input 
 | 
                v-model="scanForm.scanRemark" 
 | 
                type="textarea" 
 | 
                :rows="3" 
 | 
                placeholder="请输入扫码备注信息" 
 | 
              /> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
        <el-row :gutter="20"> 
 | 
          <el-col :span="24"> 
 | 
            <el-form-item label="扫码记录:"> 
 | 
              <el-table :data="scanRecords" border style="width: 100%"> 
 | 
                <el-table-column label="序号" type="index" width="60" align="center" /> 
 | 
                <el-table-column label="扫码时间" prop="scanTime" width="180" /> 
 | 
                <el-table-column label="扫码人" prop="scannerName" width="120" /> 
 | 
                <el-table-column label="扫码状态" prop="scanStatus" width="100"> 
 | 
                  <template #default="scope"> 
 | 
                    <el-tag :type="scope.row.scanStatus === '已扫码' ? 'success' : 'warning'"> 
 | 
                      {{ scope.row.scanStatus }} 
 | 
                    </el-tag> 
 | 
                  </template> 
 | 
                </el-table-column> 
 | 
                <el-table-column label="备注" prop="scanRemark" /> 
 | 
              </el-table> 
 | 
            </el-form-item> 
 | 
          </el-col> 
 | 
        </el-row> 
 | 
      </el-form> 
 | 
      <template #footer> 
 | 
        <div class="dialog-footer"> 
 | 
          <el-button type="primary" @click="submitScan">确认扫码</el-button> 
 | 
          <el-button @click="closeScanDialog">取消</el-button> 
 | 
        </div> 
 | 
      </template> 
 | 
    </el-dialog> 
 | 
  </div> 
 | 
</template> 
 | 
  
 | 
<script setup> 
 | 
import { getToken } from "@/utils/auth"; 
 | 
import pagination from "@/components/PIMTable/Pagination.vue"; 
 | 
import { ref, onMounted, reactive, toRefs, getCurrentInstance, nextTick } from "vue"; 
 | 
import { Search } from "@element-plus/icons-vue"; 
 | 
import { ElMessageBox } from "element-plus"; 
 | 
import { userListNoPage } from "@/api/system/user.js"; 
 | 
import { 
 | 
  getSalesLedgerWithProducts, 
 | 
  addOrUpdateSalesLedgerProduct, 
 | 
  delProduct, 
 | 
  delLedgerFile, 
 | 
  getProductInfoByContractNo, 
 | 
} from "@/api/salesManagement/salesLedger.js"; 
 | 
import { 
 | 
  addOrEditPurchase, 
 | 
  delPurchase, 
 | 
  getSalesNo, 
 | 
  purchaseListPage, 
 | 
  productList, 
 | 
  getPurchaseById, 
 | 
  getOptions, 
 | 
  createPurchaseNo, 
 | 
} from "@/api/procurementManagement/procurementLedger.js"; 
 | 
import useFormData from "@/hooks/useFormData.js"; 
 | 
import QRCode from "qrcode"; 
 | 
const { proxy } = getCurrentInstance(); 
 | 
const tableData = ref([]); 
 | 
const productData = ref([]); 
 | 
const selectedRows = ref([]); 
 | 
const productSelectedRows = ref([]); 
 | 
const modelOptions = ref([]); 
 | 
const userList = ref([]); 
 | 
const productOptions = ref([]); 
 | 
const salesContractList = ref([]); 
 | 
const supplierList = ref([]); 
 | 
const tableLoading = ref(false); 
 | 
const page = reactive({ 
 | 
  current: 1, 
 | 
  size: 100, 
 | 
}); 
 | 
const total = ref(0); 
 | 
const fileList = ref([]); 
 | 
import useUserStore from "@/store/modules/user"; 
 | 
import { modelList, productTreeList } from "@/api/basicData/product.js"; 
 | 
import dayjs from "dayjs"; 
 | 
  
 | 
const userStore = useUserStore(); 
 | 
  
 | 
// 二维码相关变量 
 | 
const qrCodeDialogVisible = ref(false); 
 | 
const qrCodeUrl = ref(""); 
 | 
  
 | 
// 用户信息表单弹框数据 
 | 
const operationType = ref(""); 
 | 
const dialogFormVisible = ref(false); 
 | 
const data = reactive({ 
 | 
  searchForm: { 
 | 
    supplierName: "", // 供应商名称 
 | 
    purchaseContractNumber: "", // 采购合同编号 
 | 
    salesContractNo: "", // 销售合同编号 
 | 
    projectName: "", // 项目名称 
 | 
    entryDate: null, // 录入日期 
 | 
    entryDateStart: undefined, 
 | 
    entryDateEnd: undefined, 
 | 
  }, 
 | 
  form: { 
 | 
    purchaseContractNumber: "", 
 | 
    salesLedgerId: "", 
 | 
    projectName: "", 
 | 
    recorderId: "", 
 | 
    entryDate: "", 
 | 
    productData: [], 
 | 
    supplierName: "", 
 | 
    supplierId: "", 
 | 
    paymentMethod: "", 
 | 
  }, 
 | 
  rules: { 
 | 
    purchaseContractNumber: [ 
 | 
      { required: true, message: "请输入", trigger: "blur" }, 
 | 
    ], 
 | 
    projectName: [{ required: true, message: "请输入", trigger: "blur" }], 
 | 
    supplierId: [{ required: true, message: "请输入", trigger: "blur" }], 
 | 
  }, 
 | 
}); 
 | 
const {  form, rules } = toRefs(data); 
 | 
const { form: searchForm } = useFormData(data.searchForm); 
 | 
  
 | 
// 产品表单弹框数据 
 | 
const productFormVisible = ref(false); 
 | 
const productOperationType = ref(""); 
 | 
const productOperationIndex = ref(""); 
 | 
const currentId = ref(""); 
 | 
const productFormData = reactive({ 
 | 
  productForm: { 
 | 
    productId: "", 
 | 
    productCategory: "", 
 | 
    productModelId: "", 
 | 
    specificationModel: "", 
 | 
    unit: "", 
 | 
    quantity: "", 
 | 
    taxInclusiveUnitPrice: "", 
 | 
    taxRate: "", 
 | 
    taxInclusiveTotalPrice: "", 
 | 
    taxExclusiveTotalPrice: "", 
 | 
    invoiceType: "", 
 | 
  }, 
 | 
  productRules: { 
 | 
    productId: [{ required: true, message: "请选择", trigger: "change" }], 
 | 
    productModelId: [{ 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 upload = reactive({ 
 | 
  // 上传的地址 
 | 
  url: import.meta.env.VITE_APP_BASE_API + "/file/upload", 
 | 
  // 设置上传的请求头部 
 | 
  headers: { Authorization: "Bearer " + getToken() }, 
 | 
}); 
 | 
  
 | 
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 formattedNumber = (row, column, cellValue) => { 
 | 
  return parseFloat(cellValue).toFixed(2); 
 | 
}; 
 | 
// 查询列表 
 | 
/** 搜索按钮操作 */ 
 | 
const handleQuery = () => { 
 | 
  page.current = 1; 
 | 
  getList(); 
 | 
}; 
 | 
// 子表合计方法 
 | 
const summarizeChildrenTable = (param) => { 
 | 
  return proxy.summarizeTable( 
 | 
    param, 
 | 
    [ 
 | 
      "taxInclusiveUnitPrice", 
 | 
      "taxInclusiveTotalPrice", 
 | 
      "taxExclusiveTotalPrice", 
 | 
      "ticketsNum", 
 | 
      "ticketsAmount", 
 | 
      "futureTickets", 
 | 
      "futureTicketsAmount", 
 | 
    ], 
 | 
    { 
 | 
      ticketsNum: { noDecimal: true }, // 不保留小数 
 | 
      futureTickets: { noDecimal: true }, // 不保留小数 
 | 
    } 
 | 
  ); 
 | 
}; 
 | 
const paginationChange = (obj) => { 
 | 
  page.current = obj.page; 
 | 
  page.size = obj.limit; 
 | 
  getList(); 
 | 
}; 
 | 
const getList = () => { 
 | 
  tableLoading.value = true; 
 | 
  const { entryDate, ...rest } = searchForm; 
 | 
  purchaseListPage({ ...rest, ...page }) 
 | 
    .then((res) => { 
 | 
      tableLoading.value = false; 
 | 
      tableData.value = res.data.records; 
 | 
      tableData.value.map((item) => { 
 | 
        item.children = []; 
 | 
      }); 
 | 
      total.value = res.data.total; 
 | 
      expandedRowKeys.value = []; 
 | 
    }) 
 | 
    .catch(() => { 
 | 
      tableLoading.value = false; 
 | 
    }); 
 | 
}; 
 | 
// 表格选择数据 
 | 
const handleSelectionChange = (selection) => { 
 | 
  selectedRows.value = selection; 
 | 
}; 
 | 
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: 2 }).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"]); 
 | 
}; 
 | 
// 子表合计方法 
 | 
const summarizeProTable = (param) => { 
 | 
  return proxy.summarizeTable(param, [ 
 | 
    "taxInclusiveUnitPrice", 
 | 
    "taxInclusiveTotalPrice", 
 | 
    "taxExclusiveTotalPrice", 
 | 
  ]); 
 | 
}; 
 | 
// 打开弹框 
 | 
const openForm = (type, row) => { 
 | 
  operationType.value = type; 
 | 
  form.value = {}; 
 | 
  productData.value = []; 
 | 
  fileList.value = []; 
 | 
  if (operationType.value == "add") { 
 | 
    createPurchaseNo().then((res) => { 
 | 
      form.value.purchaseContractNumber = res.data; 
 | 
    }); 
 | 
  } 
 | 
  userListNoPage().then((res) => { 
 | 
    userList.value = res.data; 
 | 
  }); 
 | 
  getSalesNo().then((res) => { 
 | 
    salesContractList.value = res; 
 | 
  }); 
 | 
  getOptions().then((res) => { 
 | 
    supplierList.value = res.data; 
 | 
  }); 
 | 
  form.value.recorderId = userStore.id; 
 | 
  form.value.entryDate = getCurrentDate(); 
 | 
  if (type === "edit") { 
 | 
    currentId.value = row.id; 
 | 
    getPurchaseById({ id: row.id, type: 2 }).then((res) => { 
 | 
      form.value = { ...res }; 
 | 
      productData.value = form.value.productData; 
 | 
      if (form.value.salesLedgerFiles) { 
 | 
        fileList.value = form.value.salesLedgerFiles; 
 | 
      } else { 
 | 
        fileList.value = []; 
 | 
      } 
 | 
    }); 
 | 
  } 
 | 
  dialogFormVisible.value = true; 
 | 
}; 
 | 
// 上传前校检 
 | 
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) { 
 | 
  console.log("handleRemove", file.id); 
 | 
  if (file.size > 1024 * 1024 * 10) {  
 | 
    // 仅前端清理,不调用删除接口和提示 
 | 
    return;  
 | 
  } 
 | 
  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) { 
 | 
      if (productData.value.length > 0) { 
 | 
        form.value.productData = proxy.HaveJson(productData.value); 
 | 
      } else { 
 | 
        proxy.$modal.msgWarning("请添加产品信息"); 
 | 
        return; 
 | 
      } 
 | 
      let tempFileIds = []; 
 | 
      if (fileList.value.length > 0) { 
 | 
        tempFileIds = fileList.value.map((item) => item.tempId); 
 | 
      } 
 | 
      form.value.tempFileIds = tempFileIds; 
 | 
      form.value.type = 2; 
 | 
      addOrEditPurchase(form.value).then((res) => { 
 | 
        proxy.$modal.msgSuccess("提交成功"); 
 | 
        closeDia(); 
 | 
        getList(); 
 | 
      }); 
 | 
    } 
 | 
  }); 
 | 
}; 
 | 
// 关闭弹框 
 | 
const closeDia = () => { 
 | 
  proxy.resetForm("formRef"); 
 | 
  dialogFormVisible.value = false; 
 | 
}; 
 | 
// 打开产品弹框 
 | 
const openProductForm = (type, row, index) => { 
 | 
  productOperationType.value = type; 
 | 
  productOperationIndex.value = index; 
 | 
  productForm.value = {}; 
 | 
  proxy.resetForm("productFormRef"); 
 | 
  if (type === "edit") { 
 | 
    productForm.value = { ...row }; 
 | 
  } 
 | 
  productFormVisible.value = true; 
 | 
  getProductOptions(); 
 | 
}; 
 | 
const getProductOptions = () => { 
 | 
  productTreeList().then((res) => { 
 | 
    productOptions.value = convertIdToValue(res); 
 | 
  }); 
 | 
}; 
 | 
const getModels = (value) => { 
 | 
  productForm.value.productCategory = findNodeById(productOptions.value, value); 
 | 
  modelList({ id: value }).then((res) => { 
 | 
    modelOptions.value = res; 
 | 
  }); 
 | 
}; 
 | 
const getProductModel = (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.label; // 在子节点中找到,返回该节点 
 | 
      } 
 | 
    } 
 | 
  } 
 | 
  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 submitProduct = () => { 
 | 
  proxy.$refs["productFormRef"].validate((valid) => { 
 | 
    if (valid) { 
 | 
      if (operationType.value === "edit") { 
 | 
        submitProductEdit(); 
 | 
      } else { 
 | 
        if (productOperationType.value === "add") { 
 | 
          productData.value.push({ ...productForm.value }); 
 | 
          console.log("productData.value---", productData.value); 
 | 
        } else { 
 | 
          productData.value[productOperationIndex.value] = { 
 | 
            ...productForm.value, 
 | 
          }; 
 | 
        } 
 | 
        closeProductDia(); 
 | 
      } 
 | 
    } 
 | 
  }); 
 | 
}; 
 | 
const submitProductEdit = () => { 
 | 
  productForm.value.salesLedgerId = currentId.value; 
 | 
  productForm.value.type = 2; 
 | 
  addOrUpdateSalesLedgerProduct(productForm.value).then((res) => { 
 | 
    proxy.$modal.msgSuccess("提交成功"); 
 | 
    closeProductDia(); 
 | 
    getPurchaseById({ id: currentId.value, type: 2 }).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: 2 }).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("/purchase/ledger/export", {}, "采购台账.xlsx"); 
 | 
    }) 
 | 
    .catch(() => { 
 | 
      proxy.$modal.msg("已取消"); 
 | 
    }); 
 | 
}; 
 | 
// 删除 
 | 
const handleDelete = () => { 
 | 
  let ids = []; 
 | 
  if (selectedRows.value.length > 0) { 
 | 
        // 检查是否有他人维护的数据 
 | 
        const unauthorizedData = selectedRows.value.filter(item => item.recorderName !== userStore.nickName); 
 | 
        if (unauthorizedData.length > 0) { 
 | 
            proxy.$modal.msgWarning("不可删除他人维护的数据"); 
 | 
            return; 
 | 
        } 
 | 
    ids = selectedRows.value.map((item) => item.id); 
 | 
  } else { 
 | 
    proxy.$modal.msgWarning("请选择数据"); 
 | 
    return; 
 | 
  } 
 | 
  ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", { 
 | 
    confirmButtonText: "确认", 
 | 
    cancelButtonText: "取消", 
 | 
    type: "warning", 
 | 
  }) 
 | 
    .then(() => { 
 | 
      delPurchase(ids).then((res) => { 
 | 
        proxy.$modal.msgSuccess("删除成功"); 
 | 
        getList(); 
 | 
      }); 
 | 
    }) 
 | 
    .catch(() => { 
 | 
      proxy.$modal.msg("已取消"); 
 | 
    }); 
 | 
}; 
 | 
// 获取当前日期并格式化为 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 mathNum = () => { 
 | 
    if (!productForm.value.taxRate) { 
 | 
        proxy.$modal.msgWarning("请先选择税率"); 
 | 
        return; 
 | 
    } 
 | 
  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 reverseMathNum = (field) => { 
 | 
    if (!productForm.value.taxRate) { 
 | 
        proxy.$modal.msgWarning("请先选择税率"); 
 | 
        return; 
 | 
    } 
 | 
  const taxRate = Number(productForm.value.taxRate); 
 | 
  if (!taxRate) return; 
 | 
  if (field === 'taxInclusiveTotalPrice') { 
 | 
    // 已知含税总价和数量,反算含税单价 
 | 
    if (productForm.value.quantity) { 
 | 
      productForm.value.taxInclusiveUnitPrice =  
 | 
        (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.quantity)).toFixed(2); 
 | 
    } 
 | 
    // 已知含税总价和含税单价,反算数量 
 | 
    else if (productForm.value.taxInclusiveUnitPrice) { 
 | 
      productForm.value.quantity =  
 | 
        (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.taxInclusiveUnitPrice)).toFixed(2); 
 | 
    } 
 | 
    // 反算不含税总价 
 | 
    productForm.value.taxExclusiveTotalPrice =  
 | 
      (Number(productForm.value.taxInclusiveTotalPrice) / (1 + taxRate / 100)).toFixed(2); 
 | 
  } else if (field === 'taxExclusiveTotalPrice') { 
 | 
    // 反算含税总价 
 | 
    productForm.value.taxInclusiveTotalPrice =  
 | 
      (Number(productForm.value.taxExclusiveTotalPrice) * (1 + taxRate / 100)).toFixed(2); 
 | 
    // 已知数量,反算含税单价 
 | 
    if (productForm.value.quantity) { 
 | 
      productForm.value.taxInclusiveUnitPrice =  
 | 
        (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.quantity)).toFixed(2); 
 | 
    } 
 | 
    // 已知含税单价,反算数量 
 | 
    else if (productForm.value.taxInclusiveUnitPrice) { 
 | 
      productForm.value.quantity =  
 | 
        (Number(productForm.value.taxInclusiveTotalPrice) / Number(productForm.value.taxInclusiveUnitPrice)).toFixed(2); 
 | 
    } 
 | 
  } 
 | 
}; 
 | 
// 销售合同选择改变方法 
 | 
const salesLedgerChange = async (row) => { 
 | 
  console.log("row", row); 
 | 
  var index = salesContractList.value.findIndex((item) => item.id == row); 
 | 
  console.log("index", index); 
 | 
  if (index > -1) { 
 | 
    form.value.projectName = salesContractList.value[index].projectName; 
 | 
    await querygProductInfoByContractNo(); 
 | 
  } 
 | 
}; 
 | 
  
 | 
const querygProductInfoByContractNo = async () => { 
 | 
  const { code, data } = await getProductInfoByContractNo({ 
 | 
    contractNo: form.value.salesLedgerId, 
 | 
  }); 
 | 
  if (code == 200) { 
 | 
    productData.value = data; 
 | 
  } 
 | 
}; 
 | 
  
 | 
// 显示二维码 
 | 
const showQRCode = async (row) => { 
 | 
  try { 
 | 
    // 构建二维码内容,只包含采购合同号(纯文本) 
 | 
    const qrContent = row.purchaseContractNumber || ''; 
 | 
    // 检查内容是否为空 
 | 
    if (!qrContent || qrContent.trim() === '') { 
 | 
      proxy.$modal.msgWarning("该行没有采购合同号,无法生成二维码"); 
 | 
      return; 
 | 
    } 
 | 
    qrCodeUrl.value = await QRCode.toDataURL(qrContent, { 
 | 
      width: 200, 
 | 
      margin: 2, 
 | 
      color: { 
 | 
        dark: '#000000', 
 | 
        light: '#FFFFFF' 
 | 
      } 
 | 
    }); 
 | 
    qrCodeDialogVisible.value = true; 
 | 
  } catch (error) { 
 | 
    console.error('生成二维码失败:', error); 
 | 
    proxy.$modal.msgError("生成二维码失败:" + error.message); 
 | 
  } 
 | 
}; 
 | 
  
 | 
// 下载二维码 
 | 
const downloadQRCode = () => { 
 | 
  if (!qrCodeUrl.value) { 
 | 
    proxy.$modal.msgWarning("二维码未生成"); 
 | 
    return; 
 | 
  } 
 | 
   
 | 
  const a = document.createElement('a'); 
 | 
  a.href = qrCodeUrl.value; 
 | 
  a.download = `采购合同号二维码_${new Date().getTime()}.png`; 
 | 
  document.body.appendChild(a); 
 | 
  a.click(); 
 | 
  document.body.removeChild(a); 
 | 
  proxy.$modal.msgSuccess("下载成功"); 
 | 
}; 
 | 
  
 | 
// 扫码新增对话框相关变量 
 | 
const scanAddDialogVisible = ref(false); 
 | 
const scanAddForm = reactive({ 
 | 
  scanContent: "", 
 | 
  purchaseContractNumber: "", 
 | 
  supplierName: "", 
 | 
  projectName: "", 
 | 
  contractAmount: "", 
 | 
  paymentMethod: "", 
 | 
  recorderName: "", 
 | 
  scanRemark: "", 
 | 
}); 
 | 
const scanAddRules = { 
 | 
  purchaseContractNumber: [{ required: true, message: "请输入采购合同号", trigger: "blur" }], 
 | 
  supplierName: [{ required: true, message: "请输入供应商名称", trigger: "blur" }], 
 | 
  projectName: [{ required: true, message: "请输入项目名称", trigger: "blur" }], 
 | 
}; 
 | 
  
 | 
// 扫码登记对话框相关变量 
 | 
const scanDialogVisible = ref(false); 
 | 
const scanForm = reactive({ 
 | 
  purchaseContractNumber: "", 
 | 
  supplierName: "", 
 | 
  projectName: "", 
 | 
  scanTime: "", 
 | 
  scannerName: "", 
 | 
  scanStatus: "未扫码", 
 | 
  scanRemark: "", 
 | 
}); 
 | 
const scanRules = { 
 | 
  scanRemark: [{ required: true, message: "请输入扫码备注", trigger: "blur" }], 
 | 
}; 
 | 
const scanRecords = ref([]); 
 | 
  
 | 
// 打开扫码新增对话框 
 | 
const openScanAddDialog = () => { 
 | 
  scanAddForm.scanContent = ""; 
 | 
  scanAddForm.purchaseContractNumber = ""; 
 | 
  scanAddForm.supplierName = ""; 
 | 
  scanAddForm.projectName = ""; 
 | 
  scanAddForm.contractAmount = ""; 
 | 
  scanAddForm.paymentMethod = ""; 
 | 
  scanAddForm.recorderName = userStore.nickName; 
 | 
  scanAddForm.scanRemark = ""; 
 | 
  scanAddDialogVisible.value = true; 
 | 
}; 
 | 
  
 | 
// 解析扫码内容(模拟解析二维码数据) 
 | 
const parseScanContent = (content) => { 
 | 
  if (!content) return; 
 | 
   
 | 
  // 模拟解析二维码内容,这里可以根据实际需求调整解析逻辑 
 | 
  // 假设扫码内容格式为:合同号|供应商|项目|金额|付款方式 
 | 
  const parts = content.split('|'); 
 | 
  if (parts.length >= 3) { 
 | 
    scanAddForm.purchaseContractNumber = parts[0] || ""; 
 | 
    scanAddForm.supplierName = parts[1] || ""; 
 | 
    scanAddForm.projectName = parts[2] || ""; 
 | 
    scanAddForm.contractAmount = parts[3] || ""; 
 | 
    scanAddForm.paymentMethod = parts[4] || ""; 
 | 
  } 
 | 
}; 
 | 
  
 | 
// 关闭扫码新增对话框 
 | 
const closeScanAddDialog = () => { 
 | 
  scanAddDialogVisible.value = false; 
 | 
  proxy.resetForm("scanAddFormRef"); 
 | 
}; 
 | 
  
 | 
// 提交扫码新增 
 | 
const submitScanAdd = () => { 
 | 
  proxy.$refs["scanAddFormRef"].validate((valid) => { 
 | 
    if (valid) { 
 | 
      // 构建新增数据 
 | 
      const newData = { 
 | 
        purchaseContractNumber: scanAddForm.purchaseContractNumber, 
 | 
        supplierName: scanAddForm.supplierName, 
 | 
        projectName: scanAddForm.projectName, 
 | 
        contractAmount: scanAddForm.contractAmount, 
 | 
        paymentMethod: scanAddForm.paymentMethod, 
 | 
        recorderName: scanAddForm.recorderName, 
 | 
        entryDate: getCurrentDate(), 
 | 
        remark: scanAddForm.scanRemark, 
 | 
        type: 2 
 | 
      }; 
 | 
       
 | 
      // 模拟新增成功 
 | 
      proxy.$modal.msgSuccess("扫码新增成功!"); 
 | 
      closeScanAddDialog(); 
 | 
       
 | 
      // 可以选择是否刷新列表 
 | 
      // getList(); 
 | 
    } 
 | 
  }); 
 | 
}; 
 | 
  
 | 
// 打开扫码登记对话框 
 | 
const openScanDialog = (row) => { 
 | 
  scanForm.purchaseContractNumber = row.purchaseContractNumber; 
 | 
  scanForm.supplierName = row.supplierName; 
 | 
  scanForm.projectName = row.projectName; 
 | 
  scanForm.scanTime = getCurrentDateTime(); 
 | 
  scanForm.scannerName = userStore.nickName; 
 | 
  scanForm.scanStatus = "未扫码"; 
 | 
  scanForm.scanRemark = ""; 
 | 
  scanRecords.value = []; 
 | 
  scanDialogVisible.value = true; 
 | 
}; 
 | 
  
 | 
// 关闭扫码登记对话框 
 | 
const closeScanDialog = () => { 
 | 
  scanDialogVisible.value = false; 
 | 
  proxy.resetForm("scanFormRef"); 
 | 
}; 
 | 
  
 | 
// 提交扫码登记 
 | 
const submitScan = () => { 
 | 
  proxy.$refs["scanFormRef"].validate((valid) => { 
 | 
    if (valid) { 
 | 
      // 添加扫码记录 
 | 
      scanRecords.value.push({ 
 | 
        ...scanForm, 
 | 
        id: Date.now(), // 模拟ID 
 | 
        scanTime: getCurrentDateTime(), 
 | 
      }); 
 | 
      scanForm.scanStatus = "已扫码"; 
 | 
      scanForm.scanRemark = scanForm.scanRemark || "无"; 
 | 
      proxy.$modal.msgSuccess("扫码登记成功!"); 
 | 
      closeScanDialog(); 
 | 
    } 
 | 
  }); 
 | 
}; 
 | 
  
 | 
// 获取当前日期时间 
 | 
function getCurrentDateTime() { 
 | 
  const now = new Date(); 
 | 
  const year = now.getFullYear(); 
 | 
  const month = String(now.getMonth() + 1).padStart(2, "0"); 
 | 
  const day = String(now.getDate()).padStart(2, "0"); 
 | 
  const hours = String(now.getHours()).padStart(2, "0"); 
 | 
  const minutes = String(now.getMinutes()).padStart(2, "0"); 
 | 
  const seconds = String(now.getSeconds()).padStart(2, "0"); 
 | 
  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`; 
 | 
} 
 | 
  
 | 
  
 | 
  
 | 
onMounted(() => { 
 | 
  getList(); 
 | 
}); 
 | 
</script> 
 | 
  
 | 
<style scoped lang="scss"></style> 
 |