瀏覽代碼

Merge branch 'master' into release

xielin 5 年之前
父節點
當前提交
2e38585ec1
共有 36 個文件被更改,包括 2348 次插入60 次删除
  1. 74 0
      app/Console/Commands/CalcCircleMessageWeight.php
  2. 5 1
      app/Console/Kernel.php
  3. 7 2
      app/Helper/helper.php
  4. 447 0
      app/Http/Controllers/V1/CircleController.php
  5. 5 2
      app/Http/Controllers/V1/Controller.php
  6. 2 0
      app/Http/Controllers/V1/PostController.php
  7. 24 0
      app/Models/InterestCircle.php
  8. 19 0
      app/Models/InterestCircleArticle.php
  9. 25 0
      app/Models/InterestCircleMessage.php
  10. 17 0
      app/Models/InterestCircleMessageComment.php
  11. 20 0
      app/Models/InterestCircleMessageImg.php
  12. 17 0
      app/Models/InterestCircleMessageRecord.php
  13. 20 0
      app/Models/InterestCirclePicture.php
  14. 19 0
      app/Models/InterestCircleUser.php
  15. 47 13
      app/Repositories/BeanRepository.php
  16. 53 0
      app/Repositories/Circle/CircleArticleRepository.php
  17. 51 0
      app/Repositories/Circle/CircleMemberRepository.php
  18. 602 0
      app/Repositories/Circle/CircleMessageRepository.php
  19. 204 0
      app/Repositories/Circle/CircleRepository.php
  20. 7 1
      app/Repositories/FeedRepositories.php
  21. 31 5
      app/Repositories/PostRepositories.php
  22. 2 1
      app/Traits/PostTrait.php
  23. 46 21
      app/Traits/UserTrait.php
  24. 73 0
      app/Transformers/Circle/ArticleListTransformer.php
  25. 29 0
      app/Transformers/Circle/CircleMemberTransformer.php
  26. 86 0
      app/Transformers/Circle/CommentTransformer.php
  27. 91 0
      app/Transformers/Circle/DetailTransformer.php
  28. 97 0
      app/Transformers/Circle/MessageListTransformer.php
  29. 51 0
      app/Transformers/Circle/PictureListTransformer.php
  30. 54 0
      app/Transformers/Circle/QuestionTransformer.php
  31. 40 0
      app/Transformers/Circle/ReplyTransformer.php
  32. 1 0
      app/Transformers/Post/ListTransformer.php
  33. 7 1
      app/Transformers/Post/SuggestTransformer.php
  34. 20 3
      app/Transformers/Topic/TopicDetailTransformer.php
  35. 14 10
      app/Transformers/Topic/TopicPostTransformer.php
  36. 41 0
      routes/api.php

+ 74 - 0
app/Console/Commands/CalcCircleMessageWeight.php

@@ -0,0 +1,74 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Models\InterestCircleMessage;
+use App\Models\Post;
+use App\Models\PostData;
+use Carbon\Carbon;
+use Illuminate\Console\Command;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Redis;
+
+class CalcCircleMessageWeight extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'circle:calc_weight';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '计算提问权重';
+
+
+    /**
+     * Create a new command instance.
+     *
+     * @return void
+     */
+    public function __construct()
+    {
+        parent::__construct();
+    }
+
+    /**
+     * Execute the console command.
+     *
+     * @return mixed
+     */
+    public function handle()
+    {
+        $this->line(date('Y-m-d H:i:s') . '开始计算权重');
+        $key = "community_calc_circle_score";
+        $postIds = Redis::smembers($key);
+        Log::debug('提问ID:' . json_encode($postIds));
+        foreach ($postIds as $postId) {
+            $info = InterestCircleMessage::where("id", $postId)->first();
+            if (empty($info)) {
+                continue;
+            }
+            Log::debug('帖子:' . json_encode($info));
+            $temp = (
+                (3 * $info->good) +
+                (10 * $info->comment_count) +
+                (2 * $info->bad));
+            $fresh = (Carbon::parse($info['created_at'])->timestamp) - (Carbon::parse("2019-10-08 00:00:00")->timestamp);
+            if ($temp) {
+                $score = log10($temp) + $fresh / 43200 * 14;
+            } else {
+                $score = $fresh / 43200;
+            }
+            $info->weight = $score;
+            $info->save();
+            Redis::srem($key, $postId);
+            Log::debug(date("Y-m-d H:i:s") . "设置提问" . $info->id . "的权重分为:" . $score);
+        }
+        $this->line(date('Y-m-d H:i:s') . ' 计算权重结束');
+    }
+}

+ 5 - 1
app/Console/Kernel.php

@@ -4,6 +4,7 @@ namespace App\Console;
 
 use App\Console\Commands\Apollo;
 use App\Console\Commands\BehaviorRecord;
+use App\Console\Commands\CalcCircleMessageWeight;
 use App\Console\Commands\CalcPostWeight;
 use App\Console\Commands\ContentFeedCreate;
 use App\Console\Commands\ContentFeedDelete;
@@ -32,7 +33,8 @@ class Kernel extends ConsoleKernel
         DelPostNewReply::class,
         DelPostNewComment::class,
         DelMemberRepeatTopic::class,
-        RankingList::class
+        RankingList::class,
+        CalcCircleMessageWeight::class
     ];
 
     /**
@@ -52,5 +54,7 @@ class Kernel extends ConsoleKernel
         $schedule->command('ranking:list')
             ->dailyAt('00:05')
             ->withoutOverlapping()->appendOutputTo($path);
+        $schedule->command('circle:calc_weight')
+            ->everyFiveMinutes()->withoutOverlapping()->appendOutputTo($path);
     }
 }

+ 7 - 2
app/Helper/helper.php

@@ -22,6 +22,7 @@ if (!function_exists('config_path')) {
  */
 function generateSign(array $params, $secret_key)
 {
+    \Illuminate\Support\Facades\Log::debug($params);
     unset($params['sign']);
     // 将删除参数组中所有等值为FALSE的参数(包括:NULL, 空字符串,0, false)
     // $params = array_filter($params);
@@ -119,18 +120,22 @@ function jsonSuccess($data = [], $msg = "成功", $extra = [])
     return $response;
 }
 
