news 2026/1/2 10:10:05

基于Vue和Python的羽毛球拍智能推荐系统, 从“不会选羽毛球拍”到“选对拍”的一站式小工具

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Vue和Python的羽毛球拍智能推荐系统, 从“不会选羽毛球拍”到“选对拍”的一站式小工具

如果你也经历过:

  • 预算定了,但不知道该选轻一点还是头重一点
  • 看参数看懵:重量、平衡点、硬度到底怎么影响手感
  • 想要更适合自己打法的球拍清单,还想看看球友怎么说

我把这些需求做成了一个「羽毛球拍推荐系统」,把选拍流程变得更可视化、更好用,也更适合日常自用、项目展示。


1. 项目简介

这是一个面向羽毛球爱好者的 Web 系统,核心目标是把“选拍”从主观经验变成可输入、可对比、可解释的流程:

  • 通过推荐算法根据预算/重量/平衡点/硬度/技术水平匹配球拍;
  • 通过球拍库+筛选分页快速缩小选择范围;
  • 通过评价体系形成球友口碑;
  • 通过公告支持系统更新通知;
  • 通过论坛问答支持球友提问与答疑,增强内容与互动;
  • 通过个人中心管理账号信息、修改密码、查看我的评价。

2. 功能清单

2.1 前台功能

  • 首页:入口聚合、公告预览、快速开始
  • 羽毛球拍列表:筛选 + 分页
  • 羽毛球拍详情:参数展示 + 用户评价列表 +(普通用户)发布评价
  • 推荐系统:输入偏好 → 返回 Top 推荐(含匹配度)
  • 系统公告:公告列表展示
  • 球友论坛:提问列表、问题详情、发布提问、发布回答
  • 个人中心:账号信息、修改密码、我的评价(普通用户)

2.2 管理员功能

  • 管理员登录后通过 Token 调用受保护接口
  • 羽毛球拍增删改
  • 公告发布/编辑/删除(置顶排序)

2.3 系统功能展示

首页

羽毛球球拍列表

球拍推荐

论坛

系统公告

注册

个人中心


3. 技术栈

3.1 前端

  • Vue 3 + Vite
  • Tailwind CSS(统一的绿/蓝渐变主题、卡片式布局)
  • Pinia(状态管理:用户信息、球拍数据等)
  • Vue Router(路由与登录拦截)
  • Axios(请求后端 API)

3.2 后端

  • Flask + Flask-CORS
  • Flask-SQLAlchemy(ORM)
  • MySQL(通过 PyMySQL 连接)

4. 项目结构(建议读者先有全局概念)

badminton-recommend/ ├── backend/ │ ├── app.py # Flask 后端(模型 + API) │ └── requirements.txt # Python 依赖 ├── frontend/ │ ├── vite.config.js # Vite 代理配置 │ ├── src/ │ │ ├── App.vue # 全局布局(导航 + router-view + Footer) │ │ ├── router/index.js # 路由定义 + 登录拦截 │ │ ├── store/ # Pinia store │ │ └── views/ # 页面(推荐/列表/详情/公告/论坛/个人中心) │ └── package.json

5. 前后端联调方式(Vite 代理)

前端开发时通过 Vite 代理把/api转发到后端,避免跨域 & 简化请求地址:

文件:frontend/vite.config.js

exportdefaultdefineConfig({server:{port:3999,proxy:{'/api':{target:'http://127.0.0.1:5999',changeOrigin:true,secure:false}}}})

这样前端只需要请求/api/...,即可在开发环境自动走后端服务。


6. 核心模块实现(重点:推荐 / 鉴权 / 筛选分页 / 论坛问答)

6.1 推荐算法(/api/recommend)

推荐逻辑核心是:对每个球拍计算多维得分,按权重加权后取 Top N。

权重配置(可调参):

文件:backend/app.py

weights={'price':0.2,'weight':0.25,'balance_point':0.25,'hardness':0.2,'suitable_level':0.1}

推荐接口(核心片段):

