文章审核自动化

1.文本垃圾内容检测

试用阿里云的内容安全检测来做我们的文本,图片的检测

1.1使用方法如下:


@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix="aliyun")
@PropertySource("classpath:aliyun.properties")
public class AliyunTextScanRequest {

    private  String accessKey;
    private  String secret;

    public String textScanRequest(String content) throws Exception {
        IClientProfile profile = DefaultProfile.getProfile("cn-shanghai", accessKey, secret);
        IAcsClient client = new DefaultAcsClient(profile);
        TextScanRequest textScanRequest = new TextScanRequest();
        textScanRequest.setAcceptFormat(FormatType.JSON); // 指定api返回格式
        textScanRequest.setHttpContentType(FormatType.JSON);
        textScanRequest.setMethod(com.aliyuncs.http.MethodType.POST); // 指定请求方法
        textScanRequest.setEncoding("UTF-8");
        textScanRequest.setRegionId("cn-shanghai");
        List<Map<String, Object>> tasks = new ArrayList<Map<String, Object>>();
        Map<String, Object> task1 = new LinkedHashMap<String, Object>();
        task1.put("dataId", UUID.randomUUID().toString());
        /**
         * 待检测的文本,长度不超过10000个字符
         */
        task1.put("content", content);
        tasks.add(task1);
        JSONObject data = new JSONObject();

        /**
         * 检测场景,文本垃圾检测传递:antispam
         **/
        data.put("scenes", Arrays.asList("antispam"));
        data.put("tasks", tasks);
        System.out.println(JSON.toJSONString(data, true));
        textScanRequest.setHttpContent(data.toJSONString().getBytes("UTF-8"), "UTF-8", FormatType.JSON);
        // 请务必设置超时时间
        textScanRequest.setConnectTimeout(3000);
        textScanRequest.setReadTimeout(6000);
        try {
            HttpResponse httpResponse = client.doAction(textScanRequest);
            if(httpResponse.isSuccess()){
                JSONObject scrResponse = JSON.parseObject(new String(httpResponse.getHttpContent(), "UTF-8"));
                System.out.println(JSON.toJSONString(scrResponse, true));
                if (200 == scrResponse.getInteger("code")) {
                    JSONArray taskResults = scrResponse.getJSONArray("data");
                    for (Object taskResult : taskResults) {
                        if(200 == ((JSONObject)taskResult).getInteger("code")){
                            JSONArray sceneResults = ((JSONObject)taskResult).getJSONArray("results");
                            for (Object sceneResult : sceneResults) {
                                String scene = ((JSONObject)sceneResult).getString("scene");
                                String suggestion = ((JSONObject)sceneResult).getString("suggestion");
                                //根据scene和suggetion做相关处理
                                //suggestion == pass 未命中垃圾  suggestion == block 命中了垃圾,可以通过label字段查看命中的垃圾分类
                                System.out.println("args = [" + scene + "]");
                                System.out.println("args = [" + suggestion + "]");
                                return suggestion;
                            }
                        }else{
                            System.out.println("task process fail:" + ((JSONObject)taskResult).getInteger("code"));
                        }
                    }
                } else {
                    System.out.println("detect not success. code:" + scrResponse.getInteger("code"));
                }
            }else{
                System.out.println("response not success. status:" + httpResponse.getStatus());
            }
        } catch (ClientException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

编写配置类扫描阿里云Config,同时编写测试类AliTest{
@Autowired
private AliyunTextScanRequest aliyunTextScanRequest;

	@Test
	public void testText(){
		 String  content ="阿里云,阿里巴巴集团旗下云计算品牌,全球卓越的云计算技术和服务提供商。创立于2009年,在杭州、北京、硅谷等地设有研发中心和运营机构。";
		 String response=aliyunTextScanRequest.textScanRequest(content);	
		 System.out.println(response+"------------------");
}

}

2.图片审核

	图片审核,有两种方式,第一种放一个url,第二种方式传一个本地的图片到程序中进行检测

创建工具类:com.common.aliyun.AliyunImageScanRequest

@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix="aliyun")
@PropertySource("classpath:aliyun.properties")
public class AliyunImageScanRequest {


  private  String accessKey;
  private  String secret;

  public String imageScanRequest(List<String> images) throws Exception {
      IClientProfile profile = DefaultProfile.getProfile("cn-shanghai",accessKey,secret);
      DefaultProfile.addEndpoint("cn-shanghai", "cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
      IAcsClient client = new DefaultAcsClient(profile);

      ImageSyncScanRequest imageSyncScanRequest = new ImageSyncScanRequest();
      // 指定api返回格式
      imageSyncScanRequest.setAcceptFormat(FormatType.JSON);
      // 指定请求方法
      imageSyncScanRequest.setMethod(MethodType.POST);
      imageSyncScanRequest.setEncoding("utf-8");
      //支持http和https
      imageSyncScanRequest.setProtocol(ProtocolType.HTTP);


      JSONObject httpBody = new JSONObject();
      /**
       * 设置要检测的场景, 计费是按照该处传递的场景进行
       * 一次请求中可以同时检测多张图片,每张图片可以同时检测多个风险场景,计费按照场景计算
       * 例如:检测2张图片,场景传递porn,terrorism,计费会按照2张图片鉴黄,2张图片暴恐检测计算
       * porn: porn表示色情场景检测
       */

      httpBody.put("scenes", Arrays.asList("logo","porn","ad","terrorism"));


      /**
       * 设置待检测图片, 一张图片一个task,
       * 多张图片同时检测时,处理的时间由最后一个处理完的图片决定。
       * 通常情况下批量检测的平均rt比单张检测的要长, 一次批量提交的图片数越多,rt被拉长的概率越高
       * 这里以单张图片检测作为示例, 如果是批量图片检测,请自行构建多个task
       */
      List<JSONObject> list = new ArrayList<JSONObject>();
      for (String image : images) {
          JSONObject task = new JSONObject();
          task.put("dataId", UUID.randomUUID().toString());
          //设置图片链接为上传后的url
          task.put("url", image);
          task.put("time", new Date());
          list.add(task);
      }

      httpBody.put("tasks", list);

      imageSyncScanRequest.setHttpContent(org.apache.commons.codec.binary.StringUtils.getBytesUtf8(httpBody.toJSONString()),
              "UTF-8", FormatType.JSON);

      /**
       * 请设置超时时间, 服务端全链路处理超时时间为10秒,请做相应设置
       * 如果您设置的ReadTimeout 小于服务端处理的时间,程序中会获得一个read timeout 异常
       */
      imageSyncScanRequest.setConnectTimeout(3000);
      imageSyncScanRequest.setReadTimeout(10000);
      HttpResponse httpResponse = null;
      try {
          httpResponse = client.doAction(imageSyncScanRequest);
      } catch (Exception e) {
          e.printStackTrace();
      }

      //服务端接收到请求,并完成处理返回的结果
      if (httpResponse != null && httpResponse.isSuccess()) {
          JSONObject scrResponse = JSON.parseObject(org.apache.commons.codec.binary.StringUtils.newStringUtf8(httpResponse.getHttpContent()));
          System.out.println(JSON.toJSONString(scrResponse, true));
          int requestCode = scrResponse.getIntValue("code");
          //每一张图片的检测结果
          JSONArray taskResults = scrResponse.getJSONArray("data");
          if (200 == requestCode) {
              for (Object taskResult : taskResults) {
                  //单张图片的处理结果
                  int taskCode = ((JSONObject) taskResult).getIntValue("code");
                  //图片要检测的场景的处理结果, 如果是多个场景,则会有每个场景的结果
                  JSONArray sceneResults = ((JSONObject) taskResult).getJSONArray("results");
                  if (200 == taskCode) {
                      for (Object sceneResult : sceneResults) {
                          String scene = ((JSONObject) sceneResult).getString("scene");
                          String suggestion = ((JSONObject) sceneResult).getString("suggestion");
                          //根据scene和suggetion做相关处理
                          //do something
                          System.out.println("scene = [" + scene + "]");
                          System.out.println("suggestion = [" + suggestion + "]");
                          return suggestion;
                      }
                  } else {
                      //单张图片处理失败, 原因是具体的情况详细分析
                      System.out.println("task process fail. task response:" + JSON.toJSONString(taskResult));
                  }
              }
          } else {
              /**
               * 表明请求整体处理失败,原因视具体的情况详细分析
               */
              System.out.println("the whole image scan request failed. response:" + JSON.toJSONString(scrResponse));
          }
      }
      return null;
  }
}

当自媒体用户在自媒体端发表了一篇文章是需要通过审核通过之后才能在用户app端展示
news:文章状态
1.提交(待审核)
2.审核失败
3.人工审核
4.人工审核通过
8.审核通过(待发布)
9.已发布

审核的思路和流程是这样:
1.文章状态如果为4就不用再次去审核了,可以直接保存数据。
2.状态为8,发布时间是大于当前时间的,就可以保存数据了
3.判断为1,待审核
4.标题和内容是否匹配,不匹配,operation:人工复审或拒绝给用户推送消息。
5.审核文本 operation:人工复审或者拒绝。
6.审核图片,
7.判断发布时间是否大于当前时间 是的话就保存数据,不是的话就将vmNews的状态改成9审核已通过。
8.如果不是就保存数据,向ap_article中保存一条数据。
ap_article_config
ap_article
ap_ariticle_content
ap_author
4张表中都需要存贮
8.创建索引
9.修改wmNew文章的状态为9,文章审核通过保存消息。

文章审核代码实现

1.adChannelMapper的接口,添加根据id查询频道的方法.

  AdChannel selectByPrimaryKey(Integer id);
	
AdChannelMapper.xml
<select id="selectByPrimaryKey" resultMap="BaseResultMap" 		     paramType="java.lang.Integer">
select
<include refid="Base_Column_List"/>
from ad_channel
where id=#{id}
</select>

2.修改com.heima.model.mapper.app.ApAuthorMapper,添加根据名称查询作者的添加方法
ApAuthor selectByAuthorName(String authorName);
void insert(ApAuthor apAuthor);
先根据作者名称来查询作者,没有查询到就添加作者信息。
3.添加对应的ApArticleContentMapper
void insert(ApArticleContent articleContent)
ApArticleConfigMapper
int insert(ApArticleConfig apArticleConfig);
ApArrticleMapper
int insert(ApArticle apArticle);
这里的mapper中需要返回我们的文章id,这样我们才能添加对应config,content.
在WmNewsMapper
新建ApUserMessageMapper类 。

	@Service
	@SuppressWarnnings("all")
	public class ReviewMediaAtricleImpl implements ReviewMediaAtricleService{

	@Autowired
	private WmNewsMapper wmNewsMapper;
	
	@Autowired
	private AliyunTextScanRequest aliyunTestScanRequest;
	
	@Autowired
	private AliyunImageScanRequest aliyunImageScanRequest;
	@Override
	public void autoReviewAticleByMedia(Integer newsId){
	//根据文章id查询文章信
		WmNews wmNews=	wmNewsMapper.selectNewsDetailByPrirmaryKey(newsId);
		if(wmNes!=null){
		//判断状态为4的时,直接保存数据,人工审核通过了
			if(wmNews.getStatus()==4){
			reviewSuccessSaveAll(wmNews);
			return;
			}
		//审核通过后的待发布文章,判断发布时间
			if(wmNews.getStatus()==0&&wmNews.getPublishTime()!=null&&wm.getPublishTime>new Date().getTime){
		reviewSuccessSaveAll(wmNews);
			return;
			}
}
	  //审核文章
	  if(wmNews.getStatus()==1){
			//审核文章标题和内容的匹配度使用工具类Compute,比对第一个字符串,在第二个字符串的一个占有率
		String content=wmNew.getContent();
		String title=wmNew.getNews();
		double degree=Compute.SimilarDegree(content,title);			
		if(degree<=0){
			//文章标题不匹配,审核不通过
			updateWmNews(wmNews,(short)2,"文章内容和标题不匹配");
			return;
		}
		//文章标题匹配,审核文本和图片其实都是content
		//解析content
		List<String> images=new ArrayList<>();
		StringBuilder sb=new StringBuilder();
		JSONArray jsonarray=JSON.parseArray(content);
		handlerTextAndImages(images,sb,jsonArray);	 		
		//审核文本内容,
			String response =aliyunTextScanRequest.textScanRequest(sb.toString());
	if("review".equals(response)){
	//人工审核
	updateWmNews(wmNews,(short)3,"需要人工审核");
	return;
}	
	if("block".equals(response)){
	updateWmNews(wmNews,(short)2,"文本内容审核失败");
	return;
	}
	//审核文章中的图片信息,阿里接口
	String  imageResponse=aliyunImageScanRequset.imageScanRequset(images);
	if(imageResponse==null){
			updateWmNews(wmNews,(short)3,"需要人工审核");
			retrun;
	}
		if("review".equals(response)){
	//人工审核
	updateWmNews(wmNews,(short)3,"需要人工审核");
	return;
}	
	if("block".equals(response)){
	updateWmNews(wmNews,(short)2,"图片内容审核出现问题");
	return;
	}
			//审核图片信息,阿里接口
			//判断发布时间,如果否的话,保存数据,是的话,将wmApticle得status改成8.
			if(wmNews.getPublishTime()!=null){
				if(wmNews.getPublishTime.getTime()>new Date().getTime()){
				//修改wmNews的状态为8
				updateWmNews(wmNews,(short)8,"待发布");
				}
				else{	
				//立即发布
				updateWmNews(wmNews );
				}	
			}else{
				
				reviewSuccessSaveAll(wmNews);
			}
	}
	
	}


private void updateWmNews(WmNew swmNews,short status,String type){
	wmNews.setStatus(status);
	wmNews.setReason(String);
	WmNews.updateByPrimaryKeySelective(wmNews);

}
@Autowired
private ApAuthorMapper apAurthorMapper;

//保存数据,有4张表 ap_article_config,ap_article,ap_article_content,ap_author
//ap_author,保存文章的时候依赖于作者,有就用,没有就添加
private void reviewSuccessSaveAll(WmNews wmNews){
	if(wmNews.getUserId!=null){
		wmUser wmuser=wmUserMapper.selectById(wmNews.getUserId())  ;
		ApAuthor apauthor=null;
		if(wmuser!=null&&wmUser.getName!=null){
			ApAuthor apauthor=ApAtuhorMapper.selectByAuthorName(wmUser.getName());
			if(apauthor==null||author.getId()==null){
				//查询保存
				apAuthor=new ApAuthor():
				apAuthor.setUseId(wmNews.getUserId());
				apAuthor.setCreatedTime(new Dat());
				apAuthor.setType(2);
				apAuthor.setName(wmUser.getName());	
				apAUthor.setWmUserId(wmUser.getId());
				apAuthorMapper.insert(apAuthor);
			}
		}
	}
    //ap_article:channel需要查询ad_channel,布局需要设置vm中的type.文章的图片,文章的标签,创建时间设置,来源设置一下
	ApArticle apArticle=new ApArticle();
	Integer channelId=wmNews.getId();
	if(apAuthor!=null){
	apArticle.setAuthorId(apAuthor.getId().longValue());
	apArticle.setAuthorName(apAuthor.getName());}
	apArticle.setCreatTime(new Date())
	if(channelId!=null){
		adChannelMapper.selectByPrimaryKey(channelId);
		apArticle.setChannelId(channelId);
		apArticle.setChannelName(adChannel.getName());
	}
	//ap_article_congfig,ap_article_content
	apArticle.setLayout(wmNews.getType());
	apArticle.setTitle(wmNews.getTitle());
	String images=wmNews.getImages();//访问路径 servrUri+文件id
	if(images!=null){
		String[] split=images.split(",");
		StringBuilder sb=new StirngBuilder();
		for(int i<0;i<split.length;i++){
			if(i>0){
					sb.append(,);
				}
				sb.append(fileServerUrl);
				sb.append(split[i]);
		}	
		apArticle.setImages(sb.toString());
	}
	apArticleMapper.insert(apArticle);
	
	//创建ES索引,便于搜索。

}

//找出文本内容和图片列表 
private void handlerTextAndImages(List<String> images,StrinBuilder sb,JSONArray jsonArray){
		for(Object obj:jsonArray){
			JSONObject jsonObj=(JSONObject)obj;
			String type=(String)jsonObj.get("type");
			if("image".equals(type)){
				String value=(String)jsonObj.get("value");
				images.add(value);
			}
			if("text".equals(type)){
				sb.append(jsonObj.get("value"));
			}		
		}
} 	

	}

Content的格式如下:
content的格式
我们需要将text和层image都取出来,答题思路,转换成list
map中有两项,type和value,key-value。这里使用的死jsonAarry将大的json转换成小的jsonObj对象然后从小的json对象中获取对应的属性。

文章审核自动测试:

	public void TestReview(){

		reviewMediaArticleService.autoReviewByMedia(6110);	
		//当路径访问不到的时候,我们的response可能会为null,我们需要修改代码。
		//如果时间为null,我们就立即发布
	}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值