-function jsonError($msg)
+function jsonError($msg, $data = [])
 {
     $response = array(
         'code' => 1,
         'msg' => $msg,
-        'data' => ""
+        'data' => new \stdClass()
     );
+    if ($data) {
+        $response['data'] = $data;
+    }
     return $response;
 }
 
 function subtext($text, $length)
 {
+    $text = strip_tags($text);
     if (mb_strlen($text, 'utf8') > $length) {
         return mb_substr($text, 0, $length - 1, 'utf8') . '...';
     } else {

+ 447 - 0
app/Http/Controllers/V1/CircleController.php

@@ -0,0 +1,447 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/14
+ * Time: 16:23
+ */
+
+namespace App\Http\Controllers\V1;
+
+use App\Repositories\Circle\CircleArticleRepository;
+use App\Repositories\Circle\CircleMemberRepository;
+use App\Repositories\Circle\CircleMessageRepository;
+use App\Repositories\Circle\CircleRepository;
+use App\Traits\UserTrait;
+use App\Transformers\Circle\ArticleListTransformer;
+use App\Transformers\Circle\CircleMemberTransformer;
+use App\Transformers\Circle\CommentTransformer;
+use App\Transformers\Circle\DetailTransformer;
+use App\Transformers\Circle\MessageListTransformer;
+use App\Transformers\Circle\PictureListTransformer;
+use App\Transformers\Circle\QuestionTransformer;
+use App\Transformers\Circle\ReplyTransformer;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Redis;
+use Illuminate\Support\Facades\Validator;
+use Illuminate\Validation\Rule;
+use League\Fractal\Manager;
+use League\Fractal\Pagination\IlluminatePaginatorAdapter;
+use League\Fractal\Resource\Collection;
+use League\Fractal\Resource\Item;
+
+class CircleController extends Controller
+{
+    use UserTrait;
+
+    public function __construct(CircleRepository $circleRepository,
+                                CircleArticleRepository $circleArticleRepository,
+                                CircleMessageRepository $circleMessageRepository,
+                                CircleMemberRepository $circleMemberRepository)
+    {
+        $this->circleRepository = $circleRepository;
+        $this->circleArticleRepository = $circleArticleRepository;
+        $this->circleMemberRepository = $circleMemberRepository;
+        $this->circleMessageRepository = $circleMessageRepository;
+    }
+
+    /**
+     * 圈子检测
+     * @param Request $request
+     * @return array
+     */
+    public function valid(Request $request)
+    {
+        $userInfo = $this->getUserInfo();
+        if ($userInfo) {
+            $uid = $userInfo['uid'];
+        } else {
+            $uid = 0;
+        }
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|exists:interest_circles'
+        ]);
+        if ($validator->fails()) {
+            return $this->jsonError($validator->errors()->first());
+        }
+        $request = $request->all();
+        $circleInfo = $this->circleRepository->detail($request);
+        if ($circleInfo && $circleInfo->is_open == 0) {
+            return $this->jsonError('当前圈子已关闭');
+        }
+        if ($uid) {
+            $row = $this->circleMemberRepository
+                ->where('circle_id', $request['id'])
+                ->where('uid', $uid)
+                ->where('is_black', 1)->exists();
+            if ($row) {
+                return $this->jsonError('您无法进入该聊天室');
+            }
+        }
+
+        return $this->jsonSuccess();
+    }
+
+    /**
+     * 圈子首页
+     * @param Request $request
+     */
+    public function index(Request $request)
+    {
+        $userInfo = $this->getUserInfo();
+        if ($userInfo) {
+            $uid = $userInfo['uid'];
+        } else {
+            $uid = 0;
+        }
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|exists:interest_circles'
+        ]);
+        if ($validator->fails()) {
+            return $this->jsonError($validator->errors()->first());
+        }
+        $detail = $this->circleRepository->detail($request->all());
+        if ($detail) {
+            $fractal = new Manager();
+            $res = new Item($detail, new DetailTransformer($uid));
+            $data = $fractal->createData($res)->toArray();
+        }
+        return $this->jsonSuccess($data);
+    }
+
+    /**
+     * 查询圈子问题
+     * @param Request $request
+     * @return array
+     */
+    public function getQuestion(Request $request)
+    {
+        $userInfo = $this->getUserInfo();
+        if ($userInfo) {
+            $uid = $userInfo['uid'];
+        } else {
+            $uid = 0;
+        }
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|exists:interest_circles'
+        ]);
+        if ($validator->fails()) {
+            return $this->jsonError($validator->errors()->first());
+        }
+        $detail = $this->circleRepository->detail($request->all());
+        if ($detail) {
+            $fractal = new Manager();
+            $res = new Item($detail, new QuestionTransformer($uid));
+            $data = $fractal->createData($res)->toArray();
+        }
+        return $this->jsonSuccess($data);
+    }
+
+    /**
+     * 加入圈子
+     * @param Request $request
+     * @return array
+     */
+    public function joinCircle(Request $request)
+    {
+        $userInfo = $this->getUserInfo();
+        if (empty($userInfo)) {
+            return $this->jsonError('获取用户信息失败');
+        }
+//        else{
+//            $userInfo['uid'] = 268;
+//        }
+
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|exists:interest_circles'
+        ]);
+        if ($validator->fails()) {
+            return $this->jsonError($validator->errors()->first());
+        }
+        return $this->circleRepository->joinCircle($request->all(), $userInfo);
+    }
+
+    /**
+     * 退出圈子
+     * @param Request $request
+     * @return array
+     */
+    public function exitCircle(Request $request)
+    {
+        $userInfo = $this->getUserInfo();
+        if (empty($userInfo)) {
+            return $this->jsonError('获取用户信息失败');
+        }
+//        else{
+//            $userInfo['uid'] = 268;
+//        }
+
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|exists:interest_circles'
+        ]);
+        if ($validator->fails()) {
+            return $this->jsonError($validator->errors()->first());
+        }
+        return $this->circleRepository->exitCircle($request->all(), $userInfo);
+    }
+
+    /**
+     * 精华列表
+     * @param Request $request
+     * @return array
+     */
+    public function articleList(Request $request)
+    {
+        $userInfo = $this->getUserInfo();
+        if ($userInfo) {
+            $uid = $userInfo['uid'];
+            $inviteCode = $userInfo['invite_code'];
+        } else {
+            $uid = 0;
+            $inviteCode = '';
+        }
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|exists:interest_circles'
+        ]);
+        if ($validator->fails()) {
+            return $this->jsonError($validator->errors()->first());
+        }
+        $list = $this->circleArticleRepository->lists($request->all());
+        $fractal = new Manager();
+        $resource = new Collection($list, new ArticleListTransformer($uid, $inviteCode));
+        $resource->setPaginator(new IlluminatePaginatorAdapter($list));
+        $data = $fractal->createData($resource)->toArray();
+
+        return jsonSuccess($data);
+    }
+
+    /**
+     * 圈子成员列表
+     * @param Request $request
+     * @return array
+     */
+    public function memberList(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|exists:interest_circles'
+        ]);
+        if ($validator->fails()) {
+            return $this->jsonError($validator->errors()->first());
+        }
+        $list = $this->circleMemberRepository->lists($request->all());
+        $fractal = new Manager();
+        $resource = new Collection($list, new CircleMemberTransformer());
+        $resource->setPaginator(new IlluminatePaginatorAdapter($list));
+        $data = $fractal->createData($resource)->toArray();
+
+        return jsonSuccess($data);
+    }
+
+    /**
+     * 提问列表
+     * @param Request $request
+     * @return array
+     */
+    public function messageList(Request $request)
+    {
+        $userInfo = $this->getUserInfo();
+        if ($userInfo) {
+            $uid = $userInfo['uid'];
+        } else {
+            $uid = 0;
+        }
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|exists:interest_circles'
+        ]);
+        if ($validator->fails()) {
+            return $this->jsonError($validator->errors()->first());
+        }
+        $list = $this->circleMessageRepository->lists($request->all());
+        $fractal = new Manager();
+        $resource = new Collection($list, new MessageListTransformer($uid));
+        $resource->setPaginator(new IlluminatePaginatorAdapter($list));
+        $data = $fractal->createData($resource)->toArray();
+
+        return jsonSuccess($data);
+    }
+
+    /**
+     * 发布提问
+     */
+    public function messageCreate(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'circle_id' => 'required|integer',
+            'content' => 'required|string|max:150',
+        ]);
+        if ($validator->fails()) {
+            return jsonError($validator->errors()->first());
+        }
+        return $this->circleMessageRepository->create($request->all());
+    }
+
+    /**
+     * 评论&回复
+     */
+    public function comment(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'circle_id' => 'required|integer',
+            'msg_id' => 'required|integer',
+            'content' => 'required|string|max:150',
+        ]);
+        if ($validator->fails()) {
+            return jsonError($validator->errors()->first());
+        }
+        return $this->circleMessageRepository->createComment($request->all());
+    }
+
+    /**
+     * 评论列表
+     */
+    public function commentList(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'msg_id' => 'required|integer',
+        ]);
+        if ($validator->fails()) {
+            return jsonError($validator->errors()->first());
+        }
+        $exists = $this->circleMessageRepository->detail($request['msg_id']);
+        if (!$exists) {
+            return jsonError('内容飞走了');
+        }
+        $userInfo = $this->getUserInfo();
+        if ($userInfo) {
+            $uid = $userInfo['uid'];
+        }else{
+            $uid = 0;
+        }
+        $list = $this->circleMessageRepository->commentList($request->all());
+        $fractal = new Manager();
+        $resource = new Collection($list, new CommentTransformer($request['msg_id'], $uid));
+        $resource->setPaginator(new IlluminatePaginatorAdapter($list));
+        $data = $fractal->createData($resource)->toArray();
+
+        $commentCount = $this->circleMessageRepository->getCommentCount($request['msg_id']);
+        return jsonSuccess($data, '成功', ['comment_count' => $commentCount]);
+    }
+
+    /**
+     * 回复列表
+     */
+    public function replyList(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'comment_id' => 'required|integer',
+        ]);
+        if ($validator->fails()) {
+            return jsonError($validator->errors()->first());
+        }
+        $list = $this->circleMessageRepository->replyList($request->all());
+        $fractal = new Manager();
+        $resource = new Collection($list, new ReplyTransformer());
+        $resource->setPaginator(new IlluminatePaginatorAdapter($list));
+        $data = $fractal->createData($resource)->toArray();
+
+        return jsonSuccess($data);
+    }
+
+    /**
+     * 圈子顶踩
+     * @param Request $request
+     * @return array
+     */
+    public function messageAction(Request $request){
+        $validator = Validator::make($request->all(), [
+            'msg_id' => 'required|integer',
+            'action' => ['required',Rule::in([1,-1])],
+        ]);
+        if ($validator->fails()) {
+            return jsonError($validator->errors()->first());
+        }
+        return $this->circleMessageRepository->messageAction($request);
+    }
+
+
+    /**
+     * 删除提问
+     */
+    public function deleteMessage(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|integer',
+        ]);
+        if ($validator->fails()) {
+            return jsonError($validator->errors()->first());
+        }
+        return $this->circleMessageRepository->deleteMessage($request->all());
+    }
+
+    /**
+     * 删除评论
+     */
+    public function deleteComment(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|integer',
+        ]);
+        if ($validator->fails()) {
+            return jsonError($validator->errors()->first());
+        }
+        return  $this->circleMessageRepository->commentDelete($request->all());
+    }
+
+    /**
+     * 上传相册
+     */
+    public function createPictures(Request $request)
+    {
+        $validator = Validator::make($request->all(), [
+            'circle_id' => 'required|integer',
+            'imgs' => 'required|string',
+        ]);
+        if ($validator->fails()) {
+            return jsonError($validator->errors()->first());
+        }
+        return $this->circleMessageRepository->createPictures($request->all());
+    }
+
+    /**
+     * 相册列表
+     * @param Request $request
+     * @return array
+     */
+    public function pictureList(Request $request){
+        $validator = Validator::make($request->all(), [
+            'circle_id' => 'required|integer',
+        ]);
+        if ($validator->fails()) {
+            return jsonError($validator->errors()->first());
+        }
+        $list = $this->circleMessageRepository->pictureLists($request->all());
+        $fractal = new Manager();
+        $resource = new Collection($list, new PictureListTransformer());
+        $resource->setPaginator(new IlluminatePaginatorAdapter($list));
+        $data = $fractal->createData($resource)->toArray();
+
+        return jsonSuccess($data);
+    }
+
+    /**
+     * 删除相册
+     * @param Request $request
+     * @return array
+     */
+    public function deletePicture(Request $request){
+        $validator = Validator::make($request->all(), [
+            'id' => 'required|string',
+        ]);
+        if ($validator->fails()) {
+            return jsonError($validator->errors()->first());
+        }
+        return $this->circleMessageRepository->deletePicture($request->all());
+    }
+
+}

+ 5 - 2
app/Http/Controllers/V1/Controller.php

@@ -43,13 +43,16 @@ class Controller extends BaseController
         return $response;
     }
 
-    public function jsonError($msg)
+    public function jsonError($msg,$data=[])
     {
         $response = array(
             'code' => 1,
             'msg' => $msg,
-            'data' => ""
+            'data' => new \stdClass()
         );
+        if($data){
+            $response['data'] = $data;
+        }
         return $response;
     }
 }

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

@@ -59,6 +59,8 @@ class PostController extends Controller
             'title' => 'nullable|string|max:20',
             'content' => 'required|string|max:1000',
             'location' => 'nullable|string|max:32',
