dev已有「店铺运营」按学校分组看数据,但缺少全国视角。
新增一级菜单 校区地图:
| 决策 | 结论 |
|---|---|
| 位置来源 | 本地高校坐标库自动匹配(2820 所),不选省市、不点地图、不填经纬度 |
| 未收录的学校 | ① 在线地理编码兜底(Photon)→ ② 仍失败则创建为「未定位」,不点亮,列表可点「重新定位」重试 |
| 坐标系 | 统一 GCJ-02(底图坐标系);数据源是 BD-09 需转换,在线兜底是 WGS84 需转换 |
| 省份 | 由坐标预先算好(点落省份多边形),不需要用户选 |
| 批量导入 | 不做 |
| 删除保护 | 有同名运营数据时二次确认 |
[新建学校] → 弹窗:输入「学校名称」(即时联想)
┌──────────────────────────────┐
│ 中国计量大学 浙江省 │ ← 本地库命中
│ 中国计量大学现代科技学院 浙江省 │
└──────────────────────────────┘
↓ 选中
地图自动飞到该点(zoom 8)→ 落标记(脉冲)→ 底部确认卡:
┌──────────────────────────────────────┐
│ 中国计量大学 · 浙江省 │
│ 坐标 120.3626, 30.3210(GCJ-02) │
│ [取消] [创建并点亮] │
└──────────────────────────────────────┘
↓
创建成功 → 点位橙色涟漪 + 学校名,列表新增一条
规则:
[尝试在线定位];在线也失败时提供 [先创建(未定位)]点列表项 → 右侧详情卡:
┌ 中国计量大学 ──────────────────┐
│ 浙江省 · 120.3626, 30.3210 │
│ 运营数据:9 家门店 · 最近 10-07 │
│ [重新匹配] [停用] [删除] │
└────────────────────────────────┘
若「店铺运营」中存在同名学校:
确定删除「中国计量大学」?
店铺运营中有 9 家门店使用了该名称,最近数据日期 2026-10-07。
删除学校不会删除运营数据。
[取消] [仍然删除]
| 操作 | 行为 |
|---|---|
| 滚轮 / 双指 | 缩放(zoom 3~12) |
| 拖拽 | 平移 |
| 悬停点位 | tooltip:学校名 · 省份 · 门店数 |
| 点击点位 | 选中并高亮,右侧滚动到对应卡片 |
| 搜索框(列表上方) | 过滤列表;点结果地图飞过去 |
| [回到全国] | 恢复默认视野 |
| 场景 | 展示 |
|---|---|
| 没有学校 | 地图灰显 + 中央「创建第一所学校」 |
| 存储不可用 | 地图正常渲染 + 顶部提示「学校数据暂不可用」+ 重试 |
| 底图加载失败 | 提示刷新,不渲染空画布 |
| 名称重复 | 保存时提示「已存在同名学校」 |
| 未定位学校 | 列表中灰色标签「未定位」,可重新定位 |
public/vendor/cn-universities.json(238KB,2820 所):
{
"中国计量大学": { "lng": 120.362644, "lat": 30.321047, "province": "浙江省" },
"浙江科技学院": { "lng": 120.025229, "lat": 30.220034, "province": "浙江省" }
}
生成方式(构建期一次性;数据已生成,生成脚本在实施阶段一并提供):
flwfdd/china-university-location(2820 所,百度坐标)province坐标系验证(以 Photon 返回的 WGS84 → GCJ-02 为参照):
| 学校 | 数据集原始(BD-09) | 转换后 GCJ-02 | 与参照偏差 |
|---|---|---|---|
| 清华大学 | 116.33337, 40.00964 | 116.32677, 40.00391 | 45m |
| 北京大学 | 116.31683, 39.99888 | 116.31031, 39.99288 | 33m |
| 武汉大学 | 114.37292, 30.54380 | 114.36651, 30.53748 | 274m |
| 中国计量大学 | 120.36904, 30.32740 | 120.36264, 30.32105 | 284m |
| 复旦大学 | 121.51077, 31.30187 | 121.50419, 31.29623 | 392m |
不转换直接用会是 850~1200m 的系统性偏移,所以转换是必须的。残差在校区尺度内(校区本身就有几百米跨度),可接受。
按顺序尝试,命中即止:
中国计量大学(下沙校区) → 中国计量大学)计量大学 → 中国计量大学)候选排序:精确 > 归一化 > 包含;同分时名称短的优先。最多返回 8 条,带省份用于区分。
在线地理编码(服务端发起,避免浏览器跨域):
https://photon.komoot.io/api/?q=<名称>&limit=5countrycode=CN 且 name 与输入相似度足够高的结果设计上把「在线兜底」做成可选动作(用户点按钮触发),不做成创建时自动请求——避免无网络环境下创建流程卡住。
geo(省级底图,roam)
├── effectScatter「已启用」:橙色 #ff6b35,rippleEffect,右侧名称标签
└── scatter「未启用 / 未定位」:灰色 #b8b2ad,无标签
点击、悬停、选中联动;同屏像素距离 <14px 的两点做 ≤8px 确定性偏移。
沿用 ops 存储(SQLite 默认 / PG 可切):
CREATE TABLE IF NOT EXISTS ops_school (
id text PRIMARY KEY, -- sch_20261020_a1b2c3
name text NOT NULL,
province text NOT NULL DEFAULT '',
lng real, -- GCJ-02;未定位时为 NULL
lat real,
source text NOT NULL DEFAULT 'local', -- local | geocode | none
enabled integer NOT NULL DEFAULT 1,
created_at text NOT NULL,
updated_at text NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS ops_school_name_idx ON ops_school (name);
lng/lat 允许 NULL = 未定位(不点亮)source 记录定位来源,便于排查ops_shop.school = ops_school.name 精确匹配,查询时聚合门店数与 MAX(date)| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /api/schools |
列表,含 enabled、坐标、门店数、最近数据日期 |
| GET | /api/schools/search?q= |
本地高校库联想(也可前端直接加载 JSON 搜索,二选一) |
| POST | /api/schools |
创建:{ name, lng?, lat?, province?, source? };缺坐标时按名称自动匹配 |
| POST | /api/schools/:id |
更新(改名 / 重新匹配 / 坐标) |
| POST | /api/schools/:id/toggle |
启用/停用 |
| POST | /api/schools/locate |
在线兜底:{ name } → { lng, lat, province, source } |
| DELETE | /api/schools/:id |
删除 |
校验:名称 1~60 且唯一;坐标若提供必须在 GCJ-02 中国范围(lng 73~136,lat 3~54)。
┌──────────────────────────────────────────────────────────────┐
│ 校区地图 + 新建学校 │
│ 已启用 3 / 共 5 │
├───────────────────────────────────┬──────────────────────────┤
│ │ 🔍 搜索 │
│ 中国地图(可缩放) │ 浙江省 2/3 │
│ │ ┌──────────────────────┐ │
│ ● 中国计量大学 │ │● 中国计量大学 [开] │ │
│ ● 浙江工商大学桐庐校区 │ │ 9 店 · 最近 10-07 │ │
│ ○ 浙江科技学院(未启用) │ ├──────────────────────┤ │
│ │ │○ 浙江科技学院 [关] │ │
│ [回到全国] │ │ 未关联运营数据 │ │
│ │ └──────────────────────┘ │
└───────────────────────────────────┴──────────────────────────┘
ops_shop.school 名称关联,仅做只读展示(门店数、最近日期)enabled=1 也不点亮ops_shop 同名数据 → 返回门店数 2 与最近日期enabled:false,写操作 503GET /api/schools 200(只读)
输入「中国计量大学」→ 联想出现 → 选中 → 地图飞到杭州下沙 → 创建 → 点位点亮 → 刷新仍在 → 列表显示关联门店数与最近日期 → 停用变灰 → 删除时若有运营数据出现二次确认。
scripts/build-university-data.js(数据生成脚本,含 BD-09 转换与省份归属;数据文件已就绪)public/vendor/cn-universities.json(已生成,待登记静态白名单)ops_school 表 + 存储方法(SQLite / PG)/api/schools 端点(含 search / locate / 关联查询 / 删除保护所需计数)public/schools.js:地图、联想、创建、编辑、启停、删除确认、列表联动index.html 菜单与页面、app.js 注册、style.css