08-黑马点评项目发布笔记和查看笔记功能的实现

发布笔记

数据模型

tb_blog探店笔记表,包含笔记的标题、文字、图片等

在这里插入图片描述

tb_blog探店笔记表对应的实体类

  • 增加用户图标和和用户姓名以及是否被点赞过了的字段,这些字段不属于Blog表只是为了实现在展示笔记的时候同时展示用户的信息
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tb_blog")
public class Blog implements Serializable {
    private static final long serialVersionUID = 1L;
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 商户id
     */
    private Long shopId;
    /**
     * 用户id
     */
    private Long userId;
    /**
     * 用户图标,不属于Blog表中的字段
     */
    @TableField(exist = false)
    private String icon;
    /**
     * 用户姓名,不属于Blog表中的字段
     */
    @TableField(exist = false)
    private String name;
    /**
     * 是否点赞过了
     */
    @TableField(exist = false)
    private Boolean isLike;
    /**
     * 标题
     */
    private String title;
    /**
     * 探店的照片,最多9张,多张以","隔开
     */
    private String images;
    /**
     * 探店的文字描述
     */
    private String content;
    /**
     * 点赞数量
     */
    private Integer liked;
    /**
     * 评论数量
     */
    private Integer comments;
    /**
     * 创建时间
     */
    private LocalDateTime createTime;
    /**
     * 更新时间
     */
    private LocalDateTime updateTime;
}

界面原型

用户发布笔记时选择要上传的图片,笔记标题和笔记内容以及关联的商户

在这里插入图片描述

后端处理请求

第一步: 在UploadController中实现图片上传的功能,实际开发中图片一般会放在nginx上或者是云存储上

public class SystemConstants {
    // 指定图片所在的地址,这里我们放在自己的nginx服务所在的目录
    public static final String IMAGE_UPLOAD_DIR = "D:\\dev\\nginx-1.18.0\\html\\hmdp\\imgs\\";
    // 指定用户昵称的前缀
    public static final String USER_NICK_NAME_PREFIX = "user_";
    // 指定分页查询的默认页数
    public static final int DEFAULT_PAGE_SIZE = 5;
    // 指定分页查询的最大页数
    public static final int MAX_PAGE_SIZE = 10;
}
@Slf4j
@RestController
@RequestMapping("upload")
public class UploadController {
    @PostMapping("blog")
    public Result uploadImage(@RequestParam("file") MultipartFile image) {
        try {
            // 获取上传文件的文件名称
            String originalFilename = image.getOriginalFilename();
            // 生成新文件名,处理文件重名问题
            String fileName = createNewFileName(originalFilename);
            // 保存文件到自己指定的位置下
            image.transferTo(new File(SystemConstants.IMAGE_UPLOAD_DIR, fileName));
            // 返回文件名作为图片的地址
            log.debug("文件上传成功,{}", fileName);
            return Result.ok(fileName);
        } catch (IOException e) {
            throw new RuntimeException("文件上传失败", e);
        }
    }
}

// 更改上传的文件名并存储到自己指定的目录下
private String createNewFileName(String originalFilename) {
    // 获取后缀
    String suffix = StrUtil.subAfter(originalFilename, ".", true);
    // 生成目录
    String name = UUID.randomUUID().toString();
    int hash = name.hashCode();
    int d1 = hash & 0xF;
    int d2 = (hash >> 4) & 0xF;
    // 判断目录是否存在
    File dir = new File(SystemConstants.IMAGE_UPLOAD_DIR, StrUtil.format("/blogs/{}/{}", d1, d2));
    if (!dir.exists()) {
        dir.mkdirs();
    }
    // 生成文件名
    return StrUtil.format("/blogs/{}/{}/{}.{}", d1, d2, name, suffix);
}

第二步: 在BlogController中将探店笔记存储到数据库

@RestController
@RequestMapping("/blog")
public class BlogController {
   @Resource
   private IBlogService blogService;
   @PostMapping
   public Result saveBlog(@RequestBody Blog blog) {
       // 获取登录用户的Id
       UserDTO user = UserHolder.getUser();
       // 设置发布博文的用户Id
       blog.setUserId(user.getId());
       // 保存探店博文
       blogService.save(blog);
       // 返回博文的Id
       return Result.ok(blog.getId());
   }
}

查看探店笔记

界面原型

需求: 点击首页的某个探店笔记会进入笔记详情页面展示,主要展示笔记的信息和发布笔记的用户信息

在这里插入图片描述

查看用户笔记

如何实现在展示笔记的时候同时展示用户的信息的两种实现方式

  • 在Blog类中存储user属性,根据Blog对象中的userIdtb_user表中查询用户信息并封装到User对象并赋值给Blog对象的user属性

  • 在Blog中增加user的相关属性icon和name,由于这两个属性只在Blog类中不属于tb_blog表的字段,所以需要在属性上使用@TableField(exist = false)注解

第一步: 在BlogController中调用BlogService中的业务方法queryBlogById

@GetMapping("/{id}")
public Result queryBlogById(@PathVariable Integer id){
    return blogService.queryBlogById(id);
}	

