ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

全流程解析:校园二手交易微信小程序开发实战

全流程解析:校园二手交易微信小程序开发实战

1. 项目定位与核心需求拆解

先说说这个项目本身。校园二手交易平台,本质上是把大学校园里闲置物品的线下流转搬到线上。每年毕业季,学长学姐的考研资料、自行车、台灯、收纳箱,成堆成堆地当废品处理,而新生又在花高价买全新的。这个信息差就是项目存在的核心价值。

这类项目常被选作课程设计或独立开发的练手项目,因为它业务边界清晰、用户群体明确、功能复杂度适中,既能覆盖完整的开发流程,又不会因为业务过于庞大而失控。而且微信小程序作为载体有一个天然优势——不需要用户额外下载App,扫码即用,非常契合校园场景下临时性、高频次的使用习惯。

我在拆解这类项目需求时,习惯先把用户故事列出来,再反推功能模块。这个项目里核心用户角色其实只有两种:

买方的痛点是:想找便宜的教材和生活用品,但不知道哪里有,逛线下跳蚤市场又受时间限制。卖方的痛点是:东西扔了可惜,挂闲鱼上要拍照、要等快递、要跟陌生人讨价还价,太麻烦。

基于这两类用户的诉求,核心功能链路可以收敛为:发布商品 → 浏览/搜索商品 → 联系卖家 → 线下交易 → 交易完成互评。每一环都很清晰,没有复杂的分账、物流、售后体系,非常适合作为项目的第一期目标。

另外还有一个容易被忽略的需求——信任问题。校园交易场景里,用户会天然倾向跟“同校同学”交易,因为大家活动范围重叠、见面方便、跑得了和尚跑不了庙。所以“学生身份认证”和“校区/院系信息展示”这两个设计点,对平台信任度的影响非常大。这一点我在很多同类项目里见过被直接略过,结果就是平台里混入大量校外广告号,体验断崖式下降。

1.1 为什么选微信小程序而不是App或H5

这三个方案我都实际对比过,直接说结论:如果目标是“快速上线、覆盖校园用户、控制开发成本”,微信小程序是当前最合理的选择。

  • App方案:开发和维护成本最高,而且要求学生主动下载安装,这个门槛在校园场景下是致命的。很多学生手机内存本来就不够用,你让他为了买个二手台灯装一个App,他会直接关掉页面。
  • H5方案:虽然免安装,但入口太浅。用户关掉浏览器标签页就等于流失了,没有任何留存手段。而且H5在支付、消息推送、调用系统能力方面都受限。
  • 微信小程序:内置在微信里,打开路径极短。更重要的是它有“最近使用”列表,用户想再进来看一眼,下拉就能找到。还自带订阅消息能力,交易状态变更可以直接推送给用户。对于校园二手交易这种低频、但每次使用都追求“快”的场景,小程序的匹配度是最高的。

1.2 校园场景下的业务边界

做校园项目最容易犯的错就是把业务边界无限扩大。我见过有人把“校园二手交易”直接做成了“淘宝校园版”,加购物车、加运费模板、加在线支付、加物流跟踪,最后项目烂尾在开发阶段。

校园二手交易和电商平台有着本质区别:交易双方在线下,交易金额小,商品单价通常只有几十元,而且不存在跨校区快递配送的需求。所以项目设计上必须做减法,砍掉不必要的功能。我建议第一版只保留以下核心链路:

  • 用户登录与身份认证(微信授权 + 学生信息绑定)
  • 商品发布(九宫格图片、标题、描述、价格、成色、交易地点)
  • 商品列表与分类筛选(按品类、按价格区间、按最新发布)
  • 商品详情页 + 联系卖家(展示微信号/手机号,或通过会话组件沟通)
  • 交易状态管理(在售 / 锁定 / 已售 / 下架)
  • 收藏与搜索

支付环节我建议第一期先不做。校园二手交易的特点是强线下属性,买卖双方会当面验货、当面付款。如果强行接入在线支付,就必然引入退款、纠纷仲裁、平台担保等重运营逻辑,完全超出了个人开发者的能力边界。第一版用“线下交易 + 状态标记”的方式,反而更真实地还原了校园闲置流转的场景。

2. 技术选型与整体架构

