WxCircleRepositores.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. <?php
  2. namespace App\Http\Controllers\Api\Repositories;
  3. use App\Jobs\Circle\UpdateCircleCountJob;
  4. use App\Models\Posts\WxPost;
  5. use App\Models\Posts\WxUserCircle;
  6. use App\Models\Circle\WxCircle;
  7. use App\Models\User\WxUser;
  8. use App\Models\Circle\WxCircle as Model;
  9. use App\Models\User\WxUserVisit;
  10. use App\Models\WxPlate;
  11. use App\Wen\Utils\CircleUtils;
  12. use App\Wen\Utils\FieldUtils;
  13. use App\Wen\Utils\UserUtils;
  14. use Illuminate\Support\Facades\Cache;
  15. use Illuminate\Support\Facades\DB;
  16. use Illuminate\Support\Facades\Redis;
  17. class WxCircleRepositores
  18. {
  19. public static function add($data, $circle_state)
  20. {
  21. $model = new Model();
  22. global $__MINI_GLOBAL_TENANT_ID__;
  23. if ($data['id']) {
  24. $r = WxCircle::where('id', $data['id'])->update([
  25. 'circle_name' => $data['circle_name'],
  26. 'circle_introduce' => $data['circle_introduce'],
  27. 'head_portrait' => $data['head_portrait'],
  28. 'background_maps' => $data['background_maps'],
  29. 'plate_id' => $data['plate_id'],
  30. 'circle_state' => $circle_state
  31. ]);
  32. return $data['id'];
  33. } else {
  34. global $__MINI_GLOBAL_CURRENT_USER_ID__;
  35. if(_empty_($data['uid'])){
  36. $data['uid'] = $__MINI_GLOBAL_CURRENT_USER_ID__;
  37. }
  38. $model->circle_name = $data['circle_name'];
  39. $model->circle_introduce = $data['circle_introduce'];
  40. $model->head_portrait = $data['head_portrait'];
  41. $model->background_maps = $data['background_maps'];
  42. $model->plate_id = $data['plate_id'];
  43. $model->user_id = $data['uid'];
  44. $model->circle_state = $circle_state;
  45. if($__MINI_GLOBAL_TENANT_ID__ > 0){
  46. $model->tenant_id = $__MINI_GLOBAL_TENANT_ID__;
  47. $model->tenant_show = $__MINI_GLOBAL_TENANT_ID__;
  48. }
  49. $r = $model->save();
  50. // (0审核中,1正常,2驳回)
  51. if($r){
  52. if($circle_state == 1){
  53. UserUtils::add_user_notice(5001, $data['uid'], env('circle_call', '圈子').'审核通知', '您的创建的'.env('circle_call', '圈子').'已经审核通过啦', 100);
  54. }else{
  55. UserUtils::assistant_notice('admin', '有新的'.env('circle_call', '圈子').'创建申请待审核');
  56. }
  57. }
  58. return $model->id;
  59. }
  60. }
  61. /**
  62. * -1:最火;0:最新
  63. * @param $plateId
  64. * @return mixed
  65. */
  66. public static function circleByPlateId($plateId, $uid = 0)
  67. {
  68. global $__MINI_GLOBAL_TENANT_ID__;
  69. $data = null;
  70. if ($plateId == 0) {
  71. $query = (new Model())->where('circle_state', 1);
  72. // $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
  73. $query = $query->where(function ($query) {
  74. global $__MINI_GLOBAL_TENANT_ID__;
  75. $query->where('tenant_show', -1)
  76. ->orWhere('tenant_show', $__MINI_GLOBAL_TENANT_ID__);
  77. });
  78. $data = $query->withCount('wxPosts as posts_count')
  79. ->orderBy('created_at', 'DESC')
  80. ->limit(20)
  81. ->get();
  82. } elseif ($plateId == -1) {
  83. $query = (new Model())->where('circle_state', 1);
  84. $query = $query->where(function ($query) {
  85. global $__MINI_GLOBAL_TENANT_ID__;
  86. $query->where('tenant_show', -1)
  87. ->orWhere('tenant_show', $__MINI_GLOBAL_TENANT_ID__);
  88. });
  89. // $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
  90. $data = $query->withCount('wxPosts as posts_count')
  91. ->orderBy('sort', 'desc')
  92. ->limit(20)
  93. ->get();
  94. } elseif ($plateId == -2) {
  95. // 常用
  96. $object_ids = WxUserVisit::where([['user_id','=', $uid],['type', '=', 2]])->orderBy('updated_at', 'desc')->limit(100)->pluck('object_id');
  97. if($object_ids) {
  98. $query = (new Model())->whereIn('id', $object_ids);
  99. $query = $query->where(function ($query) {
  100. global $__MINI_GLOBAL_TENANT_ID__;
  101. $query->where('tenant_show', -1)
  102. ->orWhere('tenant_show', $__MINI_GLOBAL_TENANT_ID__);
  103. });
  104. $query = $query->orderBy(DB::raw('FIND_IN_SET(id, "' . implode(",", $object_ids->toArray()) . '"' . ")"));
  105. $data = $query->withCount('wxPosts as posts_count')
  106. ->orderBy('sort', 'desc')
  107. ->limit(20)
  108. ->get();
  109. }else{
  110. $data = [];
  111. }
  112. }else{
  113. $query = (new Model())
  114. ->where('plate_id', $plateId)
  115. ->where('circle_state', 1);
  116. $query = $query->where(function ($query) {
  117. global $__MINI_GLOBAL_TENANT_ID__;
  118. $query->where('tenant_show', -1)
  119. ->orWhere('tenant_show', $__MINI_GLOBAL_TENANT_ID__);
  120. });
  121. $data = $query->withCount('wxPosts as posts_count')
  122. ->orderBy('sort', 'desc')
  123. ->get();
  124. }
  125. if($data){
  126. $data->map(function ($v) use ($uid){
  127. $v->is_follow_circle = self::isFollowCircle($uid, $v->id);
  128. $v->can_i_visit = CircleUtils::can_i_visit($v, $uid);
  129. $v->user_circle_count = CircleUtils::circleFollowCount($v->id);
  130. return $v;
  131. });
  132. return $data;
  133. }
  134. return null;
  135. }
  136. /**
  137. * 搜索
  138. * @param $keyword
  139. * @return mixed
  140. */
  141. public static function searchCircle($keyword, $uid = 0, $limit = 10, $is_tenant = false)
  142. {
  143. global $__MINI_GLOBAL_TENANT_ID__;
  144. $query = (new Model())
  145. ->where('circle_state', 1);
  146. if($is_tenant){
  147. $query = $query->where(function ($query) {
  148. global $__MINI_GLOBAL_TENANT_ID__;
  149. $query->where('tenant_show', -1)
  150. ->orWhere('tenant_show', $__MINI_GLOBAL_TENANT_ID__);
  151. });
  152. // $query = $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
  153. }
  154. $data = $query->where(function ($query) use ($keyword) {
  155. $query->orWhere('circle_name', 'like', '%' . $keyword . '%')
  156. ->orWhere('circle_introduce', 'like', '%' . $keyword . '%')
  157. ->orWhere('id', $keyword);
  158. })
  159. ->withCount('wxPosts as posts_count')
  160. ->simplePaginate($limit);
  161. if($data){
  162. $data->map(function ($item) use ($uid) {
  163. $item->is_follow = (new WxUserCircle())->isFollowCircle($uid, $item->id);
  164. $item->user_circle_count = CircleUtils::circleFollowCount($item->id);
  165. });
  166. return $data;
  167. }
  168. return null;
  169. }
  170. /**
  171. * 推荐
  172. * @return mixed
  173. */
  174. public static function recommendCircle()
  175. {
  176. return (new Model())->where('circle_state', 1)->where('is_top_recommend', 1)->withCount('wxPosts as posts_count')->orderBy('sort', 'desc')->limit(4)->get();
  177. }
  178. /**
  179. * 热门
  180. * @return mixed
  181. */
  182. public static function hotCircle()
  183. {
  184. return (new Model())->where('circle_state', 1)->where('is_hot', 1)->orderBy('sort', 'desc')->limit(12)->get();
  185. }
  186. /**
  187. * 最新
  188. * @return mixed
  189. */
  190. public static function newCircle()
  191. {
  192. return (new Model())->where('circle_state', 1)->where('circle_state', 0)->limit(12)->orderBy('id', 'desc')->get();
  193. }
  194. /**
  195. * 全部
  196. * @param $page
  197. * @return mixed
  198. */
  199. public static function listAll()
  200. {
  201. return (new Model())->where('circle_state', 1)->orderBy('id', 'desc')->get(['id','circle_name']);
  202. // return (new Model())->where('circle_state', 1)->where('circle_state', 0)->orderBy('id', 'desc')->get(['id','circle_name']);
  203. }
  204. /**
  205. * 全部
  206. * @param $page
  207. * @return mixed
  208. */
  209. public static function list($page)
  210. {
  211. return (new Model())->where('circle_state', 1)->where('circle_state', 0)->orderBy('id', 'desc')->paginate($page);
  212. }
  213. /**
  214. * 圈子文章组合(有的问题with limit)
  215. * @param $page
  216. * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection
  217. */
  218. public static function circleAndPost($limit = 10)
  219. {
  220. $data = (new Model())->where('circle_state', 1)
  221. ->withCount(['wxPosts as posts_count' => function ($query) {
  222. $query->where('is_examine', 1);
  223. }])
  224. ->orderBy('sort', 'desc')
  225. ->simplePaginate($limit);
  226. if($data){
  227. $data->map(function ($v, $k) {
  228. $data = WxPost::where('is_examine', 1)
  229. ->where('posts_state', 0)
  230. ->where('circle_id', $v->id)
  231. ->orderBy('id', 'desc')
  232. ->with(["user" => function ($query) {
  233. $query->select(['id', 'user_avatar']);
  234. }])->limit(3)
  235. ->get(['id', 'posts_content', 'user_id', 'circle_id']);
  236. $data->map(function ($v) {
  237. $v->commment_count = WxCommentRepositores::commentCount($v->id);
  238. // 这里可以直接截取
  239. $v->posts_content_raw = mb_substr(preg_replace("/<(img|video).*?src[^\'\"]+[\'\"]([^\"\']+)[^>]+>/is", '',$v->posts_content), 0, 30);
  240. });
  241. $v->wx_posts = $data;
  242. });
  243. return $data;
  244. }
  245. return null;
  246. }
  247. /**
  248. * 用户关注圈子
  249. * @param $user_id
  250. * @param $circle_id
  251. * @param null $payment_duration 日期时间字符串
  252. * @return bool
  253. */
  254. public static function userFollowCircle($user_id, $circle_id, $payment_duration = null)
  255. {
  256. $flag = 0;
  257. $model_obj = WxUserCircle::where('user_id', $user_id)->where('circle_id', $circle_id)->first();
  258. if($model_obj){
  259. if($model_obj->user_circle_state == 1){
  260. if($payment_duration){
  261. $flag = WxUserCircle::where('user_id', $user_id)->where('circle_id', $circle_id)->update( [ 'user_circle_state' => 0, 'payment_duration' => $payment_duration ]);
  262. }else{
  263. $flag = WxUserCircle::where('user_id', $user_id)->where('circle_id', $circle_id)->update( [ 'user_circle_state' => 0 ]);
  264. }
  265. }else{
  266. if($payment_duration){
  267. $flag = WxUserCircle::where('user_id', $user_id)->where('circle_id', $circle_id)->update( [ 'user_circle_state' => 0, 'payment_duration' => $payment_duration ]);
  268. }else{
  269. $flag = WxUserCircle::where('user_id', $user_id)->where('circle_id', $circle_id)->update( [ 'user_circle_state' => 1 ]);
  270. }
  271. }
  272. Cache::forget('circle:followCount:'.$circle_id);
  273. Cache::forget('circle:follow:users:'.$circle_id);
  274. UpdateCircleCountJob::dispatch($circle_id)->delay(now()->addSeconds(2));
  275. update_user_visit($user_id, 2, $circle_id);
  276. Cache::forget('user_circle_unread_count:'.$user_id);
  277. return $flag;
  278. }else{
  279. DB::beginTransaction();
  280. try {
  281. $model = new WxUserCircle();
  282. $model->user_id = $user_id;
  283. $model->circle_id = $circle_id;
  284. if($payment_duration){
  285. $model->payment_duration = $payment_duration;
  286. }
  287. $r = $model->save();
  288. if($r){
  289. $user = WxUser::where('id', $user_id)->first(FieldUtils::userInfoColums());
  290. $circle = WxCircle::where('id', $circle_id)->first(['id','user_id', 'circle_name']);
  291. Redis::sadd('realtime:others:set', json_encode([$circle['user_id'], 4, 1]));
  292. Redis::sadd('realtime:others:set', json_encode([$circle_id, 2, 1]));
  293. if($circle['user_id'] > 0){
  294. UserUtils::add_user_notice(5002, $circle['user_id'], '创建的'.env('circle_call', '圈子').'收获粉丝', '「<a href="/pages/user/user?id='.$user_id.'">'.$user['user_name'].'</a>」' . '关注了你创建的「' . '<a href="/pages/circle/list?id='.$circle['id'].'">'.$circle['circle_name'].'</a>' . '」圈子。', 100);
  295. }
  296. UserUtils::add_user_experience($user_id, 6);
  297. update_user_visit($user_id, 2, $circle_id);
  298. DB::commit();
  299. Cache::forget('circle:followCount:'.$circle_id);
  300. Cache::forget('circle:follow:users:'.$circle_id);
  301. UpdateCircleCountJob::dispatch($circle_id)->delay(now()->addSeconds(2));
  302. Cache::forget('user_circle_unread_count:'.$user_id);
  303. return true;
  304. }
  305. DB::rollBack();
  306. return false;
  307. } catch (\Exception $e) {
  308. DB::rollBack();
  309. _logger_(__file__, __line__, $e->getMessage());
  310. return false;
  311. }
  312. }
  313. }
  314. /**
  315. * 用户关注的圈子文章组合列表
  316. * @param int $limit
  317. * @return \Illuminate\Contracts\Pagination\Paginator
  318. */
  319. public static function userFollowCircleList($uid, $limit = 10)
  320. {
  321. $userFollowCircle = WxUserCircle::where('user_id', $uid)->get();
  322. if($userFollowCircle){
  323. $circle_id_arr = [];
  324. foreach ($userFollowCircle as $k => $v) {
  325. $circle_id_arr[] = $v['circle_id'];
  326. }
  327. $data = (new Model())->where('circle_state', 1)
  328. ->whereIn('id', $circle_id_arr)
  329. ->withCount(['wxPosts as posts_count' => function ($query) {
  330. $query->where('is_examine', 1);
  331. }])
  332. ->orderBy('sort', 'desc')
  333. ->simplePaginate($limit);
  334. $data->map(function ($v, $k) {
  335. $data = WxPost::where('is_examine', 1)
  336. ->where('posts_state', 0)
  337. ->where('circle_id', $v->id)
  338. ->orderBy('id', 'desc')
  339. ->with(["user" => function ($query) {
  340. $query->select(['id', 'user_avatar']);
  341. }])->limit(3)
  342. ->get(['id', 'posts_content', 'user_id', 'circle_id']);
  343. $data->map(function ($v) {
  344. $v->commment_count = WxCommentRepositores::commentCount($v->id);
  345. });
  346. $v->wx_posts = $data;
  347. });
  348. return $data;
  349. }
  350. return null;
  351. }
  352. /**
  353. * 获取圈子详细信息
  354. * @param $circle_id
  355. * @return mixed
  356. */
  357. public static function CircleInfo($circle_id)
  358. {
  359. $data = WxCircle::where('id', $circle_id)->first();
  360. if($data){
  361. if($data->circle_user_division > 0){
  362. $data->circle_user_division = $data->circle_user_division * 100;
  363. }
  364. if($data->circle_user_paycontent_division > 0){
  365. $data->circle_user_paycontent_division = $data->circle_user_paycontent_division * 100;
  366. }
  367. if($data){
  368. $data->append(['circle_user', 'circle_follow_count', 'circle_posts_count']);
  369. return $data;
  370. }
  371. }
  372. return null;
  373. }
  374. /**
  375. * 判断是否关注了该圈子
  376. */
  377. public static function isFollowCircle($uid, $circle_id = 0)
  378. {
  379. return WxUserCircle::where('user_id', $uid)
  380. ->where('circle_id', $circle_id)->where('user_circle_state', 0)->exists();
  381. }
  382. /**
  383. * 关注圈子
  384. * @param $uid
  385. * @param $circle_id
  386. * @return bool
  387. */
  388. public static function followCircle($uid, $circle_id)
  389. {
  390. $UserCircleModel = (new WxUserCircle());
  391. $UserCircleModel->user_id = $uid;
  392. $UserCircleModel->circle_id = $circle_id;
  393. return $UserCircleModel->save();
  394. }
  395. }