+            'lat' => 'nullable|numeric',
+            'lng' => 'nullable|numeric',
             'imgs' => 'required_if:type,image|string',
         ]);
         if ($validator->fails()) {

+ 24 - 0
app/Models/InterestCircle.php

@@ -0,0 +1,24 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/5
+ * Time: 16:24
+ */
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+class InterestCircle extends Model
+{
+    //
+    use SoftDeletes;
+    protected $table = 'interest_circles';
+    protected $guarded = [];
+
+    public function imgs()
+    {
+        return $this->hasMany('App\Models\InterestCircleMessageImg', 'msg_id', 'id');
+    }
+}

+ 19 - 0
app/Models/InterestCircleArticle.php

@@ -0,0 +1,19 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/5
+ * Time: 16:24
+ */
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+class InterestCircleArticle extends Model
+{
+    //
+    protected $table = 'interest_circle_articles';
+    protected $guarded = [];
+
+}

+ 25 - 0
app/Models/InterestCircleMessage.php

@@ -0,0 +1,25 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/5
+ * Time: 16:24
+ */
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+class InterestCircleMessage extends Model
+{
+    //
+    use SoftDeletes;
+    protected $table = 'interest_circle_messages';
+    protected $guarded = [];
+
+    public function imgs()
+    {
+        return $this->hasMany('App\Models\InterestCircleMessageImg', 'msg_id', 'id');
+    }
+
+}

+ 17 - 0
app/Models/InterestCircleMessageComment.php

@@ -0,0 +1,17 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/6
+ * Time: 11:21
+ */
+
+namespace App\Models;
+use Illuminate\Database\Eloquent\Model;
+
+class InterestCircleMessageComment extends Model
+{
+//
+    protected $table = 'interest_circle_message_comments';
+    protected $guarded = [];
+}

+ 20 - 0
app/Models/InterestCircleMessageImg.php

@@ -0,0 +1,20 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/5
+ * Time: 16:24
+ */
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+class InterestCircleMessageImg extends Model
+{
+    //
+    protected $table = 'interest_circle_message_imgs';
+    protected $guarded = [];
+
+
+}

+ 17 - 0
app/Models/InterestCircleMessageRecord.php

@@ -0,0 +1,17 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/6
+ * Time: 11:21
+ */
+
+namespace App\Models;
+use Illuminate\Database\Eloquent\Model;
+
+class InterestCircleMessageRecord extends Model
+{
+//
+    protected $table = 'interest_circle_message_records';
+    protected $guarded = [];
+}

+ 20 - 0
app/Models/InterestCirclePicture.php

@@ -0,0 +1,20 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/5
+ * Time: 16:24
+ */
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+class InterestCirclePicture extends Model
+{
+    //
+    use SoftDeletes;
+    protected $table = 'interest_circle_pictures';
+    protected $guarded = [];
+
+}

+ 19 - 0
app/Models/InterestCircleUser.php

@@ -0,0 +1,19 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/5
+ * Time: 16:24
+ */
+namespace App\Models;
+
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+class InterestCircleUser extends Model
+{
+    //
+    protected $table = 'interest_circle_users';
+    protected $guarded = [];
+
+}

+ 47 - 13
app/Repositories/BeanRepository.php

@@ -3,6 +3,7 @@
 namespace App\Repositories;
 
 use App\Models\Post;
+use App\Repositories\Circle\CircleRepository;
 use App\Traits\PostTrait;
 use App\Traits\UserTrait;
 use Illuminate\Support\Carbon;
@@ -16,6 +17,11 @@ class BeanRepository
     use PostTrait;
     use UserTrait;
 
+    public function __construct(CircleRepository $circleRepository)
+    {
+        $this->circleRepository = $circleRepository;
+    }
+
     public function beanDetail($request)
     {
         try {
@@ -222,23 +228,38 @@ class BeanRepository
 //        $star_home['battle']['end'] = $activityInfo['end'];
 //        $star_home['battle']['news'] = Redis::get('battle_latest_info_'.$activityInfo['id'])??'战场四平八稳,劳驾老板亲自去战场督战';
 
+        $circleList = $this->circleRepository->circleLists(['is_recommend' => 1]);
+        $circles = [];
+        foreach ($circleList as $circle) {
+            $temp = [];
+            $temp['circle_id'] = $circle['id'];
+            $temp['image'] = $circle['image'];
+            $temp['join_count'] = $circle['join_count'];
+            $temp['circle_name'] = mb_substr($circle['name'], 0, 6);
+            $circles[] = $temp;
+        }
+        $star_home['circles'] = $circles;
         //聊天室
         $tmpChatroom = Redis::get('user_service_chatroom');
-        $chatrooms = $tmpChatroom?json_decode($tmpChatroom,true):[];
+        $chatrooms = $tmpChatroom ? json_decode($tmpChatroom, true) : [];
         $current = Carbon::now()->format('H:i:s');
         $chatRoomsData1 = [];
         $chatRoomsData0 = [];
         foreach ($chatrooms as &$chatroom) {
-            if ($chatroom['start']<$chatroom['end']) {
-                if ($current<$chatroom['start'] || $current>$chatroom['end']) {
+            //没有推荐的则不显示
+            if ($chatroom['is_recommend'] == 0) {
+                continue;
+            }
+            if ($chatroom['start'] < $chatroom['end']) {
+                if ($current < $chatroom['start'] || $current > $chatroom['end']) {
                     $chatroom['is_open'] = 0;
                     $chatRoomsData0[] = $chatroom;
                 } else {
                     $chatroom['is_open'] = 1;
                     $chatRoomsData1[] = $chatroom;
                 }
-            } elseif ($chatroom['start']>$chatroom['end']) {
-                if ($current>$chatroom['end'] && $current<$chatroom['start']) {
+            } elseif ($chatroom['start'] > $chatroom['end']) {
+                if ($current > $chatroom['end'] && $current < $chatroom['start']) {
                     $chatroom['is_open'] = 0;
                     $chatRoomsData0[] = $chatroom;
                 } else {
@@ -372,7 +393,7 @@ class BeanRepository
             $star_detail['invite']['bean'] = config("customer.share_post_bean") ?? 0;
         } else {
             Log::debug($request['invite_code']);
-            return jsonError('邀请码有误');
+            //return jsonError('邀请码有误');
         }
 
         $star_detail['mybean']['user_count'] = intval($user_bean['user_count']) ?? 0;//已入驻老板
@@ -381,8 +402,17 @@ class BeanRepository
 
         $star_detail['daily_news'] = $this->getNews($request);
         $star_detail['exchange'] = $exchange;
-
-
+        $circleList = $this->circleRepository->circleLists(['is_recommend' => 1]);
+        $circles = [];
+        foreach ($circleList as $circle) {
+            $temp = [];
+            $temp['circle_id'] = $circle['id'];
+            $temp['image'] = $circle['image'];
+            $temp['join_count'] = $circle['join_count'];
+            $temp['circle_name'] = mb_substr($circle['name'], 0, 6);
+            $circles[] = $temp;
+        }
+        $star_detail['circles'] = $circles;
 
         return $star_detail;
 
@@ -422,21 +452,25 @@ class BeanRepository
 
         //聊天室
         $tmpChatroom = Redis::get('user_service_chatroom');
-        $chatrooms = $tmpChatroom?json_decode($tmpChatroom,true):[];
+        $chatrooms = $tmpChatroom ? json_decode($tmpChatroom, true) : [];
         $current = Carbon::now()->format('H:i:s');
         $chatRoomsData1 = [];
         $chatRoomsData0 = [];
         foreach ($chatrooms as &$chatroom) {
-            if ($chatroom['start']<$chatroom['end']) {
-                if ($current<$chatroom['start'] || $current>$chatroom['end']) {
+            //没有推荐的则不显示
+            if ($chatroom['is_recommend'] == 0) {
+                continue;
+            }
+            if ($chatroom['start'] < $chatroom['end']) {
+                if ($current < $chatroom['start'] || $current > $chatroom['end']) {
                     $chatroom['is_open'] = 0;
                     $chatRoomsData0[] = $chatroom;
                 } else {
                     $chatroom['is_open'] = 1;
                     $chatRoomsData1[] = $chatroom;
                 }
-            } elseif ($chatroom['start']>$chatroom['end']) {
-                if ($current>$chatroom['end'] && $current<$chatroom['start']) {
+            } elseif ($chatroom['start'] > $chatroom['end']) {
+                if ($current > $chatroom['end'] && $current < $chatroom['start']) {
                     $chatroom['is_open'] = 0;
                     $chatRoomsData0[] = $chatroom;
                 } else {

+ 53 - 0
app/Repositories/Circle/CircleArticleRepository.php

@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/5
+ * Time: 16:03
+ */
+
+namespace App\Repositories\Circle;
+
+use App\Models\InterestCircle;
+use App\Models\InterestCircleArticle;
+use App\Models\InterestCircleUser;
+use App\Models\Post;
+use Illuminate\Database\QueryException;
+use Dingo\Api\Http\Response;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Redis;
+
+class CircleArticleRepository
+{
+
+    public function __construct(InterestCircle $interestCircle,
+                                InterestCircleArticle $interestCircleArticle,
+                                Post $post)
+    {
+        $this->interestCircle = $interestCircle;
+        $this->interestCircleArticle = $interestCircleArticle;
+        $this->post = $post;
+    }
+
+    /**
+     * 内容列表
+     */
+    public function lists($request)
+    {
+        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;
+
+        $where[] = ['interest_circle_articles.circle_id', $request['id']];
+
+        $articleModel = $this->post;
+        return $articleModel
+            ->join('interest_circle_articles', 'interest_circle_articles.post_id', '=', 'post.id')
+            ->select('post.*', 'interest_circle_articles.is_recommend', 'interest_circle_articles.circle_id')
+            ->where($where)
+            ->orderBy('interest_circle_articles.is_recommend', 'desc')
+            ->orderBy('post.weight', 'desc')
+            ->paginate($perPage);
+    }
+}

+ 51 - 0
app/Repositories/Circle/CircleMemberRepository.php

@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/5
+ * Time: 16:03
+ */
+
+namespace App\Repositories\Circle;
+
+use App\Models\InterestCircle;
+use App\Models\InterestCircleArticle;
+use App\Models\InterestCircleUser;
+use App\Models\Post;
+use Illuminate\Database\QueryException;
+use Dingo\Api\Http\Response;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Redis;
+
+class CircleMemberRepository
+{
+
+    public function __construct(InterestCircle $interestCircle,
+                                InterestCircleUser $interestCircleUser
+    )
+    {
+        $this->interestCircle = $interestCircle;
+        $this->interestCircleUser = $interestCircleUser;
+    }
+
+    /**
+     * 成员列表
+     */
+    public function lists($request)
+    {
+        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;
+
+        //$where[] = ['is_black', 0];
+
+        $where[] = ['circle_id', $request['id']];
+
+        $userModel = $this->interestCircleUser;
+        return $userModel
+            ->where($where)
+            ->orderBy('id', 'desc')
+            ->paginate($perPage);
+    }
+}

+ 602 - 0
app/Repositories/Circle/CircleMessageRepository.php

@@ -0,0 +1,602 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/5
+ * Time: 16:03
+ */
+
+namespace App\Repositories\Circle;
+
+use App\Models\InterestCircle;
+use App\Models\InterestCircleArticle;
+use App\Models\InterestCircleMessage;
+use App\Models\InterestCircleMessageComment;
+use App\Models\InterestCircleMessageImg;
+use App\Models\InterestCircleMessageRecord;
+use App\Models\InterestCirclePicture;
+use App\Models\InterestCircleUser;
+use App\Models\Post;
+use App\Service\DetectionService;
+use App\Traits\UserTrait;
+use Illuminate\Database\QueryException;
+use Dingo\Api\Http\Response;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Redis;
+use Illuminate\Support\Str;
+
+class CircleMessageRepository
+{
+    use UserTrait;
+
+    public function __construct(InterestCircle $interestCircle,
+                                InterestCircleMessage $interestCircleMessage,
+                                InterestCirclePicture $interestCirclePicture,
+                                InterestCircleMessageImg $interestCircleMessageImg,
+                                InterestCircleUser $interestCircleUser,
+                                DetectionService $detectionService,
+                                InterestCircleMessageComment $interestCircleMessageComment
+    )
+    {
+        $this->interestCircle = $interestCircle;
+        $this->interestCircleMessage = $interestCircleMessage;
+        $this->interestCirclePicture = $interestCirclePicture;
+        $this->interestCircleMessageImg = $interestCircleMessageImg;
+        $this->interestCircleUser = $interestCircleUser;
+        $this->interestCircleMessageComment = $interestCircleMessageComment;
+        $this->detectionService = $detectionService;
+    }
+
+    /**
+     * 查询单个提问
+     * @param $id
+     * @return mixed
+     */
+    public function detail($id)
+    {
+        return $this->interestCircleMessage->find($id);
+    }
+
+    /**
+     * 提问列表
+     */
+    public function lists($request)
+    {
+        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;
+
+        $where[] = ['circle_id', $request['id']];
+
+        return $this->interestCircleMessage
+            ->where($where)
+            ->with('imgs')
+            ->orderBy('is_recommend', 'desc')
+            ->orderBy('id', 'desc')
+            ->paginate($perPage);
+    }
+
+    /**
+     * 发布提问
+     */
+    public function create($request)
+    {
+        //验证小号
+        $userInfo = $this->getUserInfo();
+//        $userInfo['sns_status']=1;
+//        $userInfo['uid']=268;
+        if (empty($userInfo)) {
+            return jsonError('获取用户信息失败');
+        }
+        if (!$userInfo['sns_status']) {
+            return jsonError('您已被禁言');
+        }
+        $circleUser = $this->interestCircleUser
+            ->where('circle_id', $request['circle_id'])
+            ->where('uid', $userInfo['uid'])
+            ->first();
+        if ($circleUser) {
+            if ($circleUser->is_black) {
+                return jsonError('您在本圈子内的权限受限');
+            }
+        } else {
+            return jsonError('抱歉,加入圈子才能互动');
+        }
+
+        $oneHourTime = Carbon::now()->addHours(-1)->toDateTimeString();
+        $oneHourPostCount = $this->interestCircleMessage->where('uid', $userInfo['uid'])->where('created_at', '>', $oneHourTime)->count();
+        if ($oneHourPostCount > 50) {
+            return jsonError('创作欲望太强啦,休息一下,看看其他用户的提问吧!');
+        }
+
+        $detectionText = strip_tags($request['content']);
+        $detectionTextResult = $this->detectionService->checkText($detectionText);
+        if ($detectionTextResult['code'] < 0) {
+            return jsonError('内容违规,请修正哦');
+        }
+        $imgs = [];
+        if (isset($request['imgs']) && $request['imgs']) {
+            $imgs = json_decode($request['imgs'], true);
+            $imgCount = count($imgs);
+            if ($imgCount > 3) {
+                return jsonError('最多上传3张');
+            }
+        }
+        if ($imgs) {
+            $allImg = $imgs;
+            foreach ($allImg as &$img) {
+                if (Str::contains($img, '?')) {
+                    $img = $img . '&x-oss-process=image/resize,p_50/quality,Q_50';
+                } else {
+                    $img = $img . '?x-oss-process=image/resize,p_50/quality,Q_50';
+                }
+
+            }
+            $detectionImageResult = $this->detectionService->checkImg($allImg);
+            if ($detectionImageResult['code'] < 0) {
+                Log::debug('图片违规,请修正哦' . json_encode($detectionImageResult));
+                return jsonError('图片违规,请修正哦');
+            }
+        }
+
+        $fresh = (Carbon::now()->timestamp) - (Carbon::parse("2019-10-08 00:00:00")->timestamp);
+        $score = ($fresh / 43200) * 14;
+        $data = [
+            'circle_id' => $request['circle_id'],
+            'uid' => $userInfo['uid'],
+            'content' => $request['content'],
+            'good' => 0,
+            'bad' => 0,
+            'comment_count' => 0,
+            'weight' => $score
+        ];
+        $date = date('Y-m-d H:i:s');
+        DB::beginTransaction();
+        try {
+            $message = $this->interestCircleMessage->create($data);
+            if ($imgs) {
+                $imgData = [];
+                foreach ($imgs as $img) {
+                    $imgData[] = [
+                        'msg_id' => $message->id,
+                        'circle_id' => $message->circle_id,
+                        'image' => $img,
+                        'created_at' => $date,
+                        'updated_at' => $date
+                    ];
+                }
+                $this->interestCircleMessageImg->insert($imgData);
+            }
+            $this->interestCircle->where('id', $request['circle_id'])->increment('message_count');
+            DB::commit();
+            Log::info('message_create:' . $message->id . ',post_author:' . $message->uid . ',author_ip:' . getClientIp());
+            return jsonSuccess();
+        } catch (QueryException $exception) {
+            DB::rollBack();
+            Log::debug('发布提问失败:' . $exception->getMessage());
+            return jsonError('发布提问失败,请重试');
+        }
+    }
+
+    /**
+     * 评论&回复
+     * @param $request
+     * @return array
+     */
+    public function createComment($request)
+    {
+        Log::debug('comment-request:'.json_encode($request));
+        $userInfo = $this->getUserInfo();
+//        $userInfo['sns_status']=1;
+//        $userInfo['uid']=268;
+//        $userInfo['username']='测试用户';
+//        $userInfo['avatar']='';
+        if (empty($userInfo)) {
+            return jsonError('获取用户信息失败');
+        }
+
+        if (!$userInfo['sns_status']) {
+            return jsonError('您已被禁言');
+        }
+        $circleUser = $this->interestCircleUser
+            ->where('circle_id', $request['circle_id'])
+            ->where('uid', $userInfo['uid'])
+            ->first();
+        if ($circleUser) {
+            if ($circleUser->is_black) {
+                return jsonError('您在本圈子内的权限受限');
+            }
+        } else {
+            return jsonError('抱歉,加入圈子才能互动');
+        }
+        $oneHourTime = Carbon::now()->addHours(-1)->toDateTimeString();
+        $oneHourCommentCount = $this->interestCircleMessageComment->where('uid', $userInfo['uid'])->where('created_at', '>', $oneHourTime)->count();
+        if ($oneHourCommentCount > 59) {
+            return jsonError('回复了这么多,休息休息,喝口水吧!');
+        }
+
+        $detectionTextResult = $this->detectionService->checkText($request['content']);
+        if ($detectionTextResult['code'] < 0) {
+            return jsonError('内容违规,请修正哦');
+        }
+
+        $post = $this->interestCircleMessage->find($request['msg_id']);
+        if (!$post) {
+            return jsonError('获取提问信息失败');
+        }
+        $data = [
+            'uid' => $userInfo['uid'],
+            'circle_id' => $request['circle_id'],
+            'msg_id' => $request['msg_id'],
+            'parent_id' => 0,
+            'username' => $userInfo['username'],
+            'reply_uid' => 0,
+            'reply_username' => '',
+            'avatar' => $userInfo['avatar'] ?? '',
+            'content' => $request['content'],
+            'is_delete' => 0,
+        ];
+        if (isset($request['parent_id']) && $request['parent_id'] != 0) {
+            $comment = $this->interestCircleMessageComment->find($request['parent_id']);
+            if (!$comment || $comment->msg_id != $post->id) {
+                return jsonError('获取评论信息失败');
+            }
+            if ($comment->parent_id) {
+                return jsonError('只能回复评论');
+            }
+            if ($comment->is_delete) {
+                return jsonError('不能回复已删除评论');
+            }
+            $data['parent_id'] = $request['parent_id'];
+
+            if (isset($request['reply_uid']) && isset($request['reply_username'])) {
+                $data['reply_uid'] = $request['reply_uid'];
+                $data['reply_username'] = $request['reply_username'];
+            } else {
+                $data['reply_uid'] = 0;
+                $data['reply_username'] = '';
+            }
+        }
+
+        DB::beginTransaction();
+        try {
+            $newComment = $this->interestCircleMessageComment->create($data);
+
+            if ($newComment->parent_id) {
+                $this->interestCircleMessageComment->where('id', $newComment->parent_id)->increment('reply_count');
+            }
+            $this->interestCircleMessage->where('id', $request['msg_id'])->increment('comment_count');
+            DB::commit();
+            if ($newComment->parent_id) {
+                Redis::DEL('circle_message_new_reply_' . $newComment->parent_id);
+                Log::debug('删除回复缓存'.$newComment->id);
+            } else {
+                Redis::DEL('circle_message_new_comment_' . $newComment->msg_id);
+                Log::debug('删除评论缓存'.$newComment->msg_id);
+            }
+            $key = "community_calc_circle_score";
+            Redis::sadd($key,$request['msg_id']);
+            return jsonSuccess(['id' => $newComment->id], '评论成功');
+
+        } catch (QueryException $exception) {
+            DB::rollBack();
+            Log::debug('评论内容失败:' . $exception->getMessage());
+            return jsonError('评论内容失败,请重试');
+        }
+    }
+
+    /**
+     * 评论列表
+     */
+    public function commentList($request)
+    {
+        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;
+
+        return $this->interestCircleMessageComment
+            ->where('msg_id', $request['msg_id'])
+            ->where('parent_id', 0)
+            ->orderBy('id', 'desc')
+            ->paginate($perPage);
+    }
+
+    /**
+     * 提问评论数
+     */
+    public function getCommentCount($id)
+    {
+        $commentCount = 0;
+        $post = $this->interestCircleMessage->find($id);
+        if ($post) {
+            $commentCount = $this->interestCircleMessageComment->where('msg_id', $id)->count();
+        }
+        return $commentCount;
+    }
+
+    /**
+     * 回复列表
+     */
+    public function replyList($request)
+    {
+        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;
+
+        return $this->interestCircleMessageComment
+            ->where('parent_id', $request['comment_id'])
+            ->orderBy('id', 'desc')
+            ->paginate($perPage);
+    }
+
+    /**
+     * 提问顶踩
+     * @param $request
+     * @return array
+     */
+    public function messageAction($request)
+    {
+        $userInfo = $this->getUserInfo();
+//        $userInfo['sns_status'] = 1;
+//        $userInfo['uid'] = 268;
+//        $userInfo['username'] = '测试用户';
+//        $userInfo['avatar'] = '';
+        if (empty($userInfo)) {
+            return jsonError('获取用户信息失败');
+        }
+        $messageInfo = $this->interestCircleMessage->find($request['msg_id']);
+        if (empty($messageInfo)) {
+            return jsonError('该提问不存在');
+        }
+        $circleUser = $this->interestCircleUser
+            ->where('circle_id', $messageInfo->circle_id)
+            ->where('uid', $userInfo['uid'])
+            ->first();
+        if ($circleUser) {
+            if ($circleUser->is_black) {
+                return jsonError('您在本圈子内的权限受限');
+            }
+        } else {
+            return jsonError('抱歉,加入圈子才能互动');
+        }
+        $actionRow = InterestCircleMessageRecord::where([['msg_id', $request['msg_id']], ['uid', $userInfo['uid']]])->first();
+        if ($actionRow) {
+            return jsonSuccess();
+        }
+        DB::beginTransaction();
+        try {
+            $data['msg_id'] = $request['msg_id'];
+            $data['uid'] = $userInfo['uid'];
+            $data['action'] = $request['action'];
+
+            InterestCircleMessageRecord::insert($data);
+            if ($request['action'] == 1) {
+                InterestCircleMessage::where('id', $request['msg_id'])->increment('good');
+            } elseif ($request['action'] == -1) {
+                InterestCircleMessage::where('id', $request['msg_id'])->increment('bad');
+            }
+
+            DB::commit();
+            $key = "community_calc_circle_score";
+            Redis::sadd($key,$request['msg_id']);
+            return jsonSuccess();
+        } catch (QueryException $exception) {
+            DB::rollBack();
+            Log::debug('顶踩提问失败:' . $exception->getMessage());
+            return jsonError('操作失败,请重试');
+        }
+    }
+
+    /**
+     * 删除评论
+     */
+    public function commentDelete($request)
+    {
+        $userInfo = $this->getUserInfo();
+        if (empty($userInfo)) {
+            return jsonError('获取用户信息失败');
+        }
+        $comment = $this->interestCircleMessageComment->find($request['id']);
+        if (!$comment) {
+            return jsonError('获取评论信息失败');
+        }
+
+        if ($userInfo['uid'] != $comment->uid) {
+            return jsonError('只能删除自己的评论');
+        }
+
+        if ($comment->is_delete == 1) {
+            return jsonError('该评论已经删除');
+        }
+
+        DB::beginTransaction();
+        try {
+            $comment->is_delete = 1;
+            $comment->save();
+
+            DB::commit();
+            if (!$comment->parent_id) {
+                Redis::DEL('circle_message_new_comment_' . $comment->msg_id);
+            } else {
+                Redis::DEL('circle_message_new_reply_' . $comment->id);
+            }
+            Redis::SADD('delete_circle_message_comment_ids', $comment->id);
+            return jsonSuccess();
+
+        } catch (QueryException $exception) {
+            DB::rollBack();
+            Log::debug('删除评论:' . $request['id'] . $exception->getMessage());
+            return jsonError('删除评论失败');
+        }
+    }
+
+    /**
+     * 删除提问
+     */
+    public function deleteMessage($request)
+    {
+        //验证用户信息
+        $userInfo = $this->getUserInfo();
+        if (empty($userInfo)) {
+            return jsonError('获取用户信息失败');
+        }
+
+        $post = $this->interestCircleMessage->find($request['id']);
+        if (!$post) {
+            return jsonError('获取提问信息失败');
+        }
+        if ($post->uid != $userInfo['uid']) {
+            return jsonError('只能删除自己发布的提问');
+        }
+
+        DB::beginTransaction();
+        try {
+            $post->delete();
+            $this->interestCircle->where('id', $post->circle_id)->decrement('message_count');
+            DB::commit();
+            Redis::SADD('delete_circle_message_ids', $request['id']);
+            Log::debug('删除提问成功:' . $request['id']);
+            return jsonSuccess();
+
+        } catch (QueryException $exception) {
+            DB::rollBack();
+            Log::debug('删除提问失败:' . $request['id'] . $exception->getMessage());
+            return jsonError('删除提问失败,请重试');
+        }
+    }
+
+    /**
+     * 创建相册
+     */
+    public function createPictures($request)
+    {
+        //验证小号
+        $userInfo = $this->getUserInfo();
+//        $userInfo['sns_status']=1;
+//        $userInfo['uid']=268;
+        if (empty($userInfo)) {
+            return jsonError('获取用户信息失败');
+        }
+        if (!$userInfo['sns_status']) {
+            return jsonError('您已被禁言');
+        }
+        $circleUser = $this->interestCircleUser
+            ->where('circle_id', $request['circle_id'])
+            ->where('uid', $userInfo['uid'])
+            ->first();
+        if ($circleUser) {
+            if ($circleUser->is_black) {
+                return jsonError('您在本圈子内的权限受限');
+            }
+        } else {
+            return jsonError('抱歉,加入圈子才能互动');
+        }
+
+        $oneHourTime = Carbon::now()->addHours(-1)->toDateTimeString();
+        $oneHourPostCount = $this->interestCirclePicture
+            ->where('uid', $userInfo['uid'])
+            ->where('is_main', 1)
+            ->where('created_at', '>', $oneHourTime)
+            ->count();
+        if ($oneHourPostCount > 5) {
+            return jsonError('创作欲望太强啦,休息一下,看看其他用户的相册吧!');
+        }
+
+        $imgs = json_decode($request['imgs'], true);
+        $imgCount = count($imgs);
+        if ($imgCount == 0 || $imgCount > 9) {
+            return jsonError('所传图集必须1-9个');
+        }
+        $allImg = $imgs;
+        foreach ($allImg as &$img) {
+            if (Str::contains($img, '?')) {
+                $img = $img . '&x-oss-process=image/resize,p_50/quality,Q_50';
+            } else {
+                $img = $img . '?x-oss-process=image/resize,p_50/quality,Q_50';
+            }
+
+        }
+        $detectionImageResult = $this->detectionService->checkImg($allImg);
+        if ($detectionImageResult['code'] < 0) {
+            Log::debug('图片违规,请修正哦' . json_encode($detectionImageResult));
+            return jsonError('图片违规,请修正哦');
+        }
+
+        $date = date('Y-m-d H:i:s');
+        $patchNum = Str::random(32);
+        DB::beginTransaction();
+        try {
+            $imgData = [];
+            foreach ($imgs as $k => $img) {
+                $isMain = 0;
+                if ($k == 0) {
+                    $isMain = 1;
+                }
+                $imgData[] = [
+                    'circle_id' => $request['circle_id'],
+                    'uid' => $userInfo['uid'],
+                    'image' => $img,
+                    'patch_num' => $patchNum,
+                    'is_main' => $isMain,
+                    'created_at' => $date,
+                    'updated_at' => $date
+                ];
+            }
+            $this->interestCirclePicture->insert($imgData);
+            $this->interestCircle->where('id', $request['circle_id'])->increment('picture_count', $imgCount);
+            $key = 'circle_picture_' . $patchNum;
+            Redis::set($key, json_encode($imgs));
+            DB::commit();
+            return jsonSuccess();
+        } catch (QueryException $exception) {
+            DB::rollBack();
+            Log::debug('上传相册失败:' . $exception->getMessage());
+            return jsonError('上传失败');
+        }
+    }
+
+    /**
+     * 相册列表
+     */
+    public function pictureLists($request)
+    {
+        $perPage = isset($request['per_page']) ? $request['per_page'] : 20;
+        $where[] = ['circle_id', $request['circle_id']];
+        $where[] = ['is_main', 1];
+
+        return $this->interestCirclePicture
+            ->where($where)
+            ->orderBy('id', 'desc')
+            ->paginate($perPage);
+    }
+
+    /**
+     * 删除相册图片
+     */
+    public function deletePicture($request)
+    {
+        $circle = $this->interestCirclePicture->where('patch_num', $request['id'])->first();
+        if (!$circle) {
+            return jsonError('相册不存在');
+        }
+        $userInfo = $this->getUserInfo();
+//        $userInfo['sns_status']=1;
+//        $userInfo['uid']=268;
+        if (empty($userInfo)) {
+            return jsonError('获取用户信息失败');
+        }
+        if ($userInfo['uid'] != $circle->uid) {
+            return jsonError('只能删除自己的相册');
+        }
+        DB::beginTransaction();
+        try {
+            $picCount = $this->interestCirclePicture->where('patch_num', $request['id'])->count();
+            $this->interestCirclePicture->where('patch_num', $request['id'])->delete();
+            $this->interestCircle->where('circle_id', $circle->circle_id)->decrement('picture_count', $picCount);
+            DB::commit();
+            return jsonSuccess();
+
+        } catch (QueryException $exception) {
+            DB::rollBack();
+            Log::debug('删除相册图片:' . $request['id'] . $exception->getMessage());
+            return jsonError('操作失败,请重试');
+        }
+    }
+}

+ 204 - 0
app/Repositories/Circle/CircleRepository.php

@@ -0,0 +1,204 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/5
+ * Time: 16:03
+ */
+
+namespace App\Repositories\Circle;
+
+use App\Models\InterestCircle;
+use App\Models\InterestCircleUser;
+use Illuminate\Database\QueryException;
+use Dingo\Api\Http\Response;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Redis;
+
+class CircleRepository
+{
+
+    public function __construct(InterestCircle $interestCircle,
+                                InterestCircleUser $interestCircleUser)
+    {
+        $this->interestCircle = $interestCircle;
+        $this->interestCircleUser = $interestCircleUser;
+    }
+
+    /**
+     * 圈子列表
+     */
+    public function circleLists($request, $limit = 3)
+    {
+        $where[] = ['is_open', 1];
+        if (isset($request['is_recommend'])) {
+            $where[] = ['is_recommend', 1];
+        }
+
+        return $this->interestCircle
+            ->where($where)
+            ->orderBy('id', 'desc')
+            ->take($limit)
+            ->get();
+    }
+
+    /**
+     * 圈子详情
+     */
+    public function detail($request, $isTrashed = false)
+    {
+        $model = $this->interestCircle;
+        if ($isTrashed) {
+            $model->withTrashed();
+        }
+        $this->interestCircle->where('id', $request['id'])->increment('view_count');
+        return $model->find($request['id']);
+    }
+
+    /**
+     * 加入圈子
+     * @param $request
+     * @param $userInfo
+     * @return array
+     */
+    public function joinCircle($request, $userInfo)
+    {
+        $row = $this->interestCircleUser
+            ->where('uid', $userInfo['uid'])
+            ->where('circle_id', $request['id'])
+            ->first();
+        if ($row) {
+            return jsonError('您已经加入该圈子了', ['answer_count' => 0]);
+        }
+        $circle = $this->interestCircle->where('id', $request['id'])->first();
+        $limitCount = 0;
+        if ($circle->join_limit) {
+            if($circle->limit_condition){
+                $key = 'circle_error_count_' . $userInfo['uid'];
+                $errorCount = Redis::get($key);
+                if ($errorCount >= $circle->limit_condition) {
+                    return jsonError('今日次数已用完,明天再来吧', ['answer_count' => 0]);
+                }
+                if (empty($request['answer'])) {
+                    return jsonError('请输入答案~', ['answer_count' => intval($circle->limit_condition)-$errorCount]);
+                }
+            }else{
+                $limitCount = -1;
+                if (empty($request['answer'])) {
+                    return jsonError('请输入答案~', ['answer_count' => $limitCount]);
+                }
+            }
+            $question = json_decode($circle->join_question, true);
+            $answer = json_decode($request['answer'], true);
+            $checkRow = $this->checkQuestion($question, $answer);
+            if (!$checkRow) {
+                if($circle->limit_condition){
+                    if (!$errorCount) {
+                        Redis::set($key, 1);
+                        $expire = Carbon::today()->endOfDay()->timestamp - Carbon::now()->timestamp;
+                        Redis::expire($key, $expire);
+                    } else {
+                        Redis::incr($key);
+                    }
+                    $answerCount = intval($circle->limit_condition - Redis::get($key));
+                }else{
+                    $answerCount = -1;
+                }
+
+                if ($answerCount == 0) {
+                    return jsonError('学习学习,明天再来吧~', ['answer_count' => $answerCount]);
+                } else {
+                    return jsonError('真遗憾,没有答对哦~', ['answer_count' => $answerCount]);
+                }
+
+            }
+        }
+        DB::beginTransaction();
+        try {
+            $this->interestCircleUser->create(['uid' => $userInfo['uid'], 'circle_id' => $request['id']]);
+            $this->interestCircle->where('id', $request['id'])->increment('join_count');
+            DB::commit();
+            //加入圈子成功后,清除错误回答次数
+            $key = 'circle_error_count_' . $userInfo['uid'];
+            Redis::del($key);
+            return jsonSuccess();
+        } catch (QueryException $exception) {
+            DB::rollBack();
+            return jsonError('加入圈子失败,再试试吧', ['answer_count' => $limitCount]);
+        }
+
+    }
+
+    /**
+     * 检测答案是否正确
+     * @param $question 问题
+     * @param $answer   答案
+     * @return bool
+     */
+    private function checkQuestion($question, $answer)
+    {
+        $result = true;
+        $rightAnswer = [];
+        foreach ($question as $key => $value) {
+            $temp = [];
+            foreach ($value['answer'] as $k => $v) {
+                if ($v['right']) {
+                    $temp['answer_id'][] = $k + 1;
+                }
+            }
+            $rightAnswer[$key + 1] = $temp;
+        }
+//        var_dump(json_encode($rightAnswer));
+        foreach ($answer as $ak => $av) {
+            $right = $rightAnswer[$av['question']]['answer_id'];
+//            var_dump($right);
+//            var_dump($av['answer']);
+//            var_dump($right != $av['answer']);
+            if ($right != $av['answer']) {
+                $result = false;
+                break;
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * 退出圈子
+     * @param $request
+     * @param $userInfo
+     * @return array
+     */
+    public function exitCircle($request, $userInfo)
+    {
+        $info = $this->interestCircleUser
+            ->where('uid', $userInfo['uid'])
+            ->where('circle_id', $request['id'])
+            ->first();
+        if (!$info) {
+            return jsonError('您未加入该圈子');
+        }
+        if($info->is_black){
+            return jsonError('您在本圈子内的权限受限');
+        }
+        DB::beginTransaction();
+        try {
+            $info->delete();
+            $this->interestCircle->where('id', $request['id'])->decrement('join_count');
+            DB::commit();
+            //退出圈子成功后,清除错误回答次数
+            $key = 'circle_error_count_' . $userInfo['uid'];
+            Redis::del($key);
+            return jsonSuccess();
+        } catch (QueryException $exception) {
+            DB::rollBack();
+            return jsonError('退出圈子失败,再试试吧');
+        }
+    }
+
+
+
+
+}

+ 7 - 1
app/Repositories/FeedRepositories.php

@@ -206,6 +206,11 @@ class FeedRepositories
             $isFollow = $followStatus;
         }
         $user = $this->userInfo($postInfo['uid']);
+        if($postInfo['type']=='html'){
+            $content = subtext($postInfo['content'],100);
+        }else{
+            $content = $postInfo['content'];
+        }
         return [
             'id' => (int)$postInfo['id'],
             'type' => $postInfo['type'],
@@ -214,8 +219,9 @@ class FeedRepositories
             'username' => $user['username'],
             'avatar' => $user['avatar'],
             'topic' => $this->getTopic($postInfo['topic_ids']),
+            'is_fine' => $postInfo['is_fine'],
             'title' => $postInfo['title'],
-            'content' => $postInfo['content'],
+            'content' => $content,
             'location' => $postInfo['location'],
             'img' => $postInfo['img'],
             'imgs' => $postInfo['imgs'],

+ 31 - 5
app/Repositories/PostRepositories.php

@@ -25,6 +25,7 @@ use App\Models\PostShare;
 use App\Models\Topic;
 use App\Service\AliYunVodService;
 use App\Service\DetectionService;
+use App\Service\RabbitMqUtil;
 use App\Traits\CmsTrait;
 use App\Traits\PostTrait;
 use App\Traits\UserTrait;
@@ -92,7 +93,7 @@ class PostRepositories
             return jsonError('创作欲望太强啦,休息一下,看看其他用户的内容吧!');
         }
 
-        $detectionText = $request['title'] . ',' . $request['content'];
+        $detectionText = strip_tags($request['title']) . ',' . strip_tags($request['content']);
         $detectionTextResult = $this->detectionService->checkText($detectionText);
         if ($detectionTextResult['code'] < 0) {
             return jsonError('内容违规,请修正哦');
@@ -100,8 +101,8 @@ class PostRepositories
 
         $topicIds = json_decode($request['topic_ids'], true);
         $topicCount = count($topicIds);
-        if ($topicCount == 0 || $topicCount > 5) {
-            return jsonError('所选话题必须1-5个');
+        if ($topicCount == 0 || $topicCount > 2) {
+            return jsonError('所选话题必须1-2个');
         }
         //验证话题
         $hasTopicCount = $this->topic->whereIn('id', $topicIds)->count();
@@ -126,6 +127,10 @@ class PostRepositories
             Log::debug('图片违规,请修正哦' . json_encode($detectionImageResult));
             return jsonError('图片违规,请修正哦');
         }
+        //如果为html时候,则imgs只是去把富文本的图片拿去鉴黄,但不做其他处理
+        if ($request['type'] == 'html') {
+            $imgs = [];
+        }
         $videoUrl = "";
         $videoId = "";
         if (isset($request['video']) && $request['video']) {
@@ -154,9 +159,11 @@ class PostRepositories
             'video' => $videoUrl,
             'video_id' => $videoId,
             'topic_ids' => implode(',', $topicIds),
-            'title' => isset($request['title']) ? $request['title'] : '',
+            'title' => isset($request['title']) ? strip_tags($request['title']) : '',
             'content' => $request['content'],
-            'location' => isset($request['location']) ? $request['location'] : '',
+            'lat' => isset($request['lat']) ? number_format($request['lat'],8) : 0,
+            'lng' => isset($request['lng']) ? number_format($request['lng'],8) : 0,
+            'location' => isset($request['location']) ? strip_tags($request['location']) : '',
             'is_suggest' => 0,
             'is_hide' => 0,
             'weight' => $score
@@ -212,6 +219,7 @@ class PostRepositories
                 'imgs', json_encode($imgs),
                 'video', $post->video,
                 'topic_ids', $post->topic_ids,
+                'is_fine', $post->is_fine,
                 'title', $post->title,
                 'content', $post->content,
                 'location', $post->location,
@@ -227,6 +235,23 @@ class PostRepositories
                 'collect_bean', $postData->collect_bean,
                 'created_at', $post->created_at);
             Log::info('post_create:' . $post->id . ',post_author:' . $post->uid . ',author_ip:' . getClientIp());
+            $behavior = Behavior::where('behavior_identification', 'publish')->first();
+            if ('html' == $post->type && $behavior) {
+                $data = [
+                    "behavior_id" => $behavior['virus_behavior_id'],
+                    "behavior_flag" => "publish",
+                    "post_id" => $post->id,
+                    "post_type" => $post->type,
+                    "post_desc" => $post->title?$post->title:subtext($post->conetnt,100),
+                    "post_cover" => $post->img,
+                    "target_id" => $post->uid,
+                    "action_id" => $post->id,  //传帖子ID
+                ];
+                Log::debug('h5邀请用户注册' . json_encode($data));
+                //扔进virus队列
+                $rabbit = new RabbitMqUtil();
+                $rabbit->push('virus_add', $data);
+            }
             return jsonSuccess([
                 'post_id' => $post->id,
                 'h5url' => config('customer.share_post_h5url') . "?post_id={$post->id}&invite_code={$userInfo['invite_code']}",
@@ -548,6 +573,7 @@ class PostRepositories
         $perPage = isset($request['per_page']) ? $request['per_page'] : 20;
 
         return $this->post
+            ->where('is_hide', 0)
             ->whereRaw('FIND_IN_SET(' . $request['id'] . ',topic_ids)')
             ->orderBy('id', 'desc')
             ->paginate($perPage);

+ 2 - 1
app/Traits/PostTrait.php

@@ -72,6 +72,7 @@ trait PostTrait
         }
         $data = Redis::HGETALL('post_info_' . $id);
         if ($data) {
+            $data['is_fine'] = isset($data['is_fine']) ? intval($data['is_fine']) : 0;
             $data['praise_count'] = intval($data['praise_count']);
             $data['comment_count'] = intval($data['comment_count']);
             $data['collect_count'] = intval($data['collect_count']);
@@ -91,7 +92,7 @@ trait PostTrait
         $commentKey = 'post_new_comment_' . $id;
         $commentData = Redis::GET($commentKey);
         if ($commentData) {
-            $comment = json_decode($commentData,true);
+            $comment = json_decode($commentData, true);
             foreach ($comment as &$item) {
                 $isLike = 0;
                 if ($uid) {

+ 46 - 21
app/Traits/UserTrait.php

@@ -6,7 +6,9 @@
  * Date: 2019/5/5
  * Time: 17:11
  */
+
 namespace App\Traits;
+
 use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Redis;
 use Tymon\JWTAuth\Facades\JWTAuth;
@@ -14,14 +16,15 @@ use Tymon\JWTAuth\Facades\JWTAuth;
 trait UserTrait
 {
     //获取用户
-    public function getUserInfo() {
+    public function getUserInfo()
+    {
         try {
             $sign = generateSign([], config('customer.app_secret'));
-            $url = config("customer.app_service_url").'/user/userInfo';
+            $url = config("customer.app_service_url") . '/user/userInfo';
             $array = [
-                'json' => ['sign' => $sign], 'query' => [], 'http_errors' => false,'headers'=>['Authorization'=>"Bearer ".JWTAuth::getToken()]
+                'json' => ['sign' => $sign], 'query' => [], 'http_errors' => false, 'headers' => ['Authorization' => "Bearer " . JWTAuth::getToken()]
             ];
-            return http($url,$array);
+            return http($url, $array);
         } catch (\Exception $e) {
             return [];
         }
@@ -29,21 +32,22 @@ trait UserTrait
     }
 
     //获取用户信息
-    public function userInfo($uid) {
+    public function userInfo($uid)
+    {
         $user = Redis::HGETALL('userInfo:' . $uid);
-        if(!$user){
+        if (!$user) {
             try {
                 $sign = generateSign(['uid' => $uid], config('customer.app_secret'));
-                $url = config("customer.app_service_url").'/user/getUserInfo';
+                $url = config("customer.app_service_url") . '/user/getUserInfo';
                 $array = [
-                    'json' => ['sign' => $sign,'uid' => $uid], 'query' => [], 'http_errors' => false,'headers'=>['Authorization'=>"Bearer ".JWTAuth::getToken()]
+                    'json' => ['sign' => $sign, 'uid' => $uid], 'query' => [], 'http_errors' => false, 'headers' => ['Authorization' => "Bearer " . JWTAuth::getToken()]
                 ];
-                $user =  http($url,$array,'get');
+                $user = http($url, $array, 'get');
             } catch (\Exception $e) {
-                $user =  [];
+                $user = [];
             }
         }
-        if(!$user){
+        if (!$user) {
             $user = [
                 'uid' => $uid,
                 'username' => '老板',
@@ -55,42 +59,63 @@ trait UserTrait
         return $user;
     }
 
+    /**
+     * 格式化user的字段类型
+     * @param $user
+     * @return array
+     */
+    public function formatUser($user)
+    {
+        $u = [
+            'uid' => intval($user['uid']),
+            'username' => $user['username'],
+            'avatar' => $user['avatar'],
+            'gender' => intval($user['gender']),
+            'invite_code' => $user['invite_code']
+        ];
+        return $u;
+    }
+
     //获取关注状态
     public function getFollowStatus($uid, $followUid)
     {
         $status = 0;
-        if(Redis::ZSCORE('follow:'.$uid, $followUid)){
+        if (Redis::ZSCORE('follow:' . $uid, $followUid)) {
             $status = 1;
-            if(Redis::ZSCORE('follow:'.$followUid, $uid)){
+            if (Redis::ZSCORE('follow:' . $followUid, $uid)) {
                 $status = 2;
             }
         }
         return $status;
     }
+
     //检查关注状态 多个uid
-    public function getFollowMembersStatus($uids) {
+    public function getFollowMembersStatus($uids)
+    {
         try {
             $sign = generateSign(['uids' => $uids], config('customer.app_secret'));
-            $url = config("customer.app_service_url").'/user/v2/member/getMemberIds';
+            $url = config("customer.app_service_url") . '/user/v2/member/getMemberIds';
             $array = [
-                'json' => ['sign' => $sign, 'uids' => $uids], 'query' => [], 'http_errors' => false,'headers'=>['Authorization'=>"Bearer ".JWTAuth::getToken()]
+                'json' => ['sign' => $sign, 'uids' => $uids], 'query' => [], 'http_errors' => false, 'headers' => ['Authorization' => "Bearer " . JWTAuth::getToken()]
             ];
-            return http($url,$array,'get');
+            return http($url, $array, 'get');
         } catch (\Exception $e) {
             Log::debug($e->getMessage());
             return [];
         }
     }
+
     //检查关注状态 多个uid
-    public function getFollowMemberFans($follow_id) {
+    public function getFollowMemberFans($follow_id)
+    {
         try {
             $sign = generateSign(['follow_id' => $follow_id], config('customer.app_secret'));
-            $url = config("customer.app_service_url").'/user/v2/member/getFollowMemberFans';
+            $url = config("customer.app_service_url") . '/user/v2/member/getFollowMemberFans';
             //$url = 'http://localhost:8080/v2/member/getFollowMemberFans';
             $array = [
-                'json' => ['sign' => $sign, 'follow_id' => $follow_id], 'query' => [], 'http_errors' => false,'headers'=>['Authorization'=>"Bearer ".JWTAuth::getToken()]
+                'json' => ['sign' => $sign, 'follow_id' => $follow_id], 'query' => [], 'http_errors' => false, 'headers' => ['Authorization' => "Bearer " . JWTAuth::getToken()]
             ];
-            return http($url,$array,'get');
+            return http($url, $array, 'get');
         } catch (\Exception $e) {
             Log::debug($e->getMessage());
             return [];

+ 73 - 0
app/Transformers/Circle/ArticleListTransformer.php

@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/15
+ * Time: 11:07
+ */
+namespace  App\Transformers\Circle;
+
+use App\Models\Post;
+use App\Traits\PostTrait;
+use App\Traits\UserTrait;
+use Carbon\Carbon;
+use Illuminate\Support\Facades\Redis;
+use League\Fractal\TransformerAbstract;
+
+class ArticleListTransformer extends TransformerAbstract
+{
+    use UserTrait;
+    use PostTrait;
+    public function __construct($uid, $invite_code)
+    {
+        $this->uid = $uid;
+        $this->invite_code = $invite_code;
+    }
+    public function transform(Post $post)
+    {
+        $isLike = 0;
+        $isDislike = 0;
+        $isCollect = 0;
+        if($this->uid){
+            $isLike = Redis::SISMEMBER('post_like_'.$post['id'], $this->uid);
+            $isDislike = Redis::SISMEMBER('post_unlike_'.$post['id'], $this->uid);
+            $isCollect = Redis::SISMEMBER('post_collect_'.$post['id'], $this->uid);
+        }
+        $user = $this->userInfo($post['uid']);
+        $postInfo = $this->getPostInfo($post['id']);
+        if($post['type']=='html'){
+            $content = subtext($post['content'],100);
+        }else{
+            $content = $post['content'];
+        }
+        return [
+            'id' => $post['id'],
+            'type' => $post['type'],
+            'created_at' => Carbon::parse($post['created_at'])->diffForHumans(),
+            'uid' => $post['uid'],
+            'username' => $user['username'],
+            'avatar' => $user['avatar'],
+            'topic' => $this->getTopic($post['topic_ids']),
+            'is_fine' => $post['is_fine'],
+            'title' => $post['title'],
+            'content' => $content,
+            'location' => $post['location'],
+            'img' => $post['img'],
+            'imgs' => $postInfo['imgs'],
+            'video' => $post['video'],
+            'pv' => getNumber($postInfo['pv']),
+            'praise_count' => $postInfo['praise_count'],
+            'comment_count' => $postInfo['comment_count'],
+            'collect_count' => $postInfo['collect_count'],
+            'will_collect_bean' => $postInfo['will_collect_bean'],
+            'is_like' => $isLike,
+            'is_dislike' => $isDislike,
+            'is_collect' => $isCollect,
+            'comment' => $this->getNewComment($post['id'], $this->uid),
+            'is_follow' => $this->getFollowStatus($this->uid, $post['uid']),
+            'h5url' => config('customer.share_post_h5url')."?post_id={$post['id']}&invite_code={$this->invite_code}",
+            'desc_url' => $post['type'] == 'html'?config('customer.app_service_url').'/community/fragment/detail/'.$post['id']:'',
+        ];
+    }
+}

+ 29 - 0
app/Transformers/Circle/CircleMemberTransformer.php

@@ -0,0 +1,29 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/6
+ * Time: 14:08
+ */
+namespace App\Transformers\Circle;
+
+use App\Models\InterestCircleUser;
+use App\Models\Post;
+use App\Traits\PostTrait;
+use App\Traits\UserTrait;
+use Illuminate\Support\Carbon;
+use League\Fractal\TransformerAbstract;
+
+class CircleMemberTransformer extends TransformerAbstract
+{
+    use UserTrait;
+    public function transform(InterestCircleUser $interestCircleUser)
+    {
+        $user = $this->formatUser($this->userInfo($interestCircleUser['uid']));
+        return [
+            'user' => $user?$user:new \stdClass(),
+            'created_at' => Carbon::parse($interestCircleUser['created_at'])->toDateTimeString()
+        ];
+    }
+}

+ 86 - 0
app/Transformers/Circle/CommentTransformer.php

@@ -0,0 +1,86 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/15
+ * Time: 16:40
+ */
+namespace  App\Transformers\Circle;
+
+use App\Models\InterestCircleMessageComment;
+use App\Models\PostComment;
+use App\Traits\PostTrait;
+use App\Traits\UserTrait;
+use Carbon\Carbon;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Redis;
+use League\Fractal\TransformerAbstract;
+
+class CommentTransformer extends TransformerAbstract
+{
+    use UserTrait;
+    use PostTrait;
+    public function __construct($msgId, $uid)
+    {
+        $this->msgId = $msgId;
+        $this->uid = $uid;
+    }
+
+    public function transform(InterestCircleMessageComment $interestCircleMessageComment)
+    {
+        $reply = [];
+        $replyKey = 'circle_message_new_reply_'.$interestCircleMessageComment['id'];
+        $replyData = Redis::GET($replyKey);
+        if($replyData){
+            $reply = json_decode($replyData);
+            foreach($reply as &$item){
+                $item->created_at = Carbon::parse($item->created_at)->diffForHumans();
+            }
+        }else{
+            $replies = InterestCircleMessageComment::where('parent_id', $interestCircleMessageComment['id'])->orderBy('id', 'desc')->limit(2)->get();
+            $redisReply = [];
+            foreach($replies as $val){
+                $userComment = $this->userInfo($val->uid);
+                $replyUsername = '';
+                if($val->reply_uid){
+                    $userReply = $this->userInfo($val->reply_uid);
+                    $replyUsername = $userReply['username'];
+                }
+                $reply[] = [
+                    'id' => $val->id,
+                    'uid' => $val->uid,
+                    'username' => $userComment['username'],
+                    'avatar' => $userComment['avatar'],
+                    'reply_username' => $replyUsername,
+                    'content' => $val->is_delete?'该评论已被删除':$val->content,
+                    'created_at' => Carbon::parse($val->created_at)->diffForHumans(),
+                    'is_delete' => $val->is_delete,
+                ];
+                $redisReply[] = [
+                    'id' => $val->id,
+                    'uid' => $val->uid,
+                    'username' => $userComment['username'],
+                    'avatar' => $userComment['avatar'],
+                    'reply_username' => $replyUsername,
+                    'content' => $val->is_delete?'该评论已被删除':$val->content,
+                    'created_at' => $val->created_at,
+                    'is_delete' => $val->is_delete,
+                ];
+            }
+            Redis::SET($replyKey, json_encode($redisReply));
+            Redis::EXPIRE($replyKey, 604800);
+        }
+        $user = $this->userInfo($interestCircleMessageComment['uid']);
+        return [
+            'id' => $interestCircleMessageComment['id'],
+            'uid' => $interestCircleMessageComment['uid'],
+            'username' => $user['username'],
+            'avatar' => $user['avatar'],
+            'content' => $interestCircleMessageComment['is_delete']?'该评论已被删除':$interestCircleMessageComment['content'],
+            'created_at' => Carbon::parse($interestCircleMessageComment['created_at'])->diffForHumans(),
+            'reply_count' => $interestCircleMessageComment['reply_count'],
+            'reply' => $reply,
+            'is_delete' => $interestCircleMessageComment['is_delete'],
+        ];
+    }
+}

+ 91 - 0
app/Transformers/Circle/DetailTransformer.php

@@ -0,0 +1,91 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/6
+ * Time: 14:08
+ */
+
+namespace App\Transformers\Circle;
+
+use App\Models\InterestCircle;
+use App\Models\InterestCircleUser;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Redis;
+use League\Fractal\TransformerAbstract;
+
+class DetailTransformer extends TransformerAbstract
+{
+
+    public function __construct($uid)
+    {
+        $this->uid = $uid;
+    }
+
+    public function transform(InterestCircle $interestCircle)
+    {
+        if ($interestCircle['limit_condition']) {
+            $answer = $interestCircle['limit_condition'] - intval(Redis::get('circle_error_count_' . $this->uid));
+        } else {
+            $answer = -1;
+        }
+
+        $row = [
+            'id' => $interestCircle['id'],
+            'name' => $interestCircle['name'],
+            'notice' => $interestCircle['notice'],
+            'image' => $interestCircle['image'],
+            'join_limit' => $interestCircle['join_limit'],
+            'is_join' => $this->isJoin($this->uid, $interestCircle['id']),
+            'answer_count' => $answer,
+            'is_black' => $this->isBlack($this->uid, $interestCircle['id'])
+        ];
+        $funs = $this->getFunction($interestCircle);
+        return array_merge($row, $funs);
+    }
+
+    //判读当前用户是否圈子黑名单
+    public function isBlack($uid, $circleId)
+    {
+        $info = InterestCircleUser::where([['circle_id', $circleId], ['uid', $uid], ['is_black', 1]])->first();
+        Log::debug('blacklist:'.json_encode($info));
+        return $info ? 1 : 0;
+    }
+
+    //判读当前用户是否加入圈子
+    public function isJoin($uid, $circleId)
+    {
+        $info = InterestCircleUser::where([['circle_id', $circleId], ['uid', $uid]])->first();
+        return $info ? 1 : 0;
+    }
+
+    /**
+     * 查询圈子开放功能
+     * @param InterestCircle $interestCircle
+     * @return array
+     */
+    private function getFunction(InterestCircle $interestCircle)
+    {
+        $functions = json_decode($interestCircle['contains_function'], true);
+        $info['members'] = ['is_open' => 1, 'extra' => intval($interestCircle['join_count'])];
+        $info['pictures'] = ['is_open' => 0, 'extra' => 0];
+        $info['chatroom'] = ['is_open' => 0, 'extra' => ''];
+        if (empty($functions)) {
+            return $info;
+        }
+        foreach ($functions as &$func) {
+            if ('pictures' == $func['function']) {
+                if (1 == $func['is_open']) {
+                    $info['pictures'] = ['is_open' => 1, 'extra' => intval($interestCircle['picture_count'])];
+                }
+            }
+            if ('chatroom' == $func['function']) {
+                if (1 == $func['is_open']) {
+                    $info['chatroom'] = ['is_open' => 1, 'extra' => (string)$interestCircle['relate_id']];
+                }
+            }
+        }
+        return $info;
+    }
+}

+ 97 - 0
app/Transformers/Circle/MessageListTransformer.php

@@ -0,0 +1,97 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/6
+ * Time: 14:08
+ */
+
+namespace App\Transformers\Circle;
+
+use App\Models\InterestCircle;
+use App\Models\InterestCircleMessage;
+use App\Models\InterestCircleMessageComment;
+use App\Models\InterestCircleMessageRecord;
+use App\Models\Post;
+use App\Traits\PostTrait;
+use App\Traits\UserTrait;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\Redis;
+use League\Fractal\TransformerAbstract;
+
+class MessageListTransformer extends TransformerAbstract
+{
+    use UserTrait;
+
+    public function __construct($uid)
+    {
+        $this->uid = $uid;
+    }
+
+    public function transform(InterestCircleMessage $interestCircleMessage)
+    {
+        $user = $this->formatUser($this->userInfo($interestCircleMessage['uid']));
+        $imgs = [];
+        foreach ($interestCircleMessage->imgs as $img) {
+            $imgs[] = $img['image'];
+        }
+        return [
+            'id' => $interestCircleMessage['id'],
+            'created_at' => Carbon::parse($interestCircleMessage['created_at'])->diffForHumans(),
+            'user' => $user ? $user : new \stdClass(),
+            'content' => $interestCircleMessage['content'],
+            'imgs' => $imgs,
+            'good' => $interestCircleMessage['good'],
+            'bad' => $interestCircleMessage['bad'],
+            'action' => $this->getAction($this->uid,$interestCircleMessage['id']),
+            'comment_count' => $interestCircleMessage['comment_count'],
+            'comment' => $this->getNewComment($interestCircleMessage['id']),
+        ];
+    }
+
+    public function getAction($uid, $msgId)
+    {
+        $info = InterestCircleMessageRecord::where([['uid', $uid], ['msg_id', $msgId]])->first();
+        $status = 0;
+        if ($info && $info->action == 1) {
+            $status = 1;
+        } elseif ($info && $info->action == -1) {
+            $status = -1;
+        }
+        return $status;
+    }
+
+    //获取内容最新评论
+    public function getNewComment($id, $uid = 0)
+    {
+        $comment = [];
+        $commentKey = 'circle_message_new_comment_' . $id;
+        $commentData = Redis::GET($commentKey);
+        if ($commentData) {
+            $comment = json_decode($commentData, true);
+            foreach ($comment as &$item) {
+                $item['uid'] = intval($item['uid']);
+                $item['reply_count'] = 0;
+                $item['reply'] = [];
+            }
+        } else {
+            $comments = InterestCircleMessageComment::where('msg_id', $id)->where('parent_id', 0)->where('is_delete', 0)->orderBy('id', 'desc')->limit(2)->get();
+            foreach ($comments as $item) {
+                $userComment = $this->userInfo($item->uid);
+                $comment[] = [
+                    'id' => $item->id,
+                    'uid' => intval($userComment['uid']),
+                    'username' => $userComment['username'],
+                    'content' => $item->is_delete ? '该评论已被删除' : $item->content,
+                    'is_delete' => $item->is_delete,
+                    'reply_count' => 0,
+                    'reply' => [],
+                ];
+            }
+            Redis::SET($commentKey, json_encode($comment));
+            Redis::EXPIRE($commentKey, 300);
+        }
+        return $comment;
+    }
+}

+ 51 - 0
app/Transformers/Circle/PictureListTransformer.php

@@ -0,0 +1,51 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/6
+ * Time: 14:08
+ */
+
+namespace App\Transformers\Circle;
+
+use App\Models\InterestCircle;
+use App\Models\InterestCirclePicture;
+use App\Traits\UserTrait;
+use Illuminate\Support\Carbon;
+use Illuminate\Support\Facades\Redis;
+use League\Fractal\TransformerAbstract;
+
+class PictureListTransformer extends TransformerAbstract
+{
+    use UserTrait;
+
+    public function transform(InterestCirclePicture $interestCirclePicture)
+    {
+        $user = $this->formatUser($this->userInfo($interestCirclePicture['uid']));
+
+        return [
+            'id' => $interestCirclePicture['patch_num'],
+            'user' => $user ? $user : new \stdClass(),
+            'imgs' => $this->getImgs($interestCirclePicture),
+            'created_at' => Carbon::parse($interestCirclePicture['created_at'])->toDateTimeString(),
+        ];
+    }
+
+    public function getImgs(InterestCirclePicture $interestCirclePicture)
+    {
+        $imgs = [];
+        $key = 'circle_picture_' . $interestCirclePicture['patch_num'];
+        $tmp = Redis::get($key);
+        if (empty($tmp)) {
+            $picList = InterestCirclePicture::where('patch_num', $interestCirclePicture['patch_num'])->get();
+            foreach ($picList as $pic) {
+                $imgs[] = $pic->image;
+            }
+        } else {
+            $imgs = json_decode($tmp, true);
+        }
+
+        return $imgs;
+    }
+}

+ 54 - 0
app/Transformers/Circle/QuestionTransformer.php

@@ -0,0 +1,54 @@
+<?php
+
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/6
+ * Time: 14:08
+ */
+
+namespace App\Transformers\Circle;
+
+use App\Models\InterestCircle;
+use App\Models\InterestCircleUser;
+use Illuminate\Support\Facades\Redis;
+use League\Fractal\TransformerAbstract;
+
+class QuestionTransformer extends TransformerAbstract
+{
+
+    public function __construct($uid)
+    {
+        $this->uid = $uid;
+    }
+
+    public function transform(InterestCircle $interestCircle)
+    {
+        if ($interestCircle['limit_condition']) {
+            $answer = $interestCircle['limit_condition'] - intval(Redis::get('circle_error_count_' . $this->uid));
+        } else {
+            $answer = -1;
+        }
+        return [
+            'id' => $interestCircle['id'],
+            'join_question' => $this->formatQuestion($interestCircle),
+            'answer_count' => $answer
+        ];
+    }
+
+    public function formatQuestion(InterestCircle $interestCircle)
+    {
+        $question = [];
+        $ques = json_decode($interestCircle['join_question'], true);
+        if (empty($ques)) {
+            return $question;
+        }
+        foreach ($ques as $key => &$value) {
+            $value['id'] = $key + 1;
+            foreach ($value['answer'] as $k => &$v) {
+                $v['id'] = $k + 1;
+            }
+        }
+        return $ques;
+    }
+}

+ 40 - 0
app/Transformers/Circle/ReplyTransformer.php

@@ -0,0 +1,40 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: Administrator
+ * Date: 2019/6/15
+ * Time: 17:08
+ */
+namespace  App\Transformers\Circle;
+
+use App\Models\InterestCircleMessageComment;
+use App\Models\PostComment;
+use App\Traits\PostTrait;
+use App\Traits\UserTrait;
+use Carbon\Carbon;
+use League\Fractal\TransformerAbstract;
+
+class ReplyTransformer extends TransformerAbstract
+{
+    use UserTrait;
+
+    public function transform(InterestCircleMessageComment $postComment)
+    {
+        $user = $this->userInfo($postComment['uid']);
+        $replyUsername = '';
+        if($postComment['reply_uid']){
+            $userReply = $this->userInfo($postComment['reply_uid']);
+            $replyUsername = $userReply['username'];
+        }
+        return [
+            'id' => $postComment['id'],
+            'uid' => $postComment['uid'],
+            'username' => $user['username'],
+            'reply_username' => $replyUsername,
+            'avatar' => $user['avatar'],
+            'content' => $postComment['is_delete']?'该回复已被删除':$postComment['content'],
+            'created_at' => Carbon::parse($postComment['created_at'])->diffForHumans(),
+            'is_delete' => $postComment['is_delete']
+        ];
+    }
+}

+ 1 - 0
app/Transformers/Post/ListTransformer.php

@@ -37,6 +37,7 @@ class ListTransformer extends TransformerAbstract
             'uid' => $post['uid'],
             'username' => $user['username'],
             'avatar' => $user['avatar'],
+            'is_fine' => $post['is_fine']??0,
             'title' => $post['title'],
             'content' => subtext($post['content'], 100),
             'img' => $post['img'],

+ 7 - 1
app/Transformers/Post/SuggestTransformer.php

@@ -38,6 +38,11 @@ class SuggestTransformer extends TransformerAbstract
         }
         $user = $this->userInfo($post['uid']);
         $postInfo = $this->getPostInfo($post['id']);
+        if($post['type']=='html'){
+            $content = subtext($post['content'],100);
+        }else{
+            $content = $post['content'];
+        }
         return [
             'show_type' => 'post',
             'id' => $post['id'],
@@ -47,8 +52,9 @@ class SuggestTransformer extends TransformerAbstract
             'username' => $user['username'],
             'avatar' => $user['avatar'],
             'topic' => $this->getTopic($post['topic_ids']),
+            'is_fine' => $post['is_fine'],
             'title' => $post['title'],
-            'content' => $post['content'],
+            'content' => $content,
             'location' => $post['location'],
             'img' => $post['img'],
             'imgs' => $postInfo['imgs'],

+ 20 - 3
app/Transformers/Topic/TopicDetailTransformer.php

@@ -5,8 +5,10 @@
  * Date: 2019/6/17
  * Time: 18:10
  */
-namespace  App\Transformers\Topic;
 
+namespace App\Transformers\Topic;
+
+use App\Models\InterestCircle;
 use App\Models\Topic;
 use Carbon\Carbon;
 use League\Fractal\TransformerAbstract;
@@ -17,18 +19,33 @@ class TopicDetailTransformer extends TransformerAbstract
     {
         $this->uid = $uid;
     }
+
     public function transform(Topic $topic)
     {
         $isFollow = 0;
-        if($this->uid){
-            $isFollow = $topic->follow->where('uid', $this->uid)->count()?1:0;
+        if ($this->uid) {
+            $isFollow = $topic->follow->where('uid', $this->uid)->count() ? 1 : 0;
         }
+
         return [
             'id' => $topic['id'],
             'name' => $topic['name'],
             'img' => $topic['img'],
             'follow_count' => getNumber($topic['use_count'] + $topic['base_count']),
             'is_follow' => $isFollow,
+            'circle' => $this->getCircleInfo($topic['circle_id'])
         ];
     }
+
+    public function getCircleInfo($circleId)
+    {
+        $circleInfo = InterestCircle::find($circleId);
+        if ($circleInfo) {
+            $circle['id'] = $circleInfo->id;
+            $circle['name'] = $circleInfo->name;
+        } else {
+            $circle = new \stdClass();
+        }
+        return $circle;
+    }
 }

+ 14 - 10
app/Transformers/Topic/TopicPostTransformer.php

@@ -5,7 +5,8 @@
  * Date: 2019/6/17
  * Time: 19:26
  */
-namespace  App\Transformers\Topic;
+
+namespace App\Transformers\Topic;
 
 use App\Models\Post;
 use App\Models\PostCollect;
@@ -21,27 +22,29 @@ class TopicPostTransformer extends TransformerAbstract
 {
     use UserTrait;
     use PostTrait;
+
     public function __construct($uid, $invite_code)
     {
         $this->uid = $uid;
         $this->invite_code = $invite_code;
     }
+
     public function transform(Post $post)
     {
         $imgs = [];
-        foreach($post->imgs as $img){
+        foreach ($post->imgs as $img) {
             $imgs[] = $img['img'];
         }
         $isLike = 0;
         $isDislike = 0;
         $isCollect = 0;
         $isFollow = 0;
-        if($this->uid){
-            $isLike = PostLike::where('post_id', $post['id'])->where('uid', $this->uid)->exists()?1:0;
-            $isDislike = PostDislike::where('post_id', $post['id'])->where('uid', $this->uid)->exists()?1:0;
-            $isCollect = PostCollect::where('post_id', $post['id'])->where('uid', $this->uid)->exists()?1:0;
+        if ($this->uid) {
+            $isLike = PostLike::where('post_id', $post['id'])->where('uid', $this->uid)->exists() ? 1 : 0;
+            $isDislike = PostDislike::where('post_id', $post['id'])->where('uid', $this->uid)->exists() ? 1 : 0;
+            $isCollect = PostCollect::where('post_id', $post['id'])->where('uid', $this->uid)->exists() ? 1 : 0;
             $followStatus = $this->getFollowStatus($this->uid, $post['uid']);
-            if($followStatus){
+            if ($followStatus) {
                 $isFollow = $followStatus;
             }
         }
@@ -54,8 +57,9 @@ class TopicPostTransformer extends TransformerAbstract
             'username' => $user['username'],
             'avatar' => $user['avatar'],
             'topic' => $this->getTopic($post['topic_ids']),
+            'is_fine' => $post['is_fine'],
             'title' => $post['title'],
-            'content' => $post['content'],
+            'content' => subtext($post['content'], 100),
             'location' => $post['location'],
             'img' => $post['img'],
             'imgs' => $imgs,
@@ -69,8 +73,8 @@ class TopicPostTransformer extends TransformerAbstract
             'is_collect' => $isCollect,
             'comment' => $this->getNewComment($post['id'], $this->uid),
             'is_follow' => $isFollow,
-            'h5url' => config('customer.share_post_h5url')."?post_id={$post['id']}&invite_code={$this->invite_code}",
-            'desc_url' => $post['type'] == 'html'?config('customer.app_service_url').'/community/fragment/detail/'.$post['id']:'',
+            'h5url' => config('customer.share_post_h5url') . "?post_id={$post['id']}&invite_code={$this->invite_code}",
+            'desc_url' => $post['type'] == 'html' ? config('customer.app_service_url') . '/community/fragment/detail/' . $post['id'] : '',
         ];
     }
 }

+ 41 - 0
routes/api.php

@@ -71,6 +71,26 @@ $api->version('v1', [
     //图片验证
     $api->get('post/checkImage', 'PostController@checkImage');
 
+    //圈子相关
+
+    //圈子检测
+    $api->get('circle/valid', 'CircleController@valid');
+    //圈子首页
+    $api->get('circle', 'CircleController@index');
+    //圈子问题
+    $api->get('circle/question', 'CircleController@getQuestion');
+    //圈子精华文章列表
+    $api->get('circle/articles', 'CircleController@articleList');
+    //圈子提问列表
+    $api->get('circle/messages', 'CircleController@messageList');
+    //圈子提问评论列表
+    $api->get('circle/comments', 'CircleController@commentList');
+    //圈子提问回复列表
+    $api->get('circle/replys', 'CircleController@replyList');
+    //相册列表
+    $api->get('circle/pictures', 'CircleController@pictureList');
+    //圈子成员
+    $api->get('circle/members', 'CircleController@memberList');
     //登录+验签
     $api->group(['middleware' => ['chxq_jwt_auth','chxq_sign']], function ($api) {
         //发布内容
@@ -112,6 +132,27 @@ $api->version('v1', [
         $api->get('rankingList', 'BeanDetailController@rankingList');
         //后院首页
         $api->get('starHome', 'BeanDetailController@starHome');
+
+        //加入圈子
+        $api->post('circle/join', 'CircleController@joinCircle');
+        //退出圈子
+        $api->delete('circle/join', 'CircleController@exitCircle');
+
+        //创建提问
+        $api->post('circle/message', 'CircleController@messageCreate');
+        //创建提问评论
+        $api->post('circle/comment', 'CircleController@comment');
+        //提问顶踩
+        $api->post('circle/message/action', 'CircleController@messageAction');
+        //删除提问
+        $api->delete('circle/message', 'CircleController@deleteMessage');
+        //删除评论
+        $api->delete('circle/comment', 'CircleController@deleteComment');
+        //删除相册
+        $api->delete('circle/picture', 'CircleController@deletePicture');
+
+        //创建相册
+        $api->post('circle/picture', 'CircleController@createPictures');
     });