<!-- 非平行度修正工具组件 -->
<template>
  <div class="nonparallelism-correction-tool">
    <!-- 操作按钮区 -->
    <div class="tool-header">
      <div class="card-header-buttons">
        <el-button type="primary" @click="handleImport" size="small" icon="el-icon-upload">
          导入Excel
        </el-button>

        <el-button 
          type="warning" 
          @click="handleCalculate" 
          size="small" 
          :disabled="!hasValidData || calculating"
          :loading="calculating"
          icon="el-icon-caret-right">
          {{ calculating ? '计算中...' : '执行计算' }}
        </el-button>
        <el-button 
          type="danger" 
          @click="clearAll" 
          size="small" 
          :disabled="!hasAnyData"
          plain
          icon="el-icon-delete">
          清空全部
        </el-button>
      </div>
    </div>
    
    <!-- 参数设置区域 -->
    <div class="params-area">
      <div class="params-row">
        <div class="params-group">
          <label class="param-label">坐标系</label>
          <el-select v-model="commonParams.coordinateSystem" size="small" style="width: 140px;">
            <el-option label="WGS84" value="WGS84"></el-option>
            <el-option label="CGCS2000" value="CGCS2000"></el-option>
            <el-option label="Beijing54" value="Beijing54"></el-option>
            <el-option label="Xian80" value="Xian80"></el-option>
          </el-select>
        </div>
        
        <div class="params-group">
          <label class="param-label">经度位置</label>
          <el-select v-model="commonParams.longitudePosition" size="small" style="width: 80px;">
            <el-option label="E" value="E"></el-option>
            <el-option label="W" value="W"></el-option>
          </el-select>
        </div>
        
        <div class="params-group">
          <label class="param-label">纬度位置</label>
          <el-select v-model="commonParams.latitudePosition" size="small" style="width: 80px;">
            <el-option label="N" value="N"></el-option>
            <el-option label="S" value="S"></el-option>
          </el-select>
        </div>
        
        <div class="params-group">
          <label class="param-label">带号</label>
          <el-input-number v-model="commonParams.zoneNo" size="small" :precision="3" :step="0.1" :controls="false" style="width: 80px;" placeholder="带号"></el-input-number>
        </div>
        
        <div class="params-group">
          <label class="param-label">带宽(°)</label>
          <el-select v-model="commonParams.bandWidth" size="small" style="width: 80px;">
            <el-option label="3" :value="3"></el-option>
            <el-option label="6" :value="6"></el-option>
          </el-select>
        </div>
        
        <div class="params-group">
          <label class="param-label">投影面高程(m)</label>
          <el-input v-model.number="commonParams.projectionHeight" size="small" style="width: 120px;"></el-input>
        </div>
        
        <div class="params-group">
          <label class="param-label">水准等级</label>
          <el-select v-model="commonParams.level" size="small" style="width: 100px;">
            <el-option label="二等" :value="2"></el-option>
            <el-option label="三等" :value="3"></el-option>
            <el-option label="四等" :value="4"></el-option>
          </el-select>
        </div>
        
        <div class="params-group">
          <label class="param-label">标尺真长(m)</label>
          <el-input-number 
            v-model="commonParams.scaleTrueLength" 
            size="small" 
            :min="0" 
            :max="10" 
            :controls="false"
            style="width: 140px;" 
            placeholder="请输入标尺真长">
          </el-input-number>
        </div>
      </div>
    </div>

    <!-- 数据展示区 -->
    <div class="data-section">
      <el-tabs v-model="activeDataTab" type="border-card">
        <!-- 测段高差表 -->
        <el-tab-pane label="测段高差表" name="heightDifference">
          <div class="result-section">
            <div class="section-header">
              <span class="section-info">共 {{ heightDifferenceData.length }} 条数据</span>
              <el-button v-if="hasAnyData" type="text" size="small" @click="handleExport" icon="el-icon-download">
                导出结果
              </el-button>
            </div>
            
            <el-table :data="heightDifferenceDisplayData" style="width: 100%" border stripe :span-method="heightDifferenceSpanMethod">
              <el-table-column label="序号" width="60" align="center">
                <template slot-scope="scope">
                  {{ Math.floor(scope.$index / 2) + 1 }}
                </template>
              </el-table-column>
              <el-table-column prop="startPointNo" label="起点号" width="100" align="center"></el-table-column>
              <el-table-column prop="endPointNo" label="终点号" width="100" align="center"></el-table-column>
              <el-table-column prop="stationCount" label="站数" width="80" align="center">
                <template slot-scope="scope">
                  {{ formatNumber(scope.row.stationCount, 0) }}
                </template>
              </el-table-column>
              <el-table-column prop="distance" label="距离(m)" width="120" align="center">
                <template slot-scope="scope">
                  {{ formatNumber(scope.row.distance, 4) }}
                </template>
              </el-table-column>
              <el-table-column prop="heightDifference" label="高差值(m)" width="120" align="center">
                <template slot-scope="scope">
                  {{ formatNumber(scope.row.heightDifference, 4) }}
                </template>
              </el-table-column>
              <el-table-column prop="averageScaleCorrectedHeightDiff" label="平均尺改高差(m)" width="140" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.averageScaleCorrectedHeightDiff !== undefined" class="result-value">{{ formatNumber(scope.row.averageScaleCorrectedHeightDiff, 5) }}</span>
                  <span v-else class="empty-cell">-</span>
                </template>
              </el-table-column>
              <!-- 计算结果字段 -->
              <el-table-column prop="averageDistance" label="平均距离(km)" width="130" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.averageDistance !== undefined" class="result-value">{{ formatNumber(scope.row.averageDistance, 4) }}</span>
                  <span v-else class="empty-cell">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="roundTripDifference" label="往返较差(mm)" width="130" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.roundTripDifference !== undefined" class="result-value">{{ formatNumber(scope.row.roundTripDifference, 3) }}</span>
                  <span v-else class="empty-cell">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="tolerance" label="限差(mm)" width="100" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.tolerance !== undefined" class="result-value">{{ formatNumber(scope.row.tolerance, 3) }}</span>
                  <span v-else class="empty-cell">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="precisionStatistics" label="精度统计" width="100" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.precisionStatistics !== undefined" class="result-value">{{ formatNumber(scope.row.precisionStatistics, 3) }}</span>
                  <span v-else class="empty-cell">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="qualityScore" label="质量评分" width="100" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.qualityScore !== undefined" class="result-value" :class="{ 'quality-pass': scope.row.qualityScore >= 60, 'quality-fail': scope.row.qualityScore < 60 }">
                    {{ scope.row.qualityScore >= 0 ? formatNumber(scope.row.qualityScore, 2) : '不合格' }}
                  </span>
                  <span v-else class="empty-cell">-</span>
                </template>
              </el-table-column>
            </el-table>
            
            <!-- 测段高差表分页 -->
            <div class="pagination-wrapper">
              <el-pagination
                @size-change="(val) => handleHeightDiffSizeChange(val)"
                @current-change="(val) => handleHeightDiffCurrentChange(val)"
                :current-page="heightDiffCurrentPage"
                :page-sizes="[100, 200, 500]"
                :page-size="heightDiffPageSize"
                layout="total, sizes, prev, pager, next, jumper"
                :total="heightDifferenceData.length">
              </el-pagination>
            </div>
          </div>
        </el-tab-pane>
        
        <!-- 不平行改正表 -->
        <el-tab-pane label="不平行改正表" name="correction">
          <div class="result-section">
            <div class="section-header">
              <span class="section-info">共 {{ correctionData.length }} 条数据 | 坐标系：{{ commonParams.coordinateSystem }}</span>
              <el-button v-if="hasAnyData" type="text" size="small" @click="handleExport" icon="el-icon-download">
                导出结果
            </el-button>
            </div>
            <el-table :data="correctionDisplayData" style="width: 100%" border stripe :span-method="correctionSpanMethod">
              <el-table-column prop="pendingPoint" label="待求点" width="100" align="center"></el-table-column>
              <el-table-column prop="coordinateX" label="纵坐标X(m)" width="150" align="center">
                <template slot-scope="scope">
                  {{ formatNumber(scope.row.coordinateX, 4) }}
                </template>
              </el-table-column>
              <el-table-column prop="coordinateY" label="横坐标Y(m)" width="150" align="center">
                <template slot-scope="scope">
                  {{ formatNumber(scope.row.coordinateY, 4) }}
                </template>
              </el-table-column>
              <el-table-column prop="heightH" label="高程H(m)" width="120" align="center">
                <template slot-scope="scope">
                  {{ formatNumber(scope.row.heightH, 4) }}
                </template>
              </el-table-column>
              <el-table-column prop="zoneNo" label="带号" width="80" align="center"></el-table-column>
              <el-table-column prop="bandWidth" label="带宽(°)" width="80" align="center"></el-table-column>
              <!-- 计算结果字段 -->
              <el-table-column prop="geodeticLongitude" label="大地经度(°′″)" width="150" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.geodeticLongitude !== undefined" class="result-value">{{ formatNumber(scope.row.geodeticLongitude, 7) }}</span>
                  <span v-else class="empty-cell">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="geodeticLatitude" label="大地纬度(°′″)" width="150" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.geodeticLatitude !== undefined" class="result-value">{{ formatNumber(scope.row.geodeticLatitude, 7) }}</span>
                  <span v-else class="empty-cell">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="pointCorrection" label="点间改正ε(m)" width="130" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.pointCorrection !== undefined" class="result-value">{{ formatNumber(scope.row.pointCorrection, 6) }}</span>
                  <span v-else class="empty-cell">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="correctedHeightDifference" label="改正后高差(m)" width="140" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.correctedHeightDifference !== undefined" class="result-value">{{ formatNumber(scope.row.correctedHeightDifference, 4) }}</span>
                  <span v-else class="empty-cell">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="elevation" label="高程(m)" width="120" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.elevation !== undefined" class="result-value">{{ formatNumber(scope.row.elevation, 4) }}</span>
                  <span v-else class="empty-cell">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="distanceFromStart" label="起点距(km)" width="120" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.distanceFromStart !== undefined" class="result-value">{{ formatNumber(scope.row.distanceFromStart, 4) }}</span>
                  <span v-else class="empty-cell">-</span>
                </template>
              </el-table-column>
              <el-table-column prop="heightMiddleError" label="高程中误差(mm)" width="140" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.heightMiddleError !== undefined" class="result-value">{{ formatNumber(scope.row.heightMiddleError, 3) }}</span>
                  <span v-else class="empty-cell">-</span>
                </template>
              </el-table-column>
            </el-table>
            
            <!-- 不平行改正表分页 -->
            <div class="pagination-wrapper">
              <el-pagination
                @size-change="(val) => handleCorrectionSizeChange(val)"
                @current-change="(val) => handleCorrectionCurrentChange(val)"
                :current-page="correctionCurrentPage"
                :page-sizes="[100, 200, 500]"
                :page-size="correctionPageSize"
                layout="total, sizes, prev, pager, next, jumper"
                :total="correctionData.length">
              </el-pagination>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>
    
    <!-- 空状态 -->
    <div v-if="!hasAnyData" class="empty-state">
      <i class="el-icon-document"></i>
      <p>暂无数据</p>
      <p class="empty-tip">请先导入Excel数据（需包含测段高差表和不平行改正表），然后点击"执行计算"</p>
    </div>
    
    <!-- 导入Excel对话框 -->
    <el-dialog title="导入Excel" :visible.sync="importDialogVisible" width="550px" @close="resetImport">
      <div style="text-align: center;">
        <el-upload
          class="upload-area"
          :action="''"
          :auto-upload="false"
          :on-change="handleFileChange"
          :show-file-list="true"
          accept=".xlsx,.xls"
          drag
          ref="upload">
          <i class="el-icon-upload"></i>
          <div class="el-upload__text">将Excel文件拖到此处，或<em>点击选择</em></div>
          <div class="el-upload__tip" slot="tip">
            支持.xlsx和.xls格式文件，需包含"测段高差表"和"不平行改正表"两个工作表
          </div>
        </el-upload>
      </div>
      
      <span slot="footer" class="dialog-footer">
        <el-button @click="importDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitImport" :loading="importLoading" :disabled="!importFile">
          确认导入
        </el-button>
      </span>
    </el-dialog>
    
    <!-- 字段映射对话框 -->
    <el-dialog title="字段映射" :visible.sync="fieldMappingVisible" width="650px" @close="cancelMapping">
      <div class="mapping-tips">
        <el-alert
          title="字段映射说明"
          type="info"
          :closable="false"
          show-icon>
          <p>请为每个工作表配置字段映射。</p>
        </el-alert>
      </div>
      
      <!-- 工作表选择和字段映射 -->
      <div class="sheet-select-section">
        <!-- 测段高差表字段映射 -->
        <div class="mapping-section">
          <h4 style="margin-bottom: 15px; font-weight: bold; color: #303133;">测段高差表字段映射</h4>
          <div class="mapping-row">
            <label class="mapping-label">选择工作表：</label>
            <el-select v-model="heightDiffSheetName" class="mapping-select" placeholder="请选择工作表" @change="onHeightDiffSheetChange">
              <el-option v-for="sheet in sheetInfo" :key="sheet.sheetName" :label="sheet.sheetName" :value="sheet.sheetName"></el-option>
            </el-select>
          </div>
          <div class="mapping-row">
            <label class="mapping-label">起点号：</label>
            <el-select v-model="fieldMapping.heightDifference.startPointNo" class="mapping-select" placeholder="请选择起点号列">
              <el-option v-for="col in heightDiffHeaders" :key="col" :label="col" :value="col"></el-option>
            </el-select>
          </div>
          <div class="mapping-row">
            <label class="mapping-label">终点号：</label>
            <el-select v-model="fieldMapping.heightDifference.endPointNo" class="mapping-select" placeholder="请选择终点号列">
              <el-option v-for="col in heightDiffHeaders" :key="col" :label="col" :value="col"></el-option>
            </el-select>
          </div>
          <div class="mapping-row">
            <label class="mapping-label">站数：</label>
            <el-select v-model="fieldMapping.heightDifference.stationCount" class="mapping-select" placeholder="请选择站数列">
              <el-option v-for="col in heightDiffHeaders" :key="col" :label="col" :value="col"></el-option>
            </el-select>
          </div>
          <div class="mapping-row">
            <label class="mapping-label">距离(m)：</label>
            <el-select v-model="fieldMapping.heightDifference.distance" class="mapping-select" placeholder="请选择距离列">
              <el-option v-for="col in heightDiffHeaders" :key="col" :label="col" :value="col"></el-option>
            </el-select>
          </div>
          <div class="mapping-row">
            <label class="mapping-label">高差值(m)：</label>
            <el-select v-model="fieldMapping.heightDifference.heightDifference" class="mapping-select" placeholder="请选择高差值列">
              <el-option v-for="col in heightDiffHeaders" :key="col" :label="col" :value="col"></el-option>
            </el-select>
          </div>
        </div>
        
        <!-- 分隔线 -->
        <div style="border-top: 1px solid #e4e7ed; margin: 20px 0; padding-top: 20px;"></div>
        
        <!-- 不平行改正表字段映射 -->
        <div class="mapping-section">
          <h4 style="margin-bottom: 15px; font-weight: bold; color: #303133;">不平行改正表字段映射</h4>
          <div class="mapping-row">
            <label class="mapping-label">选择工作表：</label>
            <el-select v-model="correctionSheetName" class="mapping-select" placeholder="请选择工作表" @change="onCorrectionSheetChange">
              <el-option v-for="sheet in sheetInfo" :key="sheet.sheetName" :label="sheet.sheetName" :value="sheet.sheetName"></el-option>
            </el-select>
          </div>
          <div class="mapping-row">
            <label class="mapping-label">待求点：</label>
            <el-select v-model="fieldMapping.correction.pendingPoint" class="mapping-select" placeholder="请选择待求点列">
              <el-option v-for="col in correctionHeaders" :key="col" :label="col" :value="col"></el-option>
            </el-select>
          </div>
          <div class="mapping-row">
            <label class="mapping-label">纵坐标X(m)：</label>
            <el-select v-model="fieldMapping.correction.coordinateX" class="mapping-select" placeholder="请选择纵坐标X列">
              <el-option v-for="col in correctionHeaders" :key="col" :label="col" :value="col"></el-option>
            </el-select>
          </div>
          <div class="mapping-row">
            <label class="mapping-label">横坐标Y(m)：</label>
            <el-select v-model="fieldMapping.correction.coordinateY" class="mapping-select" placeholder="请选择横坐标Y列">
              <el-option v-for="col in correctionHeaders" :key="col" :label="col" :value="col"></el-option>
            </el-select>
          </div>
          <div class="mapping-row">
            <label class="mapping-label">高程H(m)：</label>
            <el-select v-model="fieldMapping.correction.heightH" class="mapping-select" placeholder="请选择高程H列">
              <el-option v-for="col in correctionHeaders" :key="col" :label="col" :value="col"></el-option>
            </el-select>
          </div>
          <div class="mapping-row">
            <label class="mapping-label">带号：</label>
            <el-select v-model="fieldMapping.correction.zoneNo" class="mapping-select" placeholder="请选择带号列">
              <el-option v-for="col in correctionHeaders" :key="col" :label="col" :value="col"></el-option>
            </el-select>
          </div>
          <div class="mapping-row">
            <label class="mapping-label">带宽°：</label>
            <el-select v-model="fieldMapping.correction.bandWidth" class="mapping-select" placeholder="请选择带宽列">
              <el-option v-for="col in correctionHeaders" :key="col" :label="col" :value="col"></el-option>
            </el-select>
          </div>
        </div>
      </div>
      
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancelMapping">取消</el-button>
        <el-button type="primary" @click="confirmMapping" :disabled="!validateMapping">
          确认映射
        </el-button>
      </span>
    </el-dialog>
    
    <!-- 预览数据对话框 -->
    <el-dialog title="导入数据预览" :visible.sync="previewDialogVisible" width="80%">
      <el-tabs v-model="previewTab" type="card">
        <el-tab-pane label="测段高差表" name="heightDifference">
          <div class="preview-info">
            <span>共 {{ heightDifferenceData.length }} 条数据</span>
          </div>
          <el-table :data="heightDifferenceData" border stripe max-height="500">
            <el-table-column prop="startPointNo" label="起点号" width="100" align="center"></el-table-column>
            <el-table-column prop="endPointNo" label="终点号" width="100" align="center"></el-table-column>
            <el-table-column prop="stationCount" label="站数" width="80" align="center"></el-table-column>
            <el-table-column prop="distance" label="距离(m)" width="120" align="center"></el-table-column>
            <el-table-column prop="heightDifference" label="高差值(m)" width="120" align="center"></el-table-column>
          </el-table>
        </el-tab-pane>
        <el-tab-pane label="不平行改正表" name="correction">
          <div class="preview-info">
            <span>共 {{ correctionData.length }} 条数据</span>
          </div>
          <el-table :data="correctionData" border stripe max-height="500">
            <el-table-column prop="pendingPoint" label="待求点" width="100" align="center"></el-table-column>
            <el-table-column prop="coordinateX" label="纵坐标X(m)" width="150" align="center"></el-table-column>
            <el-table-column prop="coordinateY" label="横坐标Y(m)" width="150" align="center"></el-table-column>
            <el-table-column prop="heightH" label="高程H(m)" width="120" align="center"></el-table-column>
            <el-table-column prop="zoneNo" label="带号" width="80" align="center"></el-table-column>
            <el-table-column prop="bandWidth" label="带宽(°)" width="80" align="center"></el-table-column>
          </el-table>
        </el-tab-pane>
      </el-tabs>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="previewDialogVisible = false">关闭</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { calculate, importExcel, exportExcel } from '@/api/calculate/nonparallelismcorrection'

