| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216 |
- <template>
- <div class="map-page">
- <!-- 错误提示 -->
- <div v-if="error" class="error-message">
- <i class="fa fa-exclamation-circle"></i> {{ error }}
- </div>
-
- <!-- 加载状态 -->
- <div v-if="loading" class="loading-state">
- <div class="spinner"></div>
- <p>数据加载中...</p>
- </div>
- <!-- 数据表格容器 -->
- <div v-else class="table-container">
- <table class="data-table">
- <!-- 表头 -->
- <thead>
- <tr>
- <th>断面编号</th>
- <th>所属河流</th>
- <th>断面位置</th>
- <th>所属区县</th>
- <th>Cd含量(ug/L)</th>
- <th>经度</th>
- <th>纬度</th>
- </tr>
- </thead>
- <!-- 表体(遍历数据) -->
- <tbody>
- <tr v-for="item in state.excelData" :key="item.id">
- <td>{{ item.id }}</td>
- <td>{{ item.river }}</td>
- <td>{{ item.location }}</td>
- <td>{{ item.district }}</td>
- <td>{{ item.cdValue }}</td>
- <td>{{ item.longitude.toFixed(6) }}</td> <!-- 保留6位小数 -->
- <td>{{ item.latitude.toFixed(6) }}</td>
- </tr>
- <!-- 空数据提示 -->
- <tr v-if="state.excelData.length === 0">
- <td colspan="7" class="empty-state">暂无数据</td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </template>
- <script setup>
- import { ref, reactive, onMounted } from 'vue'
- import { wgs84togcj02 } from 'coordtransform';
- // 状态管理
- const error = ref(null)
- const loading = ref(true)
- const state = reactive({
- excelData: [], // 存储解析后的断面数据
- riverAvgData: [] // 存储按河流分组后的平均数据
- })
- // 从接口获取数据并处理
- const fetchData = async () => {
- try {
- // 接口地址
- const apiUrl = 'http://localhost:8000/api/vector/export/all?table_name=cross_section'
-
- // 发起请求
- const response = await fetch(apiUrl)
- if (!response.ok) {
- throw new Error(`接口请求失败: ${response.status}`)
- }
-
- // 解析GeoJSON数据
- const geoJsonData = await response.json()
-
- // 处理数据
- state.excelData = geoJsonData.features
- .map(feature => {
- const props = feature.properties
- // 转换经纬度
- const lng = Number(props.longitude)
- const lat = Number(props.latitude)
-
- if (isNaN(lat) || isNaN(lng)) {
- console.error('无效经纬度数据:', props)
- return null
- }
-
- // WGS84转GCJ02坐标
- const [gcjLng, gcjLat] = wgs84togcj02(lng, lat)
-
- return {
- id: props.id,
- river: props.river_name || '未知河流',
- location: props.position || '未知位置',
- district: props.county || '未知区县',
- cdValue: props.cd_concentration !== undefined ? props.cd_concentration : '未知',
- latitude: gcjLat,
- longitude: gcjLng
- }
- })
- .filter(item => item !== null) // 过滤无效数据
-
- } catch (err) {
- error.value = `数据加载失败: ${err.message}`
- console.error('数据处理错误:', err)
- } finally {
- loading.value = false
- }
- }
- // 生命周期
- onMounted(async () => {
- await fetchData()
- })
- </script>
- <style scoped>
- .map-page {
- width: 100%;
- margin: 0 auto 24px;
- background-color: white;
- border-radius: 12px;
- padding: 20px;
- box-sizing: border-box;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
- }
- /* 错误提示样式 */
- .error-message {
- color: #dc2626;
- background-color: #fee2e2;
- padding: 12px 16px;
- border-radius: 6px;
- margin-bottom: 16px;
- display: flex;
- align-items: center;
- font-weight: 500;
- }
- .error-message i {
- margin-right: 8px;
- font-size: 18px;
- }
- /* 加载状态样式 */
- .loading-state {
- text-align: center;
- padding: 40px 0;
- color: #6b7280;
- }
- .spinner {
- width: 40px;
- height: 40px;
- margin: 0 auto 16px;
- border: 4px solid #e5e7eb;
- border-top: 4px solid #3b82f6;
- border-radius: 50%;
- animation: spin 1s linear infinite;
- }
- @keyframes spin {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(360deg); }
- }
- .data-container {
- width: 100%;
- overflow-x: auto;
- padding: 0;
- margin: 0;
- }
- .data-table {
- width: 100%;
- border-collapse: collapse;
- }
- .data-table th, .data-table td {
- padding: 12px 15px;
- text-align: center;
- border: 1px solid #e5e7eb;
- background-color: white;
- }
- .data-table th {
- background-color: white;
- font-weight: bold;
- color: #1f2937;
- }
- .data-table tr:hover {
- background-color: #f3f4f6;
- }
- /* 空数据状态 */
- .empty-state {
- padding: 40px 0;
- color: #6b7280;
- font-style: italic;
- }
- /* 响应式调整 */
- @media (max-width: 768px) {
- .map-page {
- width: 96%;
- }
-
- .table-container {
- overflow-x: auto;
- }
- }
- </style>
|