app端保存接口

背景:

  当审核通过后,将自媒体发布的news存入leadnews_article数据库,让移动端用户能够访问到

分布式id

  随着业务的增长,文章表可能要占用很大的物理存储空间,为了解决该问题,后期使用数据库分片技术。将一个数据库进行拆分,通过数据库中间件连接。如果数据库中该表选用ID自增策略,则可能产生重复的ID,此时应该使用分布式ID生成策略来生成ID。

   

        

  snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0

  文章端相关的表都使用雪花算法生成id,包括ap_article、 ap_article_config、 ap_article_content

 

保存app端文章-思路分析:

在文章审核成功以后需要在app的article库中新增文章数据:

  1.保存文章信息 ap_article

  2.保存文章配置信息 ap_article_config

  3.保存文章内容 ap_article_content

注:自媒体文章wm-news审核成功后会分配一个article-id,当修改后再次通过审核,文章表需要根据article-id修改更新对应文章信息

①:在heima-leadnews-feign-api中定义接口

  导入feign远程调用依赖

  定义文章端的远程接口

②:在heima-leadnews-article实现feign接口

③:新建ApArticleConfigMapper类到文章微服务mapper包下

④:在ApArticleService中新增保存方法进行实现

⑤:postman进行测试。

 

package com.heima.apis.article;

import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

@FeignClient(value = "leadnews-article")
public interface IArticleClient {

    @PostMapping("/api/v1/article/save")
    public ResponseResult saveArticle(@RequestBody ArticleDto dto);
}

 

  /**
     * 保存到app端相关文章
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveArticle(ArticleDto dto) {
        //1、检查参数
        if(dto == null){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        ApArticle apArticle = new ApArticle();
        BeanUtils.copyProperties(dto, apArticle);
        //2、判断是否存在id
        if(dto.getId() == null){
            //2、1 不存在id,保存 文章 文章配置 文章内容
            //保存文章
            save(apArticle);
            //保存配置
            ApArticleConfig apArticleConfig = new ApArticleConfig(apArticle.getId());
            apArticleConfigMapper.insert(apArticleConfig);
            //保存文章内容
            ApArticleContent apArticleContent = new ApArticleContent();
            apArticleContent.setArticleId(apArticle.getId());
            apArticleContent.setContent(dto.getContent());
            apArticleContentMapper.insert(apArticleContent);
            

        }else{
            //2、2 存在id 修改 文章 文章内容
            updateById(apArticle);
            //修改文章内容
            ApArticleContent apArticleContent = apArticleContentMapper.selectOne(Wrappers.<ApArticleContent>lambdaQuery().eq(ApArticleContent::getArticleId, apArticle.getId()));
            apArticleContent.setContent(dto.getContent());
            apArticleContentMapper.updateById(apArticleContent);
        }


        //3、结果返回, 文章id
        return ResponseResult.okResult(apArticle.getId());
    }

 feign远程接口调用方式:

                        

 

 
 

Wemedia-service进行审核

  1、通过id查询自媒体文章

  2、从自媒体文章中抽取文本和图片,图片包含内容图片和封面图片

  3、审核文本和图片,若不通过修改审核状态,有一个不通过则结束,

  4、文本和图片通过审核后,利用feign进行远程调用leadnews-article中实现了IArticleClient接口的ArticleClient,存储app文章到app文章数据库的方法。修改审核状态为已通过审核。

  5、存储完成后,将ArticleClient返回的articleId回填到自媒体文章数据库。


package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.heima.apis.article.IArticleClient;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.file.service.FileStorageService;
import com.heima.model.article.dtos.ArticleDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.model.wemedia.pojos.WmUser;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.mapper.WmUserMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import com.heima.wemedia.service.WmNewsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
@Slf4j
@Transactional
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {

@Autowired
private WmNewsService wmNewsService;

@Autowired
private GreenTextScan greenTextScan;

@Autowired
private GreenImageScan greenImageScan;

@Autowired
private FileStorageService fileStorageService;





@Autowired
private WmChannelMapper wmChannelMapper;

@Autowired
private WmUserMapper wmUserMapper;



/**
* 自媒体文章审核
* @param id 自媒体文章id
*/
@Override
public void autoScanWmNews(Integer id) {
//1、查询自媒体文章
WmNews wmNews = wmNewsService.getById(id);

if(wmNews == null){
throw new RuntimeException("WmNewsAutoScanServiceImpl-文章不存在");
}
//当自媒体文章处于待审核状态1时才会进行审核
if(wmNews.getStatus().equals(WmNews.Status.SUBMIT.getCode())){
//从内容中抽取文本内容和图片
Map<String, Object> textandImages = handleTextAndImages(wmNews);
//2、审核文本内容,阿里云接口
boolean isTextScan = handleTextScan((String) textandImages.get("content"), wmNews);
//文本内容审核不通过,结束
if(!isTextScan)return;
//3、审核图片内容,阿里云接口
boolean isImageScan = handleImageScan((List<String>) textandImages.get("images"), wmNews);
//图片内容审核不通过,结束
if(!isImageScan)return;

//4、审核成功,将自媒体文章保存到app端的文章数据
ResponseResult responseResult = saveAppArticle(wmNews);
if(!responseResult.getCode().equals(200)){
throw new RuntimeException("WmNewsAutoScanServiceImpl-文章审核,保存app端相关文章数据失败");
}
//回填articleId
wmNews.setArticleId((Long) responseResult.getData());
updateWmNews(wmNews, (short) 9, "审核通过");

}

}


