<template>
  <div class="contract-list">
    <!-- 筛选区和按钮操作区合并 -->
    <div class="filter-section" style="padding: 10px; border-bottom: 1px solid #e4e7ed;">
      <div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px;">
        <div style="display: flex; align-items: center; gap: 4px; flex-wrap: wrap;">
          <el-input v-model="queryParams.keyword" placeholder="请输入关键字" clearable
            @keyup.enter.native="handleQuery" style="width: 160px;" />
          <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">筛选</el-button>
          <el-button icon="el-icon-sort" size="mini" @click="toggleMoreFilter"
            :type="showMoreFilter ? 'primary' : 'default'">
          </el-button>
          <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="$emit('add')"></el-button>
        </div>
        <div style="font-size: 12px; color: #909399;">
          共 <span style="color: #409eff; font-weight: bold;">{{ total }}</span> 条记录
        </div>
      </div>

      <!-- 日期范围筛选行 -->
      <div style="display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 4px;">
        <div style="display: flex; align-items: center; gap: 4px; font-size: 13px; color: #606266;">
          <span style="white-space: nowrap;">签订日期：</span>
          <el-date-picker clearable v-model="queryParams.signDateStart" type="date" value-format="yyyy-MM-dd"
            placeholder="签订日期开始" style="width: 180px;" />
          <span>~</span>
          <el-date-picker clearable v-model="queryParams.signDateEnd" type="date" value-format="yyyy-MM-dd"
            placeholder="签订日期结束" style="width: 180px;" />
        </div>
        <div style="display: flex; align-items: center; gap: 4px; font-size: 13px; color: #606266;">
          <span style="white-space: nowrap;">交货日期：</span>
          <el-date-picker clearable v-model="queryParams.deliveryDateStart" type="date" value-format="yyyy-MM-dd"
            placeholder="交货开始日期" style="width: 180px;" />
          <span>~</span>
          <el-date-picker clearable v-model="queryParams.deliveryDateEnd" type="date" value-format="yyyy-MM-dd"
            placeholder="交货结束日期" style="width: 180px;" />
        </div>
      </div>

      <!-- 更多筛选条件 -->
      <div v-show="showMoreFilter" class="more-filter"
        style="margin-top: 8px; padding-top: 10px; border-top: 1px dashed #e4e7ed;">
        <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" label-width="80px">
          <el-form-item label="合同名称" prop="contractName">
            <el-input v-model="queryParams.contractName" placeholder="请输入合同名称" clearable
              @keyup.enter.native="handleQuery" />
          </el-form-item>
          <el-form-item label="销售员" prop="salesman">
            <el-input v-model="queryParams.salesman" placeholder="请输入销售员" clearable
              @keyup.enter.native="handleQuery" />
          </el-form-item>
          <el-form-item label="合同编号" prop="contractCode">
            <el-input v-model="queryParams.contractCode" placeholder="请输入合同编号" clearable
              @keyup.enter.native="handleQuery" />
          </el-form-item>
          <el-form-item label="供方" prop="supplier">
            <el-input v-model="queryParams.supplier" placeholder="请输入供方" clearable @keyup.enter.native="handleQuery" />
          </el-form-item>
          <el-form-item label="需方" prop="customer">
            <el-input v-model="queryParams.customer" placeholder="请输入需方" clearable @keyup.enter.native="handleQuery" />
          </el-form-item>
          <el-form-item label="签订地点" prop="signLocation">
            <el-input v-model="queryParams.signLocation" placeholder="请输入签订地点" clearable
              @keyup.enter.native="handleQuery" />
          </el-form-item>
          <el-form-item label="合同状态" prop="status">
            <el-select v-model="queryParams.status" placeholder="请选择合同状态">
              <el-option label="草稿" value="0" />
              <el-option label="已生效" value="1" />
              <el-option label="已作废" value="2" />
              <el-option label="已完成" value="3" />
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-form>
      </div>
    </div>

    <div class="custom-list" v-loading="loading">
      <div class="list-body">
        <div v-for="row in contractList" :key="row.contractId" class="list-item"
        style="padding: 10px; border-bottom: 2px solid #dddddd; cursor: pointer;"
        :class="{ 'list-item-active': selectedRow === row, 'list-item-top': row.isTop }" @click="handleRowClick(row)">
        <!-- 合同名称和编号 -->
        <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
          <div style="display: flex; align-items: center; gap: 8px;">
            <el-tag v-if="row.isTop" type="warning" size="mini" effect="dark">置顶</el-tag>
            <div style="font-weight: bold;">{{ row.contractName }}</div>
          </div>
          <div style="font-size: 12px; color: #606266;">{{ row.contractCode }}</div>
        </div>

          <!-- 供方和需方 -->
          <div style="font-size: 12px; color: #909399; margin-bottom: 6px;">
            <span>供方: {{ row.supplier }}</span>
            <span style="margin-left: 20px;">需方: {{ row.customer }}</span>
          </div>

          <!-- 签订时间和交货日期 -->
          <div style="font-size: 12px; color: #909399; margin-bottom: 6px;">
            <span>签订时间: {{ parseTime(row.signTime, '{y}-{m}-{d}') }}</span>
            <span style="margin-left: 20px;">交货日期: {{ parseTime(row.deliveryDate, '{y}-{m}-{d}') }}</span>
          </div>

          <!-- 签订地点和状态 -->
          <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
            <div style="font-size: 12px; color: #909399;">
              签订地点: {{ row.signLocation }}
            </div>
            <el-tag
              :type="row.status == 0 ? 'info' : row.status == 1 ? 'success' : row.status == 2 ? 'danger' : 'primary'"
              size="small">
              {{ row.status == 0 ? '草稿' : row.status == 1 ? '已生效' : row.status == 2 ? '已作废' : '已完成' }}
            </el-tag>
          </div>

          <!-- 操作按钮独占一行 -->
        <div style="display: flex; gap: 10px; padding-top: 8px; border-top: 1px dashed #f0f0f0;">
          <el-button size="mini" type="text" :icon="row.isTop ? 'el-icon-top' : 'el-icon-s-operation'" @click.stop="handleToggleTop(row)">{{ row.isTop ? '取消置顶' : '置顶' }}</el-button>
          <el-button size="mini" type="text" icon="el-icon-document" @click.stop="$emit('detailEdit', row)">详情编辑</el-button>
          <el-button size="mini" type="text" icon="el-icon-download" @click.stop="handleExport(row)">导出</el-button>
          <el-button size="mini" type="text" icon="el-icon-edit" @click.stop="$emit('update', row)">修改</el-button>
          <el-button size="mini" type="text" icon="el-icon-delete" @click.stop="$emit('delete', row)">删除</el-button>
        </div>
        </div>
        <div v-if="contractList.length === 0" style="padding: 40px; text-align: center; color: #909399;">
          暂无合同数据
        </div>
      </div>
    </div>

    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
      @pagination="getList" style="padding: 10px; margin-bottom: 10px !important;" />

    <!-- 导出预览对话框 -->
    <el-dialog title="导出预览" :visible.sync="exportDialogVisible" width="95%" top="20px" append-to-body
      :close-on-click-modal="false" @open="generatePreviewHtml">
      <div style="display: flex; gap: 16px; height: calc(100vh - 200px);">
        <!-- 左侧：列配置 -->
        <div style="width: 200px; flex-shrink: 0; border: 1px solid #e4e7ed; border-radius: 4px; padding: 12px; overflow-y: auto;">
          <div style="font-weight: bold; margin-bottom: 10px; font-size: 14px;">产品表列配置</div>
          <el-checkbox v-model="selectAllColumns" :indeterminate="columnIndeterminate" @change="handleSelectAllColumns"
            style="margin-bottom: 8px;">全选</el-checkbox>
          <div v-for="col in columnConfigs" :key="col.key" style="margin-bottom: 6px;">
            <el-checkbox v-model="col.checked" @change="onColumnChange">{{ col.label }}</el-checkbox>
          </div>
          <el-divider />
          <div style="font-size: 12px; color: #909399;">勾选的列将显示在导出的产品表中</div>
        </div>
        <!-- 右侧：预览 -->
        <div style="flex: 1; border: 1px solid #e4e7ed; border-radius: 4px; overflow: hidden; background: #f0f0f0;">
          <iframe ref="previewFrame" style="width: 100%; height: 100%; border: none; background: #fff;"></iframe>
        </div>
      </div>
      <span slot="footer">
        <el-button @click="exportDialogVisible = false">取 消</el-button>
        <el-button type="primary" :loading="exportLoading" @click="confirmExport">确认导出</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { listOrder, updateOrder } from "@/api/crm/order";