第二步:在Service接口的实现类BlogServiceImpl中实现查看笔记信息和发布笔记的用户信息的业务逻辑

public interface IBlogService extends IService<Blog> {
    Result queryBlogById(Integer id);
}

@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements IBlogService {
    @Resource
    private IUserService userService;
    @Override
    public Result queryBlogById(Integer id) {
        // 1.根据ID查询Blog
        Blog blog = getById(id);
        if (blog == null) {
            return Result.fail("评价不存在或已被删除");
        }
        // 2.查询发表Blog的用户
        queryBlogUser(blog);
        return Result.ok(blog);
    }
    // 由于查看用户信息这个操作比较通用,所以这里封装成了一个方法
    private void queryBlogUser(Blog blog) {
        Long userId = blog.getUserId();
        User user = userService.getById(userId);
        blog.setName(user.getNickName());
        blog.setIcon(user.getIcon());
    }
}

查看热门笔记

当我们访问首页的时候会根据用户点赞数量降序分页查询多个热门笔记(包含用户昵称和头像)

@GetMapping("/hot")
public Result queryHotBlog(@RequestParam(value = "current", defaultValue = "1") Integer current) {
    return blogService.queryHotBlog(current);
}
@Resource
private IUserService userService;
@Override
public Result queryHotBlog(Integer current) {
    // 根据用户点赞数量降序分页查询热门笔记
    Page<Blog> page = query()
        .orderByDesc("liked")
        .page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));
    // 获取查询到的所有热门笔记信息
    List<Blog> records = page.getRecords();
    // 查询每个热门笔记对应的用户昵称和头像
    /*records.forEach(blog ->{
        Long userId = blog.getUserId();
        User user = userService.getById(userId);
        blog.setName(user.getNickName());
        blog.setIcon(user.getIcon());
    });*/
   	// 将查询用户昵称和图标逻辑封装成一个方法
    /*
    records.forEach(blog->{
    	queryBlogUser(blog);
    });
    */
    records.forEach(this::queryBlogUser);
    // 返回查询到的所有笔记信息包含用户的昵称和图标
    return Result.ok(records);
}
private void queryBlogUser(Blog blog) {
    Long userId = blog.getUserId();
    User user = userService.getById(userId);
    blog.setName(user.getNickName());
    blog.setIcon(user.getIcon());
}

查看自己发布的笔记

根据当前登录用户的Id分页查询用户自己发布的所有笔记并且不用包含用户昵称和头像

@GetMapping("/of/me")
public Result queryMyBlog(@RequestParam(value = "current", defaultValue = "1") Integer current) {
    // 获取当前登录用户的Id
    UserDTO user = UserHolder.getUser();
    // 根据用户Id分页查询用户自己发布的所有笔记
    Page<Blog> page = blogService.query()
        .eq("user_id", user.getId()).page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));
    // 返回查询到的笔记信息不用包含用户昵称和头像
    List<Blog> records = page.getRecords();
    return Result.ok(records);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/163019.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

移动端路径传参以数字的形式,写死的情况

