基于微信小程序的家政服务平台的实现 Realization of Housekeeping Service Platform Based on WeChat Mini Program
摘 要
随着中国市场经济的不断发展,人口老龄化的加剧,社会对家庭服务市场的需求越来越大。但是,传统的线下家庭服务往往遇到瓶颈,逐渐跟不上时代的发展趋势,满足不了用户的需求。此外,随着互联网的飞速发展以及越来越多人拥有如手机、平板等移动设备,伴随着微信的快速发展,已经成为现代人不可缺少的社交工具。几乎所有行业都希望接入互联网,形成O2O模式,也就是我们熟知的线上对线下的模式。此外,使用B2B2C模式,即公司对公司、再由公司推到个人,也在发挥巨大的作用。如阿里巴巴、美团等等。利用互联网高效便捷地为用户提供便利,解决国内家政行业面临的瓶颈问题是大势所趋。因此,建立一个透明、公开、平等、高效运行的家政服务平台势在必行。 关键字:微信小程序 网络平台 家政服务 透明化
Abstract
With the continuous development of China's market economy and the aging of the population, the society's demand for the family service market is increasing. However, traditional offline family services often encounter bottlenecks, and gradually fail to keep up with the development trend of the times, and cannot meet the needs of users. With the rapid development of the Internet and more and more people own mobile devices such as mobile phones and tablets. WeChat has become an indispensable social tool for modern people because of the rapid development of the Internet. Almost all industries want to access the Internet to form an O2O model, which is what we know as an online-to-offline model. In addition, the B2B2C model, that is, company-to-company and then company-to-person promotion, has also played a huge role, such as Alibaba Group and so on. It is the general trend to use the Internet to efficiently and conveniently provide convenience to users and solve the bottleneck problems faced by the domestic housekeeping industry. Therefore, to build a transparent, open and efficient homemaking service platform is very imperative.
Key words:Mini Program Platform Housekeeping Transparency
目 录
第一章 绪论 ............................................... 1 1.1 课题背景与意义 ................................................................................... 1 1.2 研究现状 ............................................................................................... 1 1.3 论文研究的主要内容 ........................................................................... 2 第二章 相关开发环境和技术的简介 ............................ 3 2.1 开发环境介绍 ....................................................................................... 3 2.1.1 开发环境 ......................................................................................... 3 2.1.2 开发技术 ......................................................................................... 3 2.1.3 部署环境技术 ................................................................................. 3 2.1.4 系统配置 ......................................................................................... 3 2.2 相关技术介绍 ....................................................................................... 3 2.2.1 Java ................................................................................................... 3 2.2.2 SpringBoot ....................................................................................... 4 2.2.3 MyBatis-Plus .................................................................................... 4 2.2.4 Vue ................................................................................................... 4 2.2.5 微信小程序 ..................................................................................... 4 2.3 本章小结 ............................................................................................... 5 第三章 需求分析 ........................................... 6 3.1 编写目的 ............................................................................................... 6 3.2 总体需求 ............................................................................................... 6 3.3 功能性需求 ........................................................................................... 6 3.4 非功能性需求 ....................................................................................... 8 3.5 本章小结 ............................................................................................... 8 第四章 系统的总体设计 ...................................... 9 4.1 系统边界设计 ....................................................................................... 9 4.2 系统业务流程 ..................................................................................... 10 4.2.1 总体业务流程图 ........................................................................... 10 4.2.2 查看文章流程图 ........................................................................... 11 4.2.3 登录流程图 ................................................................................... 11 4.2.4 支付流程图 ................................................................................... 12 4.3 系统数据流图 ..................................................................................... 13 4.3.1 顶层数据流图 ............................................................................... 13 4.3.2 中层数据流图 ............................................................................... 13
4.3.3 底层数据流图 ............................................................................... 14 4.4 总体软件实现架构描述 ..................................................................... 18 4.4.1 层次结构 ....................................................................................... 18 4.4.2技术架构 ........................................................................................ 19 4.5 系统的开发模式设计 ......................................................................... 19 4.6 总体模块结构 ..................................................................................... 20 4.7 子模块设计 ......................................................................................... 21 4.7.1 系统管理模块 ............................................................................... 21 4.7.2 平台管理模块 ............................................................................... 21 4.7.3 小程序管理模块 ........................................................................... 22 4.7.4 数据模块 ....................................................................................... 22 4.7.5 微信小程序模块 ........................................................................... 23 4.8 数据库的设计 ..................................................................................... 23 4.8.1 地址表 address ............................................................................. 23 4.8.2 文章表 article ............................................................................... 24 4.8.3 文章点赞表 article_appreciate .................................................... 25 4.8.4 分类表 category ........................................................................... 25 4.8.5 优惠券表 coupon ......................................................................... 25 4.8.6 评论表 evaluate ........................................................................... 26 4.8.7 反馈表 feedback .......................................................................... 27 4.8.8 服务表 good ................................................................................. 27 4.8.9 足迹表 good_access .................................................................... 28 4.8.10 收藏表 good_love ...................................................................... 28 4.8.11 轮播图表 rotation ...................................................................... 29 4.8.12 公司&部门表 sys_dept ............................................................. 29 4.8.13 日志表 sys_log .......................................................................... 30 4.8.14 菜单表 sys_menu ....................................................................... 31 4.8.15 角色表 sys_role ......................................................................... 31 4.8.16 角色菜单表 sys_role_menu ...................................................... 32 4.8.17 管理员表 sys_user ..................................................................... 32 4.8.18 用户角色表 sys_user_role ........................................................ 33 4.8.18 用户token表 sys_user_token ................................................... 33 4.8.19 订单表 t_order ........................................................................... 33 4.8.20 用户优惠券表 user_coupon ...................................................... 34
4.8.21 微信用户表 wechat_user .......................................................... 35 4.9 本章小结 ............................................................................................. 35 第五章 系统的详细设计 ..................................... 36 5.1 项目结构 ............................................................................................. 36 5.1.1 目录结构 ....................................................................................... 36 5.2 部件详细设计 ..................................................................................... 39 5.2.1 统一结果返回 ............................................................................... 39 5.2.2 系统日志注解 ............................................................................... 39 5.2.3 自定义异常 ................................................................................... 40 5.2.4 获取请求IP .................................................................................. 41 5.2.5 生成Token .................................................................................... 41 5.2.6 公共实体 ....................................................................................... 41 5.2.7 Shiro权限认证 .............................................................................. 42 5.3 后台管理系统API .............................................................................. 44 5.3.1后台用户管理模块 ........................................................................ 44 5.3.2角色管理模块 ................................................................................ 49 5.3.3菜单管理模块 ................................................................................ 51 5.3.4部门(商家)管理模块 ............................................................... 54 5.3.5日志模块 ........................................................................................ 55 5.3.6文件上传模块 ................................................................................ 55 5.3.7文章管理模块 ................................................................................ 56 5.3.8分类管理模块 ................................................................................ 57 5.3.9优惠券管理模块 ............................................................................ 58 5.3.10服务管理模块 .............................................................................. 60 5.3.11订单管理模块 .............................................................................. 61 5.3.12轮播图管理模块 .......................................................................... 62 5.3.13微信用户管理模块 ...................................................................... 62 5.4 微信小程序端API .............................................................................. 63 5.4.1用户中心 ........................................................................................ 63 5.4.2地址中心 ........................................................................................ 66 5.4.3文章中心 ........................................................................................ 67 5.4.3优惠券中心 .................................................................................... 68 5.4.4评价中心 ........................................................................................ 69 5.4.5服务中心 ........................................................................................ 70
5.4.6首页 ................................................................................................ 73 5.4.7订单中心 ........................................................................................ 73 5.5 Vue后台管理端设计 ........................................................................... 75 5.5.1 主要设计 ....................................................................................... 75 5.6微信小程序页面设计 .......................................................................... 76 5.6.1主要设计 ........................................................................................ 76 5.7 本章小结 ............................................................................................. 76 第六章 系统的展示 ........................................ 77 6.1后台管理平台 ...................................................................................... 77 6.2微信小程序 .......................................................................................... 85 6.3本章小结 .............................................................................................. 92 第七章 系统特色和创新 ..................................... 93 7.1系统特色 .............................................................................................. 93 7.2系统创新 .............................................................................................. 93 第八章 总结 .............................................. 94 参 考 文 献 .............................................. 95 致 谢 ...................................... 错误!未定义书签。
广东东软学院本科毕业设计(论文)
第一章 绪论
1.1 课题背景与意义
由2018年中国老年健康研究报告的研究数据显示,中国人口老龄化问题日益严重。年轻人经常需要上班,甚至加班,因此,家庭的卫生状况以及是否有小孩都将面临无人照料的困境。所以以保姆中介市场为代表的家政服务越来越受到广大家庭的认同。随着中国经济的发展,每座城市生活节奏的飞速提升,家政服务市场的扩张速度十分迅猛,家政服务在每个城市中越来越普遍。伴随着上述的问题,家政服务市场的需求也变得日趋明显。但近几年在家政市场发生的各种事故,如杭州纵火案等,使不少人担心家政企业对自身财产和生命的保障,对家政行业的发展也产生了很大的影响。线下家政服务机构的良莠不齐,给用人单位的选择带来不便。因此,随着互联网的发展,人们越来越迫切地需要一个能够提供透明的企业信息和价格的家政服务平台,以及目标明确的从业者管理机制。
家政服务平台,是将家政公司与雇主两者结合起来的一种方式,雇主可以通过家政服务平台,进行横向的对比,包括选择适合自己的价格、优势、劣势等,物美价廉的家政服务公司,为雇主提供最大的便利,提高雇主的家庭生活质量。其次,优胜劣汰,家政公司还可以通过用户反馈对从业人员实行考评管理,营造一种良好的市场氛围。对互联网来说,是近十年科技发展的产物,几乎家家户户都能上网,每个人都有手机或者手机,随时随地上网已经成了家常便饭。将互联网的便利与家政服务平台相结合,既能方便雇主对家政服务的选择,又能给传统的线下行业带来全新的机遇,从而打开家政服务新的市场。因此,基于互联网的家政服务平台是未来几年甚至几十年的主流发展趋势。
1.2 研究现状
“家政服务人员”这个职业现在已经非常常见了,这个职业最开始是由中国劳动和社会保障部在2000年确定的。家政服务也开始走上了一条“专业化”的发展道路。家政行业的出现,使中国社会家庭幸福程度大大提高。根据统计,家庭佣工的分类主要有“职业保姆”、“涉外保姆”、“高级保姆”、“育儿早管”、“育儿早管”、“幼儿育儿服务”、“家教外教”、“水电维修”、“管道疏通”、“清洁”、“搬家服务”等,各类家政服务正深入社会的每一个家庭。
由中国家庭服务行业在2019年的研究数据表明,目前中国约有3000万家庭需要家政服务,这个数据占到了总调查人数的15%。由此可见,家政行业的社会需求十分的明显,发展前景十分光明。
根据市民的反馈,目前家政市场的乱象也比较明显,如临时加价、退货无果、甚
1
广东东软学院本科毕业设计(论文)
至抢劫、盗窃等。家政市场越来越需要一个合适的解决方案,以约束家政服务行业的服务效果,从而达到双赢的局面。
1.3 论文研究的主要内容
以家政服务为核心的发展理念是本课题的研究目标。这次家政服务平台的设计与实现,将形成一个三方平台,将作为第三方平台进行监管,实时监督家政服务公司的服务内容,并实时接受用户的反馈和建议,一旦发生用户的投诉或不满情况,第三方平台将积极开展调查,如确实发现用户的举报行为,该从业人员将无法在本平台上执行接单,其对应的家政公司也会收到警告,一旦积累到一定的次数,该服务公司也会退出本平台,并发出通知,其他雇主将该公司的情况告知,建立一个透明化的服务平台。
本论文研究的主要内容:
(1)分析线上家政服务平台的现状以及研究的意义,确定研究的目的; (2)研究SpringBoot、Vue、微信小程序开发技术,MVC、前后端分离的设计模式以及MySQL数据库、Redis高速缓存等相关技术;
(3)详细分析家政服务平台的功能需求,并进行具体的需求分析;
(4)研究家政服务平台的总体设计方案,包括总体架构和基于典型三层结构(视图、模型和控制)的设计和使用微信小程序这一最新的开发技术;
(5)对完成的家政服务平台进行测试。在测试中发现其中的问题,不断的解决问题,完善平台的功能;
(6)试发布项目,测试其运行稳定性。
2
广东东软学院本科毕业设计(论文)
第二章 相关开发环境和技术的简介
2.1 开发环境介绍
2.1.1 开发环境
➢ 开发工具:IntelliJ IDEA 2019.2.3 x64、微信开发者工具、Visual Studio Code ➢ 数据库:MySQL 8.0.18
➢ 数据库操作工具:Navicat Premium 12 ➢ 服务器操作工具:Xshell 6
2.1.2 开发技术
➢ SpringBoot-2.1.9.RELEASE ➢ MyBatisPlus-3.2.0 ➢ Vue-Cli3 ➢ MySQL-8.0.18 ➢ Java11 ➢ NodeJs
➢ 微信小程序开发
2.1.3 部署环境技术
➢ Docker ➢ Nginx
2.1.4 系统配置
➢ 开发环境配置:Windows10操作系统,16G内存,硬盘1T+256G,CPU2.6GHz ➢ 部署环境配置:腾讯云服务器(Linux操作系统 1核 2GB 2Mbps)
2.2 相关技术介绍
家政服务平台在设计与开发的工程中,使用了多种技术,包括Java、Vue、SQL等等。本节我将对上述所涉及到的技术做简单的介绍说明。
2.2.1 Java
作为一种广泛使用的语言,Java具有跨平台和面向对象两大特点。他在当前社会中的开发被广泛的运用,是当前十分火爆的开发技术之一。
20世纪90年代初,将网络计算的功能扩展到日常生活是一个激进的设想。1991年, Sun一小部分名为“GreenTeam”的工程师认为,下一步的重点是数字消费设备和计算机的结合。在 JamesGosling的带领下,这个团队日以继夜地工作,最终创造出了一种能彻底改变世界的编程语言Java。Java语言是基于C++语言进行开发的并进行了改进,也继承了面向对象的技术核心,淘汰了部分过时的容易出错的代码。简言之,Java是一款多平台、高效的、面向对象的开发语言。
3
广东东软学院本科毕业设计(论文)
Java11在2018年9月25日发布,是一个长期支持的版本,带来了很多新功能,比如 LocalVar,HttpClient,List API,等等。本次家政服务平台的实现也是基于Java11进行开发的。
2.2.2 SpringBoot
Spring是基于Java平台的应该框架,它是完全开源的,并且拥有控制反转这一重大的功能。同时,Web应用也采用Spring作为Java企业版平台构建的技术支持。目前Spring已经在Java世界中被广泛运用,基本上已经替代了JavaBeans模型。
SpringBoot是Spring家族中的一部分,其使用配置方式的方法,从而搭建Spring运行环境,用配置替代原始Spring的搭建方式,使得用户可以以最小模块的形式进行SpringBoot项目的开发,而完成这件事情也只需要很少的配置文件就可以完成。其主要功能是:
建立独立的Spring应用程式
无需像传统Web项目部署WAR包,可以直接使用自带的Tomcat组件 自动配置Spring所需要的配置文件
为简化Maven配置提供自定义的“入门”项目对象模型(POM) 很方便的提供如指标等生产准备,方便的检查和外部化的配置 几乎不需要代码生成和XML配置
2.2.3 MyBatis-Plus
MyBatis是一款完全适合于Spring开发的工具,其优点是简化了传统JDBC的方式,只要一行SQL语句就可以对数据库进行操作,同时也可以很方便的生成动态的SQL语句。
MyBatis-Plus是由国内开发团队开发的对MyBatis的增强工具,简称为MP。MP对MyBatis没有做出任何的修改,只是在MyBatis的基础上,增加了基本的增删改查的操作、分页、全局拦截插件等等的功能。从而为开发者简化了开发的流程,避免了重复的工作,从而把时间完全留在业务的开发上,提高了开发者的效率。
2.2.4 Vue
Vue跟Spring一样是一个开发框架,区别是Vue是基于JavaScript的。从下到上是Vue的设计特点。其核心只关注与三层结构中的视图层。Vue基于npm的方式可以非常方便的将第三方代码库融合进来。简言之,Vue是一款十分高效的单页面应用工具引擎。
2.2.5 微信小程序
微信小程序是由腾讯公司设计开发的一种全新的连接用户与服务的方式,其用户量十分庞大,绝大多数中国人已经开始使用微信,而且越来越多外国人也开始接触并使用微信。而微信小程序可以以视作在另外一个操作系统上运行的移动端软件,
4
广东东软学院本科毕业设计(论文)
为用户提供了轻量化的程序,用户无需下载软件就可以体验到传统APP上才有的功能。微信小程序的开发者可以利用微信官方提供应用开发框架和丰富的组件和 API服务,开发具有原生 APP体验。
2.3 本章小结
本章主要介绍了本次在家政服务平台的开发编码过程中所使用到框架和技术,在系统构建的过程中对所需要使用的技术理论基础进行了充分的研究和分析,为接下来的开发打下坚实的基础,也为我们的系统进一步的开发做了技术上的阐述。
5
广东东软学院本科毕业设计(论文)
第三章 需求分析
3.1 编写目的
家政服务平台的需求分析主要是提出系统应该具备的功能模块,以及我们期望达到的目标。通过对用户需求的理解,需求分析确定了家政服务平台的功能和非功能需求。功能需求指的是系统的主要功能和完成的目的。而提供除了业务之外的功能就是非功能需求了。除此之外,包括其他与功能需求无关的需求则是针对系统的质量特性进行描述的。它包含了相关的标准,需要对系统的质量特性进行描述,包括一些性能要求、安全要求、可维护性要求和其他要求。系统开发的重要内容是系统相关需求分析,是进行系统设计和开发的基础。也为系统后期测试提供了重要依据和基础,因此,系统后期维护的说明文档就是需求分析的目的所在。
3.2 总体需求
经相关调查得知,传统的家政服务平台是雇主前往线下家政服务机构,询问价格后机构会派遣工作人员上门服务,而雇主往往对工作人员的具体情况和服务态度一无所知,因此雇主也只能“踩着石头过河”,有时还会因为这种情况导致最终获得的服务效果不佳,有时甚至导致家庭财物失窃,亲人生命安全受到威胁等严重情况发生。而且,雇主需要花一定的时间到线下找家政机构了解服务情况和价格,即使是比较多家机构,往往也会浪费雇主的时间。
综合以上情况,本次设计的家政服务平台的总体需求是提高用户选择家政服务的时间效率,对比家政服务的价格,对家政服务进行监控,节省雇主的宝贵时间,降低服务过程中的危险因素,保证服务质量,利用互联网的优势将家政服务态度和价格透明化公开,给用户带来最大的便利,并带来高质量的选择。
3.3 功能性需求
根据调查得到家政服务平台的具体需求,具体情况如下: 前台(微信小程序端):
1) 用户注册登录,用户通过微信授权,发起登录,并输入其手机号码,用户信息将在后台保存,然后完成登录。登录成功后,即可进行预约服务等操作。
2) 用户对家政服务功能的需求查询:用户可以通过不同的分类,查询相应的家政服务,在家政服务中查询相应的机构信息、评价、价格等,服务筛选也可以通过距离、地点等信息进行。对所感兴趣的服务还可以进行收集,方便查询。
3) 用户对家政预约的需求:用户查询了家政服务后,如果需要的话,用户可以通过小程序端进行下单预约,选择了预约联系人和联系方式后,家政公司就会有专人电联用户,确定具体上门时间和注意事项。
6
广东东软学院本科毕业设计(论文)
4) 用户完成订单并做出评价的需要:家政公司服务完成后,用户可以通过微信小程序对家政公司的服务成果、态度、员工等进行评价,并将评分计入家政公司的评分中,在服务细节中公开展示,方便其他用户进行查询。
5) 用户学习家庭生活提示的需求:用户可以通过机构或平台发布的文章,学习一些家庭清洁的小技巧,更好的学习家庭生活服务。
6) 用户获得优惠的需求:用户可获得优惠券,在下单时减免部分金额,提供部分优惠。
后台(Web管理端):
1) 管理员登录功能:管理员通过输入用户名、密码、验证码后,后端进行校验,验证通过即可进入管理端,不同的管理员将会拥有不同的权限,从而可以操作不同的功能。
2) 家政公司管理功能:平台方可对家政公司进行管理,包括新公司入驻、违规公司封禁等,通过审核公司即可进行操作,在平台发布服务等。家政公司可以在这一职能下增加自己的内部组织,对自己的内部组织进行管理。
3) 管理员管理功能:平台方可以通过此功能管理系统管理员,也可以管理家政公司的人员,一旦出现违规情况,将给予封杀并取消该员工的工作资格。家政公司方可以执行诸如员工的添加和删除等操作。
4) 订单查询管理功能:家政公司可以在此对相应的订单进行查询,并在此对客户进行联系、服务评估等操作。平台方可跟踪订单情况,保证家政服务公司的服务质量。
5) 服务管理功能:家政服务公司可以在这里发布服务或下架服务。通过这一功能,平台方监控家政公司发布的服务是否符合平台运行规则,并及时发现异常并进行处理。
6) 分类管理功能:平台方可以通过此功能对微信小程序进行分类管理。 7) 文章管理功能:平台方和部分家政公司可以使用此功能发布文章,提供家居清洁等有效指南。
8) 小程序用户管理:平台可通过此功能查询已注册用户列表,如有用户恶意操作或违法行为发生,平台可及时进行处理,确保平台正常运行。
9) 系统管理功能:平台可以对管理系统的权限、菜单等进行管理,从而可以对整个家庭服务平台进行灵活的管理。
10) 11)
优惠券管理:平台方可以管理优惠券的发布,提供一部分优惠活动。 数据展示功能:提供平台数据的展示,方便地了解每日的运行情况。
7
广东东软学院本科毕业设计(论文)
3.4 非功能性需求
非功能需求是业务之外的需求,非业务需求也决定用户的使用体验、包括了系统总体的稳定性。下面列出了一些更重要的非功能性需求。
1.界面美观需求
这一需求主要描述了对系统外观的期望,要求系统实现符合规范的外观。家政服务平台应具备简洁、庄重、简约、精致的界面,给人一种专业而又不失精致的体验,也要充分符合家政服务的气氛。对于后台管理来说就需要有专业的感觉了。可参考其他管理学上的设计风格。
2.易操作性需求
易操作性将使系统的使用变得更加简单,对于家政服务经理来说,可以实现“一见钟情”地使用本系统。与花大量时间和精力熟悉系统操作相比,让家政公司管理人员快速掌握操作系统更好。对于微信小程序用户来说,小程序需要清楚地显示服务、订单、个人信息等内容,以方便用户选择和比较。
3.安全性需求
安全性是家政服务平台的关键,系统必须具有消除潜在风险的能力,并对风险有一定的承压能力。家政服务平台不仅要保证微信小程序端用户资料的安全性,还要保证后台管理模块家政机构信息和从业人员信息的安全性,防止造成安全事故的发生。
3.5 本章小结
系统开发过程中的需求分析尤为重要,对用户的需求要有全面的了解,对用户存在的问题要有透彻的理解。本章主要介绍了家政服务平台的一些基本情况,这一点在本系统的设计中占有重要地位,本章将为后面的家政服务平台的详细设计提供完整的文档支持。
8
广东东软学院本科毕业设计(论文)
第四章 系统的总体设计
4.1 系统边界设计
菜单管理<<包含>>角色管理机构管理管理员管理日志管理公司管理<<包含>>系统管理<<包含>><<包含>><<包含>><<包含>>公司管理员订单管理<<包含>>服务模块平台管理<<包含>><<包含>><<包含>>文章管理服务管理公司员工订单模块收藏模块优惠券管理优惠券模块微信用户管理<<包含>>系统管理员小程序管理<<包含>>足迹模块轮播图管理分类管理分类模块<<包含>>普通用户文章模块平台数据管理<<包含>>首页数据个人信息模块 图 1系统边界设计图
家政服务平台的总体边界设计如图1所示,整个家政服务平台分成后台管理平台和前台微信小程序平台两部分,作为第三方,系统管理员拥有整个平台的功能权限,公司管理员作为商户方进入平台,会赋予一部分的系统管理权限和平台管理权限,其公司内部的员工则拥有查看服务和订单的权限,可以对公司的订单业务进行精细化处理。用户则使用微信小程序端进行下单、评价等操作。
9
广东东软学院本科毕业设计(论文)
4.2 系统业务流程
4.2.1 总体业务流程图
开始生活小帮手订单中心生成订单选择分类是否有优惠券是选择优惠券否选择服务收藏服务支付流程超时结束文案提示成功立即预定支付状态失败是否登录否登录流程商家派单是检查订单参数是否填写完整是检查是否有已有地址是服务人员上门完成服务否否参数填写订单状态修改否添加地址服务已完成是选择地址订单完成商家买家互评提交订单结束文案提示 图 2系统总体业务流程图
10
广东东软学院本科毕业设计(论文)
4.2.2 查看文章流程图
开始选择文章查看文章点赞/评论结束 图 3系统文章业务流程图
4.2.3 登录流程图
开始后台管理登录平台小程序输入用户名、密码、验证码否授权获取用户信息输入是否符合规范是结束文案提示结束文案提示是否授权否否用户名和密码是否正确是是生成token并返回结束 图 4系统登录业务流程图
11
广东东软学院本科毕业设计(论文)
4.2.4 支付流程图
开始用户发起支付生成付款订单并支付超时结束文案提示支付状态失败成功记录支付数据修改订单状态结束
图 5系统支付业务流程图
12
广东东软学院本科毕业设计(论文)
4.3 系统数据流图
4.3.1 顶层数据流图
管理员登录请求信息管理与维护游客登录信息、文章预约服务家政服务平台用户、商户、订单、数据服务信息、订单信息、商家信息、员工信息会员文章、服务、优惠券、订单订单、数据商家 图 6系统顶层数据流图
4.3.2 中层数据流图
审核意见用户信息游客用户信息用户注册登录用户信息记录查询条件管理员优惠券信息优惠券信息记录文章信息记录文章管理优惠券信息优惠券管理审核意见文章信息优惠券领取商家信息商家信息查询查询条件查看文章领取条件订单信息记录预约服务商家入驻信息记录商家入驻查询条件订单信息预约信息订单信息订单信息记录订单管理入驻信息会员订单查询查询条件服务信息服务信息记录查询条件商家查询条件服务查询服务管理服务信息
图 7系统中层数据流图
13
广东东软学院本科毕业设计(论文)
4.3.3 底层数据流图
(1)底层用户登录数据流图
通过验证用户信息登录登录时间、IP验证生成token用户用户用户信息注册用户信息 图 8系统底层用户登录数据流图
(2)底层文章数据流图
用户信息管理员文章信息登录流程文章信息添加文章文章信息文章信息记录按关键字查询关键字文章信息用户查询条件分析查询日期文章信息查询显示按日期查询文章信息记录用户 图 9系统底层文章数据流图
14
广东东软学院本科毕业设计(论文)
(3)底层服务数据流图
商家用户信息登录系统服务信息用户信息记录服务管理服务信息文章信息记录文章信息记录关键字按关键字查询服务信息服务信息查询显示用户用户查询条件分析查询分类按分类查询商家按商家查询服务信息 图 10系统底层服务查询数据流图
(4)底层订单查询数据流图 用户信息记录用户登录系统查询条件订单信息记录订单信息记录分析查询订单日期按订单日期查询订单信息订单信息查询显示用户订单号按订单号查询预约人按预约人查询订单信息 图 11系统底层订单查询数据流图
15
广东东软学院本科毕业设计(论文)
(5)底层预约服务数据流图
用户用户信息登录用户信息记录选择服务服务信息记录订单提交订单订单记录显示订单订单用户 图 12系统底层预约服务数据流图
(6)底层商家数据流图
商家商家信息申请入驻商家信息审核商家商家信息管理员用户信息登录管理员信息记录 图 13系统底层商家信息数据流图 16
广东东软学院本科毕业设计(论文)
(7)底层优惠券数据流图 用户领取优惠券优惠券信息添加优惠券优惠券信息管理员用户信息登录管理员信息记录 图 14系统底层优惠券数据流图
17
广东东软学院本科毕业设计(论文)
4.4 总体软件实现架构描述
4.4.1 层次结构
Database数据库(MySQL)中间件(Redis)DAL数据访问层(Dao层)业务逻辑层(Service层)BLL视图控制层(Controller层)UI系统管理平台管理小程序管理平台数据管理数据安全管理管理平台小程序平台 图 15 层次结构图
家政平台的软件层次结构如图15所示,用户通过操控UI界面的内容进行系统的管理和小程序的操作,用户点击某一个按钮后,前端请求api接口,api接口调用后端的Controller层是视图控制层,其通过直接调用Service层(业务逻辑层)对业务进行处理,处理过程中如果需要调用到数据,则需要调用Dao层(数据访问层)对数据进行查询。最后通过原路径将数据返回到视图层,视图层将数据封装成Json格式返回到前端,前端则根据后端返回的接口进行页面的渲染,完成整个的数据交互。
18
广东东软学院本科毕业设计(论文) 4.4.2技术架构 客户端数据处理框架(SpringBoot+Mybatis)数据库表现层业务层持久层MySQL小程序调用Api接口SpringMVC管理页面无状态的会话服务器定位Spring事务处理调用第三方接口数据访问对象Hikari连接池持久化数据访问SpringBoot快速搭建业务服务类Mybatis相关Dao类XML配置文件Redis 图 16技术架构图
家政平台的技术架构如图16所示,主要采用的是前后端分离模式进行设计,前端使用目前比较流行的Vue框架和微信小程序框架进行设计;后端使用目前比较流行和稳定的SpringBoot和MyBatis框架进行设计,数据库分别使用了传统数据库MySQL和高性能缓冲数据库Redis。这样一来,整个系统前后端分离,可以提高整体运行的性能,也可以方便的进行修改,是当前比较流行的软件框架。
4.5 系统的开发模式设计
本平台的实现主要采用瀑布模式,瀑布模式是家政服务平台实现的开发模式,其核心思想是按工序完成问题,把功能的实现和设计分离开,使用结构化分析的方法,完成软件的开发,并遵循软件生命周期自上而下、相互衔接的顺序。
19
广东东软学院本科毕业设计(论文) 4.6 总体模块结构 家政服务平台后台管理系统系平统平小程台管台序数理管理管据理查询
微信小程序分个类服订人优模务单文章信惠块模块模块模块息券模模块块 17总体模块结构图 20
图
广东东软学院本科毕业设计(论文) 4.7 子模块设计 家政平台的模块主要由后台系统模块、后台平台模块、后台小程序模块、后台数据模块和微信小程序模块5个模块组成。 4.7.1 系统管理模块 系统管理菜单管理日志管理公司管理管理员管理角色管理 图 18系统管理模块示意图 4.7.2 平台管理模块 平台管理服务管理订单管理分类管理 图 19平台管理模块示意图
21
广东东软学院本科毕业设计(论文) 4.7.3 小程序管理模块 小程序管理轮播图管理文章管理微信用户管理优惠券管理 图 20小程序管理模块示意图 4.7.4 数据模块 数据模块用户数据订单数据服务数据流量数据 图 21数据模块示意图
22
广东东软学院本科毕业设计(论文) 4.7.5 微信小程序模块 小程序文章中心分类中心服务中心订单中心用户中心 图 22小程序模块示意图 4.8 数据库的设计
4.8.1 地址表 address
索引 名 index_address 字段 Id 索引类型 索引方法 注释 NORMAL BTREE 字段 列名 id mobile name province area city detail is_default create_by last_modified_by gmt_create 名称 id 手机号 联系人 省份 地区 城市 详情 是否默认 创建人 修改人 创建时间 数据类型 varchar(32) varchar(11) varchar(32) varchar(10) varchar(10) varchar(10) varchar(10) tinyint(1) varchar(32) varchar(32) datetime 23
字段类型 varchar varchar varchar varchar varchar varchar varchar tinyint varchar varchar datetime 长度 32 11 32 10 10 10 10 32 32 是否为空 NO YES YES YES YES YES YES NO NO YES NO 描述 广东东软学院本科毕业设计(论文)
gmt_modified is_deleted sort_no version 修改时间 是否删除 排序 版本号 datetime tinyint(1) int(11) int(11) datetime tinyint int int YES NO NO NO 4.8.2 文章表 article
索引 名 index_article 字段 Id 索引类型 索引方法 注释 NORMAL BTREE 字段 列名 id title author author_avatar_uri comment_disabled content content_short image_uri importance source_uri appreciate attention forward status create_by last_modified_by gmt_create gmt_modified is_deleted sort_no version 名称 id 标题 作者 作者头像uri 数据类型 varchar(32) varchar(255) varchar(64) varchar(255) 字段类型 varchar varchar varchar varchar tinyint varchar varchar varchar smallint varchar smallint smallint smallint smallint varchar varchar datetime datetime tinyint int int 长度 是否为空 32 255 64 255 NO YES YES YES YES 描述 是否可以评论 tinyint(1) 内容 描述 图片uri 重要程度 源地址 点赞数 点击数 转发数 状态 创建人 修改人 创建时间 修改时间 是否删除 排序 版本号 varchar(1024) varchar(255) varchar(255) smallint(6) varchar(255) smallint(255) smallint(255) smallint(255) smallint(6) varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) 1024 YES 255 255 255 32 32 YES YES YES YES YES YES YES YES NO YES NO YES NO NO NO
24
广东东软学院本科毕业设计(论文)
4.8.3 文章点赞表 article_appreciate
索引 名 idx_article idx_user 字段 article_id user_id 索引类型 索引方法 注释 NORMAL BTREE NORMAL BTREE 字段 列名 article_id user_id 名称 文章id 用户id 数据类型 varchar(32) varchar(32) 字段类型 长度 varchar varchar 32 32 是否为空 NO NO 描述 4.8.4 分类表 category
索引 名 idx_ category 字段 id 索引类型 索引方法 注释 NORMAL BTREE 字段 列名 id color icon name create_by last_modified_by gmt_create gmt_modified is_deleted sort_no version 名称 id 颜色 图标 名称 创建人 修改人 创建时间 修改时间 是否删除 排序 版本号 数据类型 varchar(32) varchar(32) varchar(255) varchar(64) varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) 字段类型 varchar varchar varchar varchar varchar varchar datetime datetime tinyint int int 长度 32 32 255 64 32 32 是否为空 描述 NO YES YES YES NO YES NO YES NO NO NO 4.8.5 优惠券表 coupon
索引
名 idx_ coupon 字段 id 索引类型 索引方法 注释 NORMAL BTREE
25
广东东软学院本科毕业设计(论文)
字段 列名 id color detail discount_value name 名称 id 颜色 详情 优惠价格 优惠券名称 unit use_limit_type_name validity create_by last_modified_by gmt_create gmt_modified is_deleted sort_no version 单位 使用限制 使用时间 创建人 修改人 创建时间 修改时间 是否删除 排序 版本号 varchar(32) varchar(32) datetime varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) varchar varchar datetime varchar varchar datetime datetime tinyint int int 32 32 32 32 YES YES YES NO YES NO YES NO NO NO 数据类型 varchar(32) varchar(256) varchar(256) decimal(10,2) varchar(64) 字段类型 varchar varchar varchar decimal varchar 长度 32 256 256 64 是否为空 NO YES YES YES YES 描述 4.8.6 评论表 evaluate
索引 名 idx_evaluate idx_good_id idx_order_id 字段 id good_id order_id 索引类型 索引方法 注释 NORMAL BTREE NORMAL BTREE NORMAL BTREE 字段 列名 id dept_point detail environment_point good_id order_id worker_point 名称 id 公司评分 详情 环境评分 服务id 订单id 员工评分 数据类型 varchar(32) smallint(6) 字段类型 varchar smallint 长度 32 1024 32 32 是否为空 NO YES YES YES YES YES YES 描述 varchar(1024) varchar smallint(6) varchar(32) varchar(32) smallint(6) smallint varchar varchar smallint 26
广东东软学院本科毕业设计(论文)
create_by last_modified_by gmt_create gmt_modified is_deleted sort_no version 创建人 修改人 创建时间 修改时间 是否删除 排序 版本号 varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) varchar varchar datetime datetime tinyint int int 32 32 NO YES NO YES NO NO NO 4.8.7 反馈表 feedback
索引 名 idx_feedback idx_order_id 字段 id order_id 索引类型 索引方法 注释 NORMAL BTREE NORMAL BTREE 字段 列名 id achievement feedback notice order_id create_by 名称 id 完成情况 备注 通知 订单id 创建人 数据类型 varchar(32) tinyint(4) 字段类型 varchar tinyint 长度 32 255 255 32 32 32 是否为空 NO YES YES YES NO NO YES NO YES NO NO NO 描述 varchar(255) varchar varchar(255) varchar varchar(32) varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) varchar varchar varchar datetime datetime tinyint int int last_modified_by 修改人 gmt_create gmt_modified is_deleted sort_no version 创建时间 修改时间 是否删除 排序 版本号 4.8.8 服务表 good
索引 名 idx_good 字段 id 索引类型 索引方法 注释 NORMAL BTREE idx_category_id category_id NORMAL BTREE idx_dept_id dept_id NORMAL BTREE
27
广东东软学院本科毕业设计(论文)
字段 列名 id category_id dept_id detail image_uri name price unit create_by last_modified_by gmt_create gmt_modified is_deleted sort_no version 名称 id 分类id 公司id 详情 图片连接 服务名 价格 单位 创建人 修改人 创建时间 修改时间 是否删除 排序 版本号 数据类型 varchar(32) varchar(32) varchar(32) varchar(1024) varchar(255) varchar(64) decimal(5,1) varchar(32) varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) 字段类型 长度 varchar varchar varchar varchar varchar varchar decimal varchar varchar varchar datetime datetime tinyint int int 32 32 32 1024 255 64 32 32 32 是否为空 NO YES YES YES YES YES YES YES NO YES NO YES NO NO NO 描述 4.8.9 足迹表 good_access
索引 名 idx_good_id idx_user_id 字段 good_id user_id 索引类型 索引方法 注释 NORMAL BTREE NORMAL BTREE 字段 列名 good_id user_id 名称 服务id 用户id 数据类型 varchar(32) varchar(32) 字段类型 长度 varchar varchar 32 32 是否为空 NO NO 描述 4.8.10 收藏表 good_love
索引 名 idx_good_id idx_user_id 字段 good_id user_id 索引类型 索引方法 注释 NORMAL BTREE NORMAL BTREE
28
广东东软学院本科毕业设计(论文)
字段 列名 good_id user_id 名称 服务id 用户id 数据类型 varchar(32) varchar(32) 字段类型 长度 varchar varchar 32 32 是否为空 NO NO 描述 4.8.11 轮播图表 rotation
索引 名 idx_rotation_id 字段 id 索引类型 索引方法 注释 NORMAL BTREE 字段 列名 id url create_by 名称 id 图片url 创建人 数据类型 varchar(32) 字段类型 varchar 长度 32 255 32 32 是否为空 NO YES NO YES NO YES NO NO NO 描述 varchar(255) varchar varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) varchar varchar datetime datetime tinyint int int last_modified_by 修改人 gmt_create gmt_modified is_deleted sort_no version 创建时间 修改时间 是否删除 排序 版本号 4.8.12 公司&部门表 sys_dept
索引 名 idx_dept 字段 id 索引类型 索引方法 注释 NORMAL BTREE 字段 列名 id address avatar lat lng name parent_id legal 名称 id 地址 头像url 纬度 经度 部门名称 父id 企业法人 数据类型 varchar(32) 字段类型 长度 varchar 32 255 255 50 32 50 是否为空 NO YES YES YES YES YES NO YES 描述 地址计算的纬度 地址计算经度 一级部门为0 varchar(255) varchar varchar(255) varchar decimal(7,4) decimal decimal(7,4) decimal varchar(50) varchar(32) varchar(50) varchar varchar varchar 29
广东东软学院本科毕业设计(论文)
email tel license create_by 邮箱 联系电话 营业执照 创建人 varchar(50) varchar(20) varchar varchar 50 50 255 32 32 YES YES YES NO YES NO YES NO NO NO varchar(255) varchar varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) varchar varchar datetime datetime tinyint int int last_modified_by 修改人 gmt_create gmt_modified is_deleted sort_no version 创建时间 修改时间 是否删除 排序 版本号 4.8.13 日志表 sys_log
索引
名 Idx_log 字段 id 索引类型 索引方法 注释 NORMAL BTREE 字段 列名 id ip method operation params time username create_by 名称 id IP地址 请求方法 用户操作 请求参数 执行时长 用户名 创建人 数据类型 varchar(32) varchar(64) varchar(200) varchar(50) 字段类型 varchar varchar varchar varchar 长度 32 64 200 50 5000 50 32 32 是否为空 描述 NO YES YES YES YES YES YES NO YES NO YES NO NO NO 毫秒 varchar(5000) varchar bigint(20) varchar(50) varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) bigint varchar varchar varchar datetime datetime tinyint int int last_modified_by 修改人 gmt_create gmt_modified is_deleted sort_no version 创建时间 修改时间 是否删除 排序 版本号
30
广东东软学院本科毕业设计(论文)
4.8.14 菜单表 sys_menu
索引 名 字段 索引类型 索引方法 注释 NORMAL BTREE idx_sys_menu_id id 字段 列名 id component hidden icon name parent_id path perms redirect create_by last_modified_by gmt_create gmt_modified is_deleted sort_no version 名称 id 组件 是否隐藏 图标 名称 父菜单ID 路径 授权 重定向地址 创建人 修改人 创建时间 修改时间 是否删除 排序 版本号 数据类型 varchar(32) varchar(256) tinyint(1) varchar(32) varchar(32) varchar(32) varchar(255) varchar(500) varchar(255) varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) 字段类型 长度 varchar varchar tinyint varchar varchar varchar varchar varchar varchar varchar varchar datetime datetime tinyint int int 32 256 32 32 32 255 500 255 32 32 是否为空 描述 NO YES YES YES YES YES YES YES YES NO YES NO YES NO NO NO 0否,1是 一级菜单为null 多个用逗号分隔 4.8.15 角色表 sys_role
索引 名 idx_sys_role_id 字段 id 索引类型 索引方法 注释 NORMAL BTREE 字段 列名 名称 数据类型 字段类型 id dept_id remark role_name id 公司id 备注 角色名称 varchar(32) varchar(32) varchar varchar 32 32 256 32 长度 是否为空 NO YES YES YES 描述 varchar(256) varchar varchar(32) varchar 31
广东东软学院本科毕业设计(论文)
create_by 创建人 varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) varchar varchar datetime datetime tinyint int int 32 32 NO YES NO YES NO NO NO last_modified_by 修改人 gmt_create gmt_modified is_deleted sort_no version 创建时间 修改时间 是否删除 排序 版本号 4.8.16 角色菜单表 sys_role_menu
索引 名 idx_menu_id idx_role_id 字段 索引类型 索引方法 注释 menu_id NORMAL BTREE role_id NORMAL BTREE 字段 列名 menu_id role_id 名称 菜单id 角色id 数据类型 varchar(32) varchar(32) 字段类型 长度 varchar varchar 32 32 是否为空 NO NO 描述 4.8.17 管理员表 sys_user
索引 名 idx_sys_user_id idx_username idx_dept_id 字段 id 索引类型 索引方法 注释 NORMAL BTREE username NORMAL BTREE dept_id NORMAL BTREE 字段 列名 id avatar dept_id email gmt_login last_login_ip mobile password username 名称 id 头像 公司id 邮箱 上次登录时间 上次登录ip 联系电话 密码 用户名 数据类型 varchar(32) 字段类型 varchar 长度 32 100 32 32 32 16 64 32 是否为空 NO YES YES YES YES YES YES YES NO 描述 varchar(100) varchar varchar(32) varchar(32) datetime varchar(32) varchar(16) varchar(64) varchar(32) varchar varchar datetime varchar varchar varchar varchar 32
广东东软学院本科毕业设计(论文)
create_by 创建人 varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) varchar varchar datetime datetime tinyint int int 32 32 NO YES NO YES NO NO NO last_modified_by 修改人 gmt_create gmt_modified is_deleted sort_no version 创建时间 修改时间 是否删除 排序 版本号 4.8.18 用户角色表 sys_user_role
索引 名 idx_user_id idx_role_id 字段 user_id role_id 索引类型 索引方法 注释 NORMAL BTREE NORMAL BTREE 字段 列名 user_id role_id 名称 用户id 角色id 数据类型 varchar(32) varchar(32) 字段类型 长度 varchar varchar 32 32 是否为空 NO NO 描述 4.8.18 用户token表 sys_user_token
索引 名 idx_token idx_user_id 字段 Token user_id 索引类型 索引方法 注释 UNIQUE BTREE NORMAL BTREE 字段 列名 expire_time token update_time user_id 名称 过期时间 token 更新时间 用户id 数据类型 datetime varchar(100) datetime varchar(100) 字段类型 长度 datetime varchar datetime varchar 100 100 是否为空 YES NO YES NO 描述 4.8.19 订单表 t_order
索引 名 idx_order idx_dept_id 字段 id dept_id 索引类型 索引方法 注释 NORMAL BTREE NORMAL BTREE
33
广东东软学院本科毕业设计(论文)
字段 列名 id address contact dept_id discount_price gmt_pay good_id image_uri is_comment mobile name payment price remark status create_by 名称 id 地址 联系人 公司id 优惠价格 支付时间 服务id 服务图片 是否评论 联系电话 联系人 支付方式 价格 备注 状态 创建人 数据类型 varchar(32) varchar(32) varchar(32) varchar(32) decimal(5,1) datetime varchar(32) varchar(255) tinyint(1) varchar(11) varchar(128) tinyint(4) decimal(5,1) 字段类型 varchar varchar varchar varchar decimal datetime varchar varchar tinyint varchar varchar tinyint decimal 长度 32 32 32 32 32 255 11 128 1024 32 32 是否为空 NO YES YES YES YES YES YES YES YES YES YES YES YES YES YES NO YES NO YES NO NO NO 描述 1是0否 varchar(1024) varchar tinyint(4) varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) tinyint varchar varchar datetime datetime tinyint int int last_modified_by 修改人 gmt_create gmt_modified is_deleted sort_no version 创建时间 修改时间 是否删除 排序 版本号 4.8.20 用户优惠券表 user_coupon
索引 名 idx_user_id 字段 userid 索引类型 索引方法 注释 NORMAL BTREE 字段 列名 名称 数据类型 字段类型 长度 32 32 是否为空 NO YES YES 描述 coupon_id 优惠券id order_id use_time 订单id 使用时间 varchar(32) varchar varchar(32) varchar datetime datetime 34
广东东软学院本科毕业设计(论文)
user_id 用户id varchar(32) varchar 32 NO 4.8.21 微信用户表 wechat_user
索引 名 idx_wechat_user_id 字段 id 索引类型 索引方法 注释 NORMAL BTREE idx_wechat_user_openid openid NORMAL BTREE 字段 列名 id avatar_url city country gender gmt_login language last_login_ip mobile nickname openid province session_key unionid create_by 名称 id 头像url 国家 城市 性别 上次登录时间 语言 上次登录ip 手机号 昵称 openid 省份 session_key unionid 创建人 数据类型 varchar(32) 字段类型 varchar 长度 32 255 32 32 32 32 11 32 32 32 32 32 32 32 是否为空 NO YES YES YES YES YES YES YES YES YES YES YES YES YES NO YES NO YES NO NO NO 描述 0未知1男2女 varchar(255) varchar varchar(32) varchar(32) tinyint(4) datetime varchar(32) varchar(32) varchar(11) varchar(32) varchar(32) varchar(32) varchar(32) varchar(32) varchar(32) varchar(32) datetime datetime tinyint(1) int(11) int(11) varchar varchar tinyint datetime varchar varchar varchar varchar varchar varchar varchar varchar varchar varchar datetime datetime tinyint int int last_modified_by 修改人 gmt_create gmt_modified is_deleted sort_no version 创建时间 修改时间 是否删除 排序 版本号 4.9 本章小结
本章主要是说明家政服务平台的总体设计,对系统进行总体模块进行划分,大概描述系统开发的总体内容情况,为接下来详细设计奠定基础。
35
广东东软学院本科毕业设计(论文)
第五章 系统的详细设计
5.1 项目结构
5.1.1 目录结构
图 23后端目录结构
项目使用了Maven进行托管,采用父子包的形式进行搭建,最外层的pom.xml对项目引用的jar包版本进行管理,common包是基本工具类,entity包是实体类,dao包是数据访问层的类,service包是业务处理类,web-api是后台管理系统的前端控制器类,wx-api是微信小程序的前端控制器类。
common模块
图 24commom结构
common包中,annotaion是注解的配置类,exception是存放自定义异常的处理类的包,utils是存放工具类的包,xss是存放防攻击类的包,Constant是一些常量类。
36
广东东软学院本科毕业设计(论文)
web-api模块
图 25web-api结构
web-api模块中,aspect是存放切面类的包,config是存放配置类的包,controller是存放前端控制器类的包,oauth2是存放shiro登录类的包,utils是存放工具类的包,WebApiApplication是SpringBoot项目的启动类。
wx-api模块
图 26wx-api结构
wx-api模块中, annotaion和config是存放配置文件的包,utils中是整个项目所需要使用的工具,controller中的类是前端访问的唯一途径。
37
广东东软学院本科毕业设计(论文)
前端Vue模块
图 27前端Vue目录结构
前端Vue模块中,public是index.html和图标的包,src中,api是存放封装了请求api的包,assets是存放了图片的包,components是存放了一部分公用模块的包,directive和utils是存放了工具类的包,icons是存放了系统图标库的包,layout是存放了布局的包,route是存放了路由的包,store是存放了本地缓存的包,styles是存放了部分样式的包,vendor是存放了excle表格导出使用的工具类的包,views是存放了页面的包,App.vue是项目的根路径,main.js是基本的js类,permission.js是权限管理类,settings.js是设置管理类。
微信小程序模块
图 28微信小程序结构
38
广东东软学院本科毕业设计(论文)
微信小程序模块中,colorui是存放前端样式的基础包,images是静态的图片,pages是全部的小程序页面,utils是所有使用到的工具;app.js、app.json、app.wxss是主文件的包,project.config.json是项目配置文件的包。
5.2 部件详细设计
5.2.1 统一结果返回
(1)结果类 R
public class R extends HashMap { public R() {put(\"code\", 200); }
public static R error() {
return error(500, \"未知异常,请联系管理员\"); }
public static R ok(String msg) { R r = new R(); r.put(\"msg\", msg); return r; } }
创建类R,继承HashMap,生成error方法和ok方法,提供两个返回结果。
5.2.2 系统日志注解
(2)自定义注解类 Log
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) @Documented
public @interface Log {
}
String value() default \"\";
创建@interface类,即注解类Log,使用@Target注解指定在何处写入注释的合法位置,这里使用的是ElementType.METHOD,即方法声明;这里将@Retention的策略设置为RUNTIME,则在项目整体运行的过程中会一直存在Log类,从而全局都可使用。@Document则是说明Log类是可以JavaDoc进行记录的,可以保留文档。在Log类中设置了一个属性value,通过这个熟悉可以设置方法的描述。
(3)系统日志切面处理类 LogAspect
使用Spring的面向切面的编程思想,进行日志的记录,并保存的数据库中。
@Pointcut(\"@annotation(cn.lhryk.common.annotation.Log)\")
public void logPointCut(){}
使用@Pointcut确认其切点的切入方向。
@Around(\"logPointCut()\")
39
广东东软学院本科毕业设计(论文)
public Object around(ProceedingJoinPoint point) throws Throwable { // 开始时间
Long beginTime = System.currentTimeMillis(); // 执行方法
Object result = point.proceed();
// 执行时长(毫秒)
Long time = System.currentTimeMillis() - beginTime; saveSysLog(point, time); return result; }
在切点处理方法中,先通过System.currentTimeMillis获取方法开始执行的时间,然后调用point.proceed继续执行方法,执行结束后通过再次获取当前系统时间,减去起始时间,得到执行时长,然后通过调用saveSysLog方法将日志保存到数据库中。
5.2.3 自定义异常
(1)自定义异常类 RRException
public class RRException extends RuntimeException { private String msg; private int code = 500;
RRException是继承了RuntimeExcetion的实现类,其中包括code和msg属性,分别为返回代码和消息。
(2)统一异常处理类 RRExceptionHandler
@RestControllerAdvice
public class RRExceptionHandler {
创建异常类RRExceptionHandler,使用Spring中的@RestControllerAdvice注解进行配置,设置其全局处理异常类的功能。
@ExceptionHandler(RRException.class)
public R handleRRException(RRException e) { R r = new R();
r.put(\"code\", e.getCode()); r.put(\"msg\", e.getMsg()); return r; }
在Spring中,@ExceptionHandler可以全局捕获异常,然后根据自定义进行处理。
本类还分别处理DuplicateKeyException(重复数据异常)、AuthorizationException(权限验证失败异常)、NullPointerException(空指针异常)和Exception(其他异常)。
40
广东东软学院本科毕业设计(论文)
5.2.4 获取请求IP
(1)IP工具类 IPUtils
public static String getIpAddr(HttpServletRequest request)
创建静态方法类getIpAddr,方法参数为HttpServletRequest,使用request. getRemoteAddr()获取请求的IP地址。
如果使用了Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址,因此需要使用request.getHeader(\"x-forwarded-for\")、request.getHeader(\"Proxy-Client-IP\")
、
request.getHeader(\"WL-Proxy-Client-IP\")
、、
request.getHeader(\"HTTP_CLIENT_IP\")
request.getHeader(\"HTTP_X_FORWARDED_FOR\")获取IP地址。
由于多层方向代理使用X-Forwarded-For可能存在多个IP地址,因此如果想获取最开始请求的地址就需要用到ip.substring(0, ip.indexOf(\来获取第一个有效的IP地址。
5.2.5 生成Token
(1)Token生成类 TokenGenerator
public static String generateValue() {
return generateValue(UUIDUtils.uuidStr()); }
创建Token生成类,使用UUID的形式先生成UUID字符串,然后再调用generateValue(String param)方法对UUID字符串进行处理。
MessageDigest algorithm = MessageDigest.getInstance(\"MD5\"); algorithm.reset();
algorithm.update(param.getBytes());
byte[] messageDigest = algorithm.digest(); return toHexString(messageDigest);
使用secutity包中的MessageDigest方法对uuid进行处理,然后再对结果进行Hex处理。
5.2.6 公共实体
(1)公共实体类 BaseEntity
项目数据库中共有8个公共的实体,分别是id、create_by(创建人)、last_modified_by(最后修改人)、gmt_modified(最后修改时间)、gmt_create(创建时间)、sort(排序)、is_deleted(逻辑删除标志)、version(版本号)。创建公共实体类,将其他实体类继承此类,即可获得这8个属性。
其中, id是使用由 Twitter 开源的分布式 id 生成算法,称之为雪花(SnowFlake)算法,其根据机器码和时间戳等,生成的是全局唯一的long类型的数据id。
创建人(createBy)、创建时间(gmtCreate)使用MyBatisPlus提供的注解
41
广东东软学院本科毕业设计(论文)
@TableField(fill = FieldFill.INSERT)进行设置,然后在使用插入语句时,会自动将这两个字段插入到sql语句中,保存到数据库。
修改人(lastModifiedBy)、修改时间(gmtModified)与上面描述类似。 排序(sortNo)是将数据进行排序。
删除标志(isDeleted)是将数据进行逻辑删除,如果该数据以及删除,则将该字段设置为1,在查询时会将这个字段带入查询条件,只查询该字段为0的字段。
版本号(version)是给每条数据加上乐观锁,防止数据的误读、脏读,保证数据的安全。
5.2.7 Shiro权限认证
(1)Shiro
Apache Shiro是一个Java安全框架,市面上还有Spring Security等类似的框架。Shiro可以对会话进行安全管理,包括认证和授权等等。
(2)OAuth2Filter
使用OAuth2Filter对每条请求连接进行拦截过滤,通过请求头中的token属性获取请求的token字符串,从而对用户权限做出校验。
@Override protected String servletRequest);
if (StringUtils.isBlank(token)) { HttpServletResponse
(HttpServletResponse)servletResponse;
String json = new Gson().toJson(R.error(500, \"invalid token\")); httpServletResponse.getWriter().print(json); return false; }
return executeLogin(servletRequest, servletResponse); }
httpServletResponse
=
boolean
token
onAccessDenied(ServletRequest
=
servletRequest,
ServletResponse servletResponse) throws Exception {
getRequestToken((HttpServletRequest)
如果拿到的token为空,则返回登录失败,如果不为空,则调用executeLogin方法对token进行校验,鉴权。
(3)OAuth2Realm
@Override protected SysUser
sysUser
=
AuthorizationInfo
(SysUser)
doGetAuthorizationInfo(PrincipalCollection principalCollection) { principalCollection.getPrimaryPrincipal(); String userId = sysUser.getId(); //获取用户权限列表
42
广东东软学院本科毕业设计(论文)
Set permsSet = shiroService.getUserPermissions(userId); SimpleAuthorizationInfo info = new SimpleAuthorizationInfo(); info.setStringPermissions(permsSet); return info; }该方法会在授权(验证权限)时调用,其主要思想是在Shiro的用户信息类PrincipalCollection中获取用户信息实体,从而获取对应的用户id,通过用户id去数据库中查询用户的权限列表,并将权限列表保存到用户认证信息中。
@Override protected
AuthenticationException {
String accessToken = (String) authenticationToken.getPrincipal(); SysUserToken sysUserToken = shiroService.queryByToken(accessToken); if
(sysUserToken
==
null
||
sysUserToken.getExpireTime().isAfter(LocalDateTime.now()) == false) { throw new IncorrectCredentialsException(\"token失效,请重新登录\"); }
SysUser sysUser = shiroService.queryUser(sysUserToken.getUserId()); SimpleAuthenticationInfo return info; }
info
=
new
SimpleAuthenticationInfo(sysUser, accessToken, getName());
AuthenticationInfo
doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws
上述方法会在认证时调用,该方法会从Shiro提供的AuthenticationToken类中获取用户信息,拿到请求的accessToken, 通过token去查询对应用户信息,将信息保存到Shiro提供的SimpleAuthenticationInfo类中。
(4)OAuth2Token
该类实现了AuthenticationToken接口,其中定义了一个属性token,并重写了getPrincipal和getCredentials方法,使其返回token属性。
(5)ShiroUtils
这个类是自定义的Shiro工具类,定义了方法,可以直接从Shiro的库中拿到如用户id、用户信息、权限等操作。
(6)BaseController
public abstract class BaseController { protected SysUser getUser() {
return (SysUser) SecurityUtils.getSubject().getPrincipal(); }
protected String getUserId() { return getUser().getId(); }
protected String getDeptId() {
43
广东东软学院本科毕业设计(论文)
return getUser().getDeptId(); } }
定义了Controller层的公共组件,定义了三个方法,分别位getUser(),拿到用户信息;getUserId(),拿到用户id字符串;getDeptId(),拿到对应用户的部分id。
5.3 后台管理系统API
5.3.1后台用户管理模块
(1)用户登录模块 关键代码描述
SysUser user = sysUserDao.selectOne(new
QueryWrapper().lambda().eq(SysUser::getUsername, sysUser.getUsername()));if (user == null || !user.getPassword().equals(new Sha256Hash(sysUser.getPassword(), Constant.SALT).toHex())) { return R.error(\"账号或密码不正确\"); }
if (user.getIsDeleted()) {
return R.error(\"账号已被锁定,请联系管理员\"); }
首先通过用户名去数据库查询对应的用户信息,如果查询出来的用户实体为null或者用户的密码与输入的密码不一致,就返回“账号或密码不正确”,如果该用户也被删除,则返回“账号已被锁定,请联系管理员”,如果校验通过则将最后一次登录时间和IP保存到数据库,再使用shiro框架生成token。
// 登录成功,修改登录最后登录ip和登录时间
user.setLastLoginIp(IPUtils.getIpAddr(request)); user.setGmtLogin(LocalDateTime.now()); sysUserDao.updateById(user);
//生成token,保存到数据库中
R r = sysUserTokenService.createToken(user.getId(), sysUser.getRemember());
redisTemplate.delete(sysUser.getCaptchaId()); String token = TokenGenerator.generateValue();
先使用TokenGenerator生成token;
if (remember) {
//一天
expireTime = LocalDateTime.now().plusSeconds(EXPIRE * 24); } else {
expireTime = LocalDateTime.now().plusSeconds(EXPIRE); }
再通过判断是否记住我设置token的过期时间;
44
广东东软学院本科毕业设计(论文)
SysUserToken sysUserToken = sysUserTokenDao.selectById(userId); if (sysUserToken == null) {
sysUserToken = new SysUserToken(); sysUserToken.setUserId(userId); sysUserToken.setToken(token);
sysUserToken.setUpdateTime(LocalDateTime.now()); sysUserToken.setExpireTime(expireTime); sysUserTokenDao.insert(sysUserToken); } else {
sysUserToken.setToken(token);
sysUserToken.setUpdateTime(LocalDateTime.now()); sysUserToken.setExpireTime(expireTime); sysUserTokenDao.updateById(sysUserToken); }
return R.ok().put(\"token\", token).put(\"expire\", expireTime);
然后通过用户id去数据库查询是否已经存在token,如果不存在,则新建sysUserToken对象,将该对象保存到数据库中,如果存在,则修改对应的token值和时间,并修改数据库中的值,最后将token和有效时间返回到前端。
(2)验证码 关键代码说明
public R initCaptcha() {
//生成文字验证码
String text = producer.createText(); String captchaId = UUIDUtils.uuidStr();
//缓存验证码
redisTemplate.opsForValue().set(captchaId, text, 2L, TimeUnit.MINUTES);
return R.ok().put(\"captchaId\", captchaId); }
验证码使用google提供的kaptcha工具,首先生成验证码文本,再使用UUID随机字符串生成验证码的id,使用redisTemplate将对应的验证码文本和id保存到redis服务器上,并设置过期时间为2分钟,然后将验证码的id返回给前端。
public void captcha(HttpServletResponse response, @PathVariable String captchaId) throws IOException {
response.setHeader(\"Cache-Control\", \"no-store, no-cache\"); response.setContentType(\"image/jpeg\");
//生成文字验证码
String text = redisTemplate.opsForValue().get(captchaId); //生成图片验证码
BufferedImage image = producer.createImage(text); ServletOutputStream out = response.getOutputStream(); ImageIO.write(image, \"jpg\", out);
45
广东东软学院本科毕业设计(论文)
…
此接口将前端传入的验证码id接受起来,然后调用redisTemplate的方法从redis服务器查询出对应的验证码字符串,再使用producer的createImage方法将验证码字符串转换为图片,并使用输出流的形式将图片返回到前端。
(3)获取用户信息 关键代码说明
SysUser sysUser = sysUserService.getById(getUserId()); List roleNameList =sysUserRoleService.queryRoleNameList(getUserId());
return R.ok().put(\"name\", sysUser.getUsername()).put(\"avatar\", sysUser.getAvatar()).put(\"roles\", roleNameList);
通过BaseController层中的getUserId()方法,调用SysUserService中的getById方法查询对应用户信息,再调用SysUserRoleService中的queryRoleNameList方法查询出用户的角色信息,并将用户信息和角色信息放到统一返回结果中。
select sr.role_name from sys_role sr LEFT JOIN sys_user_role sur on sr.id = sur.role_id where user_id = #{userId}
(4)获取用户列表 关键代码说明
if (!StringUtils.equals(getUserId(), Constant.SUPER_ADMIN)) { params.put(\"deptId\", getDeptId()); }
List items = sysUserService.selectUser(params); int total = sysUserService.countAll(params);return R.ok().put(\"items\", items).put(\"total\", total);
判断请求的用户是否是超级管理员的用户,如果不是,则只筛选对应公司的管理员名单。查询后返回出用户列表和数量,返回给前端调用者。
public List selectUser(Map params) { params = PageUtils.handlePage(params); return sysUserDao.selectUser(params); }将传进来的参数使用PageUtils对参数进行处理。
public static Map handlePage(Map params) {if (params.get(\"page\") != null) {
long page = Long.parseLong((String) params.get(\"page\")); long limit = Long.parseLong((String) params.get(\"limit\")); params.put(\"offset\", (page - 1) * limit); params.put(\"page\", page); params.put(\"limit\", limit); }
return params;
46
广东东软学院本科毕业设计(论文)
将参数中的page和limit取出来,计算一下offset,提供给dao层访问数据库。
select su.*, sur.role_id from sys_user su left join sys_user_role sur on su.id = sur.user_id
order by su.gmt_create asc limit #{offset}, #{limit};
select count(*) from sys_user
使用Mybatis的include标签将公共代码模块引入,offset和limit提供给分页使用的。
and su.dept_id = #{dept}
and su.name like CONCAT('%',#{name},'%')
以上是公共代码块。 (5)创建新用户 关键代码说明
if (StringUtils.isEmpty(sysUser.getId())) {
sysUser.setId(SnowFlakeUtil.getFlowIdInstance().toString()); }
sysUser.setPassword(new Sha256Hash(sysUser.getPassword(), Constant.SALT).toHex());
sysUserService.save(sysUser);
判断用户实体中的id是否为空,如果为空就将用户id设置进去,然后将用户的密码进行加密,最后保存到数据库中。
47
广东东软学院本科毕业设计(论文)
(6)修改用户信息 关键代码说明
sysUserService.updateById(sysUser);
List roleIds = sysUser.getRoleIds(); sysUserRoleService.removeById(sysUser.getId()); sysUserRoleService.saveBatch(getCollection(roleIds, sysUser.getId()));更新用户信息后,将用户的角色id列表查询出来,调用SysUserRoleService的removeById方法将用户角色映射表的数据删除,然后在调用saveBatch方法将用户角色映射表保存起来。
getCollection()方法
Collection userRoleCollection = Lists.newArrayList();roleIds.forEach(roleId -> {
SysUserRole sysUserRole = new SysUserRole(); sysUserRole.setRoleId(roleId); sysUserRole.setUserId(userId); userRoleCollection.add(sysUserRole); });
return userRoleCollection;
getCollection方法将用户角色id封装成用户id和角色id的映射表,用以插入数据库。
(7)删除/恢复用户 关键代码描述
sysUserService.removeById(id); sysUserService.recoverUser(id);
使用SysUserService中的removeById删除用户,revocerUser恢复用户。
update sys_user set is_deleted = 0 where id = #{id} and is_deleted = 1
(8)修改密码 关键代码描述
sysUser.setPassword(new Sha256Hash(sysUser.getPassword(), Constant.SALT).toHex());
sysUserService.updateById(sysUser);
对用户密码使用加盐和Sha1进行双重加密,然后通过service层的updateById根据用户id,将修改后的用户信息保存到数据库。
48
广东东软学院本科毕业设计(论文)
5.3.2角色管理模块
(1)根据用户id获取用户角色 关键代码描述
List roleNameList =sysUserRoleService.queryRoleNameList(userId); return R.ok().put(\"roles\", roleNameList);
调用sysUserRoleService中的queryRoleNameList,根据用户id进行角色列表的查询。
(2)获取全部角色 关键代码描述
Map params = new HashMap<>(1);if (!StringUtils.equals(getUserId(), Constant.SUPER_ADMIN)) { params.put(\"createBy\", getUserId()); }
List sysRoleList = sysRoleService.selectAllRole(params); return R.ok().put(\"data\", sysRoleList);定义一个大小为1的Map集合,然后判断请求中的token携带的userId是否位超级管理员的id,如果是超级管理员,则默认是查询所有的角色列表,如果是非超级管理员,就将创建者字段放到参数集合中,然后调用sysRoleService中的selectAllRole方法进行查询。
sysRoleList.forEach(sysRole -> { List sysMenuList =sysMenuDao.selectMenuByRoleId(sysRole.getId());
List routes = Lists.newArrayList(); String parentId = \"0\";sysMenuList.forEach(sysMenu -> {
if (parentId.equals(sysMenu.getParentId())) { List children = Lists.newArrayList(); sysMenuList.forEach(child -> {if (child.getParentId().equals(sysMenu.getId())) { children.add(child); } });
sysMenu.setChildren(children); routes.add(sysMenu); } });
sysRole.setRoutes(routes); });
在service层中,将查询出来的用户角色列表进行循环,然后使用sysMenuDao中的selectMenuByRoleId方法对角色的菜单列表进行查询,菜单列表再将子菜单进
49
广东东软学院本科毕业设计(论文)
行查询,最后将菜单列表设置给角色列表。
(3)新增角色 关键代码描述
public R createRole(@RequestBody Map params) { SysRole sysRole = new SysRole(); String roleId =String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()); sysRole.setId(roleId);
sysRole.setRemark((String) params.get(\"remark\")); sysRole.setRoleName((String) params.get(\"roleName\")); sysRole.setDeptId(getDeptId()); sysRoleService.save(sysRole);
List menuIds = (List) params.get(\"routes\"); sysRoleMenuService.saveBatch(getCollection(menuIds, roleId)); return R.ok(); }使用角色实体封装前台传递的参数,然后将前端传入的菜单 id列表保存到 menuIds列表中,然后调用服务层的save方法将角色数据保存起来,然后调用 getCollection方法将菜单 id和角色 id封装到 collection列表中,并在数据库中保存 sysRoleMenuService的 saveBatch方法。
(4)修改角色 关键代码描述
public R updateRole(@RequestBody Map map) { SysRole sysRole = new SysRole();String roleId = (String) map.get(\"id\"); sysRole.setId(roleId);
sysRole.setRemark((String) map.get(\"remark\")); sysRole.setRoleName((String) map.get(\"roleName\")); sysRoleService.updateById(sysRole);
List menuIds = (List) map.get(\"routes\"); sysRoleMenuService.removeBatch(menuIds, roleId);sysRoleMenuService.saveBatch(getCollection(menuIds, roleId)); return R.ok();
}
修改角色的逻辑与创建角色的逻辑相类似,通过前端获取请求参数,将参数中的参数封装成一个角色实体,调用sysRoleService的updateById方法将角色修改保存到数据库中,再调用sysRoleMenuService的removeBatch方法将数据库中的角色菜单映射删除,再使用saveBatch方法将角色和菜单映射保存到数据库中。
(5)删除/恢复角色 关键代码描述
50
广东东软学院本科毕业设计(论文)
sysRoleService.removeById(id); sysRoleService.recoverRole(id);
使用sysRoleService中的removeById对角色信息进行逻辑删除,使用recoverRole方法进行恢复角色。
update sys_role set is_deleted = 0 where id = #{id} and is_deleted = 1
在dao层中使用update语句,通过传入的id值和删除标志对对应的数据进行恢复操作。
5.3.3菜单管理模块
(1)加载所有菜单 关键代码描述
if (StringUtils.isNotEmpty(query)) { map.put(\"name\", query); }
if (getUserId().equals(Constant.SUPER_ADMIN)) { roles.add(\"ROLE_ADMIN\"); } else {
roles = sysUserRoleService.queryRoleNameList(getUserId()); }
List sysMenuList = sysMenuService.selectAllMenu(map, roles);通过判断前端创建来的查询参数,如果查询参数不为空,则加入到查询条件中,然后判断请求的用户id是否为超级管理员id,如果是,则默认查询所有的菜单,如果不是,则值查询对应用户拥有的菜单。然后调用sysMenuService中的selectAllMenu方法对菜单列表进行查询。
@Override
public List selectAllMenu(Map map, List roles) {List sysMenuList = sysMenuDao.selectAllMenu(map); sysMenuList = SetMeta.setMeta(sysMenuList, roles, false); return sysMenuList; }在service层总,调用sysMenuDao的selectAllMenu方法对数据库的菜单列表进行查询,查询出来的菜单列表再使用SetMeta对菜单列表中的数据进行封装,形成前端需要的菜单列表。
在dao层的selectAllMenu的xml文件中,使用case when 1 = 0 then 0 else 1 end as fatherDeleted为子查询封装一个是否删除的条件,并将前端的其余条件拼接到查询条件中。
select * from sys_menu where parent_id = #{id} and is_deleted = ${fatherDeleted} order by sort_no asc
在子查询中,使用上述的fatherDeleted就可以通过前端判断是否需要筛选出删除包括已经删除的菜单列表。
public static List setMeta(List menuList, List roleNameList, boolean nav) { for (SysMenu s : menuList) {s.setMeta(new Meta(s.getName(), s.getIcon(), roleNameList, false));
List delete = Lists.newArrayList(); for (SysMenu child : s.getChildren()) {child.setMeta(new Meta(child.getName(), child.getIcon(), roleNameList, false));
child.setChildren(null);
if (nav && child.getIsDeleted()) {
delete.add(s.getChildren().indexOf(child)); } }
for (int i : delete) {
s.getChildren().remove(i);
52
广东东软学院本科毕业设计(论文)
} }
return menuList; }
setMeta方法中,循环遍历菜单列表,并封装Meta属性,设置给对应的菜单实体,如果对应的菜单有子菜单,则对子菜单也封装Meta属性,设置给菜单实体。如果子菜单的删除标志是已经被删除,则将子菜单中的菜单删除。
(2)新增菜单 关键代码描述
public R createMenu(@RequestBody SysMenu sysMenu) { sysMenuService.save(sysMenu); return R.ok(); }
使用sysMenuService中的save方法将菜单保存到数据库中。 (3)修改菜单 关键代码描述
public R updateMenu(@RequestBody SysMenu sysMenu) { sysMenuService.updateById(sysMenu); return R.ok(); }
使用sysMenuService中的updateById方法将修改的属性保存到数据库中。 (4)禁用/启用菜单 关键代码描述
sysMenuService.removeById(id); sysMenuService.recoverMenu(id);
使用sysMenuService中的removeById将对应的菜单禁用,使用recoverMenu启用菜单。其内部的代码逻辑与角色管理模块中的禁用/启用逻辑类似。
(5)导航菜单 关键代码描述
public R nav() {
List nav = sysMenuService.nav(getUserId()); List roleNameList =sysUserRoleService.queryRoleNameList(getUserId()); nav = SetMeta.setMeta(nav, roleNameList, true); return R.ok().put(\"nav\", nav); }
使用sysMenuService的nav方法将导航的菜单查询出来,再调用sysUserRoleService中的queryRoleNameList方法把用户对应的角色列表查询出来,使用setMeta方法将菜单列表中的Meta属性进行封装。
53
广东东软学院本科毕业设计(论文)
select sm.*, case when 0 = 0 then 0 else 1 end as fatherDeleted from sys_menu sm LEFT JOIN sys_role_menu srm on sm.id = srm.menu_id LEFT JOIN sys_role sr on
srm.role_id = sr.id LEFT JOIN sys_user_role sur on sr.id = sur.role_id
where user_id = #{userId} and sm.is_deleted = 0 and sm.parent_id = '0'
order by sm.sort_no asc
在dao层中,使用连接操作关联菜单表、菜单角色映射表和角色表进行查询,找出对应用户所拥有的菜单列表,并按照排序号进行排序。其中也封装了fatherDeleted数据,其目的与查询菜单列表中的一致。
5.3.4部门(商家)管理模块
(1)查询所有部门 关键代码描述
public R selectAllDept(@RequestParam Map params) { if (!UserUtils.isSuperAdmin(getUserId())) { params.put(\"parent_id\", getDeptId()); }List items = sysDeptService.selectAllDept(params); int total = sysDeptService.countAll(params);return R.ok().put(\"items\", items).put(\"total\", total); }
首先调用UserUtils中的isSuperAdmin方法判断是否为超级管理员,如果不是,则再查询条件中增加parent_id属性,值为部门对应的用户的部门id,然后调用sysDeptService中的selectAllDept查询出部门列表,在调用countAll查询出相应条件下的部门总数,将两者返回给前端。
parent_id = '0'
and name like CONCAT('%',#{name},'%')
and is_deleted = 0
and parent_id = #{parent_id}
54
广东东软学院本科毕业设计(论文)
在dao层的xml文件中 (2)新增部门/公司 关键代码描述
sysDeptService.save(sysDept);
调用sysDeptService的save方法保存新的部门到数据库中。 (3)修改部门/公司 关键代码描述
sysDeptService.updateById(sysDept);
调用updateById方法将修改后的内容保存到数据库中。 (4)禁用/启用部门 关键代码描述
sysDeptService.removeById(id); sysDeptService.recoverDept(id);
调用sysDeptService的removeById方法对指定id的部门进行删除,调用recoverDept方法对指定id的部门进行恢复。其dao层的代码逻辑与前文禁用菜单的逻辑相似。
5.3.5日志模块
(1)查询所有日志 关键代码描述
IPage sysLogIPage = sysLogService.selectAll(params);调用sysLogService的selectAll方法查询出所有的日志,封装成IPage对象,并返回数据。5.3.6文件上传模块
(1)上传文件到腾讯云 关键代码描述
@Value(\"${spring.tengxun.secretId}\") private String secretId;
使用上述代码,从配置文件(application.xml)中获取腾讯云文件存储的相关配置信息。
String oldFileName = file.getOriginalFilename(); String eName =
oldFileName.substring(oldFileName.lastIndexOf(\".\"));
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
Region region = new Region(this.region);
ClientConfig clientConfig = new ClientConfig(region); COSClient cosClient = new COSClient(cred, clientConfig); File localFile = null;
55
广东东软学院本科毕业设计(论文)
if (StringUtils.isEmpty(userId)) { userId =
String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId()); }
String newFileName = userId + eName;
使用上述代码创建新的文件名,判断请求参数中是否有userId字段,如果有,则直接拼接新的文件名称,如果没有,则使用雪花算法生成一个新的字符串,在拼接成新的文件名称。并使用配置信息,封装一个文件存储的客户端,为上传文件准备好环境。
// 指定要上传的文件
localFile = File.createTempFile(\"temp\", null); file.transferTo(localFile); // 指定要上传到的存储桶
String bucketName = this.bucket;
// 指定要上传到 COS 上对象键
String key = \"/\" + director + \"/\" + newFileName; PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile); PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
return R.ok().put(\"path\", key).put(\"userId\", userId);
将需要上传的文件先缓存到本地,然后指定需要上传到腾讯云对象存储上的存储桶,并指定对象的键,使用腾讯云提供的PutObjectRequest封装一个上传请求的对象,并调用上述创建的客户端中的putObject方法将文件对象传至服务器上。如果上传成功,则返回成功的结果并将对象的键值和id。
5.3.7文章管理模块
(1)查询所有文章 关键代码描述
Map params = new HashMap<>(2); params.put(\"limit\", limit); params.put(\"page\", page); List articleList = articleService.setAllArticles(params);int total = articleService.countAllArticles();
定义一个长度为2的Map集合,将当前页面数和限制数保存到Map集合中,调用articleService中的setAllArticles方法查询所有的文章列表,调用countAllArticles统计对应查询条件的文章总数,查询成功后把结果返回。
long page = (long) params.get(\"page\"); long limit = (long) params.get(\"limit\"); long offset = (page - 1) * limit;
56
广东东软学院本科毕业设计(论文)
params.put(\"offset\", offset);
return articleDao.setAllArticles(params);
在service层中,通过controller中的page参数和limit参数,计算出分页查询所需要用到的offset参数,并将该参数保存到请求参数中,调用articleDao的setAllArticles方法查询文章列表。
(2)创建文章 关键代码描述
articleService.save(article);
调用articleService的save方法将传进来的文章实体保存到数据库中。 (3)修改文章 关键代码描述
articleService.updateById(article);
调用articleService的save方法将传进来的文章实体保存到数据库中。 (4)通过id获取文章信息 关键代码描述
Article article = articleService.selectArticle(id);
调用articleService的selectArticle方法根据id查询对应的文章信息。 (5)删除/恢复文章 关键代码描述
articleService.removeById(id); articleService.recoverArticle(id);
调用articleService的removeById把文章进行删除,调用recoverArticle对文章进行恢复操作。其dao层与前述的逻辑相似。
5.3.8分类管理模块
(1)查询所有的分类 关键代码描述
List categoryList =categoryService.selectAllCategory(isDeleted);
调用categoryService的selectAllCategory方法查询所有的分类,使用isDeleted来区别查询是否查询已经禁用的分类。
select * from categorywhere is_deleted = 0 and id != '216375712775409664'
order by sort_no asc
在dao层的xml文件中,判断isDeleted参数,如果不为true,则筛选没有被删
57
广东东软学院本科毕业设计(论文)
除的分类和id不为'216375712775409664'的列表。
(2)添加分类 关键代码描述
categoryService.save(category);
调用categoryService的save方法将分类实体保存到数据库中。 (3)修改分类 关键代码描述
categoryService.updateById(category);
调用categoryService的updateById方法将修改的分类信息保存到数据库中。 (4)删除/启用分类 关键代码描述
categoryService.recoverCategory(id); categoryService.removeById(id);
调用categoryService的removeById方法将对应id的分类进行逻辑删除,使用recoverCategory对应id的分类进行恢复。
5.3.9优惠券管理模块
(1)查询所有的优惠券 关键代码描述
List couponList = couponService.selectCoupon(page, limit, name);int total = couponService.countAll(name);
调用couponService的selectCoupon方法查询所有的优惠券列表,使用page、limit对列表进行分类,使用name对数据进行模糊查询,使用countAll方法统计所有的优惠券总数。
(2)新建优惠券 关键代码描述
couponService.save(coupon);
couponService.removeById(coupon.getId());
调用couponService的save方法将优惠券数据保存到数据库中,然后调用removeById方法将该优惠券下架。
58
广东东软学院本科毕业设计(论文)
(3)修改优惠券 关键代码描述
couponService.updateById(coupon);
调用couponService的updateById方法将修改后的优惠券数据保存到数据库中。 (4)删除/恢复优惠券 关键代码描述
couponService.removeById(id); couponService.recoverCoupon(id);
调用couponService的removeById方法将对应id的优惠券信息进行逻辑删除,调用recoverCoupon方法恢复指定id的优惠券信息。
(5)获取用户优惠券 关键代码描述
IPage couponIPage =userCouponService.getUserCoupon(userId, page, limit);
调用userCouponService中的getUserCoupon方法获取对应用户id的用户优惠券,使用page、limit参数进行分页。
IPage userCouponIPage = new Page<>(); userCouponIPage.setCurrent(page); userCouponIPage.setSize(limit);userCouponIPage = userCouponDao.selectPage(userCouponIPage, new QueryWrapper().eq(\"user_id\", userId)); IPage couponIPage = new Page<>(); List couponList = Lists.newArrayList(); userCouponIPage.getRecords().forEach(userCoupon -> { Coupon coupon =couponDao.selectById(userCoupon.getCouponId()); coupon.setOrderId(userCoupon.getOrderId()); coupon.setUseTime(userCoupon.getUseTime()); couponList.add(coupon); });
couponIPage.setSize(userCouponIPage.getSize()); couponIPage.setCurrent(userCouponIPage.getCurrent()); couponIPage.setTotal(userCouponIPage.getTotal()); couponIPage.setPages(userCouponIPage.getPages()); couponIPage.setRecords(couponList);
在service层中,封装一个泛型为UserCoupon的IPage实体,并设置其当前页和大小,调用userCouponDao的selectPage方法根据用户id查询对应的优惠券分类实体。从该实体中拿到列表并循环,将对应的信息封装成泛型为Coupon的IPage实体,循环后将对应的couponIPage放入couponList列表中。并将couponIPage的属性从userCouponIPage中获取并封装,最后返回couponIPage实体。
59
广东东软学院本科毕业设计(论文)
5.3.10服务管理模块
(1)查询所有服务 关键代码描述
if (!StringUtils.equals(getUserId(), Constant.SUPER_ADMIN)) { params.put(\"dept\", getDeptId()); }
List goodList = goodService.selectAll(params); int total = goodService.countAll(params);判断前端请求的用户是否为超级管理员,如果否,则在查询参数中插入一个部门id,然后调用goodService的selectAll方法将服务列表查询出来,再调用countAll方法查询出对应查询条件的总数量。并将两个结果返回。
(2)添加服务 关键代码描述
good.setDeptId(getDeptId()); goodService.save(good);
先将服务的部门id参数设置成当前用户的id,然后调用服务处的goodService将数据保存到数据库中。
(3)修改服务 关键代码描述
goodService.updateById(good);
调用goodService的updateById方法更新指定服务的信息。 (4)下架/上架服务 关键代码描述
goodService.removeById(id); goodService.recoverGood(id);
调用goodService的removeById方法将指定id的服务从数据库中进行逻辑删除。调用recoverGood方法将指定id的服务进行恢复。
(5)查询收藏的服务 关键代码描述
IPage goodPage = goodLoveService.getGoodLove(userId, page, limit);调用goodLoveService的getGoodLove方法分页查询对应用户收藏的服务。其service层中的代码逻辑与优惠券中心的获取优惠券信息模块相似。
(6)删除服务收藏 关键代码描述
goodLoveService.remove(new QueryWrapper().eq(\"good_id\", id).eq(\"user_id\", userId));60
广东东软学院本科毕业设计(论文)
调用goodLoveService的remove方法,封装一个查询条件类,指定删除条目的服务id和用户id,进行物理删除。
(7)访问足迹 关键代码描述
IPage goodPage = goodAccessService.getGoodAccess(userId, page, limit);调用goodAccessService的getGoodAccess方法对指定用户id的访问足迹列表进行分页查询。
(8)删除访问足迹 关键代码描述
goodAccessService.remove(new
QueryWrapper().eq(\"user_id\", userId).eq(\"good_id\", id));调用goodAccessService的remove方法删除对应的访问足迹,使用QueryWrapper封装查询条件,通过用户id和服务id封装查询条件。
(9)查询评论列表 关键代码描述
List evaluateList = evaluateService.selectAll(params); int total = evaluateService.countAll(params);调用evaluateService的selectAll查询评论列表,再使用countAll方法查询对应查询条件的列表总数。
(10)删除评论 关键代码描述
evaluateService.removeById(id);
调用evaluateService的removeById方法对指定id的的评论进行逻辑删除。
5.3.11订单管理模块
(1)查询所有订单 关键代码描述
if (!StringUtils.equals(getUserId(), Constant.SUPER_ADMIN)) { params.put(\"dept\", getDeptId()); }
List orderList = orderService.selectOrder(params); int total = orderService.countAll(params);判断请求的用户是不是超级管理员,如果是,则将对应的部门id放入查询条件中,然后调用orderService的selectOrder方法查询所有的订单列表,然后调用countAll查询对应查询条件下的订单总数,然后返回数据。
61
广东东软学院本科毕业设计(论文)
(2)回馈 关键代码描述
feedbackService.save(feedback);
调用feedbackService的save方法将回馈的数据保存到实体中。 (3)修改订单 关键代码描述
orderService.saveOrUpdate(order);
调用服务层的saveOrUpdate方法根据订单id将修改后的订单数据保存到数据库中。
(4)删除订单 关键代码描述
orderService.removeById(id);
调用orderService的removeById方法将指定id的订单进行逻辑删除。
5.3.12轮播图管理模块
(1)创建轮播图 关键代码描述
rotationService.save(rotation);
调用rotationService的save方法将轮播图数据保存到数据库中。 (2)获取轮播图列表 关键代码描述
List rotations = rotationService.list();调用rotationService的list方法从数据库中获取轮播图列表。 (3)删除轮播图 关键代码描述
rotationService.removeById(id);
调用rotationService的removeById方法通过id将数据库中的数据删除。
5.3.13微信用户管理模块
(1)查找所有微信用户 关键代码描述
params = PageUtils.handlePage(params); List wechatUserList = wechatUserService.selectAll(params);int total = wechatUserService.countAll(params);
调用PageUtils的handlePage方法,将params中的分页参数进行处理,然后调用wechatUserService的selectAll方法查询微信用户列表,然后调用countAll方法查询对应查询条件的列表总数。
62
广东东软学院本科毕业设计(论文)
(2)禁用/恢复微信用户 关键代码描述
wechatUserService.removeById(id); wechatUserService.recoverUser(id);
调用wechatUserService的removeById方法根据id对微信用户进行逻辑删除,调用recoverUser方法对指定id的微信用户进行恢复操作。
5.4 微信小程序端API
5.4.1用户中心
(1)微信登录接口 关键代码描述
@Value(\"${auth.wechat.appid}\") private String appid;
@Value(\"${auth.wechat.secret}\") private String secret;
使用@Value从配置文件中将微信官方接口的appid和secret配置到系统中。
String url =
\"https://api.weixin.qq.com/sns/jscode2session?appid=\" + appid + \"&secret=\" + secret +
\"&js_code=\" + authcode + \"&grant_type=authorization_code\"; CloseableHttpClient httpClient = HttpClients.createDefault(); HttpGet httpGet = new HttpGet(url); InputStream inputStream = null;
CloseableHttpResponse httpResponse = null; StringBuilder result = new StringBuilder();
使用以上代码拼接url链接,将url、appid、secret等信息拼接成请求字符串,为后续的认证准备条件。
JSONObject jsonObject = JSON.parseObject(line); String openid = (String) jsonObject.get(\"openid\");
String sessionKey = (String) jsonObject.get(\"session_key\"); WechatUser wechatUser = wechatUserService.getOne(new QueryWrapper().eq(\"openid\", openid));将请求结束后的结果使用fastjson包进行解析,获取微信官方返回的用户id(openid)和缓存key(session_key),然后通过openid请求wechatUserService的getOne方法,查询对应openid的用户是否已经存在数据库中。
if (wechatUser == null) {
wechatUser = new WechatUser(); wechatUser.setOpenid(openid);
wechatUser.setSessionKey(sessionKey);
wechatUser.setGmtLogin(LocalDateTime.now());
63
广东东软学院本科毕业设计(论文)
wechatUser.setLastLoginIp(ip);
wechatUser.setCreateBy(wechatUser.getId()); wechatUserService.save(wechatUser); } else {
wechatUser.setSessionKey(sessionKey);
wechatUser.setGmtLogin(LocalDateTime.now()); wechatUser.setLastLoginIp(ip);
wechatUserService.updateById(wechatUser); }
如果对应openid的用户存在,则修改其sessionKey和登录ip及时间,保存到数据库中。如果数据存在,则将对应的用户信息保存到数据库中。
String token = getToken(wechatUser); return R.ok().put(\"token\", token);
使用getToken方法,生成token并返回。
protected String getToken(WechatUser wechatUser) { String token = \"\"; token = JWT.create()
.withKeyId(wechatUser.getId()) .withIssuer(\"www.lhryk.cn\") .withIssuedAt(new Date()) .withJWTId(\"jwt.lhryk.cn\")
.withClaim(\"sessionKey\", wechatUser.getSessionKey()) .withClaim(\"openid\", wechatUser.getOpenid()) .withAudience(wechatUser.getId())
.sign(Algorithm.HMAC256(wechatUser.getOpenid())); return token;
}
使用JWT生成一个token,将对应的id、sessionKey和openid赋值到JWT信息中,对应的JWT签名信息则是经过加密的微信openid。
(2)加密信息解密 关键代码描述
String sessionKey = (String) request.getAttribute(\"sessionKey\"); String encryptedData = (String) maps.get(\"encrypted_data\"); String iv = (String) maps.get(\"iv\"); int referrer = (int) maps.get(\"referrer\"); AES aes = new AES();
WechatUser wechatUser = new WechatUser(); if (StringUtils.isEmpty(sessionKey) ||
StringUtils.isEmpty(encryptedData) || StringUtils.isEmpty(iv)) { return R.error(\"异常,请重试\"); } …
64
广东东软学院本科毕业设计(论文)
byte[] resultByte =
aes.decrypt(Base64.decodeBase64(encryptedData),
Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv));
在请求中获取sessionKey、加密数据encryptedData、iv和referrer,然后使用AES进行解密。
wechatUserService.updateById(wechatUser);
将解密后的数据封装起来,然后调用服务层的updateById方法根据id修改数据库中对于的用户信息,把数据保存到数据库中。
(3)用户中心 关键代码描述
String userId = (String) request.getAttribute(\"userId\"); return R.ok().put(\"browseCount\", goodAccessService.count(new QueryWrapper().eq(\"user_id\", userId))).put(\"favorCount\", goodLoveService.count(new QueryWrapper().eq(\"user_id\", userId))).put(\"orderCount\", orderService.count(new QueryWrapper().eq(\"create_by\", userId)));通过请求头获取对应的userId,然后调用goodAccessService的count方法,根据用户id查询出对应用户的浏览数,调用goodLoveService的count方法查询对应用户的收藏数,调用orderService的count方法查询对应用户的订单数。
(4)token拦截器 关键代码描述
if (method.isAnnotationPresent(AllowAnonymous.class)) { AllowAnonymous passToken =
method.getAnnotation(AllowAnonymous.class); if (passToken.required()) { return true; } }
使用AllowAnonymous来判断指定的方法是否需要通过拦截器,如果是需要拦截的就进行token的解析。
userId = JWT.decode(token).getKeyId(); request.setAttribute(\"userId\", userId);
WechatUser wechatUser = wechatUserService.getById(userId); if (wechatUser == null) {
throw new RuntimeException(\"用户不存在,请重新登录\"); } try {
String session_key =
JWT.decode(token).getClaim(\"sessionKey\").as(String.class); request.setAttribute(\"sessionKey\", session_key);
65
广东东软学院本科毕业设计(论文)
String openid =
JWT.decode(token).getClaim(\"openid\").as(String.class); request.setAttribute(\"openid\", openid); } catch (Exception e) {}
获取请求头中的token字段,使用JWT的decode方法,对token中的数据进行解析,获取对应的openid和userId,然后将openid和userId放到请求头中,将对应的数据带到接下来的请求中。
5.4.2地址中心
(1)新增地址 关键代码描述
String userId = (String) request.getAttribute(\"userId\"); if (address.getIsDefault()) {
Address defaultAddress = addressService.getOne(new QueryWrapper
().eq(\"is_default\", true)); if (defaultAddress != null) {defaultAddress.setIsDefault(false);
addressService.updateById(defaultAddress); } }
调用addressService的getOne方法通过用户id查询该用户是否有默认的地址,如果有,则将对应的地址设置为false,然后将修改后的数据保存到数据库中。 addressService.saveOrUpdate(address);
调用addressService的saveOrUpdate方法将对于id的地址数据保存到数据库中。 (2)查找用户的地址列表 关键代码描述
String userId = (String) request.getAttribute(\"userId\"); List
addressList = addressService.list(new QueryWrapper().eq(\"create_by\", userId)); addressList.forEach(address -> {address.setMobile(address.getMobile().substring(0,3) + \"****\" + address.getMobile().substring(7)); });
调用addressService的list方法通过用户id查询数据库中对应的创建用户的地址列表,然后对地址列表中的手机号码进行隐藏处理。
(3)用户删除地址 关键代码描述
addressService.removeById(id);
调用addressService的removeById方法根据id删除对应的地址数据。
66
广东东软学院本科毕业设计(论文)
(4)查找地址信息 关键代码描述
Address address = addressService.getById(id);
address.setMobile(address.getMobile().substring(0,3) + \"****\" + address.getMobile().substring(7));
调用addressService的getById方法根据id查询对应的数据,然后对手机号码进行隐藏部分信息的处理。
5.4.3文章中心
(1)获取文章信息 关键代码描述
String token = request.getHeader(\"authorization\"); boolean isAppreciate = false;
if (StringUtils.isNotEmpty(token)) {
String userId = JWT.decode(token).getKeyId(); List articleAppreciateList = articleAppreciateService.list(newQueryWrapper().eq(\"user_id\", userId).eq(\"article_id\", id));isAppreciate = articleAppreciateList.size() != 0; }
articleService.addAttention(id);
Article article = articleService.getById(id);
通过请求头中的authorization,取得token,如果token不为空,则是已登录用户,通过使用JWT的decode方法解析token字符串获取用户id,然后调用articleAppreciateService的list方法,通过用户id和文章id该用户是否已经对该文章进行了点赞操作;调用articleService的addAttention方法将文章的浏览数加1,再调用articleService的getById方法通过文章id查询数据库对应的数据,最后将文章信息和是否点赞返回。
(2)转发 关键代码描述
articleService.addForward(id);
调用articleService的addForward方法添加转发数。
update article set forward = forward + 1 where id = #{id}
添加转发数的操作是在对应id的数据上对转发数进行加1操作。
67
广东东软学院本科毕业设计(论文)
5.4.3优惠券中心
(1)查询所有优惠券 关键代码描述
String userId =
JWT.decode(request.getHeader(\"authorization\")).getKeyId(); List couponList = couponService.list(); if (StringUtils.isNotEmpty(userId)) {couponList.parallelStream().forEach(coupon -> {
UserCoupon userCoupon = userCouponService.getOne(new QueryWrapper().eq(\"user_id\", userId).eq(\"coupon_id\", coupon.getId()));if (userCoupon != null) { coupon.setIsOperable(true);
coupon.setOperableName(LocalDateTime.now().isAfter(coupon.getValidity()) \"已过期\":\"已领取\"); } }); }
调用couponService的list方法查询优惠券列表,获取authorization的数据,即用户请求的token,如果token不为空,使用JWT的deocode方法解析token字符串获取用户id,循环遍历优惠券列表,调用getOne方法查询对应的用户id和优惠券id,查询是否有对应的记录,如果有,则视为已经领取优惠券,然后在优惠券的信息中将isOperable标志设置为true。如果该优惠券没被领取但是有效期已经过了,则将对应的信息设置为已过期。
(2)获取优惠券 关键代码描述
String userId = (String) request.getAttribute(\"userId\"); UserCoupon userCoupon = new UserCoupon(); userCoupon.setCouponId(couponId); userCoupon.setUserId(userId); userCouponService.save(userCoupon);
获取请求头中的用户id,并将用户id和优惠券id赋值到userCoupon实体中,调用userCouponService的save方法将优惠券用户映射保存到数据库中。
(3)用户优惠券 关键代码描述
List userCouponList = userCouponService.list(new QueryWrapper().eq(\"user_id\", userId));…
68
广东东软学院本科毕业设计(论文)
for (UserCoupon userCoupon : userCouponList) { Coupon coupon =
couponService.getById(userCoupon.getCouponId());
if (StringUtils.isEmpty(userCoupon.getOrderId())) { coupon.setOperableName(\"未使用\"); noUseList.add(coupon); continue; }
if (LocalDateTime.now().isAfter(coupon.getValidity())) { coupon.setIsOperable(true); coupon.setOperableName(\"已过期\"); alreadyExpireList.add(coupon); continue; }
coupon.setUseTime(userCoupon.getUseTime()); alreadyUseList.add(coupon); }
调用userCouponService的list方法,根据用户id查询用户优惠券映射列表,然后对列表进行循环,在循环体中,调用couponService的getById方法根据优惠券id进行查询,如果映射表中订单编号为空,则优惠券的操作名称为“未使用”,如果有效时间是在当前时间之前,则操作名称为“已过期”。
5.4.4评价中心
(1)发表评价 关键代码描述
Evaluate evaluate = new Evaluate();
String userId = (String) request.getAttribute(\"userId\"); Order order = orderService.getById(id); evaluate.setCreateBy(userId); evaluate.setDeptPoint(deptPoint); evaluate.setWorkerPoint(workerPoint); evaluate.setDetail(opinion);
evaluate.setEnvironmentPoint(servicePoint); evaluate.setOrderId(id);
evaluate.setGoodId(order.getGoodId()); evaluateService.save(evaluate); order.setIsComment(true); orderService.updateById(order);
通过请求获取用户id,然后调用orderService的getById方法根据订单id查询订单信息,将评价实体中的参数进行赋值,然后调用服务层的save方法将评价数据先保存到内存中,然后将订单的是否评价表示设置为true,调用orderService的updateById方法将修改后的订单数据保存到数据库中。
69
广东东软学院本科毕业设计(论文)
(2)查看对应商品的评价 关键代码描述
IPage evaluateIPage = new Page<>(); evaluateIPage.setCurrent(page); evaluateIPage.setSize(8);evaluateIPage = evaluateService.page(evaluateIPage, new QueryWrapper().eq(\"good_id\", id));evaluateIPage.getRecords().forEach(evaluate -> {
evaluate.setWechatUser(wechatUserService.getById(evaluate.getCreateBy()));
});
调用evaluateService的page方法根据商品id对评论列表进行查询,然后循环该评论列表,将评论的微信用户信息调用wechatUserService的getById方法根据创建者查询出来。
5.4.5服务中心
(1)获取服务列表 关键代码描述
IPage goodPage = new Page<>(); goodPage.setCurrent(page); goodPage.setSize(5);QueryWrapper queryWrapper = new QueryWrapper<>(); if (StringUtils.isNotEmpty(categoryId)) { queryWrapper.eq(\"category_id\", categoryId); }if (StringUtils.isNotEmpty(deptId)) { queryWrapper.eq(\"dept_id\", deptId); }
goodPage = goodService.page(goodPage, queryWrapper);
创建一个泛型为Good的IPage实体,设置其大小为5,然后分别判断categoryId和deptId是否为空,不为空则拼接到查询条件中去,再调用goodService的page方法进行分页查询。
goodPage.getRecords().forEach(good -> {
good.setEnvironmentPoint(evaluateService.environmentPoint(good.getId()));
SysDept dept = sysDeptService.getById(good.getDeptId()); if (!StringUtils.equals(dept.getParentId(), \"0\")) { dept = sysDeptService.getById(dept.getParentId()); }
good.setDept(dept);
对查询出来的列表进行遍历,调用evaluateService的environmentPoint方法将对
70
广东东软学院本科毕业设计(论文)
应服务的评论查询出来,再调用sysDeptService的getById方法将对应的公司信息查询出来,然后赋值到服务实体中去。
(2)通过id获取商品 关键代码描述
if (StringUtils.isNotEmpty(token)) {
String userId = JWT.decode(token).getKeyId(); love = goodLoveService.getOne(new
QueryWrapper().eq(\"user_id\", userId).eq(\"good_id\", id)) != null;判断请求头中的token是否为空,如果不为空,则解析token中的userId,然后调用goodLoveService的getOne方法查询对应的用户id和服务id是否再数据库中,如果在则将收藏标示设置为true。
boolean isAccess = goodAccessService.getOne(new
QueryWrapper().eq(\"user_id\", userId).eq(\"good_id\", id)) == null;if (isAccess) {
GoodAccess goodAccess = new GoodAccess(); goodAccess.setGoodId(id); goodAccess.setUserId(userId); goodAccessService.save(goodAccess); } }
调用goodAccessService的getOne方法,通过userId和商品id查询足迹是否存在,不存在则调用goodAccessService的save方法将用户id和对于的商品id保存为足迹,然后保存到数据库中。
Good good = goodService.getById(id); if (good != null) {
good.setSalesCount(orderService.count(new QueryWrapper().eq(\"good_id\", id)));good.setAccessCount(goodAccessService.count(new QueryWrapper().eq(\"good_id\", id)));good.setCommentsCount(evaluateService.count(new QueryWrapper().eq(\"good_id\", id)));good.setEnvironmentPoint(evaluateService.environmentPoint(id)); good.setWorkerPoint(evaluateService.workerPoint(id)); good.setDeptPoint(evaluateService.deptPoint(id));
SysDept dept = sysDeptService.getById(good.getDeptId()); List evaluateList = evaluateService.list(new QueryWrapper().eq(\"good_id\", id)); evaluateList.forEach(evaluate -> {71
广东东软学院本科毕业设计(论文)
evaluate.setWechatUser(wechatUserService.getById(evaluate.getCreateBy()));
});
return R.ok().put(\"goods\", good).put(\"dept\", dept).put(\"evaluateList\", evaluateList).put(\"love\", love); }
调用goodService的getById方法根据id查询对应id的服务信息,如果商品不为空,则调用orderService的count方法查询对应的商品销量,调用goodAccessService的count方法查询对应商品的浏览数量,调用evaluateService的count方法查询对应商品的评论数,调用evaluateService的environmentPoint方法查询对应商品的平均环境评分,调用evaluateService的workerPoint方法查询对应商品的员工平均评分,调用evaluateService的deptPoint方法查询对应商品的平均公司评分,调用sysDeptService的getById方法查询对应的公司信息,调用evaluateService的list方法查询对应商品的评论列表,对评论列表进行循环,调用wechatUserService的getById方法查询对应评论的用户信息,最后将数据返回。
(3)收藏服务 关键代码描述
String userId = (String) request.getAttribute(\"userId\"); GoodLove goodLove = new GoodLove(); goodLove.setGoodId(id); goodLove.setUserId(userId); goodLoveService.save(goodLove);
调用goodLoveService的save方法将用户id和服务id映射保存到数据库中。 (4)浏览记录 关键代码描述
String userId = (String) request.getAttribute(\"userId\"); IPage goodAccessIPage = new Page<>(); goodAccessIPage.setCurrent(page); goodAccessIPage.setSize(8);goodAccessIPage = goodAccessService.page(goodAccessIPage, new QueryWrapper().eq(\"user_id\", userId));调用goodAccessService的page方法,对用户的浏览列表进行分页查询。
List goodList = Lists.newArrayList();goodAccessIPage.getRecords().forEach(goodAccess -> {
Good good = goodService.getById(goodAccess.getGoodId()); goodList.add(good); });
IPage goodIPage = new Page<>();goodIPage.setSize(goodAccessIPage.getSize());
72
广东东软学院本科毕业设计(论文)
goodIPage.setCurrent(goodAccessIPage.getCurrent()); goodIPage.setPages(goodAccessIPage.getPages()); goodIPage.setTotal(goodAccessIPage.getTotal()); goodIPage.setRecords(goodList);
循环遍历浏览列表中的数据,调用goodService的getById方法查询指定服务id的数据,并保存到goodList中,然后定义一个泛型为Good的IPage实体,将goodList设置到该实体中,并将其他参数从goodAccessIPage复制到goodIPage中。
(5)收藏记录 关键代码描述
IPage goodLoveIPage = new Page<>(); …goodLoveIPage = goodLoveService.page(goodLoveIPage, new QueryWrapper().eq(\"user_id\", userId)); List goodList = Lists.newArrayList(); goodLoveIPage.getRecords().forEach(goodLove -> {Good good = goodService.getById(goodLove.getGoodId()); goodList.add(good); });
IPage goodIPage = new Page<>(); …主要逻辑与浏览记录的相似,主要区分的是这里调用的是goodLoveService的page方法来对用户收藏映射表进行查询。
5.4.6首页
(1)初始化首页 关键代码描述
ListcategoryList
=
categoryService.list(new
QueryWrapper().orderByAsc(\"sort_no\"));List rotationList = rotationService.list(); List articleList = articleService.list(new QueryWrapper().eq(\"status\", 1));调用categoryService的list方法查询分类的列表,调用rotationService的list方法查询轮播图列表,调用articleService的list列表查询文章列表。
5.4.7订单中心
(1)创建订单 关键代码描述
Order order = new Order();
String userId = (String) request.getAttribute(\"userId\"); if (couponId != null) {
coupon = couponService.getById(couponId);
73
广东东软学院本科毕业设计(论文)
}
Good good = goodService.getById(goodId);
Address address = addressService.getById(addressId);
order.setAddress(address.getProvince()+address.getCity()+address.getArea()+address.getDetail()); …
orderService.save(order);
UserCoupon userCoupon = userCouponService.getOne(new QueryWrapper().eq(\"user_id\", userId).eq(\"coupon_id\", couponId));userCoupon.setOrderId(order.getId()); userCoupon.setUseTime(LocalDateTime.now()); userCouponService.updateById(userCoupon);
调用couponService的getById方法查询对应的优惠券信息,调用goodService的getById方法查询指定id的商品信息,调用addressService的getById方法查询地址信息,然后封装一个order实体,调用orderService的save方法将订单数据保存到数据库中,再调用userCouponService的getOne方法查询指定用户id和优惠券id的优惠券信息,修改其使用时间和订单id,调用userCouponService的updateById方法将修改后的优惠券数据保存到数据库中。
(2)个人订单 关键代码描述
QueryWrapper queryWrapper = new QueryWrapper().eq(\"create_by\", userId); if (StringUtils.isNotEmpty(keywords)) { queryWrapper.eq(\"name\", keywords); }if (status != -1) {
queryWrapper.eq(\"status\", status); }
orderPage = orderService.page(orderPage, queryWrapper);
根据keywords和status是否传入,拼装查询条件,然后调用orderService的page方法对订单列表进行分页查询。
(3)取消/支付/确认订单 关键代码描述
String userId = (String) request.getAttribute(\"userId\"); Order order = orderService.getById(id); order.setStatus(4);
order.setLastModifiedBy(userId); orderService.updateById(order);
调用orderService的getById方法查询指定id的订单,然后修改其状态,调用
74
广东东软学院本科毕业设计(论文)
orderService的updateById方法将数据保存到数据库中。
5.5 Vue后台管理端设计
5.5.1 主要设计
import RightPanel from '@/components/RightPanel' export default { name: 'Layout', components: {
RightPanel },
使用组件化设计,通过import语法,将其他的组件引入需要用到的页面中,然后将对于的组件采用export的方式暴露出来。
import { selectAllArticles } from '@/api/article' getList() {
this.listLoading = true
selectAllArticles(this.listQuery).then(response => { this.list = response.articleList this.total = response.total this.listLoading = false })
调用API接口,将api包下的article.js中的方法selectAllArticles引入,在方法中直接调用此方法,就可以请求到后台的API接口,请求成功后,返回的数据在response中,就可以将数据绑定到页面上。
import request from '@/utils/request' export function selectAllArticles(data) { return request({
url: '/article/selectAllArticles', method: 'get', params: data }) }
在article.js中,引入request方法模块,然后定义一个方法,返回一个request请求,对应请求链接写在key为url的value里,请求方法写在method里,请求的参数写在params里,然后就可以调用后端的API接口。
75
广东东软学院本科毕业设计(论文)
5.6微信小程序页面设计
5.6.1主要设计
小程序的每个页面都是一个文件夹,里面包含了4个同名不同类型的文件,*.js存放的是js文件,主要是按钮绑定的操作等等,*.json文件是存放配置的文件,*.wxml是存放的页面代码的文件,*.wxss是存放页面样式的文件,主要开发使用到的是js和wxml文件。
wx.request({
url: app.get_request_url(\"index\", \"index\"), method: \"GET\", data: {},
dataType: \"json\", success: res => { … },
fail: () => { … } });
使用微信官方提供的wx.request模块可以请求后端的API接口,请求成功后可以在success中对返回的数据进行处理,如判断、绑定等操作,请求失败后也可以做出处理。
微信官方提供了很多开发的模块,由于篇幅限制,不会在此一一描述,如有需要,可翻阅微信小程序官方文档,有更多详细的介绍和教程:https://developers.weixin.qq.com/miniprogram/dev/api/。
5.7 本章小结
本章主要是说明家政服务平台的编码,包括各个模块程序的编码和系统业务流程处理的详细流程。
76
广东东软学院本科毕业设计(论文)
第六章 系统的展示
6.1后台管理平台
图 29登录页面
图 30首页
77
广东东软学院本科毕业设计(论文)
图 31服务管理
图 32修改/新增
78
广东东软学院本科毕业设计(论文)
图 33查看服务评论
图 34订单管理
79
广东东软学院本科毕业设计(论文)
图 35分类管理
图 36优惠券管理
80
广东东软学院本科毕业设计(论文)
图 37轮播图管理
图 38文章管理
81
广东东软学院本科毕业设计(论文)
图 39编辑文章
图 40微信用户管理
82
广东东软学院本科毕业设计(论文)
图 41菜单管理
图 42管理员管理
83
广东东软学院本科毕业设计(论文)
图 43角色管理
图 44公司管理
84
广东东软学院本科毕业设计(论文)
图 45日志管理
6.2微信小程序
图 46首页
85
广东东软学院本科毕业设计(论文)
图 47文章
图 48服务
86
广东东软学院本科毕业设计(论文)
图 49筛选
图 50服务详情1
87
广东东软学院本科毕业设计(论文)
图 51服务详情2
图 52我的页面
88
广东东软学院本科毕业设计(论文)
图 53我的订单
图 54订单详情
89
广东东软学院本科毕业设计(论文)
图 55我的足迹
图 56我的优惠券
90
广东东软学院本科毕业设计(论文)
图 57我的地址
图 58新增地址
91
广东东软学院本科毕业设计(论文)
6.3本章小结
本章主要是说明家政服务平台的页面效果。
92
广东东软学院本科毕业设计(论文)
第七章 系统特色和创新
7.1系统特色
在开发技术上,依靠当前流行的SpringBoot快速搭建开发环境,其易用性已被广大的公司所认可,并且使用MyBatis框架进行数据访问,可以快速方便地进行数据的查询操作,开发过程中只需要关注主要的业务,从而提高开发速度。
在管理端使用了近几年非常流行的Vue框架,其支持双向数据绑定,相比起其他前端框架而言无需刷新页面就可以局部更新数据,其次,Vue支持组件化、模块化,每一个组件都可以独立地工作,这样一来可以提高整个开发效率,也可以方便地重复使用。
之所以使用小程序进行开发,是因为当前微信非常的火爆,其已经是我们生活的一部分,微信小程序作为微信的衍生品,可以理解为另外一套操作系统上的APP,相比起传统的APP开发起来比较快捷,也可以借助微信这个平台简化用户的操作,提高使用的体验。
因此,本次的设计就是以微信小程序为出发,使用SpringBoot快速搭建后台API程序,使用前后端分离的模式进行交互,并使用Vue进行搭建后台管理系统,对整体系统进行维护,构成一套完整的、前后端分离的、高可用性的系统,给用户带来优质的操作体验。此外,由于完成了整套的前后端分离,部署到服务器也是轻而易举的,使用容器化部署,也可以轻松地应对高并发的情况。
7.2系统创新
家政服务平台分为微信小程序移动端和电脑管理端,前台小程序,后台管理平台,不同用户使用不通的模块进行操作,提供基础和拓展功能。结合用户、家政公司、第三方三个角度进行日常的运营管理,第三方可以及时发现家政公司的服务缺陷,接受用户的投诉并做出处理,严格规范家政公司的服务,提高家政公司的服务水平,给用户打造一个方便快捷、安全信赖的家政服务平台;而符合规范的家政服务公司则可以通过此平台接到更多的订单;用户则可以放心地在平台上挑选所需要的家政服务,从而达到一个用户、公司、第三方一个三赢的局面。
93
广东东软学院本科毕业设计(论文)
第八章 总结
这次的毕业设计是四年来我在大学里所学到的知识的综合,也是四年来我遇到的最大的挑战。通过这次毕业设计,我使用了目前最流行的几个大框架来进行系统设计,这也是对我以前所学知识的检验,如果没有以前长期的学习和积累,完成这样的项目是不可能的。通过本次毕业设计,我也熟悉了系统设计流程和整体设计架构,这对我以后步入社会有很大的帮助。
本次设计,从选题到需求分析,再到详细的系统设计和代码开发,由我独立完成。整体设计过程约4个月,从系统的总体设计到详细设计,从小程序开发到vue开发再到SpringBoot的开发。我主要使用的软件是Idea、 VSCode、微信小程序开发工具、 Navicat等等,使用的框架在目前的市场上也被广泛采用,比如 SpringBoot、MyBatis、Vue、Redis、MySQL等等。这是我第一次在使用 Java语言完整开发之前和之后进行端分离项目,在系统的开发过程中,在系统中学习的许多课程被系统的插入,如数据库设计、软件工程、 JSP开发、计算机系统基础等,这些课程中所学到的知识将会在这个项目中体现出来,而且对我完成本次毕业设计也有很大的帮助。
感谢大学四年来辛勤工作的任课教师,也感谢毕业设计这一次的指导老师和朋友们,在他们的帮助下,我能够顺利的完成本次毕业设计。同时也希望借此可以在毕业设计的过程中不断的成长。
94
广东东软学院本科毕业设计(论文)
参 考 文 献
[1] 中国政府网.国务院办公厅关于促进家政服务业提质扩容的意见[EB/OL],http://www.gov.cn/zhengce/content/2019-06/26/content_5403340.htm,2019-06;
[2] 新华网.临时加价、服务水平参差不齐、退款难……互联网家政鱼龙混杂盼规范[EB/OL],http://www.xinhuanet.com/2018-08/01/c_1123208361.htm,2018-08;
[3] 贾晓芳、沈泽刚。 Java Web应用开发中的常见乱码形式及解决方法[J]. 软件导刊,2017,(04),214-216;
[4] 苏航.接口的意义及在Java Web三层架构中的作用分析[J],西部皮革,2016,(24),19;
[5] 朱柏锡.SQL数据库注入攻击及Java Web应用过程中防御措施分析[J].,网络安全技术与应用,2016,(05),63-64;
[6] 詹少威.解析Java Web后端开发模式的演变[J],中国新通信,2014,(14),7;
[7] 周春容、肖祥林、杨桦.Java Web通用用户权限管理框架设计与实现[J], 计算机与现代化,2014,(03),177-179+196;
[6] 贺伟、李凤. 基于项目驱动式教学的《Java面向对象程序设计》课程实践[J],计算机产品与流通,2019(01),263-264;
[9] 唐权. SSM框架在JavaEE教学中的应用与实践[J],福建电脑,2017,33(12),93-94+61;
[10] 杨开振.深入浅出SpringBoot2.x[M],人民邮电出版社,北京,201808,20。
95