| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- const axios = require('axios')
- const db = require('./plugin/DataBase/db')
- const API_URL = 'http://222.178.152.79:100/api_v1/getSportRecord'
- // ===== 账号组成 =====
- let part1 = '23'
- let part2 = 995 // 第二部分
- let part3 = 1 // 第三部分
- let part4 = 1 // 第四部分
- // ===== 最大范围(可自行调整)=====
- const MAX_P3 = 20
- const MAX_P4 = 90
- // ===== 南泉校区 =====
- const nq = [106.594871,29.421079]
- // ===== 双桥校区 =====
- const sq = [105.778790,29.512079]
- /**
- * 计算两点经纬度之间的距离(单位:米)
- * @param {[number, number]} p1 [经度, 纬度]
- * @param {[number, number]} p2 [经度, 纬度]
- * @returns {number} 距离(米,浮点数)
- */
- function calcDistance(p1, p2) {
- const [lng1, lat1] = p1
- const [lng2, lat2] = p2
- console.log(`计算距离,点1: (${lat1}, ${lng1}),点2: (${lat2}, ${lng2})`)
- const toRad = d => d * Math.PI / 180
- const R = 6378137 // 地球半径(米,WGS84)
- const φ1 = toRad(lat1)
- const φ2 = toRad(lat2)
- const Δφ = toRad(lat2 - lat1)
- const Δλ = toRad(lng2 - lng1)
- const a =
- Math.sin(Δφ / 2) ** 2 +
- Math.cos(φ1) * Math.cos(φ2) *
- Math.sin(Δλ / 2) ** 2
- const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
- return R * c
- }
- // ===== 工具函数 =====
- const pad2 = n => String(n).padStart(2, '0')
- function genAccount() {
- return `${part1}${part2}${pad2(part3)}${pad2(part4)}`
- }
- function parsePathLine(pathLine) {
- return pathLine.split(';').map(p => {
- const [lat, lng] = p.split(',').map(Number);
- return [lng, lat];
- });
- }
- // ===== 进位逻辑 =====
- // 无数据:第三部分进位,必要时第二部分进位
- function advanceOnNoData() {
- part3++
- if (part3 > MAX_P3) {
- part3 = 1
- part2++
- console.log('>>> 第三部分耗尽,第二部分进位为:', part2)
- }
- part4 = 1
- }
- // 有数据:第四部分进位
- function advanceOnHasData() {
- part4++
- if (part4 > MAX_P4) {
- part4 = 1
- part3++
- if (part3 > MAX_P3) {
- part3 = 1
- part2++
- console.log('>>> 第四、三部分耗尽,第二部分进位为:', part2)
- }
- }
- }
- // ===== 单次请求 =====
- async function fetchOnce() {
- const account = genAccount()
- console.log('\n请求 account:', account)
- const res = await axios.post(
- API_URL,
- `account=${account}&startdate=2020-01-01&enddate=2025-12-31`,
- { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
- )
- const data = res.data
- // ❌ 无数据
- if (!data || !data.data || data.data.length === 0) {
- console.log('无 data,执行进位')
- advanceOnNoData()
- return
- }
- // ✅ 有数据
- for (let index = 0; index < data.data.length; index++) {
- const item = data.data[index]
- if (item.status !== 1) continue
- const coords = parsePathLine(item.pathLine)
- const pathLineJson = JSON.stringify(coords)
- const sq_distance = calcDistance(sq, coords[0])
- const nq_distance = calcDistance(nq, coords[0])
- console.log(`双桥校区距离起点: ${sq_distance.toFixed(2)} 米,南泉校区距离起点: ${nq_distance.toFixed(2)} 米`)
- const run_zone_name = sq_distance < nq_distance ? '重庆工程学院双桥校区' : '重庆工程学院南泉校区'
- const sql = `
- INSERT INTO path_data
- (distance, time, calorie, speed, data, run_zone_name)
- VALUES (?, ?, ?, ?, ?, ?)
- `
- await db.query(sql, [
- item.distance,
- item.duration,
- item.calorie,
- item.distribution,
- pathLineJson,
- run_zone_name
- ])
- console.log(
- `已保存到数据库。距离:${item.distance} 米,时长:${item.duration} 秒,路径点:${coords.length} 个`
- )
- }
- advanceOnHasData()
- }
- // ===== 主循环 =====
- (async function start() {
- while (true) {
- try {
- await fetchOnce()
- } catch (e) {
- console.error('请求异常:', e.message)
- }
- // 控制请求频率
- await new Promise(r => setTimeout(r, 200))
- }
- })()
|