源码请点赞关注收藏后评论区留言和私信博主
开发环境:Web服务器使用Servlet容器,数据库采用mysql,集成开发环境为Spring Tool Suite(STS)
一、系统设计
电子商务平台分为两个子系统 一个是后台管理系统 一个是电子商务系统,下面分别讲解着两个子系统的功能需要与模块划分
系统功能需求
1:后台管理子系统
要求管理员登录成功后,才能对商品进行管理,包括添加商品,查询商品,修改商品以及删除商品,除商品管理外,管理员还需要对商品类型,注册用户以及用户的订单等进行管理
2:电子商务子系统
(1):非注册用户
具有浏览首页,查看商品详情以及搜索商品的功能
(2):注册用户
还可以购买商品,查看购物车,收藏商品,查看订单等等
系统模块划分
1:后台管理子系统
模块划分如下
2:电子商务子系统
模块划分如下
二、数据库设计
系统采用加载纯Java数据库驱动程序的方式连接MYSQL数据库,创建数据库shop并创建8张系统表 数据库E-R图如下
建表的sql语句此处省略 需要请点赞关注收藏后私信博主
部分sql语句如下
/* Navicat MySQL Data Transfer Source Server : testSpringMVC Source Server Version : 50519 Source Host : localhost:3306 Source Database : shop Target Server Type : MYSQL Target Server Version : 50519 File Encoding : 65001 Date: 2019-10-08 07:41:20 */ SET FOREIGN_KEY_CHECKS=0; -- ---------------------------- -- Table structure for `ausertable` -- ---------------------------- DROP TABLE IF EXISTS `ausertable`; CREATE TABLE `ausertable` ( `aname` varchar(50) COLLATE utf8_unicode_ci NOT NULL, `apwd` varchar(50) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`aname`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Records of ausertable -- ---------------------------- INSERT INTO ausertable VALUES ('admin', 'admin'); -- ---------------------------- -- Table structure for `busertable` -- ---------------------------- DROP TABLE IF EXISTS `busertable`; CREATE TABLE `busertable` ( `id` int(11) NOT NULL AUTO_INCREMENT, `bemail` varchar(50) COLLATE utf8_unicode_ci NOT NULL, `bpwd` varchar(32) COLLATE utf8_unicode_ci NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Records of busertable -- ---------------------------- INSERT INTO busertable VALUES ('6', 'chenhengdl@126.com', '78f8a7ae700c91db09facb05a675432b'); -- ---------------------------- -- Table structure for `carttable` -- ---------------------------- 还没弄 DROP TABLE IF EXISTS `carttable`; CREATE TABLE `carttable` ( `id` int(11) NOT NULL AUTO_INCREMENT, `busertable_id` int(11) NOT NULL, `goodstable_id` int(11) NOT NULL, `shoppingnum` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `bid` (`busertable_id`), KEY `gno` (`goodstable_id`), CONSTRAINT `bid` FOREIGN KEY (`busertable_id`) REFERENCES `busertable` (`id`), CONSTRAINT `gno` FOREIGN KEY (`goodstable_id`) REFERENCES `goodstable` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Records of carttable -- ---------------------------- -- ---------------------------- -- Table structure for `focustable` -- ---------------------------- 还没弄 DROP TABLE IF EXISTS `focustable`; CREATE TABLE `focustable` ( `id` int(11) NOT NULL AUTO_INCREMENT, `goodstable_id` int(11) NOT NULL, `busertable_id` int(11) NOT NULL, `focustime` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `gno1` (`goodstable_id`), KEY `bid1` (`busertable_id`), CONSTRAINT `bid1` FOREIGN KEY (`busertable_id`) REFERENCES `busertable` (`id`), CONSTRAINT `gno1` FOREIGN KEY (`goodstable_id`) REFERENCES `goodstable` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Records of focustable -- ---------------------------- INSERT INTO focustable VALUES ('5', '29', '6', '2019-10-05 14:55:51'); -- ---------------------------- -- Table structure for `goodstable` -- ---------------------------- 还没弄 DROP TABLE IF EXISTS `goodstable`; CREATE TABLE `goodstable` ( `id` int(11) NOT NULL AUTO_INCREMENT, `gname` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, `goprice` double DEFAULT NULL, `grprice` double DEFAULT NULL, `gstore` int(11) DEFAULT NULL, `gpicture` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, `isRecommend` tinyint(2) DEFAULT NULL, `isAdvertisement` tinyint(2) DEFAULT NULL, `goodstype_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY `typeid` (`goodstype_id`), CONSTRAINT `typeid` FOREIGN KEY (`goodstype_id`) REFERENCES `goodstype` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=36 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Records of goodstable -- ---------------------------- INSERT INTO goodstable VALUES ('26', '广告商品4', '90', '80', '1000', '201910274135059473.jpg', '0', '1', '2'); INSERT INTO goodstable VALUES ('27', '广告商品5', '80', '30', '122', '201910274135126352.jpg', '0', '1', '3'); INSERT INTO goodstable VALUES ('28', '抱枕11号', '100', '20', '200', '201910274135150096.jpg', '1', '0', '14'); INSERT INTO goodstable VALUES ('29', '抱枕22号', '300', '200', '180', '201910274135212497.jpg', '1', '0', '15'); INSERT INTO goodstable VALUES ('32', '抱枕99', '80', '70', '80', '201910280135330014.jpg', '1', '0', '14'); DROP TABLE IF EXISTS `orderdetail`; CREATE TABLE `orderdetail` ( `id` int(11) NOT NULL AUTO_INCREMENT, `orderbasetable_id` int(11) NOT NULL, `goodstable_id` int(11) NOT NULL, `shoppingnum` int(11) NOT NULL, PRIMARY KEY (`id`), KEY `odsn` (`orderbasetable_id`), KEY `gno3` (`goodstable_id`), CONSTRAINT `gno3` FOREIGN KEY (`goodstable_id`) REFERENCES `goodstable` (`id`), CONSTRAINT `odsn` FOREIGN KEY (`orderbasetable_id`) REFERENCES `orderbasetable` (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; -- ---------------------------- -- Records of orderdetail -- ---------------------------- INSERT INTO orderdetail VALUES ('5', '3', '29', '20'); INSERT INTO orderdetail VALUES ('6', '4', '33', '20');
建表后效果如下
三、系统管理
1:添加相关依赖
在pom.xml文件中添加如下代码
<!-- 添加MySQL依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.45</version> <!-- MySQL8.x时,请使用8.x的连接器 --> </dependency> <!-- MyBatis-Spring,Spring Boot应用整合MyBatis框架的核心依赖配置 --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.0</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <!-- 由于commons-fileupload组件不属于Spring Boot,所以需要加上版本 --> <version>1.3.3</version> </dependency>
应用的目录结构如下
在配置文件application.properties中添加如下代码
server.servlet.context-path=/eBusiness ### ##数据源信息配置 ### #数据库地址 spring.datasource.url=jdbc:mysql://localhost:3306/shop?characterEncoding=utf8 #数据库MySQL为8.x时,url为jdbc:mysql://localhost:3306/springbootjpa?useSSL=false&serverTimezone=Asia/Beijing&characterEncoding=utf-8 #数据库用户名 spring.datasource.username=root #数据库密码 spring.datasource.password=root #数据库驱动 spring.datasource.driver-class-name=com.mysql.jdbc.Driver #设置包别名(在Mapper映射文件中直接使用实体类名) mybatis.type-aliases-package=com.ch.ebusiness.entity #告诉系统在哪里去找mapper.xml文件(映射文件) mybatis.mapperLocations=classpath:mappers/*.xml #在控制台输出SQL语句日志 logging.level.com.ch.ebusiness.repository=debug #关闭Thymeleaf模板引擎缓存(使页面热部署),默认是开启的 spring.thymeleaf.cache=false #上传文件时,默认单个上传文件大小是1MB,max-file-size设置单个上传文件大小 spring.servlet.multipart.max-file-size=50MB #默认总文件大小是10MB,max-request-size设置总上传文件大小 spring.servlet.multipart.max-request-size=500MB
四、组件设计
包括 管理员登录权限验证 前台用户登录权限验证 验证码 统一异常处理 工具类等等
五、后台管理子系统的实现
管理员登录界面如下
代码如下
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>管理员登录页面</title> <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}" /> <body> <div class="container"> <div class="bg-primary" style="width:70%; height: 60px;padding-top: 1px;"> <h3 align="center">管理员登录</h3> </div> <br> <br> <form th:action="@{/admin/login}" name="myform" method="post" th:object="${aUser}" class="form-horizontal" role="form" > <div class="form-group has-success"> <label class="col-sm-2 col-md-2 control-label">用户名</label> <div class="col-sm-4 col-md-4"> <input type="text" class="form-control" placeholder="请输入管理员名" th:field="*{aname}"/> <span th:errors="*{aname}"></span> </div> </div> <div class="form-group has-success"> <label class="col-sm-2 col-md-2 control-label">密码</label> <div class="col-sm-4 col-md-4"> <input type="password" class="form-control" placeholder="请输入您的密码" th:field="*{apwd}"/> <span th:errors="*{apwd}"></span> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit"class="btn btn-success" >登录</button> <button type="reset" class="btn btn-primary" >重置</button> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <font size="6" color="red"> <span th:text="${errorMessage }"></span> </font> </div> </div> </form> </div> </body> </html>
类型管理界面如下 包括增删改查
添加类型页面代码如下
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>商品类型添加页面</title> <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}" /> <body> <div th:include="admin/header"></div> <br><br><br> <div class="container"> <div class="bg-primary" style="width:70%; height: 60px;padding-top: 0.5px;"> <h3 align="center">添加类型</h3> </div><br> <form th:action="@{/type/addType}" name="myform" method="post" th:object="${goodsType}" class="form-horizontal" role="form" > <div class="form-group has-success"> <label class="col-sm-2 col-md-2 control-label">类型名称</label> <div class="col-sm-4 col-md-4"> <input type="text" class="form-control" placeholder="请输入类型名" th:field="*{typename}"/> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit"class="btn btn-success" >添加</button> <button type="reset" class="btn btn-primary" >重置</button> </div> </div> </form> </div> </body> </html>
添加商品效果如下
代码如下
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>商品类型添加页面</title> <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}" /> <body> <div th:include="admin/header"></div> <br><br><br> <div class="container"> <div class="bg-primary" style="width:70%; height: 60px;padding-top: 0.5px;"> <h3 align="center">添加商品</h3> </div><br> <form th:action="@{/goods/addGoods?act=add}" name="myform" method="post" th:object="${goods}" class="form-horizontal" enctype="multipart/form-data" > <div class="form-group has-success"> <label class="col-sm-2 col-md-2 control-label">商品名称</label> <div class="col-sm-4 col-md-4"> <input type="text" class="form-control" placeholder="请输入商品名" th:field="*{gname}"/> </div> </div> <div class="form-group has-success"> <label class="col-sm-2 col-md-2 control-label">商品原价</label> <div class="col-sm-4 col-md-4"> <input type="number" class="form-control" placeholder="请输入商品原价" th:field="*{goprice}"/> </div> </div> <div class="form-group has-success"> <label class="col-sm-2 col-md-2 control-label">商品折扣价</label> <div class="col-sm-4 col-md-4"> <input type="number" class="form-control" placeholder="请输入商品折扣价" th:field="*{grprice}"/> </div> </div> <div class="form-group has-success"> <label class="col-sm-2 col-md-2 control-label">商品库存</label> <div class="col-sm-4 col-md-4"> <input type="number" class="form-control" placeholder="请输入商品库存" th:field="*{gstore}"/> </div> </div> <div class="form-group has-success"> <label class="col-sm-2 col-md-2 control-label">商品图片</label> <div class="col-sm-4 col-md-4"> <input type="file" placeholder="请选择商品图片" class="form-control" name="fileName"/> </div> </div> <div class="form-group has-success"> <label class="col-sm-2 col-md-2 control-label">是否推荐</label> <div class="col-sm-4 col-md-4 radio"> <label> <input type="radio" th:field="*{isRecommend}" value="1">是 </label> <label> <input type="radio" th:field="*{isRecommend}" value="0">否 </label> </div> </div> <div class="form-group has-success"> <label class="col-sm-2 col-md-2 control-label">是否广告</label> <div class="col-sm-4 col-md-4 radio"> <label> <input type="radio" th:field="*{isAdvertisement}" value="1">是 </label> <label> <input type="radio" th:field="*{isAdvertisement}"s value="0">否 </label> </div> </div> <div class="form-group has-success"> <label class="col-sm-2 col-md-2 control-label">商品类型</label> <div class="col-sm-4 col-md-4"> <select class="form-control" th:field="*{goodstype_id}"> <option th:each="gty:${goodsType}" th:value="${gty.id}" th:text="${gty.typename}"> </select> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <button type="submit"class="btn btn-success" >添加</button> <button type="reset" class="btn btn-primary" >重置</button> </div> </div> </form> </div> </body> </html>
其余的删除修改页面此处省略 有需要者点赞关注收藏后评论区留言或私信博主
六、前台商务子系统的实现
导航页效果如下 点击即可跳转到其他页面
代码如下
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>导航页</title> <base th:href="@{/}"><!-- 不用base就使用th:src="@{/js/jquery.min.js} --> <!-- Bootstrap --> <link href="css/bootstrap.min.css" rel="stylesheet"> <script src="js/jquery.min.js"></script> <script src="js/bootstrap.min.js"></script> <style type="text/css"> .carousel{ height: 200px; background-color: #000; } .carousel .item{ height: 200px; background-color: #000; } .carousel img{ width: 100%; } </style> </head> <body> <div class="container-fruid"> <div class="navbar navbar-default navbar-fixed-top" role="navigation" style="padding-left: 30px;"> <div class="navbar-header"> <span class="navbar-brand">欢迎光临eBusiness</span> </div> <ul class="nav navbar-nav"> <li><a th:href="@{user/toRegister}">注册</a></li> <li> <a th:href="(${session.bUser} == null)?'user/toLogin':'#'" > <span th:if="${session.bUser} == null" > 登录 </span> <span th:if="${session.bUser} != null" > 欢迎<span th:text="${session.bUser.bemail}" ></span> </span> </a> </li> <li><a th:href="@{admin/toLogin}">后台</a></li> </ul> <ul class="nav navbar-nav navbar-right" style="padding-right: 30px;"> <li><a href="cart/userInfo">个人信息</a></li> <li><a href="cart/selectCart">我的购物车</a></li> <li><a href="cart/myFocus">我的收藏</a></li> <li><a href="cart/myOder">我的订单</a></li> <li class="dropdown"><a href="##" data-toggle="dropdown" class="dropdown-toggle">关于我们<span class="caret"></span></a> <ul class="dropdown-menu"> <li><a href="##">联系我们</a></li> <li><a href="##">投诉建议</a></li> </ul> </li> </ul> </div> <!-- ************************************************** --> <div id="carousel-example-generic" class="carousel slide" data-ride="carousel" style="margin-top: 20px;"> <!-- Indicators 小圆圈--> <ol class="carousel-indicators"> <li data-target="#carousel-example-generic" th:each="advertise,adstat:${advertisementGoods}" th:data-slide-to="${adstat.index}" th:class="(${adstat.index}==0)? 'active' : ''"></li> </ol> <!-- 滚动广告图片 --> <div class="carousel-inner" role="listbox"> <div th:each="advertise,adstat:${advertisementGoods}" th:class="(${adstat.index}==0)? 'item active' : 'item'"> <img th:src="'images/' + ${advertise.gpicture}" th:alt="${adstat.index + 1}"> <div class="carousel-caption"><span th:text="${advertise.gname}"></span></div> </div> </div> <!-- Controls --> <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev"> <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span> <span class="sr-only">Previous</span> </a> <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next"> <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span> <span class="sr-only">Next</span> </a> </div> <!-- *************************************** --> <div class="navbar navbar-default " role="navigation"> <ul class="nav navbar-nav" style="padding-left: 50px;"> <li><a th:href="@{/}">首页</a></li> <li th:each="gty:${goodsType}"><a th:href="'?tid=' + ${gty.id}"><span th:text="${gty.typename}"></span></a></li> </ul> <form action="search" class="navbar-form navbar-right" style="padding-right: 50px;"> <div class="form-group"> <input type="text" class="form-control" name="mykey" placeholder="请输入关键词" /> </div> <button type="submit" class="btn btn-default">搜索</button> </form> </div> </div> </body> </html>
商品详情页面如下
代码如下
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <base th:href="@{/}"><!-- 不用base就使用th:src="@{/js/jquery.min.js} --> <meta charset="UTF-8"> <title>商品页面</title> <link rel="stylesheet" href="css/bootstrap.min.css" /> <script src="js/jquery.min.js"></script> <script type="text/javascript" th:inline="javascript"> function focus(){ $.ajax( { //请求路径,要注意的是url和th:inline="javascript" url : [[@{/cart/focus}]], //请求类型 type : "post", contentType : "application/json", //data表示发送的数据 data : JSON.stringify({ id : $("#gid").val() }), //成功响应的结果 success : function(obj){//obj响应数据 if(obj == "no"){ alert("您已收藏该商品!"); }else if(obj == "ok"){ alert("成功收藏该商品"); }else{ alert("您没有登录,请登录!"); } }, error : function() { alert("处理异常!"); } } ); } function putCart(){ if(!(/(^[1-9]\d*$)/.test($("#buyNumber").val()))){ alert("购买量请输入正整数!"); $("#buyNumber").focus(); return; } if(parseInt($("#buyNumber").val()) > parseInt($("#gstore").text())){ alert("购买量超出库存!"); $("#buyNumber").focus(); return; } //获取路径 var pathName=window.document.location.pathname; //截取,得到项目名称 var projectName=pathName.substring(0,pathName.substr(1).indexOf('/')+1); window.location.href = projectName + "/cart/putCart?id=" + $("#gid").val() + "&buyNumber=" + $("#buyNumber").val(); } </script> </head> <body> <!-- 加载header.html --> <div th:include="user/header"></div> <div class="container"> <div class="row"> <div class="col-xs-6 col-md-3"> <img th:src="'images/' + ${goods.gpicture}" style="height: 220px; width: 280px; display: block;"> </div> <div class="col-xs-6 col-md-3"> <p>商品名:<span th:text="${goods.gname}"></span></p> <p> 商品折扣价:<span style="color: red;">¥ <span th:text="${goods.grprice}"></span> </span> </p> <p> 商品原价: <span class="text-dark" style="text-decoration: line-through;"> ¥ <span th:text="${goods.goprice}"></span> </span> </p> <p> 商品类型:<span th:text="${goods.typename}"></span> </p> <p> 库存:<span id="gstore" th:text="${goods.gstore}"></span> </p> <p> <input type="text" size="12" class="form-control" placeholder="请输入购买量" id="buyNumber" name="buyNumber"/> <input type="hidden" name="gid" id="gid" th:value="${goods.id}"/> </p> <p> <a href="javascript:focus()" class="btn btn-primary" style="font-size: 10px;">加入收藏</a> <a href="javascript:putCart()" class="btn btn-success" style="font-size: 10px;">加入购物车</a> </p> </div> </div> </div> </body> </html>
测试效果如下
如果账号密码不对则弹出错误窗口
还有用户注册 登录页面 购物车 下单页面 个人信息 我的收藏页面等等此处省略
需要源码请点赞关注收藏后评论区留言或 私信博主即可