页面1 async getListTransferAndApprova() { //把mark值拼接到路径的后面&#xff0c;定义一个变量&#xff0c;使得切换穿的mark都不一样let mark ;if (this.tabsCurrent 0) {mark 2;} else if (this.tabsCurrent 1) {mark 3;}else if (this.tabsCurrent 2) {mark 4;}…

CSS特效014:模仿钟摆效果

CSS常用示例100专栏目录 本专栏记录的是经常使用的CSS示例与技巧&#xff0c;主要包含CSS布局&#xff0c;CSS特效&#xff0c;CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点&#xff0c;CSS特效主要是一些动画示例&#xff0c;CSS花边是描述了一些CSS…

毕业设计1784 ASP.NET停车场管理系统

摘要 本文设计了一个停车场管理系统&#xff0c;该系统分为超级管理员和管理员两种用户。系统实现了车位管理、停车卡管理、停车管理、统计报表、系统管理等功能。管理员可以添加、查看、编辑或删除车位信息、停车卡信息、停车记录等&#xff0c;同时可以按日、月、年统计进场…

springboot实现在线人数统计

在线人数统计 笔者做了一个网站&#xff0c;需要统计在线人数。 在线有两种&#xff1a; 一、如果是后台系统如果登录算在线&#xff0c;退出的时候或者cookie、token失效的时候就算下线 二、如果是网站前台&#xff0c;访问的时候就算在线 今天我们来讲一下第2种情况&…

创建谷歌账号 绕过手机验证(2023.11亲测有效)

如何成功注册谷歌账号&#xff1a;一个详细实用指南 写在最前面谷歌注册全流程环境配置切换至全英文环境 开通foxmail.com邮箱在英文环境下注册验证邮箱注册过程中的注意事项完成&#xff01;总结 写在最前面 在这个数字化迅速发展的时代&#xff0c;谷歌账号几乎成为了我们日…

STM32外部中断(EXTI)与RTOS多任务处理的协同设计

当在STM32上使用外部中断&#xff08;EXTI&#xff09;与RTOS&#xff08;Real-Time Operating System&#xff0c;实时操作系统&#xff09;进行多任务处理时&#xff0c;需要设计合适的协同机制&#xff0c;以确保可靠的中断处理和任务调度。在下面的概述中&#xff0c;我将介…

python django 小程序博客源码

开发工具&#xff1a; PyCharm&#xff0c;mysql5.7&#xff0c;微信开发者工具 技术说明&#xff1a; python django html 小程序 功能介绍&#xff1a; 用户端&#xff1a; 登录注册&#xff08;含授权登录&#xff09; 首页显示搜索文章&#xff0c;文章分类&#xf…

【每日一题】—— C. Yarik and Array(Codeforces Round 909 (Div. 3))(贪心)

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;每日一题 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日反刍 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓称…

【C++】类与对象(上)

目录 1. 面向过程和面向对象初步认识 2. 类的引入 3. 类的定义 4. 类的访问限定符及封装 4.1 访问限定符 4.2 封装 5. 类的作用域 6. 类的实例化 7. 类对象模型 7.1 如何计算类对象的大小 7.2 类对象的存储方式猜测 7.3 结构体内存对齐规则 8. this指针 8.1 this指…

Day34力扣打卡

打卡记录 合并石头的最低成本&#xff08;区间DP&#xff09; 链接 与多边形的三角形问题相同&#xff0c;将大问题化小问题&#xff0c;再用中间节点不断地寻找最值。 class Solution:def mergeStones(self, stones: List[int], k: int) -> int:n len(stones)if (n - 1…

wangEditor富文本编辑器使用

一、官网 开源 Web 富文本编辑器&#xff0c;开箱即用&#xff0c;配置简单 二、下载安装 npm install --save wangeditor/editor-for-vue 三、在vue中使用 3.1、抽离组件editor.vue 在工程的components目录下新建组件editor <template><div><Toolbar:edi…

【C++入门到精通】右值引用 | 完美转发 C++11 [ C++入门 ]

阅读导航 引言一、左值引用和右值引用1. 什么是左值&#xff1f;什么是左值引用&#xff1f;2. 什么是右值&#xff1f;什么是右值引用&#xff1f;3. move( )函数 二、左值引用与右值引用比较三、右值引用使用场景和意义四、完美转发std::forward 函数完美转发实际中的使用场景…

SVG的viewBox、width和height释义, 示例及代码

svg的是没有边界的&#xff0c;svg画布只是用于展示svg世界中某一个范围的内容&#xff0c;而对于超过了svg画布范围的内容&#xff0c;则会被遮挡。默认svg画布默认显示世界坐标下原点坐标的width*height面积的矩形视野。 ​ 我们可以通过viewBox来修改默认的显示配置&#…

图新地球地图导入操作步骤

1、下载图源&#xff0c;如下&#xff1a; 2、将其全部复制或部分复制&#xff0c;然后回到桌面&#xff0c;打开文件所在位置&#xff0c;如下&#xff1a; 3、将复制的数据粘贴到文件夹下&#xff0c;具体如下&#xff1a; 4、复制到路径如下&#xff1a; 5、复制结果如下&am…

Spring Boot - filter 的顺序

定义过滤器的执行顺序 1、第一个过滤器 import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; impor…

linux如何使用shell远程连接

简介&#xff1a;本文的一切条件基于redhat的linux操作系统。 1、创建虚拟机&#xff1a; 如有需要&#xff0c;请转至【linux基础】在VMware上安装RHEL9详细教程_融社的博客-CSDN博客 &#xff08;如若侵权&#xff0c;该篇立删&#xff09; 2、使用命令查看网段信息 打…

LeetCode【4】寻找两个正序数组中位数

题目&#xff1a; 思路&#xff1a; https://blog.csdn.net/a1111116/article/details/115033098 代码&#xff1a; public double findMedianSortedArrays(int[] nums1, int[] nums2) {int[] ints Arrays.copyOf(nums1, nums1.length nums2.length);System.arraycopy(nums2…

Linux网络——HTTP

一.应用层 我们程序员写的一个个解决我们实际问题, 满足我们日常需求的网络程序, 都是在应用层. 我们上一次写的网络版本计算器就是一个应用层的网络程序。 我们约定了数据的读取&#xff0c;一端发送时构造的数据, 在另一端能够正确的进行解析, 就是ok的. 这种约定, 就是应…

java 访问sqlserver 和 此驱动程序不支持jre1.8错误

sqlserver数据如下&#xff1b; TestSQL.java&#xff1b; import java.sql.*;public class TestSQL {public static void main(String[] args) throws ClassNotFoundException, SQLException {String driverName "com.microsoft.sqlserver.jdbc.SQLServerDriver";…

Golang起步篇(Windows、Linux、mac三种系统安装配置go环境以及IDE推荐以及入门语法详细释义)

Golang起步篇 Golang起步篇一. 安装Go语言开发环境1. Wondows下搭建Go开发环境(1). 下载SDK工具包(2). 解压下载的压缩包&#xff0c;放到特定的目录下&#xff0c;我一般放在d:/programs下(路径不能有中文或者特殊符号如空格等)(3). 配置环境变量步骤1&#xff1a;先打开环境变…