技术选型没有绝对的对错,只有适不适合当前阶段。对于个人开发者做校园类小程序,核心诉求是开发效率高、部署成本低、维护简单。我推荐一套组合方案,也是我实际跑通过的架构。

2.1 小程序前端:原生还是框架

小程序前端有两条路:原生小程序和跨端框架(uni-app、Taro等)。我的建议是:如果这个项目的目标是学习或完成课程设计,用原生小程序就够了,不要为了“框架经验”强行引入跨端框架。

原因有三个:

  • 原生框架写出的代码没有中间层转换的性能损耗,真机渲染更稳定。
  • 这个项目涉及的小程序API范围不大(登录、上传、列表渲染、路由),原生语法完全够用。
  • 原生小程序的调试工具对新手更友好,出问题好排查。

当然,如果已经有Vue或React基础,用uni-app在编辑器里写起来确实舒服,而且以后想跨端发布App时能省很多事。但从项目可维护性的角度,原生小程序仍然是稳妥之选。

2.2 后端方案:自建服务还是云开发

这是近几年做小程序项目最关键的分岔路。微信官方推出的云开发能力,提供云数据库、云函数、云存储,几乎是为小程序项目量身定制的。而传统方案是自己搭建后端服务,部署到服务器上,走完整的请求-响应链路。

我在这里说几句实在话。如果项目定位是“独立开发 + 快速上线 + 低运维成本”,云开发能把整体工作量砍掉至少三分之一。不需要自己买服务器、配域名、办备案、维护Nginx,也不需要写登录态校验,云开发自带openid鉴权体系,直接能拿到用户的唯一身份标识。这些都是自建服务器时最耗时又最容易出错的环节。

但云开发也有明显天花板:数据库操作用的是它封装好的API,复杂事务支持较弱,而且一旦后续要加复杂的推荐算法或数据分析,扩展起来会很别扭。如果项目规划比较长远,或者想借这个项目练后端技能,那自建服务必然是更好的选择。

稳妥的组合方案是:前端用原生小程序,后端用自建服务(Spring Boot / Node.js),数据库用MySQL,对象存储用云存储或自建OSS。这个方案技术栈通用性强、不绑定特定平台、资料丰富遇到问题好查,也是我在这篇文章里要展开讲的方案。

2.3 整体架构图和数据流向

整个系统可以分为三层。最外层是微信小程序客户端,负责界面展示和交互。中间是后端服务层,负责业务逻辑、权限控制、数据校验。最底层是数据存储层,负责持久化用户信息、商品信息、交易记录等数据。

数据流向是这样的:小程序端发起请求 → 云网关或API网关转发到后端服务 → 后端解析参数、校验身份、访问数据库 → 返回结构化数据 → 小程序渲染页面。上传图片时,小程序直接把文件传到对象存储,然后把返回的URL存入数据库。

有一个细节需要注意:小程序请求的域名必须是HTTPS,而且在微信公众平台后台要配置为合法域名。开发阶段可以在开发者工具里勾选“不校验合法域名”来跳过限制,但体验版和正式版必须配置真实域名。这一步很多人做到一半才发现,卡在部署环节出不去。

3. 核心功能模块的难点与实现思路

功能模块拆开看每一个都不难,但连起来之后会出现几个需要重点设计的环节。挑几个我实际开发中踩过坑、也花过心思的地方展开聊。

3.1 用户登录与身份认证

微信小程序的标准登录流程是:前端调用wx.login拿到临时code,传给后端,后端拿着code + appid + secret 去微信接口换session_key和openid。这里的openid是微信用户在当前小程序下的唯一标识,或者说ID,所有业务数据都以它作为用户主键。

云开发环境自带了免鉴权逻辑,云函数内通过上下文直接拿openid,少了很多事。自建服务则需要自己做一套登录态管理:后端在用户首次登录后,可以把openid存库并签发一个自定义token,前端后续请求都带着这个token,后端通过拦截器校验有效性。

身份认证是校园平台特有的需求。常见做法是让学生填学号和学校邮箱,然后发一封验证邮件。但问题来了——学生邮箱的收件延迟不稳定,有时候要等好几分钟,体验很差。我后来改用另一种方案:把“认证与否”从硬性门槛降级为“信任标识”——没有认证的用户也可以发布商品,但标题栏会带一个“未认证”的标签;认证用户可以发布商品并带“已认证”标识。不为了验证流程为难用户,但又给交易双方提供了判断依据。实测下来,这种方式对平台友好度的影响最小。

