1
This commit is contained in:
@@ -7,6 +7,7 @@ type SearchPoiReq struct {
|
||||
Keywords string `json:"keywords" dc:"搜索关键词(和行业分类二选一,或同时使用)"`
|
||||
Types string `json:"types" dc:"行业分类编码(如 050000=餐饮,多个用|分隔,高德详见分类表)"`
|
||||
City string `json:"city" dc:"城市名称(文本搜索时使用)"`
|
||||
District string `json:"district" dc:"区县名称(选中具体区县时使用,此时不再展开城市下的所有区县)"`
|
||||
Longitude float64 `json:"longitude" dc:"中心点经度(周边搜索时使用)"`
|
||||
Latitude float64 `json:"latitude" dc:"中心点纬度(周边搜索时使用)"`
|
||||
Radius int `d:"1000" json:"radius" dc:"搜索半径(米,默认1000,最大50000)"`
|
||||
|
||||
+11
-16
@@ -23,7 +23,7 @@ var PoiService = new(poiService)
|
||||
var amapClient = g.Client().Timeout(30 * time.Second)
|
||||
|
||||
const (
|
||||
maxOffset = 25 // 每页展示条数(高德最大25)
|
||||
maxOffset = 20 // 每页展示条数
|
||||
maxPage = 100 // 高德API最大页数
|
||||
)
|
||||
|
||||
@@ -91,9 +91,12 @@ func (s *poiService) Search(ctx context.Context, req *dto.SearchPoiReq) (res *dt
|
||||
if types != "" {
|
||||
req.Types = types
|
||||
|
||||
// 获取区县列表,按区县 × 分类循环搜索
|
||||
g.Log().Info(ctx, "搜索参数", "city", req.City, "district", req.District, "types", req.Types)
|
||||
// 确定搜索范围:选中区县则只搜该区县,否则获取城市下所有区县
|
||||
var places []string
|
||||
if req.City != "" {
|
||||
if req.District != "" {
|
||||
places = []string{req.District}
|
||||
} else if req.City != "" {
|
||||
places, err = s.fetchCityDistricts(ctx, req.City, apiKey)
|
||||
if err != nil {
|
||||
g.Log().Warning(ctx, "获取区县列表失败,使用城市级搜索", "error", err)
|
||||
@@ -204,27 +207,20 @@ func (s *poiService) searchByTypes(ctx context.Context, apiKey string, req *dto.
|
||||
all := make([]*dto.PoiItem, 0, needTotal)
|
||||
seen := map[string]bool{}
|
||||
|
||||
// 有区县列表时:按区县 × 分类循环,每组合获取全部分页,全局限定最大请求数
|
||||
// 有区县列表时:按区县 × 分类循环,每组合获取全部分页
|
||||
if len(places) > 0 {
|
||||
maxAPICalls := 150
|
||||
callCount := 0
|
||||
rateLimitDelay := 200 * time.Millisecond
|
||||
var hasCalls bool
|
||||
|
||||
for _, place := range places {
|
||||
if callCount >= maxAPICalls {
|
||||
break
|
||||
}
|
||||
for _, tc := range typeCodes {
|
||||
if callCount >= maxAPICalls {
|
||||
break
|
||||
}
|
||||
if callCount > 0 {
|
||||
if hasCalls {
|
||||
time.Sleep(rateLimitDelay)
|
||||
}
|
||||
|
||||
// 第1页:获取count以计算总页数
|
||||
pois, totalCount := s.fetchAmapPage(ctx, apiKey, baseUrl, req.Keywords, tc, place, 1, offset)
|
||||
callCount++
|
||||
hasCalls = true
|
||||
|
||||
if len(pois) == 0 {
|
||||
continue
|
||||
@@ -248,10 +244,9 @@ func (s *poiService) searchByTypes(ctx context.Context, apiKey string, req *dto.
|
||||
}
|
||||
|
||||
// 第2页起继续获取
|
||||
for ap := 2; ap <= totalPages && callCount < maxAPICalls; ap++ {
|
||||
for ap := 2; ap <= totalPages; ap++ {
|
||||
time.Sleep(rateLimitDelay)
|
||||
morePois, _ := s.fetchAmapPage(ctx, apiKey, baseUrl, req.Keywords, tc, place, ap, offset)
|
||||
callCount++
|
||||
if len(morePois) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Pointly-Tel - 高德POI商户查询</title>
|
||||
<script type="module" crossorigin src="/assets/index-C_dWvpn_.js"></script>
|
||||
<script type="module" crossorigin src="/assets/index-DDfvPHBE.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-Bm3pUfxc.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
+2
-1
@@ -425,13 +425,14 @@ async function doSearch() {
|
||||
const opts = {
|
||||
keywords: keywords.value.trim(),
|
||||
city: regionValues.value[1] || '',
|
||||
district: regionValues.value[2] || '',
|
||||
page: page.value,
|
||||
longitude: centerLng.value,
|
||||
latitude: centerLat.value,
|
||||
radius: radius.value,
|
||||
types: searchTypes.value,
|
||||
}
|
||||
const data = await searchPoi(opts.keywords, opts.city, opts.page, opts.longitude, opts.latitude, opts.radius, opts.types)
|
||||
const data = await searchPoi(opts.keywords, opts.city, opts.page, opts.longitude, opts.latitude, opts.radius, opts.types, opts.district)
|
||||
results.value = data.list || []
|
||||
total.value = data.total || 0
|
||||
maxPage.value = Math.max(1, Math.ceil(total.value / 20))
|
||||
|
||||
+2
-1
@@ -5,11 +5,12 @@ const api = axios.create({
|
||||
timeout: 30000,
|
||||
})
|
||||
|
||||
export async function searchPoi(keywords, city = '', page = 1, longitude = 0, latitude = 0, radius = 1000, types = '') {
|
||||
export async function searchPoi(keywords, city = '', page = 1, longitude = 0, latitude = 0, radius = 1000, types = '', district = '') {
|
||||
const params = { page }
|
||||
if (keywords) params.keywords = keywords
|
||||
if (types) params.types = types
|
||||
if (city) params.city = city
|
||||
if (district) params.district = district
|
||||
if (longitude) params.longitude = longitude
|
||||
if (latitude) params.latitude = latitude
|
||||
if (radius) params.radius = radius
|
||||
|
||||
Reference in New Issue
Block a user