ASP.NET Core餐饮点餐系统开发实战
2026/9/14 20:51:13 网站建设 项目流程

1. 项目背景与核心需求

去年接手了一个餐饮连锁企业的数字化改造项目,他们急需一套能够打通线上线下点餐流程的系统。经过多方对比,最终选择了ASP.NET Core作为技术栈,主要看中其高性能、跨平台特性和丰富的生态系统。这个点餐系统需要满足以下核心需求:

  • 支持微信小程序和网页端双渠道点餐
  • 实时同步后厨订单数据
  • 会员积分与优惠券系统
  • 智能推荐菜品功能
  • 多门店库存管理

2. 技术架构设计

2.1 整体架构方案

系统采用经典的三层架构:

  1. 表现层:微信小程序+管理后台网页
  2. 业务逻辑层:ASP.NET Core Web API
  3. 数据访问层:Entity Framework Core + SQL Server

特别加入了SignalR实现实时通信,当后厨完成菜品制作时,前台和大屏能实时收到通知。数据库方面采用读写分离设计,主库负责订单写入,从库处理查询请求。

2.2 关键技术选型

  • 跨域处理:使用EnableCorsAttribute配置
services.AddCors(options => { options.AddPolicy("AllowAll", builder => { builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); }); });

实际生产环境中不建议使用AllowAnyOrigin(),我们后期改为指定具体域名

  • ORM选择:Entity Framework Core 6.0
  • 缓存方案:Redis缓存热门菜品数据
  • 文件存储:阿里云OSS存储菜品图片

3. 核心功能实现

3.1 微信小程序接入

小程序端采用uniapp框架开发,与ASP.NET后端通过JWT进行认证。关键点在于处理微信支付回调:

[HttpPost] [Route("api/payment/notify")] public async Task<IActionResult> WechatPayNotify() { using var reader = new StreamReader(Request.Body); var xmlData = await reader.ReadToEndAsync(); // 验证签名逻辑 if(!VerifyWechatSign(xmlData)) { return BadRequest(); } // 更新订单状态 var orderId = GetOrderIdFromXml(xmlData); await _orderService.CompletePaymentAsync(orderId); return Ok("<xml><return_code>SUCCESS</return_code></xml>"); }

3.2 实时订单处理

使用SignalR实现订单状态实时推送:

public class OrderHub : Hub { public async Task JoinKitchenGroup() { await Groups.AddToGroupAsync(Context.ConnectionId, "Kitchen"); } } // 订单状态变更时通知 await _hubContext.Clients.Group("Kitchen") .SendAsync("OrderUpdated", orderId, status);

前端通过监听事件更新UI:

connection.on("OrderUpdated", (orderId, status) => { const orderElement = document.getElementById(`order-${orderId}`); orderElement.classList.add(`status-${status}`); });

4. 数据库设计要点

4.1 主要表结构

CREATE TABLE [dbo].[Dishes] ( [Id] INT IDENTITY PRIMARY KEY, [Name] NVARCHAR(100) NOT NULL, [Price] DECIMAL(10,2) NOT NULL, [ImageUrl] NVARCHAR(255), [IsRecommend] BIT DEFAULT 0 ); CREATE TABLE [dbo].[Orders] ( [Id] UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID(), [OrderNo] VARCHAR(20) NOT NULL, [TotalAmount] DECIMAL(10,2) NOT NULL, [Status] TINYINT NOT NULL DEFAULT 0, [CreateTime] DATETIME2 DEFAULT SYSDATETIME() );

4.2 性能优化措施

  1. 为高频查询字段添加索引:
CREATE INDEX IX_Orders_Status ON Orders(Status); CREATE INDEX IX_Orders_CreateTime ON Orders(CreateTime);
  1. 使用表分区处理历史订单数据
  2. 引入Redis缓存菜单数据

5. 踩坑经验分享

5.1 跨域问题排查

开发初期遇到CORS问题,发现即使配置了EnableCorsAttribute("","","*"),某些请求仍然失败。后来发现:

  1. 预检请求(OPTIONS)需要单独处理
  2. 带凭证的请求不能使用*
  3. 某些特殊Header需要显式暴露

最终解决方案:

services.AddCors(options => { options.AddPolicy("ProductionPolicy", builder => { builder.WithOrigins("https://client.domain.com") .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials() .SetPreflightMaxAge(TimeSpan.FromHours(1)) .WithExposedHeaders("X-Custom-Header"); }); });

5.2 并发订单处理

高峰期出现超卖问题,通过三种方案对比测试:

  1. 乐观并发控制(EF Core原生支持)
try { var dish = await _context.Dishes.FindAsync(id); dish.Stock -= quantity; await _context.SaveChangesAsync(); } catch(DbUpdateConcurrencyException) { // 处理冲突 }
  1. 使用数据库事务
using var transaction = await _context.Database.BeginTransactionAsync(); // 业务逻辑 await transaction.CommitAsync();
  1. Redis分布式锁(最终采用方案)
using var redLock = await _redLockFactory.CreateLockAsync( $"dish_{dishId}_lock", TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10), TimeSpan.FromSeconds(0.5) ); if(redLock.IsAcquired) { // 处理库存 }

6. 部署与监控

6.1 容器化部署

使用Docker编排服务:

FROM mcr.microsoft.com/dotnet/aspnet:6.0 WORKDIR /app COPY ./publish . ENTRYPOINT ["dotnet", "RestaurantSystem.dll"]

配合docker-compose.yml管理多个服务:

version: '3.8' services: web: build: . ports: - "5000:80" environment: - ConnectionStrings__Default=Server=db;Database=Restaurant;User=sa;Password=yourpassword; db: image: mssql/server:2019-latest environment: - ACCEPT_EULA=Y - SA_PASSWORD=yourpassword

6.2 监控配置

  1. 健康检查端点:
app.MapHealthChecks("/health", new HealthCheckOptions { ResponseWriter = async (context, report) => { context.Response.ContentType = "application/json"; await context.Response.WriteAsync(/* 自定义格式 */); } });
  1. 使用Application Insights收集日志
  2. 配置警报规则监控订单失败率

这个项目从零开始到最终上线历时4个月,期间遇到了各种技术挑战,特别是高并发场景下的数据一致性问题。建议后续可以考虑引入领域驱动设计(DDD)来更好地处理复杂业务逻辑,同时将部分服务拆分为微服务架构以提升扩展性。

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

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

立即咨询