@app.route('/api/recommend',methods=['POST'])defrecommend_racket():data=request.get_json()user_price=float(data.get('price',0))user_weight=int(data.get('weight',0))user_balance_point=int(data.get('balance_point',0))user_hardness=int(data.get('hardness',0))user_level=str(data.get('suitable_level','初级'))rackets=Racket.query.all()scores=[]forracketinrackets:price_score=max(0,1-abs(racket.price-user_price)/max(1000,user_price))weight_score=max(0,1-abs(racket.weight-user_weight)/30)balance_score=max(0,1-abs(racket.balance_point-user_balance_point)/30)user_hardness_normalized=min(10,max(1,user_hardness))/10*3hardness_score=max(0,1-abs(racket.hardness-user_hardness_normalized)/3)user_level_value=level_mapping.get(user_level,2)racket_level_value=level_mapping.get(racket.suitable_level,2)level_score=max(0,1-abs(racket_level_value-user_level_value)/3)total_score=(weights['price']*price_score+weights['weight']*weight_score+weights['balance_point']*balance_score+weights['hardness']*hardness_score+weights['suitable_level']*level_score)scores.append({'id':racket.id,'brand':racket.brand,'model':racket.model,'score':total_score})scores.sort(key=lambdax:x['score'],reverse=True)returnjsonify(scores[:5])

前端调用(Pinia action):

文件:frontend/src/store/racket.js

asyncrecommendRackets(criteria){constresponse=awaitaxios.post('/api/recommend',criteria)this.recommendedRackets=response.datareturnresponse.data}

6.2 管理员鉴权(Token + 装饰器)

管理员登录后返回 Token,前端保存到localStorage,后续在需要管理员权限的接口中通过Authorization: Bearer <token>传递。

文件:backend/app.py

def_get_bearer_token():auth_header=request.headers.get('Authorization','')parts=auth_header.split(' ',1)iflen(parts)!=2:returnNonescheme,value=parts[0].strip().lower(),parts[1].strip()ifscheme!='bearer'ornotvalue:returnNonereturnvaluedef_get_admin_from_request():token=_get_bearer_token()orrequest.headers.get('X-Admin-Token')ifnottoken:returnNonereturnAdmin.query.filter_by(token=token).first()defrequire_admin(func):@wraps(func)defwrapper(*args,**kwargs):admin=_get_admin_from_request()ifnotadmin:returnjsonify({'success':False,'message':'需要管理员登录'}),401returnfunc(*args,**kwargs)returnwrapper

前端保存登录态(Pinia):

文件:frontend/src/store/user.js

login(userData){constid=userData.user_id??userData.admin_id??nullthis.userId=idthis.username=userData.username||nullthis.role=userData.role||(userData.admin_id?'admin':'user')this.token=userData.token||nullthis.isLoggedIn=!!id localStorage.setItem('role',this.role)if(this.token)localStorage.setItem('token',this.token)}

6.3 球拍列表筛选 + 分页(/api/rackets)

后端通过 query 参数拼装 SQLAlchemy 查询,再分页返回:

文件:backend/app.py

@app.route('/api/rackets',methods=['GET'])defget_rackets():page=request.args.get('page',1,type=int)per_page=request.args.get('per_page',10,type=int)brand=request.args.get('brand')price_min=request.args.get('price_min',type=float)price_max=request.args.get('price_max',type=float)# ... 省略其他过滤条件query=Racket.queryifbrand:query=query.filter(Racket.brand.like(f'%{brand}%'))ifprice_minisnotNone:query=query.filter(Racket.price>=price_min)ifprice_maxisnotNone:query=query.filter(Racket.price<=price_max)total_count=query.count()rackets=query.offset((page-1)*per_page).limit(per_page).all()returnjsonify({'items':[...],'total':total_count,'page':page,'per_page':per_page,'pages':(total_count+per_page-1)//per_page})

前端 Pinia 统一接收分页结构(total/pages/page/per_page),页面只消费 store:

文件:frontend/src/store/racket.js

constresponse=awaitaxios.get('/api/rackets',{params})this.racketItems=response.data.itemsthis.total=response.data.totalthis.page=response.data.pagethis.perPage=response.data.per_pagethis.totalPages=response.data.pages

6.4 系统公告(置顶排序 + 分页)

公告列表按“置顶优先 + 时间倒序”:

文件:backend/app.py

query=Announcement.query.order_by(Announcement.is_pinned.desc(),Announcement.created_at.desc(),Announcement.id.desc())

管理员发布公告加上@require_admin

@app.route('/api/announcements',methods=['POST'])@require_admindefcreate_announcement():# ...db.session.add(announcement)db.session.commit()returnjsonify({'success':True,'item':_announcement_to_dict(announcement)})

6.5 球友论坛问答(提问/答疑)

论坛接口包括:

  • GET /api/forum/questions:问题列表(分页 + 回复数)
  • POST /api/forum/questions:发布提问
  • GET /api/forum/questions/<id>:详情 + 回答列表
  • POST /api/forum/questions/<id>/answers:发布回答

列表接口中通过 SQL 聚合统计answer_count(用于列表显示“xx 回复”):

