PostsRepositores.php 59 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683
  1. <?php
  2. namespace App\Http\Controllers\Api\Repositories;
  3. use App\Jobs\AttachIpAddressJob;
  4. use App\Jobs\Search\ElasticSearchBatchSyncJob;
  5. use App\Jobs\SubscribeMessageJob;
  6. use App\Models\Posts\WxComment;
  7. use App\Models\Posts\WxPostsFile;
  8. use App\Models\Posts\WxPostsPayContent;
  9. use App\Models\Shop\WxShopGoods;
  10. use App\Models\Posts\WxPostsSound;
  11. use App\Models\Posts\WxPostsField;
  12. use App\Wen\Utils\CircleUtils;
  13. use App\Wen\Utils\FieldUtils;
  14. use App\Wen\Utils\FileUtils;
  15. use App\Wen\Utils\ImageUtils;
  16. use App\Wen\Utils\PostUtils;
  17. use App\Wen\Utils\SearchUtils;
  18. use App\Wen\Utils\StrUtils;
  19. use App\Wen\Utils\UserUtils;
  20. use App\Wen\Utils\Utils;
  21. use App\Models\Posts\WxCollect;
  22. use App\Models\Posts\WxLike;
  23. use App\Models\Posts\WxPost;
  24. use App\Models\Posts\WxPost as Model;
  25. use App\Models\Posts\WxPostsAddress;
  26. use App\Models\Posts\WxPostsImg;
  27. use App\Models\Posts\WxPostsTag;
  28. use App\Models\Posts\WxPostsVideo;
  29. use App\Models\Posts\WxPostsVote;
  30. use App\Models\Posts\WxTag;
  31. use App\Models\Circle\WxCircle;
  32. use App\Models\WxExceptional;
  33. use App\Models\WxNotice;
  34. use App\Models\Posts\WxPostsGoods;
  35. use App\Models\WxSyncRelation;
  36. use App\Models\User\WxUser;
  37. use App\Models\User\WxUserFollow;
  38. use Illuminate\Support\Carbon;
  39. use Illuminate\Support\Facades\Cache;
  40. use Illuminate\Support\Facades\DB;
  41. use App\Wen\Utils\Settings;
  42. use Illuminate\Support\Facades\Redis;
  43. class PostsRepositores
  44. {
  45. /**
  46. * Model.
  47. *
  48. * @var string
  49. */
  50. protected $eloquentClass = Model::class;
  51. public static function add($uid, $is_examine, $posts_title, $contents, $circle_id, $tags, $goods, $images, $video, $address, $videoThumbUrl, $video_width, $video_height, $votes = [], $files = [], $sounds = [], $pay_content_id = 0, $device = '', $refer_id = 0, $contact_phone = '', $sph_obj = null, $useds = [], $bureaus = [], $is_anonymous = 0, $voter_id = 0,$photo_url='',$is_draft)
  52. {
  53. DB::beginTransaction();
  54. $user = UserUtils::get_cached_user($uid);
  55. $circle = null;
  56. if(_empty_($refer_id) && $circle_id){
  57. $circle = WxCircle::where('id', $circle_id)->first();
  58. }else{
  59. $circle_id = null;
  60. }
  61. if($sph_obj && is_array($sph_obj) && isset($sph_obj['type'])){
  62. }else{
  63. $sph_obj = null;
  64. }
  65. try {
  66. $addressId = 0;
  67. if (!_empty_($address) && _array_key($address, 'address_name', '')) {
  68. // 创建地址
  69. $addr = new WxPostsAddress([
  70. 'address_name' => $address['address_name'],
  71. 'address_detailed' => $address['address_detailed'],
  72. 'latitude' => $address['latitude'],
  73. 'longitude' => $address['longitude']
  74. ]);
  75. $addr->save();
  76. $addressId = $addr->id;
  77. }
  78. global $__MINI_GLOBAL_IP__,$__MINI_GLOBAL_TENANT_ID__;
  79. $timestamp = current_time();
  80. // 创建笔记
  81. $contents = trim($contents);
  82. $post_conetnt = _mini_phone( _mini_emoji( _mini_aite_replace( $contents ) ) );
  83. $post = new Model([
  84. 'posts_content' => $post_conetnt,
  85. 'user_id' => $uid,
  86. 'pay_content_id' => $pay_content_id > 0 ? $pay_content_id : 0,
  87. 'circle_id' => ($circle_id && $circle_id > 0) ? $circle_id : 0,
  88. 'circle_name' => ($circle && !_empty_(_array_key($circle, 'circle_name', null))) ? $circle['circle_name'] : '广场',
  89. 'address_id' => _empty_($addressId) ? 0 : $addressId,
  90. 'tags_id' => '0',
  91. 'weight' => $timestamp,
  92. 'last_reply_at' => $timestamp,
  93. 'is_draft' => $is_draft,
  94. ]);
  95. // print_r($post);exit;
  96. if(!_empty_($posts_title)){
  97. $post->posts_title = $posts_title;
  98. }
  99. $post->is_examine = $is_examine;
  100. if(!_empty_($refer_id)){
  101. $post->refer_id = $refer_id;
  102. }
  103. if($voter_id > 0){
  104. $post->voter_id = $voter_id;
  105. }
  106. if($device){
  107. $post->device = $device;
  108. }
  109. if($__MINI_GLOBAL_IP__){
  110. $post->ip = $__MINI_GLOBAL_IP__;
  111. }
  112. if($__MINI_GLOBAL_TENANT_ID__ > 0){
  113. $post->tenant_id = $__MINI_GLOBAL_TENANT_ID__;
  114. }
  115. if($sph_obj){
  116. $post->is_wechat_sph = true;
  117. }
  118. if(!_empty_($useds)){
  119. $post->useds = implode(',', $useds);
  120. }
  121. if($contact_phone){
  122. $post->has_fields = 1;
  123. }
  124. if($is_anonymous == 1){
  125. $post->is_anonymous = 1;
  126. }
  127. $post->save();
  128. $postId = $post->id;
  129. if($contact_phone){
  130. $post_field = new WxPostsField();
  131. $post_field->post_id = $postId;
  132. $post_field->contact_phone = $contact_phone;
  133. $post_field->save();
  134. }
  135. if($circle_id > 0){
  136. Redis::sadd('realtime:others:set', json_encode([$circle_id, 2, 10]));
  137. }
  138. Redis::sadd('realtime:others:set', json_encode([$uid, 4, 10]));
  139. if($pay_content_id > 0){
  140. $pay_r = WxPostsPayContent::where('id', $pay_content_id)->update(['post_id'=>$postId]);
  141. if(!$pay_r){
  142. WxPostsPayContent::where('id', $pay_content_id)->forceDelete();
  143. DB::rollBack();
  144. return 0;
  145. }
  146. }
  147. if($sph_obj){
  148. update_post_meta($postId, 'wechat_sph', $sph_obj, 'j');
  149. }
  150. // 图片组
  151. if (!_empty_($images)) {
  152. $postImage = [];
  153. foreach ($images as $k => $v) {
  154. if(_empty_(_array_key($v, 'url', ''))){
  155. continue;
  156. }
  157. $tmp_images = [];
  158. $tmp_images['posts_id'] = $postId;
  159. $tmp_images['user_id'] = $uid;
  160. $tmp_images['img_url'] = $v['url'];
  161. if(!StrUtils::endsWith($v['url'] ?? '', '.gif')){
  162. $img_info = ImageUtils::get_url_img_info($v['url']);
  163. if($img_info){
  164. $tmp_images['width'] = $img_info['width'];
  165. $tmp_images['height'] = $img_info['height'];
  166. }
  167. }else{
  168. $tmp_images['width'] = 0;
  169. $tmp_images['height'] = 0;
  170. }
  171. $postImage[] = $tmp_images;
  172. }
  173. if($postImage){
  174. $postImg = new WxPostsImg();
  175. $postImg->addAll($postImage);
  176. }
  177. }
  178. // print_r($photo_url);exit;
  179. // print_r('123');exit;
  180. if (!empty($photo_url)) {
  181. // print_r('123');exit;
  182. $postImages = new WxPostsImg();
  183. $post_img['posts_id'] =$postId;
  184. $post_img['user_id'] =$uid;
  185. $post_img['img_url'] =$photo_url;
  186. $postImages->posts_id = $postId;
  187. $postImages->user_id = $uid;
  188. $postImages->img_url = $photo_url;
  189. // $postImages->add($post_img);
  190. $postImages->save();
  191. }
  192. if(!_empty_($refer_id)){
  193. //转发评论
  194. $berefer_post = WxPost::find($refer_id);
  195. if($berefer_post){
  196. $CommentModel = new WxComment();
  197. $CommentModel->posts_id = $berefer_post->id;
  198. $CommentModel->posts_user_id = $berefer_post->user_id;
  199. $CommentModel->user_id = $uid;
  200. $CommentModel->user_name = $user['user_name'];
  201. $CommentModel->user_avatar = $user['user_avatar'];
  202. $CommentModel->comment_content = '<mini-icon name="mini-icon mini-fenxiang2"></mini-icon> '.$post_conetnt;
  203. $CommentModel->comment_img_url = '';
  204. $CommentModel->is_sticky = 0;
  205. $CommentModel->comment_state = 1;
  206. if($device){
  207. $CommentModel->device = $device;
  208. }
  209. if($__MINI_GLOBAL_IP__){
  210. $CommentModel->ip = $__MINI_GLOBAL_IP__;
  211. }
  212. $comment_r = $CommentModel->save();
  213. if($berefer_post->user_id != $uid){
  214. UserUtils::add_user_notice(2007, $berefer_post->user_id, '笔记被转发', '「<a href="/pages/user/user?id='.$user['id'].'">'.$user['user_name'].'</a>」' . '转发了您的笔记。', 102, $berefer_post->id);
  215. }
  216. $comment_count = WxCommentRepositores::commentCount($berefer_post->id) ?: 0;//评论数量
  217. $weight = WxPost::where('id', $berefer_post->id)->value('weight');
  218. $weight += ( Utils::getDecayCoefficient($comment_count, 5) * 1000);
  219. if($weight > time()){
  220. $weight = time();
  221. }
  222. WxPost::withoutSyncingToSearch(function () use ($berefer_post, $weight) {
  223. WxPost::where('id', $berefer_post->id)->update(['last_reply_at' => current_time(), 'weight' => timetostr($weight)]);
  224. });
  225. Cache::forget('post:commentCount:'.$berefer_post->id);
  226. }
  227. }
  228. // 话题
  229. if (!_empty_($tags)) {
  230. $postTag = [];
  231. $tagsIds = [];
  232. foreach ($tags as $k => $v) {
  233. $postTag[$k]['posts_id'] = $postId;
  234. $postTag[$k]['tags_id'] = $v['id'];
  235. $tagsIds[] = $v['id'];
  236. Redis::sadd('realtime:others:set', json_encode([$v['id'], 5, 10]));
  237. }
  238. $tags = new WxPostsTag();
  239. $tags->addAll($postTag);
  240. WxTag::whereIn('id', $tagsIds)->increment('tags_number');
  241. if($circle_id > 0){
  242. CircleUtils::add_circle_tags($circle_id, $tagsIds);
  243. }
  244. }
  245. // 商品
  246. if (!_empty_($goods)) {
  247. $postGoods = [];
  248. foreach ($goods as $k => $v) {
  249. $postGoods[$k]['posts_id'] = $postId;
  250. $postGoods[$k]['goods_id'] = $v['id'];
  251. Redis::sadd('realtime:others:set', json_encode([$v['id'], 3, 10]));
  252. }
  253. $goods = new WxPostsGoods();
  254. $goods->addAll($postGoods);
  255. }
  256. // 视频组
  257. if (!_empty_($video)) {
  258. $postVideoModel = new WxPostsVideo();
  259. $postVideoModel->user_id = $uid;
  260. $postVideoModel->posts_id = $postId;
  261. $postVideoModel->video_url = $video;
  262. $postVideoModel->video_thumb_url = $videoThumbUrl;
  263. $postVideoModel->video_width = $video_width;
  264. $postVideoModel->video_height = $video_height;
  265. $attachment = FileUtils::get_url_attach($video);
  266. if($attachment->state == 2){
  267. // 状态(0正常,1用户删除,2管理员下架, 3审核中 4冻结中 5已清理)
  268. $postVideoModel->posts_video_state = 5;
  269. }else if($attachment->state == 3 || $attachment->state == 4){
  270. $postVideoModel->posts_video_state = 4;
  271. }else if(in_array($attachment->cos_review, [3,4,5])){
  272. $postVideoModel->posts_video_state = 3;
  273. }
  274. $postVideoModel->save();
  275. }
  276. // 投票
  277. if(!_empty_($votes)){
  278. $vote = new WxPostsVote();
  279. $vote->post_id = $postId;
  280. foreach ([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] as $num){
  281. if(_array_key($votes, $num - 1, '')){
  282. $vote['option'.$num] = _array_key($votes, $num - 1, '');
  283. }
  284. }
  285. $vote->save();
  286. }
  287. if(!_empty_($files)){
  288. foreach ($files as $file){
  289. if($file['name'] && $file['url']){
  290. $file_model = new WxPostsFile();
  291. $file_model->name = $file['name'];
  292. $file_model->url = $file['url'];
  293. $file_model->size = _array_key($file, 'size', 0);
  294. $file_model->post_id = $postId;
  295. $file_model->save();
  296. }
  297. }
  298. }
  299. if(!_empty_($sounds)){
  300. foreach ($sounds as $sound){
  301. $sound_model = new WxPostsSound();
  302. $sound_model->name = $sound['name'];
  303. $sound_model->time = $sound['time'];
  304. $sound_model->url = $sound['url'];
  305. $sound_model->post_id = $postId;
  306. $sound_model->save();
  307. }
  308. }
  309. if(!_empty_($circle)){
  310. $pay_res = CircleUtils::user_can_publish($user, $circle, true);
  311. if($pay_res['code'] == 0){
  312. DB::rollBack();
  313. return 0;
  314. }
  315. }
  316. if($circle_id && $circle_id > 0){
  317. WxCircle::withoutSyncingToSearch(function () use ($circle_id){
  318. WxCircle::where('id', $circle_id)->update(['last_publish_at' => current_time()]);
  319. });
  320. }
  321. Redis::sadd('realtime:post:set', $postId);
  322. if($__MINI_GLOBAL_IP__){
  323. AttachIpAddressJob::dispatch(1, $postId)->delay(2);
  324. }
  325. DB::commit();
  326. return $postId;
  327. } catch (\Exception $e) {
  328. DB::rollBack();
  329. _logger_(__file__, __line__, $e->getMessage());
  330. // _logger_(__file__, __line__, $e->getTrace());
  331. return 0;
  332. }
  333. }
  334. /**
  335. * @param $uid 'uid'
  336. * @param $contents 'content'
  337. * @param $circle_id 'id'
  338. * @param $tag_ids [id1,id2,id3]
  339. * @param $good_ids [id1,id2,id3]
  340. * @param $image_urls 'url1,url2,url3'
  341. * @param $video_url 'url'
  342. * @param $address_id 'id'
  343. * @return bool|string
  344. */
  345. public static function admin_add($domain, $uid, $title, $contents, $circle_id, $tag_ids, $good_ids, $image_urls, $video_url, $address_id, $external_id = '', $date = '', $tenant_id = 0)
  346. {
  347. DB::beginTransaction();
  348. try {
  349. if($domain){
  350. $post_id = WxSyncRelationRepositories::wx_post_id($domain, $external_id);
  351. if($post_id){
  352. return $post_id;
  353. }
  354. }
  355. $timestamp = current_time();
  356. // 圈子名称
  357. if($circle_id > 0){
  358. $circle = WxCircle::where('id', $circle_id)->first();
  359. if(_empty_($circle)){
  360. _logger_(__file__, __line__, '同步失败,不存在ID为'.$circle_id.'的圈子');
  361. return 0;
  362. }
  363. }else{
  364. $circle['circle_name'] = '广场';
  365. }
  366. $is_examine = 1;
  367. $contents = trim($contents);
  368. // 创建笔记
  369. $post = new Model([
  370. 'posts_title' => $title ?: '',
  371. 'posts_content' =>_mini_phone( _mini_emoji( _mini_aite_replace($contents) ) ),
  372. 'user_id' => $uid,
  373. 'circle_id' => $circle_id,
  374. 'circle_name' => $circle['circle_name'],
  375. 'address_id' => _empty_($address_id) ? 0 : $address_id,
  376. 'tags_id' => 0,
  377. 'device' => ['app', 'mp'][(int)mini_rand(0,1)],
  378. 'is_examine'=>1,
  379. 'weight' => $timestamp,
  380. 'last_reply_at' => $timestamp
  381. ]);
  382. if($date){
  383. $post->updated_at = strtotime($date);
  384. $post->created_at = strtotime($date);
  385. $post->weight = $date;
  386. $post->last_reply_at = $date;
  387. }
  388. if($tenant_id > 0){
  389. $post->tenant_id = $tenant_id;
  390. }
  391. $post->save();
  392. $postId = $post->id;
  393. Redis::sadd('realtime:others:set', json_encode([$circle_id, 2, 10]));
  394. Redis::sadd('realtime:others:set', json_encode([$uid, 4, 10]));
  395. // 视频组
  396. if (!_empty_($video_url)) {
  397. $videoThumbUrl = null;
  398. if(!_empty_($image_urls)){
  399. $videoThumbUrl = explode(',', $image_urls)[0];
  400. }
  401. $postVideoModel = new WxPostsVideo();
  402. $postVideoModel->user_id = $uid;
  403. $postVideoModel->posts_id = $postId;
  404. $postVideoModel->video_url = stripslashes($video_url);
  405. $postVideoModel->video_thumb_url = $videoThumbUrl;
  406. $postVideoModel->video_width = null;
  407. $postVideoModel->video_height = null;
  408. $postVideoModel->save();
  409. }else{
  410. // 图片组
  411. if (!_empty_($image_urls)) {
  412. $postImage = [];
  413. $k = 0;
  414. $image_urls = explode(',', $image_urls);
  415. foreach ($image_urls as $img_url) {
  416. if(_empty_($img_url)){
  417. continue;
  418. }
  419. $postImage[$k]['posts_id'] = $postId;
  420. $postImage[$k]['user_id'] = $uid;
  421. $postImage[$k]['img_url'] = $img_url;
  422. if(Cache::has($img_url)){
  423. $img_info = json_decode(Cache::get($img_url), true);
  424. $postImage[$k]['width'] = $img_info['width'];
  425. $postImage[$k]['height'] = $img_info['height'];
  426. Cache::forget($img_url);
  427. }
  428. $k ++;
  429. }
  430. if($postImage){
  431. $postImg = new WxPostsImg();
  432. $postImg->addAll($postImage);
  433. }
  434. }
  435. }
  436. // 话题
  437. if (!_empty_($tag_ids)) {
  438. $postTag = [];
  439. $tagsIds = [];
  440. $k = 0;
  441. foreach ($tag_ids as $tag_id) {
  442. if(_empty_($tag_id)){
  443. continue;
  444. }
  445. $postTag[$k]['posts_id'] = $postId;
  446. $postTag[$k]['tags_id'] = $tag_id;
  447. $tagsIds[] = $tag_id;
  448. Redis::sadd('realtime:others:set', json_encode([$tag_id, 5, 10]));
  449. $k++;
  450. }
  451. if($postTag){
  452. $tags = new WxPostsTag();
  453. $tags->addAll($postTag);
  454. WxTag::whereIn('id', $tagsIds)->increment('tags_number');
  455. if($circle_id > 0){
  456. CircleUtils::add_circle_tags($circle_id, $tagsIds);
  457. }
  458. }
  459. }
  460. // 商品
  461. if (!_empty_($good_ids)) {
  462. $postGoods = [];
  463. $k = 0;
  464. foreach ($good_ids as $good_id) {
  465. if(_empty_($good_id)){
  466. continue;
  467. }
  468. $postGoods[$k]['posts_id'] = $postId;
  469. $postGoods[$k]['goods_id'] = $good_id;
  470. Redis::sadd('realtime:others:set', json_encode([$good_id, 3, 10]));
  471. $k ++;
  472. }
  473. if($postGoods){
  474. $goods = new WxPostsGoods();
  475. $goods->addAll($postGoods);
  476. }
  477. }
  478. // 圈主
  479. // 待审核
  480. if($circle_id > 0){
  481. if($is_examine == 0){
  482. //给对应圈子发送待审核信息
  483. UserUtils::assistant_notice($circle['user_id'], '您创建的圈子「' . '<a href="/pages/circle/list?id='.$circle['id'].'">'.$circle['circle_name'].'</a>' . '」有一篇新的内容等待您去审核哦,请务必在24小时内进行处理。');
  484. }else{
  485. //给对应圈子圈主发送新内容信息
  486. UserUtils::assistant_notice($circle['user_id'], '您创建的圈子「' . '<a href="/pages/circle/list?id='.$circle['id'].'">'.$circle['circle_name'].'</a>' . '」有一篇新的内容发布,您要好好把关哦。');
  487. }
  488. }
  489. if($external_id && $domain){
  490. $sync = new WxSyncRelation();
  491. $sync->domain = $domain;
  492. $sync->type = 'post';
  493. $sync->inner_id = $postId;
  494. $sync->external_id = $external_id;
  495. $sync->status = 1;
  496. $sync->save();
  497. }
  498. Redis::sadd('realtime:post:set', $postId);
  499. DB::commit();
  500. return $postId;
  501. } catch (\Exception $e) {
  502. DB::rollBack();
  503. _logger_(__file__, __line__, $e->getMessage());
  504. return 0;
  505. }
  506. }
  507. /**
  508. * 推荐的笔记列表
  509. * @param $uid
  510. * @param int $limit
  511. * @return mixed
  512. */
  513. public static function list($uid, $limit = 10, $is_waterfall = false, $city = '')
  514. {
  515. global $__MINI_GLOBAL_TENANT_ID__,$__MINI_GLOBAL_DEVICE__,$__MINI_GLOBAL_MODE__;
  516. $sorts = Settings::get('app_index_list_sort', ['weight', 'created_at', 'id'], true);
  517. $not_list_circles = explode(',', Settings::get('app_index_not_list_circles', '', true));
  518. $not_like_post_set = get_user_meta($uid, 'feedback:notlike:post:set', 'j');
  519. $not_like_user_set = get_user_meta($uid, 'feedback:notlike:user:set', 'j');
  520. if(_empty_($city) || $city == '全国'){
  521. $city = '';
  522. }
  523. $data = (new Model())
  524. ->where('is_examine', 1)
  525. ->where('posts_state', 0)
  526. ->orderBy('is_sticky', 'desc');
  527. $data = $data->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
  528. if(!_empty_($not_list_circles)){
  529. $data = $data->whereNotIn('circle_id', $not_list_circles);
  530. }
  531. if(!_empty_($not_like_user_set)){
  532. $data = $data->whereNotIn('user_id', $not_like_user_set);
  533. }
  534. if(!_empty_($not_like_post_set)){
  535. $data = $data->whereNotIn('id', $not_like_post_set);
  536. }
  537. // 控制视频隐藏
  538. if($__MINI_GLOBAL_DEVICE__ != 'mp'){
  539. global $__MINI_GLOBAL_FRONT_VERSION__;
  540. // todo: 临时
  541. if($__MINI_GLOBAL_FRONT_VERSION__ >= '1.2.2.24'){
  542. }else{
  543. $data = $data->where('is_wechat_sph', 0);
  544. }
  545. }
  546. if($__MINI_GLOBAL_MODE__ == 'examine'){
  547. $data = $data->where('post_type', '<>', 'video');
  548. }
  549. if($city){
  550. if(StrUtils::endsWith($city, '市')){
  551. $data = $data->where('city', $city);
  552. }else{
  553. $data = $data->where('city', $city.'市');
  554. }
  555. }
  556. if($sorts){
  557. foreach ($sorts as $sort_){
  558. if(StrUtils::startsWith($sort_, 'rand')){
  559. if(StrUtils::startsWith($sort_, 'rand_new')){
  560. $number = explode('_', $sort_)[2];
  561. $the_base_id = Cache::remember('posts:new:'.$number, 3600 * 5, function () use ($number){
  562. $base_id = WxPost::where('is_examine', 1)->where('posts_state', 0)->orderBy('id', 'desc')->skip($number)->value('id');
  563. return $base_id > 0 ? $base_id : 0;
  564. });
  565. $data = $data->where('id', '>=', $the_base_id)->inRandomOrder();
  566. break;
  567. }else{
  568. $days = explode('_', $sort_)[1];
  569. $data = $data->where('created_at', '>=', Carbon::now()->subDays($days))->inRandomOrder();
  570. break;
  571. }
  572. }
  573. $data = $data->orderBy($sort_, 'desc');
  574. }
  575. }else{
  576. $data = $data->orderBy('id', 'desc');
  577. }
  578. $data = $data->simplePaginate($limit, FieldUtils::postInfoColums());
  579. if($is_waterfall){
  580. PostUtils::reset_loop();
  581. $data->map(function ($v, $k) use ($uid){
  582. return PostUtils::WaterfallProcess($k, $v, 1);
  583. });
  584. }else{
  585. $data = self::postsParame($data, $uid,1);//文章详情
  586. }
  587. return $data;
  588. }
  589. /**
  590. * 我关注的笔记列表
  591. * @param $uid
  592. * @param int $limit
  593. * @return mixed
  594. */
  595. public static function followPosts($uid, $limit = 10, $is_waterfall = false)
  596. {
  597. $userFollowIds = WxUserFollow::where('user_id', $uid)->pluck('user_follow_id');
  598. global $__MINI_GLOBAL_TENANT_ID__;
  599. $query = WxPost::where('is_examine', 1)
  600. ->where('posts_state', 0)
  601. ->whereIn('user_id', $userFollowIds)->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
  602. // 控制视频隐藏
  603. global $__MINI_GLOBAL_DEVICE__,$__MINI_GLOBAL_MODE__;
  604. if($__MINI_GLOBAL_DEVICE__ != 'mp'){
  605. global $__MINI_GLOBAL_FRONT_VERSION__;
  606. // todo: 临时
  607. if($__MINI_GLOBAL_FRONT_VERSION__ >= '1.2.2.24'){
  608. }else {
  609. $query = $query->where('is_wechat_sph', 0);
  610. }
  611. }
  612. if($__MINI_GLOBAL_MODE__ == 'examine'){
  613. $query = $query->where('post_type', '<>', 'video');
  614. }
  615. $data = $query->orderBy('id', 'desc')
  616. ->simplePaginate($limit, FieldUtils::postInfoColums());
  617. if($is_waterfall){
  618. PostUtils::reset_loop();
  619. $data->map(function ($v, $k) use ($uid){
  620. return PostUtils::WaterfallProcess($k, $v, 1);
  621. });
  622. }else{
  623. $data = self::postsParame($data, $uid, 1);//文章详情
  624. }
  625. return $data;
  626. }
  627. /**
  628. * 热榜的笔记列表
  629. * @param $uid
  630. * @param int $limit
  631. * @return mixed
  632. */
  633. public static function hotPosts($uid, $limit = 10, $is_waterfall = false, $is_mutisite = false)
  634. {
  635. global $__MINI_GLOBAL_DEVICE__,$__MINI_GLOBAL_MODE__, $__MINI_GLOBAL_TENANT_ID__;
  636. $query = (new Model())
  637. ->where('is_examine', 1)
  638. ->where('posts_state', 0);
  639. if(!$is_mutisite){
  640. $query = $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
  641. }
  642. // 控制视频隐藏
  643. if($__MINI_GLOBAL_DEVICE__ != 'mp'){
  644. global $__MINI_GLOBAL_FRONT_VERSION__;
  645. // todo: 临时
  646. if($__MINI_GLOBAL_FRONT_VERSION__ >= '1.2.2.24'){
  647. }else {
  648. $query = $query->where('is_wechat_sph', 0);
  649. }
  650. }
  651. if($__MINI_GLOBAL_MODE__ == 'examine'){
  652. $query = $query->where('post_type', '<>', 'video');
  653. }
  654. if(true){
  655. $data = $query->orderBy('degree', 'desc')->orderBy('created_at', 'desc')
  656. ->simplePaginate($limit, FieldUtils::postInfoColums());
  657. }else{
  658. $data = $query->withCount('like as like_count')
  659. ->orderBy('like_count', 'desc')
  660. ->simplePaginate($limit, FieldUtils::postInfoColums());
  661. }
  662. if($data){
  663. if($is_mutisite){
  664. PostUtils::$force_show_multi_site = true;
  665. }
  666. if($is_waterfall){
  667. PostUtils::reset_loop();
  668. $data->map(function ($v, $k) use ($uid){
  669. return PostUtils::WaterfallProcess($k, $v, 1);
  670. });
  671. }else{
  672. $data = self::postsParame($data, $uid, 1);//文章详情
  673. }
  674. return $data;
  675. }
  676. return null;
  677. }
  678. public static function getPostTags($post_id){
  679. if(_empty_($post_id)){
  680. return null;
  681. }
  682. return Cache::remember('get:post:tags:'.$post_id, 3600, function () use ($post_id){
  683. $tagsIds = WxPostsTag::where('posts_id', $post_id)->pluck('tags_id');//话题ID列表
  684. if($tagsIds){
  685. return WxTag::whereIn('id', $tagsIds)->get(['tags_name', 'id']);//话题列表
  686. }
  687. return null;
  688. });
  689. }
  690. public static function getPostGoods($post_id){
  691. if(_empty_($post_id)){
  692. return null;
  693. }
  694. return Cache::remember('get:post:goods:'.$post_id, 3600, function () use ($post_id){
  695. $goodsIds = WxPostsGoods::where([['posts_id','=', $post_id],['type', '=', 0]])->pluck('goods_id');//商品ID列表
  696. if($goodsIds){
  697. return WxShopGoods::whereIn('id', $goodsIds)->get(['id', 'pic', 'name', 'credit_type', 'intro', 'price', 'vip_price', 'tk_platform_id', 'buys']);//商品列表
  698. }
  699. return null;
  700. });
  701. }
  702. public static function getPostFiles($post_id){
  703. if(_empty_($post_id)){
  704. return null;
  705. }
  706. return Cache::remember('get:post:files:'.$post_id, 3600, function () use ($post_id){
  707. return WxPostsFile::where('post_id', $post_id)->get();
  708. });
  709. }
  710. public static function getPostSounds($post_id){
  711. if(_empty_($post_id)){
  712. return null;
  713. }
  714. return Cache::remember('get:post:sounds:'.$post_id, 3600, function () use ($post_id){
  715. return WxPostsSound::where('post_id', $post_id)->get();
  716. });
  717. }
  718. /**
  719. * 板块推荐的笔记列表
  720. * @param $uid
  721. * @param int $limit
  722. * @return mixed
  723. */
  724. public static function getListByPlate($uid, $plate_id, $limit = 6)
  725. {
  726. global $__MINI_GLOBAL_DEVICE__,$__MINI_GLOBAL_MODE__;
  727. $circleIds = WxCircle::where('plate_id', $plate_id)->pluck('id');
  728. $query = (new Model())
  729. ->where('is_examine', 1)
  730. ->where('posts_state', 0);
  731. // 控制视频隐藏
  732. if($__MINI_GLOBAL_DEVICE__ != 'mp'){
  733. global $__MINI_GLOBAL_FRONT_VERSION__;
  734. // todo: 临时
  735. if($__MINI_GLOBAL_FRONT_VERSION__ >= '1.2.2.24'){
  736. }else {
  737. $query = $query->where('is_wechat_sph', 0);
  738. }
  739. }
  740. if($__MINI_GLOBAL_MODE__ == 'examine'){
  741. $query = $query->where('post_type', '<>', 'video');
  742. }
  743. $data = $query->whereIn('circle_id', $circleIds)
  744. ->orderBy('id', 'desc')
  745. ->simplePaginate($limit);
  746. $data = self::postsParame($data, $uid, 1);//文章详情
  747. return $data;
  748. }
  749. /**
  750. * 点赞
  751. */
  752. public static function addLike($uid, $posts_id)
  753. {
  754. $like_count = PostsRepositores::likeCont($posts_id);
  755. $posts_user_id = WxPost::where('id', $posts_id)->pluck('user_id')->first();
  756. $isExists = WxLike::where('posts_user_id', $posts_user_id)
  757. ->where('posts_id', $posts_id)
  758. ->where('user_id', $uid)
  759. ->exists();
  760. if (!$isExists) {
  761. // 点赞
  762. $wxLike = new WxLike();
  763. $wxLike->posts_user_id = $posts_user_id;
  764. $wxLike->posts_id = $posts_id;
  765. $wxLike->user_id = $uid;
  766. $wxLike->save();
  767. $weight = WxPost::where('id', $posts_id)->value('weight');
  768. $weight += ( Utils::getDecayCoefficient($like_count, 10) * 400);
  769. if($weight > time()){
  770. $weight = time();
  771. }
  772. WxPost::withoutSyncingToSearch(function () use ($posts_id, $weight){
  773. WxPost::where('id', $posts_id)->update(['weight'=>timetostr($weight)]);
  774. });
  775. $circle_id = WxPost::where('id', $posts_id)->value('circle_id');
  776. $circle_user_id = WxCircle::where('id', $circle_id)->value('user_id');
  777. Redis::sadd('realtime:others:set', json_encode([$circle_id, 2, 1]));
  778. Redis::sadd('realtime:others:set', json_encode([$posts_user_id, 4, 1]));
  779. if($circle_user_id){
  780. Redis::sadd('realtime:others:set', json_encode([$circle_user_id, 4, 1]));
  781. }
  782. $tagsIds = WxPostsTag::where('posts_id', $posts_id)->pluck('tags_id');//话题ID列表
  783. if($tagsIds){
  784. foreach ($tagsIds as $tag_id){
  785. Redis::sadd('realtime:others:set', json_encode([$tag_id, 5, 1]));
  786. }
  787. }
  788. $user = UserUtils::get_cached_user($uid);
  789. if($user['id'] != $posts_user_id){
  790. UserUtils::add_user_notice(2003, $posts_user_id, '收到了一个喜欢', '您的笔记收到了「' . '<a href="/pages/user/user?id='.$user['id'].'">'.$user['user_name'].'</a>' . '」的喜欢。', 101, $posts_id);
  791. }
  792. UserUtils::add_user_experience($user['id'], 3);
  793. SubscribeMessageJob::dispatch('beliked', $wxLike->id);
  794. } else {
  795. $weight = WxPost::where('id', $posts_id)->value('weight');
  796. $weight -= ( Utils::getDecayCoefficient($like_count, 10) * 400);
  797. if($weight > time()){
  798. $weight = time();
  799. }
  800. WxPost::withoutSyncingToSearch(function () use ($posts_id, $weight){
  801. WxPost::where('id', $posts_id)->update(['weight'=>timetostr($weight)]);
  802. });
  803. // 取消点赞
  804. (new WxLike())->where('posts_user_id', $posts_user_id)
  805. ->where('posts_id', $posts_id)
  806. ->where('user_id', $uid)
  807. ->delete();
  808. (new WxNotice())->where('posts_id', $posts_id)
  809. ->where('user_id', $posts_user_id)
  810. ->where('notice_type', 2)
  811. ->delete();
  812. }
  813. update_user_visit($uid, 1, $posts_id);
  814. Cache::forget('posts:likeCont:'.$posts_id);
  815. Cache::forget('user:beliked:count:'.$posts_user_id);
  816. Cache::forget($uid.':like:post:'.$posts_id);
  817. Redis::sadd('realtime:post:set', $posts_id);
  818. }
  819. /**
  820. * 收藏
  821. */
  822. public static function addCollect($uid, $posts_id)
  823. {
  824. $posts_user_id = WxPost::where('id', $posts_id)->value('user_id');
  825. $isExists = WxCollect::where('posts_user_id', $posts_user_id)
  826. ->where('posts_id', $posts_id)
  827. ->where('user_id', $uid)
  828. ->exists();
  829. if (!$isExists) {
  830. // 收藏
  831. $wxLike = new WxCollect();
  832. $wxLike->posts_user_id = $posts_user_id;
  833. $wxLike->posts_id = $posts_id;
  834. $wxLike->user_id = $uid;
  835. $wxLike->save();
  836. $user = UserUtils::get_cached_user($uid);
  837. $circle_id = WxPost::where('id', $posts_id)->value('circle_id');
  838. $circle_user_id = WxCircle::where('id', $circle_id)->value('user_id');
  839. Redis::sadd('realtime:others:set', json_encode([$circle_id, 2, 1]));
  840. Redis::sadd('realtime:others:set', json_encode([$posts_user_id, 4, 1]));
  841. if($circle_user_id){
  842. Redis::sadd('realtime:others:set', json_encode([$circle_user_id, 4, 1]));
  843. }
  844. $tagsIds = WxPostsTag::where('posts_id', $posts_id)->pluck('tags_id');//话题ID列表
  845. if($tagsIds){
  846. foreach ($tagsIds as $tag_id){
  847. Redis::sadd('realtime:others:set', json_encode([$tag_id, 5, 1]));
  848. }
  849. }
  850. if($posts_user_id != $user['id']){
  851. UserUtils::add_user_notice(2006, $posts_user_id, '收到了一个收藏', '您的笔记被「' . '<a href="/pages/user/user?id='.$user['id'].'">'.$user['user_name'].'</a>' . '」收藏啦!', 101, $posts_id);
  852. UserUtils::add_user_experience($user['id'], 4);
  853. }
  854. } else {
  855. // 取消收藏
  856. (new WxCollect())->where('posts_user_id', $posts_user_id)
  857. ->where('posts_id', $posts_id)
  858. ->where('user_id', $uid)
  859. ->delete();
  860. (new WxNotice())->where('posts_id', $posts_id)
  861. ->where('user_id', $posts_user_id)
  862. ->where('notice_type', 3)
  863. ->delete();
  864. }
  865. Redis::sadd('realtime:post:set', $posts_id);
  866. Cache::forget('user:becollected:count:'.$posts_user_id);
  867. Cache::forget('post:becollected:count:'.$posts_id);
  868. Cache::forget($uid.':collect:post:'.$posts_id);
  869. }
  870. public static function addBlur($posts_id){
  871. $post = WxPost::find($posts_id);
  872. if($post){
  873. if($post->is_blur){
  874. $post->is_blur = 0;
  875. return $post->save();
  876. }else{
  877. $post->is_blur = 1;
  878. return $post->save();
  879. }
  880. }
  881. return false;
  882. }
  883. public static function addSticky($scene, $posts_id){
  884. if($scene == 1 || $scene == 10 || $scene == 9){
  885. $post = WxPost::find($posts_id);
  886. if($post){
  887. if($post->is_sticky){
  888. return WxPost::where('id', $posts_id)->update([
  889. 'is_sticky' => 0
  890. ]);
  891. }else{
  892. return WxPost::where('id', $posts_id)->update([
  893. 'is_sticky' => 1
  894. ]);
  895. }
  896. }
  897. }else if($scene == 5 || $scene == 8){
  898. $user_id = WxPost::where('id', $posts_id)->value('user_id');
  899. if($user_id){
  900. $sticky_post = get_user_meta($user_id, 'sticky', 'n');
  901. if($sticky_post == $posts_id){
  902. // 取消置顶
  903. $posts_id = 0;
  904. }
  905. if(update_user_meta($user_id, 'sticky', $posts_id, 'n')){
  906. return true;
  907. }
  908. }
  909. }else if( $scene == 6 || $scene == 60001 ){
  910. $circle_id = WxPost::where('id', $posts_id)->value('circle_id');
  911. if($circle_id){
  912. if($scene == 60001){
  913. $sticky_posts = _empty_default_(get_circle_meta($circle_id, 'sticky_notice_list', 'j'), []);
  914. $sticky_posts = array_values($sticky_posts);
  915. $flag = -1;
  916. if($sticky_posts){
  917. _logger_(__file__, __line__, $sticky_posts);
  918. for ($i = 0; $i < count($sticky_posts); $i++){
  919. if($sticky_posts[$i] == $posts_id){
  920. $flag = 1;
  921. unset($sticky_posts[$i]);
  922. break;
  923. }
  924. }
  925. }
  926. if($flag == -1){
  927. $sticky_posts[] = $posts_id;
  928. }
  929. $sticky_posts = array_unique($sticky_posts);
  930. if(update_circle_meta($circle_id, 'sticky_notice_list', $sticky_posts, 'j')){
  931. return true;
  932. }
  933. }else{
  934. $sticky_post = get_circle_meta($circle_id, 'sticky', 'n');
  935. if($sticky_post == $posts_id){
  936. // 取消置顶
  937. $posts_id = 0;
  938. }
  939. if(update_circle_meta($circle_id, 'sticky', $posts_id, 'n')){
  940. return true;
  941. }
  942. }
  943. }
  944. }
  945. return false;
  946. }
  947. /**
  948. * 关注
  949. * @param $uid
  950. * @param $user_follow_id
  951. */
  952. public static function followUser($uid, $user_follow_id)
  953. {
  954. $isExists = WxUserFollow::where('user_follow_id', $user_follow_id)
  955. ->where('user_id', $uid)
  956. ->exists();
  957. if (!$isExists) {
  958. // 不能关注自己
  959. if ($user_follow_id != $uid) {
  960. // 关注
  961. $wxLike = new WxUserFollow();
  962. $wxLike->user_follow_id = $user_follow_id;
  963. $wxLike->user_id = $uid;
  964. $wxLike->save();
  965. }
  966. } else {
  967. // 取消关注
  968. (new WxUserFollow())->where('user_follow_id', $user_follow_id)
  969. ->where('user_id', $uid)
  970. ->delete();
  971. }
  972. }
  973. /**
  974. * 删除笔记
  975. */
  976. public static function deletePosts($posts_id, $posts_state = 1)
  977. {
  978. DB::beginTransaction();
  979. try {
  980. // 删除文章(真删)
  981. // $addressId = WxPost::where('id', $posts_id)->pluck('address_id')->first();
  982. // WxPost::destroy($posts_id);
  983. // WxPostsAddress::where('id', $addressId)->delete();
  984. // WxPostsImg::where('posts_id', $posts_id)->delete();
  985. // WxPostsVideo::where('posts_id', $posts_id)->delete();
  986. // WxPostsTag::where('posts_id', $posts_id)->delete();
  987. // 删除文章(假删)
  988. $post = WxPost::find($posts_id);
  989. if($post){
  990. if($post->circle_id && $post->circle_id > 0){
  991. $sticky_post1 = get_circle_meta($post->circle_id, 'sticky', 'n');
  992. if($sticky_post1 == $posts_id){
  993. update_circle_meta($post->circle_id, 'sticky', 0, 'n');
  994. }
  995. $sticky_posts2 = _empty_default_(get_circle_meta($post->circle_id, 'sticky_notice_list', 'j'), []);
  996. $sticky_posts2 = array_values($sticky_posts2);
  997. $flag = -1;
  998. if($sticky_posts2){
  999. for ($i = 0; $i < count($sticky_posts2); $i++){
  1000. if($sticky_posts2[$i] == $posts_id){
  1001. $flag = 1;
  1002. unset($sticky_posts2[$i]);
  1003. break;
  1004. }
  1005. }
  1006. }
  1007. update_circle_meta($post->circle_id, 'sticky_notice_list', $sticky_posts2, 'j');
  1008. }
  1009. // 主页置顶
  1010. $sticky_post3 = get_user_meta($post->user_id, 'sticky', 'n');
  1011. if($sticky_post3 == $posts_id){
  1012. update_user_meta($post->user_id, 'sticky', 0, 'n');
  1013. }
  1014. }
  1015. WxPost::where('id', $posts_id)->update(['posts_state' => $posts_state]);
  1016. Db::commit();
  1017. return true;
  1018. } catch (\Exception $e) {
  1019. DB::rollBack();
  1020. _logger_(__file__, __line__, $e->getMessage());
  1021. return false;
  1022. }
  1023. }
  1024. /**
  1025. * 0:我发布的,1: 我收藏的;2:我喜欢的 3:我充电的
  1026. * @param $uid
  1027. * @param int $limit
  1028. * @return mixed
  1029. */
  1030. public static function myPosts($uid, $limit = 10, $type = 0, $orderBy = 'id', $order = 'desc')
  1031. {
  1032. if ($type == 'post') {
  1033. return self::mySendPosts($uid, $limit);
  1034. } elseif ($type == 'collected') {
  1035. return self::myCollectPosts($uid, $limit);
  1036. } elseif ($type == 'liked') {
  1037. return self::myLikePosts($uid, $limit);
  1038. } elseif ($type == 'exceptionaled') {
  1039. return self::myExceptionalPosts($uid, $limit);
  1040. } elseif ($type == 'voted') {
  1041. return self::myVotePosts($uid, $limit);
  1042. } elseif ($type == 'shop') {
  1043. return self::myShopGoods($uid, $limit, $orderBy, $order);
  1044. }
  1045. }
  1046. public static function myShopGoods($uid, $limit = 10, $orderBy = 'id', $order = 'desc'){
  1047. $shop_id = WxUser::where('id', $uid)->value('shop_id');
  1048. if(UserUtils::is_mini_supder_admin($uid)){
  1049. $data = WxShopGoods::whereIn('shop_id', [$shop_id, 0])->where('state', 1)->orderBy($orderBy, $order)->paginate($limit);
  1050. }else{
  1051. $data = WxShopGoods::where('shop_id', $shop_id)->where('state', 1)->orderBy($orderBy, $order)->paginate($limit);
  1052. }
  1053. if($data){
  1054. return $data;
  1055. }
  1056. return null;
  1057. }
  1058. /** 我发起的投票的帖子
  1059. * @param $uid
  1060. * @param int $limit
  1061. * @return mixed
  1062. */
  1063. public static function myVotePosts($uid, $limit = 10){
  1064. $votedPostIdsSubQuery = DB::table('wx_posts_vote')
  1065. ->where('user_id', $uid)
  1066. ->select('post_id');
  1067. $data = WxPost::whereIn('id', $votedPostIdsSubQuery)
  1068. ->paginate($limit);
  1069. if($data){
  1070. $data = self::postsParame($data, $uid,5);//文章详情
  1071. return $data;
  1072. }
  1073. return null;
  1074. }
  1075. /**
  1076. * 我发的笔记
  1077. * @return mixed
  1078. */
  1079. public static function mySendPosts($uid, $limit = 10)
  1080. {
  1081. global $__MINI_GLOBAL_CURRENT_USER_ID__;
  1082. global $__MINI_GLOBAL_DEVICE__,$__MINI_GLOBAL_MODE__,$__MINI_GLOBAL_SCENE__;
  1083. $query = (new Model())
  1084. ->withCount('like as like_count');
  1085. $uid_ = $uid;
  1086. if($uid < 0){
  1087. $uid_ = $uid;
  1088. $uid = _abs($uid);
  1089. $query = $query->where('is_anonymous', 1);
  1090. }else{
  1091. if($uid == $__MINI_GLOBAL_CURRENT_USER_ID__ && $__MINI_GLOBAL_SCENE__ == 5){
  1092. }else{
  1093. $query = $query->where('is_anonymous', 0);
  1094. }
  1095. }
  1096. if($uid == $__MINI_GLOBAL_CURRENT_USER_ID__){
  1097. if($__MINI_GLOBAL_SCENE__ == 8){
  1098. $query = $query->where('is_examine', 1);
  1099. }
  1100. }else{
  1101. $query = $query->where('is_examine', 1);
  1102. }
  1103. $is_waterfall = Settings::get('app_user_list_style', 0) == 1;
  1104. $user_setting_style = mini_current_user(2, 'diy_scene_8_post_list_style');
  1105. if($user_setting_style){
  1106. if($user_setting_style != 1){
  1107. if($user_setting_style == 3){
  1108. $is_waterfall = true;
  1109. }else{
  1110. $is_waterfall = false;
  1111. }
  1112. }
  1113. }
  1114. $sticky_post = get_user_meta($uid, 'sticky', 'n');
  1115. if($sticky_post){
  1116. $query = $query->where('id', '<>', $sticky_post);
  1117. }
  1118. $query = $query->where('user_id', $uid);
  1119. if($__MINI_GLOBAL_SCENE__ == 5 && $uid == $__MINI_GLOBAL_CURRENT_USER_ID__){
  1120. $query = $query->whereIn('posts_state', [0, 2]);
  1121. }else{
  1122. $query = $query->where('posts_state', 0);
  1123. }
  1124. // 控制视频隐藏
  1125. if($__MINI_GLOBAL_DEVICE__ != 'mp'){
  1126. global $__MINI_GLOBAL_FRONT_VERSION__;
  1127. // todo: 临时
  1128. if($__MINI_GLOBAL_FRONT_VERSION__ >= '1.2.2.24'){
  1129. }else {
  1130. $query = $query->where('is_wechat_sph', 0);
  1131. }
  1132. }
  1133. if($__MINI_GLOBAL_MODE__ == 'examine'){
  1134. $query = $query->where('post_type', '<>', 'video');
  1135. }
  1136. $data = $query->orderBy('id', 'desc')->paginate($limit);
  1137. if($is_waterfall){
  1138. PostUtils::reset_loop();
  1139. $data->map(function ($v, $k) use ($uid){
  1140. return PostUtils::WaterfallProcess($k, $v, 5);
  1141. });
  1142. }else {
  1143. $data = PostsRepositores::postsParame($data, $uid,5);
  1144. }
  1145. if($uid_ > 0 && request()->page == 1 && $sticky_post){
  1146. $data2 = WxPost::where('id', $sticky_post)->whereIn('posts_state', [0, 2])->get();
  1147. if($data2){
  1148. if($is_waterfall){
  1149. PostUtils::reset_loop();
  1150. $data2->map(function ($v, $k) use ($uid){
  1151. return PostUtils::WaterfallProcess($k, $v,5);
  1152. });
  1153. }else {
  1154. $data2 = PostsRepositores::postsParame($data2, $uid,5);
  1155. }
  1156. $data = json_decode($data->toJson(), true);
  1157. $data['data'] = $data2->concat($data['data']);
  1158. }
  1159. }
  1160. return $data;
  1161. }
  1162. /**
  1163. * 我收藏的文章列表
  1164. * @param $uid
  1165. * @param int $limit
  1166. * @return mixed
  1167. */
  1168. public static function myCollectPosts($uid, $limit = 10)
  1169. {
  1170. $postsIds = WxCollect::where('user_id', $uid)->pluck('posts_id');
  1171. $data = (new Model())
  1172. ->where('is_examine', 1)
  1173. ->where('posts_state', 0)
  1174. ->whereIn('id', $postsIds)
  1175. ->orderBy('id', 'desc')
  1176. ->paginate($limit);
  1177. $data = self::postsParame($data, $uid, 5);//文章详情
  1178. return $data;
  1179. }
  1180. /**
  1181. * 我喜欢的
  1182. * @return mixed
  1183. */
  1184. public static function myLikePosts($uid, $limit = 10)
  1185. {
  1186. $postsIds = WxLike::where('user_id', $uid)->pluck('posts_id');
  1187. $data = (new Model())
  1188. ->where('is_examine', 1)
  1189. ->where('posts_state', 0)
  1190. ->whereIn('id', $postsIds)
  1191. ->paginate($limit);
  1192. $data = self::postsParame($data, $uid, 5);//文章详情
  1193. return $data;
  1194. }
  1195. /**
  1196. * 我充电的
  1197. * @return mixed
  1198. */
  1199. public static function myExceptionalPosts($uid, $limit = 10)
  1200. {
  1201. $postsIds = WxExceptional::where('user_id', $uid)->orderBy('id', 'desc')->pluck('posts_id')->toArray();
  1202. $data = (new Model())
  1203. ->where('is_examine', 1)
  1204. ->where('posts_state', 0)
  1205. ->whereIn('id', $postsIds)->orderBy(DB::raw('FIND_IN_SET(id, "' . implode(",", $postsIds) . '"' . ")"))
  1206. ->paginate($limit);
  1207. $data = self::postsParame($data, $uid, 5);//文章详情
  1208. return $data;
  1209. }
  1210. /**
  1211. * 根据圈子ID获取最新和最热的笔记
  1212. * @param $circle_id
  1213. * @param $type 0:最新,1:最热
  1214. */
  1215. public static function postsByCircleId($circle_id, $type, $limit, $uid, $page, $tags, $sort, $city = '', $is_tenant = false)
  1216. {
  1217. $is_waterfall = CircleUtils::is_list_waterfall($circle_id);
  1218. global $__MINI_GLOBAL_DEVICE__,$__MINI_GLOBAL_MODE__,$__MINI_GLOBAL_TENANT_ID__;
  1219. if ($type == 0) {
  1220. $sorts = Settings::get('app_circle_list_sort', ['weight', 'created_at', 'id'], true);
  1221. $sticky_post = get_circle_meta($circle_id, 'sticky', 'n');
  1222. $sticky_notice_posts = get_circle_meta($circle_id, 'sticky_notice_list', 'j');
  1223. $data = (new Model())
  1224. ->where('is_examine', 1)
  1225. ->where('posts_state', 0)
  1226. ->where('circle_id', $circle_id);
  1227. if($is_tenant){
  1228. $data = $data->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
  1229. }
  1230. if($sticky_post){
  1231. $data = $data->Where('id', '<>', $sticky_post);
  1232. }
  1233. if($city){
  1234. if(StrUtils::endsWith($city, '市')){
  1235. $data = $data->where('city', $city);
  1236. }else{
  1237. $data = $data->where('city', $city.'市');
  1238. }
  1239. }
  1240. // 控制视频隐藏
  1241. if($__MINI_GLOBAL_DEVICE__ != 'mp'){
  1242. global $__MINI_GLOBAL_FRONT_VERSION__;
  1243. // todo: 临时
  1244. if($__MINI_GLOBAL_FRONT_VERSION__ >= '1.2.2.24'){
  1245. }else {
  1246. $data = $data->where('is_wechat_sph', 0);
  1247. }
  1248. }
  1249. if($__MINI_GLOBAL_MODE__ == 'examine'){
  1250. $data = $data->where('post_type', '<>', 'video');
  1251. }
  1252. $not_like_post_set = get_user_meta($uid, 'feedback:notlike:post:set', 'j');
  1253. $not_like_user_set = get_user_meta($uid, 'feedback:notlike:user:set', 'j');
  1254. if(!_empty_($not_like_user_set)){
  1255. $data = $data->whereNotIn('user_id', $not_like_user_set);
  1256. }
  1257. if(!_empty_($not_like_post_set)){
  1258. $data = $data->whereNotIn('id', $not_like_post_set);
  1259. }
  1260. if(!_empty_($sticky_notice_posts)){
  1261. $data = $data->whereNotIn('id', $sticky_notice_posts);
  1262. }
  1263. if($tags && is_array($tags)){
  1264. $data = $data->whereIn('id', function ($query) use ($tags) {
  1265. $query->select('posts_id')
  1266. ->from('wx_posts_tags')
  1267. ->whereIn('tags_id', $tags);
  1268. });
  1269. }
  1270. //
  1271. // if($sticky_post){
  1272. // $data = $data->orderByRaw(DB::raw("CASE WHEN id = $sticky_post then 1 else 0 end"), 'desc');
  1273. // }
  1274. if($sort == 1){
  1275. $data = $data->orderBy('last_reply_at', 'desc')->orderBy('id', 'desc');
  1276. }else if($sort == 2){
  1277. $data = $data->orderBy('degree', 'desc')->orderBy('id', 'desc');
  1278. }else{
  1279. if($sorts){
  1280. foreach ($sorts as $sort_){
  1281. $data = $data->orderBy($sort_, 'desc');
  1282. }
  1283. }else{
  1284. $data = $data->orderBy('id', 'desc');
  1285. }
  1286. }
  1287. $data = $data->simplePaginate($limit);
  1288. if($is_tenant){
  1289. PostUtils::$force_show_multi_site = false;
  1290. }
  1291. if($is_waterfall){
  1292. PostUtils::reset_loop();
  1293. $data->map(function ($v, $k) use ($uid){
  1294. return PostUtils::WaterfallProcess($k, $v, 6);
  1295. });
  1296. }else {
  1297. $data = self::postsParame($data, $uid,6);//文章详情
  1298. }
  1299. if($page == 1 && $sticky_post){
  1300. $data2 = WxPost::where('id', $sticky_post)->where('is_examine', 1)->where('posts_state', 0)->get();
  1301. if($data2){
  1302. if($is_waterfall){
  1303. PostUtils::reset_loop();
  1304. $data2->map(function ($v, $k) use ($uid){
  1305. return PostUtils::WaterfallProcess($k, $v,6);
  1306. });
  1307. }else {
  1308. $data2 = self::postsParame($data2, $uid, 6);//文章详情
  1309. }
  1310. $data = json_decode($data->toJson(), true);
  1311. $data['data'] = $data2->concat($data['data']);
  1312. }
  1313. }
  1314. return $data;
  1315. }elseif ($type == 999) {
  1316. // 验证权限
  1317. if(UserUtils::is_mini_admin($uid) || UserUtils::is_circle_admin($circle_id, $uid)){
  1318. // 审核中的笔记
  1319. $data = (new Model())
  1320. ->where('is_examine', 0)
  1321. ->where('circle_id', $circle_id)
  1322. ->orderBy('id', 'desc')
  1323. ->simplePaginate($limit);
  1324. if($is_waterfall){
  1325. PostUtils::reset_loop();
  1326. $data->map(function ($v, $k) use ($uid){
  1327. return PostUtils::WaterfallProcess($k, $v, 6);
  1328. });
  1329. }else {
  1330. $data = self::postsParame($data, $uid, 6);//文章详情
  1331. }
  1332. return $data;
  1333. }
  1334. return null;
  1335. }
  1336. }
  1337. /**
  1338. * 搜索
  1339. * @param $keyword
  1340. * @param int $uid
  1341. * @param int $limit
  1342. * @return mixed
  1343. */
  1344. public static function searchPosts($keyword, $uid = 0, $limit = 10, $is_tenant = false)
  1345. {
  1346. global $__MINI_GLOBAL_TENANT_ID__;
  1347. WxSearchRepositores::record($uid, $keyword);
  1348. $query = (new Model())
  1349. ->where('is_examine', 1)
  1350. ->where('posts_state', 0);
  1351. if($is_tenant){
  1352. $query = $query->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__);
  1353. }
  1354. $data = $query->where(function ($query) use ($keyword) {
  1355. if(is_numeric($keyword)){
  1356. $query->orWhere('id', $keyword)
  1357. ->orWhere('posts_content', 'like', '%' . $keyword . '%');
  1358. }else{
  1359. $query->orWhere('posts_content', 'like', '%' . $keyword . '%');
  1360. }
  1361. })->orderBy('id', 'desc')->simplePaginate($limit);
  1362. if($is_tenant){
  1363. PostUtils::$force_show_multi_site = false;
  1364. }
  1365. $data = self::postsParame($data, $uid, 10);//文章详情
  1366. return $data;
  1367. }
  1368. public static function relevantPosts($post_id, $uid = 0, $limit = 10)
  1369. {
  1370. $result = [];
  1371. if(SearchUtils::is_use_es()){
  1372. try{
  1373. global $__MINI_GLOBAL_TENANT_ID__;
  1374. $keyword = str_replace('?', '?', PostUtils::get_the_title('', $post_id));
  1375. $data = WxPost::search($keyword)->where('is_examine', 1)->where('posts_state', 0)->where('tenant_id', $__MINI_GLOBAL_TENANT_ID__)->simplePaginate($limit);
  1376. PostUtils::reset_loop();
  1377. $data->map(function ($v, $k) use ($uid){
  1378. return PostUtils::WaterfallProcess($k, $v,90001);
  1379. });
  1380. $result = json_decode($data->toJson(), true);
  1381. $data_ = [];
  1382. if($result['data']){
  1383. foreach ($result['data'] as $obj){
  1384. if($obj['id'] != $post_id && $obj['is_examine'] == 1 && $obj['posts_state'] == 0 && $obj['tenant_id'] == $__MINI_GLOBAL_TENANT_ID__){
  1385. $data_[] = $obj;
  1386. }
  1387. }
  1388. }
  1389. $result['data'] = $data_;
  1390. }catch (\Exception $e){
  1391. if(strpos($e->getMessage(), '404 Not Found') !== false){
  1392. ElasticSearchBatchSyncJob::dispatch(0, 1000, 'post');
  1393. }else{
  1394. _logger_(__file__, __line__, $e->getMessage());
  1395. }
  1396. }
  1397. }
  1398. return $result;
  1399. }
  1400. /**
  1401. * 商品晒单
  1402. * @return mixed
  1403. */
  1404. public static function goodsBaskPosts($uid, $gid)
  1405. {
  1406. $postsIds = WxPostsGoods::where('goods_id', $gid)->pluck('posts_id');//笔记ID列表
  1407. $data = (new Model())
  1408. ->where('is_examine', 1)
  1409. ->where('posts_state', 0)
  1410. ->whereIn('id', $postsIds)
  1411. ->paginate(6);
  1412. $data = self::postsParame($data, $uid);//文章详情
  1413. return $data;
  1414. }
  1415. // $style样式位置
  1416. public static function postsParame($data, $uid, $scene = 0, $actree = null)
  1417. {
  1418. if($data){
  1419. PostUtils::reset_loop();
  1420. $data->map(function ($v, $k) use ($uid, $scene, $actree) {
  1421. return PostUtils::defaultProcess($k, $v, $scene, $actree);
  1422. });
  1423. $data->append(['format_time', 'is_ellipsis', 'is_content_beyond', 'ip_address']);
  1424. return $data;
  1425. }
  1426. return null;
  1427. }
  1428. /**
  1429. * 获取笔记喜欢数量
  1430. */
  1431. public static function likeCont($postId)
  1432. {
  1433. return (int)(Cache::remember('posts:likeCont:'.$postId, 36000, function () use ($postId){
  1434. return WxLike::where(['posts_id' => $postId])->count();
  1435. }));
  1436. }
  1437. /**
  1438. * 获取笔记充电总数
  1439. */
  1440. public static function exceptionalCont($postId)
  1441. {
  1442. return (int)Cache::remember('exceptional:cont:'.$postId, 3600, function () use ($postId){
  1443. return WxExceptional::where(['posts_id' => $postId])->count();
  1444. });
  1445. }
  1446. /**
  1447. * 获取笔记充电列表(只显示头像)
  1448. */
  1449. public static function exceptionalList($postId)
  1450. {
  1451. if(_empty_($postId)){
  1452. return null;
  1453. }
  1454. return Cache::remember('post:exceptional:list:'.$postId, 3600, function () use ($postId){
  1455. $ids = WxExceptional::where('posts_id', $postId)
  1456. ->groupBy('user_id')
  1457. ->pluck('user_id');//充电用户ID列表
  1458. if($ids){
  1459. return WxUser::whereIn('id', $ids)->limit(6)->get(['user_avatar']);
  1460. }
  1461. return null;
  1462. });
  1463. }
  1464. }