• 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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    界面原型

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

    在这里插入图片描述

    后端处理请求

    第一步: 在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;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    第二步: 在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());
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    查看探店笔记

    界面原型

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

    在这里插入图片描述

    查看用户笔记

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

    • 在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);
    }	
    
    • 1
    • 2
    • 3
    • 4

    第二步:在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());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    查看热门笔记

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

    @GetMapping("/hot")
    public Result queryHotBlog(@RequestParam(value = "current", defaultValue = "1") Integer current) {
        return blogService.queryHotBlog(current);
    }
    
    • 1
    • 2
    • 3
    • 4
    @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());
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    查看自己发布的笔记

    根据当前登录用户的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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  • 相关阅读:
    leetcode:1189. “气球” 的最大数量
    最新美国斯坦福大学2023全球前2%科学家(中国内地)榜单
    leetcode数据结构与算法刷题(三)
    Android Button点击事件
    实习面试
    华为云云耀云服务器L实例评测|云耀云服务器L实例部署paperless-ngx文档管理系统
    泛微OA E-Office V10 OfficeServer 任意文件上传漏洞复现
    PyTorch中的CPU和GPU代码实现详解
    conda命令详解
    linux-文件服务
  • 原文地址:https://blog.csdn.net/qq_57005976/article/details/134486185