自媒体文章-发布、修改、保存草稿

发布时间 2023-06-29 17:00:28作者: 佛系粥米

文章素材关系表:关联文章内容和素材的关系,关联封面中的图片与素材的关系。

若为草稿,则保存wm_news文章,不保存其中的图片信息。

若不是草稿,则保存wm_news文章进入数据库,此外保存该文章与数据库material素材图片的关系:

      1、保存文章内容图片与素材的关系

      2、保存文章封面与素材的关系:若为auto:要从文章内容中的图片选为封面图片,再保存封面与图片的关系

      3、保存内容与文章和保存封面与文章的关系抽取为保存图片与文章的关系方法。唯一不同的是字段type:0表示内容引用,1表示封面引用。

      4、保存文章还是修改文章通过news是否有id判断,有则是修改update并要删除原来文章和素材图片之间的所有关系,下面会重新保存关系。没有则是保存save。

  /**
     * 文章:发布、修改、保存为草稿
     * @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){
            //将list集合以, 分隔开如: a.jpg,b.jpg
            String join = StringUtils.join(dto.getImages(), ",");
            wmNews.setImages(join);
        }
        //当前封面类型为自动 -1
        if(dto.getType().equals(WemediaConstants.WM_NEWS_TYPE_AUTO)){
            //要从内容中获取图片才能确定wmNews是 type = 无图0、单图1、多图3哪一种
            wmNews.setType(null);
        }

        saveOrUpdateWmNews(wmNews);

        //2、判断是否为草稿
        if(dto.getStatus().equals(WmNews.Status.NORMAL.getCode())){
            //3、如果为草稿,结束
            return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
        }

        //4、不是草稿,保存文章内容图片与素材关系
        //获取文章内容图片信息
        List<String> materials = ectratcUrlInfo(dto.getContent());
        //保存文章内容图片与素材的关系
        saveRelativeInfoForContent(materials, wmNews.getId());

        //5、不是草稿,保存文章封面图片与素材关系,如果当前布局是自动,需要匹配封面图片
        saveRelativeInfoForCover(dto, wmNews, materials);

        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }



    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;

    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    /**
     * 1、如果当前封面类型为自动,则设置封面类型的数据
     * 匹配规则:
     *      如果内容图片大于等于1,小于3,单图 type = 1
     *      如果内容图片大于等于3,多图 type = 3
     *      如果内容没有图片,无图 type = 0
     * 2、保存封面图片与素材的关系
     * @param dto
     * @param wmNews
     * @param materials
     */
    private void saveRelativeInfoForCover(WmNewsDto dto, WmNews wmNews, List<String> materials) {
        //封面图片
        List<String> images = dto.getImages();

        //1、如果当前封面类型为自动,则设置封面类型的数据
        if(dto.getType().equals(WemediaConstants.WM_NEWS_TYPE_AUTO)){
            //materials从文章内容获取的图片
            //多图
            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);
            }

            //修改更新数据库中的news属性
            if(images != null && images.size() > 0){
                wmNews.setImages(StringUtils.join(images, ","));
            }
            updateById(wmNews);

            //保存封面与news的关系
            if(images != null && images.size() > 0){
                //代表主图引用,material用作news的封面
                saveRelativeInfo(images, wmNews.getId(), WemediaConstants.WM_COVER_REFERENCE);
            }



        }
    }

    /**
     * 保存文章图片与素材的关系到数据库中
     * @param materials
     * @param newsId
     * @param type
     */
    private void saveRelativeInfo(List<String> materials, Integer newsId, Short type) {
        if(materials != null && !materials.isEmpty()){
            //通过素材materials的图片路径url查询素材id
            List<WmMaterial> dbMaterials = wmMaterialMapper.selectList(Wrappers.<WmMaterial>lambdaQuery().in(WmMaterial::getUrl, materials));
            //前端传来的图片个数与数据库中查询的不等
            if(materials.size() != dbMaterials.size()){
                throw new CustomException(AppHttpCodeEnum.MATERIAL_REFERENCE_FAIL);
            }
            //判断素材是否有效
            if(dbMaterials == null || dbMaterials.size() == 0){
                //手动抛出异常:能够提示要用的素材失效了、数据回滚
                throw new CustomException(AppHttpCodeEnum.MATERIAL_REFERENCE_FAIL);

            }
            List<Integer> idList = dbMaterials.stream().map(WmMaterial::getId).collect(Collectors.toList());
            //批量保存
            wmNewsMaterialMapper.saveRelations(idList, newsId, type);
        }

    }



    /**
     * 保存文章内容图片与素材的关系
     * @param materials
     * @param newsId
     */
    private void saveRelativeInfoForContent(List<String> materials, Integer newsId) {
        //表示这些material被news引用为内容图片
        saveRelativeInfo(materials, newsId, WemediaConstants.WM_CONTENT_REFERENCE);
    }


    /**
     * 提取文章内容图片信息
     * @param content
     * @return
     */
    public List<String> ectratcUrlInfo(String content){
        List<Map> maps = JSON.parseArray(content, Map.class);
        List<String>  materials = new ArrayList<>();
        for (Map map : maps) {
            if(map.get("type").equals("image")){
                String imgUrl = (String)map.get("value");
                materials.add(imgUrl);
            }
        }
        return materials;
    }


    /**
     * 保存或修改文章
     */
    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);
        }
    }