当前位置: 首页 > news >正文

基于Java+VUE+MariaDB实现(Web)仿小米商城

仿小米商城

环境安装

nodejs

maven

JDK11

运行

mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm 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 OneToOne
  • user shopping_cart OneToOne
  • user order OneToMany
  • item shopping_cart ManyToOne
  • item order ManyToOne
  • address user_detail ManyToOne
  • address order OneToOne
  • item 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@NotBlankprivate String description;// 商品价格@Column(nullable = false, length = 10)private double price;// 商品数量@Column(nullable = false, length = 10)private int stockQuantity;// 商品图片@Column(nullable = false, length = 150)@NotBlank@NotNullprivate String picUrl;@Column(nullable = false, length = 50)@NotBlank@NotNullprivate String productName;@Column(nullable = false, length = 11)private int typeId;@Transientprivate ItemTypeEntity itemTypeEntity;
}

商品中包含一个商品类型的属性 ItemTypeEntity,通过 @Transient 注解来使得该属性不参与数据库的读写。

用户角色认证,使用 spring-security 框架,进行角色假认证,在从数据库读取用户时,直接设置用户权限为 user,因为普通用户角色与管理员用户角色基本上不用互通,而商品的查询不需要进行认证,游客也可进行访问。

用户客户端实现

客户端采用 vue 框架,实现商品的查找,购物车的显示,商品加入购物车等操作。

商城主页
 


商品信息
 


购物车

管理员系统实现

管理员系统中需要新增功能:对用户的禁用与启用,商品的修改和增加。

  1. 新建 admin 实体类
  2. 新建 AdminRepository 接口
  3. 新建使用 AdminService 进行登录的验证
  4. 在 Controller 中增加几个 Controller 用于管理员的相关操作

管理员客户端实现

同样使用 vue 框架,效果图如下:

面板
 


所有用户
 


所有商品
 


商品修改

spring-security 鉴权优化

将 spring-security 功能分别从 admin 与 Web 模块中提取出来整合到一个新的模块中,修改原实体类中的假认证(用户角色直接指定),转变成从数据库中读取。修改后的 Security 配置如下:

    @Overridepublic 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, // 是否启用websocketspathRewrite: {"^/api": "/api"}}}}

以上配置是将以 /api 开头的请求转发到:8080 端口上。

我们的项目分为用户使用的前台应用与管理员使用的后台应用,而管理员用户有着比普通用户更高的权限,所以普通用户的一些请求操作管理员也应该是可以完成的,但是如果将这些 controller 再编写一遍不仅工作量加大,而且没达到代码复用的效果。

利用 webpack 可以将不同请求转发到不同 host 上,而不影响用户使用。

相关文章:

  • conda指定包安装的channel
  • linux 用户态时间性能优化工具perf/strace/gdb/varlind/gprof
  • Linux中MySQL的逻辑备份与恢复
  • Vue:Ajax
  • 微前端 - Module Federation使用完整示例
  • 深入理解PHP安全漏洞:文件包含与SSRF攻击全解析
  • 「Java基本语法」代码格式与注释规范
  • K8S认证|CKS题库+答案| 6. 创建 Secret
  • NLP学习路线图(三十):微调策略
  • 【K8S系列】Kubernetes 中 Pod(Java服务)启动缓慢的深度分析与解决方案
  • YOLO11解决方案之分析
  • PyTorch 中contiguous函数使用详解和代码演示
  • 【科研绘图系列】R语言绘制论文组图(multiple plots)
  • 【20250607接单】Spark + Scala + IntelliJ 项目的开发环境配置从零教学
  • Redis 实现分布式锁:深入剖析与最佳实践(含Java实现)
  • 【精选】计算机毕业设计Python Flask海口天气数据分析可视化系统 气象数据采集处理 天气趋势图表展示 数据可视化平台源码+论文+PPT+讲解
  • Java实现飞机射击游戏:从设计到完整源代码
  • ubuntu 22.04虚拟机配置静态IP
  • OpenWrt:使用ALSA实现边录边播
  • 【数据结构】6. 时间与空间复杂度
  • 孙红雷做的二手车网站/山东潍坊疫情最新消息
  • 网站建设实习小结/手机端搜索引擎排名
  • 聊城做网站优化/长沙网站推广
  • 江苏优化网站公司/搜索引擎优化排名工具
  • 做网站用什么服务器比较好/坚持
  • 做网站最好的软件是/软文广告是什么意思