实战篇 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 中配置的静态资源拦截目录保持一致。
相关推荐
码兄科技3 小时前
Java AI智能体开发实战:从零构建智能对话系统指南
java·开发语言·人工智能
折哥的程序人生 · 物流技术专研4 小时前
第8篇:六大设计原则在工厂模式中的体现
java·设计模式·设计原则·工厂模式·编程进阶·扩充系列
小明bishe184 小时前
计算机毕业设计之基于JAVA的植物科普网站
java·spring boot·spring·架构·课程设计
r_oo_ki_e_4 小时前
Java Map 集合学习笔记
java·笔记·学习
SL-staff5 小时前
智慧园区2000+设备统一管理:JVS-IoT如何降低运维成本40%
java·开发语言·物联网·智慧园区·设备管理·运维优化·jvs-iot
咖啡八杯5 小时前
GoF设计模式——模板方法模式
java·后端·spring·设计模式
爱笑的源码基地6 小时前
一款全开源的信创云PACS影像云平台解决方案,支持多模态医学影像处理(CT/MR/DR/超声/病理等)
java·源码·国产化·pacs·云影像·区域pacs
我命由我123456 小时前
Android 开发问题:ClickableSpan 的点击事件没有生效
java·java-ee·android studio·android jetpack·android-studio·android runtime
万亿少女的梦1686 小时前
基于Python的高考志愿填报辅助系统设计与实现
java·spring boot·python·mysql·vue
微信开发api-视频号协议7 小时前
企业微信外部群开发自动化实践过程
java·前端·微信·自动化·企业微信·ipad