3.2 商品发布与状态机

商品发布是整个平台的核心数据入口,必须设计得合理。我先定义商品对象的核心字段:

  • 标题(限制20字以内,标题越短越明确,会减少沟通成本)
  • 描述(限制500字以内,自由文本)
  • 图片列表(最多9张,首张作为封面图)
  • 价格(只允许数字,单位元)
  • 成色(全新/几乎全新/轻微使用痕迹/明显使用痕迹/已破损)
  • 交易地点(通过地图选点或手动输入校区+楼栋)
  • 分类(教材教辅/数码电器/生活用品/运动器材/服饰美妆/其他)
  • 联系方式切换开关(默认隐藏,用户点击“查看联系方式”后展示,增加一层防爬门槛)

商品的状态流转也值得提前设计。我定义了四个状态:

  • 在售(visible=1):正常出现在列表和搜索中
  • 锁定(visible=0,locked=1):用户点击“我已卖出”或“我找到买家”时进入,相当于占位状态
  • 已售(visible=0,locked=1,status=2):双方完成交易后标记
  • 下架(visible=0):用户主动下架或超过有效期自动下架

为什么需要“锁定”这个中间状态?因为现实中经常出现这种情况:A用户看中一台显示器,联系卖家说“我明天来拿”,但东西还没拿走。如果此时商品还挂在“在售”状态并没有“锁定”,别人也能看到并来问,就会产生两个买家被同时接待、先到先得还是价高者得等尴尬局面。加了锁定状态以后,卖家可以主动把商品标记为“已被预订”,减少无效沟通。

还有一个细节是商品的有效期。校园商品的时效性很强,一个台灯挂出来一周没卖掉,大概率就是定价或商品本身有问题。我设置了30天自动下架的机制,过期后通知用户“重新上架”即可。这样能保证列表里的商品始终是比较“新鲜”的,而不是积压了一年的僵尸商品。

3.3 交易安全与防骚扰

校园平台虽然信任度比开放社会平台高,但照样需要防护策略。我实际处理过的问题有:校外广告党刷屏、有人发布违规商品(香烟、违规电器等)、有人拿到联系方式后骚扰卖家。

对策分三层:

内容过滤:发布商品前做关键词过滤。我用的是一个简单的前端关键词列表 + 后端敏感词库双重校验,命中直接拦截并提示修改。不要花太多精力在AI审核上,对校园平台来说关键词库足够用。

操作频率限制:每个用户每天发布商品上限设为20个,每个商品每天最多被查看联系方式10次。这样可以有效防止爬虫脚本批量抓取信息。限制频率在拦截非法爬虫和异常操作方面的性价比是最高的。

举报机制:商品详情页放举报入口,用户提交举报原因后,商品自动进入隐藏状态,由管理员在后台审核处理。虽然个人项目没有专职运营,但每天登录后台看一眼举报列表,成本并不高。用隐藏代替直接删除,既避免了误杀,也让流程更可操作。

3.4 搜索与推荐

校园商品数量级通常不大,几百到几千这个量级。这种数据规模,直接上Elasticsearch搜索引擎属于杀鸡用牛刀。MySQL的全文索引足够支撑,但需要注意写法。

我用的方案是:标题 + 描述两个字段做LIKE模糊匹配,商品标题加权排序优先展示。核心搜索逻辑是:

SELECT * FROM goods WHERE title LIKE '%关键词%' OR description LIKE '%关键词%' ORDER BY (title LIKE '%关键词%') DESC, publish_time DESC

这种写法在小数据量下性能完全够用。如果非要上搜索引擎,建议等商品量超过5万条再考虑,现在不要给自己增加无谓的运维复杂度。

3.5 消息通知的设计取舍

交易过程中最关键的节点是“有人对你的商品感兴趣”,所以推送场景是:用户收藏或点击“我想要”时,给卖家推送一条订阅消息。

小程序的订阅消息有一个限制,用户必须点击授权才会推送,而且一次性订阅只能推送一条。所以设计上不能依赖订阅消息做会话,它只适合做“通知提醒”,不适合做沟通主渠道。

