发布笔记
数据模型
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 {@Resourceprivate IBlogService blogService;@PostMappingpublic Result saveBlog(@RequestBody Blog blog) {// 获取登录用户的IdUserDTO user = UserHolder.getUser();// 设置发布博文的用户Idblog.setUserId(user.getId());// 保存探店博文blogService.save(blog);// 返回博文的Idreturn Result.ok(blog.getId());}
}
查看探店笔记
界面原型
需求: 点击首页的某个探店笔记会进入笔记详情页面展示,主要展示笔记的信息和发布笔记的用户信息
查看用户笔记
如何实现在展示笔记的时候同时展示用户的信息
的两种实现方式
-
在Blog类中
存储user属性
,根据Blog对象中的userId
去tb_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 {@Resourceprivate IUserService userService;@Overridepublic Result queryBlogById(Integer id) {// 1.根据ID查询BlogBlog 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) {// 获取当前登录用户的IdUserDTO 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);
}