@Autowired
private IArticleClient articleClient;

/**
* 将自媒体文章保存到app端文章的数据库
* @param wmNews
*/
private ResponseResult saveAppArticle(WmNews wmNews) {

ArticleDto dto = new ArticleDto();
//属性拷贝
BeanUtils.copyProperties(wmNews, dto);
dto.setLayout(wmNews.getType());
//频道:拷贝过来的属性只有chanelId,没有channelName
WmChannel wmChannel = wmChannelMapper.selectById(wmNews.getChannelId());
if (wmChannel != null) {
dto.setChannelName(wmChannel.getName());
}
//author_id
dto.setAuthorId(wmNews.getUserId().longValue());
//author_name
WmUser wmUser = wmUserMapper.selectById(wmNews.getUserId());
if (wmUser != null) {
dto.setAuthorName(wmUser.getName());
}
//设置文章id
if (wmNews.getArticleId() != null) {
dto.setId(wmNews.getArticleId());
}
dto.setCreatedTime(new Date());

ResponseResult responseResult = articleClient.saveArticle(dto);
return responseResult;
}

/**
* 审核图片
* @param images
* @param wmNews
* @return
*/
private boolean handleImageScan(List<String> images, WmNews wmNews){
boolean flag = true;

if(images == null || images.size() == 0){
return flag;
}

// //下载图片 minIO
// //图片去重
// images = images.stream().distinct().collect(Collectors.toList());
// ArrayList<byte[]> imageList = new ArrayList<>();
// for (String image : images) {
// byte[] bytes = fileStorageService.downLoadFile(image);
// imageList.add(bytes);
//
// }
// try {
// //审核图片
// Map map = greenImageScan.imageScan(imageList);
// if(map != null){
// //审核失败
// if(map.get("suggestion").equals("block")){
// flag = false;
// updateWmNews(wmNews, (short) 1, "当前文章图片存在违规内容");
// }
// //不确定信息,需要人工审核
// if(map.get("suggestion").equals("review")){
// flag = false;
// updateWmNews(wmNews, (short) 3, "当前文章图片存在不确定");
// }
// }
// } catch (Exception e) {
// flag = false;
// e.printStackTrace();
// }
return flag;

}

/**
* 审核文本内容
* @param content
* @param wmNews
* @return
*/
private boolean handleTextScan(String content, WmNews wmNews){
boolean flag = true;
//审核标题和内容
if((wmNews.getTitle()+'-'+content).length() == 0){
return flag;
}
// try {
// Map map = greenTextScan.greeTextScan(wmNews.getTitle()+'-'+content);
// if(map != null){
// //审核失败
// if(map.get("suggestion").equals("block")){
// flag = false;
// updateWmNews(wmNews, (short) 1, "当前文章中存在违规内容");
// }
// //不确定信息,需要人工审核
// if(map.get("suggestion").equals("review")){
// flag = false;
// updateWmNews(wmNews, (short) 3, "文章内容存在不确定");
// }
// }
// } catch (Exception e) {
// flag = false;
// e.printStackTrace();
// }
return flag;
}

/**
* 修改文章内容
* @param wmNews
* @param status
* @param reason
*/
private void updateWmNews(WmNews wmNews, short status, String reason) {
wmNews.setStatus(status);
wmNews.setReason(reason);
wmNewsService.updateById(wmNews);
}


/**
* 1、从自媒体文章内容中抽取文本内容和图片
* 2、提取文章封面图片
* @param wmNews
*/
private Map<String, Object> handleTextAndImages(WmNews wmNews) {

StringBuilder stringBuilder = new StringBuilder();
List<String> images = new ArrayList<>();
//1、从自媒体文章内容中抽取文本内容和图片
if(StringUtils.isNotBlank(wmNews.getContent())){
List<Map> maps = JSONArray.parseArray(wmNews.getContent(), Map.class);
for(Map map: maps){
if(map.get("type").equals("text")){
stringBuilder.append(map.get("value"));
}
if(map.get("type").equals("image")){
images.add((String) map.get("value"));
}
}
}

//2、提取文章封面
if(StringUtils.isNotBlank(wmNews.getImages())){
String[] split = wmNews.getImages().split(",");
images.addAll(Arrays.asList(split));
}

Map<String, Object> resultMap = new HashMap<>();
resultMap.put("content", stringBuilder.toString());
resultMap.put("images", images);
return resultMap;



}
}
 

 在自媒体微服务启动类尚开启feign服务并设置扫描feign接口包路径

  @EnableFeignClients(basePackages = "com.heima.apis")

posted @ 2023-06-30 14:48  佛系粥米  阅读(32)  评论(0编辑  收藏  举报