Преглед на файлове

Auto stash before merge of "develop" and "origin/develop"

wzq преди 5 години
родител
ревизия
f7913098ca

+ 24 - 0
app/Http/Controllers/V1/PostController.php

@@ -32,6 +32,28 @@ class PostController extends Controller
         $this->postRepositories = $postRepositories;
     }
 
+    /**
+     * 发布内容
+     */
+    public function create(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'type' => ['required',Rule::in('image', 'video', 'html')],
+            'img' => 'required|url',
+            'video' => 'required_if:type,video|string|url',
+            'topic_ids' => 'required|string|max:64',
+            'title' => 'nullable|string|max:20',
+            'content' => 'required|string|max:1000',
+            'location' => 'nullable|string|max:20',
+            'imgs' => 'required_if:type,image|string',
+        ]);
+        if ($validator->fails()) {
+            return jsonError($validator->errors()->first());
+        }
+
+        return  $this->postRepositories->create($request->all());
+    }
+
     /**
      * 内容列表
      */
@@ -133,4 +155,6 @@ class PostController extends Controller
         ];
         return jsonSuccess($data);
     }
+
+
 }

+ 126 - 1
app/Repositories/PostRepositories.php

@@ -14,16 +14,141 @@ use App\Models\Post;
 use App\Models\PostCollect;
 use App\Models\PostComment;
 use App\Models\PostData;
+use App\Models\PostImgs;
 use App\Models\PostLike;
+use App\Models\Topic;
+use App\Service\DetectionService;
+use App\Traits\PostTrait;
+use App\Traits\UserTrait;
+use Illuminate\Database\QueryException;
 use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Redis;
