综合实践

这个项目属于哪个课程 2025综合设计——多源异构数据采集与融合应用综合实践
组名、项目简介 组名:汪汪功立大队
项目需求:随着个性化旅游需求的爆发式增长,传统碎片化的信息获取与行程管理方式已无法满足用户对效率与深度的双重追求。同时,旅行结束后的数据资产(如足迹、消费、情感记忆)往往散落在不同平台,缺乏系统的沉淀与分析。
项目目标:构建一个集智能规划、实时地图联动、全生命周期旅行记录与多维数据洞察于一体的 Web 应用平台。
项目开展技术路线
数据采集层:高德地图API实时地理数据获取 + 旅游信息采集 + AI清洗去重
数据存储层:SQLite/PostgreSQL关系型数据库 + Redis缓存机制 + 结构化行程数据建模
后端逻辑层:Python FastAPI异步框架 + 阿里云Qwen大模型Agent + Pydantic数据验证
算法层:高德地图多模式路线规划API + 旅行人格DNA量化算法 + 经济学模型分析
前端交互层:React 18数据流UI + 高德地图交互式组件 + 生态流光可视化仪表盘
团队成员学号 102302132(组长),102302133,102302134,102302135,102302137,102302145,102302107
这个项目目标 本项目旨在打造一款全生命周期的智能旅行助手,实现以下目标:
1. 智能规划:利用 LLM 实现“一句话生成可执行路书”。
2. 地图联动:实现对话与地图的实时双向交互,所见即所得。
3. 资产沉淀:提供完善的旅行记录功能,覆盖从计划到完成的全过程。
4. 深度分析:通过可视化数据看板,为用户提供上帝视角的旅行行为分析报告。

本人在项目中承担的前后端工作内容,这里重点展示Vue3 组合式 API 的实际使用方式、Vite 工程化配置,以及前后端协作的关键实现

一、使用 Vite 搭建前端工程

1.1 项目初始化

npm create vite@latest
cd project
npm install
npm run dev

Vite 提供了:

  • 原生 ES Module 加载
  • 极快的冷启动
  • 高效热更新

1.2 Vite 配置示例

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  server: {
    port: 5173,
    proxy: {
      '/api': {
        target: 'http://localhost:8000',
        changeOrigin: true
      }
    }
  }
})

体现前后端协作

  • 前端通过 /api 访问后端
  • 避免本地开发时的跨域问题
  • 前端无需关心后端真实地址

二、Vue3 组合式 API:页面状态与逻辑组织方式

2.1 使用 setup + ref + reactive 组织页面状态

<script setup>
import { ref, reactive, computed } from 'vue'

const inputMessage = ref('')
const isLoading = ref(false)

const chatList = reactive([])

const canSend = computed(() => {
  return inputMessage.value.trim().length > 0 && !isLoading.value
})
</script>
  • 使用 ref 管理基础状态
  • 使用 reactive 管理集合数据
  • 使用 computed 派生状态,避免模板中写逻辑

2.2 组合式 API 中的事件逻辑封装

<script setup>
import axios from 'axios'

const sendMessage = async () => {
  if (!canSend.value) return

  chatList.push({
    role: 'user',
    content: inputMessage.value
  })

  isLoading.value = true

  try {
    const res = await axios.post('/api/chat', {
      message: inputMessage.value
    })

    chatList.push({
      role: 'assistant',
      content: res.data.reply
    })
  } finally {
    isLoading.value = false
    inputMessage.value = ''
  }
}
</script>
  • 前端负责请求组织
  • 根据返回结构渲染 UI

对应运行截图

image


三、组合式 API 中的生命周期管理

3.1 使用 onMounted 初始化复杂功能

<script setup>
import { onMounted } from 'vue'
import mapService from '@/services/mapService'

onMounted(async () => {
  const location = await mapService.getCurrentLocation()
  mapService.initMap('map-container', location)
})
</script>

关键点

  • 地图初始化放在生命周期中
  • 避免 DOM 未就绪导致错误

四、地图模块:SDK 调用 + 业务封装

4.1 页面中只做“调用”

<script setup>
import mapService from '@/services/mapService'

const addMarker = (point) => {
  mapService.addMarker(point)
}
</script>

4.2 地图业务服务层

class MapService {
  map = null
  markers = []

  initMap(containerId, center) {
    this.map = new AMap.Map(containerId, {
      zoom: 12,
      center: [center.lng, center.lat]
    })
  }

  addMarker({ lng, lat }) {
    const marker = new AMap.Marker({
      position: [lng, lat],
      map: this.map
    })
    this.markers.push(marker)
  }

  calculateDistance(lng1, lat1, lng2, lat2) {
    const R = 6371
    const dLat = (lat2 - lat1) * Math.PI / 180
    const dLon = (lng2 - lng1) * Math.PI / 180

    const a =
      Math.sin(dLat / 2) ** 2 +
      Math.cos(lat1 * Math.PI / 180) *
      Math.cos(lat2 * Math.PI / 180) *
      Math.sin(dLon / 2) ** 2

    return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
  }

  async getCurrentLocation() {
    return new Promise((resolve) => {
      navigator.geolocation.getCurrentPosition(
        pos => {
          resolve({
            lng: pos.coords.longitude,
            lat: pos.coords.latitude
          })
        },
        () => {
          resolve({ lng: 116.397428, lat: 39.90923 })
        }
      )
    })
  }
}

export default new MapService()

对应运行截图

地图搜索功能
image

路线规划展示
image

五、本地状态管理:

5.1 数据结构设计

class TravelStore {
  data = {
    searchHistory: [],
    travelStats: {
      generated: 0,
      cities: []
    }
  }

  save() {
    localStorage.setItem('travel_data', JSON.stringify(this.data))
  }

  load() {
    const raw = localStorage.getItem('travel_data')
    if (raw) this.data = JSON.parse(raw)
  }
}

5.2 搜索历史管理

addSearch(query) {
  this.data.searchHistory.unshift({
    query,
    time: Date.now()
  })

  if (this.data.searchHistory.length > 10) {
    this.data.searchHistory.length = 10
  }

  this.save()
}

5.3 统计数据更新

addPlan(city) {
  this.data.travelStats.generated += 1

  if (!this.data.travelStats.cities.includes(city)) {
    this.data.travelStats.cities.push(city)
  }

  this.save()
}

对应运行截图

旅行数据统计
image

六、前后端协作能力

6.1 前端接口调用统一规范

export const chatAPI = (message) => {
  return axios.post('/api/chat', { message })
}

页面中:

const res = await chatAPI(inputMessage.value)
  • 前端不直接散落 axios
  • 接口层统一,方便后期修改

6.2 接口结果只做“消费”,不做业务判断

chatList.push({
  role: 'assistant',
  content: res.data.reply
})

前端不关心:

  • AI 如何生成
  • 后端如何处理

七、总结

通过本项目的开发,我在以下方面获得了明确提升:

  • 熟练使用Vue3 组合式 API 组织复杂页面逻辑
  • 掌握 Vite 工程化配置与开发流程
  • 学会通过接口约定与模块封装提升前后端协作效率