1. 项目介绍
尚品甄选是一个B2C模式的电子商务平台,包含后台管理系统和前台用户系统。项目采用前后端分离开发模式,基于SpringBoot + SpringCloud微服务架构。
后台管理系统后端采用的是单体架构【就是把所有的功能写在同一个项目中】,如下所示:
前台用户系统的后端采用的是微服务系统架构【一个模块就是一个独立服务】,如下图所示:
项目使用技术栈:
后端:Spring Boot、Spring Cloud Alibaba、Redis、EasyExcel、Minio、短信平台、支付宝支付等
前端:Vue3、ES6、Node.js、NPM、Element Plus、ECharts等
2. 后台系统
2.1 工程结构图
spzx-parent: 尚品甄选项目的父工程,进行项目依赖的统一管理,打包方式为pom
spzx-common: 尚品甄选项目公共模块的管理模块,父工程为spzx-parent
common-util: 工具类模块,父工程为spzx-common
common-service:公共服务模块,父工程为spzx-common
spzx-model: 尚品甄选实体类模块
spzx-manager: 尚品甄选项目后台管理系统的后端服务
2.2 统一结果实体类
前端需要从返回结果中解析出来三部分的数据:
// code:自定义的业务状态码,前端会根据具体的业务状态码给出不同的处理。比如:200表示成功、非200都是失败
// message:响应消息。比如:登录成功、用户名或者密码错误、用户无权限访问
// data:后端返回给前端的业务数据
const { code, data, message } = await Login(state.model)
在spzx-model模块,定义Result实体类:
@Data
public class Result<T> {
//返回码
private Integer code;
//返回消息
private String message;
//返回数据
private T data;
// 私有化构造
private Result() {}
// 返回数据
public static <T> Result<T> build(T body, Integer code, String message) {
Result<T> result = new Result<>();
result.setData(body);
result.setCode(code);
result.setMessage(message);
return result;
}
}
2.3 登录流程
令牌:登录成功以后系统给当前登录用户分配的唯一标识。前端系统获取到后端返回的令牌的时候就会把令牌存储起来。
登录校验:
更新Redis中数据的存活时间的主要目的就是为了保证用户在使用该系统的时候,Redis中会一直保证用户的登录状态,如果用户在30分钟之内没有使用该系统,那么此时登录超时。此时用户就需要重新进行登录。将从Redis中获取到的用户存储到ThreadLocal中,这样在一次请求的中就可以在controller、service、mapper中获取用户数据。
跨域问题:
在浏览器中存在一种安全策略就是同源策略,同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
CORS解决跨域: 添加一个配置类配置跨域请求
@Component
public class WebMvcConfiguration implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 添加路径规则
.allowCredentials(true) // 是否允许在跨域的情况下传递Cookie
.allowedOriginPatterns("*") // 允许请求来源的域规则
.allowedMethods("*")
.allowedHeaders("*") ; // 允许所有的请求头
}
}
2.4 权限管理
权限管理所涉及到数据库表以及其对应关系如下所示:
2.5 商品管理
SPU:SPU = Standard Product Unit (标准化产品单元), SPU是商品信息聚合的最小单位,是一组可复用、易检索的标准化信息的集合。通俗点讲就是泛指一类商品,这种商品具有相同的属性。
SKU:SKU = stock keeping unit(库存量单位) SKU即库存进出计量的单位(买家购买、商家进货、供应商备货、工厂生产都是依据SKU进行的)。SKU是物理上不可分割的最小存货单元。也就是说一款商品,可以根据SKU来确定具体的货物存量。
2.6 订单统计
用户在前台系统中购买完商品以后生成对应的订单数据,在后台管理系统中就可以查看到订单数据,在后台管理系统中也可以对订单数据进行统计,形成图形化报表【柱状图、饼状图、曲线图、散点图…】用于数据分析。
定时任务程序每天凌晨2点运行一次,从order_info表中查询出前一天的订单总金额数据,然后将总金额数据写入到统计结果表中;当用户发起查询订单统计结果请求的时候,此时后端系统从统计结果表中查询到对应的数据返回给前端系统;前端系统通过Echarts的柱状图展示数据。
Spring Task: Spring Task是Spring框架中的一个定时任务调度模块,它提供了一种简单的方式来实现基于时间的调度任务。
cron表达式:
定时任务程序代码实现:
@Component
@Slf4j
public class OrderStatisticsTask {
@Autowired
private OrderInfoMapper orderInfoMapper;
@Autowired
private OrderStatisticsMapper orderStatisticsMapper;
@Scheduled(cron = "0 0 2 * * ?")
public void orderTotalAmountStatistics() {
String createTime = DateUtil.offsetDay(new Date(), -1).toString(new SimpleDateFormat("yyyy-MM-dd"));
OrderStatistics orderStatistics = orderInfoMapper.selectOrderStatistics(createTime);
if(orderStatistics != null) {
orderStatisticsMapper.insert(orderStatistics) ;
}
}
}
2.7 记录日志
安全性:操作日志可以记录管理员操作行为,以此来监控和防止管理员滥用权限或进行其他不当操作。如果后台管理系统没有记录操作日志,那么一旦出现不当操作,就无法对其进行追踪和定位,造成不可估量的安全风险。
追溯性:操作日志可以帮助管理员及时发现问题,并可以通过日志进行快速定位和处理。例如某个用户投诉自己的订单异常,管理员可以直接通过查询该订单的操作日志,找到问题所在并进行修改或解决。
定义一个切面类,并且在该切面类中提供一个环绕通知方法,代码如下所示:
@Aspect
@Component
@Slf4j
public class LogAspect { // 环绕通知切面类定义
@Around(value = "@annotation(sysLog)")
public Object doAroundAdvice(ProceedingJoinPoint joinPoint , Log sysLog) {
String title = sysLog.title();
log.info("LogAspect...doAroundAdvice方法执行了"+title);
System.out.println("LogAspect...doAroundAdvice方法执行了"+title);
Object proceed = null;
try {
proceed = joinPoint.proceed(); // 执行业务方法
} catch (Throwable e) { // 代码执行进入到catch中,业务方法执行产生异常
throw new RuntimeException(e);
}
return proceed ; // 返回执行结果
}
}
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import(value = LogAspect.class) // 通过Import注解导入日志切面类到Spring容器中
public @interface EnableLogAspect {
}
3. 前台系统
Nacos注册中心:
服务提供方在启动的时候,会向注册中心注册自己服务的详情信息(ip、端口号等)。在注册中心中会维护一张服务清单,保存这些注册信息,注册中心需要以心跳的方式去监测清单中的服务是否可用,如果不可用,需要在服务清单中剔除不可用的服务。
服务消费方向服务注册中心咨询服务,并获取所有服务的实例清单,然后按照指定的负载均衡算法从服务清单中选择一个服务实例进行访问。
Gateway组件:
Gateway是在spring生态系统之上构建的API网关服务,基于Spring5,SpringBoot2和Project Reactor等技术。Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能,例如:熔断、限流、重试等。
SpringCloud Gateway是SpringCloud的一个全新项目,基于Spring5.X+SpringBoot2.X和Project Reactor等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的API路由管理方式。
为了提升网关的性能,SpringCloud Gatway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通讯框架Netty。
SpringCloud Gateway的目标提供统一的路由方式且基于Filter链的方式提供了网关基本的功能,例如:安全、监控/指标、和限流。
Route(路由):路由是构建网关的基本模块,它由ID,目标URI,一系列的断言和过滤器组成,如果断言为true则匹配该路由。
Predicate(断言):参考的是java8的java.util.function.Predicate开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数)。
Filter(过滤):指的是Spring框架中GatewayFilter的实例,使用过滤器,可以在请求被路由前或者之后对请求进行修改。。
购物车请求响应流程:
订单流程:
4. 项目功能