ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

基于Android的网上订餐系统设计与实现:双端全流程与状态机实践

基于Android的网上订餐系统设计与实现:双端全流程与状态机实践 基于Android的晓海网上订餐系统的设计与实现——从0到1搭建双端点餐全链路做这个项目的时候我其实是把它当成一个完整的商业系统来推演的而不是应付式地搭个Demo。现在回头看最值钱的部分反而不是代码本身而是如何梳理角色、梳理订单状态、梳理双端协作这一整套思维。很多同学做订餐系统上来就写界面、写按钮结果做到后半程发现用户端、商家端、管理端数据对不上订单状态乱成一锅粥购物车和小程序的库存不同步最后只能推翻重来。这篇文章就把我做晓海网上订餐系统的完整思路、技术选型、核心实现和踩坑记录分享出来希望能帮你少走几周弯路。这套系统解决的核心问题是用户怎么通过Android App或微信小程序快速完成浏览菜品、加购、下单、支付商家怎么接单、备餐、出餐管理员怎么看数据、管菜品、管分类。整体项目覆盖了Android端、小程序端、共用的后端API服务三块。适合正在做毕设、课设或者想自己完整走一遍双端服务端全栈流程的开发者参考。文章不会堆砌每行代码而是把关键链路和决策过程讲透让你拿去能直接动手搭。1. 项目整体设计与技术选型为什么是Android小程序双端1.1 需求背景与用户角色拆解网上订餐系统本质上就是一个多角色协作平台在设计之初我首先做的是把利益相关方全部列出来而不是急着写代码。这个系统里至少存在三类核心角色普通消费者、餐厅商家、平台管理员。消费者想要的是快速浏览、顺畅下单、方便支付商家想要的是看到新订单、及时改状态、维护菜品管理员想要的是知道每天卖了多少、哪些菜好卖、用户反馈如何。这三类角色的诉求互相交织如果没有一开始就画清楚后边很容易出现用户下单了商家不知道这种致命问题。我把角色的权限边界和操作边界做成了一张表贴在开发文档第一页角色使用端核心操作数据可见范围消费者Android App / 微信小程序浏览菜品、加购、下单、支付、查看订单自己的订单、个人信息商家管理后台Web/Android上架下架菜品、接单、备餐、出餐、查看本店订单本店菜品、本店订单管理员管理后台用户管理、商家管理、数据统计、分类维护全平台数据这个表格看起来简单但它决定了后续所有接口的权限设计。我在开发时把权限控制放在后端做统一校验用户登录后拿到的token里带角色标识每次请求API时后端都会校验角色和资源归属比如商家只能修改自己店铺的菜品不能动别人的用户只能看到自己名下的订单不能查别人。这样设计的好处是双端Android和小程序只是皮肤真正的业务规则全部收敛在服务端无论哪个端出问题数据不会乱。1.2 技术栈选型的核心考量我选技术栈的时候遵循一个原则不追新求稳。因为这是一个需要完整跑通的系统不是某个单一功能的验证如果选了社区不成熟、坑都没人踩过的框架很容易卡在环境问题上消耗时间。Android端我用了原生开发语言选Java。虽然现在Kotlin已经是官方主推但我的考量是两点第一大量参考项目和文档还是Java写的遇到问题更容易找到现成答案第二对于毕设和课程设计场景很多老师还停留在JavaXML的开发思维里这样答辩的时候解释起来更顺畅。IDE用的是Android Studio这里要提醒一下版本匹配问题。我一开始装的是最新的Android Studio Hedgehog2023.1.1创建项目时发现AGP版本要求8.2以上而很多第三方库和模拟器镜像还没有完全适配后来我调整为AGP 8.1配合Gradle 8.0整体编译稳定性明显提升。如果你在建项目时遇到构建脚本报错优先检查AGP和Gradle的版本兼容表不要盲目升级到最新。小程序端我选择了原生微信小程序没有用uniapp或HBuilderX。理由也很简单这个项目的核心诉求是打通登录-点餐-支付这条链路而原生的微信登录、wx.request、wx.requestPayment接口在文档和社区里资料最全踩坑成本最低。如果你做的是一个需要同时发布到支付宝、百度等多平台的小程序uniapp确实更合适但对这个项目来说没必要引入额外的抽象层。另外现在微信开发者工具已经非常成熟支持云开发、真机调试、性能面板联调效率不低。服务端用了Spring Boot 2.xMySQL这是最标准的组合。选Spring Boot是因为它天然适合做RESTful API内置Tomcat、依赖注入、Spring Security这些组件让我可以专注于业务逻辑本身不用重复造轮子。MySQL单库设计订单表、用户表、菜品表、购物车表、分类表共五张核心表表关系清晰后续扩展也方便。1.3 系统总体架构与数据流设计整体架构是标准的三层表现层Android端小程序端→ 业务层Spring Boot API → 数据层MySQL。用户在Android端或小程序端发起请求通过HTTP/HTTPS调用后端接口后端处理业务逻辑后返回JSON数据。支付环节走微信支付用户在端上拉起支付后微信服务器会通过回调通知后端后端更新订单状态。这里有一个关键设计决策小程序端与Android端共用同一套后端API。很多初学同学会犯一个错误就是两端各自写一套接口Android调Java接口小程序调Node接口维护成本直接翻倍。我坚持共用API好处有三个一是业务规则只维护一份二是数据格式统一两端展示效果一致三是新增客户端时比如以后要做iOS端可以无缝接入。接口设计上我遵循RESTful风格资源用名词操作用动词比如GET /api/dishes获取菜品列表、POST /api/orders创建订单、PUT /api/orders/{id}/status更新订单状态。数据流最核心的节点是订单。用户从点餐到支付完成订单状态的变化路径是这样一条链路待支付→已支付→商家接单→备餐中→出餐/待取餐→完成。每一跳都由某个角色的某个操作触发后端在接收状态变更请求时会做校验不允许跳级修改。比如用户不能把待接单直接改成已完成因为中间还隔着备餐、出餐两个环节。这条状态机的设计在开发时是直接写死在服务端的枚举类里的避免了状态乱跳导致的各种逻辑漏洞。2. 服务端设计与数据库建模先有规矩后有代码2.1 接口设计思路与鉴权方案接口设计是整个系统的交通规则我在动手写代码之前先花了差不多三个小时把接口文档列出来。不需要用什么昂贵的工具一个Excel表格就够接口路径、请求方式、请求参数、返回格式、当前端点和后端方法的对应关系。全部列完以后我发现自己对系统的理解又清晰了一层后面写代码基本是照着翻译而不是边写边想。鉴权方案我选用了比较轻量的Token方式。用户登录成功后后端生成一个UUID作为token存入Redis并设置过期时间同时把token返回给客户端。客户端在后续所有请求的Header里带上Authorization: Bearer 后端通过拦截器统一校验校验不通过直接返回401状态码。这个方案比Session简单天然适合无状态API而且小程序端处理起来非常方便——每次wx.request时在header里追加token字段就行。有一个细节值得单独拿出来讲用户表里我设计了一个roles字段来区分角色Android端和小程序端的用户默认都是消费者角色。但数据库中消费者和商家的用户信息都存在同一张表里通过role字段0-管理员、1-商家、2-用户区分。这样设计的好处是登录接口不需要分两套一套接口通过手机号密码完成认证后端根据roles字段返回对应的角色信息。商家端的注册和审核流程我没做得很复杂管理员在后台上直接把某个账号的角色改为商家即可毕设场景这个粒度完全够用。2.2 订单状态机的设计与实现如果说接口是系统的血管那么状态机就是系统的心脏。订单状态一旦设计得有漏洞整个系统的可靠性就会崩塌。我的订单状态枚举设计如下0-待支付用户提交订单后默认状态绑定支付倒计时比如15分钟未支付自动取消1-已支付用户支付成功等待商家处理2-商家接单商家看到新订单后点击接单表示已确认3-备餐中商家开始制作通常由接单操作自动触发或商家手动修改4-待取餐/配送中备餐完成等待用户到店自取或骑手取餐5-已完成用户确认收货或商家确认完成6-已取消用户或商家取消订单有原因记录在代码实现上我用了一个枚举类OrderStatus里面定义了statusCode、description以及一个canTransitTo方法用来判断当前状态能否跳到目标状态。比如status1已支付的订单只能跳转到2商家接单或6已取消不能跳转到4。这个方法在订单状态变更接口里作为第一道校验防止非法跳转。实测下来这个设计在真实场景里非常有用。比如我后期测出一个bug用户支付成功后微信回调还没到用户就自己点取消订单结果状态被改成已取消但钱已经扣了。引入状态机的canTransitTo校验后我发现已支付状态在回调尚未到达前其实有两种可能情况于是我又加了一个中间状态支付中微信回调到达后再从支付中变更为已支付。这个细节如果不做状态机靠if-else硬顶代码会越写越乱。2.3 数据库表结构核心要点数据库我建了五张核心表外加一个token表其实可以用Redis代替但考虑到项目部署的简单性我直接存了数据库。下面是每张表的设计要点用户表(user)主键id、手机号phone唯一索引、密码passwordMD5加盐、昵称nickname、头像avatar、角色role、创建时间。密码加盐这一点必须强调直接用MD5不加盐在真实环境里等于裸奔虽然毕设演示没问题但养成好习惯很重要。菜品表(dish)主键id、所属商家store_id、分类category_id、菜品名称name、图片url、单价price、描述description、月销量sold、状态status上架/下架、创建时间。月销量这个字段每次订单完成时自增方便列表页按销量排序。订单表(orders)主键id、订单编号order_no全局唯一、用户user_id、商家store_id、总金额total_amount、订单状态status、收货信息address、备注remark、支付方式pay_method、创建时间、支付时间、更新时间。order_no我用了时间戳用户ID随机数拼出来的字符串保证并发场景下不重复。订单明细表(order_item)主键id、订单id order_id、菜品id dish_id、菜品名称、下单时单价price、数量count、小计subtotal。这里有个很重要的设计要把菜品名称和下单时单价冗余到明细表里。这样即使商家后面修改了菜品价格甚至删除了菜品历史订单依然能够正确显示当时买的是什么、花了多少钱。购物车表(cart)主键id、用户id、菜品id、数量count、加入时间。购物车我按用户维度设计Android端和小程序端共用同一份购物车数据。用户在App加了几个菜到小程序里打开购物车依然能看到体验上是无缝的。实现方法不复杂就是两个端都调用同一个读取购物车接口而不是存在本地。数据库设计阶段最容易犯的错误是为了方便查询把很多字段堆在同一个表里或者反过来为了范式化把表拆得太碎。我的原则是核心业务数据订单、明细适度冗余方便联表查询状态类字段使用枚举值而不是字符串减少脏数据。比如订单状态我用INT类型存枚举编号搭配状态解释表而不是直接存已支付这样的中文文本避免因手误产生以支负已支付 这类脏数据。3. Android端核心功能落地从界面到交互的完整实现3.1 环境配置与项目骨架搭建Android端我采用MVC分层结构包名划分成activity、adapter、model、utils、api、fragment这样几个层级。如果你对架构模式还没什么概念建议别一上来就上MVP/MVVMMVC在这个体量的项目里最清晰逻辑全在Activity里虽然被诟病很重但这个体量下不会有问题反而是最好复盘和答辩的。构建项目时先确认好Android Studio和AGP版本。我用的版本组合是Android Studio Hedgehog2023.1.1配合AGP 8.1Gradle 8.0。如果项目创建失败或编译报错先检查gradle-wrapper.properties里的distributionUrl再检查build.gradle里的AGP版本两者必须兼容。有时候报Failed to resolve: com.android.tools.build:gradle就是版本不匹配的典型症状。网络层我用了OkHttpRetrofit的组合。Retrofit负责接口定义和参数绑定OkHttp做底层的连接管理和拦截器。拦截器里做了三件很关键的事给所有请求自动添加token头、统一的日志打印、统一的异常处理。这样一来业务代码里就不用反复写获取token-塞进header-处理401这一套重复逻辑了。3.2 点餐-加购-下单-支付主链路实现主链路是用户打开App后完成一次完整点餐的核心路径我把它切成五个界面来承载首页分类菜品、菜品详情、购物车底栏、确认订单、支付结果。每个界面之间的数据传递我统一采用Intent传id网络拉取详情的方式而不是把整个对象序列化传过去。这样做的好处是如果菜品信息在跳转过程中被修改了用户看到的始终是最新的数据避免展示过期价格。购物车的实现是这个项目的重点也最容易出bug。Android端的购物车数据完全来自后端本地不做持久化。每次进入购物车页面时调用GET /api/cart?userIdxxx拿到菜品ID、数量、单价列表。加购操作的核心逻辑是点击加购按钮时先检查购物车里是否已有这个菜有则数量1没有则新增一条记录。因为这个项目是单店铺模型我没有处理不同店铺的菜不能混加这种多店铺购物车逻辑实际开发中如果扩展成多商家平台购物车的表结构就需要增加store_id维度下单时按store_id分组拆单。确认订单页比较常规展示菜品清单、总价、收货地址、备注输入框。这里有个用户容易困惑的点总价怎么算我一开始在Android端手动累加购物车条目生成总价后来发现如果后端价格调整了或者购物车里有已下架菜品客户端算出来的总价就会和后端不一致。于是我把这个逻辑也收敛到了后端确认订单接口会重新读取购物车、校验菜品上架状态和价格然后返回最新的明细和总价。客户端只负责展示不参与金额计算。这一点在你做任何涉及钱的项目时都应该强制坚持金额计算永远以服务端为准。支付环节我用的是微信支付App支付。在Android端拉起支付的流程是后端先生成预支付订单返回给客户端一组参数appid、partnerid、prepayid、package、noncestr、timestamp、sign客户端用这组参数调用微信SDK的PayReq发起支付。支付完成后微信会通过回调通知后端服务器后端才更新订单状态为已支付App端则通过轮询或长连接方式获取最新状态。这里要注意App端不能只凭本地回调结果就认定支付成功因为本地回调可能被伪造一定要以服务端接收到的微信回调为准。3.3 登录鉴权与本地缓存方案Android端登录我实现了两种方式密码登录和验证码登录验证码用短信模拟的本地写死一个万能验证码便于演示。登录成功后token存到一个全局的单例类里同时用SharedPreferences持久化。每次App冷启动时先从SharedPreferences读取token如果存在就尝试调一下获取用户信息接口来判断token是否过期如果返回401就自动跳转到登录页。本地缓存这块我用SharedPreferences存了用户基本信息头像、昵称、手机号菜品列表的图片用了简单的三级缓存机制——内存缓存LruCache 磁盘缓存 网络。开发时我用的是自己搭的本地图片服务没有接七牛或OSS因为毕设场景里本地存储完全够用。这里有一个实践小技巧图片URL不要直接存绝对路径存相对路径比如/image/dish/001.jpg请求时再拼接当前服务器的BaseUrl。这样后期如果换了服务器地址只需要改一个常量不需要改数据库里的数据。有一段踩坑经历值得分享Android 11开始系统对文件访问做了严格限制很多同学在开发时会遇到读取本地图片失败或者file:///storage/emulated/0/... 无法访问这种问题。我的解决方法是所有涉及图片存取的操作都通过应用私有目录getExternalFilesDir来做不要直接读写公共存储目录。这样既符合规范又省去了申请存储权限的麻烦。如果你在写文件上传功能时遇到FileProvider配置相关的问题也可以直接采用这个方案绕开。4. 微信小程序端开发要点不是简单搬运而是场景化重构4.1 小程序与Android端的功能边界划分很多同学做双端项目时会陷入一个误区把Android端的界面原封不动搬到小程序里。这样做既累又没必要。我一开始就明确了一个原则核心业务闭环点餐、下单、支付两端都要有但展示形式和交互细节根据端特点做差异化设计。Android端的目标用户更倾向于深度使用界面可以信息密度高一些侧边栏分类列表式菜品小程序端则应该是轻量快捷用户打开就能看到重点推荐首页做了一张大大的轮播图下面是按销量排序的菜品列表减少冗余跳转。小程序端我给商家做了一个管理功能入口商家可以用小程序快速查看新订单并接单。这个功能在Android端我没有做因为商家的高频操作场景是人在店里手机随手点一下小程序不用下载、即用即走的属性天然更适合。功能边界划分清晰后两端的开发量都大幅下降了。Android端聚焦用户点餐小程序端做用户点餐商家简易接单后台管理系统放在Web端。三个端覆盖了所有角色又不会出现同一功能被重复开发的情况。4.2 微信登录与后端session打通小程序登录流程和App登录有本质区别App登录是用户主动输入账号密码小程序登录则依赖微信的openid体系。常规的流程是小程序端调用wx.login获取code - 把code发送到后端 - 后端拿code到微信接口换openid和session_key - 后端用openid关联本地用户如果查不到就自动创建一个新用户 - 返回自定义token给小程序。我在这条链路上踩过一个比较大的坑。先在微信开发者工具里测试一切正常但真机预览时始终报获取登录后的微信用户失败。排查了很久发现是没配置request合法域名。开发者工具里可以勾选不校验合法域名但真机上必须在小程序管理后台配置request合法域名和业务域名否则wx.request会直接失败。这里提醒一点开发阶段可以勾选跳过校验上线前一定要去微信公众平台把域名配置好否则用户手机上根本打不开。另外wx.login的code有效期只有5分钟且每次调用都会刷新所以后端要用完就换成openid不要再依赖code做后续操作。openid是用户在微信生态里的唯一标识同一个用户在不同小程序里openid不同所以后端用户表里我专门加了openid字段与手机号、密码字段允许同时存在小程序用户mobile字段为空用openid登录Android端用户openid字段为空用手机号密码登录。两端是同一个用户实体只是登录方式不同。如果用户希望两边能合并账号最简单的做法是在小程序端做一个绑定手机号的入口登录后引导用户绑定手机号绑定后下次就能直接用手机号在Android端登录而且订单数据天然互通。4.3 小程序UI适配与组件坑点小程序端的UI框架我直接用WXMLWXSS手写没有引入Vant Weapp等组件库。原因很简单项目页面数量不多手写更轻量引入组件库反而增加了不必要的体积和样式覆盖成本。但手写也意味着要自己处理不少兼容性问题。最常见的坑是iPhone底部的安全区适配。小程序页面如果有固定在底部的按钮比如去结算按钮在iPhone X及以后的机型上会被系统Home Indicator遮挡。解决办法是在按钮容器上加padding-bottom: constant(safe-area-inset-bottom)并兼容env()写法。很多同学知道要加但忘了一个细节constant()只兼容iOS 11.0-11.2env()兼容iOS 11.2所以两条都要写顺序是先constant()再env()。我自己的button容器最终写法是.settle-bar { padding-bottom: constant(safe-area-inset-bottom); padding-bottom: env(safe-area-inset-bottom); }另一个点是导航栏高度。小程序的胶囊按钮位置在不同机型上不一致如果做自定义导航栏需要动态获取胶囊位置来计算状态栏高度。我封装了一个getSystemInfo方法在onLoad里调用把状态栏高度、胶囊按钮位置存到全局变量里所有页面的自定义导航栏都按这个值来布局。小程序页面之间传递数据我用的是事件通道eventChannel替代了Android里的Intent传参在跳转前通过navigationController配合eventChannel来传参。还有一个小程序特有的痛点图片上传。Android端用multipart/form-data格式上传小程序里要先用wx.chooseMedia选图然后通过wx.uploadFile上传网络库跟wx.request是两个体系。我在后端写的上传接口同时兼容这两种格式用文件名判断二进制流读取的方式统一处理这样Android和小程序都不用改后端代码。小程序还有一个性能上的注意点setData操作会同步更新视图高频调用会造成渲染卡顿。我在购物车数量频繁加减的场景里做了节流处理只在用户停止点击后批量更新数据而不是每次1就setData一次。看起来很小但实测对低端Android手机上的小程序体验影响很明显。5. 联调、测试与常见问题排查真实开发中避不开的坑5.1 真机联调环境准备联调是双端项目里最考验耐心的一环。我发现的第一个问题是localhost陷阱Android模拟器上访问本机服务端用10.0.2.2真机要访问电脑的局域网IP小程序开发者工具里要关掉不校验合法域名或者配置好域名。这三个地方的服务器地址如果不统一联调时就会频繁出现请求失败、连接超时、网络错误等提示。我的做法是项目里所有网络请求的BaseUrl统一封装在一个常量配置类里通过BuildConfig字段区分debug和release环境。联调时用debug环境BaseUrl指向电脑局域网IP比如http://192.168.1.100:8080上线前切换releaseBaseUrl指向云服务器域名。这样切换环境只改一个配置文件不用全局搜索替换。第二个坑是HTTPS证书问题。小程序正式环境要求所有请求必须是HTTPS且证书要备案和配置到合法域名里。我在联调阶段用HTTPIP地址开发工具里勾选不校验合法域名真机预览时会遇到一个比较隐蔽的问题如果后端是HTTP微信开发者工具预览时虽然能打开但某些真机上会请求失败。所以在真机联调阶段我直接把后端服务配了一个HTTPS证书用Nginx做的SSL反向代理小程序端全部走HTTPS。如果你用的是云服务器现在申请免费SSL证书很方便别在HTTP上浪费时间。如果你在真机上遇到小程序显示客户端SSL握手失败这样的报错首先要检查后端证书链是否完整我遇到过证书只部署了域名证书而没部署中间证书导致握手失败的情况调试了很久才发现问题出在证书链上。5.2 高频报错与解决方案速查开发过程中我整理了高频报错清单这些都是实打实踩过的坑。第一个高频报错是content://com.baidu.searchbox.fileprovider/baiddpath/android/data/com.ba...这类路径解析失败很多同学在小程序里选图片上传时拿到的是一个content://开头的URI不是常规的file:///路径。解决办法是不要直接拿这个URI去File操作要用wx.getFileSystemManager()或者直接传给wx.uploadFile去处理小程序框架会自动处理content://协议。第二个高频报错是微信小程序无法打开公众号文章。这个问题的根源是业务域名配置。小程序内打开公众号文章需要在公众平台配置业务域名而且网页需要下载校验文件放到域名根目录。很多人只配置了request合法域名就以为万事大吉实际上web-view组件和业务域名是两套体系要分别配置。第三个高频问题是微信支付的签名错误。小程序端的支付参数签名和App端完全不同小程序用的是微信支付统一下单接口返回的paySign生成的参数顺序必须严格按照文档拼接否则一直报签名错误。我最后调试通过的办法是先在后端把签名打出来和微信支付官方签名校验工具比对确认无误后再传给前端避免前后端各自生成签名互相甩锅。下面是我整理的一个高频问题速查表方便你联调时直接对照现象大概率原因解决方案wx.request返回failrequest合法域名未配置开发工具勾选不校验域名 / 正式环境配置合法域名wx.login的code换不到openidappid配置错误确认用的是同一个appid检查开发者工具的appid与后台一致支付成功后订单状态还是待支付后端没收到支付回调检查回调地址是否公网可访问配置支付回调白名单Android端图片上传失败Android 11存储权限限制改用应用私有目录或FileProviderSSL握手失败证书链不完整或TLS版本低部署完整证书链升级TLS1.2小程序底部按钮被遮挡缺safe-area适配添加constant()和env()两行样式订单状态乱跳接口未做状态校验服务端增加订单状态机canTransitTo校验5.3 上线前需要检查的细节清单每次项目做完准备提交之前我都会过一遍以下清单确保不会在演示或答辩时掉链子第一数据初始化。数据库里要预置好测试商家、测试菜品、测试分类图片URL要有效。很多同学数据库里菜品图片是空字符串一打开App全是默认图标观感很差。我用本地图片服务存了一批真实的食物图片菜品信息也都填得比较完整演示效果好很多。第二异常兜底。网络异常时App的Toast提示、小程序的wx.showToast提示以及加载中的Loading动画都要有。我见过太多项目一断网就白屏完全没有错误反馈。虽然不是核心功能但直接影响体验感。我在每个网络请求的onError回调里统一弹网络异常请检查网络连接并把错误日志打印到控制台方便定位。第三权限收敛。Android端除了基础的INTERNET权限外没有申请任何冗余权限。小程序端在app.json里只声明了需要的权限模块用不到的不写。这一步看似无关紧要但答辩时老师如果问起你这个App都用了哪些权限、为什么需要你要能清晰说出来。第四状态一致性。我专门写了一个测试脚本模拟用户下单到支付完成的全流程确认订单状态每一步都正确流转。同时测试了边界情况支付超时自动取消、商家取消订单、用户在待支付状态退出重新进入。这些场景都能正常走通后我才认为系统达到了可演示状态。6. 项目复盘与可扩展方向走完整个项目我最大的感受是双端项目真正的成本不在前端而在后端能否做到一次设计多端复用。我一开始没有立刻写代码而是花了很多时间梳理角色、设计接口、定义状态机这些前期投入在后期的联调和测试阶段节省了数倍的时间。如果你正在做类似的系统我强烈建议你也先按这个顺序来。回看整个系统和开发过程有几个点如果让我重新做一遍我会做得更好。第一支付这块我会提前接入微信支付的沙箱环境或使用模拟支付而不是等到最后联调时才去找商户号、AppID配置流程比想象中繁琐。第二我会更早地引入接口自动化测试哪怕只是简单的Postman脚本也能在修改后端逻辑时快速回归验证。第三我会把后台管理端也纳入到整个项目里来统一设计而不是等到双端都做完才开始补管理后台。这个项目后续还可以往几个方向扩展选一个或几个做都能拿到高分一是接入地图服务做基于定位的附近餐厅推荐和外卖配送距离计算二是增加商家端的数据看板用图表统计今日营收、热销菜品排行三是引入WebSocket或轮询让用户订单状态变化能实时推送到客户端而不是每次都手动下拉刷新。这些扩展方向每一个都能单独做成一个亮点也为项目后续的迭代留下空间。最后分享一个小技巧无论你做Android端还是小程序端建议都保留一个开发调试模式开关。在debug模式下App端和小程序端都可以一键切换服务器地址、打印详细请求日志、跳过登录直接进入测试账号。这个开关在开发阶段能省下大量时间在演示阶段还能帮你快速演示不同角色入口。我实际写了两行代码就实现了这个功能但带来的便利是贯穿整个项目周期的。
返回列表