mirror of
				https://gitee.com/binary/weixin-java-tools.git
				synced 2025-10-31 02:28:25 +08:00 
			
		
		
		
	#857 添加微信小程序敏感文本检测接口
This commit is contained in:
		| @ -0,0 +1,43 @@ | |||||||
|  | package cn.binarywang.wx.miniapp.api; | ||||||
|  |  | ||||||
|  | import java.io.File; | ||||||
|  |  | ||||||
|  | import me.chanjar.weixin.common.error.WxErrorException; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * <pre> | ||||||
|  |  * 内容安全相关接口. | ||||||
|  |  * Created by Binary Wang on 2018/11/24. | ||||||
|  |  * </pre> | ||||||
|  |  * | ||||||
|  |  * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||||
|  |  */ | ||||||
|  | public interface WxMaSecCheckService { | ||||||
|  |  | ||||||
|  |   String IMG_SEC_CHECK_URL = "https://api.weixin.qq.com/wxa/img_sec_check"; | ||||||
|  |  | ||||||
|  |   String MSG_SEC_CHECK_URL = "https://api.weixin.qq.com/wxa/msg_sec_check"; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * <pre> | ||||||
|  |    * 校验一张图片是否含有违法违规内容. | ||||||
|  |    * 应用场景举例: | ||||||
|  |    * 1)图片智能鉴黄:涉及拍照的工具类应用(如美拍,识图类应用)用户拍照上传检测;电商类商品上架图片检测;媒体类用户文章里的图片检测等; | ||||||
|  |    * 2)敏感人脸识别:用户头像;媒体类用户文章里的图片检测;社交类用户上传的图片检测等。频率限制:单个 appId 调用上限为 1000 次/分钟,100,000 次/天 | ||||||
|  |    * 详情请见: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/sec-check/imgSecCheck.html | ||||||
|  |    * </pre> | ||||||
|  |    */ | ||||||
|  |   boolean checkImage(File file) throws WxErrorException; | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * <pre> | ||||||
|  |    * 检查一段文本是否含有违法违规内容。 | ||||||
|  |    * 应用场景举例: | ||||||
|  |    * 用户个人资料违规文字检测; | ||||||
|  |    * 媒体新闻类用户发表文章,评论内容检测; | ||||||
|  |    * 游戏类用户编辑上传的素材(如答题类小游戏用户上传的问题及答案)检测等。 频率限制:单个 appId 调用上限为 4000 次/分钟,2,000,000 次/天* | ||||||
|  |    * 详情请见: https://developers.weixin.qq.com/miniprogram/dev/api/open-api/sec-check/msgSecCheck.html | ||||||
|  |    * </pre> | ||||||
|  |    */ | ||||||
|  |   boolean checkMessage(String msgString); | ||||||
|  | } | ||||||
| @ -1,7 +1,5 @@ | |||||||
| package cn.binarywang.wx.miniapp.api; | package cn.binarywang.wx.miniapp.api; | ||||||
|  |  | ||||||
| import java.io.File; |  | ||||||
|  |  | ||||||
| import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | ||||||
| import cn.binarywang.wx.miniapp.config.WxMaConfig; | import cn.binarywang.wx.miniapp.config.WxMaConfig; | ||||||
| import me.chanjar.weixin.common.error.WxErrorException; | import me.chanjar.weixin.common.error.WxErrorException; | ||||||
| @ -20,17 +18,6 @@ public interface WxMaService { | |||||||
|  |  | ||||||
|   String JSCODE_TO_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session"; |   String JSCODE_TO_SESSION_URL = "https://api.weixin.qq.com/sns/jscode2session"; | ||||||
|  |  | ||||||
|   String IMG_SEC_CHECK_URL = "https://api.weixin.qq.com/wxa/img_sec_check"; |  | ||||||
|  |  | ||||||
|   /** |  | ||||||
|    * <pre> |  | ||||||
|    * 校验一张图片是否含有违法违规内容. |  | ||||||
|    * 应用场景举例:1)图片智能鉴黄:涉及拍照的工具类应用(如美拍,识图类应用)用户拍照上传检测;电商类商品上架图片检测;媒体类用户文章里的图片检测等;2)敏感人脸识别:用户头像;媒体类用户文章里的图片检测;社交类用户上传的图片检测等。频率限制:单个 appId 调用上限为 1000 次/分钟,100,000 次/天 |  | ||||||
|    * 详情请见: https://developers.weixin.qq.com/miniprogram/dev/api/imgSecCheck.html |  | ||||||
|    * </pre> |  | ||||||
|    */ |  | ||||||
|   boolean imgSecCheck(File file) throws WxErrorException; |  | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 获取登录后的session信息. |    * 获取登录后的session信息. | ||||||
|    * |    * | ||||||
| @ -186,11 +173,17 @@ public interface WxMaService { | |||||||
|   WxMaShareService getShareService(); |   WxMaShareService getShareService(); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 返回维新运动相关接口服务对象. |    * 返回微信运动相关接口服务对象. | ||||||
|    * @return WxMaShareService |    * @return WxMaShareService | ||||||
|    */ |    */ | ||||||
|   WxMaRunService getRunService(); |   WxMaRunService getRunService(); | ||||||
|  |  | ||||||
|  |   /** | ||||||
|  |    * 返回内容安全相关接口服务对象. | ||||||
|  |    * @return WxMaShareService | ||||||
|  |    */ | ||||||
|  |   WxMaSecCheckService getSecCheckService(); | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * 初始化http请求对象. |    * 初始化http请求对象. | ||||||
|    */ |    */ | ||||||
|  | |||||||
| @ -0,0 +1,48 @@ | |||||||
|  | package cn.binarywang.wx.miniapp.api.impl; | ||||||
|  |  | ||||||
|  | import java.io.File; | ||||||
|  |  | ||||||
|  | import cn.binarywang.wx.miniapp.api.WxMaSecCheckService; | ||||||
|  | import cn.binarywang.wx.miniapp.api.WxMaService; | ||||||
|  | import com.google.gson.JsonObject; | ||||||
|  | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||||
|  | import me.chanjar.weixin.common.error.WxErrorException; | ||||||
|  | import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * <pre> | ||||||
|  |  * | ||||||
|  |  * Created by Binary Wang on 2018/11/24. | ||||||
|  |  * </pre> | ||||||
|  |  * | ||||||
|  |  * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||||
|  |  */ | ||||||
|  | public class WxMaSecCheckServiceImpl implements WxMaSecCheckService { | ||||||
|  |   private WxMaService service; | ||||||
|  |  | ||||||
|  |   public WxMaSecCheckServiceImpl(WxMaService service) { | ||||||
|  |     this.service = service; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public boolean checkImage(File file) throws WxErrorException { | ||||||
|  |     //这里只是借用MediaUploadRequestExecutor,并不使用其返回值WxMediaUploadResult | ||||||
|  |     WxMediaUploadResult result = this.service.execute(MediaUploadRequestExecutor | ||||||
|  |       .create(this.service.getRequestHttp()), IMG_SEC_CHECK_URL, file); | ||||||
|  |     return result != null; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public boolean checkMessage(String msgString) { | ||||||
|  |     JsonObject jsonObject = new JsonObject(); | ||||||
|  |     jsonObject.addProperty("content", msgString); | ||||||
|  |     try { | ||||||
|  |       this.service.post(MSG_SEC_CHECK_URL, jsonObject.toString()); | ||||||
|  |     } catch (WxErrorException e) { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return true; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
| @ -1,6 +1,5 @@ | |||||||
| package cn.binarywang.wx.miniapp.api.impl; | package cn.binarywang.wx.miniapp.api.impl; | ||||||
|  |  | ||||||
| import java.io.File; |  | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| @ -12,8 +11,6 @@ import org.apache.http.client.methods.CloseableHttpResponse; | |||||||
| import org.apache.http.client.methods.HttpGet; | import org.apache.http.client.methods.HttpGet; | ||||||
| import org.apache.http.impl.client.BasicResponseHandler; | import org.apache.http.impl.client.BasicResponseHandler; | ||||||
| import org.apache.http.impl.client.CloseableHttpClient; | import org.apache.http.impl.client.CloseableHttpClient; | ||||||
| import org.slf4j.Logger; |  | ||||||
| import org.slf4j.LoggerFactory; |  | ||||||
|  |  | ||||||
| import cn.binarywang.wx.miniapp.api.WxMaAnalysisService; | import cn.binarywang.wx.miniapp.api.WxMaAnalysisService; | ||||||
| import cn.binarywang.wx.miniapp.api.WxMaCodeService; | import cn.binarywang.wx.miniapp.api.WxMaCodeService; | ||||||
| @ -22,6 +19,7 @@ import cn.binarywang.wx.miniapp.api.WxMaMediaService; | |||||||
| import cn.binarywang.wx.miniapp.api.WxMaMsgService; | import cn.binarywang.wx.miniapp.api.WxMaMsgService; | ||||||
| import cn.binarywang.wx.miniapp.api.WxMaQrcodeService; | import cn.binarywang.wx.miniapp.api.WxMaQrcodeService; | ||||||
| import cn.binarywang.wx.miniapp.api.WxMaRunService; | import cn.binarywang.wx.miniapp.api.WxMaRunService; | ||||||
|  | import cn.binarywang.wx.miniapp.api.WxMaSecCheckService; | ||||||
| import cn.binarywang.wx.miniapp.api.WxMaService; | import cn.binarywang.wx.miniapp.api.WxMaService; | ||||||
| import cn.binarywang.wx.miniapp.api.WxMaSettingService; | import cn.binarywang.wx.miniapp.api.WxMaSettingService; | ||||||
| import cn.binarywang.wx.miniapp.api.WxMaShareService; | import cn.binarywang.wx.miniapp.api.WxMaShareService; | ||||||
| @ -31,14 +29,13 @@ import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult; | |||||||
| import cn.binarywang.wx.miniapp.config.WxMaConfig; | import cn.binarywang.wx.miniapp.config.WxMaConfig; | ||||||
| import com.google.common.base.Joiner; | import com.google.common.base.Joiner; | ||||||
| import com.google.gson.Gson; | import com.google.gson.Gson; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
| import me.chanjar.weixin.common.bean.WxAccessToken; | import me.chanjar.weixin.common.bean.WxAccessToken; | ||||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; |  | ||||||
| import me.chanjar.weixin.common.error.WxError; | import me.chanjar.weixin.common.error.WxError; | ||||||
| import me.chanjar.weixin.common.error.WxErrorException; | import me.chanjar.weixin.common.error.WxErrorException; | ||||||
| import me.chanjar.weixin.common.util.DataUtils; | import me.chanjar.weixin.common.util.DataUtils; | ||||||
| import me.chanjar.weixin.common.util.crypto.SHA1; | import me.chanjar.weixin.common.util.crypto.SHA1; | ||||||
| import me.chanjar.weixin.common.util.http.HttpType; | import me.chanjar.weixin.common.util.http.HttpType; | ||||||
| import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; |  | ||||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | import me.chanjar.weixin.common.util.http.RequestExecutor; | ||||||
| import me.chanjar.weixin.common.util.http.RequestHttp; | import me.chanjar.weixin.common.util.http.RequestHttp; | ||||||
| import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; | ||||||
| @ -51,9 +48,8 @@ import static cn.binarywang.wx.miniapp.constant.WxMaConstants.ErrorCode.*; | |||||||
| /** | /** | ||||||
|  * @author <a href="https://github.com/binarywang">Binary Wang</a> |  * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||||
|  */ |  */ | ||||||
|  | @Slf4j | ||||||
| public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpClient, HttpHost> { | public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpClient, HttpHost> { | ||||||
|   private final Logger log = LoggerFactory.getLogger(this.getClass()); |  | ||||||
|  |  | ||||||
|   private CloseableHttpClient httpClient; |   private CloseableHttpClient httpClient; | ||||||
|   private HttpHost httpProxy; |   private HttpHost httpProxy; | ||||||
|   private WxMaConfig wxMaConfig; |   private WxMaConfig wxMaConfig; | ||||||
| @ -69,6 +65,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||||
|   private WxMaJsapiService jsapiService = new WxMaJsapiServiceImpl(this); |   private WxMaJsapiService jsapiService = new WxMaJsapiServiceImpl(this); | ||||||
|   private WxMaShareService shareService = new WxMaShareServiceImpl(this); |   private WxMaShareService shareService = new WxMaShareServiceImpl(this); | ||||||
|   private WxMaRunService runService = new WxMaRunServiceImpl(this); |   private WxMaRunService runService = new WxMaRunServiceImpl(this); | ||||||
|  |   private WxMaSecCheckService secCheckService = new WxMaSecCheckServiceImpl(this); | ||||||
|  |  | ||||||
|   private int retrySleepMillis = 1000; |   private int retrySleepMillis = 1000; | ||||||
|   private int maxRetryTimes = 5; |   private int maxRetryTimes = 5; | ||||||
| @ -153,13 +150,6 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||||
|     return this.getWxMaConfig().getAccessToken(); |     return this.getWxMaConfig().getAccessToken(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Override |  | ||||||
|   public boolean imgSecCheck(File file) throws WxErrorException { |  | ||||||
|     //这里只是借用MediaUploadRequestExecutor,并不使用其返回值WxMediaUploadResult |  | ||||||
|     WxMediaUploadResult result = this.execute(MediaUploadRequestExecutor.create(this.getRequestHttp()), IMG_SEC_CHECK_URL, file); |  | ||||||
|     return result != null; |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @Override |   @Override | ||||||
|   public WxMaJscode2SessionResult jsCode2SessionInfo(String jsCode) throws WxErrorException { |   public WxMaJscode2SessionResult jsCode2SessionInfo(String jsCode) throws WxErrorException { | ||||||
|     final WxMaConfig config = getWxMaConfig(); |     final WxMaConfig config = getWxMaConfig(); | ||||||
| @ -209,7 +199,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||||
|         return this.executeInternal(executor, uri, data); |         return this.executeInternal(executor, uri, data); | ||||||
|       } catch (WxErrorException e) { |       } catch (WxErrorException e) { | ||||||
|         if (retryTimes + 1 > this.maxRetryTimes) { |         if (retryTimes + 1 > this.maxRetryTimes) { | ||||||
|           this.log.warn("重试达到最大次数【{}】", maxRetryTimes); |           log.warn("重试达到最大次数【{}】", maxRetryTimes); | ||||||
|           //最后一次重试失败后,直接抛出异常,不再等待 |           //最后一次重试失败后,直接抛出异常,不再等待 | ||||||
|           throw new RuntimeException("微信服务端异常,超出重试次数"); |           throw new RuntimeException("微信服务端异常,超出重试次数"); | ||||||
|         } |         } | ||||||
| @ -219,7 +209,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||||
|         if (error.getErrorCode() == -1) { |         if (error.getErrorCode() == -1) { | ||||||
|           int sleepMillis = this.retrySleepMillis * (1 << retryTimes); |           int sleepMillis = this.retrySleepMillis * (1 << retryTimes); | ||||||
|           try { |           try { | ||||||
|             this.log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1); |             log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1); | ||||||
|             Thread.sleep(sleepMillis); |             Thread.sleep(sleepMillis); | ||||||
|           } catch (InterruptedException e1) { |           } catch (InterruptedException e1) { | ||||||
|             throw new RuntimeException(e1); |             throw new RuntimeException(e1); | ||||||
| @ -230,7 +220,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||||
|       } |       } | ||||||
|     } while (retryTimes++ < this.maxRetryTimes); |     } while (retryTimes++ < this.maxRetryTimes); | ||||||
|  |  | ||||||
|     this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes); |     log.warn("重试达到最大次数【{}】", this.maxRetryTimes); | ||||||
|     throw new RuntimeException("微信服务端异常,超出重试次数"); |     throw new RuntimeException("微信服务端异常,超出重试次数"); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @ -246,7 +236,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||||
|  |  | ||||||
|     try { |     try { | ||||||
|       T result = executor.execute(uriWithAccessToken, data); |       T result = executor.execute(uriWithAccessToken, data); | ||||||
|       this.log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); |       log.debug("\n【请求地址】: {}\n【请求参数】:{}\n【响应数据】:{}", uriWithAccessToken, dataForLog, result); | ||||||
|       return result; |       return result; | ||||||
|     } catch (WxErrorException e) { |     } catch (WxErrorException e) { | ||||||
|       WxError error = e.getError(); |       WxError error = e.getError(); | ||||||
| @ -264,12 +254,12 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       if (error.getErrorCode() != 0) { |       if (error.getErrorCode() != 0) { | ||||||
|         this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error); |         log.error("\n【请求地址】: {}\n【请求参数】:{}\n【错误信息】:{}", uriWithAccessToken, dataForLog, error); | ||||||
|         throw new WxErrorException(error, e); |         throw new WxErrorException(error, e); | ||||||
|       } |       } | ||||||
|       return null; |       return null; | ||||||
|     } catch (IOException e) { |     } catch (IOException e) { | ||||||
|       this.log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage()); |       log.error("\n【请求地址】: {}\n【请求参数】:{}\n【异常信息】:{}", uriWithAccessToken, dataForLog, e.getMessage()); | ||||||
|       throw new RuntimeException(e); |       throw new RuntimeException(e); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @ -349,4 +339,9 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl | |||||||
|   public WxMaRunService getRunService() { |   public WxMaRunService getRunService() { | ||||||
|     return this.runService; |     return this.runService; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @Override | ||||||
|  |   public WxMaSecCheckService getSecCheckService() { | ||||||
|  |     return this.secCheckService; | ||||||
|  |   } | ||||||
| } | } | ||||||
|  | |||||||
| @ -0,0 +1,51 @@ | |||||||
|  | package cn.binarywang.wx.miniapp.api.impl; | ||||||
|  |  | ||||||
|  | import java.io.File; | ||||||
|  |  | ||||||
|  | import org.testng.annotations.*; | ||||||
|  |  | ||||||
|  | import cn.binarywang.wx.miniapp.api.WxMaService; | ||||||
|  | import cn.binarywang.wx.miniapp.test.ApiTestModule; | ||||||
|  | import com.google.inject.Inject; | ||||||
|  | import me.chanjar.weixin.common.error.WxErrorException; | ||||||
|  |  | ||||||
|  | import static org.assertj.core.api.Assertions.assertThat; | ||||||
|  | import static org.testng.Assert.*; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * <pre> | ||||||
|  |  * | ||||||
|  |  * Created by Binary Wang on 2018/11/24. | ||||||
|  |  * </pre> | ||||||
|  |  * | ||||||
|  |  * @author <a href="https://github.com/binarywang">Binary Wang</a> | ||||||
|  |  */ | ||||||
|  | @Test | ||||||
|  | @Guice(modules = ApiTestModule.class) | ||||||
|  | public class WxMaSecCheckServiceImplTest { | ||||||
|  |   @Inject | ||||||
|  |   private WxMaService wxService; | ||||||
|  |  | ||||||
|  |   @Test | ||||||
|  |   public void testCheckImage() throws WxErrorException { | ||||||
|  |     boolean result = this.wxService.getSecCheckService() | ||||||
|  |       .checkImage(new File(ClassLoader.getSystemResource("tmp.png").getFile())); | ||||||
|  |     assertTrue(result); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @DataProvider | ||||||
|  |   public Object[][] secData() { | ||||||
|  |     return new Object[][]{ | ||||||
|  |       {"特3456书yuuo莞6543李zxcz蒜7782法fgnv级", false}, | ||||||
|  |       {"完2347全dfji试3726测asad感3847知qwez到", false}, | ||||||
|  |       {"hello world!", true} | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Test(dataProvider = "secData") | ||||||
|  |   public void testCheckMessage(String msg, boolean result) { | ||||||
|  |     assertThat(this.wxService.getSecCheckService() | ||||||
|  |       .checkMessage(msg)) | ||||||
|  |       .isEqualTo(result); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @ -33,9 +33,4 @@ public class WxMaServiceImplTest { | |||||||
|     assertTrue(StringUtils.isNotBlank(after)); |     assertTrue(StringUtils.isNotBlank(after)); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Test |  | ||||||
|   public void testImgSecCheck() throws WxErrorException { |  | ||||||
|     boolean result = this.wxService.imgSecCheck(new File(ClassLoader.getSystemResource("tmp.png").getFile())); |  | ||||||
|     assertTrue(result); |  | ||||||
|   } |  | ||||||
| } | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 Binary Wang
					Binary Wang