feat:自提点

This commit is contained in:
dzc committed 2025-10-16 16:56:35 +08:00
1 parent 8dba6a0894
commit cf8aa56c9c
13 files changed
+1767 -15

No files matched your search

+187
View File
@@ -0,0 +1,187 @@
/**
* JSONP 工具函数
* 用于跨域请求
*/
interface JsonpOptions {
timeout?: number
callbackName?: string
callbackParam?: string
debug?: boolean
}
/**
* JSONP 请求
* @param url 请求地址
* @param options 配置选项
* @returns Promise
*/
export function jsonp(url: string, options: JsonpOptions = {}): Promise<any> {
const {
timeout = 15000,
callbackName = `jsonp_callback_${Date.now()}_${Math.random().toString(36).substr(2)}`,
callbackParam = "callback",
debug = false
} = options
if (debug) {
console.log('[JSONP] 发起请求:', url)
console.log('[JSONP] 回调函数名:', callbackName)
}
return new Promise((resolve, reject) => {
// 创建 script 标签
const script = document.createElement("script")
// 设置超时
const timer = setTimeout(() => {
cleanup()
const error = new Error(`JSONP request timeout after ${timeout}ms`)
if (debug) {
console.error('[JSONP] 请求超时:', error)
}
reject(error)
}, timeout)
// 清理函数
const cleanup = () => {
if (script.parentNode) {
script.parentNode.removeChild(script)
}
if ((window as any)[callbackName]) {
delete (window as any)[callbackName]
}
clearTimeout(timer)
}
// 设置全局回调函数
;(window as any)[callbackName] = (data: any) => {
if (debug) {
console.log('[JSONP] 收到响应:', data)
}
cleanup()
resolve(data)
}
// 处理错误
script.onerror = (event) => {
cleanup()
const error = new Error("JSONP request failed to load script")
if (debug) {
console.error('[JSONP] 脚本加载失败:', event)
}
reject(error)
}
// 构建请求 URL
const separator = url.includes("?") ? "&" : "?"
const requestUrl = `${url}${separator}${callbackParam}=${callbackName}`
if (debug) {
console.log('[JSONP] 完整请求URL:', requestUrl)
}
// 发起请求
script.src = requestUrl
script.async = true
document.head.appendChild(script)
})
}
/**
* 腾讯地图 API JSONP 请求封装
*/
export class TencentMapAPI {
private apiKey: string
private debug: boolean
constructor(apiKey: string, debug: boolean = false) {
this.apiKey = apiKey
this.debug = debug
}
/**
* 逆地址解析
* @param lat 纬度
* @param lng 经度
* @returns Promise
*/
async reverseGeocode(lat: number, lng: number): Promise<any> {
const url = `https://apis.map.qq.com/ws/geocoder/v1/?location=${lat},${lng}&key=${this.apiKey}&get_poi=1&output=jsonp`
if (this.debug) {
console.log('[TencentMapAPI] 逆地址解析请求:', { lat, lng })
}
try {
const data = await jsonp(url, { debug: this.debug })
if (this.debug) {
console.log('[TencentMapAPI] 逆地址解析响应:', data)
}
return data
} catch (error) {
console.error("逆地址解析失败:", error)
throw error
}
}
/**
* 地址搜索
* @param keyword 搜索关键词
* @param boundary 搜索范围
* @returns Promise
*/
async searchLocation(keyword: string, boundary: string = "region(全国,0)"): Promise<any> {
const url = `https://apis.map.qq.com/ws/place/v1/search?boundary=${encodeURIComponent(boundary)}&keyword=${encodeURIComponent(
keyword,
)}&page_size=10&page_index=1&key=${this.apiKey}&output=jsonp`
if (this.debug) {
console.log('[TencentMapAPI] 地址搜索请求:', { keyword, boundary })
}
try {
const data = await jsonp(url, { debug: this.debug })
if (this.debug) {
console.log('[TencentMapAPI] 地址搜索响应:', data)
}
return data
} catch (error) {
console.error("地址搜索失败:", error)
throw error
}
}
/**
* 地址解析(正向地理编码)
* @param address 地址
* @returns Promise
*/
async geocode(address: string): Promise<any> {
const url = `https://apis.map.qq.com/ws/geocoder/v1/?address=${encodeURIComponent(address)}&key=${this.apiKey}&output=jsonp`
try {
const data = await jsonp(url)
return data
} catch (error) {
console.error("地址解析失败:", error)
throw error
}
}
/**
* POI 搜索
* @param keyword 搜索关键词
* @param boundary 搜索范围
* @returns Promise
*/
async searchPOI(keyword: string, boundary: string = "region(全国,0)"): Promise<any> {
return this.searchLocation(keyword, boundary)
}
}
export default jsonp