【从0到1:一个篮球迷的“全栈执念”】后端+小程序全开源,跑起来就是完整社区
We-Ball是一个前后端全开源的 NBA 赛事与社交社区项目。它从数据库设计、Service 层封装,到好友关系、社区热榜,再到配套的微信小程序前端,提供了完整可运行、可修改、可直接上线的全栈解决方案。。
先看成果:后端 + 小程序,完整闭环
We-Ball不是只写了一半的后端,而是一套可直接上线的完整产品:
- 🏀 后端 API:ThinkPHP 5.1,提供赛事数据 + 用户体系 + 社区论坛
- 📱 微信小程序:原生开发,真机可跑,支持查看比赛、刷帖子、加好友
- 🗄️ 数据库:MySQL 5.7+,表结构已给全
- 📸 媒体上传:图片/视频统一入口
目前全部开源,没有任何加密,你可以直接拿去二次开发。
下面我把开发过程中最得意的 7 个设计特点拆开来讲,每一个都是真实踩坑后的沉淀。
一、为什么我要自己写这个项目?
市面上已有的体育类开源项目,要么是爬虫脚本,要么只提供比分 API,缺少用户沉淀的能力。而体育,尤其是 NBA ——天然就是社交话题。
我想要一个既能查数据,又能加好友、发帖子、讨论比赛的完整后端。
既然找不到,那就自己造一个。
目标很明确:
- 代码要清晰,别让接手的人骂我
- 接口要规范,前端同学用着舒服
- 扩展要容易,加一个新功能不改老代码
- 最好再配一个小程序 Demo,让新手也能快速跑起来
于是 We-Ball 诞生了,而且后端 + 小程序一起开源。
二、后端架构特点(重点中的重点)
1️⃣ 分层设计:Controller → Service → Model 三层
ThinkPHP 自带 MVC,但我把业务逻辑全部抽到了Service 层。
// application/index/controller/MatchController.phppublicfunctiondetail(){$matchId=input('matchId');$data=(newMatchService())->getMatchDetail($matchId);returnjson(['code'=>200,'msg'=>'ok','data'=>$data]);}MatchService里做数据查询、组装、缓存等。这样做的好处:
- 控制器极薄:只负责参数校验和响应格式
- 逻辑可复用:比如
UserService里也能调用MatchService获取用户关注球队的比赛 - 容易测试:可以单独对 Service 做单元测试
我个人建议,任何超过 20 个接口的项目都应该引入 Service 层。
2️⃣ 统一 API 响应与异常处理
所有接口返回同一个结构:
{"code":200,"msg":"success","data":{}}错误码统一管理(200 成功,400 参数错,401 未登录,500 服务器错)。
同时在app.php里关闭debug模式下的错误详情暴露,生产环境不会把 SQL 报错吐给用户。
3️⃣ 模块化目录:一个模块一个服务
application/index/ ├── controller/ │ ├── HomeController.php │ ├── MatchController.php │ ├── TeamController.php │ ├── PlayerController.php │ ├── UserController.php # 包含登录/好友/收藏/动态 │ ├── CommunityController.php # 帖子/分类 │ └── MediaController.php ├── service/ │ ├── HomeService.php │ ├── MatchService.php │ └── ... └── utils/ └── utils.php # 公共函数新增一个功能(比如“球员对比”),就在PlayerController里加方法,在PlayerService里实现逻辑,不影响现有模块。
4️⃣ 数据库设计:不做过度设计,但要能撑住真实场景
挑几张核心表详细说:
matches比赛表
| 字段 | 类型 | 说明 |
|---|---|---|
| id | int | 主键 |
| home_team_id | int | 主队 ID |
| away_team_id | int | 客队 ID |
| match_time | datetime | 比赛时间 |
| home_score | int | 主队得分 |
| away_score | int | 客队得分 |
| status | tinyint | 0未开始 1进行中 2已结束 |
设计思路:不把技术统计塞进主表,单独用match_stats表存球员个人数据,避免字段爆炸。
friends好友关系表
| 字段 | 说明 |
|---|---|
| user_id | 发起方 |
| friend_id | 目标方 |
| status | 0待确认 1同意 2拒绝 |
设计思路:只存一条记录,查询“我的好友”时用(user_id = 某 AND status=1) OR (friend_id = 某 AND status=1),配合联合索引,性能足够。
moments用户动态表
类似微信朋友圈,支持文字 + 最多 9 张图片(图片 ID 存在images字段,逗号分隔,关联media表)。
设计思路:简单够用,不搞复杂的多表关联,图片用explode拆开即可。
5️⃣ 媒体上传:统一入口,安全过滤
MediaController提供/media/upload接口,支持图片和短视频:
// 前端传 file,后端校验类型$file=request()->file('file');$type=$this->checkFileType($file);if(!$type)returnerror('不支持的文件类型');// 按日期分目录存储:/uploads/2025/04/xxx.jpg$path=$file->move(ROOT_PATH.'public/uploads/'.date('Ymd'));同时返回可访问的 URL,前端直接展示。小程序里用wx.uploadFile对接即可。
6️⃣ 路由配置:清晰、可维护
所有接口定义在route/route.php:
// 比赛模块Route::get('match/list$','index/Match/list');Route::get('match/detail$','index/Match/detail');// 用户模块Route::post('user/login$','index/User/login');Route::get('user/friend$','index/User/friend');Route::post('user/submitmoment$','index/User/submitMoment');// 社区模块Route::get('community/list$','index/Community/list');Route::post('community/submitpost$','index/Community/submitPost');特点:全部带$结尾,严格匹配,避免/match/list/xxx误匹配。同时支持 GET/POST 分离,符合 RESTful 习惯。
7️⃣ 缓存与性能优化(实战经验)
- 球队列表、球员排行榜这种不常变的数据,用ThinkPHP 缓存存 10 分钟,减轻数据库压力。
- 比赛中的实时比分不做缓存,直接查库(因为前端轮询频率不高)。
- 帖子列表用分页 +
limit,避免一次查几千条。
示例代码(TeamService):
publicfunctiongetRankList(){$cacheKey='team_rank';$data=cache($cacheKey);if(!$data){$data=TeamModel::order('points','desc')->select();cache($cacheKey,$data,600);// 10分钟}return$data;}三、配套小程序前端:真机可跑,无缝对接
光有后端还不够,为了让整个项目真正“活”起来,我专门开发了一个完整的微信小程序前端。这样,无论是初学者还是开发者,都能立即上手体验,看到前后端联动的完整效果。让大家真正能跑起来。
小程序技术栈
- 前端框架:基于微信小程序原生框架(MINA),使用 WXML、WXSS 和 JavaScript 进行开发。
- UI 组件库:采用 Vant Weapp v1.11.7,提供丰富、美观且高性能的组件,加速界面开发。
- 状态管理:主要使用小程序原生的
globalData进行全局状态共享,并可选搭配轻量级的事件总线机制来处理跨页面通信。 - 网络请求:对
wx.request进行了二次封装,统一管理 API 请求的 URL、请求头、错误处理和 loading 状态,提升代码复用性和可维护性。 - 版本控制:使用 Git 进行代码管理,并通过
.gitignore文件忽略了node_modules、miniprogram_npm等非必需提交的目录,保持仓库整洁。
核心页面展示
为了让您更直观地了解小程序的功能和界面,这里展示了几个核心页面的截图:
首页:赛事信息、热门帖子一目了然。
社区:浏览和参与各类篮球话题讨论。
我的:个人中心,管理个人信息、收藏和动态。
球友圈:查看好友动态,分享篮球生活。
我的球友:管理好友列表,添加或移除好友。
关注的球员:查看已关注球员的最新数据和动态。
关注的球队:获取已关注球队的赛程和新闻。
帖子详情:深入参与某个帖子的讨论和互动。
比赛赛程:查看即将进行和已结束的比赛。
好友资料:查看好友的详细信息和动态。
前后端对接示例
小程序里请求比赛列表:
// 小程序端wx.request({url:'https://your-domain.com/match/list',success:(res)=>{if(res.data.code===200){this.setData({matches:res.data.data});}}});后端返回的数据格式完全匹配,前端不需要做额外转换。
用户登录、发帖子、加好友等接口也都已联调通过。
如何本地运行小程序?
- 下载微信开发者工具
- 克隆小程序源码:
git clone https://gitee.com/walii/mini-weball.git - 修改
utils/config.js里的后端域名(本地调试可以用http://localhost:8000,但注意微信小程序的 request 合法域名需要配置 HTTPS) - 真机预览或模拟器运行
如果你只想测试后端,也可以直接用 Postman 调用 API。
四、开发中踩过的 3 个大坑(附解法)
🧨 坑1:好友关系查询性能差
一开始用(user_id = 1 OR friend_id = 1),随着数据量增大,索引失效。
解法:加冗余字段relation_key,存min(uid, fid)_max(uid, fid),直接等值查询。或者保持原逻辑但建联合索引(user_id, status)和(friend_id, status)。
🧨 坑2:小程序登录态管理
小程序调用wx.login拿到 code,后端请求微信接口换取 openid,再返回自定义 token。
解法:我做了完整的 token 生成与校验,后端通过UserService::checkToken()统一验证,存在缓存中。
🧨 坑3:图片上传在小程序端被压缩
小程序wx.chooseImage默认会压缩图片,导致后端收到的图片尺寸变小。
解法:前端设置sizeType: ['original'],后端限制最大 5MB,并压缩一遍。
五、项目亮点 VS 其他开源体育项目
| 特性 | 一般爬虫项目 | We-Ball(我的项目) |
|---|---|---|
| 用户系统 | ❌ 无 | ✅ 登录/好友/收藏/动态 |
| 社区帖子 | ❌ 无 | ✅ 完整帖子+分类+评论 |
| API 设计 | 零散不规范 | ✅ RESTful + 统一响应 |
| Service 层 | 无 | ✅ 业务逻辑独立 |
| 媒体上传 | 无 | ✅ 图片/视频统一入口 |
| 配套前端 | 无 | ✅微信小程序,开箱即用 |
| 文档 | 几乎没有 | ✅ 详细 README + API 表格 + 小程序文档 |
很多开源体育项目只提供数据,但体育天生需要人和人一起讨论。We-Ball 把“看球”和“聊球”连在一起,这才是社区的价值。
六、技术栈与快速上手指南
后端环境
- PHP 7.0 ~ 8.0
- MySQL 5.7+
- Nginx / Apache
- Composer
小程序环境
- 微信开发者工具
- 小程序 AppID(自己注册一个免费的)
5 分钟跑起来
# 1. 克隆后端gitclone https://gitee.com/walii/php-weball.gitcdphp-weballcomposerinstall# 2. 配置数据库 config/database.php# 3. 导入 SQL(仓库里有个 weball.sql)mysql-uroot-pdb_weball<weball.sql# 4. 启动后端php think run# 后端地址:http://localhost:8000# 5. 克隆小程序gitclone https://gitee.com/walii/mini-weball.git# 用微信开发者工具打开,修改 config.js 里的域名# 真机调试(注意 localhost 只能在模拟器用,真机需配置 HTTPS 或使用内网穿透)七、未来计划(欢迎 PR)
- ✅ 已完成:核心 API + 小程序 Demo
- ✅ 已完成:详细的 README 和接口文档
- 🔲 进行中:JWT 替代 Session 认证
- 🔲 计划中:WebSocket 实时推送比分
- 🔲 计划中:管理后台(Vue 3 + Element Plus)
- 🔲 计划中:支持多语言(英文/中文)
如果你对某个方向感兴趣,欢迎提 Issue 或直接 PR,一起把 We-Ball 做得更强。
八、源码获取
项目完全开源,没有任何加密、没有任何商用限制,代码随便改、随便用。
📦 后端仓库(ThinkPHP 5.1)
- Gitee:https://gitee.com/walii/php-weball
- 包含:完整 API 接口、Service 层代码、数据库表结构、配置文件
- 克隆命令:
git clone https://gitee.com/walii/php-weball.git
📖 使用建议
- 先克隆后端,配置
config/database.php,导入 SQL composer install安装依赖php think run启动后端- 克隆小程序,修改
utils/config.js里的后端域名 - 微信开发者工具打开,真机调试或预览
⚠️ 注意事项
- 小程序 request 合法域名需要配置 HTTPS,本地调试可以用模拟器或内网穿透
- 生产环境记得关闭
app_debug和数据库debug - 图片上传路径需要写权限:
public/uploads/
💬 有问题?
- Gitee Issues:直接提
- 欢迎 PR,欢迎 Star,欢迎 fork 自己魔改
九、写给读者的话
开源一个完整的项目并不容易,从设计到编码到写文档,再到写一个小程序 Demo,前前后后花了几百个小时。
但当你看到有人在 Issue 里认真提问,甚至有人 Star 时说“这能直接拿去接小程序”,那种感觉确实很爽。
如果你也是 PHP 开发者,或者体育爱好者,或者小程序初学者,欢迎:
- ⭐ Star 支持后端:https://gitee.com/walii/php-weball
- ⭐ Star 支持小程序:https://gitee.com/walii/mini-weball
- 🐛 提 Bug / 建议
- 🍴 Fork 自己改一个版本
也欢迎在评论区聊聊:你理想中的体育社区应该有什么功能?
