@TOC
ssm304社区生鲜电商平台+vue
绪论
1.1研究背景
社会的进步,带来的就是城市化人数的急剧增长,随着人数的不断增加,社区生鲜电商平台工作越来越艰巨,传统的社区生鲜电商平台模式面对大量的用户信息、社区生鲜信息等,信息的及时更新等弊端凸显,传统的社区生鲜管理过度的依靠人力资源的记录,对于庞大的用户信息及社区生鲜信息,显然只依靠人力,很难准确的处理好大量的数据,传统的管理模式不仅效率低,出错率高,而且难查询社区生鲜的实时信息,对于社区生鲜带来了诸多不便,因此,传统的社区生鲜管理模式已经远远无法满足当社区的发展需求,我们急需对社区生鲜体系进行变革。
城市化进程的迅猛发展,社区规模不断扩大,社区可调配资源也明显增加。我们经过对社区生鲜信息进行调查,发现了随着社区人数的不断扩大,社区生鲜工作也越来越繁重和琐碎,容易出错,数据繁多,因此需要对社区生鲜管理体系进行及时改善,来提高社区生鲜管理效率,从而也可避免因管理体系的不完善而导致管理漏洞,使得社区生鲜电商平台的运行和管理显得尤为重要。
1.2研究现状
随着网络高速发展,全球的网络科技增长速度明显,后劲十足,网络的普及率明显的很大提高。截止今年的六月份,不完全统计,光中国的网民数量就已经达到了7.54亿,超过了总人口的一半以上,占全球网民总数的五分之一。而利用计算机进行传统信息管理也成为一种新的朝流,逐渐替代传统的管理方式。互联网的发展,无线网络的覆盖也达到了百分之八九十。所以未来网络还会更大的改变这个世界,创新整个社会。
随着约翰.冯.诺依曼创建出第一台计算机,成为20世纪最先进的科学技术发明之一开始,人类进入了一个新的世界,开始了一个互联网的年代。第一台计算机占地庞大,处理速度慢,而且只能用于进行科学计算,开机一次都需要浪费很多时间,并且使用必须是专业的人员,都是代码算法,非常的不方便。自从微软公司创建了操作系统开始,人们可以可视化的进行电脑操作,电脑的用途也多样化起来。进而新的互联网出现在了大家的面前,人们可以利用计算机来实现繁琐的计算和信息管理。网络的发展都为社区生鲜电商平台的设计与实现提供了良好的基础,在网络和计算机的大力发展下,社区生鲜电商平台开始出现,社区生鲜电商平台是借助网络和计算机的无纸媒体,既节省了纸张的浪费,又保证了社区生鲜电商平台的实时性,满足了社区社区生鲜电商平台的需求。
1.3研究内容
本社区生鲜电商平台采用SSM框架和MYSQL数据库技术开发,实现了房用户社区生鲜的科学化管理,大大的提高了管理效率,使得用户社区生鲜相关信息的管理系统化、高效化、科学化。通过对系统的需求分析,设计出了本社区生鲜电商平台,主要的研究内容有:
(1)在使用中了解系统的工作流程,撰写关于系统的需求分析。
(2)通过对系统的需求分析及可行性进行分析。
(3)系统的流程分析,操作流程、开发流程等。
(4)系统实现编写本系统的开发技术文档。
(5)编写代码。
(6)对本社区生鲜电商平台进行系统测试。
2 相关技术简介
2.1 B/S结构
B/S最大的优点就是可以在任何地方进行操作而不用安装任何专门的软件。只要有一台能上网的电脑就能使用,客户端零维护。系统的扩展非常容易。
B/S架构不需要在任何客户端来进行程序的部署,使用这样的程序结构来使用开发好的系统是利用浏览器来使用的,就是把开发好的程序配置到一台远程服务器上,在任何可以访问这台服务器的客户端电脑上都可以对程序进行操作和使用,这样的方式给使用者带来了极大的便捷。这样的结构提高了程序的运行效率,打破了地域的限制,降低了程序的使用成本。
我们开发的是一套社区生鲜电商平台,我们可以把社区生鲜电商平台系统配置在远程的服务器上,在得到访问权限之后,只要能够上网就可以使用和访问该系统并进行相关的操作,这样的一种先进模式我们之后只需要对服务器上的程序进行维护即可保证程序的正常使用,大大的提高了工作效率,降低了维护的成本。
2.2 MYSQL数据库
本次开发的社区生鲜电商平台使用的数据库是MYSQL数据库,这个数据库是国外微软公司提出来的具有一定扩展性以及性能高的数据库。MySQL是一个开源和多线程的关系管理数据库系统,MySQL是开放源代码的数据库,具有跨平台性,虽然功能未必强大,导致很多人都了解这个数据库的基本应用,在数据库中,总共建立了10几个表,这里面每个表都是相对应的,都各自有各自的联系,数据库意义重大,如果没有数据库的链接,就没办法运行程序,这显然可以看见数据库与程序的重要性,是紧密相连接的。
MYSQL特点如下:
(1)C和C ++中使用和测试,以确保源代码的编译器的便携性和灵活性。
(2)支持多种操作系统AIX的,FreeBSD下,HP-UX,Linux和Mac OS中,Novell公司的Netware,OpenBSD系统,OS/2裹时,Solaris,Windows等。
(3)提供了用于不同的编程语言的API。
(4)以及使用的CPU资源来支持多线程。
(5)算法优化查询SQL,切实提高搜索速度。
(6)网络上的客户端和服务器可以用来编程任何独立的编程环境,也有中国,GB2312,BIG5,日文写作,一般基金,用于支持多国语言,并且可以嵌入在数据表和其他软件shift_jis访问柱可以用作的名称。
(7)TCP / IP,ODBC和JDBC数据库,并提供连接到其他
(8)管理工具的管理,控制和优化数据库的操作
(9)可以数以千万计的记录在一个大的数据库
2.3 Java简介
本次系统开发采用的是面向对象的Java作为软件编程语言,Java表面上很像C++,但是Java仅仅是继承了C++的某些优点,程序员很少使用的C++语言的特征在Java设计中去掉了。Java编程语言并没有什么结构,它把数组跟串都当成对象来处理,这样就免去了指针,并且Java编程语言还省去了预处理程序。Java编程语言能够极好的体现出面向对象的相关理论知识,程序开发者在进行程序开发中能够省去许多不必要的操作,节约大把时间,能够预留出更多的时间和精力来研究程序,通常Java在直接和间接引用对象上面能够实现自动处理的功能,它可以自动收集那些无用单元,极好地避免了关于存储管理的问题。当一个Java源文件在编译和运行时,这就需要写字板、附件里面的记事本等编辑文字软件,或者利用专门的程序开发平台(MyEclipse)来定义各种类,通过调用类来进行系统资源的访问操作,把Java源文件编译成中间码(二进制)存放在class文件里面,最后利用Java虚拟机执行调用class文件来满足Java API的调用。随着软件开发技术的日趋成熟,Java语言能够让网络应用高效快速,更接近实际,目前它是IT产业应用得最多的技术。目前市场上的编程工具有很多,下面就简单介绍几款编程工具供大家简单了解。
编程工具一:Eclipse,它是源代码免费开放的可扩展性强的一款开发软件
编程工具二:NetBeans同样是源代码免费开放,它能够满足和适应多种Web应用和客户机。在Java集成开发环境上能够投入使用
编程工具三:IntelliJ IDEA能够自动提示和分析源代码
编程工具四:MyEclipse这款商业化软件在Java集成开发环境上使用得比较多
编程工具五:EditPlus能够直接运行Java程序,前提是编译器和解释器能够正常运行。
2.4 SSM框架简介
SSM框架,是Spring+Spring MVC+MyBatis的缩写,这个是继SSH之后,目前比较主流的Java EE企业级框架,适用于搭建各种大型的企业级应用系统。
1.Spring简介
Spring是一个开源框架,Spring是于2003年兴起的一个轻量级的Java开发框架,由Rod Johnson在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。简单来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。
A.控制反转(IOC)是什么呢?
IOC:控制反转也叫依赖注入。利用了工厂模式将对象交给容器管理,你只需要在spring配置文件总配置相应的bean,以及设置相关的属性,让spring容器来生成类的实例对象以及管理对象。在spring容器启动的时候,spring会把你在配置文件中配置的bean都初始化好,然后在你需要调用的时候,就把它已经初始化好的那些bean分配给你需要调用这些bean的类(假设这个类名是A),分配的方法就是调用A的setter方法来注入,而不需要你在A里面new这些bean了。
B.面向切面(AOP)又是什么呢?
首先,需要说明的一点,AOP只是Spring的特性,它就像OOP一样是一种编程思想,并不是某一种技术,AOP可以说是对OOP的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。将程序中的交叉业务逻辑(比如安全,日志,事务等),封装成一个切面,然后注入到目标对象(具体业务逻辑)中去。
实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
2.Spring MVC简介
Spring MVC属于Spring Framework的后续产品,已经融合在Spring Web Flow里面,它原生支持的Spring特性,让开发变得非常简单规范。Spring MVC分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。
3.MyBatis简介
MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。MyBatis是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。可以这么理解,MyBatis是一个用来帮你管理数据增删改查的框架。
3 系统分析
3.1 可行性分析
可行性分析目的是根据所开发系统的用户需求,明确研究方向和目标,通过可行性分析确定系统的框架和功能模块。
3.1.1 技术可行性
大学期间我自己利用空闲时间学习了java编程语言,通过图书馆查阅资料以及利用社区生鲜电脑上网了解了MyEclipse开发平台,熟悉并研究了SSM框架开发技术,对web服务器Tomcat有了比较系统的认识,数据库像mysql和sqlserver自己在平时作业中也有一定的接触,基本的操作流程还是很熟悉。对于开发软件基础知识自身还是具备,所以技术上面还是不用担心。
3.1.2 经济可行性
这次我打算开发的系统,源代码我已经在网上找好了,利用360安全浏览器就可以下载,不需要收费,加上我自己上学期间已经配置好的一台笔记本电脑就能进行开发,目前我已经在准备在自己电脑上安装MyEclipse开发平台和mysql数据库等开发软件。这些软件也是自己在网上下载的,不用花钱,这样看来开发社区生鲜电商平台经济上不需要太多支出,开发出来的系统能解决社区生鲜电商平台的许多难题,开发这样的软件很有必要。
3.1.3 操作可行性
在设计之初,我在网上参考了许多社区生鲜电商平台的界面布局设计,发现该系统界面展示比较简单,功能罗列齐全,操作流程简单明了,系统用户不用担心不会操作,系统各个功能模块都会有相应的提示,一看就明白,实在不知道的话,稍微指点就能上手,上手速度很快,时间不会耽误太多。
3.1.3 法律可行性
本社区生鲜电商平台开发的所有技术资料都为合法,知识产权问题不会发生在开发过程中,而且没有抄袭其他相关系统,不会有侵犯版权的问题。另外,社区生鲜电商平台设计与开发所采用的操作和工作方式符合工作人员的日常习惯,而且操作方便灵活,便于管理。所以在开发过程中不会涉及法律责任,具有可行性;
综上所述,设计一个社区生鲜电商平台具有效率高,操作简便,降低成本等优点,所以,建立一个社区生鲜电商平台是必要可行的。
3.2 系统性能分析
(1)系统的存储性:因为是社区生鲜电商平台,所以就会在数据库要求上比较严格,信息录入的比较多,而且丰富复杂, 这就需要一个强大的数据库来存放更多的数据和保证数据的时时性。
(2)系统的易学性:系统设计的应该简单易学的,设计的各种功能应该简单操作,不需要努力学习培训,缩短用户熟悉系统的进程。
(3)系统的数据要求:数据应该录入准确,需要更新时,数据应该可以及时的修改,数据还应该有独立保存,不能删除数据的时候会连带着把还需要的数据都删除掉。
(4)系统的可靠性:在实际使用的过程中系统都会涉及到很对需要进行保密的数据,系统出现一些漏洞将这些信息泄露出去将会对用户产生很大的损失,所以在开发系统时我们充分确保了本系统的可靠性。
3.3 系统功能分析
本社区生鲜电商平台主要实现了管理员和用户两个角色。
管理员功能有个人中心,用户管理,员工信息管理,商品分类管理,商品信息管理,订单评价管理,系统管理,订单管理等。
用户功能有个人中心,订单评价管理,我的收藏管理,订单管理等。
系统用例图如图3-1所示。
图3-1 系统用例图
3.4 系统结构分析
3.4.1逻辑结构
社区生鲜电商平台的特点就是利用Browser/Server(B/S)结构,为社区生鲜电商平台提供了一个网络管理平台,让管理人员只要上网就可以实现用户社区生鲜相关信息的管理。
本系统的网络应用原理示意图如图3-2所示:
图3-2系统的网络应用原理示意图
3.4.2 物理结构
系统实现的物理结构如图3-3所示:
图3-3 系统实现的物理结构图
3.5 系统流程分析
3.5.1 操作流程
管理人员要想进入系统进行管理操作,必须登录系统,在登录界面输入登录信息,系统判断登录信息是否正确,正确登录进入管理员功能界面,可进行功能处理,反之登录失败。系统操作的流程图如图3-4所示。
图3-4 操作流程图
3.5.2 添加信息流程
添加信息时,系统采用自动增号的模式,无需管理员填写,管理员在添加信息输入信息,系统会自动对信息数据进行验证,信息合法则验证成功添加至数据库,信息不合法提示添加失败,重新输入信息。添加信息流程如图3-5所示。
图3-5 添加信息流程图
3.5.3 编辑信息流程
管理员在进行编辑信息操作时,首先进入编辑信息界面,管理员输入编辑信息数据,系统进行数据的判断验证,编辑信息合法则编辑成功,信息更新至数据库,信息不合法则修改失败,重新输入。编辑信息流程图如图3-6所示。
图3-6 编辑信息流程图
3.5.4 删除信息流程
管理员选择要删除的信息,单击删除按钮,系统则提示是否确定删除信息,管理员选择确定删除,则删除信息成功,系统数据库将信息进行删除。删除信息流程图如图3-7所示。
图3-7 删除信息流程图
4 系统设计
4.1 系统结构设计
系统结构设计是一个将一个庞大的任务细分为多个小的任务的过程,这些小的任务分段完成后,组合在一起形成一个完整的任务。本社区生鲜电商平台的功能结构设计如图4-1所示。
图4-1系统结构图
4.2 系统顺序图设计
4.2.1登录模块顺序图
登录模块满足了管理人员的权限登录,登录模块顺序图如图4-2所示。
图4-2 登录模块顺序图
4.2.2添加信息模块顺序图
管理人员登录后可进行添加信息操作,添加信息模块的顺序图如图 4-3 所示。
图4-3添加信息模块顺序图
4.3 数据库设计
4.3.1数据库E-R图设计
系统E-R图就是系统的实体关系图,它是用来描述某一组织(单位)的概念模型,提供了表示实体、属性和联系的方法。构成E-R图的基本要素是实体、属性和关系。实体是指客观存在并可相互区分的事特;属性指指实体所具有的每一个特性。
设计概念就是在数据分析的基础上自下而上的对整个系统的数据库概念结构进行设计。从用户的角度对视图进行开发,然后集成视图,最后分析从而取得最后的结果。
本数据库概念模型是为了将现实世界中信息进行抽象而设计的,从而实现信息世界的建模,因此,概念模型是进行数据库设计的重要工具。数据库的概念模型设计可以通过E-R图来现实世界的概念模型,本系统的E-R图表现了系统中各个实体之间的联系。
根据系统的一般要求,通过对整个系统功能、运行过程的分析,形成了反应信息需求的概念数据模型。概念模型可以通过E-R图来表示,根据数据库中的几个表分别绘制数据库的实体图。以下给出本系统中比较重要的实体E-R图。
1、在线客服信息实体属性E-R图如图4-4所示
图4-4 在线客服信息实体属性E-R图
2、商品资讯信息实体属性E-R图如图4-5所示
图4-5商品资讯信息实体属性E-R图
3、商品分类信息实体属性E-R图如图4-6所示
图4-6 商品分类信息实体属性E-R图
4.3.2数据库表设计
数据库的设计通常是以一个已经存在的数据库管理系统为基础的,常用的数据库管理系统有MYSQL,SQL Server, ACCESS等。本社区生鲜电商平台采用了MYSQL数据库管理系统,各个表结构如下:
表4.1 地址
字段 | 类型 | 空 | 默认 | 注释 |
---|---|---|---|---|
id (主键) | bigint(20) | 否 | 主键 | |
addtime | timestamp | 否 | CURRENT_TIMESTAMP | 创建时间 |
userid | bigint(20) | 否 | 用户id | |
address | varchar(200) | 否 | 地址 | |
name | varchar(200) | 否 | 收货人 | |
phone | varchar(200) | 否 | 电话 | |
isdefault | varchar(200) | 否 | 是否默认地址[是/否] |
表4.2 购物车表
字段 | 类型 | 空 | 默认 | 注释 |
---|---|---|---|---|
id (主键) | bigint(20) | 否 | 主键 | |
addtime | timestamp | 否 | CURRENT_TIMESTAMP | 创建时间 |
tablename | varchar(200) | 是 | shangpinxinxi | 商品表名 |
userid | bigint(20) | 否 | 用户id | |
goodid | bigint(20) | 否 | 商品id | |
goodname | varchar(200) | 是 | NULL | 商品名称 |
picture | varchar(200) | 是 | NULL | 图片 |
buynumber | int(11) | 否 | 购买数量 | |
price | float | 是 | NULL | 单价 |
discountprice | float | 是 | NULL | 会员价 |
表4.3 在线客服
字段 | 类型 | 空 | 默认 | 注释 |
---|---|---|---|---|
id (主键) | bigint(20) | 否 | 主键 | |
addtime | timestamp | 否 | CURRENT_TIMESTAMP | 创建时间 |
userid | bigint(20) | 否 | 用户id | |
adminid | bigint(20) | 是 | NULL | 管理员id |
ask | longtext | 是 | NULL | 提问 |
reply | longtext | 是 | NULL | 回复 |
isreply | int(11) | 是 | NULL | 是否回复 |
表4.4 订单评价
字段 | 类型 | 空 | 默认 | 注释 |
---|---|---|---|---|
id (主键) | bigint(20) | 否 | 主键 | |
addtime | timestamp | 否 | CURRENT_TIMESTAMP | 创建时间 |
dingdanbianhao | varchar(200) | 是 | NULL | 订单编号 |
shangpinmingcheng | varchar(200) | 是 | NULL | 商品名称 |
shangpinfenlei | varchar(200) | 是 | NULL | 商品分类 |
pingfen | varchar(200) | 是 | NULL | 评分 |
tianjiatupian | varchar(200) | 是 | NULL | 添加图片 |
pingjianeirong | longtext | 是 | NULL | 评价内容 |
pingjiariqi | date | 是 | NULL | 评价日期 |
yonghuming | varchar(200) | 是 | NULL | 用户名 |
lianxidianhua | varchar(200) | 是 | NULL | 联系电话 |
sfsh | varchar(200) | 是 | 否 | 是否审核 |
shhf | longtext | 是 | NULL | 审核回复 |
表4.5 商品信息评论表
字段 | 类型 | 空 | 默认 | 注释 |
---|---|---|---|---|
id (主键) | bigint(20) | 否 | 主键 | |
addtime | timestamp | 否 | CURRENT_TIMESTAMP | 创建时间 |
refid | bigint(20) | 否 | 关联表id | |
userid | bigint(20) | 否 | 用户id | |
nickname | varchar(200) | 是 | NULL | 用户名 |
content | longtext | 否 | 评论内容 | |
reply | longtext | 是 | NULL | 回复内容 |
表4.6 商品资讯
字段 | 类型 | 空 | 默认 | 注释 |
---|---|---|---|---|
id (主键) | bigint(20) | 否 | 主键 | |
addtime | timestamp | 否 | CURRENT_TIMESTAMP | 创建时间 |
title | varchar(200) | 否 | 标题 | |
introduction | longtext | 是 | NULL | 简介 |
picture | varchar(200) | 否 | 图片 | |
content | longtext | 否 | 内容 |
表4.7 订单
字段 | 类型 | 空 | 默认 | 注释 |
---|---|---|---|---|
id (主键) | bigint(20) | 否 | 主键 | |
addtime | timestamp | 否 | CURRENT_TIMESTAMP | 创建时间 |
orderid | varchar(200) | 否 | 订单编号 | |
tablename | varchar(200) | 是 | shangpinxinxi | 商品表名 |
userid | bigint(20) | 否 | 用户id | |
goodid | bigint(20) | 否 | 商品id | |
goodname | varchar(200) | 是 | NULL | 商品名称 |
picture | varchar(200) | 是 | NULL | 商品图片 |
buynumber | int(11) | 否 | 购买数量 | |
price | float | 否 | 0 | 价格/积分 |
discountprice | float | 是 | 0 | 折扣价格 |
total | float | 否 | 0 | 总价格/总积分 |
discounttotal | float | 是 | 0 | 折扣总价格 |
type | int(11) | 是 | 1 | 支付类型 |
status | varchar(200) | 是 | NULL | 状态 |
address | varchar(200) | 是 | NULL | 地址 |
tel | varchar(200) | 是 | NULL | 电话 |
consignee | varchar(200) | 是 | NULL | 收货人 |
表4.8 商品分类
字段 | 类型 | 空 | 默认 | 注释 |
---|---|---|---|---|
id (主键) | bigint(20) | 否 | 主键 | |
addtime | timestamp | 否 | CURRENT_TIMESTAMP | 创建时间 |
shangpinfenlei | varchar(200) | 否 | 商品分类 |
表4.9 商品信息
字段 | 类型 | 空 | 默认 | 注释 |
---|---|---|---|---|
id (主键) | bigint(20) | 否 | 主键 | |
addtime | timestamp | 否 | CURRENT_TIMESTAMP | 创建时间 |
shangpinmingcheng | varchar(200) | 否 | 商品名称 | |
shangpinfenlei | varchar(200) | 否 | 商品分类 | |
tupian | varchar(200) | 否 | 图片 | |
guige | varchar(200) | 是 | NULL | 规格 |
baozhiqi | varchar(200) | 是 | NULL | 保质期 |
chandi | varchar(200) | 是 | NULL | 产地 |
shangjiashijian | datetime | 是 | NULL | 上架时间 |
shangpinxiangqing | longtext | 是 | NULL | 商品详情 |
clicktime | datetime | 是 | NULL | 最近点击时间 |
clicknum | int(11) | 是 | 0 | 点击次数 |
price | float | 否 | 价格 | |
onelimittimes | int(11) | 是 | -1 | 单限 |
alllimittimes | int(11) | 是 | -1 | 库存 |
表4.10 收藏表
字段 | 类型 | 空 | 默认 | 注释 |
---|---|---|---|---|
id (主键) | bigint(20) | 否 | 主键 | |
addtime | timestamp | 否 | CURRENT_TIMESTAMP | 创建时间 |
userid | bigint(20) | 否 | 用户id | |
refid | bigint(20) | 是 | NULL | 收藏id |
tablename | varchar(200) | 是 | NULL | 表名 |
name | varchar(200) | 否 | 收藏名称 | |
picture | varchar(200) | 否 | 收藏图片 |
表4.11 管理员表
字段 | 类型 | 空 | 默认 | 注释 |
---|---|---|---|---|
id (主键) | bigint(20) | 否 | 主键 | |
username | varchar(100) | 否 | 用户名 | |
password | varchar(100) | 否 | 密码 | |
role | varchar(100) | 是 | 管理员 | 角色 |
addtime | timestamp | 否 | CURRENT_TIMESTAMP | 新增时间 |
表4.12 用户
字段 | 类型 | 空 | 默认 | 注释 |
---|---|---|---|---|
id (主键) | bigint(20) | 否 | 主键 | |
addtime | timestamp | 否 | CURRENT_TIMESTAMP | 创建时间 |
yonghuming | varchar(200) | 否 | 用户名 | |
mima | varchar(200) | 否 | 密码 | |
xingming | varchar(200) | 是 | NULL | 姓名 |
touxiang | varchar(200) | 是 | NULL | 头像 |
xingbie | varchar(200) | 是 | NULL | 性别 |
lianxidianhua | varchar(200) | 是 | NULL | 联系电话 |
money | float | 是 | 0 | 余额 |
表4.13 员工信息
字段 | 类型 | 空 | 默认 | 注释 |
---|---|---|---|---|
id (主键) | bigint(20) | 否 | 主键 | |
addtime | timestamp | 否 | CURRENT_TIMESTAMP | 创建时间 |
yuangonggonghao | varchar(200) | 否 | 员工工号 | |
yuangongxingming | varchar(200) | 是 | NULL | 员工姓名 |
xingbie | varchar(200) | 是 | NULL | 性别 |
fuzepinlei | varchar(200) | 是 | NULL | 负责品类 |
lianxidianhua | varchar(200) | 是 | NULL | 联系电话 |
yuangongyouxiang | varchar(200) | 是 | NULL | 员工邮箱 |
shenfenzheng | varchar(200) | 是 | NULL | 身份证 |
5 系统实现
5.1 用户管理
管理员可以对用户管理,可以添加,修改,删除以及查询操作。管理员界面展示如图5-1所示。
图5-1用户管理面图
5.2 员工信息管理
管理员在员工信息管理界面可查看所有员工信息,对已有员工信息可进行编辑和删除操作,同时也可新增员工信息,员工管理界面展示如图5-2所示
图5-2 员工管理界面图
5.3 商品信息管理
管理员可管理商品信息,可以对商品进行添加,修改,删除查询操作。界面如图5-3所示
图5-3商品信息管理界面图
5.4 订单评价管理
管理员能够对订单评价信息进行查看,删除,以及审核操作。订单评价信息界面展示如图5-4所示。
图5-4 订单评价界面图
5.5 系统首页
用户可以在首页查看各种商品,首页展示如图5-8所示。
图5-5 首页界面图
5.6商品下单
用户登录后,可以在商品界面进行购买,并且可以下单操作,下单界面展示如图5-6所示。
图5-6 用户下单界面图
5.7用户订单
用户登录后,可以在后台管理里面查看订单信息,对订单的各种状态都可以查看,用户订单信息界面展示如图5-7所示。
图5-7 用户订单界面图
CartServiceImpl.java
package com.service.impl;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.List;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.utils.PageUtils;
import com.utils.Query;
import com.dao.CartDao;
import com.entity.CartEntity;
import com.service.CartService;
import com.entity.vo.CartVO;
import com.entity.view.CartView;
@Service("cartService")
public class CartServiceImpl extends ServiceImpl<CartDao, CartEntity> implements CartService {
@Override
public PageUtils queryPage(Map<String, Object> params) {
Page<CartEntity> page = this.selectPage(
new Query<CartEntity>(params).getPage(),
new EntityWrapper<CartEntity>()
);
return new PageUtils(page);
}
@Override
public PageUtils queryPage(Map<String, Object> params, Wrapper<CartEntity> wrapper) {
Page<CartView> page =new Query<CartView>(params).getPage();
page.setRecords(baseMapper.selectListView(page,wrapper));
PageUtils pageUtil = new PageUtils(page);
return pageUtil;
}
@Override
public List<CartVO> selectListVO(Wrapper<CartEntity> wrapper) {
return baseMapper.selectListVO(wrapper);
}
@Override
public CartVO selectVO(Wrapper<CartEntity> wrapper) {
return baseMapper.selectVO(wrapper);
}
@Override
public List<CartView> selectListView(Wrapper<CartEntity> wrapper) {
return baseMapper.selectListView(wrapper);
}
@Override
public CartView selectView(Wrapper<CartEntity> wrapper) {
return baseMapper.selectView(wrapper);
}
}
CommonUtil.java
package com.utils;
import java.util.Random;
public class CommonUtil {
/**
* 获取随机字符串
*
* @param num
* @return
*/
public static String getRandomString(Integer num) {
String base = "abcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < num; i++) {
int number = random.nextInt(base.length());
sb.append(base.charAt(number));
}
return sb.toString();
}
}
ShangpinfenleiServiceImpl.java
package com.service.impl;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.List;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.utils.PageUtils;
import com.utils.Query;
import com.dao.ShangpinfenleiDao;
import com.entity.ShangpinfenleiEntity;
import com.service.ShangpinfenleiService;
import com.entity.vo.ShangpinfenleiVO;
import com.entity.view.ShangpinfenleiView;
@Service("shangpinfenleiService")
public class ShangpinfenleiServiceImpl extends ServiceImpl<ShangpinfenleiDao, ShangpinfenleiEntity> implements ShangpinfenleiService {
@Override
public PageUtils queryPage(Map<String, Object> params) {
Page<ShangpinfenleiEntity> page = this.selectPage(
new Query<ShangpinfenleiEntity>(params).getPage(),
new EntityWrapper<ShangpinfenleiEntity>()
);
return new PageUtils(page);
}
@Override
public PageUtils queryPage(Map<String, Object> params, Wrapper<ShangpinfenleiEntity> wrapper) {
Page<ShangpinfenleiView> page =new Query<ShangpinfenleiView>(params).getPage();
page.setRecords(baseMapper.selectListView(page,wrapper));
PageUtils pageUtil = new PageUtils(page);
return pageUtil;
}
@Override
public List<ShangpinfenleiVO> selectListVO(Wrapper<ShangpinfenleiEntity> wrapper) {
return baseMapper.selectListVO(wrapper);
}
@Override
public ShangpinfenleiVO selectVO(Wrapper<ShangpinfenleiEntity> wrapper) {
return baseMapper.selectVO(wrapper);
}
@Override
public List<ShangpinfenleiView> selectListView(Wrapper<ShangpinfenleiEntity> wrapper) {
return baseMapper.selectListView(wrapper);
}
@Override
public ShangpinfenleiView selectView(Wrapper<ShangpinfenleiEntity> wrapper) {
return baseMapper.selectView(wrapper);
}
}
login.vue
<template>
<div>
<div class="container loginIn" style="backgroundImage: url(http://codegen.caihongy.cn/20210308/ebad2b2b09fe4a12add1ed68d1ede24f.jpg)">
<div :class="2 == 1 ? 'left' : 2 == 2 ? 'left center' : 'left right'" style="backgroundColor: rgba(255, 255, 255, 0.2)">
<el-form class="login-form" label-position="left" :label-width="2 == 3 ? '56px' : '0px'">
<div class="title-container"><h3 class="title" style="color: rgba(0, 150, 136, 1)">社区生鲜电商平台登录</h3></div>
<el-form-item :label="2 == 3 ? '用户名' : ''" :class="'style'+2">
<span v-if="2 != 3" class="svg-container" style="color:rgba(0, 150, 136, 1);line-height:44px"><svg-icon icon-class="user" /></span>
<el-input placeholder="请输入用户名" name="username" type="text" v-model="rulesForm.username" />
</el-form-item>
<el-form-item :label="2 == 3 ? '密码' : ''" :class="'style'+2">
<span v-if="2 != 3" class="svg-container" style="color:rgba(0, 150, 136, 1);line-height:44px"><svg-icon icon-class="password" /></span>
<el-input placeholder="请输入密码" name="password" type="password" v-model="rulesForm.password" />
</el-form-item>
<el-form-item v-if="0 == '1'" class="code" :label="2 == 3 ? '验证码' : ''" :class="'style'+2">
<span v-if="2 != 3" class="svg-container" style="color:rgba(0, 150, 136, 1);line-height:44px"><svg-icon icon-class="code" /></span>
<el-input placeholder="请输入验证码" name="code" type="text" v-model="rulesForm.code" />
<div class="getCodeBt" @click="getRandCode(4)" style="height:44px;line-height:44px">
<span v-for="(item, index) in codes" :key="index" :style="{color:item.color,transform:item.rotate,fontSize:item.size}">{{ item.num }}</span>
</div>
</el-form-item>
<el-form-item label="角色" prop="loginInRole" class="role">
<el-radio
v-for="item in menus"
v-if="item.hasBackLogin=='是'"
v-bind:key="item.roleName"
v-model="rulesForm.role"
:label="item.roleName"
>{{item.roleName}}</el-radio>
</el-form-item>
<el-button type="primary" @click="login()" class="loginInBt" style="padding:0;font-size:16px;border-radius:4px;height:44px;line-height:44px;width:100%;backgroundColor:rgba(0, 150, 136, 1); borderColor:rgba(0, 150, 136, 1); color:rgba(255, 255, 255, 1)">{{'1' == '1' ? '登录' : 'login'}}</el-button>
<el-form-item class="setting">
<!-- <div style="color:rgba(0, 150, 136, 1)" class="reset">修改密码</div> -->
</el-form-item>
</el-form>
</div>
</div>
</div>
</template>
<script>
import menu from "@/utils/menu";
export default {
data() {
return {
rulesForm: {
username: "",
password: "",
role: "",
code: '',
},
menus: [],
tableName: "",
codes: [{
num: 1,
color: '#000',
rotate: '10deg',
size: '16px'
},{
num: 2,
color: '#000',
rotate: '10deg',
size: '16px'
},{
num: 3,
color: '#000',
rotate: '10deg',
size: '16px'
},{
num: 4,
color: '#000',
rotate: '10deg',
size: '16px'
}],
};
},
mounted() {
let menus = menu.list();
this.menus = menus;
},
created() {
this.setInputColor()
this.getRandCode()
},
methods: {
setInputColor(){
this.$nextTick(()=>{
document.querySelectorAll('.loginIn .el-input__inner').forEach(el=>{
el.style.backgroundColor = "rgba(247, 247, 247, 1)"
el.style.color = "rgba(51, 51, 51, 1)"
el.style.height = "44px"
el.style.lineHeight = "44px"
el.style.borderRadius = "4px"
})
document.querySelectorAll('.loginIn .style3 .el-form-item__label').forEach(el=>{
el.style.height = "44px"
el.style.lineHeight = "44px"
})
document.querySelectorAll('.loginIn .el-form-item__label').forEach(el=>{
el.style.color = "rgba(0, 150, 136, 1)"
})
setTimeout(()=>{
document.querySelectorAll('.loginIn .role .el-radio__label').forEach(el=>{
el.style.color = "rgba(0, 150, 136, 1)"
})
},350)
})
},
register(tableName){
this.$storage.set("loginTable", tableName);
this.$router.push({path:'/register'})
},
// 登陆
login() {
let code = ''
for(let i in this.codes) {
code += this.codes[i].num
}
if ('0' == '1' && !this.rulesForm.code) {
this.$message.error("请输入验证码");
return;
}
if ('0' == '1' && this.rulesForm.code.toLowerCase() != code.toLowerCase()) {
this.$message.error("验证码输入有误");
this.getRandCode()
return;
}
if (!this.rulesForm.username) {
this.$message.error("请输入用户名");
return;
}
if (!this.rulesForm.password) {
this.$message.error("请输入密码");
return;
}
if (!this.rulesForm.role) {
this.$message.error("请选择角色");
return;
}
let menus = this.menus;
for (let i = 0; i < menus.length; i++) {
if (menus[i].roleName == this.rulesForm.role) {
this.tableName = menus[i].tableName;
}
}
this.$http({
url: `${this.tableName}/login?username=${this.rulesForm.username}&password=${this.rulesForm.password}`,
method: "post"
}).then(({ data }) => {
if (data && data.code === 0) {
this.$storage.set("Token", data.token);
this.$storage.set("role", this.rulesForm.role);
this.$storage.set("sessionTable", this.tableName);
this.$storage.set("adminName", this.rulesForm.username);
this.$router.replace({ path: "/index/" });
} else {
this.$message.error(data.msg);
}
});
},
getRandCode(len = 4){
this.randomString(len)
},
randomString(len = 4) {
let chars = [
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",
"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
"w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",
"H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",
"S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",
"3", "4", "5", "6", "7", "8", "9"
]
let colors = ["0", "1", "2","3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"]
let sizes = ['14', '15', '16', '17', '18']
let output = [];
for (let i = 0; i < len; i++) {
// 随机验证码
let key = Math.floor(Math.random()*chars.length)
this.codes[i].num = chars[key]
// 随机验证码颜色
let code = '#'
for (let j = 0; j < 6; j++) {
let key = Math.floor(Math.random()*colors.length)
code += colors[key]
}
this.codes[i].color = code
// 随机验证码方向
let rotate = Math.floor(Math.random()*60)
let plus = Math.floor(Math.random()*2)
if(plus == 1) rotate = '-'+rotate
this.codes[i].rotate = 'rotate('+rotate+'deg)'
// 随机验证码字体大小
let size = Math.floor(Math.random()*sizes.length)
this.codes[i].size = sizes[size]+'px'
}
},
}
};
</script>
<style lang="scss" scoped>
.loginIn {
min-height: 100vh;
position: relative;
background-repeat: no-repeat;
background-position: center center;
background-size: cover;
.left {
position: absolute;
left: 0;
top: 0;
width: 360px;
height: 100%;
.login-form {
background-color: transparent;
width: 100%;
right: inherit;
padding: 0 12px;
box-sizing: border-box;
display: flex;
justify-content: center;
flex-direction: column;
}
.title-container {
text-align: center;
font-size: 24px;
.title {
margin: 20px 0;
}
}
.el-form-item {
position: relative;
.svg-container {
padding: 6px 5px 6px 15px;
color: #889aa4;
vertical-align: middle;
display: inline-block;
position: absolute;
left: 0;
top: 0;
z-index: 1;
padding: 0;
line-height: 40px;
width: 30px;
text-align: center;
}
.el-input {
display: inline-block;
height: 40px;
width: 100%;
& /deep/ input {
background: transparent;
border: 0px;
-webkit-appearance: none;
padding: 0 15px 0 30px;
color: #fff;
height: 40px;
}
}
}
}
.center {
position: absolute;
left: 50%;
top: 50%;
width: 360px;
transform: translate3d(-50%,-50%,0);
height: 446px;
border-radius: 8px;
}
.right {
position: absolute;
left: inherit;
right: 0;
top: 0;
width: 360px;
height: 100%;
}
.code {
.el-form-item__content {
position: relative;
.getCodeBt {
position: absolute;
right: 0;
top: 0;
line-height: 40px;
width: 100px;
background-color: rgba(51,51,51,0.4);
color: #fff;
text-align: center;
border-radius: 0 4px 4px 0;
height: 40px;
overflow: hidden;
span {
padding: 0 5px;
display: inline-block;
font-size: 16px;
font-weight: 600;
}
}
.el-input {
& /deep/ input {
padding: 0 130px 0 30px;
}
}
}
}
.setting {
& /deep/ .el-form-item__content {
padding: 0 15px;
box-sizing: border-box;
line-height: 32px;
height: 32px;
font-size: 14px;
color: #999;
margin: 0 !important;
.register {
float: left;
width: 50%;
}
.reset {
float: right;
width: 50%;
text-align: right;
}
}
}
.style2 {
padding-left: 30px;
.svg-container {
left: -30px !important;
}
.el-input {
& /deep/ input {
padding: 0 15px !important;
}
}
}
.code.style2, .code.style3 {
.el-input {
& /deep/ input {
padding: 0 115px 0 15px;
}
}
}
.style3 {
& /deep/ .el-form-item__label {
padding-right: 6px;
}
.el-input {
& /deep/ input {
padding: 0 15px !important;
}
}
}
.role {
& /deep/ .el-form-item__label {
width: 56px !important;
}
& /deep/ .el-radio {
margin-right: 12px;
}
}
}
</style>
声明
本博客适用于广泛的学术和教育用途,包括但不限于个人学习、开发设计,产品设计。仅供学习参考,旨在为读者提供深入理解和学术研究的材料。