智速优座项目总结
2026/7/3 5:02:32 网站建设 项目流程

目录

一、做这个项目的背景

二、技术栈的选择

前端技术栈

后端技术栈

项目架构图

三、核心功能的详解

1. 用户系统:登录注册与权限控制

2. 演出搜索:让用户快速找到想看的演出

3. 智能推荐:猜你喜欢

数据来源

推荐策略

4. 核心交互:选座购票

4.1 交互式座位图

4.2 座位锁定机制

5. 秒杀系统:高并发挑战

6. 订单管理:全生命周期追踪

7. 智能客服:24小时在线答疑

7.1 多轮对话支持

7.2 知识库集成

7.3 智能路由

7.4 客服界面

8. 后台管理系统

8.1 演出管理

8.2 用户管理

8.3 订单管理

8.4 数据统计

四、项目中遇到的问题以及解决

问题一:库存超卖

问题二:缓存一致性问题

问题三:分布式事务问题

问题四:消息队列堆积

五、项目的亮点

六、项目总结与感受


这篇博客是我做完这个项目后的一个总结

一、做这个项目的背景

这是一个高并发的票务平台项目;

做这个项目的初衷是:市面上的票务平台,对于个别城市开放的中小型演出没有兼顾到,并且在热门演出开票时常常出现卡顿,库存超卖的情况,我想切实的解决这些问题,所以做了这个项目试水

核心目标有三个:

  1. 扛住高并发:秒杀场景下能稳定处理大量请求
  2. 数据实时同步:座位、订单状态要实时更新
  3. 智能化体验:给用户推荐感兴趣的演出,用AI客服减轻运营压力

二、技术栈的选择

前端技术栈

  • 框架:Vue 3 + TypeScript(Vue3的组合式API太好用了,TypeScript让代码更规范)
  • 构建工具:Vite(开发体验好)
  • 状态管理:Pinia(Vue官方推荐)
  • 路由:Vue Router 4(单页应用必备)
  • UI组件库:Element Plus(组件丰富,文档友好)
  • 样式:Tailwind CSS 3(原子化CSS,写样式快到飞起)

后端技术栈

  • 框架:FastAPI(Python异步生态成熟,开发效率高,自动生成API文档)
  • 数据库:MySQL 8.0 + SQLAlchemy 2.0(关系型数据库首选,ORM用着省心)
  • 缓存:Redis 7(支持分布式锁、原子操作,秒杀必备)
  • 搜索:Elasticsearch 8(全文检索性能好,还支持向量检索)
  • 消息队列:RabbitMQ(异步任务处理,解耦业务)
  • AI能力:Dify(可视化工作流,快速集成LLM)

项目架构图

┌─────────────────────────────────────────────────────────────┐ │ 前端层 (Vue3 + TypeScript) │ ├─────────────────────────────────────────────────────────────┤ │ API Gateway (FastAPI + Nginx) │ ├─────────────────────────────────────────────────────────────┤ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────────────────┐ │ │ │ 用户服务│ │ 演出服务│ │ 订单服务 │ │ AI服务 │ │ │ │ │ │ │ │ │ │ (Dify工作流) │ │ │ └────┬────┘ └────┬────┘ └────┬────┘ └────────┬─────────┘ │ │ │ │ │ │ │ ├───────┼───────────┼───────────┼────────────────┼───────────┤ │ ▼ ▼ ▼ ▼ │ │ ┌─────────────────────────────────────────────────────────┐│ │ │ 中间件层 ││ │ │ Redis(座位锁/热点缓存) │ RabbitMQ(异步消息任务) ││ │ │ Elasticsearch(演出检索) │ Canal(MySQL数据同步) ││ │ └─────────────────────────────────────────────────────────┘│ ├─────────────────────────────────────────────────────────────┤ │ 数据持久层 (MySQL 8.0) │ └─────────────────────────────────────────────────────────────┘

三、核心功能的详解

1. 用户系统:登录注册与权限控制

用户模块是基础,我们做了手机号注册、密码登录,还集成了JWT认证

登录成功后返回token,后续请求都要带上这个token

@app.post("/api/login") async def login(username: str, password: str): user = await get_user_by_username(username) if not user or not verify_password(password, user.password): raise HTTPException(status_code=401, detail="用户名或密码错误") access_token = create_access_token(data={"sub": user.username}) return {"access_token": access_token, "token_type": "bearer"}

2. 演出搜索:让用户快速找到想看的演出

搜索功能用了Elasticsearch,支持关键词搜索、分类筛选、城市筛选

比如用户搜"周杰伦",就能找到相关演出