我的做法是:

  • 用户对商品点“我想要”→ 给卖家推送一条订阅消息 → 消息内容是“有人对你发布的xx商品感兴趣”
  • 同时在商品详情页展示卖家的微信号(脱敏展示,点击复制)

注意,复制微信号这个功能在小程序里有接口可以直接调,代码很简单。核心逻辑是:

wx.setClipboardData({ data: '微信号字符串', success: () => wx.showToast({ title: '微信号已复制,去添加好友吧' }) })

这样把即时沟通的闭环交给微信本身去解决,不需要自己在平台内做聊天系统。省去了IM开发和内容审核的负担,平台反而更简洁。

4. 数据库设计与关键表结构

数据表的设计决定了这个项目能跑多稳。我按核心业务域拆成五张表:用户表、商品表、收藏表、举报表、浏览记录表。另外还有一张管理员表,独立于普通用户体系。

4.1 用户表和商品表的设计细节

用户表的重点字段:

CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `openid` varchar(64) NOT NULL COMMENT '微信openid', `nickname` varchar(50) DEFAULT NULL, `avatar_url` varchar(255) DEFAULT NULL, `student_id` varchar(20) DEFAULT NULL COMMENT '学号', `campus` varchar(50) DEFAULT NULL COMMENT '校区', `college` varchar(50) DEFAULT NULL COMMENT '院系', `is_verified` tinyint(1) DEFAULT 0 COMMENT '是否通过学生认证', `phone` varchar(20) DEFAULT NULL, `create_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `idx_openid` (`openid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

商品表在上一节列过字段,这里补充主表和索引的设计思路。给title加普通索引即可,不需要全文索引(数据量小,且MySQL的全文索引对中文分词支持一般,LIKE足够)。

商品表的索引设计:

KEY `idx_category` (`category_id`), KEY `idx_status` (`status`), KEY `idx_publish_time` (`publish_time`)

查询“某个分类下所有在售商品、按时间倒序”这个高频SQL,最合理的做法是建立联合索引(category_id, status, publish_time)。注意,单列索引在组合查询时的效果不稳定,MySQL的优化器可能只走其中一个索引,这是新手最不容易察觉的性能问题。

4.2 为什么给openid建唯一索引

这一点单独拿出来说。openid是微信侧的用户唯一标识,它是所有用户操作逻辑的锚点。如果不建唯一索引,同一个用户换头像换昵称后重新授权,就可能在表里产生重复openid记录,业务数据关联就会乱掉。

MySQL不允许重复的机制是唯一索引,插入重复值时会被拦截。代码里要捕获这个异常并走查询权重判断。不过更推荐的做法是通过openid查询用户存在与否来决定是登录还是注册,把重复写入作为异常兜底,而不是作为常规业务逻辑。

4.3 收藏表和浏览记录表

收藏表其实是个简单的多对多关系表:

CREATE TABLE `favorite` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) NOT NULL, `goods_id` int(11) NOT NULL, `create_time` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_user_id` (`user_id`), KEY `idx_goods_id` (`goods_id`), UNIQUE KEY `uk_user_goods` (`user_id`, `goods_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

唯一约束uk_user_goods保证同一个用户不能重复收藏同一件商品。浏览记录表用于“猜你喜欢”推荐,因为校园平台数据量不大,我直接用商品标题里的关键词匹配计算相似度,没有引入额外算法。

4.4 管理员后台的独立设计

个人项目的后台不需要重设计。管理员表直接复用user表,加一个role字段即可,取值是user、admin。用户进入“我的”页面时,如果role为admin,展示“管理后台”入口。

管理后台的功能只需要一块:审核举报内容并处理违规商品。列表展示待审核举报、被举报商品的信息、举报理由,管理员可以执行“隐藏商品”“下架商品”或“忽略举报”。不需要大而全的运营后台,够用就行。

5. 实操过程:从接口设计到前后端联调

这一部分直接进入实操层面。我给出一套可落地的接口定义和小程序端实现思路,包含真实的代码片段和联调注意事项。

5.1 接口设计与统一返回格式

后端接口走RESTful风格,统一使用JSON格式的返回结构:

{ "code": 0, "msg": "success", "data": {} }