export default {
  name: 'NonParallelismCorrectionTool',
  data() {
    return {
      // 导入的数据
      heightDifferenceData: [],
      correctionData: [],
      calculationResults: [],
      
      // 对话框控制
      importDialogVisible: false,
      importLoading: false,
      importFile: null,
      fieldMappingVisible: false,
      previewDialogVisible: false,
      previewTab: 'heightDifference',
      
      // 计算状态
      calculating: false,
      
      // 工作表信息
      sheetNames: [],
      sheetInfo: [],
      heightDiffSheetName: '',
      correctionSheetName: '',
      
      // 字段映射配置
      fieldMapping: {
        heightDifference: {
          startPointNo: '',
          endPointNo: '',
          stationCount: '',
          distance: '',
          heightDifference: ''
        },
        correction: {
          pendingPoint: '',
          coordinateX: '',
          coordinateY: '',
          heightH: '',
          zoneNo: '',
          bandWidth: ''
        }
      },
      
      // 公共参数
      commonParams: {
        coordinateSystem: 'CGCS2000',
        longitudePosition: 'W',
        latitudePosition: 'N',
        zoneNo: 0,
        bandWidth: 3,
        projectionHeight: 0,
        level: 2,
        scaleTrueLength: 1,
      },
      
      // 数据tab切换
      activeDataTab: 'heightDifference',
      
      // 测段高差表分页
      heightDiffCurrentPage: 1,
      heightDiffPageSize: 100,
      
      // 不平行改正表分页
      correctionCurrentPage: 1,
      correctionPageSize: 100
    }
  },
  computed: {
    hasAnyData() {
      return this.heightDifferenceData.length > 0 || this.correctionData.length > 0
    },
    
    hasValidData() {
      return this.heightDifferenceData.length > 0 && this.correctionData.length > 0
    },
    
    validateMapping() {
      const hdMapping = this.fieldMapping.heightDifference
      const hdValid = hdMapping.startPointNo && hdMapping.endPointNo && 
                      hdMapping.distance && hdMapping.heightDifference
      
      const corrMapping = this.fieldMapping.correction
      const corrValid = corrMapping.pendingPoint && corrMapping.coordinateX && 
                        corrMapping.coordinateY && corrMapping.heightH
      const scaleValid = this.commonParams.scaleTrueLength !== '' && 
                       this.commonParams.scaleTrueLength !== null
      const sheetValid = this.heightDiffSheetName && this.correctionSheetName
      return hdValid && corrValid && scaleValid && sheetValid
    },
    
    // 获取测段高差表选中工作表的表头
    heightDiffHeaders() {
      const sheet = this.sheetInfo.find(s => s.sheetName === this.heightDiffSheetName)
      return sheet ? sheet.headers : []
    },
    
    // 获取不平行改正表选中工作表的表头
    correctionHeaders() {
      const sheet = this.sheetInfo.find(s => s.sheetName === this.correctionSheetName)
      return sheet ? sheet.headers : []
    },
    
    // 测段高差表分页数据
    heightDifferenceDisplayData() {
      const start = (this.heightDiffCurrentPage - 1) * this.heightDiffPageSize
      const end = start + this.heightDiffPageSize
      return this.heightDifferenceData.slice(start, end)
    },
    
    // 不平行改正表分页数据
    correctionDisplayData() {
      const start = (this.correctionCurrentPage - 1) * this.correctionPageSize
      const end = start + this.correctionPageSize
      return this.correctionData.slice(start, end)
    }
  },
  methods: {
    handleImport() {
      this.importDialogVisible = true
    },
    
    handleFileChange(file) {
      this.importFile = file.raw
    },
    
    async submitImport() {
      if (!this.importFile) {
        this.$message.warning('请选择文件')
        return
      }
      
      this.importLoading = true
      
      const formData = new FormData()
      formData.append('file', this.importFile)
      
      const response = await importExcel(formData)
      
      if (response.code === 200) {
        const result = response.data
        
        this.sheetNames = result.sheetNames || []
        this.sheetInfo = result.sheetInfo || []
        this.autoMatchSheetNames()
        this.autoMatchFields()
        
        this.calculationResults = []
        
        this.importDialogVisible = false
        this.importLoading = false
        
        // 在对话框显示前设置第一个tab，确保打开时显示第一个tab内容
        if (this.sheetInfo.length > 0) {
          this.activeSheetTab = this.sheetInfo[0].sheetName
        }
        this.fieldMappingVisible = true
      } else {
        this.$message.error(response.msg)
        this.importLoading = false
      }
    },
    
    autoMatchSheetNames() {
      // 根据索引直接设置工作表名称，不依赖名称匹配
      if (this.sheetInfo.length >= 1) {
        this.heightDiffSheetName = this.sheetInfo[0].sheetName
      }
      if (this.sheetInfo.length >= 2) {
        this.correctionSheetName = this.sheetInfo[1].sheetName
      }
    },
    
    // 测段高差表工作表变更时自动匹配字段
    onHeightDiffSheetChange() {
      this.resetHeightDiffMapping()
      const sheet = this.sheetInfo.find(s => s.sheetName === this.heightDiffSheetName)
      if (sheet) {
        const keywords = {
          startPointNo: ['起点号', '起点', 'start', 'from'],
          endPointNo: ['终点', '终点号', 'end', 'to'],
          stationCount: ['站数', '测站数', 'station'],
          distance: ['距离', 'dist', 'distance'],
          heightDifference: ['高差', '高差值', 'height', 'diff']
        }
        this.autoMatchSheetFields(sheet.headers, keywords, 'heightDifference')
      }
    },
    
    // 不平行改正表工作表变更时自动匹配字段
    onCorrectionSheetChange() {
      this.resetCorrectionMapping()
      const sheet = this.sheetInfo.find(s => s.sheetName === this.correctionSheetName)
      if (sheet) {
        const keywords = {
          pendingPoint: ['待求点', '点号', 'point'],
          coordinateX: ['x', '横坐标', '纵坐标x'],
          coordinateY: ['y', '纵坐标', '横坐标y'],
          heightH: ['高程', '高度', 'h', 'height'],
          zoneNo: ['带号', 'zone'],
          bandWidth: ['带宽', 'band']
        }
        this.autoMatchSheetFields(sheet.headers, keywords, 'correction')
      }
    },
    
    // 重置测段高差表字段映射
    resetHeightDiffMapping() {
      this.fieldMapping.heightDifference = {
        startPointNo: '',
        endPointNo: '',
        stationCount: '',
        distance: '',
        heightDifference: ''
      }
    },
    
    // 重置不平行改正表字段映射
    resetCorrectionMapping() {
      this.fieldMapping.correction = {
        pendingPoint: '',
        coordinateX: '',
        coordinateY: '',
        heightH: '',
        zoneNo: '',
        bandWidth: ''
      }
    },
    
    autoMatchFields() {
      const heightDiffKeywords = {
        startPointNo: ['起点号', '起点', 'start', 'from'],
        endPointNo: ['终点', '终点号', 'end', 'to'],
        stationCount: ['站数', '测站数', 'station'],
        distance: ['距离', 'dist', 'distance'],
        heightDifference: ['高差', '高差值', 'height', 'diff']
      }
      
      const correctionKeywords = {
        pendingPoint: ['待求点', '点号', 'point'],
        coordinateX: ['x', '横坐标', '纵坐标x'],
        coordinateY: ['y', '纵坐标', '横坐标y'],
        heightH: ['高程', '高度', 'h', 'height'],
        zoneNo: ['带号', 'zone'],
        bandWidth: ['带宽', 'band']
      }
      
      const heightDiffSheet = this.sheetInfo.find(s => s.sheetName === this.heightDiffSheetName)
      if (heightDiffSheet) {
        this.autoMatchSheetFields(heightDiffSheet.headers, heightDiffKeywords, 'heightDifference')
      }
      
      const correctionSheet = this.sheetInfo.find(s => s.sheetName === this.correctionSheetName)
      if (correctionSheet) {
        this.autoMatchSheetFields(correctionSheet.headers, correctionKeywords, 'correction')
      }
    },
    
    autoMatchSheetFields(headers, keywords, mappingType) {
      Object.keys(keywords).forEach(key => {
        for (const keyword of keywords[key]) {
          const matchedCol = headers.find(col => 
            col.includes(keyword) || col.toLowerCase().includes(keyword.toLowerCase())
          )
          if (matchedCol) {
            this.fieldMapping[mappingType][key] = matchedCol
            break
          }
        }
      })
    },
    

    
    confirmMapping() {
      if (!this.validateMapping) {
        this.$message.warning('请完成所有必填字段映射')
        return
      }
      
      const heightDiffSheet = this.sheetInfo.find(s => s.sheetName === this.heightDiffSheetName)
      if (heightDiffSheet) {
        this.heightDifferenceData = this.convertSheetData(heightDiffSheet.rawData, 'heightDifference')
      }
      
      const correctionSheet = this.sheetInfo.find(s => s.sheetName === this.correctionSheetName)
      if (correctionSheet) {
        this.correctionData = this.convertSheetData(correctionSheet.rawData, 'correction')
      }
      
      if (this.heightDifferenceData.length !== this.correctionData.length) {
        this.$message.warning(`测段高差表(${this.heightDifferenceData.length}条)与不平行改正表(${this.correctionData.length}条)数据条数不一致，请检查数据`)
      }
      
      this.fieldMappingVisible = false
      this.$message.success('数据导入成功')
    },
    
    convertSheetData(rawData, mappingType) {
      const mapping = this.fieldMapping[mappingType]
      const result = []
      
      for (const row of rawData) {
        const item = {}
        Object.keys(mapping).forEach(key => {
          const colName = mapping[key]
          if (colName && row[colName] !== undefined && row[colName] !== null && row[colName] !== '') {
            item[key] = row[colName]
          }
        })
        
        item.coordinateSystem = this.commonParams.coordinateSystem
        item.longitudePosition = this.commonParams.longitudePosition
        item.latitudePosition = this.commonParams.latitudePosition
        item.projectionHeight = this.commonParams.projectionHeight
        item.level = this.commonParams.level
        item.scaleTrueLength = this.commonParams.scaleTrueLength
        if (mappingType === 'correction') {
          if (!item.zoneNo) item.zoneNo = this.commonParams.zoneNo
          if (!item.bandWidth) item.bandWidth = this.commonParams.bandWidth
        } else {
          item.zoneNo = this.commonParams.zoneNo
          item.bandWidth = this.commonParams.bandWidth
        }
        
        result.push(item)
      }
      
      return result
    },
    
    cancelMapping() {
      this.fieldMappingVisible = false
      this.sheetInfo = []
      this.sheetNames = []
      this.resetFieldMapping()
    },
    
    resetFieldMapping() {
      this.fieldMapping = {
        heightDifference: {
          startPointNo: '',
          endPointNo: '',
          stationCount: '',
          distance: '',
          heightDifference: ''
        },
        correction: {
          pendingPoint: '',
          coordinateX: '',
          coordinateY: '',
          heightH: '',
          zoneNo: '',
          bandWidth: ''
        }
      }
    },
    
    async handleCalculate() {
      if (!this.hasValidData) {
        this.$message.warning('请导入测段高差表和不平行改正表数据')
        return
      }
      
      this.calculating = true
      
      const requestData = []
      for (let i = 0; i < Math.max(this.heightDifferenceData.length, this.correctionData.length); i++) {
        const hdItem = this.heightDifferenceData[i] || {}
        const corrItem = this.correctionData[i] || {}
        
        requestData.push({
          startPointNo: hdItem.startPointNo,
          endPointNo: hdItem.endPointNo,
          stationCount: hdItem.stationCount,
          distance: hdItem.distance,
          heightDifference: hdItem.heightDifference,
          level: this.commonParams.level,
          scaleTrueLength: this.commonParams.scaleTrueLength,
          pendingPoint: corrItem.pendingPoint,
          coordinateX: corrItem.coordinateX,
          coordinateY: corrItem.coordinateY,
          heightH: corrItem.heightH,
          coordinateSystem: this.commonParams.coordinateSystem,
          zoneNo: corrItem.zoneNo || this.commonParams.zoneNo,
          bandWidth: corrItem.bandWidth || this.commonParams.bandWidth,
          latitudePosition: this.commonParams.latitudePosition,
          longitudePosition: this.commonParams.longitudePosition,
          projectionHeight: this.commonParams.projectionHeight
        })
      }
      
      const response = await calculate(requestData)
      
      if (response.code === 200) {
        const results = response.data || []
        
        this.calculationResults = results
        
        // 
        for (let i = 0; i < this.heightDifferenceData.length && i < results.length; i++) {
        const result = results[i]
        if (result) {
          // 使用 $set 确保响应式
          this.$set(this.heightDifferenceData[i], 'averageDistance', result.averageDistance)
          this.$set(this.heightDifferenceData[i], 'averageScaleCorrectedHeightDiff', result.averageScaleCorrectedHeightDiff)
          this.$set(this.heightDifferenceData[i], 'roundTripDifference', result.roundTripDifference)
          this.$set(this.heightDifferenceData[i], 'tolerance', result.tolerance)
          this.$set(this.heightDifferenceData[i], 'precisionStatistics', result.precisionStatistics)
          this.$set(this.heightDifferenceData[i], 'qualityScore', result.qualityScore)
          this.$set(this.heightDifferenceData[i], 'scaleTrueLength', result.scaleTrueLength)
        }
      }
      
      // 使用 this.$set 更新不平行改正数据
      for (let i = 0; i < this.correctionData.length && i < results.length; i++) {
        const result = results[i]
        if (result) {
          this.$set(this.correctionData[i], 'geodeticLongitude', result.geodeticLongitude)
          this.$set(this.correctionData[i], 'geodeticLatitude', result.geodeticLatitude)
          this.$set(this.correctionData[i], 'pointCorrection', result.pointCorrection)
          this.$set(this.correctionData[i], 'correctedHeightDifference', result.correctedHeightDifference)
          this.$set(this.correctionData[i], 'elevation', result.elevation)
          this.$set(this.correctionData[i], 'distanceFromStart', result.distanceFromStart)
          this.$set(this.correctionData[i], 'heightMiddleError', result.heightMiddleError)
        }
      }
        
        const successCount = results.length
        this.$message.success(`计算完成，成功 ${successCount} 条`)
        this.calculating = false
      } else {
        this.$message.error(response.msg)
        this.calculating = false
      }
    },
    
    async handleExport() {
      if (this.heightDifferenceData.length === 0 && this.correctionData.length === 0) {
        this.$message.warning('没有数据可导出')
        return
      }
      
      // 组装导出数据，包含两个表
      const exportData = {
        heightDifferenceData: this.heightDifferenceData,
        correctionData: this.correctionData
      }
      
      const response = await exportExcel(exportData)
      
      const blob = new Blob([response], { 
        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
      })
      
      const url = window.URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = url
      link.download = `水准测段高差正常水准面不平行改正结果_${new Date().getTime()}.xlsx`
      link.click()
      window.URL.revokeObjectURL(url)
    },
    
    clearAll() {
      if (!this.hasAnyData) return
      
      this.$confirm('确定清空所有数据吗？此操作不可恢复！', '警告', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.heightDifferenceData = []
        this.correctionData = []
        this.calculationResults = []
        this.$message.success('已清空所有数据')
      }).catch(() => {})
    },
    
    resetImport() {
      this.importFile = null
      if (this.$refs.upload) {
        this.$refs.upload.clearFiles()
      }
    },
    
    formatNumber(value, decimals = 3) {
      if (value === null || value === undefined || value === '') return '--'
      return Number(value).toFixed(decimals)
    },
    
    // 测段高差表分页方法
    handleHeightDiffSizeChange(val) {
      this.heightDiffPageSize = val
      this.heightDiffCurrentPage = 1
    },
    
    handleHeightDiffCurrentChange(val) {
      this.heightDiffCurrentPage = val
    },
    
    // 不平行改正表分页方法
    handleCorrectionSizeChange(val) {
      this.correctionPageSize = val
      this.correctionCurrentPage = 1
    },
    
    handleCorrectionCurrentChange(val) {
      this.correctionCurrentPage = val
    },
    
    correctionSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 需要合并的列索引（从0开始）
      // 8: 点间改正ε(m), 9: 改正后高差(m)
      const mergeColumns = [8, 9]
      
      if (mergeColumns.includes(columnIndex)) {
        // 偶数行合并自己和下一行
        if (rowIndex % 2 === 0) {
          if (rowIndex + 1 < this.correctionData.length) {
            return {
              rowspan: 2,
              colspan: 1
            }
          } else {
            // 最后一行单独显示
            return {
              rowspan: 1,
              colspan: 1
            }
          }
        } else {
          // 奇数行不显示
          return {
            rowspan: 0,
            colspan: 0
          }
        }
      }
      
      // 其他列不合并
      return {
        rowspan: 1,
        colspan: 1
      }
    },
    
    heightDifferenceSpanMethod({ row, column, rowIndex, columnIndex }) {
      // 需要合并的列索引（从0开始）
      // 0: 序号, 6: 平均距离(km), 7: 平均尺改高差(m), 8: 往返较差(mm), 9: 限差(mm), 10: 精度统计, 11: 质量评分
      const mergeColumns = [0, 6, 7, 8, 9, 10, 11]
      
      if (mergeColumns.includes(columnIndex)) {
        // 偶数行合并自己和下一行
        if (rowIndex % 2 === 0) {
          if (rowIndex + 1 < this.heightDifferenceData.length) {
            return {
              rowspan: 2,
              colspan: 1
            }
          } else {
            // 最后一行单独显示
            return {
              rowspan: 1,
              colspan: 1
            }
          }
        } else {
          // 奇数行不显示
          return {
            rowspan: 0,
            colspan: 0
          }
        }
      }
      
      // 其他列不合并
      return {
        rowspan: 1,
        colspan: 1
      }
    }
  }
}
</script>