async def search_performance(keyword: str, city: str = None): query = {"bool": {"must": [{"match": {"name": keyword}}], "filter": []}} if city: query["bool"]["filter"].append({"term": {"city": city}}) result = await es_client.search(index="performance_index", query=query) return [hit["_source"] for hit in result["hits"]["hits"]]

3. 智能推荐:猜你喜欢

这个功能是提升用户转化率的关键,我们基于用户行为做个性化推荐:

数据来源

  • 用户浏览过的演出
  • 用户购买过的演出
  • 用户搜索过的关键词
  • 用户收藏的演出

推荐策略

  • 协同过滤:根据相似用户的行为推荐
  • 内容推荐:根据演出类型、艺人、城市推荐
  • 热门推荐:结合平台热度综合推荐

实现方式: 我们用Dify搭建了推荐工作流,输入用户行为数据,输出个性化推荐列表

async def get_personalized_recommend(user_id: int): # 获取用户最近30天的行为数据 behavior = await get_user_behavior(user_id) # 调用Dify工作流生成推荐 response = await dify_client.run_workflow( workflow_id="personalized_recommend", inputs={ "user_id": user_id, "behavior": behavior, "top_k": 6 # 返回6个推荐结果 } ) return response.get("recommendations", [])

效果: 上线后,推荐模块的点击率比随机推荐提升了35%,用户转化率提升了20%

4. 核心交互:选座购票

这部分是用户购票的核心流程,我们做了很多优化:

4.1 交互式座位图

用户进入选座页面后,会看到一个可视化的座位图,不同状态的座位用不同颜色区分:

  • 绿色:可选座位
  • 红色:已售出座位
  • 蓝色:用户已选座位
  • 黄色:临时锁定座位
<template> <div class="seat-map-container"> <div class="stage-indicator">舞台</div> <div class="seat-area"> <div v-for="(row, rowIndex) in seatRows" :key="rowIndex" class="seat-row"> <div class="row-label">{{ rowIndex + 1 }}</div> <div v-for="seat in row" :key="seat.id" :class="getSeatClass(seat)" @click="handleSeatClick(seat)" > <span v-if="seat.status === 0 && selectedSeats.includes(seat.id)">✓</span> </div> </div> </div> </div> </template>

4.2 座位锁定机制

用户选好座位后,系统会自动锁定这些座位15分钟,防止被其他用户抢走:

async def lock_seats(seat_ids: list, user_id: int) -> bool: async with async_session() as session: seats = await session.execute( select(Seat).where(Seat.id.in_(seat_ids), Seat.status == 0) ) if len(seats.scalars().all()) != len(seat_ids): return False await session.execute( update(Seat) .where(Seat.id.in_(seat_ids)) .values(status=2, lock_user_id=user_id, lock_time=datetime.now()) ) await session.commit() for seat_id in seat_ids: await redis_client.set(f"seat_lock:{seat_id}", user_id, ex=900) return True

5. 秒杀系统:高并发挑战

秒杀是最考验技术的部分。我们用Redis预减库存,再用MySQL乐观锁兜底,确保不会超卖。单SKU能支持5万次/秒的请求

async def seckill(sku_id: int, user_id: int): result = await redis_client.decr(f"stock:{sku_id}") if result < 0: return False async with async_session() as session: update_count = await session.execute( update(PerformanceSKU) .where(PerformanceSKU.id == sku_id, PerformanceSKU.stock >= 1) .values(stock=PerformanceSKU.stock - 1) ) if update_count.rowcount == 0: await redis_client.incr(f"stock:{sku_id}") return False await session.commit() return True

6. 订单管理:全生命周期追踪

订单状态流转很复杂,我们做了清晰的状态机:待支付→已支付→已出票,支持退票和取消。超时未支付的订单会自动取消

待支付 → 已支付 → 已出票 ↓ ↓ 支付失败 退票申请中 → 已退款 ↓ 超时取消/主动取消

7. 智能客服:24小时在线答疑

7.1 多轮对话支持

用户可以和客服进行多轮对话,客服会记住上下文:

async def ai_chat(user_id: int, question: str, session_id: str = None): history = await get_chat_history(user_id, session_id) messages = [] for msg in history: messages.append({"role": msg.role, "content": msg.content}) messages.append({"role": "user", "content": question}) response = await dify_client.run_workflow( workflow_id="ai_chat", inputs={"user_id": user_id, "messages": messages} ) await save_chat_history(user_id, response.get("session_id"), [ {"role": "user", "content": question}, {"role": "assistant", "content": response.get("answer")} ]) return {"answer": response.get("answer"), "session_id": response.get("session_id")}

7.2 知识库集成

我们把演出信息、购票规则、退票政策等内容整理成知识库,让AI客服能准确回答用户问题

