shopping-web项目逻辑分析

shopping-web项目逻辑分析
mengnankkzhou项目结构
1 | historical-voting-web/ |
核心功能模块
4.1 用户认证模块
4.1.1 JWT认证流程
用户登录流程:
1
用户登录 -> 验证凭据 -> 生成JWT令牌(访问令牌+刷新令牌)-> 返回令牌
流程:
在serviceimpl中实现login方法:
从数据库中select有没有输入的username,用户注册状态是不是0,用户是否是被封锁,密码是不是对。
然后生成access token 和refreash token
使用redis,opsforvalue.set设置key-vaule和过期时间
把他们放入map集合里面,然后返回token
JWT加密:
采用HS512,然后创建payload,里面存入username。
1 | return Jwts.builder() |
请求认证流程:
1
请求 -> JwtAuthenticationFilter拦截 -> 验证Token -> 提取用户信息 -> 放行请求
JwtAuthenticationFilter:
尝试直接使用access token,从requset的头里提取header.startsWith(“Bearer “)开头的,然后跳过前面的前缀,获取到token
access token刷新,claims必须要合法,然后从claims里获取username
然后检查token是不是在redis的黑名单中,然后看redis是不是存了这个令牌,get出来,然后requset.setAttribute加到请求上,然后返回response
然后refresh token刷新,
先是从request看到刷新令牌,然后先验证是不是和redis中的相同
相同的话,再生成一个新的access token令牌,然后更新redis中的令牌
把他加到resonse的响应头里,然后去看放不放行请求。
注册的话,就是使用mailSender去发送验证码,只有验证码对才可以进行注册操作,创建新用户,写入数据库。
4.1.2 OAuth2认证流程
GitHub OAuth2登录流程:
1 | 用户点击GitHub登录 -> 重定向到GitHub -> 用户授权 -> 回调接口 -> 创建/更新用户信息 -> 生成JWT |
4.2 用户管理模块
主要接口
1 |
|
4.3 文件存储+处理模块
- 支持图片、视频上传
- 支持生成缩略图
- 文件存储位置可配置(本地/腾讯云COS)
📌 文件合法性校验(FileUtils)
在用户上传视频文件时,系统会通过 FileUtils 工具类对文件进行校验,主要包括以下几项逻辑:
- 单个文件大小限制:系统设定上传视频的最大允许体积(如 100MB),超过则直接拒绝上传。
- 总上传大小控制:可根据用户标识或 IP,设置每日或每小时内上传视频的总大小上限,用于防止恶意刷带宽。
- 文件类型判断:仅允许特定的视频类型(如 MP4、AVI 等)通过,防止伪装文件上传。
该工具类在上传接口中被调用,作为服务端对用户输入的第一道校验防线。
🧩 策略模式设计:TranscodingStrategy
系统中使用了策略模式来支持不同的转码协议(如 HLS、DASH),定义了统一的策略接口 TranscodingStrategy,它约定了所有转码实现类都必须提供统一的转码方法。
该接口屏蔽了具体的命令细节,为后续新增新格式(如 WebM、AV1)提供了扩展点。
🏗️ 抽象策略实现类:AbstractTranscodingStrategy
系统设计了一个抽象类 AbstractTranscodingStrategy 来统一封装转码过程的通用步骤。主要逻辑包括:
- 组装转码命令:根据输入路径、输出路径、分辨率等参数拼接出 FFmpeg 的命令行。
- 调用系统进程:通过
ProcessBuilder.start()执行命令,完成实际的视频转码操作。 - 异常捕获与输出校验:判断进程返回值是否为 0,确认转码是否成功,并统一抛出异常或写入日志。
这样,具体策略类只需关注自己的格式命令,不用重复通用逻辑。
🔀 具体策略类:HLS 与 DASH 实现
系统实现了两个具体的转码策略:
- HLSTranscodingStrategy:使用
.m3u8+ 分片方式转码,适用于直播或渐进式加载。 - DASHTranscodingStrategy:使用
.mpd格式与多码率轨道,适用于 ABR(自适应码率)播放。
每个策略类内部根据自己的输出格式构建专属的 FFmpeg 命令,并通过抽象类封装的方法执行转码。
策略类使用 @Component 注册为 Spring Bean,支持通过名称注入选择。
🏭 策略工厂类:TranscodingStrategyFactory
为了按需获取具体的策略实现,系统设计了一个工厂类:
- 构造时收集策略 Bean:在 Spring 初始化过程中,将所有实现了
TranscodingStrategy接口的 Bean 收集进 Map,key 为策略名(如 “hls”、”dash”)。 - 根据名称获取策略:对外提供
get(String name)方法,根据输入的策略名称,返回对应的实现类。 - 支持动态扩展:后续新增策略只需实现接口并加
@Component即可被自动注册到工厂中。
该工厂类被视频服务调用,用于根据配置或用户选择的协议动态选择转码策略。
VideoServiceImpl 服务实现逻辑说明:
- 视频上传与转码处理
- 视频上传路径配置:通过配置注入
videoUploadPath和thumbnailPath,用于存储上传的视频文件和封面缩略图。 - 视频转码处理 (
processVideo):- 通过
ffmpeg命令行对上传视频进行转码,统一编码格式(H.264)和音频编码(AAC),并启用快速启动优化。 - 转码完成后调用封面提取方法。
- 若转码或封面提取失败,抛出自定义异常
FileProcessException,确保上传流程异常可控。
- 通过
- 封面缩略图提取 (
extractThumbnail):- 利用
ffmpeg截取视频的第一帧作为缩略图,存放到指定目录。 - 确保缩略图文件命名与视频文件对应,方便管理和访问。
- 利用
- ABR(自适应码率)转码任务提交
- 多分辨率转码 (
submitTranscoding):- 针对预设的多个分辨率(如 720p、480p、360p),先通过
ffmpeg对视频进行缩放处理,生成不同清晰度的视频片段。 - 使用线程池异步执行各分辨率转码任务,提高并发性能,避免阻塞主流程。
- 转码后调用策略工厂,获取指定格式(如 HLS)的转码策略,执行格式封装转码。
- 任何转码失败都会被捕获并记录日志,保证服务稳定。
- 针对预设的多个分辨率(如 720p、480p、360p),先通过
- 播放记录与访问限流
- 播放记录统计 (
recordView):- 使用 Redis 以用户 IP 作为唯一标识限制重复计数,避免刷播放量。
- 通过
setIfAbsent设置一分钟的缓存有效期,实现短时间内对同一视频同一 IP 只计数一次。 - 播放量计数存在 Redis,减少数据库压力。
- 定时同步播放量 (
syncViewCounts):- 使用定时任务每 5 分钟将 Redis 中缓存的播放量批量同步到数据库。
- 同步后清理缓存,保证数据一致性和高效。
- 点赞与点踩功能
- 点赞与点踩操作:
- 采用 Redis Set 结构存储点赞和点踩的用户 ID,保证用户只能点赞或点踩其中一个。
- 点赞时自动移除对应的点踩记录,点踩亦然,确保数据互斥。
- 读取点赞和点踩数量时,直接返回 Redis Set 的大小,实时且性能高。
- 分享统计
- 分享次数统计:
- 通过 Redis 字符串计数,记录视频被分享的总次数。
- 读写均通过 Redis 完成,避免频繁访问数据库。
- 标签分页查询
- 视频标签分页查询 (
pageByTags):- 支持根据标签关键字模糊查询视频列表。
- 使用 MyBatis-Plus 的分页功能,按发布时间倒序排列,方便前端分页展示。
- 如果标签为空,则返回全部视频列表。
4.3 优惠券模块
4.3.1 优惠券类型
- 满减券:满足指定金额后减免固定金额
- 折扣券:按比例折扣
- 无门槛券:直接减免固定金额
- 限时券:在指定时间段内有效
4.3.2 主要接口
1 |
|
4.3.3 优惠券业务流程
优惠券创建流程:
1
管理员创建优惠券 -> 设置优惠券规则 -> 设置发放策略 -> 保存优惠券信息
优惠券发放流程:
1
触发发放条件 -> 检查发放规则 -> 创建用户优惠券记录 -> 发送优惠券到账通知
优惠券使用流程:
1
用户选择优惠券 -> 验证使用条件 -> 计算优惠金额 -> 标记优惠券已使用 -> 应用优惠
4.4 限流AOP注释
限流注解:RateLimit
定义了这个注解,
1 | @Target(ElementType.METHOD) |
这个注解只能用在方法上,注解信息会保留到运行时,这允许通过反射读取注解内容,用于 AOP(切面)处理。可以通过@Around来拦截
里面定义了标识,每秒最大的访问次数,默认五次,然后
RateLimitUtils:工具类
基于内存桶(Bucket4j)限流实现的核心方法,使用 ConcurrentHashMap 存储每个唯一 key 对应的令牌桶。
然后创键一个限流规则,容量为permitsPerSecond,然后Refill每秒
然后返回这个使用这个限流规则的Bucket4j作为value
Aspect类
获取注解参数:key(限流维度)、permitsPerSecond(限流速率)、message(失败提示)
获取客户端 IP + 方法名 作为限流键(若未自定义)
使用 Bucket4j 获取或创建对应的桶对象
使用 tryConsume(1) 判断是否允许访问,调用限流器看是不能是访问,失败就返回msg
@Around规定切入点
还加上了全局处理异常,如果类型是限流的这个异常,给出429,说明当前是限流了。
4.5 AOP实现业务和登录的跟踪