<style scoped>
.nonparallelism-correction-tool {
  width: 100%;
}

.tool-header {
  margin-bottom: 20px;
}

.card-header-buttons {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.params-area {
  background: #f5f7fa;
  border-radius: 8px;
  padding: 16px 20px;
  margin-bottom: 20px;
  border: 1px solid #e4e7ed;
}

.params-row {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  align-items: center;
}

.params-group {
  display: flex;
  align-items: center;
  gap: 8px;
}

.param-label {
  font-weight: 500;
  color: #606266;
  min-width: 80px;
}

.data-section {
  margin-top: 10px;
}

.result-section {
  margin-top: 10px;
}

.section-header {
  padding: 12px 16px;
  background: #f5f7fa;
  border-radius: 8px 8px 0 0;
  border: 1px solid #e4e7ed;
  border-bottom: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.section-title {
  font-size: 14px;
  font-weight: bold;
  color: #303133;
}

.section-title i {
  margin-right: 8px;
  color: #11a983;
}

.section-info {
  font-size: 12px;
  color: #909399;
}

.result-value {
  color: #409eff;
  font-family: monospace;
  font-weight: 500;
}

.quality-pass {
  color: #67c23a;
}

.quality-fail {
  color: #f56c6c;
}

.empty-cell {
  color: #c0c4cc;
}

.pagination-wrapper {
  display: flex;
  justify-content: flex-end;
  padding: 12px 16px;
  background: #f5f7fa;
  border-radius: 0 0 8px 8px;
  border: 1px solid #e4e7ed;
  border-top: none;
}

.empty-state {
  text-align: center;
  padding: 60px 20px;
  background: #fff;
  border-radius: 8px;
  border: 1px solid #e4e7ed;
  color: #909399;
}

.empty-state i {
  font-size: 64px;
  margin-bottom: 16px;
}

.empty-tip {
  font-size: 12px;
  margin-top: 12px;
  color: #c0c4cc;
}

.upload-area {
  margin-top: 10px;
}

.preview-info {
  margin-bottom: 15px;
  padding: 10px;
  background: #f5f7fa;
  border-radius: 4px;
  font-size: 14px;
  color: #606266;
}

.dialog-footer {
  width: 100%;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.mapping-tips {
  margin-bottom: 20px;
}

.sheet-tabs {
  margin-bottom: 20px;
}

.mapping-section {
  background: #f9fafb;
  border-radius: 8px;
  padding: 16px;
}

.mapping-row {
  display: flex;
  align-items: center;
  margin-bottom: 12px;
}

.mapping-row:last-child {
  margin-bottom: 0;
}

.mapping-label {
  width: 100px;
  font-weight: 500;
  color: #606266;
}

.mapping-select {
  flex: 1;
  min-width: 200px;
}
</style>