| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555 |
- <!-- 高斯正算工具组件 -->
- <template>
- <div class="gauss-positive-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="success"
- @click="handlePreview"
- size="small"
- :disabled="!importedData || importedData.length === 0"
- icon="el-icon-view">
- 预览数据
- </el-button>
- <el-button
- type="warning"
- @click="handleCalculate"
- size="small"
- :disabled="!importedData || importedData.length === 0 || calculating"
- :loading="calculating"
- icon="el-icon-caret-right">
- {{ calculating ? '计算中...' : '执行计算' }}
- </el-button>
- <el-button
- type="danger"
- @click="clearAll"
- size="small"
- :disabled="(!importedData || importedData.length === 0) && calculationResults.length === 0"
- plain
- icon="el-icon-delete">
- 清空全部
- </el-button>
- </div>
- </div>
-
- <!-- 投影面高程设置 -->
- <div class="height-setting">
- <div class="setting-label">
- <span>投影面高程</span>
- </div>
- <div class="setting-content">
- <el-input
- v-model="projectionHeight"
- size="small"
- style="width: 120px; margin-right: 10px;">
- </el-input>
- <span class="unit">米 (m)</span>
-
- </div>
- </div>
-
- <!-- 计算结果展示区 - 只显示计算结果,不包含原始数据 -->
- <div v-if="calculationResults.length > 0" class="result-section">
- <div class="section-header">
- <span class="section-title">
- <i class="el-icon-tickets"></i>
- 计算结果
- </span>
- <span class="section-info">
- 共 {{ calculationResults.length }} 条计算结果
- </span>
- <el-button type="text" size="small" @click="handleExport" icon="el-icon-download">
- 导出结果
- </el-button>
- </div>
-
- <el-table :data="calculationResults" style="width: 100%" border stripe>
- <el-table-column prop="pointNumber" label="待求点号" width="120" align="center"></el-table-column>
- <el-table-column prop="gaussX" label="高斯X坐标(m)" width="180" align="center">
- <template slot-scope="scope">
- <span class="result-value">{{ formatNumber(scope.row.gaussX,4) }}</span>
- </template>
- </el-table-column>
- <el-table-column prop="gaussY" label="高斯Y坐标(m)" width="180" align="center">
- <template slot-scope="scope">
- <span class="result-value">{{ formatNumber(scope.row.gaussY,4) }}</span>
- </template>
- </el-table-column>
- <el-table-column prop="meridianConvergence" label="子午线收敛角γ(°)" width="200" align="center">
- <template slot-scope="scope">
- <span class="result-value">{{ formatNumber(scope.row.meridianConvergence, 7) }}</span>
- </template>
- </el-table-column>
- </el-table>
- </div>
-
- <!-- 空状态 -->
- <div v-else 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 class="import-tips">
- <el-alert
- title="Excel模板格式说明"
- type="info"
- :closable="false"
- show-icon>
- <div class="template-info">
- <p>请确保Excel文件包含以下列(第一行为表头):</p>
- <ul>
- <li><strong>待求点</strong> - 点号</li>
- <li><strong>坐标系</strong> - WGS84/CGCS2000/Beijing54/Xian80</li>
- <li><strong>大地经度</strong> - 经度数值(° ′ ″)</li>
- <li><strong>经度位置</strong> - E/W</li>
- <li><strong>大地纬度</strong> - 纬度数值(° ′ ″)</li>
- <li><strong>纬度位置</strong> - N/S</li>
- <li><strong>带号</strong> - 带号数值</li>
- <li><strong>带宽</strong> - 3或6</li>
- </ul>
- </div>
- </el-alert>
- <div class="template-download-wrapper">
- <el-button type="primary" plain size="small" @click="handleDownloadTemplate" icon="el-icon-download">
- 下载Excel模板
- </el-button>
- </div>
- </div>
- <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="previewDialogVisible" width="80%">
- <div class="preview-info">
- <span>共 {{ importedData.length }} 条数据</span>
- <span style="margin-left: 20px;">状态:{{ importedData.filter(item => item.calculated).length }} 条已计算,{{ importedData.filter(item => !item.calculated).length }} 条未计算</span>
- </div>
- <el-table :data="importedData" border stripe max-height="500">
- <el-table-column prop="pointNumber" label="待求点号" width="120" fixed="left"></el-table-column>
- <el-table-column prop="coordinateSystem" label="坐标系" width="110">
- <template slot-scope="scope">
- <el-tag size="small" :type="getCoordinateType(scope.row.coordinateSystem)">
- {{ scope.row.coordinateSystem }}
- </el-tag>
- </template>
- </el-table-column>
- <el-table-column prop="longitude" label="大地经度" width="130" align="center">
- <template slot-scope="scope">
- {{ scope.row.longitude }}
- </template>
- </el-table-column>
- <el-table-column prop="longitudePosition" label="经度位置" width="130" align="center">
- <template slot-scope="scope">
- {{ scope.row.longitudePosition}}
- </template>
- </el-table-column>
- <el-table-column prop="latitude" label="大地纬度" width="130" align="center">
- <template slot-scope="scope">
- {{ scope.row.latitude }}
- </template>
- </el-table-column>
- <el-table-column prop="latitudePosition" label="纬度位置" width="130" align="center">
- <template slot-scope="scope">
- {{ scope.row.latitudePosition}}
- </template>
- </el-table-column>
- <el-table-column prop="zone" label="带号" width="80" align="center"></el-table-column>
- <el-table-column prop="bandwidth" label="带宽" width="80" align="center">
- <template slot-scope="scope">
- {{ scope.row.bandwidth }}
- </template>
- </el-table-column>
- </el-table>
- <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,downloadTemplate } from '@/api/calculate/gausspositive'
-
- export default {
- name: 'GaussPositiveTool',
- data() {
- return {
- importedData: [], // 导入的原始数据
- calculationResults: [], // 计算结果
- importDialogVisible: false,
- importLoading: false,
- importFile: null,
- calculating: false,
- previewDialogVisible: false,
- projectionHeight: 0
- }
- },
- watch: {
- // 当投影面高程改变时,重新计算(如果已有数据)
- projectionHeight(newVal, oldVal) {
- if (this.importedData.length > 0 && this.calculationResults.length > 0) {
- this.handleCalculate()
- }
- }
- },
- 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.importedData = (result.data || []).map(item => ({
- pointNumber: item.pointNumber,
- coordinateSystem: item.coordinateSystem,
- longitude: item.longitude,
- longitudePosition: item.longitudePosition,
- latitude: item.latitude,
- latitudePosition: item.latitudePosition,
- zone: item.zone,
- bandwidth: item.bandwidth
- }))
-
- // 清空之前的计算结果
- this.calculationResults = []
-
- this.$message.success(`${response.msg}`)
- this.importDialogVisible = false
- this.importLoading = false
- } else {
- this.$message.error(response.msg)
- }
- },
-
- // 预览数据 - 显示导入的原始数据
- handlePreview() {
- if (!this.importedData || this.importedData.length === 0) {
- this.$message.warning('没有可预览的数据')
- return
- }
- this.previewDialogVisible = true
- },
-
- // 下载模板
- handleDownloadTemplate() {
- this.download('/calculate/gaussPositive/template', {}, '高斯正算模板.xlsx')
- },
-
-
- // 执行计算
- async handleCalculate() {
- if (!this.importedData || this.importedData.length === 0) {
- this.$message.warning('没有数据可计算')
- return
- }
-
- this.calculating = true
- const results = []
- let successCount = 0
- let failCount = 0
-
- // 构建请求参数
- const requestData = this.importedData.map(item => ({
- pointNumber: item.pointNumber,
- coordinateSystem: item.coordinateSystem,
- longitude: parseFloat(item.longitude),
- longitudePosition: item.longitudePosition,
- latitude: parseFloat(item.latitude),
- latitudePosition: item.latitudePosition,
- zone: parseInt(item.zone),
- bandwidth: parseInt(item.bandwidth),
- projectionHeight: this.projectionHeight
- }))
-
- const response = await calculate(requestData)
-
- if (response.code === 200) {
- const results = response.data || []
-
- // 更新计算结果
- this.calculationResults = results.map(item => ({
- pointNumber: item.pointNumber,
- coordinateSystem: item.coordinateSystem,
- longitude: parseFloat(item.longitude),
- longitudePosition: item.longitudePosition,
- latitude: parseFloat(item.latitude),
- latitudePosition: item.latitudePosition,
- zone: parseInt(item.zone),
- bandwidth: parseInt(item.bandwidth),
- projectionHeight: this.projectionHeight,
- gaussX: item.gaussX,
- gaussY: item.gaussY,
- meridianConvergence: item.meridianConvergence
- }))
-
- // 更新导入数据的计算状态
- this.importedData.forEach(importItem => {
- const found = results.find(r => r.pointNumber === importItem.pointNumber)
- if (found && found.gaussX !== -1) {
- importItem.calculated = true
- }
- })
-
- const successCount = results.filter(r => r.gaussX !== -1).length
- const failCount = results.length - successCount
-
- this.$message.success(`计算完成,成功 ${successCount} 条${failCount > 0 ? `,失败 ${failCount} 条` : ''}`)
- this.calculating = false
- } else {
- this.$message.error(response.msg)
- }
- },
-
-
- // 导出结果
- async handleExport() {
- if (this.calculationResults.length === 0) {
- this.$message.warning('没有结果可导出')
- return
- }
-
- const response = await exportExcel(this.calculationResults)
-
- 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.importedData || this.importedData.length === 0) && this.calculationResults.length === 0) {
- return
- }
-
- this.$confirm('确定清空所有数据吗?此操作不可恢复!', '警告', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- }).then(() => {
- this.importedData = []
- 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) return '--'
- return Number(value).toFixed(decimals)
- },
-
- // 获取坐标系标签类型
- getCoordinateType(system) {
- const types = {
- 'WGS84': 'primary',
- 'CGCS2000': 'success',
- 'Beijing54': 'warning',
- 'Xian80': 'info'
- }
- return types[system] || 'info'
- }
- }
- }
- </script>
-
- <style scoped>
- .gauss-positive-tool {
- width: 100%;
- }
-
- .tool-header {
- margin-bottom: 20px;
- }
-
- .card-header-buttons {
- display: flex;
- gap: 10px;
- flex-wrap: wrap;
- }
-
- /* 投影面高程设置样式 */
- .height-setting {
- background: #f5f7fa;
- border-radius: 8px;
- padding: 12px 20px;
- margin-bottom: 20px;
- border: 1px solid #e4e7ed;
- display: flex;
- align-items: center;
- gap: 20px;
- flex-wrap: wrap;
- }
-
- .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;
- }
-
- .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;
- }
-
- .import-tips {
- margin-bottom: 20px;
- }
-
- .template-info {
- margin-top: 12px;
- }
-
- .template-info ul {
- margin: 8px 0;
- padding-left: 20px;
- }
-
- .template-info li {
- margin: 4px 0;
- font-size: 13px;
- }
-
- .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;
- }
-
- .template-download-wrapper {
- margin-top: 12px;
- display: flex;
- align-items: center;
- justify-content: flex-end;
- gap: 10px;
- padding-top: 12px;
- border-top: 1px dashed #e4e7ed;
- }
- </style>
|