async def query_knowledge_base(question: str) -> str: """查询知识库""" # 构建ES查询 query = { "bool": { "should": [ {"match": {"title": {"query": question, "boost": 2}}}, {"match": {"content": question}} ] } } result = await es_client.search(index="knowledge_base", query=query) if result["hits"]["total"]["value"] > 0: return result["hits"]["hits"][0]["_source"]["content"] return None

7.3 智能路由

根据用户问题类型,自动路由到不同的处理逻辑:订单查询、退票政策、演出信息等

async def process_user_question(user_id: int, question: str): """处理用户问题""" # 意图识别 intent = await classify_intent(question) if intent == "order_status": # 查询订单状态 order_no = extract_order_no(question) return await get_order_status(order_no) elif intent == "refund_policy": # 返回退票政策 return await query_knowledge_base("退票政策") elif intent == "performance_info": # 查询演出信息 performance_name = extract_performance_name(question) return await get_performance_info(performance_name) else: # 交给AI处理 return await ai_chat(user_id, question)

7.4 客服界面

前端做了一个类似聊天软件的界面:

<template> <div class="chat-container"> <!-- 聊天消息列表 --> <div class="message-list"> <div v-for="(msg, index) in messages" :key="index" :class="['message', msg.role]" > <div class="avatar">{{ msg.role === 'user' ? '我' : '客服' }}</div> <div class="content">{{ msg.content }}</div> </div> </div> <!-- 输入框 --> <div class="input-area"> <input v-model="inputMessage" @keyup.enter="sendMessage" placeholder="请问有什么可以帮您?" /> <button @click="sendMessage">发送</button> </div> </div> </template> <script setup lang="ts"> import { ref } from 'vue' const messages = ref<{role: string; content: string}[]>([ {role: 'assistant', content: '您好!我是智速优座的智能客服,请问有什么可以帮您?'} ]) const inputMessage = ref('') const sendMessage = async () => { if (!inputMessage.value.trim()) return // 添加用户消息 messages.value.push({role: 'user', content: inputMessage.value}) // 调用API const response = await api.aiChat(inputMessage.value) // 添加客服回复 messages.value.push({role: 'assistant', content: response.answer}) inputMessage.value = '' } </script>

8. 后台管理系统

有很多功能,这里挑重要的说

8.1 演出管理

  • 演出列表:支持分页、搜索、筛选(按状态、城市、类型)
  • 新增演出:填写演出名称、类型、海报、场馆、时间等信息
  • 场次管理:给演出添加多个场次,设置票价和库存
  • 座位管理:批量导入座位信息,可视化座位图编辑
  • 状态控制:一键上架/下架演出,自动下架过期演出

8.2 用户管理

  • 用户列表:查看所有用户,支持搜索和筛选
  • 用户详情:查看用户的基本信息、订单记录、积分余额
  • 黑名单管理:将恶意用户加入黑名单,禁止登录

8.3 订单管理

  • 订单列表:支持按订单号、用户ID、状态筛选
  • 订单详情:查看订单完整信息(座位、金额、支付方式等)
  • 退票审核:处理用户的退票申请,支持通过/拒绝
  • 订单统计:实时统计订单数量、销售额、转化率
# 退票审核接口 @app.post("/api/admin/order/{order_id}/refund") async def approve_refund(order_id: int, approved: bool, operator_id: int): async with async_session() as session: order = await session.get(Order, order_id) if not order or order.status != OrderStatus.REFUND_PENDING.value: raise HTTPException(status_code=400, detail="订单状态不允许") if approved: # 计算退款金额(扣除手续费) refund_amount = order.amount * (1 - (order.refund_fee_rate or 0)) order.status = OrderStatus.REFUNDED.value order.refund_amount = refund_amount order.refund_approved = True order.refund_approve_time = datetime.now() order.refund_operator = operator_id # 返还库存 await session.execute( update(PerformanceSKU) .where(PerformanceSKU.id == order.sku_id) .values(stock=PerformanceSKU.stock + 1) ) else: order.status = OrderStatus.PAID.value order.refund_approved = False await session.commit() return {"message": "审核成功"}

8.4 数据统计

  • 销售统计:每日/每周/每月的订单数量、销售额、客单价
  • 演出排行:按销售额、购票人数排序的演出TOP10
  • 实时监控:当前在线用户数、系统响应时间、错误率
# 获取销售统计数据 async def get_sales_statistics(start_date: date, end_date: date): async with async_session() as session: result = await session.execute( select( func.date(Order.create_time).label("date"), func.count(Order.id).label("order_count"), func.sum(Order.amount).label("total_amount") ) .where( Order.create_time >= start_date, Order.create_time <= end_date, Order.status == OrderStatus.PAID.value ) .group_by(func.date(Order.create_time)) ) return [{"date": row.date, "order_count": row.order_count, "total_amount": row.total_amount} for row in result]

四、项目中遇到的问题以及解决

问题一:库存超卖

问题场景:第一次做秒杀测试的时候,我们准备了100张票,结果系统显示卖出去了120多张

问题表现

  • 秒杀开始后,库存瞬间变成负数
  • 用户下单成功但实际没有票
  • 客服收到大量投诉

根本原因: 我们一开始用的是"先查后改"的逻辑:在高并发场景下,多个请求同时查到库存>0,然后同时扣减,就导致了超卖

解决方案: 改成了"Redis预减库存 + MySQL乐观锁"的方案:

  1. 先用Redis的原子操作预减库存
  2. 再用MySQL乐观锁兜底
  3. 如果MySQL扣减失败,回滚Redis库存

效果:秒杀成功率达到99.99%,再也没出现过超卖问题

问题二:缓存一致性问题

问题场景:运营人员在后台修改了演出信息,但用户看到的还是旧数据

问题表现

  • 后台修改了演出票价,用户看到的还是旧价格
  • 演出下架了,但搜索结果里还能找到

根本原因: MySQL数据更新后,Redis缓存没有及时失效。我们一开始是手动删除缓存,但有时候会忘记,或者删除失败

解决方案

  1. 用Canal监听MySQL的binlog
  2. 当数据变化时,自动删除对应的Redis缓存
  3. 加一个缓存失效队列,确保缓存一定会被删除

效果:数据延迟从原来的几分钟降到了<100ms

问题三:分布式事务问题

问题场景:用户下单时,订单创建成功了,但座位锁定失败,导致数据不一致。

问题表现

  • 用户收到订单成功的消息,但选的座位还是可选状态
  • 同一个座位被多个用户下单

根本原因: 订单创建和座位锁定是两个独立的数据库操作,没有用事务管理。如果中间某个步骤失败,就会导致数据不一致。

解决方案: 用消息队列实现最终一致性:

  1. 先创建订单(状态为"待确认")
  2. 发送座位锁定消息到RabbitMQ
  3. 消费者收到消息后锁定座位
  4. 如果锁定成功,更新订单状态为"待支付"
  5. 如果锁定失败,取消订单

效果:订单和座位状态保持一致,再也没有出现过数据不一致的情况

问题四:消息队列堆积

问题场景:秒杀活动结束后,支付回调消息堆了好几万条,消费者处理不过来。

问题表现

  • RabbitMQ消息队列长度持续增长
  • 用户支付成功后,订单状态迟迟不更新
  • 系统响应变慢

根本原因: 我们一开始只部署了1个消费者,处理能力有限。秒杀时每秒产生几千条消息,远远超过了消费者的处理能力。

解决方案

  1. 动态扩容消费者数量(从1个增加到10个)
  2. 给消息设置优先级,重要消息优先处理
  3. 优化消费者代码,提高处理速度

效果:消息堆积问题得到缓解,消息处理延迟从原来的几分钟降到了几秒钟

五、项目的亮点

  1. 高并发秒杀:成功率99.99%
  2. 实时数据同步:Canal监听MySQL,数据延迟<100ms
  3. AI智能推荐:提升用户转化率20%
  4. 完善的选座体验:可视化座位图,智能锁定
  5. 智能客服:多轮对话,知识库支持
  6. 强大的后台管理:全流程运营支持
  7. Docker容器化:一键部署

六、项目总结与感受

做这个项目最大的收获,就是对"高并发"有了真正的理解。以前只在书本上看过的概念,这次都在实战中用到了

智能推荐、选座体验、智能客服这些功能虽然不是核心交易流程,但对提升用户体验和转化率至关重要。后台管理系统则是运营团队的核心工具,能大大提升工作效率

还有一个感悟:没有完美的系统,只有不断进化的系统。我

标签建议

通用标签

  • 文章分析
  • 内容标签
  • 关键词提取
  • 文本分类

技术/方法论标签

  • 自然语言处理
  • 文本挖掘
  • 信息检索
  • 机器学习

应用场景标签

  • 内容推荐
  • 知识管理
  • 数据标注
  • 智能摘要

细分领域标签

  • 语义分析
  • 主题建模
  • 特征提取
  • 标签生成

如果需要更具体的标签,可以提供文章内容或主题方向以便进一步细化。

现在的系统还有很多不足,但只要持续改进,就会越来越好

最后,如果你也在做类似的项目,欢迎一起交流!

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

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

立即咨询