import html2canvas from 'html2canvas';
import jsPDF from 'jspdf';
import contractLogo from '@/assets/images/contractLogo.png';
import {
  parseProductContent,
  convertToChinese
} from '@/utils/productContent';

export default {
  name: "ContractList",
  dicts: ['wip_pack_saleman'],
  data() {
    return {
      // 合同信息表格数据
      contractList: [],
      // 遮罩层
      loading: false,
      // 总条数
      total: 0,
      // 选中的行
      selectedRow: null,
      // 是否显示更多筛选
      showMoreFilter: false,
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 10,
        contractName: undefined,
        contractCode: undefined,
        supplier: undefined,
        customer: undefined,
        signDateStart: undefined,
        signDateEnd: undefined,
        deliveryDateStart: undefined,
        deliveryDateEnd: undefined,
        signLocation: undefined,
        status: undefined,
      },
      // 导出预览
      exportDialogVisible: false,
      exportLoading: false,
      exportRow: null,
      selectAllColumns: true,
      columnIndeterminate: false,
      columnConfigs: [
        { key: 'spec', label: '规格（mm）', checked: true },
        { key: 'material', label: '材质', checked: true },
        { key: 'quantity', label: '数量（吨）', checked: true },
        { key: 'taxPrice', label: '含税单价（元/吨）', checked: true },
        { key: 'taxDivisor', label: '税率除数', checked: true },
        { key: 'noTaxPrice', label: '无税单价（元/吨）', checked: true },
        { key: 'taxTotal', label: '含税总额（元）', checked: true },
        { key: 'noTaxTotal', label: '无税总额（元）', checked: true },
        { key: 'taxAmount', label: '税额（元）', checked: true },
        { key: 'remark', label: '备注', checked: true },
      ],
    };
  },
  created() {
    this.getList();
  },
  methods: {
    /** 查询合同信息列表 */
    getList() {
      this.loading = true;
      listOrder(this.queryParams).then(response => {
        this.contractList = response.rows;
        this.total = response.total;
        this.loading = false;
      });
    },
    /** 切换置顶状态 */
    handleToggleTop(row) {
      const newTopStatus = row.isTop ? 0 : 1;
      updateOrder({ ...row, isTop: newTopStatus }).then(response => {
        this.$message({
          message: newTopStatus ? "置顶成功" : "取消置顶成功",
          type: "success"
        });
        this.getList();
      })
    },
    /** 状态变更 */
    handleChangeStatus(row) {
      updateOrder(row).then(response => {
        this.$message({
          message: "状态变更成功",
          type: "success"
        });
        this.getList();
      })
    },
    /** 搜索按钮操作 */
    handleQuery() {
      this.queryParams.pageNum = 1;
      this.getList();
    },
    /** 重置按钮操作 */
    resetQuery() {
      this.$refs["queryForm"].resetFields();
      this.queryParams.signDateStart = undefined;
      this.queryParams.signDateEnd = undefined;
      this.queryParams.deliveryDateStart = undefined;
      this.queryParams.deliveryDateEnd = undefined;
      this.handleQuery();
    },

    // 行点击事件
    handleRowClick(row) {
      this.selectedRow = row;
      this.$emit('rowClick', row);
    },
    // 切换更多筛选显示/隐藏
    toggleMoreFilter() {
      this.showMoreFilter = !this.showMoreFilter;
    },
    /** 导出合同 - 打开预览对话框 */
    handleExport(row) {
      this.exportRow = row;
      this.exportDialogVisible = true;
    },
    /** 全选/取消全选 */
    handleSelectAllColumns(val) {
      this.columnConfigs.forEach(col => { col.checked = val; });
      this.columnIndeterminate = false;
      this.generatePreviewHtml();
    },
    /** 单个列勾选变化 */
    onColumnChange() {
      const checkedCount = this.columnConfigs.filter(c => c.checked).length;
      this.selectAllColumns = checkedCount === this.columnConfigs.length;
      this.columnIndeterminate = checkedCount > 0 && checkedCount < this.columnConfigs.length;
      this.generatePreviewHtml();
    },
    /** 根据列配置生成产品表HTMl */
    buildProductTableHtml(productData, products) {
      const activeCols = this.columnConfigs.filter(c => c.checked);
      const hasCol = (key) => activeCols.some(c => c.key === key);

      // 表头
      let headerCells = '<th style="border:1px solid #000;padding:4px 4px;font-weight:bold;width:30px;">序号</th>';
      if (hasCol('spec')) headerCells += '<th style="border:1px solid #000;padding:4px 4px;font-weight:bold;width:80px;">规格(mm)</th>';
      if (hasCol('material')) headerCells += '<th style="border:1px solid #000;padding:4px 4px;font-weight:bold;width:60px;">材质</th>';
      if (hasCol('quantity')) headerCells += '<th style="border:1px solid #000;padding:4px 4px;font-weight:bold;width:55px;">数量(吨)</th>';
      if (hasCol('taxPrice')) headerCells += '<th style="border:1px solid #000;padding:4px 4px;font-weight:bold;width:70px;">含税单价(元/吨)</th>';
      if (hasCol('taxDivisor')) headerCells += '<th style="border:1px solid #000;padding:4px 4px;font-weight:bold;width:45px;">税率除数</th>';
      if (hasCol('noTaxPrice')) headerCells += '<th style="border:1px solid #000;padding:4px 4px;font-weight:bold;width:70px;">无税单价(元/吨)</th>';
      if (hasCol('taxTotal')) headerCells += '<th style="border:1px solid #000;padding:4px 4px;font-weight:bold;width:70px;">含税总额(元)</th>';
      if (hasCol('noTaxTotal')) headerCells += '<th style="border:1px solid #000;padding:4px 4px;font-weight:bold;width:70px;">无税总额(元)</th>';
      if (hasCol('taxAmount')) headerCells += '<th style="border:1px solid #000;padding:4px 4px;font-weight:bold;width:55px;">税额(元)</th>';
      if (hasCol('remark')) headerCells += '<th style="border:1px solid #000;padding:4px 4px;font-weight:bold;width:80px;">备注</th>';
      const colCount = activeCols.length + 1; // +1 for 序号

      // 数据行
      let bodyRows = '';
      products.forEach((product, index) => {
        let cells = `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${index + 1}</td>`;
        if (hasCol('spec')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${product.spec || ''}</td>`;
        if (hasCol('material')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${product.material || ''}</td>`;
        if (hasCol('quantity')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${product.quantity || ''}</td>`;
        if (hasCol('taxPrice')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${product.taxPrice || ''}</td>`;
        if (hasCol('taxDivisor')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${product.taxDivisor || '1.13'}</td>`;
        if (hasCol('noTaxPrice')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.noTaxPrice || 0).toFixed(3)}</td>`;
        if (hasCol('taxTotal')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.taxTotal || 0).toFixed(3)}</td>`;
        if (hasCol('noTaxTotal')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.noTaxTotal || 0).toFixed(3)}</td>`;
        if (hasCol('taxAmount')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${(product.taxAmount || 0).toFixed(3)}</td>`;
        if (hasCol('remark')) cells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;max-width:100px;word-wrap:break-word;">${product.remark || ''}</td>`;
        bodyRows += `<tr>${cells}</tr>`;
      });

      // 合计行
      const totalQty = products.reduce((a, p) => a + (parseFloat(p.quantity) || 0), 0);
      const totalTax = products.reduce((a, p) => a + (parseFloat(p.taxTotal) || 0), 0);
      const totalNoTax = products.reduce((a, p) => a + (parseFloat(p.noTaxTotal) || 0), 0);
      const totalTaxAmt = products.reduce((a, p) => a + (parseFloat(p.taxAmount) || 0), 0);
      const totalAmountInWords = productData.totalAmountInWords || convertToChinese(totalTax) || '零元整';

      // 合计行单元格（按列顺序填充）
      let totalCells = '';
      let cellIdx = 0;
      activeCols.forEach((col) => {
        if (cellIdx < 2) {
          // 前 2 个活动列（spec、material）与序号一起被"合计" colspan=3 覆盖
          if (cellIdx === 0) {
            totalCells += `<td colspan="3" style="border:1px solid #000;padding:4px 4px;font-weight:bold;text-align:center;">合&nbsp;&nbsp;计</td>`;
          }
        } else {
          let val = '';
          if (col.key === 'quantity') val = totalQty.toFixed(3);
          else if (col.key === 'taxTotal') val = totalTax.toFixed(3);
          else if (col.key === 'noTaxTotal') val = totalNoTax.toFixed(3);
          else if (col.key === 'taxAmount') val = totalTaxAmt.toFixed(3);
          totalCells += `<td style="border:1px solid #000;padding:3px 4px;text-align:center;">${val}</td>`;
        }
        cellIdx++;
      });

      const html = `
        <table style="width:100%;border-collapse:collapse;font-size:11px;margin-bottom:6px;">
          <tr>
            <td colspan="4" style="border:1px solid #000;padding:3px 6px;font-weight:bold;text-align:left;">产品名称：${productData.productName || ''}</td>
            <td colspan="${colCount - 4 > 0 ? colCount - 4 : 1}" style="border:1px solid #000;padding:3px 6px;font-weight:bold;text-align:left;">生产厂家：嘉祥科伦普重工有限公司</td>
          </tr>
          <tr>${headerCells}</tr>
          ${bodyRows}
          <tr>${totalCells}</tr>
          <tr>
            <td colspan="${colCount}" style="border:1px solid #000;padding:4px 6px;font-weight:bold;text-align:left;">合计人民币（大写）：${totalAmountInWords}</td>
          </tr>
          ${productData.remark ? `<tr><td colspan="${colCount}" style="border:1px solid #000;padding:4px 6px;text-align:left;">备注：${productData.remark}</td></tr>` : ''}
        </table>`;
      return html;
    },
    /** 生成预览HTML并更新iframe */
    generatePreviewHtml() {
      const row = this.exportRow;
      if (!row) return;

      let productData = parseProductContent(row.productContent);
      if (!productData.productName && row.productName) {
        productData.productName = row.productName;
      }
      const products = productData.products && productData.products.length > 0 ? productData.products : [];

      const productTableHtml = this.buildProductTableHtml(productData, products);

      // 解析合同内容
      let contractContentHtml = '';
      if (row.contractContent) {
        let htmlContent = row.contractContent;
        const pTagRegex = /<p[^>]*>([\s\S]*?)<\/p>/g;
        let match;
        const pContents = [];
        while ((match = pTagRegex.exec(htmlContent)) !== null) {
          let content = match[1].replace(/<[^>]*>/g, '').replace(/&nbsp;/g, ' ').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&').replace(/&quot;/g, '"').replace(/&#39;/g, "'").trim();
          if (content) {
            const chineseNumberRegex = /^[一二三四五六七八九十]+、/;
            pContents.push(chineseNumberRegex.test(content) ? content : '　' + content);
          }
        }
        if (pContents.length === 0) {
          const textContent = htmlContent.replace(/<[^>]*>/g, '').replace(/&nbsp;/g, ' ').trim();
          if (textContent) pContents.push(textContent);
        }
        if (pContents.length > 0) {
          contractContentHtml = '<div style="margin-top:8px;font-size:12px;line-height:1.8;">' + pContents.join('<br/>') + '</div>';
        }
      }

      const totalTax = products.reduce((a, p) => a + (parseFloat(p.taxTotal) || 0), 0);
      const amountWords = productData.totalAmountInWords || convertToChinese(totalTax) || '零元整';

      const fullHtml = `
<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>合同预览</title>
<style>
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body { font-family: 'SimSun','宋体',serif; color: #000; background: #e8e8e8; font-size: 12px; line-height: 1.6; display: flex; flex-direction: column; align-items: center; padding: 20px 0; }
  .a4-page { width: 794px; min-height: 1123px; padding: 30px 40px; background: #fff; margin-bottom: 20px; box-shadow: 0 2px 12px rgba(0,0,0,0.15); }
  .company-header { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: 6px; }
  .contract-title { text-align: center; font-size: 20px; font-weight: bold; letter-spacing: 6px; margin-bottom: 14px; }
  .info-row { display: flex; justify-content: space-between; margin-bottom: 4px; font-size: 13px; line-height: 2; }
  .section-title { font-size: 13px; font-weight: bold; margin-bottom: 4px; margin-top: 8px; }
  table { width: 100%; border-collapse: collapse; }
  th, td { border: 1px solid #000; padding: 3px 4px; text-align: center; font-size: 11px; }
  th { font-weight: bold; }
  .sign-section { margin-top: 24px; font-size: 12px; line-height: 2.2; }
  .sign-section .col { width: 48%; }
  .sign-row { display: flex; justify-content: space-between; }
</style>
</head>
<body>
  <div class="a4-page" style="position:relative;">
  <img src="${contractLogo}" style="position:absolute;left:40px;top:40px;height:80px;" crossorigin="anonymous" />
  <div style="text-align:center;padding-top:10px;">
    <div style="font-size:20px;font-weight:bold;letter-spacing:2px;">嘉祥科伦普重工有限公司</div>
  </div>
   <div style="position:relative;margin:12px 0 8px 0;text-align:center;">
    <div style="font-size:22px;font-weight:bold;letter-spacing:6px;">产 品 销 售 合 同</div>
    <div style="position:absolute;right:0;top:50%;transform:translateY(-50%);font-size:11px;">合同编号：${row.contractCode || ''}</div>
  </div>
  <div class="info-row">
    <div style="width:55%;">
      <div>供方（甲方）：${row.supplier || ''}</div>
      <div>需方（乙方）：${row.customer || ''}</div>
    </div>
    <div style="width:40%;">
      <div>签订时间：${row.signTime ? this.parseTime(row.signTime, '{y}年{m}月{d}日') : ''}</div>
      <div>签订地点：${row.signLocation || ''}</div>
    </div>
  </div>
  <div class="section-title">一、产品内容</div>
  ${productTableHtml}
  ${contractContentHtml}
  <div class="sign-section">
    <div class="sign-row">
      <div class="col">
        <div>供方（甲方）：${row.supplier || ''}</div>
        <div>地址：${row.supplierAddress || ''}</div>
        <div>电话：${row.supplierPhone || ''}</div>
        <div>开户行：${row.supplierBank || ''}</div>
        <div>账号：${row.supplierAccount || ''}</div>
        <div>税号：${row.supplierTaxNo || ''}</div>
      </div>
      <div class="col">
        <div>需方（乙方）：${row.customer || ''}</div>
        <div>地址：${row.customerAddress || ''}</div>
        <div>电话：${row.customerPhone || ''}</div>
        <div>开户行：${row.customerBank || ''}</div>
        <div>账号：${row.customerAccount || ''}</div>
        <div>税号：${row.customerTaxNo || ''}</div>
      </div>
    </div>
  </div>
</div>
</body>
</html>`;

      this.$nextTick(() => {
        const iframe = this.$refs.previewFrame;
        if (iframe) {
          iframe.srcdoc = fullHtml;
        }
      });
    },
    /** 确认导出PDF */
    async confirmExport() {
      const row = this.exportRow;
      if (!row) return;

      this.exportLoading = true;
      const loading = this.$loading({
        lock: true,
        text: '正在生成PDF，请稍候...',
        background: 'rgba(0, 0, 0, 0.7)'
      });

      try {
        let productData = parseProductContent(row.productContent);
        if (!productData.productName && row.productName) {
          productData.productName = row.productName;
        }
        const products = productData.products && productData.products.length > 0 ? productData.products : [];

        const productTableHtml = this.buildProductTableHtml(productData, products);

        // 解析合同内容
        let contractContentHtml = '';
        if (row.contractContent) {
          let htmlContent = row.contractContent;
          const pTagRegex = /<p[^>]*>([\s\S]*?)<\/p>/g;
          let match;
          const pContents = [];
          while ((match = pTagRegex.exec(htmlContent)) !== null) {
            let content = match[1].replace(/<[^>]*>/g, '').replace(/&nbsp;/g, ' ').replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&').replace(/&quot;/g, '"').replace(/&#39;/g, "'").trim();
            if (content) {
              const chineseNumberRegex = /^[一二三四五六七八九十]+、/;
              pContents.push(chineseNumberRegex.test(content) ? content : '　' + content);
            }
          }
          if (pContents.length === 0) {
            const textContent = htmlContent.replace(/<[^>]*>/g, '').replace(/&nbsp;/g, ' ').trim();
            if (textContent) pContents.push(textContent);
          }
          if (pContents.length > 0) {
            contractContentHtml = '<div style="margin-top:10px;font-size:12px;line-height:1.8;">' + pContents.join('<br/>') + '</div>';
          }
        }

        const totalTax = products.reduce((a, p) => a + (parseFloat(p.taxTotal) || 0), 0);
        const amountWords = productData.totalAmountInWords || convertToChinese(totalTax) || '零元整';

        // 构建完整的合同HTML（794px 宽，适合A4）
        const contractHtml = `
          <div id="contract-pdf-content" style="width:794px;padding:30px 40px;font-family:'SimSun','宋体',serif;color:#000;background:#fff;box-sizing:border-box;position:relative;">
<img src="${contractLogo}" style="position:absolute;left:20px;top:20px;height:80px;" crossorigin="anonymous" />
            <div style="text-align:center;padding-top:10px;">
              <div style="font-size:20px;font-weight:bold;letter-spacing:2px;">嘉祥科伦普重工有限公司</div>
            </div>
            <div style="position:relative;margin:12px 0 8px 0;text-align:center;">
              <div style="font-size:22px;font-weight:bold;letter-spacing:6px;">产 品 销 售 合 同</div>
              <div style="position:absolute;right:0;top:50%;transform:translateY(-50%);font-size:11px;">合同编号：${row.contractCode || ''}</div>
            </div>
            <div style="display:flex;justify-content:space-between;margin-bottom:8px;font-size:13px;line-height:2;">
              <div style="width:55%;">
                <div>供方（甲方）：${row.supplier || ''}</div>
                <div>需方（乙方）：${row.customer || ''}</div>
              </div>
              <div style="width:40%;text-align:left;">
                <div>签订时间：${row.signTime ? this.parseTime(row.signTime, '{y}年{m}月{d}日') : ''}</div>
                <div>签订地点：${row.signLocation || ''}</div>
              </div>
            </div>
            <div style="font-size:13px;font-weight:bold;margin-bottom:5px;">一、产品内容</div>
            ${productTableHtml}
            ${contractContentHtml}
            <div style="margin-top:40px;font-size:12px;line-height:2.2;">
              <div style="display:flex;justify-content:space-between;">
                <div style="width:48%;">
                  <div>供方（甲方）：${row.supplier || ''}</div>
                  <div>地址：${row.supplierAddress || ''}</div>
                  <div>电话：${row.supplierPhone || ''}</div>
                  <div>开户行：${row.supplierBank || ''}</div>
                  <div>账号：${row.supplierAccount || ''}</div>
                  <div>税号：${row.supplierTaxNo || ''}</div>
                </div>
                <div style="width:48%;">
                  <div>需方（乙方）：${row.customer || ''}</div>
                  <div>地址：${row.customerAddress || ''}</div>
                  <div>电话：${row.customerPhone || ''}</div>
                  <div>开户行：${row.customerBank || ''}</div>
                  <div>账号：${row.customerAccount || ''}</div>
                  <div>税号：${row.customerTaxNo || ''}</div>
                </div>
              </div>
            </div>
          </div>
        `;

        const container = document.createElement('div');
        container.style.position = 'fixed';
        container.style.left = '-9999px';
        container.style.top = '0';
        container.innerHTML = contractHtml;
        document.body.appendChild(container);

        const element = document.getElementById('contract-pdf-content');
        await new Promise(resolve => setTimeout(resolve, 500));

        const canvas = await html2canvas(element, {
          scale: 2,
          useCORS: true,
          allowTaint: true,
          logging: false,
          backgroundColor: '#ffffff',
          imageTimeout: 5000
        });

        document.body.removeChild(container);

        const pdf = new jsPDF('p', 'mm', 'a4');
        const pdfWidth = 210;
        const pdfHeight = 297;
        const margin = 5;
        const contentWidth = pdfWidth - margin * 2;
        const contentHeight = pdfHeight - margin * 2;
        const scale = contentWidth / canvas.width;

        function isBlankRow(canvas, y) {
          const ctx = canvas.getContext('2d');
          const row = ctx.getImageData(0, y, canvas.width, 1).data;
          let whiteCount = 0;
          const total = row.length / 4;
          for (let i = 0; i < row.length; i += 4) {
            if (row[i] > 250 && row[i + 1] > 250 && row[i + 2] > 250) whiteCount++;
          }
          return whiteCount / total >= 0.95;
        }

        function findBreakY(canvas, targetY, range) {
          range = range || 40;
          for (let offset = 0; offset < range; offset++) {
            if (targetY + offset < canvas.height && isBlankRow(canvas, targetY + offset)) return targetY + offset;
            if (targetY - offset > 0 && isBlankRow(canvas, targetY - offset)) return targetY - offset;
          }
          return targetY;
        }

        let currentY = 0;
        let firstPage = true;

        while (currentY < canvas.height) {
          const pageHeightPx = Math.round(contentHeight / scale);
          let endY = Math.min(currentY + pageHeightPx, canvas.height);

          if (endY < canvas.height) {
            endY = findBreakY(canvas, endY);
          }

          const sliceHeight = endY - currentY;
          const pageCanvas = document.createElement('canvas');
          pageCanvas.width = canvas.width;
          pageCanvas.height = sliceHeight;
          pageCanvas.getContext('2d').drawImage(canvas, 0, currentY, canvas.width, sliceHeight, 0, 0, canvas.width, sliceHeight);

          const imgData = pageCanvas.toDataURL('image/jpeg', 0.95);
          const pageImgHeight = sliceHeight * scale;

          if (firstPage) {
            pdf.addImage(imgData, 'JPEG', margin, margin, contentWidth, pageImgHeight);
            firstPage = false;
          } else {
            pdf.addPage();
            pdf.addImage(imgData, 'JPEG', margin, margin, contentWidth, pageImgHeight);
          }

          currentY = endY;
        }

        pdf.save(`合同_${row.contractCode || row.contractName || '未命名'}.pdf`);
        this.$message.success('PDF导出成功');
        this.exportDialogVisible = false;
      } catch (error) {
        console.error('PDF导出失败:', error);
        this.$message.error('PDF导出失败，请重试');
      } finally {
        loading.close();
        this.exportLoading = false;
      }
    },
  }
};
</script>

<style scoped>
.contract-list {
  height: 100%;
  overflow-y: auto;
}

.custom-list {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  overflow: hidden;
}

.list-item:hover {
  background-color: #f5f7fa;
}

.list-item-active {
  background-color: #ecf5ff;
  border-left: 3px solid #409eff;
}

.list-item-top {
  background-color: #fff7e6;
  border-left: 3px solid #e6a23c;
}

.list-item-top:hover {
  background-color: #ffebcc;
}

@media screen and (max-width: 1200px) {
  .list-header {
    font-size: 12px;
  }

  .list-item {
    font-size: 12px;
  }

  .list-item .el-button {
    font-size: 10px;
  }
}
</style>