文件:backend/app.py

rows=(db.session.query(ForumAnswer.question_id,func.count(ForumAnswer.id)).filter(ForumAnswer.question_id.in_(ids)).group_by(ForumAnswer.question_id).all())counts={qid:int(cnt)forqid,cntinrows}

前端发起提问(带上author_id/author_role):

文件:frontend/src/views/Forum.vue

constresponse=awaitaxios.post('/api/forum/questions',{title,content,author_id:userStore.userId,author_role:userStore.role})

前端发布回答:

文件:frontend/src/views/ForumDetail.vue

constresponse=awaitaxios.post(`/api/forum/questions/${questionId}/answers`,{content,author_id:userStore.userId,author_role:userStore.role})

7. 路由与登录拦截(个人中心示例)

个人中心需要登录后访问,使用meta.requiresAuth+beforeEach做拦截:

文件:frontend/src/router/index.js

{path:'/profile',name:'Profile',component:Profile,meta:{requiresAuth:true}}router.beforeEach((to,from,next)=>{if(to.meta?.requiresAuth){constisLoggedIn=!!localStorage.getItem('userId')if(!isLoggedIn){next({path:'/login',query:{redirect:to.fullPath}})return}}next()})

8. 可优化点

  • 论坛增强:点赞、采纳最佳答案、搜索、标签、分页加载
  • 推荐升级:引入“历史评价/行为”,做协同过滤或内容推荐
  • 管理后台:用户管理、数据统计、敏感词过滤等

如果你也想要一个“选拍更直观 + 有球友讨论氛围”的小系统,欢迎交流,我也可以继续把功能打磨得更完整的选购辅助小工具。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/18 8:27:04

Attu可视化工具:向量数据库管理的效率革命实战指南

Attu可视化工具&#xff1a;向量数据库管理的效率革命实战指南 【免费下载链接】attu Milvus management GUI 项目地址: https://gitcode.com/gh_mirrors/at/attu 还记得第一次面对Milvus命令行时的困惑吗&#xff1f;那些复杂的参数配置、繁琐的数据操作流程&#xff0…

作者头像 李华
网站建设 2025/12/25 5:51:27

深岩银河存档编辑器:新手也能轻松掌握的存档修改神器

深岩银河存档编辑器&#xff1a;新手也能轻松掌握的存档修改神器 【免费下载链接】DRG-Save-Editor Rock and stone! 项目地址: https://gitcode.com/gh_mirrors/dr/DRG-Save-Editor 还在为深岩银河游戏资源不足而烦恼吗&#xff1f;想要快速体验不同职业组合却不想花费…

作者头像 李华
网站建设 2025/12/18 8:25:41

如何快速掌握ReadCat:开源小说阅读器的完整使用指南

如何快速掌握ReadCat&#xff1a;开源小说阅读器的完整使用指南 【免费下载链接】read-cat 一款免费、开源、简洁、纯净、无广告的小说阅读器 项目地址: https://gitcode.com/gh_mirrors/re/read-cat ReadCat是一款基于Vue3和Electron技术构建的免费开源小说阅读器&…

作者头像 李华
网站建设 2025/12/18 8:22:13

企业级Vue工作流引擎:零基础搭建钉钉风格审批系统

企业级Vue工作流引擎&#xff1a;零基础搭建钉钉风格审批系统 【免费下载链接】Workflow 仿钉钉审批流程设置 项目地址: https://gitcode.com/gh_mirrors/work/Workflow 还在为复杂的审批流程配置而烦恼吗&#xff1f;这款基于Vue.js开发的钉钉风格工作流引擎&#xff0…

作者头像 李华
网站建设 2025/12/18 8:21:50

数据工作流调度系统(Kettle-Scheduler)部署与操作手册

数据工作流调度系统&#xff08;Kettle-Scheduler&#xff09;部署与操作手册 【免费下载链接】kettle-scheduler 一款简单易用的Kettle调度监控平台&#xff0c;专门用来调度和监控由kettle客户端创建的job和transformation。整体的框架是由springsprin gmvc beetlsql整合而成…

作者头像 李华
网站建设 2025/12/18 8:21:18

3分钟搞定ZeroOmega:告别繁琐的网络配置切换困境

3分钟搞定ZeroOmega&#xff1a;告别繁琐的网络配置切换困境 【免费下载链接】ZeroOmega Manage and switch between multiple proxies quickly & easily. 项目地址: https://gitcode.com/gh_mirrors/ze/ZeroOmega 还在为不同网络环境下的配置调整而头疼吗&#xff…

作者头像 李华