This commit is contained in:
2026-07-31 09:05:01 +08:00
parent a701522ee0
commit 59e7c9bac6
6 changed files with 19 additions and 21 deletions
+1
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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