文章发布
表结构分析
逻辑分析
把需求的逻辑分析清楚,写代码是很简单的
首先,和发布文章相关的表有三张:
- 文章表(news)
- 素材表(material)
- 文章和素材表(news_material)
第二,发布文章的逻辑:
- 数据库不存在文章id
- 新增文章到数据库(news)
- 关联文章和图片的关系(news_material)
- 关联封面图片和素材的关系
- 发布文章结束
- 看看数据库有没有该文章id,有的话代表文章已存在,属于是对文章的修改
- 删除文章与素材的关系(news_material)
- 修改数据库(news)
- 重新关联文章与图片关系(news_material)
- 重新关联封面图片和素材的关系
- 发布文章结束
第三,流程图展示:
代码实现
1、主方法,用来判断是发布还是保存草稿
0.条件判断
if(dto == null || dto.getContent() == null){
return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
}
1.保存或修改文章
WmNews wmNews = new WmNews();
//属性拷贝 属性名词和类型相同才能拷贝
BeanUtils.copyProperties(dto,wmNews);
//封面图片 list---> string
if(dto.getImages() != null && dto.getImages().size() > 0){
//[1dddfsd.jpg,sdlfjldk.jpg]--> 1dddfsd.jpg,sdlfjldk.jpg
String imageStr = StringUtils.join(dto.getImages(), ",");
wmNews.setImages(imageStr);
}
//如果当前封面类型为自动 -1
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.不是草稿,保存文章内容图片与素材的关系
下图为前端发布文章传来的内容,可以看到是一个json数组
那么后端该如何去解析这些数据,获得图片相关的的value呢?
- 把前端传来的数据当成一个Map类型的List集合
- 对Map集合进行遍历,如果type为image那么就取出value的值
- 把收集到的图片url加入新建的集合materials中返回
private List<String> ccUrlInfo(String content) {
List<String> materials = new ArrayList<>();
List<Map> maps = JSON.parseArray(content, Map.class);
for (Map map : maps) {
if(map.get("type").equals("image")){
String imgUrl = (String) map.get("value");
materials.add(imgUrl);
}
}
return materials;
}
保存素材和文章的关系
private void saveRelativeInfo(List<String> materials, Integer newsId, Short type) {
if(materials != null && !materials.isEmpty()){
//通过图片的url查询素材的id
List<WmMaterial> dbMaterials = wmMaterialMapper.selectList(Wrappers.<WmMaterial>lambdaQuery().in(WmMaterial::getUrl, materials));
//判断素材是否有效
if(dbMaterials==null || dbMaterials.size() == 0){
//手动抛出异常 第一个功能:能够提示调用者素材失效了,第二个功能,进行数据的回滚
throw new CustomException(AppHttpCodeEnum.MATERIASL_REFERENCE_FAIL);
}
if(materials.size() != dbMaterials.size()){
throw new CustomException(AppHttpCodeEnum.MATERIASL_REFERENCE_FAIL);
}
List<Integer> idList = dbMaterials.stream().map(WmMaterial::getId).collect(Collectors.toList());
//批量保存
wmNewsMaterialMapper.saveRelations(idList,newsId,type);
}
}
<insert id="saveRelations">
insert into wm_news_material (material_id,news_id,type,ord)
values
<foreach collection="materialIds" index="ord" item="mid" separator=",">
(#{mid},#{newsId},#{type},#{ord})
</foreach>
</insert>
4.不是草稿,保存文章封面图片与素材的关系,如果当前布局是自动,需要匹配封面图片
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_MANY_IMAGE);
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);
}
}
看上去看多,把功能理清楚了,其实也是CRUD