补全页的类别候选取「库里在用的 ∪ 静态表」

这一页原来只列静态表(30 个 MapKit 枚举),库里真在用的值不在候选里——
真机自己写的中文类别(一般道路 / 彩票店 / 租车点 / 美食街)只能手打,
一不小心就挑个名字相近的静态枚举,跟已有数据并存成两种,同一个意思分两处统计。

现在三段拼,同一个值只出现一次:
  1. 数据集里在用的,按地点数降序,标「中文名(在用 N)」
  2. 真机用过的 12 种(当前数据里还没有的),标「真机用过」
  3. 其余常见 MapKit 类别
在用的那份信息更准,所以顶掉静态表里的说明——既在用又在静态表里的只出现一次。

真实数据实测:36 项 = 16 在用 + 18 静态 +(不动)+(其它「自己写」),零重复;
排在前面的是 餐厅(在用 51)/ 商店(在用 29)/ … / 一般道路(在用 5)。
This commit is contained in:
tamakyi
2026-09-20 10:07:00 +08:00
parent da6fe54ab4
commit cbb45b6d6b
2 changed files with 100 additions and 6 deletions
+46 -6
View File
@@ -206,6 +206,11 @@ func (s *Server) adminFillupPage(w http.ResponseWriter, r *http.Request) {
s.serverError(w, r, err)
return
}
usedCats, err := s.usedCategories(ctx, ds.ID)
if err != nil {
s.serverError(w, r, err)
return
}
total := len(rows)
hinted := 0
for _, row := range rows {
@@ -223,7 +228,7 @@ func (s *Server) adminFillupPage(w http.ResponseWriter, r *http.Request) {
rows = rows[from:to]
s.render(w, "admin/fillup", FillupData{
Page: p, Rows: rows, Activities: acts, Categories: fillupCategories(),
Page: p, Rows: rows, Activities: acts, Categories: fillupCategories(usedCats),
Total: total, WithHint: hinted, PageNo: pageNo, PageCount: pageCount,
})
}
@@ -255,8 +260,32 @@ type fillupCategory struct {
Label string
}
// fillupCategories 是类别下拉的选项:真机用过的 12 种在前,其余常见 MapKit 类别在后。
func fillupCategories() []fillupCategory {
// usedCategories 列出这个数据集里真在用的类别(按地点数从多到少),排在静态表前面。
// 候选得先跟已有数据对得上——否则用户会在这一页挑一个名字相近的静态枚举,
// 跟库里已有的值并存成两种,同一个意思分两处统计。
func (s *Server) usedCategories(ctx context.Context, datasetID int64) ([]fillupCategory, error) {
rows, err := s.db.QueryContext(ctx, `SELECT poi_category, count(*) FROM places
WHERE dataset_id=$1 AND COALESCE(poi_category,'')<>'' GROUP BY 1 ORDER BY 2 DESC, 1`, datasetID)
if err != nil {
return nil, err
}
defer rows.Close()
var out []fillupCategory
for rows.Next() {
var v string
var n int
if err := rows.Scan(&v, &n); err != nil {
return nil, err
}
// 值可能是 MKPOICategory 枚举,也可能是真机自己写的中文——poiCategoryLabel 两种都认
out = append(out, fillupCategory{v, fmt.Sprintf("%s(在用 %d)", poiCategoryLabel(v), n)})
}
return out, rows.Err()
}
// fillupCategories 是类别下拉的选项:数据集里真在用的排最前面,再跟真机用过的 12 种、
// 其余常见 MapKit 类别。同一个值只出现一次——在用的那份信息更准,就顶掉静态表里的说明。
func fillupCategories(inUse []fillupCategory) []fillupCategory {
known := []string{
"MKPOICategoryRestaurant", "MKPOICategoryStore", "MKPOICategoryPublicTransport",
"MKPOICategoryHotel", "MKPOICategoryLandmark", "MKPOICategoryFoodMarket",
@@ -271,12 +300,23 @@ func fillupCategories() []fillupCategory {
"MKPOICategoryNationalPark", "MKPOICategoryAquarium", "MKPOICategoryAmusementPark",
"MKPOICategoryGasStation", "MKPOICategoryCarRental", "MKPOICategoryMarina",
}
out := make([]fillupCategory, 0, len(known)+len(extra))
seen := make(map[string]bool, len(inUse)+len(known)+len(extra))
out := make([]fillupCategory, 0, len(inUse)+len(known)+len(extra))
push := func(c fillupCategory) {
if c.Value == "" || seen[c.Value] {
return
}
seen[c.Value] = true
out = append(out, c)
}
for _, c := range inUse {
push(c)
}
for _, c := range known {
out = append(out, fillupCategory{c, poiName(c) + "(真机用过)"})
push(fillupCategory{c, poiName(c) + "(真机用过)"})
}
for _, c := range extra {
out = append(out, fillupCategory{c, poiName(c)})
push(fillupCategory{c, poiName(c)})
}
return out
}