微信小程序「专业查询」重构全记录

微信小程序「专业查询」功能重构全记录

从一次搜索到完整展开交互,从 500 条数据截断到 180 万全量索引——乐道志愿助理专业查询模块的蜕变过程。


一、起点:一个简单的搜索框

改版前的专业查询页只有基本功能:输入专业名 → 搜到院校列表 → 展开看该院校匹配的几个专业和分数范围。交互到此为止。

问题很明显: - 看不到三年完整数据 — 只能看分数范围 - 看不到院校其他专业 — 只显示搜到的那个 - 看不到专业详情 — 没有概述、就业方向 - 没有导航出口 — 搜完就困住了


二、新设计:一站式院校卡片

目标:用户搜一个专业 → 看到招生院校 → 点开展示全部。

搜索"法学"
  → 院校卡片列表(重庆地区招生院校 × 200+)
  → 展开"西南政法大学":
    ├─ 🏫 院校简介(可折叠)
    ├─ ⭐ 法学 ← 搜索专业排第一,高亮
    │   ├─ 2023: 559分 | 2024: 587分 | 2025: 582分
    │   └─ [专业详情 ▸] 概述 / 男女比例 / 就业方向
    ├─ 知识产权
    │   ├─ 三年分数
    │   └─ [专业详情 ▸]
    └─ 刑事科学技术 ...

关键技术决策:展开时懒加载,不预取全部数据。点院校才调云函数拉取数据,同一次搜索内缓存。


三、踩坑:西南政法大学怎么搜不到?

用户选了重庆生源地,搜"法学",西南政法大学竟然不在结果里。这是西南政法啊——中国法学的招牌院校。

排查过程

第一层:年份过滤。 前端去掉了年份选择器,queryMajors 默认只查 2025 年。但西南政法每年都有法学——不是这个问题。

第二层:省份匹配。 数据里的省份是"重庆市"(带市),用户选的是"重庆"(不带市)。云函数做的是 === 严格比较。

// ❌ 旧代码
if (entry.p !== province.trim()) continue

// ✅ 修复后
const qProv = province.trim().replace(/市$/, '')
const eProv = (entry.p || '').replace(/市$/, '')
if (qProv !== eProv) continue

修完后多了 4 所学校,但西南政法还是没出现。

第三层:数据截断。 查原始 admission 数据,西南政法 + 法学 + 重庆的记录确实存在(559 分)。但 build_major_index.py 里有一行:

MAX_PER_MAJOR = 500  # 每个专业只保留前 500 条

"法学"是全国最热门的专业之一,全国数百所法学院校 × 30 省份 × 3 年 = 数千条记录。559 分排不进前 500,被直接截掉了。

修复:直接取消截断限制。 180 万条记录全部保留。


四、踩坑:60 秒超时

索引从 48 个 chunk 暴涨到 151 个,原来一次性灌入的方案在 60 秒内跑不完。

修复:链式分批。 每次只处理 15 个 chunk,完成后 fire-and-forget 调用下一步。151 个文件分 11 步自动串行跑完。

// 每步结尾
cloud.callFunction({
  name: 'seedMajorIndex',
  data: { step: step + 1 }
}).catch(e => console.error('链式调用失败:', e.message))

五、200+ 所学校怎么办?

法学搜出 200+ 所学校,用户需要快速定位。加了两个筛选:

  • 院校名称搜索:客户端即时过滤,输入"西南"马上只显示相关学校
  • 院校所在省份:选"重庆"只显示重庆的大学,云函数端过滤

后者在 queryMajors 里先查 universities 拿到该省全部院校名,再与专业索引结果取交集。


六、其他细节改进

问题 解决
展开院校后滚动位置不对 _scrollToExpandedCard() 自动滚到卡片顶部
返回直接退出页面 onBackPress 拦截,展开时先折叠再退出
页面销毁后仍在处理数据 _aborted 标记 + 所有异步回调检查
-- 无说明 竖排注释"表示该校当年未开设此专业"
在校人数缺少前缀 补上"在校生 X 人"

七、最终架构

pages/major/major.js ───── 搜索入口
  ├─ queryMajors (云函数) ── major_index 倒排索引
  │   ├─ RegExp 匹配专业名
  │   ├─ 省份/年份/科类/院校省份 过滤
  │   └─ 返回按学校分组的结果
  │
  └─ 展开院校:
      ├─ getSchoolAllMajors (云函数)
      │   ├─ universities → 院校简介
      │   ├─ admission → 全部专业 + 三年分数
      │   └─ major_details → 专业百科
      │
      └─ 懒加载专业详情:
          └─ getMajorDetails (已有云函数)

八、改动的文件清单

文件 改动
scripts/build_major_index.py 取消 500 条截断
cloudfunctions/seedMajorIndex/index.js 链式分批灌入
cloudfunctions/queryMajors/index.js 省份兼容 + year:all + 院校省份筛选
cloudfunctions/getSchoolAllMajors/* 新建,展开院校数据
pages/major/major.js 展开逻辑 + 返回拦截 + 院校筛选 + 退出清理
pages/major/major.wxml 新展开视图 + 院校筛选栏
pages/major/major.wxss 展开视图全套样式

九、部署清单

  1. 部署 seedMajorIndex(已跑完,数据已在库)
  2. 部署 queryMajors
  3. 部署 getSchoolAllMajors(首次)

三个云函数部署完即可上线。


2026-06-25 · 乐道志愿助理 · Claude Code

Links

Social