基于Java+VUE+MariaDB实现(Web)仿小米商城【100010233】
仿小米商城
环境安装
运行
mvn clean install -DskipTests
cd admin
mvn spring-boot:run
cd ../web
mvn spring-boot:run
cd ../xiaomi-store-admin-vue
npm install
npm run serve
cd ../xiaomi-store-vue
npm install
npm run serve
注意:运行前请更改数据库相关属性文件
实训日志
数据库设计
根据项目需求,该项目相关实体有:用户(普通用户 user
与管理员 admin
),商品 item
,订单 order
,购物车 shopping_cart
,用户详细信息 user_detail
(包括地址 address
),商品类型 item_type
;
如下表:
实体名称 | 数据库表 |
---|---|
普通用户 | user |
管理员 | admin |
商品 | item |
订单 | order |
购物车 | shopping_cart |
用户详细信息 | user_detail |
地址 | address |
商品类型 | item_type |
实体之间的关联关系如下:
user
user_detail
OneToOneuser
shopping_cart
OneToOneuser
order
OneToManyitem
shopping_cart
ManyToOneitem
order
ManyToOneaddress
user_detail
ManyToOneaddress
order
OneToOneitem
item_type
OneToOne
所以数据库设计为:
项目设计
模块
自顶向下分析,顶层模块有用户系统,管理员系统,向下有服务层,数据库读写 dao 层,Java 实体 model 层,各层次依赖关系为,admin 和 Web 依赖 service,service 依赖 dao,dao 依赖 model,它们都是 xiaomi_store 的子项目。
Java 实体关系设计
model 层 uml 类图如下:
各实体间没有关系,但都继承自一个基类,基类存放实体创建时间,修改时间等信息。
用户系统实现
jpa 与 MyBatis 选择
Hibernate 是一个 ORM 框架,而 JPA 则是一种 ORM 规范,JPA 和 Hibernate 的关系就像 JDBC 与 JDBC 驱动的关系,即 JPA 制定了 ORM 规范,而 Hibernate 是这些规范的实现(事实上,是先有 Hibernate 后有 JPA,JPA 规范的起草者也是 Hibernate 的作者),因此从功能上来说,JPA 相当于 Hibernate 的一个子集。
jpa 使用方便,不需要开发者编写 SQL 代码,通过实体之间的关系自动创建或修改数据库;MyBatis 支持定制化 SQL、存储过程以及高级映射。MyBatis 几乎避免了所有的 JDBC 代码手动设置参数以及获取结果集。
MyBatis 灵活,jpa 简单,我认为,MyBatis 更适合长期维护的项目,jpa 更适合短期快速开发上线项目。jpa 与 MyBatis 都是通过 interface 来映射 Java 方法进行数据库操作,可以使用 MyBatis 对 jpa 接口进行继承重写,迁移也比较方便。所以该实训项目选择 jpa。
模型层设计
使用 jpa 或是 MyBatis 提供的逆向工程并不包含依赖关系,所以我将各实体模型中加入了相应映射对象,来实现数据库映射读写懒加载,拿商品举例,商品代码如下。
/**
* 商品实体
*/
@Entity
@Table(name = "items")
@Data
@Accessors(chain = true)
public class ItemEntity extends Auditable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
// 商品描述
@Column(nullable = false, length = 500)
@NotNull
@NotBlank
private String description;
// 商品价格
@Column(nullable = false, length = 10)
private double price;
// 商品数量
@Column(nullable = false, length = 10)
private int stockQuantity;
// 商品图片
@Column(nullable = false, length = 150)
@NotBlank
@NotNull
private String picUrl;
@Column(nullable = false, length = 50)
@NotBlank
@NotNull
private String productName;
@Column(nullable = false, length = 11)
private int typeId;
@Transient
private ItemTypeEntity itemTypeEntity;
}
商品中包含一个商品类型的属性 ItemTypeEntity
,通过 @Transient
注解来使得该属性不参与数据库的读写。
用户角色认证,使用 spring-security 框架,进行角色假认证,在从数据库读取用户时,直接设置用户权限为 user,因为普通用户角色与管理员用户角色基本上不用互通,而商品的查询不需要进行认证,游客也可进行访问。
用户客户端实现
客户端采用 vue 框架,实现商品的查找,购物车的显示,商品加入购物车等操作。
商城主页
商品信息
购物车
管理员系统实现
管理员系统中需要新增功能:对用户的禁用与启用,商品的修改和增加。
- 新建 admin 实体类
- 新建 AdminRepository 接口
- 新建使用 AdminService 进行登录的验证
- 在 Controller 中增加几个 Controller 用于管理员的相关操作
管理员客户端实现
同样使用 vue 框架,效果图如下:
面板
所有用户
所有商品
商品修改
spring-security 鉴权优化
将 spring-security 功能分别从 admin 与 Web 模块中提取出来整合到一个新的模块中,修改原实体类中的假认证(用户角色直接指定),转变成从数据库中读取。修改后的 Security 配置如下:
@Override
public void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeRequests()
.antMatchers("/api/order/**", "/api/cart/**").hasRole(UserRole.USER.name)
.antMatchers("/api/admin/**").hasRole(UserRole.ADMIN.name)
.antMatchers("/api/user/**").authenticated()
.and()
.formLogin().loginProcessingUrl("/api/login").loginPage("/loginPage")
.usernameParameter("username").passwordParameter("password")
.successHandler((httpServletRequest, httpServletResponse, authentication) -> {
Object principal = authentication.getPrincipal();
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter writer = httpServletResponse.getWriter();
httpServletResponse.setStatus(200);
Map<String, Object> map = new HashMap<>(2);
map.put("status", 200);
map.put("msg", principal);
ObjectMapper objectMapper = new ObjectMapper();
writer.write(objectMapper.writeValueAsString(map));
writer.flush();
writer.close();
})
.failureHandler((httpServletRequest, httpServletResponse, e) -> {
httpServletResponse.setContentType("application/json;charset=utf-8");
PrintWriter writer = httpServletResponse.getWriter();
httpServletResponse.setStatus(401);
Map<String, Object> map = new HashMap<>(2);
map.put("status", 401);
if (e instanceof LockedException) {
map.put("msg", "账户被锁定,登录失败");
} else if (e instanceof BadCredentialsException) {
map.put("msg", "用户名或密码错误");
} else if (e instanceof DisabledException) {
map.put("msg", "账户被禁用,登录失败");
} else if (e instanceof AccountExpiredException) {
map.put("msg", "账户过期,登录失败");
} else if (e instanceof CredentialsExpiredException) {
map.put("msg", "密码过期,登录失败");
} else {
map.put("msg", "登录失败");
}
ObjectMapper objectMapper = new ObjectMapper();
writer.write(objectMapper.writeValueAsString(map));
writer.flush();
writer.close();
})
.permitAll()
.and()
.logout().logoutUrl("/api/logout").clearAuthentication(true).invalidateHttpSession(true)
.addLogoutHandler((httpServletRequest, httpServletResponse, authentication) -> {
})
.logoutSuccessHandler((httpServletRequest, httpServletResponse, authentication) -> httpServletResponse.sendRedirect("/"))
.and().csrf().disable();
}
修改数据库,增加用户角色表与用户、角色中间表。修改后的数据库如下:
辅助功能增加
API 文档生成
向 Web 和 admin 模块中添加 swagger2 依赖,修改 controller 类,增加相关注解与描述即可生成文档。
应用端点监控
Actuator 是 Spring Boot 提供的对应用系统的自省和监控的集成功能,可以查看应用配置的详细信息,例如自动化配置信息、创建的 Spring beans 以及一些环境属性等。
向 Web 中增加 actuator 依赖,在浏览器地址栏访问 http://localhost:8080/actuator
即可看到如下信息。
在 idea 环境下也可以看到如下信息:
利用 webpack 模拟分布式
前端开发打包工具 webpack 提供了 dev-server 功能,可以使前端在开发期间完全独立进行运行,而无需部署。dev-server 需配置一套转发规则,将满足条件的请求转发到指定 host 上,而完全解决请求发送问题。
代理规则详细配置如下:
devServer: {
// overlay: { // 让浏览器 overlay 同时显示警告和错误
// warnings: true,
// errors: true
// },
// open: false, // 是否打开浏览器
// host: "localhost",
// port: "8080", // 代理断就
// https: false,
// hotOnly: false, // 热更新
proxy: {
"/api": {
target:
"http://localhost:8080", // 目标代理接口地址
secure: false,
changeOrigin: true, // 开启代理,在本地创建一个虚拟服务端
// ws: true, // 是否启用websockets
pathRewrite: {
"^/api": "/api"
}
}
}
}
以上配置是将以 /api
开头的请求转发到:8080 端口上。
我们的项目分为用户使用的前台应用与管理员使用的后台应用,而管理员用户有着比普通用户更高的权限,所以普通用户的一些请求操作管理员也应该是可以完成的,但是如果将这些 controller 再编写一遍不仅工作量加大,而且没达到代码复用的效果。
利用 webpack 可以将不同请求转发到不同 host 上,而不影响用户使用。
♻️ 资源
大小: 722KB
➡️ 资源下载:https://download.csdn.net/download/s1t16/87354176
相关文章
- java高级用法之:JNA中的回调
- 在java中使用JMH(Java Microbenchmark Harness)做性能测试
- List多个字段标识过滤 IIS发布.net core mvc web站点 ASP.NET Core 实战:构建带有版本控制的 API 接口 ASP.NET Core 实战:使用 ASP.NET Core Web API 和 Vue.js 搭建前后端分离项目 Using AutoFac
- Vue - 完美解决小数的四则运算(加减乘除)导致精度丢失问题,提供详细计算示例代码vue数据计算丢失精度
- Java Date Time 教程-java.sql.Date
- Java并发JUC(java.util.concurrent)JMM内存模型
- Java详解,java后端应届生面试题
- 【Java】怎么回答java垃圾回收机制
- vue.js-详解三大流行框架VUE_快速进阶前端大咖-Vue基础
- Java网页数据采集器[中篇-数据存储]【转载】
- 基于Java+Vue+MySQL实现(Web)电影院会员管理系统【100010345】
- java的Comparator和Comparable
- Java升级那么快,多个版本如何灵活切换和管理?
- vue学习笔记五:Jquery VS Vue之事件监听明细对照
- vue学习笔记十:Jquery VS Vue之页面动画明细对照
- Java中将JSON格式的数据转换成对应的Bean、Map、List数据
- 都2020年了,这5个java IDE神器你还不知道?
- java 新创建的类要重写的方法
- Redmonk发布Java框架流行度调研结果
- 《青花瓷》JAVA版:周杰伦告诉你怎么学Java
- java Lambda表达式
- jenkins配置自动部署java程序
- Vue学习第27天——路由vue-router的详解及案例练习
- java.util.concurrent.Exchanger应用范例与原理浅析--转载
- 从零学Java(22)之do while 语句
- vue-解决Vue打包上线之后部分CSS不生效的问题
- Java中Spring、SpringMVC、MyBatis、Hibernate等相关问答
- Java hutool/java 常用方法
- vue 登录页背景-粒子特效(Vue-Particles)