黑马头条(3)
自媒体素材管理
素材管理-图片上传
图片上传路径:
实现代码:
通过ThreadLocal获取用户ID
WmThreadLocalUtil
src/main/java/com/heima/utils/thread/WmThreadLocalUtil.java
public class WmThreadLocalUtil {
private final static ThreadLocal<WmUser> WM_USER_THREAD_LOCAL = new ThreadLocal<>();
// 存入线程
public static void setUser(WmUser wmUser){
WM_USER_THREAD_LOCAL.set(wmUser);
}
// 从线程中获取
public static WmUser getUser(){
return WM_USER_THREAD_LOCAL.get();
}
// 清理
public static void clear(){
WM_USER_THREAD_LOCAL.remove();
}
}
WmTokenInterceptor
定义拦截器
public class WmTokenInterceptor implements HandlerInterceptor {
/**
* 得到header中的用户信息后,并存入到当前线程中
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String userId = request.getHeader("userId");
if (userId != null) {
WmUser wmUser = new WmUser();
wmUser.setId(Integer.valueOf(userId));
WmThreadLocalUtil.setUser(wmUser);
}
return true;
}
/**
* 清理线程中的数据
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
WmThreadLocalUtil.clear();
}
}
WebMvcConfig
添加拦截器
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
InterceptorRegistration interceptorRegistration = registry.addInterceptor(new WmTokenInterceptor()).addPathPatterns("/**");
}
}
WmMaterialController
@PostMapping("/upload_picture")
public ResponseResult uploadPicture(MultipartFile multipartFile) {
ResponseResult responseResult = wmMaterialService.uploadPicture(multipartFile);
return responseResult;
}
WmMaterialService
/**
* 上传图片
* @param multipartFile
* @return
*/
public ResponseResult uploadPicture(MultipartFile multipartFile);
WmMaterialServiceImpl:
@Override
public ResponseResult uploadPicture(MultipartFile multipartFile) {
//1、检查参数
if (multipartFile == null || multipartFile.getSize() == 0) {
return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
}
//2、上传图片到minIO中
String fileName = UUID.randomUUID().toString().replace("-", "");
String originalFilename = multipartFile.getOriginalFilename();
String postfix = originalFilename.substring(originalFilename.lastIndexOf("."));
String fileId = null;
try {
fileId = fileStorageService.uploadImgFile("", fileName + postfix, multipartFile.getInputStream());
log.info("上传图片到MinIO中, fileId{}", fileId);
} catch (IOException e) {
e.printStackTrace();
log.error("WmMaterialServiceImpl-上传图片失败");
}
WmMaterial wmMaterial = new WmMaterial();
wmMaterial.setUserId(WmThreadLocalUtil.getUser().getId());
wmMaterial.setUrl(fileId);
wmMaterial.setIsCollection((short) 0);
wmMaterial.setType((short) 0);
wmMaterial.setCreatedTime(new Date());
save(wmMaterial);
//返回结果
return ResponseResult.okResult(wmMaterial);
}
自媒体文章管理
pojo - WmNews
/**
* <p>
* 自媒体图文内容信息表
* </p>
*
* @author itheima
*/
@Data
@TableName("wm_news")
public class WmNews implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 自媒体用户ID
*/
@TableField("user_id")
private Integer userId;
/**
* 标题
*/
@TableField("title")
private String title;
/**
* 图文内容
*/
@TableField("content")
private String content;
/**
* 文章布局
* 0 无图文章
* 1 单图文章
* 3 多图文章
*/
@TableField("type")
private Short type;
/**
* 图文频道ID
*/
@TableField("channel_id")
private Integer channelId;
@TableField("labels")
private String labels;
/**
* 创建时间
*/
@TableField("created_time")
private Date createdTime;
/**
* 提交时间
*/
@TableField("submited_time")
private Date submitedTime;
/**
* 当前状态
* 0 草稿
* 1 提交(待审核)
* 2 审核失败
* 3 人工审核
* 4 人工审核通过
* 8 审核通过(待发布)
* 9 已发布
*/
@TableField("status")
private Short status;
/**
* 定时发布时间,不定时则为空
*/
@TableField("publish_time")
private Date publishTime;
/**
* 拒绝理由
*/
@TableField("reason")
private String reason;
/**
* 发布库文章ID
*/
@TableField("article_id")
private Long articleId;
/**
* //图片用逗号分隔
*/
@TableField("images")
private String images;
@TableField("enable")
private Short enable;
//状态枚举类
@Alias("WmNewsStatus")
public enum Status {
NORMAL((short) 0), SUBMIT((short) 1), FAIL((short) 2), ADMIN_AUTH((short) 3), ADMIN_SUCCESS((short) 4), SUCCESS((short) 8), PUBLISHED((short) 9);
short code;
Status(short code) {
this.code = code;
}
public short getCode() {
return this.code;
}
}
}
dto - WmNewsPageReqDto
@Data
public class WmNewsPageReqDto extends PageRequestDto {
/**
* 状态
*/
private Short status;
/**
* 开始时间
*/
private Date beginPubDate;
/**
* 结束时间
*/
private Date endPubDate;
/**
* 所属频道ID
*/
private Integer channelId;
/**
* 关键字
*/
private String keyword;
}
WmNewsController
@RestController
@RequestMapping("api/v1/news")
public class WmNewsController {
@Autowired
private WmNewsService wmNewsService;
@PostMapping("/list")
public ResponseResult findList(@RequestBody WmNewsPageReqDto dto) {
return wmNewsService.findList(dto);
}
}
WmNewsService
public interface WmNewsService extends IService<WmNews> {
/**
* 条件查询文章列表
* @param dto
* @return
*/
public ResponseResult findList(WmNewsPageReqDto dto);
}
WmNewsServiceImpl
@Service
@Slf4j
@Transactional
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {
/**
* 条件查询文章列表
*
* @param dto
* @return
*/
@Override
public ResponseResult findList(WmNewsPageReqDto dto) {
// 检查参数
// 分页参数检查
dto.checkParam();
// 分页数据查询
IPage page = new Page(dto.getPage(), dto.getSize());
LambdaQueryWrapper<WmNews> lambdaQueryWrapper = new LambdaQueryWrapper();
// 状态精确查询
if (dto.getStatus() != null) {
lambdaQueryWrapper.eq(WmNews::getStatus, dto.getStatus());
}
// 频道精确查询
if (dto.getChannelId() != null) {
lambdaQueryWrapper.eq(WmNews::getChannelId, dto.getChannelId());
}
// 时间范围查询
if (dto.getBeginPubDate() != null && dto.getEndPubDate() != null) {
lambdaQueryWrapper.between(WmNews::getPublishTime, dto.getBeginPubDate(), dto.getEndPubDate());
}
// 关键字的模糊查询
if (StringUtils.isNotBlank(dto.getKeyword())) {
lambdaQueryWrapper.like(WmNews::getTitle, dto.getKeyword());
}
// 查询当前登陆人的文章
lambdaQueryWrapper.eq(WmNews::getUserId, WmThreadLocalUtil.getUser().getId());
// 按照发布时间倒序查询
lambdaQueryWrapper.orderByDesc(WmNews::getPublishTime);
page(page, lambdaQueryWrapper);
// 返回结果
ResponseResult responseResult = new PageResponseResult(dto.getPage(), dto.getSize(), (int) page.getTotal());
responseResult.setData(page.getRecords());
return responseResult;
}
}
自媒体文章-发布、修改、保存草稿
发布文章
WmNewsController
@PostMapping("/submit")
public ResponseResult submitNews(@RequestBody WmNewsDto dto) {
return wmNewsService.submitNews(dto);
}
WmNewsService
public ResponseResult submitNews(WmNewsDto dto);
WmNewsServiceImpl
/**
* 提交文章
* @param dto
* @return
*/
@Override
public ResponseResult submitNews(WmNewsDto dto) {
// 0.条件判断
if (dto == null || dto.getContent() == null) {
return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
}
// 1、保存或修改文章
WmNews wmNews = new WmNews();
BeanUtils.copyProperties(dto, wmNews);
if (dto.getImages() != null && dto.getImages().size() > 0) {
String imageStr = StringUtils.join(dto.getImages(), ",");
wmNews.setImages(imageStr);
}
// 如果当前封面类型为自动
if (dto.getType().equals(WemediaConstants.WM_NEWS_TYPE_AUTO)) {
wmNews.setType(null);
}
saveOrUpdateWmNews(wmNews);
// 2、判断是否为草稿,如果是草稿则结束当前方法
if (dto.getStatus().equals(WmNews.Status.NORMAL.getCode())) {
return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
// 3、不是草稿,保存文章内容图片与素材的关系
// 获取到文章内容中的图片信息
List<String> materials = extractUrlInfo(dto.getContent());
saveRelativeInfoForContent(materials, wmNews.getId());
// 3、不是草稿,保存文章封面与素材的关系
saveRelativeInfoForCover(dto, wmNews, materials);
return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
}
/**
* 保存或者修改文章
*
* @param wmNews
*/
private void saveOrUpdateWmNews(WmNews wmNews) {
// 补全属性
wmNews.setUserId(WmThreadLocalUtil.getUser().getId());
wmNews.setCreatedTime(new Date());
wmNews.setSubmitedTime(new Date());
wmNews.setEnable((short) 1); // 默认上架
if (wmNews.getId() == null) {
// 新增
save(wmNews);
} else {
// 修改
// 删除文章图片与素材的关系
wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, wmNews.getId()));
updateById(wmNews);
}
}
/**
* 处理文章内容图片和素材的关系
*
* @param materials
* @param newsId
*/
private void saveRelativeInfoForContent(List<String> materials, Integer newsId) {
saveRelativeInfo(materials, newsId, WemediaConstants.WM_CONTENT_REFERENCE);
}
/**
* 第一个功能:如果当前封面类型为自动,则设置封面类型的数据
* 匹配规则:
* 1、如果内容图片大于等于1,小于3,单图 type 1
* 2、如果内容图片大于等于3,多图 type 3
* 3、如果内容没有图片,无图 type 0
*
* 第二个功能:保存封面图片与素材的关系
*
* @param dto
* @param wmNews
* @param materials
*/
private void saveRelativeInfoForCover(WmNewsDto dto, WmNews wmNews, List<String> materials) {
List<String> images = dto.getImages();
// 如果当前封面类型为自动,则设置封面类型的数据
if(dto.getType().equals(WemediaConstants.WM_NEWS_TYPE_AUTO)){
if (materials.size() >= 3){
// 多图
wmNews.setType(WemediaConstants.WM_NEWS_TYPE_AUTO);
images = materials.stream().limit(3).collect(Collectors.toList());
}else if (materials.size() >= 1 && materials.size() < 3){
// 单图
wmNews.setType(WemediaConstants.WM_NEWS_SINGLE_IMAGE);
images = materials.stream().limit(1).collect(Collectors.toList());
}else{
// 无图
wmNews.setType(WemediaConstants.WM_NEWS_NONE_IMAGE);
}
// 修改文章
if (images != null && images.size() > 0){
wmNews.setImages(StringUtils.join(images,","));
}
updateById(wmNews);
}
if (images != null && images.size() > 0){
saveRelativeInfo(images, wmNews.getId(), WemediaConstants.WM_COVER_REFERENCE);
}
}