• 基于Java+SpringBoot+Vue+uniapp微信小程序外卖系统设计和实现


    博主介绍全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战

    🍅文末获取源码联系🍅

    👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟

    2022-2024年最全的计算机软件毕业设计选题大全:1000个热门选题推荐✅

    Java项目精品实战案例《100套》

    Java微信小程序项目实战《100套》

    目录

    一、摘要介绍:

    二、主要技术:

    2.1 SpringBoot框架

    2.3 Java技术

    2.3 BS架构

    2.4 微信开发者工具

    三、功能设计:

    3.1 小程序端用户功能结构图设计

    3.2 后端管理员功能结构图设计

    3.3 系统功能设计

    四、功能实现:

    4.1 后端系统

    4.1.1.登录模块

    4.1.2.资讯管理

    4.1.3.商城管理:

    4.1.4.模块管理:

    4.2 微信小程序端

    4.2.1 小程序首页

    4.2.2 菜品信息详情

    4.2.3 购物管理页面

    4.2.4 订单管理页面

    4.2.5 个人中心页面

    五、关键代码:

    六、数据库设计:

    七、论文参考:

    八、其他案例:

    九、源码获取:


     

    一、摘要介绍:

           自从计算机发展开始,计算机软硬件相关技术的发展速度越来越快,在信息化高速发展的今天,计算机应用技术似乎已经应用到了各个领域。在餐饮行业,除了外卖以外就是到店里就餐,在店里就餐如果需要等待点餐的话,用户的体验度就会急剧下降,很多餐饮店也开始开发线上订餐的系统,这样的系统给用户带来了新的体验,尤其是在时间和空间上,让使用者不管身在何处,只要连上网就能够选购菜品,进行订餐。外卖系统小程序的开发项目以Springboot框架为基础,基于B/S模式,采用Java编程语言,使用MySQL数据库,首选对外卖系统小程序的各个功能以及用户的需求做出了解释,然后根据用户线上订餐的需求,再介绍了系统的总体设计以及其详细设计,给用户提供了外卖系统小程序的总体结构的搭建方法。从而满足用户线上订餐的需求。

    二、主要技术:

    2.1 SpringBoot框架

    Spring框架是Java平台上的一种开源应用框架,提供具有控制反转特性的容器。尽管Spring框架自身对编程模型没有限制,但其在Java应用中的频繁使用让它备受青睐,以至于后来让它作为EJB(EnterpriseJavaBeans)模型的补充,甚至是替补。Spring框架为开发提供了一系列的解决方案,比如利用控制反转的核心特性,并通过依赖注入实现控制反转来实现管理对象生命周期容器化,利用面向切面编程进行声明式的事务管理,整合多种持久化技术管理数据访问,提供大量优秀的Web框架方便开发等等。Spring框架具有控制反转(IOC)特性,IOC旨在方便项目维护和测试,它提供了一种通过Java的反射机制对Java对象进行统一的配置和管理的方法。

    2.3 Java技术

    Java是美国sun公司所推出的一款程序设计语言,其能够在多个平台内应用,具有良好兼容性,进而其凭借自身优势在数据中心、个人PC与科技超级计算机等平台内广泛应用,具有目前最为庞大的开发者专业社群[3]。

    JDK为美国sun公司为java开发员所推出的一款全新产品,要是没有JDK的情况下,所安装的java程序也就无法运行[4]。

    2.3 BS架构

    基于Java技术开发的B/S架构系统,需要借助Tomcat服务器应用程序进行部署运行[5]。用户访问系统的时候,通过浏览器向应用程序服务器端发起访问请求,服务器端的程序在接到用户请求以后,服务器端应用程序对客户请求做出相应,在调用服务器端的业务逻辑程序完成和数据库端的交互,进一步生成相应的HTML/XML数据,最终把结果反馈给浏览器端用户[5]。

    在该系统的开发中,开发模式采用B/S架构技术进行实现,通过部署服务器端应用程序,实现用户通过网站域名或者内网IP地址访问系统,实现系统中数据的动态化呈现和管理,加之页面效果的动态化呈现,不仅提升了页面的表现力,而且管理者可以随时更新系统中的各种信息,充分满足管理者和访问用户之间的信息交互[6]。

    2.4 微信开发者工具

    微信开发者工具是一款专为小程序开发而设计的应用,它不断改进,提供了便捷的操作方式,并且在开发过程中可以通过微信扫描二维码来访问,从而实现快速、准确的小程序开发和调试。

    根据用户的需求,我们将采用不同的屏幕大小来制作小程序。

    在完成了视图布置之后,可以通过执行编辑功能,快速更改当前的视图界面。

    控制台:方便调试打印输出信息。

    将代码上传至腾讯服务器,并在审核过程中填写版本号和备注信息,以确保代码的安全性和准确性。

    三、功能设计:

    本外卖系统小程序总体的体系结构图分为前端用户体系结构和后端管理员体系结构,其具体结构图如图4-1和图4-2所示

    3.1 小程序端用户功能结构图设计

     外卖系统小程序前端功能结构图

    3.2 后端管理员功能结构图设计

    图4外卖系统小程序后端功能结构图

    3.3 系统功能设计

    用户管理模块

    该模块是为所有用户登录设计的,如注册用户这种普通用户登录后只能进行自己的普通功能操作(如个人信息修改),管理员能对整个系统的数据进行管理,主要是用户的登录权限以及用户登录后在系统里的操作权限。

    菜品信息模块

    普通用户和菜品信息存在学习关系,关系为一对多,根据菜品信息用户将菜品购买数据传入到订单数据中,操作人为普通用户,然后生成订单列表,普通用户查看个人历史订单列表,可以进行数据销毁。

    美食资讯模块

    普通用户和美食资讯存在学习关系,关系为一对多,根据美食资讯来将评论数据传入到美食资讯数据中,操作人为普通用户,然后生成评论列表,普通用户可以进行数据销毁。

    菜品信息维护模块

    操作人来录入菜品信息数据,点击菜品信息录入按钮,依次填写要录入的菜品信息数据,点击提交按钮,将数据提交至数据库,然后刷新菜品信息数据页面,每条数据右边有删除和编辑按钮,来完成相应的删除和更新功能。

    菜品分类模块

    管理员点击菜品分类管理菜单,点击新增添加菜品分类,添加菜品分类数据,填写标题、内容、类别、图片,提交成功后,菜品分类管理页面刷新,新数据成功载入页面。

    订单管理模块

    订单管理分为用户订单页面和商家订单管理页面,用户登录系统后,选择想要加购的美食,生成订单,商家查询该订单信息,是否生成已支付订单,并对此订单点击发货。

    四、功能实现:

    4.1 后端系统

    4.1.1.登录模块

    4.1.2.资讯管理

    4.1.3.商城管理:

    4.1.4.模块管理:

    4.2 微信小程序端

    4.2.1 小程序首页

    当进入外卖系统小程序的时候,首先映入眼帘的是系统的导航栏,导航栏上边是轮播图以及公告栏,其主界面展示如下图所示

    4.2.2 菜品信息详情

    当访客点击了任意菜品分类后将会进入该款菜品的详情界面,可以了解到该菜品的图片信息、分类信息、价钱信息等,同时可以对该菜品进行加购、评论,菜品详情展示页面如图所示,购买流程图如图所示

    4.2.3 购物管理页面

    当用户点击“购物车”按钮则会显示自己加入购物车的美食信息,然后对其进行购买管理,购物管理界面如下图所示

    4.2.4 订单管理页面

     

    4.2.5 个人中心页面

    五、关键代码:

    1. /**
    2. * 用户账户:用于保存用户登录信息(User)表控制层
    3. */
    4. @Slf4j
    5. @RestController
    6. @RequestMapping("user")
    7. public class UserController extends BaseController {
    8. /**
    9. * 服务对象
    10. */
    11. @Autowired
    12. public UserController(UserService service) {
    13. setService(service);
    14. }
    15. /**
    16. * Token服务
    17. */
    18. @Autowired
    19. private AccessTokenService tokenService;
    20. @Autowired
    21. private UserGroupService userGroupService;
    22. /**
    23. * 注册
    24. * @param user
    25. * @return
    26. */
    27. @PostMapping("register")
    28. public Map signUp(@RequestBody User user) {
    29. // 查询用户
    30. Map query = new HashMap<>();
    31. query.put("username",user.getUsername());
    32. List list = service.select(query, new HashMap<>()).getResultList();
    33. if (list.size()>0){
    34. return error(30000, "用户已存在");
    35. }
    36. user.setUserId(null);
    37. user.setPassword(service.encryption(user.getPassword()));
    38. service.save(user);
    39. return success(1);
    40. }
    41. /**
    42. * 找回密码
    43. * @param form
    44. * @return
    45. */
    46. @PostMapping("forget_password")
    47. public Map forgetPassword(@RequestBody User form,HttpServletRequest request) {
    48. JSONObject ret = new JSONObject();
    49. String username = form.getUsername();
    50. String code = form.getCode();
    51. String password = form.getPassword();
    52. // 判断条件
    53. if(code == null || code.length() == 0){
    54. return error(30000, "验证码不能为空");
    55. }
    56. if(username == null || username.length() == 0){
    57. return error(30000, "用户名不能为空");
    58. }
    59. if(password == null || password.length() == 0){
    60. return error(30000, "密码不能为空");
    61. }
    62. // 查询用户
    63. Map query = new HashMap<>();
    64. query.put("username",username);
    65. Query select = service.select(query, service.readConfig(request));
    66. List list = select.getResultList();
    67. if (list.size() > 0) {
    68. User o = (User) list.get(0);
    69. JSONObject query2 = new JSONObject();
    70. JSONObject form2 = new JSONObject();
    71. // 修改用户密码
    72. query2.put("user_id",o.getUserId());
    73. form2.put("password",service.encryption(password));
    74. service.update(query, service.readConfig(request), form2);
    75. return success(1);
    76. }
    77. return error(70000,"用户不存在");
    78. }
    79. /**
    80. * 登录
    81. * @param data
    82. * @param httpServletRequest
    83. * @return
    84. */
    85. @PostMapping("login")
    86. public Map login(@RequestBody Map data, HttpServletRequest httpServletRequest) {
    87. log.info("[执行登录接口]");
    88. String username = data.get("username");
    89. String email = data.get("email");
    90. String phone = data.get("phone");
    91. String password = data.get("password");
    92. List resultList = null;
    93. Map map = new HashMap<>();
    94. if(username != null && "".equals(username) == false){
    95. map.put("username", username);
    96. resultList = service.select(map, new HashMap<>()).getResultList();
    97. }
    98. else if(email != null && "".equals(email) == false){
    99. map.put("email", email);
    100. resultList = service.select(map, new HashMap<>()).getResultList();
    101. }
    102. else if(phone != null && "".equals(phone) == false){
    103. map.put("phone", phone);
    104. resultList = service.select(map, new HashMap<>()).getResultList();
    105. }else{
    106. return error(30000, "账号或密码不能为空");
    107. }
    108. if (resultList == null || password == null) {
    109. return error(30000, "账号或密码不能为空");
    110. }
    111. //判断是否有这个用户
    112. if (resultList.size()<=0){
    113. return error(30000,"用户不存在");
    114. }
    115. User byUsername = (User) resultList.get(0);
    116. Map groupMap = new HashMap<>();
    117. groupMap.put("name",byUsername.getUserGroup());
    118. List groupList = userGroupService.select(groupMap, new HashMap<>()).getResultList();
    119. if (groupList.size()<1){
    120. return error(30000,"用户组不存在");
    121. }
    122. UserGroup userGroup = (UserGroup) groupList.get(0);
    123. //查询用户审核状态
    124. if (!StringUtils.isEmpty(userGroup.getSourceTable())){
    125. String sql = "select examine_state from "+ userGroup.getSourceTable() +" WHERE user_id = " + byUsername.getUserId();
    126. String res = String.valueOf(service.runCountSql(sql).getSingleResult());
    127. if (res==null){
    128. return error(30000,"用户不存在");
    129. }
    130. if (!res.equals("已通过")){
    131. return error(30000,"该用户审核未通过");
    132. }
    133. }
    134. //查询用户状态
    135. if (byUsername.getState()!=1){
    136. return error(30000,"用户非可用状态,不能登录");
    137. }
    138. String md5password = service.encryption(password);
    139. if (byUsername.getPassword().equals(md5password)) {
    140. // 存储Token到数据库
    141. AccessToken accessToken = new AccessToken();
    142. accessToken.setToken(UUID.randomUUID().toString().replaceAll("-", ""));
    143. accessToken.setUser_id(byUsername.getUserId());
    144. tokenService.save(accessToken);
    145. // 返回用户信息
    146. JSONObject user = JSONObject.parseObject(JSONObject.toJSONString(byUsername));
    147. user.put("token", accessToken.getToken());
    148. JSONObject ret = new JSONObject();
    149. ret.put("obj",user);
    150. return success(ret);
    151. } else {
    152. return error(30000, "账号或密码不正确");
    153. }
    154. }
    155. /**
    156. * 修改密码
    157. * @param data
    158. * @param request
    159. * @return
    160. */
    161. @PostMapping("change_password")
    162. public Map change_password(@RequestBody Map data, HttpServletRequest request){
    163. // 根据Token获取UserId
    164. String token = request.getHeader("x-auth-token");
    165. Integer userId = tokenGetUserId(token);
    166. // 根据UserId和旧密码获取用户
    167. Map query = new HashMap<>();
    168. String o_password = data.get("o_password");
    169. query.put("user_id" ,String.valueOf(userId));
    170. query.put("password" ,service.encryption(o_password));
    171. Query ret = service.count(query, service.readConfig(request));
    172. List list = ret.getResultList();
    173. Object s = list.get(0);
    174. int count = Integer.parseInt(list.get(0).toString());
    175. if(count > 0){
    176. // 修改密码
    177. Map form = new HashMap<>();
    178. form.put("password",service.encryption(data.get("password")));
    179. service.update(query,service.readConfig(request),form);
    180. return success(1);
    181. }
    182. return error(10000,"密码修改失败!");
    183. }
    184. /**
    185. * 登录态
    186. * @param request
    187. * @return
    188. */
    189. @GetMapping("state")
    190. public Map state(HttpServletRequest request) {
    191. JSONObject ret = new JSONObject();
    192. // 获取状态
    193. String token = request.getHeader("x-auth-token");
    194. // 根据登录态获取用户ID
    195. Integer userId = tokenGetUserId(token);
    196. log.info("[返回userId] {}",userId);
    197. if(userId == null || userId == 0){
    198. return error(10000,"用户未登录!");
    199. }
    200. // 根据用户ID获取用户
    201. Map query = new HashMap<>();
    202. query.put("user_id" ,String.valueOf(userId));
    203. // 根据用户ID获取
    204. Query select = service.select(query,service.readConfig(request));
    205. List resultList = select.getResultList();
    206. if (resultList.size() > 0) {
    207. JSONObject user = JSONObject.parseObject(JSONObject.toJSONString(resultList.get(0)));
    208. user.put("token",token);
    209. ret.put("obj",user);
    210. return success(ret);
    211. } else {
    212. return error(10000,"用户未登录!");
    213. }
    214. }
    215. /**
    216. * 登录态
    217. * @param request
    218. * @return
    219. */
    220. @GetMapping("quit")
    221. public Map quit(HttpServletRequest request) {
    222. String token = request.getHeader("x-auth-token");
    223. JSONObject ret = new JSONObject();
    224. Map query = new HashMap<>(16);
    225. query.put("token", token);
    226. try{
    227. tokenService.delete(query,service.readConfig(request));
    228. }catch (Exception e){
    229. e.printStackTrace();
    230. }
    231. return success("退出登录成功!");
    232. }
    233. /**
    234. * 获取登录用户ID
    235. * @param token
    236. * @return
    237. */
    238. public Integer tokenGetUserId(String token) {
    239. log.info("[获取的token] {}",token);
    240. // 根据登录态获取用户ID
    241. if(token == null || "".equals(token)){
    242. return 0;
    243. }
    244. Map query = new HashMap<>(16);
    245. query.put("token", token);
    246. AccessToken byToken = tokenService.findOne(query);
    247. if(byToken == null){
    248. return 0;
    249. }
    250. return byToken.getUser_id();
    251. }
    252. /**
    253. * 重写add
    254. * @return
    255. */
    256. @PostMapping("/add")
    257. @Transactional
    258. public Map add(HttpServletRequest request) throws IOException {
    259. Map map = service.readBody(request.getReader());
    260. map.put("password",service.encryption(String.valueOf(map.get("password"))));
    261. service.insert(map);
    262. return success(1);
    263. }
    264. }

    六、数据库设计:

    下面是整个外卖系统小程序中主要的数据库表总E-R实体关系图。

    外卖系统小程序总E-R关系图 

    七、论文参考:

    本次写作的论文,在结构方面主要分为七大部分,每一部分都必不可少,共同组合形成一个完好的论文结构,具体的安排列出如下。

    绪论部分,该部分讲述的是外卖系统小程序的开发背景,明确开发的意义以及系统的研究动态,并对系统的整个章节安排进行介绍。

    系统分析部分,该部分首先从可行性入手进行分析,明确程序开发可行后,进而对程序的功能以及姓名需求进行分析。

    系统概要设计,对系统前后台的功能分别进行设计,然后完成系统的总体功能以及各个子模块的设计。

    系统数据库的设计,对系统的数据库实体以及数据库表进行设计

    系统的实现部分,对系统每一角色主要实现的功能的页面来进行展示一下。

    系统测试部分,介绍测试的测试目的,用例,完成对程序测试工作,让投入运行的程序减少出错的几率,力求最好。

    总结部分,此刻所有的工作都已经完成了,在此进行总结,展望。

    八、其他案例:

     

     

     

    九、源码获取:

    大家点赞、收藏、关注、评论啦 、查看👇🏻获取联系方式👇🏻

     精彩专栏推荐订阅下方专栏👇🏻

    2022-2024年最全的计算机软件毕业设计选题大全:1000个热门选题推荐✅

    Java项目精品实战案例《100套》

    Java微信小程序项目实战《100套》

  • 相关阅读:
    2023年高教社杯全国大学生数学建模竞赛赛题
    喜马拉雅 Redis 与 Pika 缓存使用军规
    SpringCloud Alibaba【二】nacos
    华为eNSP配置专题-VLAN和DHCP的配置
    惊了,国外顶级架构师编写DDD领域驱动设计总结,看到内容后破防了
    多多表查询优化,逆向思维
    3款自己电脑就可以运行AI LLM的项目
    Tomcat原理剖析-Tomcat整体架构设计
    Centos7 部署 RocketMQ 高可用集群
    毕业工作还没2年,跳到下一个公司就30K了,好家伙···
  • 原文地址:https://blog.csdn.net/weixin_39709134/article/details/131630568