邯郸建设局网站有什么好的网站建设的书
2025/12/28 4:38:29 网站建设 项目流程
邯郸建设局网站,有什么好的网站建设的书,春花直播,网站手机适配跳转如果你也经历过#xff1a; 预算定了#xff0c;但不知道该选轻一点还是头重一点看参数看懵#xff1a;重量、平衡点、硬度到底怎么影响手感想要更适合自己打法的球拍清单#xff0c;还想看看球友怎么说 我把这些需求做成了一个「羽毛球拍推荐系统」#xff0c;把选拍流程…如果你也经历过预算定了但不知道该选轻一点还是头重一点看参数看懵重量、平衡点、硬度到底怎么影响手感想要更适合自己打法的球拍清单还想看看球友怎么说我把这些需求做成了一个「羽毛球拍推荐系统」把选拍流程变得更可视化、更好用也更适合日常自用、项目展示。1. 项目简介这是一个面向羽毛球爱好者的 Web 系统核心目标是把“选拍”从主观经验变成可输入、可对比、可解释的流程通过推荐算法根据预算/重量/平衡点/硬度/技术水平匹配球拍通过球拍库筛选分页快速缩小选择范围通过评价体系形成球友口碑通过公告支持系统更新通知通过论坛问答支持球友提问与答疑增强内容与互动通过个人中心管理账号信息、修改密码、查看我的评价。2. 功能清单2.1 前台功能首页入口聚合、公告预览、快速开始羽毛球拍列表筛选 分页羽毛球拍详情参数展示 用户评价列表 普通用户发布评价推荐系统输入偏好 → 返回 Top 推荐含匹配度系统公告公告列表展示球友论坛提问列表、问题详情、发布提问、发布回答个人中心账号信息、修改密码、我的评价普通用户2.2 管理员功能管理员登录后通过 Token 调用受保护接口羽毛球拍增删改公告发布/编辑/删除置顶排序2.3 系统功能展示首页羽毛球球拍列表球拍推荐论坛系统公告注册个人中心3. 技术栈3.1 前端Vue 3 ViteTailwind CSS统一的绿/蓝渐变主题、卡片式布局Pinia状态管理用户信息、球拍数据等Vue Router路由与登录拦截Axios请求后端 API3.2 后端Flask Flask-CORSFlask-SQLAlchemyORMMySQL通过 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.json5. 前后端联调方式Vite 代理前端开发时通过 Vite 代理把/api转发到后端避免跨域 简化请求地址文件frontend/vite.config.jsexportdefaultdefineConfig({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.pyweights{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():datarequest.get_json()user_pricefloat(data.get(price,0))user_weightint(data.get(weight,0))user_balance_pointint(data.get(balance_point,0))user_hardnessint(data.get(hardness,0))user_levelstr(data.get(suitable_level,初级))racketsRacket.query.all()scores[]forracketinrackets:price_scoremax(0,1-abs(racket.price-user_price)/max(1000,user_price))weight_scoremax(0,1-abs(racket.weight-user_weight)/30)balance_scoremax(0,1-abs(racket.balance_point-user_balance_point)/30)user_hardness_normalizedmin(10,max(1,user_hardness))/10*3hardness_scoremax(0,1-abs(racket.hardness-user_hardness_normalized)/3)user_level_valuelevel_mapping.get(user_level,2)racket_level_valuelevel_mapping.get(racket.suitable_level,2)level_scoremax(0,1-abs(racket_level_value-user_level_value)/3)total_score(weights[price]*price_scoreweights[weight]*weight_scoreweights[balance_point]*balance_scoreweights[hardness]*hardness_scoreweights[suitable_level]*level_score)scores.append({id:racket.id,brand:racket.brand,model:racket.model,score:total_score})scores.sort(keylambdax:x[score],reverseTrue)returnjsonify(scores[:5])前端调用Pinia action文件frontend/src/store/racket.jsasyncrecommendRackets(criteria){constresponseawaitaxios.post(/api/recommend,criteria)this.recommendedRacketsresponse.datareturnresponse.data}6.2 管理员鉴权Token 装饰器管理员登录后返回 Token前端保存到localStorage后续在需要管理员权限的接口中通过Authorization: Bearer token传递。文件backend/app.pydef_get_bearer_token():auth_headerrequest.headers.get(Authorization,)partsauth_header.split( ,1)iflen(parts)!2:returnNonescheme,valueparts[0].strip().lower(),parts[1].strip()ifscheme!bearerornotvalue:returnNonereturnvaluedef_get_admin_from_request():token_get_bearer_token()orrequest.headers.get(X-Admin-Token)ifnottoken:returnNonereturnAdmin.query.filter_by(tokentoken).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.jslogin(userData){constiduserData.user_id??userData.admin_id??nullthis.userIdidthis.usernameuserData.username||nullthis.roleuserData.role||(userData.admin_id?admin:user)this.tokenuserData.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.pyapp.route(/api/rackets,methods[GET])defget_rackets():pagerequest.args.get(page,1,typeint)per_pagerequest.args.get(per_page,10,typeint)brandrequest.args.get(brand)price_minrequest.args.get(price_min,typefloat)price_maxrequest.args.get(price_max,typefloat)# ... 省略其他过滤条件queryRacket.queryifbrand:queryquery.filter(Racket.brand.like(f%{brand}%))ifprice_minisnotNone:queryquery.filter(Racket.priceprice_min)ifprice_maxisnotNone:queryquery.filter(Racket.priceprice_max)total_countquery.count()racketsquery.offset((page-1)*per_page).limit(per_page).all()returnjsonify({items:[...],total:total_count,page:page,per_page:per_page,pages:(total_countper_page-1)//per_page})前端 Pinia 统一接收分页结构total/pages/page/per_page页面只消费 store文件frontend/src/store/racket.jsconstresponseawaitaxios.get(/api/rackets,{params})this.racketItemsresponse.data.itemsthis.totalresponse.data.totalthis.pageresponse.data.pagethis.perPageresponse.data.per_pagethis.totalPagesresponse.data.pages6.4 系统公告置顶排序 分页公告列表按“置顶优先 时间倒序”文件backend/app.pyqueryAnnouncement.query.order_by(Announcement.is_pinned.desc(),Announcement.created_at.desc(),Announcement.id.desc())管理员发布公告加上require_adminapp.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.pyrows(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.vueconstresponseawaitaxios.post(/api/forum/questions,{title,content,author_id:userStore.userId,author_role:userStore.role})前端发布回答文件frontend/src/views/ForumDetail.vueconstresponseawaitaxios.post(/api/forum/questions/${questionId}/answers,{content,author_id:userStore.userId,author_role:userStore.role})7. 路由与登录拦截个人中心示例个人中心需要登录后访问使用meta.requiresAuthbeforeEach做拦截文件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. 可优化点论坛增强点赞、采纳最佳答案、搜索、标签、分页加载推荐升级引入“历史评价/行为”做协同过滤或内容推荐管理后台用户管理、数据统计、敏感词过滤等如果你也想要一个“选拍更直观 有球友讨论氛围”的小系统欢迎交流我也可以继续把功能打磨得更完整的选购辅助小工具。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询