实战篇 01. 达人探店 - 发布探店笔记学习文档

📚 实战篇 01. 达人探店 - 发布探店笔记学习文档

一、 业务场景介绍

"达人探店"的核心玩法是:用户去某家商户消费后,可以发布包含图片和文字的"探店笔记"(类似于发朋友圈或小红书)。其他用户可以查看这些笔记,并进行点赞、评论等互动。

在"发布探店笔记"这个首要环节中,主要包含两个核心动作:

  1. 上传图片: 用户在前端选择图片并上传,后端需要将图片保存起来,并返回图片的访问链接。
  2. 发布笔记: 用户填写标题、正文,关联商户,连同刚才的图片链接一起提交给后端,后端将其存入数据库。

二、 核心业务流程拆解

1. 图片上传接口 (uploadImage)

  • 接收请求: 前端会将图片以表单数据(MultipartFile)的形式发送给后端。

  • 保存图片: * 在真实的生产环境中,通常会使用第三方对象存储服务(如 阿里云 OSS、七牛云 等)。

    • 在我们的实战学习中,为了方便,通常会将图片保存在 Nginx 服务器的指定静态资源目录下(例如 /nginx-1.18.0/html/hmdp/imgs/)。
  • 返回路径: 图片保存成功后,后端需要生成一个该图片的相对或绝对访问路径,封装在 Result 中返回给前端,前端拿到路径后用于数据回显和后续的笔记提交。

2. 发布笔记接口 (saveBlog)

  • 接收请求: 前端将组装好的笔记数据(Blog 对象,包含 title, images, content, shopId 等)发送给后端。
  • 补充用户信息: 前端传过来的数据中往往不包含"是谁发的"。我们需要在后端通过拦截器保存的 ThreadLocal 来获取当前登录用户的 ID。
  • 保存入库: 将补全了用户 ID 的 Blog 对象调用 MyBatisPlus 的 save() 方法存入 tb_blog 数据库表中。
  • 返回结果: 返回生成的笔记 ID 给前端,代表发布成功。

三、 Java 后端代码实现思路

1. 图片上传核心代码逻辑

图片上传的难点在于生成唯一的文件名(防止图片重名被覆盖)以及目录的管理。

Java

typescript 复制代码
@PostMapping("blog/upload")
public Result uploadImage(@RequestParam("file") MultipartFile image) {
    try {
        // 1. 获取原始文件名
        String originalFilename = image.getOriginalFilename();
        // 2. 生成唯一的新文件名 (可以使用 UUID,并拼接上原始文件后缀)
        String suffix = StrUtil.subAfter(originalFilename, ".", true);
        String name = UUID.randomUUID().toString(true) + "." + suffix;
        
        // 3. 将文件保存到 Nginx 的静态资源目录
        // 注意:这里的 SystemConstants.IMAGE_UPLOAD_DIR 需要配置为你本地的 nginx 对应目录
        File dest = new File(SystemConstants.IMAGE_UPLOAD_DIR, name);
        image.transferTo(dest);
        
        // 4. 返回图片的访问相对路径
        return Result.ok(name);
    } catch (IOException e) {
        log.error("图片上传失败", e);
        return Result.fail("图片上传失败");
    }
}

2. 保存笔记核心代码逻辑

这段逻辑非常纯粹,就是标准的单表插入操作,但一定要记得关联当前用户。

Java

less 复制代码
@PostMapping("blog")
public Result saveBlog(@RequestBody Blog blog) {
    // 1. 获取当前登录用户
    // UserHolder 是我们之前封装的基于 ThreadLocal 的工具类
    Long userId = UserHolder.getUser().getId();
    
    // 2. 设置探店笔记的作者 ID
    blog.setUserId(userId);
    
    // 3. 保存探店笔记到数据库 (MyBatisPlus 提供的 save 方法)
    boolean isSuccess = blogService.save(blog);
    
    if(!isSuccess){
        return Result.fail("发布笔记失败!");
    }
    // 4. 返回笔记的 ID
    return Result.ok(blog.getId());
}

四、 学习总结与防坑指南

  1. 温故知新:saveBlog 方法中,我们再次使用了 UserHolder.getUser().getId()。这证明了我们之前设计的基于拦截器和 ThreadLocal 的用户鉴权机制是非常通用且强大的,在任何业务接口中都能随时无缝获取当前用户信息。
  2. Nginx 目录配置: 在做图片上传测试时,最容易踩的坑就是图片上传成功了,但前端页面刷不出来。这通常是因为 Nginx 的目录配置不对,或者上传的文件路径与 Nginx 的代理规则不匹配。一定要确保 Java 代码中写入的目录与 Nginx nginx.conf 中配置的静态资源拦截目录保持一致。
相关推荐
小怪吴吴1 小时前
idea 开发Android
android·java·intellij-idea
嘻嘻哈哈樱桃1 小时前
牛客经典101题题解集--动态规划
java·数据结构·python·算法·职场和发展·动态规划
一次旅行1 小时前
IDEA安装CC GUI新手指南
java·ide·intellij-idea
超梦dasgg1 小时前
Spring AI 智能航空助手项目实战
java·人工智能·后端·spring·ai编程
counting money2 小时前
Spring框架基础(配置篇)
java·后端·spring
秋92 小时前
OceanBase与GreatSQL在Java应用中的性能调优方法有哪些?
java·开发语言·oceanbase
今天又在写代码3 小时前
并发问题解决
java·开发语言·数据库
老王以为3 小时前
前端视角下的 Java
java·javascript·程序员
看腻了那片水3 小时前
开源一个对业务代码零侵入的透明数据治理框架 —— 【sangsang】
java·mybatis