code为0表示成功,非0表示失败,msg是对调用方的提示语。这样的封装方式可以保证前端异常分支判断保持一致。

核心接口清单:

  • POST /api/user/login:微信登录,参数为wx.login的code,返回token
  • GET /api/user/info:获取当前用户信息
  • POST /api/user/verify:提交学生认证信息
  • POST /api/goods/publish:发布商品,参数为商品字段
  • GET /api/goods/list:分页获取商品列表,支持分类/关键词筛选
  • GET /api/goods/detail/{id}:获取商品详情
  • POST /api/goods/favorite:收藏/取消收藏商品
  • POST /api/goods/lock:锁定/解锁商品
  • GET /api/my/goods:我发布的商品列表

分页参数统一走page和pageSize,返回数据结构为:

{ "list": [], "total": 100, "hasMore": true }

hasMore字段用于前端触底加载的判断,比前端自己算页码要简单可靠得多。

5.2 登录态的完整流程

后端登录接口的核心逻辑:

# 以Flask为例 @app.route('/api/user/login', methods=['POST']) def login(): code = request.json.get('code') # 调用微信接口换openid resp = requests.get( 'https://api.weixin.qq.com/sns/jscode2session', params={ 'appid': APP_ID, 'secret': APP_SECRET, 'js_code': code, 'grant_type': 'authorization_code' } ).json() if 'errcode' in resp: return error('登录失败, 请重试') openid = resp['openid'] user = select_user_by_openid(openid) if not user: user = create_user(openid) token = generate_token(openid) return success({'token': token, 'user': user})

前端拿到token后,存入wx.setStorageSync('token', token)。后续每个请求都在header里带上Authorization: Bearer <token>,后端用拦截器统一校验。

这里有个坑:wx.login返回的code只能用一次,5分钟有效。如果调后端失败后立刻重试,code已经失效了,必须重新调用wx.login获取新的code。前端代码里要处理好这个逻辑。

5.3 商品发布与图片上传的联调细节

图片上传是小程序开发的经典环节。标准流程是:小程序端先用wx.chooseMedia选图片,再用wx.uploadFile把文件传到后端指定的上传接口。

实际开发中建议采用“直传云存储”的方案,即小程序端直接把图片传到对象存储(如七牛云、腾讯云COS),缩短上传链路,而且不占用自己服务器的带宽。上传成功后拿到图片URL,连同其他商品字段一起传给后端。

直传的流程需要后端先给一个上传凭证,小程序端持凭证上传,这个凭证有效期通常只有几分钟。具体的凭证生成方式各家云厂商文档都写得很清楚,照着做就行。

图片尺寸也值得处理一下。小程序端拿到图片后,保险起见用wx.compressImage压一遍再传,能有效节省存储空间和加载流量。压缩参数经验值是quality: 80,肉眼几乎无差别,体积能小30%以上。

5.4 列表页的触底加载

列表加载我用的方案是“分页滚动加载”:初次进入页面加载第一页(page=1, pageSize=10),用户滚动到底部触发onReachBottom事件,如果hasMore为true,自动请求下一页并追加渲染。

注意,要加一个loading开关防止重复请求。用户快速滚动时,onReachBottom可能被触发多次,如果每次都在发请求,就会造成数据重复和页面闪烁。标准写法是:

onReachBottom() { if (this.data.loading || !this.data.hasMore) return this.setData({ loading: true }) // 请求下一页 finally(() => this.setData({ loading: false })) }

5.5 小程序端的登录态与授权时机

真正的小程序项目里,最影响用户体验的设计就是授权时机。很多开发者一进入小程序就弹窗要求授权手机号、头像昵称,用户还在懵的状态就被吓退了。

我的建议是:首屏不弹授权,等用户触发“发布商品”或“收藏”等需要登录的操作时,再引导登录。

用户在浏览商品列表时,完全不需要登录就可以看,这样降低了新用户的使用门槛。只有点“我要发布”时才跳转登录页,登录完成后自动回到发布页。

小程序获取头像昵称在2022年改版后,已经不需要用户授权了,wx.getUserProfile可以直接弹出确认框获取头像昵称。但这里建议直接做成“用户手动编辑”的形式,让用户自己上传头像、填昵称,比强制弹窗更自然。

6. 常见问题与排查技巧实录

这个部分汇总我实际开发中遇到的高频问题,列成速查表供参考。

6.1 开发调试阶段的疑难杂症

异常现象原因分析解决方案
真机预览时图片加载失败图片域名未配置到合法域名在微信公众平台后台配置downloadFile合法域名
登录后请求401过期token存储位置不对或未带header检查请求拦截器是否统一附加Authorization头
上传图片一直转圈uploadFile地址配错或凭证过期确认直传凭证有效期,失败后刷新凭证再传
页面滑动卡顿列表一次性渲染数据量过大改用分页加载,每次只渲染10条
商品列表展示不到新发布的数据数据库缓存或默认排序不正确检查SQL排序字段是否为publish_time倒序

小程序真机调试时request合法域名校验是必须要过的。开发工具可以关,真机不行。这个规则没法绕,不去后台配置好,上线后所有请求都会报url not in domain list。

6.2 后端接口偶发性超时的排查思路

如果接口平时响应正常,但特定时间段内响应慢或超时,我的排查顺序是:先看数据库慢查询日志,再看服务器CPU占用是否异常,最后看第三方API(比如微信接口)的响应时间。

有一次我排查出问题是数据库连接池耗尽。原因是某个接口在极端情况下打开了数据库连接但忘了释放,高并发时把所有连接占满,后续请求全部排队等连接。把代码里所有数据库操作加上try-finally确保连接释放后,问题解决。

这里值得强调一下:后端开发中数据库连接泄漏问题排sinhán难度不高但隐藏性极强。建议从第一天起就统一封装数据库访问入口,不要每个接口各自开连接,否则总有一天会踩这个大雷。

6.3 审核与合规的避坑指南

小程序上线前要过微信审核。校园二手交易平台最容易被拒的理由是:类目选择不当或内容涉及交易的类目资质不完整。

根据微信官方规则,涉及线上交易的平台类小程序,通常需要选择“电商平台”类目,并提交相应资质。个人开发者往往没有企业资质,这一步会是最大的门槛。

部分开发者用“社区”或“工具”类目绕过资质限制,但审核被拒后得不偿失。稳妥的做法是:如果是以学习为目的的课程设计,提交前先查看微信公众平台的最新类目要求;如果是以正式上线为目标,提前准备好对应资质文件。

注册小程序账号也需要选类型:个人主体和企业主体。个人主体注册最简单,但类目选择受限。这个决策要提前想清楚,因为主体类型一旦注册,后续变更的流程繁琐且费用不低。

6.4 发布后数据监控的几个指标

第一版上线后,至少要在后台盯着几个核心指标:当日新增用户数、日活跃用户数、商品发布量、商品浏览量、收藏量和“我想要”的点击量。不用搞复杂的BI报表,一个简单的管理页足够。

如果商品浏览量大但收藏量低,说明列表里的商品对用户缺乏吸引力;如果收藏量大但卖家被联系很少,说明价格或联系方式展示环节出了问题。这些数据能帮助你判断下一步优先优化哪块功能。我做完第一版后,发现“联系卖家”的转化率显著低于预期,后来把“点击查看微信号”的按钮从灰色改成了高亮的绿色并加大了字号,转化率立刻提升了一截。

我的实操心得

做完整套系统再回头看,最深的体会是:校园二手交易平台的技术难度并不高,真正决定项目成败的是对业务场景的理解深度。微信小程序开发本身有完整成熟的文档,数据库设计也有标准范式,这些只要肯花时间都能学会。

我花了最多精力在“如何让校园用户信任这个平台”这件事上。身份认证标识、同校优先展示、举报机制、发布门槛控制——这些不需要高深的技术,但每一个细节都直接影响用户愿不愿意在平台上完成第一次交易。

最后分享一个从开发效率角度上的体会:这类项目列表页的代码量最大、最容易出Bug,不妨把商品列表的排序逻辑做成后端可配置的,比如通过参数切换“最新发布”“价格升序”“价格降序”“离我最近”。本来以为这个设计用处不大,上线后发现“价格优先”的使用占比远超预期,学生用户对价格敏感程度确实比想象中高很多。灵活的小设计往往能在实际使用中带来超出预期的价值。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进