+use Illuminate\Support\Facades\DB;
 
 class PostRepositories
 {
-    public function __construct(Post $post,PostComment $postComment)
+    use UserTrait;
+    use PostTrait;
+    public function __construct(Post $post,
+                                PostData $postData,
+                                PostImgs $postImgs,
+                                PostComment $postComment,
+                                DetectionService $detectionService,
+                                Topic $topic)
     {
         $this->post = $post;
+        $this->postData = $postData;
+        $this->postImgs = $postImgs;
         $this->postComment = $postComment;
+        $this->detectionService = $detectionService;
+        $this->topic = $topic;
+    }
+
+    /**
+     * 发布内容
+     */
+    public function create($request)
+    {
+        //验证小号
+        $userInfo = $this->getUserInfo();
+        if (empty($userInfo)) {
+            Log::info('获取用户信息失败');
+            return jsonError('获取用户信息失败');
+        }
+
+        $detectionText = $request['title'] .','. $request['content'];
+        $detectionTextResult = $this->detectionService->checkText($detectionText);
+        if ($detectionTextResult['code']<0) {
+            return jsonError('内容违规,请修正哦');
+        }
+
+        $topicIds = json_decode($request['topic_ids'], true);
+        $topicCount = count($topicIds);
+        if($topicCount == 0 || $topicCount > 5){
+            return jsonError('所选话题必须1-5个');
+        }
+        //验证话题
+        $hasTopicCount = $this->topic->whereIn('id', $topicIds)->count();
+        if($topicCount != $hasTopicCount){
+            Log::error('所选话题非法'.$request['topic_ids']);
+            return jsonError('所选话题非法');
+        }
+        $imgs = [];
+        if($request['type'] == 'image'){
+            $imgs = json_decode($request['imgs'], true);
+            $imgCount = count($imgs);
+            if($imgCount == 0 || $imgCount > 9){
+                return jsonError('所传图集必须1-9个');
+            }
+        }
+        $allImg = array_merge($imgs, [$request['img']]);
+        $detectionImageResult = $this->detectionService->checkImg($allImg);
+        if ($detectionImageResult['code']<0) {
+            return jsonError('图片违规,请修正哦');
+        }
+
+        $data = [
+            'uid' => $userInfo['uid'],
+            'username' => $userInfo['username'],
+            'mobile' => $userInfo['mobile'],
+            'avatar' => $userInfo['avatar']??'',
+            'type' => $request['type'],
+            'img' => $request['img'],
+            'video' => isset($request['video'])? $request['video'] : '',
+            'topic_ids' => implode(',', $topicIds),
+            'title' => isset($request['title'])? $request['title'] : '',
+            'content' => $request['content'],
+            'location' => isset($request['location'])? $request['location'] : '',
+            'is_suggest' => 0,
+            'is_hide' => 0
+        ];
+
+        $date = date('Y-m-d H:i:s');
+
+
+        DB::beginTransaction();
+        try{
+            $post = $this->post->create($data);
+
+            $this->postData->create([
+                'post_id' => $post->id,
+                'pv' => 0,
+                'pv_real' => 0,
+                'dislike_count' => 0,
+                'praise_count' => 0,
+                'praise_real_count' => 0,
+                'share_count' => 0,
+                'share_real_count' => 0,
+                'comment_count' => 0,
+                'collect_count' => 0,
+                'collect_real_count' => 0,
+                'available_bean' => $this->availableBean(),
+                'will_collect_bean' => rand(100, 200),
+                'collect_bean' => 0,
+                'weight' => 0
+            ]);
+
+            if($imgs){
+                $imgData = [];
+                foreach($imgs as $img){
+                    $imgData[] = [
+                        'post_id' => $post->id,
+                        'img' => $img,
+                        'created_at' => $date,
+                        'updated_at' => $date
+                    ];
+                }
+                $this->postImgs->insert($imgData);
+            }
+
+            DB::commit();
+            return jsonSuccess();
+
+        }catch (QueryException $exception){
+            DB::rollBack();
+            Log::debug('发布内容失败:'.$exception->getMessage());
+            return jsonError('发布内容失败,请重试');
+        }
     }
 
     /**

+ 188 - 0
app/Service/DetectionService.php

@@ -0,0 +1,188 @@
+<?php
+namespace App\Service;
+
+use Green\Request\V20170112 as Green;
+
+class DetectionService
+{
+    /**
+     * Get the acs client
+     * @return \DefaultAcsClient
+     */
+    private function getClient()
+    {
+        date_default_timezone_set("PRC");
+        $iClientProfile = \DefaultProfile::getProfile("cn-shanghai", config('aliyun.access_key'), config('aliyun.access_secret'));
+
+        \DefaultProfile::addEndpoint("cn-shanghai", "cn-shanghai", "Green", "green.cn-shanghai.aliyuncs.com");
+
+        $client = new \DefaultAcsClient($iClientProfile);
+
+        return $client;
+    }
+
+    /**
+     * scene 风险场景,和传递进来的场景对应
+     * suggestion 建议用户处理,取值范围:[“pass”, “review”, “block”], pass:图片正常,review:需要人工审核,block:图片违规,
+     *            可以直接删除或者做限制处理
+     * label 文本的分类
+     * rate 浮点数,结果为该分类的概率;值越高,越趋于该分类;取值为[0.00-100.00]
+     * extras map,可选,附加信息. 该值将来可能会调整,建议不要在业务上进行依赖
+     *
+     *  -10000  检测数据有问题
+     *  10000  检测数据正常
+     *  20000  检测出异常 重试三次
+     * @param $request
+     */
+    private function processResponse($request)
+    {
+        $client = $this->getClient();
+        try {
+            $response = $client->getAcsResponse($request);
+
+            if(200 == $response->code){
+                $taskResults = $response->data;
+                $detail = [];
+                $flag = true;
+                foreach ($taskResults as $taskResult) {
+                    if(200 == $taskResult->code){
+                        $this->processSceneResult($taskResult, $flag);
+                    }else{
+                        return $this->echoStr(-2000, 'task process fail:'.$response->code);
+                    }
+                    if (isset($taskResult->filteredContent)) {
+                        array_push($detail, $taskResult->filteredContent);
+                    }
+                }
+                if($flag == false){
+                    return $this->echoStr(-10000, 'the scene is not normal', $detail);
+                }else{
+                    return $this->echoStr(10000, 'the scene is normal');
+                }
+            }else{
+                return $this->echoStr(-2000, 'detect not success. code:'.$response->code);
+            }
+        } catch (Exception $e) {
+            return $this->echoStr(-2000, $e);
+        }
+    }
+
+    /**
+     * @param $code
+     * @param $msg
+     */
+    private function echoStr($code, $msg, $detail = []){
+        return array(
+            'code' => $code,
+            'msg' => $msg,
+            'detail' => $detail
+        );
+    }
+
+    /**
+     * @param $taskResult
+     */
+    private function processSceneResult($taskResult, &$flag){
+        $sceneResults = $taskResult->results;
+        foreach ($sceneResults as $sceneResult) {
+            //根据scene和suggetion做相关的处理
+            $suggestion = $sceneResult->suggestion;
+            $rate = $sceneResult->rate;
+            if($suggestion!='pass' && $rate>80){
+                $flag = false;
+            }
+        }
+    }
+
+    /**
+     * 文本垃圾检测
+     * scenes字符串数组:
+     *   关键词识别scene场景取值keyword
+     *        分类label:正常normal 含垃圾信息spam 含广告ad 涉政politics 暴恐terrorism 色情porn 辱骂abuse
+     *                  灌水flood 命中自定义customized(阿里后台自定义)
+     *   垃圾检测识别场景scene取值antispam
+     *        分类label:正常normal 含违规信息spam 含广告ad 涉政politics 暴恐terrorism 色情porn 违禁contraband
+     *                  命中自定义customized(阿里后台自定义)
+     *
+     * tasks json数组 ,最多支持100个task即100段文本
+     * content 待检测文本,最长4000个字符
+     *
+     * @param $text 支持字符串和数组
+     * @return null
+     */
+    public function checkText($text){
+        if(empty($text)){
+            return null;
+        }
+        $request = new Green\TextScanRequest();
+        $request->setMethod("POST");
+        $request->setAcceptFormat("JSON");
+        if(is_array($text)){
+            $taskArr = [];
+            foreach($text as $k => $v){
+                $task = 'task'.$k;
+                $$task = array('dataId' =>  md5(uniqid($task)),
+                    'content' => $v,
+                    'category' => 'post',
+                    'time' => round(microtime(true)*1000)
+                );
+                array_push($taskArr, $$task);
+            }
+            $request->setContent(json_encode(array("tasks" => $taskArr,
+                "scenes" => array("antispam"))));
+        }else if(is_string($text)){
+            $task1 = array('dataId' =>  md5(uniqid()),
+                'content' => $text
+            );
+            $request->setContent(json_encode(array("tasks" => array($task1),
+                "scenes" => array("antispam"))));
+        }
+        return $this->processResponse($request);
+    }
+    /**
+     * 图片检测
+     * scenes字符串数组:
+     *   图片广告识别scene场景取值ad
+     *        分类label: 正常normal 含广告ad
+     *   图片鉴黄识别场景scene取值porn
+     *        分类label:正常normal 性感sexy 色情porn
+     *   图片暴恐涉政识别场景scene取值terrorism
+     *        分类label:正常normal terrorism含暴恐图片 outfit特殊装束 logo特殊标识 weapon武器 politics渉政 others	其它暴恐渉政
+     *
+     * tasks json数组 ,最多支持100个task即100张图片
+     *
+     * @param $img 支持字符串和数组
+     * @return null
+     */
+    public function checkImg($img){
+        if(empty($img)){
+            return null;
+        }
+        $request = new Green\ImageSyncScanRequest();
+        $request->setMethod("POST");
+        $request->setAcceptFormat("JSON");
+        if(is_array($img)){
+            $taskArr = array();
+            foreach($img as $k => $v){
+                $task = 'task'.$k;
+                $$task = array('dataId' =>  md5(uniqid($task)),
+                    'url' => $v,
+                    'time' => round(microtime(true)*1000)
+                );
+                array_push($taskArr, $$task);
+            }
+            $request->setContent(json_encode(array("tasks" => $taskArr,
+                "scenes" => array("ad", "porn", "terrorism"))));
+        }else if(is_string($img)){
+            $task1 = array('dataId' =>  md5(uniqid()),
+                'url' => $img,
+                'time' => round(microtime(true)*1000)
+            );
+            $request->setContent(json_encode(array("tasks" => array($task1),
+                "scenes" => array("ad", "porn", "terrorism"))));
+        }
+        return $this->processResponse($request);
+    }
+
+
+}

