题目名称 基于SpringBoot的B2C三只松鼠
电商平台
学 院 理工农学院
专业年级 软件工程2018级
填写时间 2021年10月19日
目 录
错误!未找到图形项目表。
基于SpringBoot+Vue的在线三只松鼠在线购物系统
摘 要:三只松鼠在线购物系统是一个网上的购物平台,基于传统的B2C系统的运作模式,提供给商家一个销售商品的平台。
本系统采用现在比较流行的前后端分离的架构模式,使用MVVM架构,使用前后端的代码达到了真实的分离。这个是基于Vue+SpringBoot的Maven聚合工程。在整个系统中数据库采用mysql和redis实现。本系统完成了主要以下几个方面的研究:
解决前后端代码的关联比较大的问题,脱离中了传统的单体架构,提高了系统的可维护性和可扩展性。
实现了管理员模块和用户模块,管理员模块有用户管理,地址管理,订单管理,商品管理,支付功能。然后用户模块有:地址管理,购物车管理,用户自己的信息管理,进行支付。
一个专注于提供质量和价格保证的网上购物平台,你值得拥有和信赖!不满意可以两个星期内随时退货。
关键词:三只松鼠在线购物系统;B/S结构;MVVM架构,Maven聚合工程,sprintBoot技术;tkmapper;MYSQL;REDIS
Three squirrels Online Shopping System based on springboot + Vue
Abstract:the system source code Three squirrels online shopping system is an online shopping platform.
The system adopts the popular architecture mode of front and back-end separation, uses MVVM architecture, and uses the front and back-end code to achieve real separation. This is a maven aggregation project based on Vue + springboot. In the whole system, the database is implemented by MySQL and redis. The system has mainly completed the research in the following aspects:
第一章绪论
当然这样就会出现一个问题,假货的出现。许多不是那么出名的主播也是可以带货的,而且有些也是带的挺不错的,厂家进行发出主播所带的货的时候因为太多,有些厂家可能不小心搞错货物的现象,甚至有些故意用虚假的物品,这些欺骗用户的行为,是我们需要进行深思的,短期内可能会带来些许的效益,但是长久下去欺骗我们的用户,最后会失去他们对你的信任,最终会因小失大,损害的是自己的平台和口碑。
一个专注于提供质量和价格保证的网上购物平台,你值得拥有和信赖!不满意可以两个星期内随时退货。
1.2 研究开发现状分析
目前遇到的问题是业务的不熟悉,和技术的不精通,很有可能导致产品的开发失败。但是网络世界的资源应有尽有,好的资源需要我们耐心去收集和整理。技术方面比如SpringBoot,这个技术官方提供了详细的英文文档,我们可以下载下来自己研究。遇到的问题可以及时请教有这个方面经验的前辈。而且尤其是有些视频资源对我们技术的提升有极其巨大的帮助,比如一些尚硅谷的项目实战的教程,图灵的项目实战的教程各有自己的优点,缺点是现在我们是第一次做这种电商项目,遇到很多困难是无法避免的,技术领域:我遇到了经常的问题就是一些版本冲突问题,和一些无法解释的bug。产品方面,对于需要实现的功能有点没有理解到位,经常需要自己去探索功能的具体运用。
1.3 项目的目标和范围
本系统的目标致力于实现用户进行网上购物,在现实中通过物流收取到货物,并实现支付线上支付的过程。用户通过网页进行商品的浏览,看到喜欢的或者适合自己的商品,自发进行添加购物车,进行订单的支付,并在订单没有进行发货之前进行无条件退货,可以随时和客服人员进行沟通的过程。解决的关键问题用户可以对商品及时的进行反馈,和物流公司那边的系统要进行对接,用户退货需要及时的进行响应,对不良的评论可以进行审核以后再进行发布,用户的访问页面的时候如何在三秒之内做出页面的展示,一些支付的安全问题需要解决,对于不法的攻击需要作出防护,ddos,xxl,sql注入等等攻击,对请求量过大时怎么解决,服务器可以随最大的请求量的测试,系统性能稳定性需要进行多个方面的测试。
1.4 研究内容
本系统主要包含可行性分析,需求分析,数据库设计,UI设计,系统设计,开发实现,测试上线,进行部署的一个简单的软件开发的生命周期。在可行性方面最重要的是需要从技术和业务的层面来考虑这个问题,技术无法实现的就需要解决是具体哪个功能用技术无法实现,是具体用什么技术无法实现。数据库设计:我们经常需要用E-R图和二维表的形式,需要具体到每个字段的,每个类型,每个长度的精准设计,需要对业务特别熟悉。UI设计:需要专门对前台界面进行绘画,进行颜色的调节,进行页面的而已。系统设计:系统先设定需要使用什么框架,需要用到什么技术,绘画出来系统的架构图。最后进行测试,上线前端进行多次的测试,多次版本的迭代。部署:通过购买一些云主机的方式,把项目进行打包,通过linux和虚拟机进行部署上线。
总体的功能模块可以包括:前台的商城首页,前台的商品详情页面,以及管理员的后台界面。设计的功能模块包括用户管理模块,商品管理模块,商品分类管理模块,购物车管理模块,订单管理模块,地址管理模块。
第二章 相关技术
2.1 SpringBoot
使用Maven聚合工程对项目进行的搭建,每个项目又是一个springBoot项目,springBoot是对ssm项目的jar包的整合,有利于简化开发,使用我们的开发更加的快捷和方便,通过注解和一些扩展的功能,使我们的项目更加的可靠。
2.2 Maven
Maven进行相关的jar包的管理的工具,它会对引入的所有的jar包进行管理,然后idea里面需要配置上你的本地自己下载的maven的仓库地址和你的自己民的maven的配置文件。它需要使用国内的镜像,下载速度更加的快。
2.3 tkmapper
相比mybatis而言,它是更加自动化的框架,比mybatis的更加的方便,直接封装了相关的查询,删除,插入和选择性插入的方法。对于单表的操作是非常的方便的,但是使用多表的时候最好使用原生的mybatis的xml文件进行操作,这样可以更加的方便。
2.4 mysql数据库
MySQL数据库服务是一个完全托管的数据库服务,可使用世界上最受欢迎的开源数据库来部署云原生应用程序,很多中小型的公司都在使用mysql作为自己的数据库,因为它一个是完全免费的开源的,然后出现问题有很多比较成熟的解决方法。
2.5 Swagger
Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。 总体目标是使客户端和文件系统作为服务器以同样的速度来更新,使用这个框架,可以使测试的时候更加的方便,快捷。当然也有很多的使用PostMan这个软件进行测试的。
2.6 Vue.js
使用了Vue相关生命周期函数,进行页面的相关的渲染,通过data进行数据的相关的绑定,使用Mounted,created这些个钩子函数进行加载数据,vue简单的语法规则使我们上手挺快的,通过webpack进行jar包的管理
2.7 axios
Axios 是一个基于 promise 的网络请求库,可以用于浏览器和 node.js,Vue也推荐使用这个请求库进行请求。Vue的作者本来想着自己可以开发一个这样的请求库,但是发现和axios都大同小异的,所以就直接推荐使用axios.
2.8 ElemenUI框架
它是目前很火的一个前端框架,和Vue使用进行后台系统的开发。它里面包含了很多好用的一些组件,Form表单,Select选择框,然后一些可以现成使用的菜单栏,这些已经封装好的组件,可以直接使用cdn的引入就可以直接使用,对前端开发都特别的友好,极大的加快了开发的速度和质量,是一款值得推荐的前端框架。
第三章 系统分析
3.1 可行性分析
3.1.1 经济可行性
该系统由虽然由个人开发,但是可以按照市场的形势进行相关的评估,按照现在的程序员行情,具有项目经验的程序员平均薪资表,可以对这个项目的成本按照时间进行评估。初期成本:开发时间半年,加上一些电费的等等其他费用的花费,初期需要分析和项目架构所用的这些时间,使用了目前比较流行的框架,然后后期的维护,总成本大约:60万。预期项目进行上线一个月用户数量可达20000左右,因为项目的UI设计风格简约和美观, 上线一两周即可开始盈利。投资回收率会在项目进行上线以后逐步上升的趋势。
3.1.2 操作可行性
本系统针对拥有一定电脑操作能力的用户开发,你只需和平常上网一样输入一个正确的网址,然后根据页面信息就可以实现正常的操作,并操作简单,用户能自如的利用PC端使用本系统,经过自测本地的环境是没有问题的,因此操作上完全没有问题。
3.1.3 技术可行性
本系统的业务的相关的逻辑处理,使用springboot框架加上tkmapper,后端也有相关数据库的实现mysql+redis,和前端的Vue+Semantic-UI+axios框架,结合上面的分析,完全可以实现本系统的所有的功能模块,可以跨平台进行平稳良好的运行,所以在技术上实现是没有问题的。
3.1.4 运行可行性
可以跨平台进行相关的运行,这个符合java语言的特性。可以产在不同的浏览器进行相关的访问,可以打成jar包部署在Linux的tomcat上面或者Nginx上面稳定运行。
3.2 需求分析
3.2.1 功能需求
用户管理模块:基本的增删改查的操作,和对用户的权限的管理,可以对不合法的用户直接进行锁定。
用户权限管理模块:这个模块可以对用户进行权限的分配,可以增加相关页面的权限和删除权限,可以对权限也进行相关的管理。
购物车模块:对加入的商品进行删除,批量删除的操作,也可以进行订单的添加操作,选中的商品可以进行加入订单,从而生成订单。
商品管理模块:商品图片的展示,上架和下架的操作,商品删除,商品修改,以及商品添加,当然还多了一个商品的复制功能,这样可以节约添加商品的时间,和商品分页的操作。
订单管理模块:可以对订单的状态进行相关的管理,有待评价,待支付,待付款,待删除,待退货等等这些状态的订单,对这些商品状态进行分类的查询的功能。
地址模块:一个用户可以有多个不同的地址,每个用户只可以查询出来自己的地址,管理员可以查询出来所有的地址。
表3-1 用户功能描述
功能名称 功能描述
普通用户 可以查看自己的相关的订单,操作自己的地址,和对商品进行相关的评价。
管理员 对所有的普通用户进行管理,操作商品的管理,商品分类,商品评价管理等等这些权限。
3.2.2 性能需求
系统响应时间:用户进入访问的页面,必须秒内可以访问到这个页面的所有数据,这个是电商系统的一个响应时间规定,本系统由于数据量不大,前期是可以实现的。
信息速率:单位时间内数字通信系统传输的二进制码元个数(即比特数)。1s传输多少个比特,因为现在的通信都用5G了传输这个速率是很大的,传输码元个数大,速率快。
安全性方面:由于还没有进行相关的上线测试和相关的黑客模仿进行攻击本网站,所以安全性能是不可靠的,对安全性能方面本系统是欠缺的。
第四章 系统设计
4.1 系统架构设计
三只松鼠商城是一个需要承受比较在的高并发,需要有高性能的一个电商购物平台,所以对软件和硬件的要求都比较高,需要使用记好合理的架构。如图4-1的系统架构图:
图4-1 系统架构图
4.2 主要功能设计
4.2.1 用户管理功能
用户注册的顺序图4-2所示:
图4-2
4.2.2 商品搜索管理功能
搜索商品的顺序图4-3所示:
图4-3
4.2.3 商品管理功能
商品进行管理顺序图4-4所示:
图4-4
4.2.4 订单管理功能
如图4-5所示:
系统功能过少,且文字描述过少。
图4-4
4.2.5 用户管理功能
对所有的普通用户进行管理,如果登录次数过多,可以对用户进行锁定,然后无法进行登录的操作。如图4-5:
4.3 数据库设计
4.3.1 概念结构设计
如图4-5所示:
图4-5
用户表:用来存储用户登录的信息,存储用户的联系方式,头像,地址等等。
商品表:商品表和商品参数表是1对多的关系。商品表包括商品的上架,下架,包括商品分类id,销量等等。
商品参数表:对商品的各个参数进行描述,包装方式,品牌名,产地,存储方法,食用方式有详细的介绍。
地址表:记录用户购买商品之后的具体地址,里面保存有用户id,和用户表是多对一关系。
商品sku表:sku(stock keeping unit),里面有商品库存,sku图片,折扣力度,销售价格等等。
需对图进行文字描述。
4.3.2 逻辑结构设计
使用具体的二维表结构画出项目的表结构
user表如表4-1所示::
表4-1 user
字段名 数据类型 允许为空 字段说明 默认值 键值
user_id Int(64) No - PRI
username Varchar(32) YES - -
password Varchar(64) YES - -
nickname Varchar(32) YES 昵称 - -
realname Varchar(128) YES 真实姓名 - -
user_img Varchar(255) YES 头像 - -
user_mobile Varchar(32) YES 手机号 - -
user_email Varchar(32) YES 邮箱地址 - -
user_sex Char(1) YES 性别 M(男) or F(女) - -
user_birth date YES 生日 - -
user_regtime datetime YES 注册时间 创建时间 - -
user_modtime datetime YES 更新时间 - -
category表如表4-2所示:
表4-2 category
字段名 数据类型 允许为空 字段说明 默认值 键值
category_id Int(11) No - PRI
category_name Varchar(32) YES 分类名称 - -
category_level Int(11) YES 分类层级 分类得类型,
1:一级大分类
2:二级分类
3:三级小分类 - -
parent_id Int(11) YES 父层级id 父id 上一级依赖的id,1级分类则为0,二级三级分别依赖上一级 - -
category_icon Varchar(32) YES 图标 logo - -
category_slogan Varchar(32) YES 口号 - -
category_pic Varchar(64) YES 分类图 - -
category_bg_color Varchar(50) YES 背景颜色 - -
Index_img表如表4-3所示:
表4-3 index_img
字段名 数据类型 允许为空 字段说明 默认值 键值
img_id Varchar(64) NO 0 - PRI
img_url Varchar(128) YES 图片 图片地址 - -
img_bg_color Varchar(32) YES 背景色 背景颜色 - -
prod_id Varchar(64) YES 商品id 商品id - -
category_id Varchar(64) YES 商品分类id - -
index_type Int(11) YES 轮播图类型,用于判断,可以根据商品id或者分类进行页面跳转,1:商品 2:分类 - -
seq Int(11) YES 轮播图展示顺序,从小到大 - -
status Int(11) YES 是否展示:1表示正常显示,0表示下线 - -
create_time datetime YES 创建时间 - -
update_time datetime YES 更新时间 - -
Order_item表如表4-4所示:
表4-4 order_item
字段名 数据类型 允许为空 字段说明 默认值 键值
item_id Varchar(255) No 订单id - PRI
order_id Varchar(64) YES 0 - -
product_id Varchar(64) YES 商品id - -
product_name Varchar(32) YES 商品名称 - -
product_img Varchar()32 YES 商品图片 - -
sku_id Varchar(128) YES skuid - -
sku_name Varchar(32) YES Sku名称 - -
product_price Decimal(32) YES 商品价格 - -
buy_counts Int(11) YES 购买数量 - -
total_amount Decimal(32,8) YES 商品总金额 - -
basket_date datetime YES 加入购物车时间 - -
buy_time datetime YES 购买时间 - -
is_comment Int(11) YES 评论状态: 0未评价1.已评价 - -
Orders表如表4-5所示:
表4-5 orders表
字段名 数据类型 允许为空 字段说明 默认值 键值
order_id Varchar(60) No 订单项ID - PRI
product_id Int(11) YES 订单ID - -
product_name Varchar(60) YES 商品ID - -
product_img Varchar(60) YES 商品名称 - -
sku_id Int(11) YES 商品图片 - -
sku_name Varchar(66) YES skuID - -
product_price Decimal(24) YES sku名称 - -
buy_counts Int(11) YES 购买数量 - -
total_amount Decimal(24) YES 商品总金额 - -
basket_date Datetime() YES 加入购物车时间 - -
buy_time datetime YES 购买时间 - -
is_comment Int(11) YES 评论状态: 0 未评价 1 已评价 - -
content Text YES 商品内容 - -
product_img表如表4-6所示:
表4-6 product_img
字段名 数据类型 允许为空 字段说明 默认值 键值
img_id Varchar(64) NO 0 - PRI
img_url Varchar(128) YES 图片 图片地址 - -
img_bg_color Varchar(32) YES 背景色 背景颜色 - -
prod_id Varchar(64) YES 商品id 商品id - -
category_id Varchar(64) YES 商品分类id - -
index_type Int(11) YES 轮播图类型,用于判断,可以根据商品id或者分类进行页面跳转,1:商品 2:分类 - -
seq Int(11) YES 轮播图展示顺序,从小到大 - -
status Int(11) YES 是否展示:1表示正常显示,0表示下线 - -
create_time datetime YES 创建时间 - -
update_time datetime YES 更新时间 - -
product_Comments表如表4-7所示:
表4-7 product_comments
字段名 数据类型 允许为空 字段说明 默认值 键值
comm_id varchar No 0 - PRI
product_id varchar YES 商品id - -
product_name varchar YES 商品名称 - -
order_item_id varchar YES 订单项(商品快照)ID 可为空 - -
user_id varchar YES 评论用户id 用户名须脱敏 - -
is_anonymous int YES 是否匿名(1:是,0:否) - -
comm_type int YES 评价类型(1好评,0中评,-1差评) - -
comm_level int YES 评价等级 1:好评 2:中评 3:差评 - -
comm_content varchar YES 评价内容 - -
comm_imgs varchar YES 评价晒图(JSON {img1:url1,img2:url2} ) - -
sepc_name datetime YES 评价时间 可为空 - -
reply_status int YES 是否回复(0:未回复,1:已回复) - -
reply_content varchar No 回复内容 - -
reply_time datetime YES 回复时间 - -
is_show int YES 是否显示(1:是,0:否) - -
product_params表如表4-8所示:
表4-8 product_params
字段名 数据类型 允许为空 字段说明 默认值 键值
param_id varchar No 商品参数id - PRI
product_id varchar YES 商品id - -
product_place varchar YES 产地 产地,例:中国江苏 - -
foot_period varchar YES 保质期 保质期,例:180天 - -
brand varchar YES 品牌名 品牌名,例:三只大灰狼 - -
factory_name varchar YES 生产厂名 生产厂名,例:大灰狼工厂 - -
factory_address varchar YES 生产厂址,例:大灰狼生产基地 - -
packaging_method varchar YES 包装方式 包装方式,例:袋装 - -
weight varchar YES 规格重量 规格重量,例:35g - -
storage_method varchar YES 存储方法 存储方法,例:常温5~25° - -
eat_method varchar YES 食用方式 食用方式,例:开袋即食 - -
create_time datetime YES 创建时间 - -
update_time datetime YES 更新时间 - -
product_sku表如表product_sku所示:
表4-9 product_sku
字段名 数据类型 允许为空 字段说明 默认值 键值
sku_id Varchar(64) No 0 - PRI
product_id Varchar(64) YES 商品id - -
sku_name Varchar(32) YES sku名称 - -
sku_img Varchar(32) YES sku图片 - -
untitled Varchar(400) YES 属性组合(格式是p1:v1;p2:v2) - -
original_price Int(11) YES 原价 - -
sell_price Int(11) YES 销售价格 - -
discounts Decimal(4) YES 折扣力度 - -
stock Int(11) YES 库存 - -
create_time Datetime() YES 创建时间 - -
update_time Datetime() YES 更新时间 - -
status Int(11) YES sku状态(1启用,0禁用,-1删除) - -
Shopping_cart表如表4-10所示:
表4-10 address
字段名 数据类型 允许为空 字段说明 默认值 键值
cart_id int No 0 - PRI
product_id varchar YES 商品ID - -
sku_id varchar YES skuid - -
sku_props varchar YES 选择的套餐的属性 - -
user_id varchar YES 用户id - -
cart_num varchar YES 购物车商品数量 - -
cart_time varchar YES 购物时间 - -
product_price decimal YES 商品价格 - -
User_addr表如表4-11所示:
表4-11 user_addr
字段名 数据类型 允许为空 字段说明 默认值 键值
addr_id Varchar(64) No 0 - PRI
user_id Varchar(64) YES 用户ID - -
receiver_name Varchar(32) YES 收件人姓名 - -
receiver_mobile Varchar(50) YES 收件人手机号 - -
province Varchar(32) YES 省份 - -
city Varchar(32) YES 城市 - -
area Varchar(32) YES 地区 - -
addr Varchar(128) YES 详细地址 - -
post_code Varchar(32) YES 邮政编码 - -
status Int(11) YES 状态,1正常,0无效 - -
common_addr Int(11) YES 是否默认地址 1是 1:是 0:否 - -
create_time Datetime() YES 创建时间 - -
update_time Datetime() No 更新时间 - -
User_login_history表如表4-12所示:
表4-12 user_login_history
字段名 数据类型 允许为空 字段说明 默认值 键值
ID Int(11) No - PRI
AREA Varchar(32) YES 地区 - -
COUNTRY Varchar(32) YES 国家 - -
USER_ID Varchar(32) YES 用户id - -
IP Varchar(32) YES ip地址 - -
LOGIN_TIME Varchar(32) YES 时间 - -
第五章 系统实现
5.1 商品管理模块
如图5-1所示:商品管理模块的商品的新增、修改商品蓪、商品进行不同方式的查询和商品的删除功能、商品规格参数的添加是通过管理员从前端发送请求调用后端的接口,通过后端接口进行数据的处理,然后响应一个提示给前端进行实现的。大致过程,前端发送post或者get请求,后端通过注解@RquestParam或者@RequestBody进行接收,controller层调用service层,然后调用dao层,操作xml文件进行数据库的操作。
图5-1
伪代码表示:
Begin:
if islogin<-true Then
Conditon<-Condition1(得到所有的条件查询所有商品)
Function selectProduct(product:Object);
Var list:List;
Chang:boolean;
Begin
List:=selectProduct(product:Object)
Change:true;
End
Else
{
Change:false;
}
End
查询商品和更新商品:
@Override
public PageInfo selecProductBypage(com.qfedu.fmmall.vo.ProductVO productVO) {
productVO.setPageSize(10);
//分页处理
com.github.pagehelper.PageHelper.startPage(productVO.getPageNum(), productVO.getPageSize());
List list = productMapper.selectProductByPage(productVO);
System.out.println(list.size());
PageInfo pageInfo = new PageInfo<>(list);
pageInfo.setSize(list.size());
return pageInfo;
}
@Override
public ResultVO updateProductByProduct(com.qfedu.fmmall.vo.ProductVO productVO) {
ResultVO resultVO = new ResultVO();
Example example = new Example(Product.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("productId",productVO.getProduct_id());
Product product = new Product();
product.setProductName(productVO.getProduct_name());
product.setIsup(productVO.getIsup());
product.setContent(productVO.getContent());
// 设置商品的更新时间
product.setUpdateTime(new Date());
// 设置商品的分类名称
product.setCategoryId(Integer.valueOf(productVO.getCategory_id()));
int i = productMapper.updateByExampleSelective(product, example);
// 更新商品sku表
Example example1 = new Example(ProductSku.class);
Example.Criteria criteria1 = example1.createCriteria();
criteria1.andEqualTo(“productId”,productVO.getProduct_id());
ProductSku productSku = new ProductSku();
productSku.setSkuName(productVO.getSku_name());
productSku.setUntitled(productVO.getUntitled());
i = productSkuMapper.updateByExampleSelective(productSku, example1);
if(i>0){
resultVO.setMsg("更新商品信息成功");
}else {
resultVO.setMsg("更新商品信息失败");
}
return resultVO;
}
5.2 购物车模块
前台的用户经过点击商品,通过商品的id进行查询出商品的信息,商品的规格参数,商品的sku,商品图片信息,然后在商品详情页面进行展示,在商品的详情页面点击添加购物车,成功则显示在购物车的列表里面,否则提示添加失败,如图5-2,5-3图所示:
图5-2
图5-3
Begin
Processdure selectCart(shoppingcart:Object)
Var list:List;
If isloing:=true Then
List:=selectCart(shoppingcart:Object)
End
package com.qfedu.fmmall.service.impl;
import com.qfedu.fmmall.dao.ShoppingCartMapper;
import com.qfedu.fmmall.entity.ShoppingCart;
import com.qfedu.fmmall.entity.ShoppingCartVO;
import com.qfedu.fmmall.service.ShoppingCartService;
import com.qfedu.fmmall.vo.ResultStatus;
import com.qfedu.fmmall.vo.ResultVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
@Service
@Transactional
public class ShoppingCartServiceimpl implements ShoppingCartService {
@Autowired
private ShoppingCartMapper shoppingCartMapper;
private SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
@Override
public ResultVO addShoppingCart(ShoppingCart cart) {
cart.setCartTime(sdf.format( new Date()));
System.out.println("购物车的相关的信息-------"+cart);
int i = shoppingCartMapper.insert(cart);
if(i>0){
return new ResultVO(ResultStatus.OK, "购物车插入成功", null);
}else {
return new ResultVO(ResultStatus.OK, "购物车插入失败", null);
}
}
@Transactional(propagation = Propagation.SUPPORTS)
@Override
public ResultVO selectShoppingCartByUserId(int userid) {
List shoppingCartVOS = shoppingCartMapper.selectShoppingCartByUserId(userid);
return new ResultVO(ResultStatus.OK,"查询购物车信息ok",shoppingCartVOS);
}
@Override
public ResultVO updateCartNum(int cartId, int cartNum) {
int i = shoppingCartMapper.updateCartNumByUserId(cartId, cartNum);
if(i>0){
return new ResultVO(ResultStatus.OK,"更新购物车信息ok",null);
}else {
return new ResultVO(ResultStatus.OK,"更新购物车信息fail",null);
}
}
@Override
public ResultVO deleteShoppCartByCartId(int cartId) {
int i = shoppingCartMapper.deleteShoppCartByCartId(cartId);
if(i>0){
return new ResultVO(ResultStatus.OK,"delete cart ok",null);
}else {
return new ResultVO(ResultStatus.OK,"delete cart fail",null);
}
}
这个是购物车的删除,和批量删除的相关的code
5.3 订单模块
用户点击商品,添加购物车成功,对于添加成功的商品可以进行结算,点击结算可以生成订单,同时通过雪花算法生成订单id。// 保存订单的步骤大致步骤
1.查询选中购买的购物车详情 2. 校验库存3.保存订单 4.保存订单快 5.购买成功需要删除购物车记录,可以知道这几个步骤需要同时成功或者同时失败,符合一个事务如图5-3所示:
图5-3
图5-4
@Transactional
public Map addOrder(List cids, Orders orders) throws SQLException{
Map map=new HashMap<>();
// 根据cids查询购物车的详情记录(包括库存)
List shoppingCartVOList = shoppingCartMapper.selectShoppingcartByids(cids);
// 校验库存
boolean f=true;
String untitled="";
for (ShoppingCartVO sc :shoppingCartVOList
) {
if(Integer.valueOf(sc.getCartNum())>sc.getStock()){
f=false;
}
// 获取所有的商品名称,以,分割拼接成字符串
untitled=untitled+sc.getProductName()+“,”;
}
if(f){
// 表示库存充足进行保存
// 1.userId 2 untitled名称 3 收件人地址,姓名,电话,地址
// 4. 总价格 5.支付方式
// 6.创建 订单的时间
// 7.订单初始状态 1 待支付
orders.setStatus(1);
orders.setUntitled(untitled);
orders.setCreateTime(new Date());
orders.setCancelTime(new Date());
orders.setDeliveryTime(new Date());
// 生成订单编号
String orderId = UUID.randomUUID().toString().replace(“-”, “”);
orders.setOrderId(orderId);
// 保存订单
int i=ordersMapper.insert(orders);
if(i>0){
// ordersItem 生成商品快照
// List ordersItemList=new ArrayList<>();
for (ShoppingCartVO sc :shoppingCartVOList) {
// 生成订单的编号
int cnum=Integer.valueOf(sc.getCartNum());
String itemid=System.currentTimeMillis()+(new Random().nextInt(9999)+100)+"";
String itemid1 = itemid.substring(1, 10);
// 注意一下double需要转换为Bigdecimal类型
// public OrdersItem(Integer orderId, Integer productId,
// String productName,
// String productImg, Integer skuId, String skuName,
// BigDecimal productPrice, Integer buyCounts,
// BigDecimal totalAmount, Date basketDate, Date buyTime,
// Integer isComment)
// int itemid2=Integer.parseInt(itemid1);
OrdersItem ordersItem= new OrdersItem();
// 这个Oders表的orderId必须和OdersItem表的orderId类型和数据一样
ordersItem.setOrderId(orders.getOrderId());
ordersItem.setProductId(Integer.valueOf(sc.getProductId()));
ordersItem.setProductName(sc.getProductName());
ordersItem.setProductImg(sc.getProductImg());
ordersItem.setSkuId(Integer.valueOf(sc.getSkuId()));
System.out.println(sc.getSkuName());
ordersItem.setSkuName(sc.getSkuName());
System.out.println(sc.getSellPrice());
ordersItem.setProductPrice(new BigDecimal(String.valueOf(sc.getProductPrice())));
ordersItem.setBuyCounts(cnum);
ordersItem.setTotalAmount(sc.getProductPrice());
ordersItem.setBasketDate(new Date());
ordersItem.setBuyTime(new Date());
ordersItem.setIsComment(0);
// ordersItemList.add(ordersItem);
int m=ordersItemMapper.insert(ordersItem);
}
// int j = ordersItemMapper.insertList(ordersItemList);
// 扣减库存???
// 根据套餐Id修改库存量
for (ShoppingCartVO sc :shoppingCartVOList
) {
String skuId = sc.getSkuId();
int newStock=sc.getStock()-Integer.valueOf(sc.getCartNum());
// Example example = new Example(ProductSku.class);
// Example.Criteria criteria = example.createCriteria();
// criteria.andEqualTo(“skuId”,skuId);
// ProductSku productSku = productSkuMapper.selectByPrimaryKey(skuId);
ProductSku productSku=new ProductSku();
productSku.setSkuId(skuId);
productSku.setStock(String.valueOf(newStock));
// productSku.setSkuImg(null);
productSkuMapper.updateByPrimaryKeySelective(productSku);
}
// 保存订单成功 删除购物车记录
for (Integer cid:cids
) {
shoppingCartMapper.deleteByPrimaryKey(cid);
}
map.put("orderId",orderId);
map.put("productNames",untitled);
return map;
}
}else{
// 不足
return null;
}
return null;
}
订单的快照的生成使用的是这个代码,然后还会删除购物车的数据。
5.4 微信支付模块
调用也第三方的接口平台,通过系统三方的接口配置文档,在代码中建立配置类,通过接口平台提供的商户id,AppId,商户的公钥,私钥,接口响应内容等进行加密,实现微信支付成功回调函数进行提示功能。如图5-5所示:
图5-5
package com.qfedu.fmmall.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping(“/pay”)
public class PayController {
@PostMapping(“/success”)
public void success(){
}
}
package com.qfedu.fmmall.config;
import com.github.wxpay.sdk.WXPayConfig;
import java.io.InputStream;
public class MyPayConfig implements WXPayConfig {
@Override
public String getAppID() {
return “wx632c8f211f8122c6”;
}
@Override
public String getMchID() {
return "1497984412";
}
@Override
public String getKey() {
return "sbNCm1JnevqI36LrEaxFwcaT0hkGxFnC";
}
@Override
public InputStream getCertStream() {
return null;
}
@Override
public int getHttpConnectTimeoutMs() {
return 0;
}
@Override
public int getHttpReadTimeoutMs() {
return 0;
}
}
5.5 地址信息管理
前端发送一个请求,通过tkmapper框架作为持久层,查询地址表进行展示到前端,管理员可以查询所有用户的地址,地址添加,通过click事件发送axios请求,通过post请求体,携带数据传递给后端进行添加,@RquestBody注解进行接收数据,tkmapper进行插入数据库的操作。删除:通过传递过来的地址id进行删除。更新:首先查询地址在地址表中是否存在,如果存在进行更新,否则进行添加操作。如图5-6所示:
图5-6
package com.qfedu.fmmall.service.impl;
import com.qfedu.fmmall.dao.UserAddrMapper;
import com.qfedu.fmmall.entity.UserAddr;
import com.qfedu.fmmall.service.UserAddrService;
import com.qfedu.fmmall.service.UserService;
import com.qfedu.fmmall.vo.ResultStatus;
import com.qfedu.fmmall.vo.ResultVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
import javax.annotation.Resource;
import java.util.List;
@Service
public class UserAddrServiceimpl implements UserAddrService{
@Resource
private UserAddrMapper userAddrMapper;
@Transactional(propagation = Propagation.SUPPORTS)
// 增删改使用required
@Override
public ResultVO queryAddressByUserId(String userId) {
Example example=new Example(UserAddr.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo(“userId”,userId);
// 地址使用状态ok
criteria.andEqualTo(“status”,1);
List userAddrs = userAddrMapper.selectByExample(example);
System.out.println(“用户地址”+userAddrs);
return new ResultVO(ResultStatus.OK,“查询用户地址成功”,userAddrs);
}
@Override
public ResultVO queryByAddrId(String AddrId) {
Example example=new Example(UserAddr.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("addrId",AddrId);
// UserAddr userAddr = userAddrMapper.selectByPrimaryKey(AddrId);
List userAddrs = userAddrMapper.selectByExample(example);
System.out.println(userAddrs);
return new ResultVO(ResultStatus.OK,"通过地址Id查询用户地址成功",userAddrs);
}
// 通过主键直接更新用户地址
@Override
public ResultVO updateByAddrId(UserAddr userAddr) {
int i = userAddrMapper.updateByPrimaryKey(userAddr);
return new ResultVO(ResultStatus.OK,"更新用户地址成功",i);
}
@Override
public ResultVO addUserAddress(UserAddr userAddr) {
int i = userAddrMapper.insertSelective(userAddr);
return new ResultVO(ResultStatus.OK,"增加用户地址成功",i);
}
//通过地址id进行相关的查询dfdsf
@Override
public ResultVO deleteByAddrId(String AddrId) {
Integer AddrId1 = Integer.valueOf(AddrId);
UserAddr userAddr = userAddrMapper.selectByPrimaryKey(AddrId1);
System.out.println(userAddr);
userAddr.setStatus("0");
int i = userAddrMapper.updateByPrimaryKey(userAddr);
return new ResultVO(ResultStatus.OK,"通过地址Id删除用户地址成功",i);
}
// 地址进行分页查询
@Override
public ResultVO queryAddressByPage(String userId, String status, int pageNum, int limit) {
return null;
}
}
5.6 商品详情模块
首先用户需要进行登录,校验token是否存在。存在:通过点击商品,在cookie里面保存商品的id,然后查询商品的图片信息,商品的参数信息,商品的套餐。展示在商品的详情页面。否则:跳转登录页面进行登录成功才可以展示商品详情。如图5-7所示:
图5-7
5.7 用户管理模块
用户必须拥有管理员权限才可以查询用户管理中,对登录的用户进行判断是否是管理员如果是展示如下的列表,然后可以对用户进行锁定的操作,通过前端的页面也可以进行用户的增删改查,操作。如图5-8所示:
图5-8
// 事务默认的隔离级别是可重复读 repeateable read
@Transactional(propagation = Propagation.SUPPORTS)
public ResultVO selectProductBasicInfo(String productId) {
// 1.查询商品的基本信息
Example example = new Example(Product.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("productId",productId);
criteria.andEqualTo("productStatus",1);
List products = productMapper.selectByExample(example);
// System.out.println(products);
if(products.size()>0){
// 2.查询商品的图片信息
Example example1 = new Example(ProductImg.class);
Example.Criteria criteria1 = example1.createCriteria();
criteria1.andEqualTo("itmeId",productId);
List productImgs = productImgMapperMapper.selectByExample(example1);
// System.out.println(productImgs);
// 3.查询商品的套餐信息
Example example2 = new Example(ProductSku.class);
Example.Criteria criteria2 = example2.createCriteria();
criteria2.andEqualTo("productId",productId);
criteria2.andEqualTo("status",1);
List productSkus = productSkuMapper.selectByExample(example2);
// System.out.println(productSkus);
// 把所有的商品的详情信息放入HashMap当中进行使用
HashMap
basicInfo.put(“product”,products.get(0));
basicInfo.put(“productImgs”,productImgs);
basicInfo.put(“productSkus”,productSkus);
return new ResultVO(ResultStatus.OK,"success",basicInfo);
}else {
new ResultVO(ResultStatus.NO,"查询商品基本信息失败",null);
}
return null;
所有模块需用文字详细描述技术实现思路。
第六章总结
这次项目总的来说还是有进步的,使自己对SpringBoot技术掌握的更加熟练,然后也使我更加的了解了项目实现的相关的过程,使自己掌握了系统开发的大致流程。从可行性分析到需求分析,再到系统设计(包括系统架构设计,主要功能设计,数据库设计),最后到系统实现等等这些流程,可以说从项目的设计到架构,到前后端的实现都走也一遍流程。
期间有些字段由于没有设计好,所以导致后面需要加上字段,然后需要修改大量的代码操作。导致工作有很多时候会重复,没有达到预期的进度,这些都是正常的,所以需要开发人员有良好的编程基础和扎实的工作态度。
我的这个项目的优点有:采用的是前后端分离SpringBoot+Vue开发,前端页面的设计还是不错的,使用目前比较火的vue后期有利于进行维护,使用的grid布局和card布局,拥有相关的商品推荐和最新的商品,用户一看便知道需要怎么操作,怎么购买,然后购物车模块可以一次性重复购买多个商品,可以给用户进行修改地址的信息,符合用户购买的一些需求,拥有微信扫码支付的功能。
不足之处:我没有做好权限管理的功能,商品的优惠活动也没有实现,以及现在的支付宝支付,和其他的绑定银行卡进行支付也没有实现。然后物流信息,和用户进行聊天的模块也没有,然后我没有把项目部署到云服务器上面,只是在本地进行访问,所以项目是没有进行上线的。
比较:在网上进行购物的时候,感觉到了淘宝京东的这些大型的购物网站的便利,首先是功能方面的完善,一般的小型项目是无法比较的,然后安全方面,它们有专门的网络安全专家进行维护,然后就是双十一的并发,可以达到几十万,这个是我们值得学习的。
改进方案:可以通过Linux进行部署项目,然后还需要进行测试项目,测试通过之后才可以进行上线,还需要加上一个权限处理模块,普通用户只可以访问商品的一些普通模块,是不可以进行后台的数据的访问的,然后还拦截器的处理,后端也需要加上相关的拦截器处理,前端也可以加上。
项目总体完工,但是需要进行改进的地方还有很多,一些页面的加载速度比较的缓慢,可以使用redis进行相关的缓存,然后也没有进行过相关的高并发的测试,只是个人进行相关的访问,使用的是SpringBoot的内置的Tomcat,并没有使用nginx进行 反向代理,还有前端后端还有很多的报错,这些没有影响整体的功能所以并没有进行相关的处理。
用户权限管理模块没有做的很全面,应该需要锁定一些发表不良言论的用户,商城项目中只是使用微信进行支付,这是不符合业务需求的,必须使用多种支付方式,比如银行卡,支付宝等等支付工具。然后就是网站的安全问题了,由于对于网络安全不是很熟悉,导致并没有进行模拟黑客攻击,这样肯定会有很多的安全隐患。
最后没有做物流模块,商品的流转,商品所处的状态,这些用户是需要进行实时的查看的,需要做出来,并进行实时的更新,如果出现什么特殊的情况还需要进行特殊说明。
展望:本系统需要从多个方面进行改进,目录最需要改进的支付模块和商品的展示详情模块,需要不断的进行迭代和版本的更新,然后本系统并没有进行相关的压力测试和bug的修复,可以说很多地方的bug是会影响到整个项目的运行的,所以对于一些重要的地方不可以出现严重的bug,比如支付模块,和商品地址管理模块,和商品图片展示等等。
总结中不能使用口语化的词语,需要总结本文或本系统完成的工作及不足或展望。
参考文献
(* 列出你在完成论文过程主要参阅的论文与著作。其中的篇数不宜太少,否则让人感觉到你没有参考相关工作就动手做论文;一篇本科毕业论文的典型参考文献是15至30篇,如果你所列参考文献数目不足5篇,则肯定无法通过论文初审的形式检查。列举参考文献时,按论文中引用文献的先后顺序列于此处;注意正文中必须引用此处所列的全部参考文献,而且引用顺序就是参考文献的列举顺序。参考文献的列举格式如下(也可参考《计算机学报》、《软件学报》、《电子学报》、《自动化学报》等刊物发表的论文所列参考文献的格式*):
[1] 甘仞初.信息系统分析设计与管理.高等教育出版社,2009
[2] 张海藩.软件工程导论(第5版).清华大学出版社,2008
[3] 丁跃潮.Web编程技术-JSP XML JavaEE.科学出版社,2008
[4] 王珊,萨师煊.数据库系统概论(第4版). 高等教育出版社,2006
[5] 赵伟,李东明.Java语言.北京航空航天大学出版社,2011
[6] 赵春利.网页设计与制作实用教程.清华大学出版社,2009
[7] 郝玉龙.Java EE编程技术.清华大学出版社,2008
[8] 史九林.数据结构基础.机械工业出版社,2008
[9] 郑宗汉,郑晓明.算法分析与设计(第2版).清华大学出版社,2011
[10] 张银鹤,梁文新.JavaScript完全学习手册.清华大学出版社,2008
[11] 强锋科技.ASP+SQL Server典型网站建设案例.清华大学出版社,2006
[12] 王津涛.网页设计与开发.东北大学出版社,2012
[13] 王中兵.Java Web主流框架整合.电子工业出版社,2008
[14] 袁然,郑自国,邹丰毅.Java案例开发集锦.电子工业出版社,2005
[15] 蔡剑,景楠.Java Web应用开发.高等教育出版社,2005
[16] 杨昭.JSP课程设计案例精编(第2版).中国水利水电出版社,2004
(参考文献格式说明
1.期刊格式(包括期刊网上的期刊)
[序号]. 作者1, 作者2, 作者3. 论文题目[J]. 刊名(全称). 出版年,卷号(期号): 起始页码.
[1].毛峡,丁玉宽.图像的情感特征分析及其和谐感评价[J].电子学报, 2001,29(12A): 1923-1927.
[2].冯新宇, 陶先平. 一种改进的移动Agent通信算法[J].计算机学报, 2002.25(4): 357-364.
2.书籍格式
[序号]. 作者1, 作者2, 作者3. 书籍名称及版次(初版不写)[M].出版地(城市名):出版者,出版年.
[1].张素琴, 吕映芝, 蒋维杜, 戴桂兰. 编译原理(第二版)[M]. 北京: 清华大学出版社, 2005.
[2].陈意云, 张昱. 编译原理(第二版)[M]. 北京: 高等教育出版社, 2008.
3.学位论文格式
[序号]. 著者. 论文题名[D]. 学位, 学位授予单位, 出版年.
[1].张和生. 地质力学系统理论[D].博士,太原: 太原理工大学,1998.
[2].黄鹏. 量子保密通信方案及信道传输特性研究[D]. 博士, 上海: 上海交通大学, 2013
4.会议录(论文集、论文汇编等)格式
[序号]. 作者1, 作者2, 作者3. 论文题目[A]. 文集实际完整名称[C].出版地(城市名): 出版者, 出版年.
[1].窦一凡, 肖勇波. 云计算模式下软件最优定价策略分析[C].第十三届中国管理科学学术年会论文集. 中国优选法统筹法与经济数学研究会. 杭州, 2011.
[2].黄茂生, 陈平. 软件测试过程的质量保证[C]. 中国电子学会可靠性分会第十四届学术年会论文选, 海口: 中国电子学会可靠性分会 2012.
5.专利格式
[序号]. 作者1, 作者2, 作者3. 专利题名[P]. 专利国别: 专利号, 出版年月日.
[1].刘海涛, 岩延, 张宝贤, 高雪,赵壮,黄奎,姚郑,张锋. 一种无线传感器网络专用操作系统的设计方法[P]. 中国专利: CN101303647, 2008-11-12.
[2].胡牧,孔震,李丹,梁吉,张涛,刘军,陈之栩,刘海涛. 一种生成框架内多页面的方法及系统 [P]. 中国专利:,CN102043630A, 2011-05-04.
6.电子文献格式
[序号]. 作者1, 作者2, 作者3. 电子文献题名[电子文献及载体类型标识].电子文献的出处或可获得地址,发表或更新日期.
[1].Android开发者社区. 7种无须编程的DIY开发工具 你知道几个?[EB/OL] http://mobile.51cto.com/android-416509.htm 2013-10- 14
[2].Android开发者社区. 教你如何修复iPhone 5s的指纹识别问题[EB/OL] http://mobile.51cto.com/android-416509.htm 2013-10-14
[电子文献类型标识/载体类型标识]
[DB/OL]——联机网上数据库(database online)
[DB/MT]——磁带数据库(database on magnetic tape)
[CP/DK]——磁盘软件(computer program on disk)
[EB/OL]——网上电子公告(electronic bulletin board online))
致谢
随着计算机网络技术的飞速发展,Web教育教学愈来愈受到广泛关注,如何进一步提高Web课程教育质量,成为教学工作普遍关注的课题。从软件工程角度分析了Web课程开发的重要意义以及具体方案,为Web教育效率的提高提供了借鉴经验。下面是学术参考网小编为朋友们搜集整理的软件工程论文致谢,欢迎阅读!
毕业—工作—辞职—上学—毕业,这一过程对我来说是漫长的,更主要的是:从工作单位重新回到学校,心是惶恐不定的。原以为一切会很难,可老师、同学、朋友、家人的关心、帮助,让我很快度过了这难忘的三年。片言只语难以表达此刻我的感激之情,我只有在今后的工作中,用我的努力、热情去回报这三年我所得到的一切!
首先衷心感谢我的导师和身边的同学三年来对我学业和工作上的谆谆教导,以及在生活方方面面给予的关心和帮助!特别是张老师,边老师一丝不苟的工作态度、严谨认真的工作作风,以及给我们传输的人生道理,值得我一生学习,记得印象最深的就是如果你每天坚持敲两个小时的代码,我保证你一年以后衣食无忧,表示了知识是需要不断的积累的,是需要行动的,需要树立一辈子学习的目标,还有边老师虽然比较的严厉,表明了她对学生的高的要求,希望学生可以学习认真,她说午休时间是用来给我们学习的,是的每个人应该要努力,既然选择了这个专业就要好好的学习,虽然我们现在不是答不到这么努力,但是让我们知道,要想优秀,不被社会淘汰就需要自己付出更多的努力,而且看到她努力的时候的那种投入的感觉也是值得我们学习的,看了了努力的快乐,而不是强迫自己,是那种心甘情愿的学习。
同时,我要感谢孟老师和陈老师,以及一个那些对我有过帮助的老师,的我还要感谢给予我帮助和关心的各位同学,特别是自己高中还一直联系着的同学卿钦,还有自己班上的同学刘科,没有他们,在学习上我会走更多的弯路,会失去许多的精神支持与信心。
另外,感谢我的家人长期对我物质、精神上的无私帮助与鼓励,因为他们我才能安心学习并顺利完成我的学业。
最后,感谢答辩委员会诸位老师在百忙之中审阅我的论文并出席论文答辩会!然后我其实还忘记了一个最重要的人,我最最应该感谢的是我自己,没有自己的坚持,没有自己的执着,没有自己的努力那么我很有可能就做不完毕业设计,感觉自己很多次的在困难面前选择的是面对,而不是逃避,每次的困难都是机遇,我始终相信我只要心态足够好,足够坚持,生活我的大部分的麻烦我都是可以解决的,所以人生路漫漫照顾好自己就行。