+ 34 - 0
app/Traits/PostTrait.php

@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/6
+ * Time: 18:05
+ */
+namespace App\Traits;
+
+use Illuminate\Support\Facades\Redis;
+
+trait PostTrait
+{
+    //预计可获得彩虹豆数
+    public function availableBean()
+    {
+        $bean = Redis::get('yesterday_post_create_bean');
+        $count = Redis::get('yesterday_post_count');
+        $num = 1000;
+        if($bean && $count){
+            $num = $bean / $count;
+        }
+        $h = date('h');
+        $H = date('H');
+        $t = $h * 60 / 720 + 2;
+
+
+        if(in_array(intval($H), [9,10,11,12,17.18,19,20,21])){
+            $t += 0.5;
+        }
+        return intval($num * $t);
+    }
+}

+ 1 - 0
bootstrap/app.php

@@ -32,6 +32,7 @@ $app->configure('auth');
 $app->configure('jwt');
 $app->configure('database');
 $app->configure('elasticsearch');
+$app->configure('aliyun');
 /*
 |--------------------------------------------------------------------------
 | Register Container Bindings

+ 1 - 0
composer.json

@@ -17,6 +17,7 @@
         "tymon/jwt-auth": "1.0.0-rc.4.1",
         "vlucas/phpdotenv": "^3.3",
         "moontoast/math": "^1.1",
+        "tomcao/aliyuncs-green": "^1.1",
         "multilinguals/apollo-client": "^0.1.2"
     },
     "require-dev": {

+ 7 - 0
config/aliyun.php

@@ -0,0 +1,7 @@
+<?php
+
+
+return [
+    'access_key'        => 'LTAIGTDKUOVQf2Ln', // accessKey
+    'access_secret'     => 'HzY9r2gDPbURQ0Vp69A7THV0RmxMkb', // accessSecret
+];

+ 11 - 0
resources/lang/zh-CN/validation.php

@@ -101,6 +101,17 @@ return [
 
     'attributes' => [
         'post_id' => '内容id',
+        'uid' => '用户uid',
+        'type' => '类型',
+        'is_suggest' => '是否推荐',
+        'img' => '图片',
+        'video' => '视频',
+        'topic_ids' => '话题id',
+        'title' => '标题',
+        'content' => '内容',
+        'location' => '位置',
+        'imgs' => '图组',
+        'imgs.*' => '图集',
     ],
     'mobile'    => '手机号码格式不正确。',
 ];

+ 1 - 0
routes/api.php

@@ -20,6 +20,7 @@ $api->version('v1', [
     $api->get('getBehaviorByIdentify', 'BehaviorController@getBehaviorByIdentify');
     //登录+验签
     $api->group(['middleware' => ['chxq_jwt_auth']], function ($api) {
+        $api->post('post', 'PostController@create');
         $api->get('post', 'PostController@index');
         $api->get('post/suggest', 'PostController@suggestPost');
         $api->get('post/comment', 'PostController@commentList');