UsedController.php 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057
  1. <?php
  2. namespace App\Http\Controllers\Api;
  3. use App\Http\Controllers\Api\Repositories\PostsRepositores;
  4. use App\Http\Controllers\Api\Repositories\WxContRepositories;
  5. use App\Jobs\AttachIpAddressJob;
  6. use App\Jobs\CalculateFollowsNumJob;
  7. use App\Jobs\CalculateLikesNumJob;
  8. use App\Jobs\Posts\UpdatePostOnlyTextJob;
  9. use App\Jobs\Posts\UpdatePostVideoIdJob;
  10. use App\Jobs\Used\UpdateUsedPosterGlassJob;
  11. use App\Lib\WeApp\WeApp;
  12. use App\Models\Used\WxUsedClassify;
  13. use App\Models\Used\WxUsedComment;
  14. use App\Models\Used\WxUsedGood;
  15. use App\Models\Used\WxUsedNeed;
  16. use App\Models\User\WxUser;
  17. use App\Models\WxChat;
  18. use App\Wen\Utils\BaiduUtils;
  19. use App\Wen\Utils\FieldUtils;
  20. use App\Wen\Utils\FileUtils;
  21. use App\Wen\Utils\ImageUtils;
  22. use App\Wen\Utils\Settings;
  23. use App\Wen\Utils\ShopUtils;
  24. use App\Wen\Utils\UserUtils;
  25. use App\Wen\Utils\Utils;
  26. use Illuminate\Http\Request;
  27. use Illuminate\Support\Facades\Cache;
  28. use Illuminate\Support\Facades\DB;
  29. use Illuminate\Support\Facades\Redis;
  30. use Intervention\Image\Facades\Image;
  31. use SimpleSoftwareIO\QrCode\Facades\QrCode;
  32. class UsedController extends BaseController
  33. {
  34. public function process(Request $request){
  35. $type = _empty_default_($request->type, '');
  36. if ($type == 'good_poster') {
  37. return $this->good_poster($request);
  38. }
  39. }
  40. private function good_poster(Request &$request){
  41. $uid = _empty_default_($request->uid, 0);
  42. $used_good_id = _empty_default_($request->used_good_id, 0);
  43. global $__MINI_GLOBAL_DEVICE__;
  44. if(_empty_($used_good_id)){
  45. return $this->fail(200001);
  46. }
  47. $used_good = WxUsedGood::find($used_good_id);
  48. if(_empty_($used_good)){
  49. return $this->fail(200003);
  50. }
  51. if($used_good->image_urls){
  52. $used_good->pic = _array_key($used_good->image_urls[0], 'url', '');
  53. $used_good->pic_width = _array_key($used_good->image_urls[0], 'width', '');
  54. $used_good->pic_height = _array_key($used_good->image_urls[0], 'height', '');
  55. if($used_good->pic_width >= 0){
  56. $old_widht = $used_good->pic_width;
  57. $used_good->pic_width = 363;
  58. $used_good->pic_height = (int)( (363 * $used_good->pic_height) / $old_widht );
  59. }
  60. }
  61. if(_empty_($used_good->pic)){
  62. if($used_good->video_cover){
  63. $used_good->pic = $used_good->video_cover;
  64. }else{
  65. $used_good->pic = Settings::get('img_share_default', '');
  66. }
  67. }
  68. $data = [];
  69. $data['title'] = Settings::get('about_title', '');
  70. $used_user_id = $used_good->user_id;
  71. $post_title = $used_good->title;
  72. // ['glass'=>'', 'theme'=>'black/white', 'attach_id'=>id]
  73. $poster_glass = get_used_meta($used_good->id, 'used_poster_glass_obj', 'j');
  74. if(_empty_($poster_glass)){
  75. $attach_id = FileUtils::get_url_attach_id($used_good->pic);
  76. if($attach_id){
  77. $used_poster_glass_obj = [
  78. 'glass' => '',
  79. 'theme' => '',
  80. 'attach_id' => $attach_id
  81. ];
  82. $first_glasses = $used_good->pic . '?imageMogr2/thumbnail/630x800/crop/630x800/gravity/center/format/png/interlace/0/blur/50x1';
  83. $path = ImageUtils::upload_url_img($first_glasses);
  84. if($path && $path['url']){
  85. // 二次上传
  86. $path2 = ImageUtils::upload_url_img($path['url']. '?imageMogr2/thumbnail/630x800/crop/630x800/gravity/center/format/png/interlace/0/blur/50x1');
  87. if($path2 && $path2['url']){
  88. // 三次上传
  89. $path3 = ImageUtils::upload_url_img($path2['url']. '?imageMogr2/thumbnail/630x800/crop/630x800/gravity/center/format/png/interlace/0/blur/50x1');
  90. if($path3 && $path3['url']){
  91. // 四次上传
  92. $path4 = ImageUtils::upload_url_img($path3['url']. '?imageMogr2/thumbnail/630x800/crop/630x800/gravity/center/format/png/interlace/0/blur/50x1');
  93. if($path4 && $path4['url']){
  94. $used_poster_glass_obj['glass'] = $path4['url'];
  95. update_used_meta($used_good->id, 'used_poster_glass_obj', $used_poster_glass_obj, 'j');
  96. FileUtils::force_del_url_file($path3['url']);
  97. $data['glass'] = $path4['url'] . '?imageMogr2/thumbnail/630x800/crop/630x800/gravity/center/format/png/interlace/0/blur/50x1';
  98. }else{
  99. $used_poster_glass_obj['glass'] = $path3['url'];
  100. update_used_meta($used_good->id, 'used_poster_glass_obj', $used_poster_glass_obj, 'j');
  101. $data['glass'] = $path3['url'] . '?imageMogr2/thumbnail/630x800/crop/630x800/gravity/center/format/png/interlace/0/blur/50x1';
  102. }
  103. }else{
  104. $used_poster_glass_obj['glass'] = $path2['url'];
  105. update_used_meta($used_good->id, 'used_poster_glass_obj', $used_poster_glass_obj, 'j');
  106. $data['glass'] = $path2['url'] . '?imageMogr2/thumbnail/630x800/crop/630x800/gravity/center/format/png/interlace/0/blur/50x1';
  107. }
  108. }else{
  109. $used_poster_glass_obj['glass'] = $path['url'];
  110. update_used_meta($used_good->id, 'used_poster_glass_obj', $used_poster_glass_obj, 'j');
  111. $data['glass'] = $path['url'] . '?imageMogr2/thumbnail/630x800/crop/630x800/gravity/center/format/png/interlace/0/blur/50x1';
  112. }
  113. }else{
  114. $data['glass'] = $used_good->pic . '?imageMogr2/thumbnail/630x800/crop/630x800/gravity/center/format/png/interlace/0/blur/50x1';
  115. }
  116. UpdateUsedPosterGlassJob::dispatch($used_good->id);
  117. }
  118. }else{
  119. if(FileUtils::get_url_attach_id($used_good->pic) == $poster_glass['attach_id']){
  120. _logger_(__file__, __line__, $poster_glass['theme']);
  121. if(_empty_($poster_glass['theme'])){
  122. UpdateUsedPosterGlassJob::dispatch($used_good->id);
  123. }
  124. $data['glass'] = $poster_glass['glass'] . '?imageMogr2/thumbnail/630x800/crop/630x800/gravity/center/format/png/interlace/0/blur/50x1';
  125. }else{
  126. update_used_meta($used_good->id, 'used_poster_glass_obj', null, 'j');
  127. FileUtils::force_del_url_file($poster_glass['glass']);
  128. }
  129. }
  130. $user = WxUser::where('id', $used_user_id)->first(FieldUtils::userInfoColums());
  131. if($user){
  132. }else{
  133. $user = ['user_name'=>'未知用户'];
  134. }
  135. $data['user'] = $user;
  136. if(empty($used_good->pic)){
  137. return $this->fail(200006, [], '请先配置“默认分享图片”');
  138. }
  139. $page = 'pagesU/used-mall/detail/index';
  140. $code_url = Utils::getMiniCode($page, 'id='.$used_good->id, $uid);
  141. $data['qrcode'] = $code_url;
  142. $data['img'] = $used_good->pic.'?imageMogr2/quality/100/interlace/0/crop/630x800/gravity/center/thumbnail/x800';
  143. $data['content'] = $post_title;
  144. $data['tip'] = Settings::get('app_post_poster_bottom_tip', '❤ 扫一扫,找到你想要的生活');
  145. if($poster_glass){
  146. $data['tip_color'] = _array_key($poster_glass, 'theme', 'black') == 'white' ? '#333' : '#FFF';
  147. }else{
  148. $data['tip_color'] = '#FFF';
  149. }
  150. if($used_good->classify_id > 0){
  151. $circle_tip = WxUsedClassify::where('id', $used_good->classify_id)->value('name');
  152. }else{
  153. $circle_tip = '广场';
  154. }
  155. $data['poster2'] = [
  156. 'content' => $post_title,
  157. 'contentImg' => ($used_good->pic == Settings::get('img_post_poster_default', '')) ? '' : ($used_good->pic. '?imageMogr2/quality/100/interlace/0/crop/630x800/gravity/center/thumbnail/x800'),
  158. 'avatar' => $user->user_avatar,
  159. 'locationText' => $circle_tip,
  160. 'locationImg' => env('APP_URL') . '/statics/images/playbill/post/ring.png',
  161. 'userName' => $user->user_name,
  162. 'code' => $code_url,
  163. 'textImg' => env('APP_URL') . '/statics/images/playbill/post/poster-text.png'
  164. ];
  165. if(Settings::get('app_h5_home', '')){
  166. $data['url'] = Settings::get('app_h5_home', '').'/#/pagesU/used-mall/detail/index?id='.$used_good->id;
  167. }else{
  168. $data['url'] = env('APP_URL');
  169. }
  170. $social = [];
  171. $share_types = Settings::get('app_post_poster_share_types', []);
  172. foreach (['wechat', 'timeline', 'qq', 'qzone', 'weibo', 'save'] as $key){
  173. if(!in_array($key, $share_types)){
  174. continue;
  175. }
  176. if($key == 'wechat'){
  177. $social[] = [
  178. 'action' => 'wechat',
  179. 'color' => '#57be6a',
  180. 'text' => '微信好友',
  181. 'icon' => 'mini-icon mini-weixin',
  182. 'share' => json_encode([
  183. 'provider' => 'weixin',
  184. 'type' => 2,
  185. 'title' => $data['content'],
  186. 'scene' => 'WXSceneSession',
  187. 'href' => $data['url'],
  188. 'imageUrl' => $data['img'],
  189. 'miniProgram' => [
  190. 'id' => Settings::get('app_meta_appid', ''),
  191. 'path' => '/pagesU/used-mall/detail?id=' . $used_good->id,
  192. 'type' => 0,
  193. 'webUrl' => $data['url']
  194. ]
  195. ]),
  196. ];
  197. }else if($key == 'timeline'){
  198. if($__MINI_GLOBAL_DEVICE__ != 'mp'){
  199. $social[] = [
  200. 'action' => 'timeline',
  201. 'color' => '#80cc46',
  202. 'text' => '朋友圈',
  203. 'icon' => 'mini-icon mini-pengyouquan1',
  204. 'share' => json_encode([
  205. 'provider' => 'weixin',
  206. 'type' => 2,
  207. 'title' => $data['content'],
  208. 'scene' => 'WXSceneTimeline',
  209. 'href' => $data['url'],
  210. 'imageUrl' => $data['img']
  211. ])
  212. ];
  213. }
  214. }else if($key == 'qq'){
  215. if($__MINI_GLOBAL_DEVICE__ != 'mp') {
  216. $social[] = [
  217. 'action' => 'qq',
  218. 'color' => '#54b4ef',
  219. 'text' => 'QQ好友',
  220. 'icon' => 'mini-icon mini-qq1',
  221. 'share' => json_encode([
  222. 'provider' => 'qq',
  223. 'type' => 2,
  224. 'title' => $data['content'],
  225. 'summary' => $data['content'],
  226. 'href' => $data['url'],
  227. 'imageUrl' => $data['img']
  228. ])
  229. ];
  230. }
  231. }else if($key == 'qzone'){
  232. if($__MINI_GLOBAL_DEVICE__ != 'mp') {
  233. $social[] = [
  234. 'action' => 'qzone',
  235. 'color' => '#f7cf46',
  236. 'text' => 'QQ空间',
  237. 'icon' => 'mini-icon mini-Rrl_s_112',
  238. 'share' => json_encode([
  239. 'provider' => 'qq',
  240. 'type' => 1,
  241. 'title' => $data['content'],
  242. 'href' => $data['url'],
  243. 'imageUrl' => $data['img']
  244. ])
  245. ];
  246. }
  247. }else if($key == 'weibo'){
  248. if($__MINI_GLOBAL_DEVICE__ != 'mp') {
  249. $social[] = [
  250. 'action' => 'weibo',
  251. 'color' => '#d4382a',
  252. 'text' => '微博',
  253. 'icon' => 'mini-icon mini-weibo',
  254. 'share' => json_encode([
  255. 'provider' => 'sinaweibo',
  256. 'type' => 0,
  257. 'title' => $data['content'],
  258. 'href' => $data['url'],
  259. 'imageUrl' => $data['img']
  260. ])
  261. ];
  262. }
  263. }else if($key == 'save'){
  264. $social[] = [
  265. 'action' => 'save',
  266. 'color' => '#999999',
  267. 'text' => '保存到相册',
  268. 'icon' => 'mini-icon mini-xiazai2',
  269. ];
  270. }
  271. }
  272. $data['social'] = $social;
  273. if($code_url){
  274. return $this->success($data);
  275. }else{
  276. return $this->fail(300001, $data);
  277. }
  278. }
  279. public function need(Request $request){
  280. $used_good_id = _empty_default_($request->used_good_id, 0);
  281. $status = _empty_default_($request->status, 0);
  282. $uid = $request->uid;
  283. if(!in_array($status, [0, 1])){
  284. return $this->fail(200004);
  285. }
  286. $user_good = WxUsedGood::find($used_good_id);
  287. if($user_good){
  288. }else{
  289. return $this->fail(200004);
  290. }
  291. $model = WxUsedNeed::where('user_id', $uid)->where('used_good_id', $used_good_id)->first();
  292. if($model){
  293. if($status == 1){
  294. if($model->status === 0){
  295. $model->status = 1;
  296. $model->save();
  297. $last_chat = WxChat::where('user_id', $user_good->user_id)->where('object_id', $uid)->orderByDesc('id')->first();
  298. if($last_chat && $last_chat->expand_type == 5 && $last_chat->expand_id == $user_good->id){
  299. }else{
  300. WxContRepositories::add($user_good->user_id, $uid, '', '', '', 0, 0, 0, 0, 0, $user_good->id);
  301. }
  302. }
  303. }else{
  304. if($model->status === 1){
  305. $model->status = 0;
  306. $model->save();
  307. }
  308. }
  309. }else{
  310. $new_model = new WxUsedNeed();
  311. $new_model->user_id = $uid;
  312. $new_model->used_good_id = $used_good_id;
  313. $new_model->status = $status;
  314. $new_model->save();
  315. $last_chat = WxChat::where('user_id', $user_good->user_id)->where('object_id', $uid)->orderByDesc('id')->first();
  316. if($last_chat && $last_chat->expand_type == 5 && $last_chat->expand_id == $user_good->id){
  317. }else{
  318. WxContRepositories::add($user_good->user_id, $uid, '', '', '', 0, 0, 0, 0, 0, $user_good->id);
  319. }
  320. }
  321. return $this->success();
  322. }
  323. public function classify_list(Request $request){
  324. $data = WxUsedClassify::orderBy('order', 'desc')->orderBy('id', 'desc')->where('status', 1)->get();
  325. if($data && $data->isNotEmpty()){
  326. return $this->success($data);
  327. }else{
  328. return $this->fail(200003);
  329. }
  330. }
  331. public function list(Request $request){
  332. global $__MINI_GLOBAL_SCENE__;
  333. $uid = $request->uid;
  334. $keyword = $request->keyword;
  335. $user_id = _empty_default_($request->user_id, 0);
  336. $status = _empty_default_($request->status, []);
  337. $orderBy = _empty_default_($request->orderBy, 'id');
  338. $order = _empty_default_($request->order, 'desc');
  339. $classify_id = _empty_default_($request->classify_id, 0);
  340. $limit = _between_(_empty_default_($request->limit, 10), 1, 100);
  341. $minprice = _between_(_empty_default_($request->minPrice, 0), 0, 999999999);
  342. $maxPrice = _between_(_empty_default_($request->maxPrice, 999999999), 0, 999999999);
  343. global $__MINI_GLOBAL_TENANT_ID__;
  344. if($minprice > $maxPrice){
  345. return $this->fail(200004);
  346. }
  347. if(!in_array($orderBy, ['id', 'distance', 'price', 'created_at', 'state'])){
  348. return $this->fail(200004);
  349. }
  350. if(!in_array($order, ['desc', 'asc'])){
  351. return $this->fail(200004);
  352. }
  353. if($orderBy != 'price'){
  354. $order = 'desc';
  355. }
  356. if(is_string($status)){
  357. $status = explode(',', $status);
  358. }
  359. if(_empty_($status)){
  360. $status = [1];
  361. }
  362. if($__MINI_GLOBAL_SCENE__ == 120 && (_empty_($user_id) || $user_id == $uid)){
  363. $status = [0,1,2,3,4,5,6,7, 99];
  364. }
  365. if($orderBy != 'distance'){
  366. $query = WxUsedGood::whereIn('status', $status);
  367. if($keyword){
  368. $query = $query->where(function ($query_) use ($keyword) {
  369. $query_->orWhere('title', 'like', '%' . $keyword . '%')
  370. ->orWhere('detail', 'like', '%' . $keyword . '%');
  371. });
  372. }
  373. if($minprice > 0){
  374. $query = $query->where('price', '>=', $minprice);
  375. }
  376. if($maxPrice != 9999999999){
  377. $query = $query->where('price', '<=', $maxPrice);
  378. }
  379. if($user_id > 0){
  380. $query = $query->where('user_id', $user_id);
  381. }else{
  382. if($__MINI_GLOBAL_SCENE__ == 120){
  383. $query = $query->where('user_id', $uid);
  384. }
  385. }
  386. if($classify_id > 0){
  387. $query = $query->where('classify_id', $classify_id);
  388. }
  389. if($orderBy == 'state'){
  390. $data = $query->orderBy(DB::raw('FIND_IN_SET(status, "' . implode(",", [1,3,5,6,7,8,9,10]) . '"' . ")"))->orderByDesc('id')
  391. ->paginate($limit);
  392. }else{
  393. $data = $query->orderBy(DB::raw('FIND_IN_SET(status, "' . implode(",", [1,3,5,6,7,8,9,10]) . '"' . ")"))->orderBy($orderBy, $order)
  394. ->paginate($limit);
  395. }
  396. // if($classify_id > 0){
  397. // $query = $query->where('classify_id', $classify_id);
  398. // }else{
  399. // $query = $query->whereNotIn('classify_id', $ban_ids);
  400. // }
  401. if($data){
  402. $data->map(function ($v, $k){
  403. ShopUtils::used_process($v);
  404. return $v;
  405. });
  406. return $this->success($data);
  407. }
  408. return $this->fail(200003);
  409. }else{
  410. if($uid > 0){
  411. $user_ip = WxUser::where('id', $uid)->value('ip');
  412. global $__MINI_GLOBAL_IP__;
  413. if($user_ip != $__MINI_GLOBAL_IP__){
  414. WxUser::where('id', $uid)->update([
  415. 'ip' => $__MINI_GLOBAL_IP__
  416. ]);
  417. AttachIpAddressJob::dispatch(2, $uid)->delay(2);
  418. }
  419. $user = WxUser::find($uid);
  420. $longitude = $user->longitude;
  421. $latitude = $user->latitude;
  422. if(_empty_($longitude) && _empty_($latitude)){
  423. $res = _ip_address($__MINI_GLOBAL_IP__);
  424. if(_empty_($res)){
  425. return $this->fail(503003);
  426. }
  427. $longitude = $res['longitude'];
  428. $latitude = $res['latitude'];
  429. }
  430. $the_base_id = Cache::remember('used:goods:new:500', 3600 * 5, function (){
  431. $base_id = WxUsedGood::where('status', 1)->orderBy('id', 'desc')->skip(500)->value('id');
  432. return $base_id > 0 ? $base_id : 0;
  433. });
  434. $data = WxUsedGood::select(DB::raw('*, ( 6378137 * acos( cos( radians('.$latitude.') ) * cos( radians( latitude ) ) * cos( radians( longitude ) - radians('.$longitude.') ) + sin( radians('.$latitude.') ) * sin( radians( latitude ) ) ) ) AS distance'))
  435. ->where('id', '>', $the_base_id)
  436. ->where('status', 1)
  437. ->where('user_id', '<>', $uid)
  438. ->having('distance', '<', 300000)
  439. ->inRandomOrder()
  440. ->simplePaginate(10);
  441. if($data){
  442. $data->map(function ($v, $k){
  443. ShopUtils::used_process($v);
  444. return $v;
  445. });
  446. return $this->success($data);
  447. }
  448. }else{
  449. return $this->fail(200003, [], '没有获取到您的经纬度信息');
  450. }
  451. }
  452. }
  453. public function detail(Request $request){
  454. $id = $request->id;
  455. if(_empty_($id)){
  456. return $this->fail(200001);
  457. }
  458. $user_good = WxUsedGood::where('id', $id)->first();
  459. if($user_good){
  460. ShopUtils::used_process($user_good);
  461. return $this->success($user_good);
  462. }
  463. return $this->fail(200003);
  464. }
  465. public function comment_process(Request $request){
  466. $action = _empty_default_($request->action, '');
  467. $uid = $request->uid;
  468. if(_empty_($action)){
  469. return $this->fail(200001);
  470. }
  471. if(!in_array($action, ['add', 'delete'])){
  472. return $this->fail(200004);
  473. }
  474. if(!UserUtils::is_user_can_speak($uid)){
  475. return $this->fail(200043, [
  476. 'title' => '禁言中,无法言论',
  477. 'content' => '是否前往解除限制',
  478. 'confirmText' => '去解除',
  479. 'target_type' => 6,
  480. 'target_id' => '/pagesA/mine/unlock/unlock?user_id='.$uid
  481. ], '您当前处于禁言期间,无法言论');
  482. }
  483. if($action == 'add'){
  484. $used_good_id = _empty_default_($request->used_good_id, 0);
  485. if(_empty_($used_good_id)){
  486. return $this->fail(200001);
  487. }
  488. if(WxUsedGood::where('id', $used_good_id)->value('status') != 1){
  489. return $this->fail(200000, [], '该闲置商品不是上架中状态');
  490. }
  491. // if(mb_strlen( str_replace( [Settings::get('default_user_name', '微信用户'), '微信用户', '普通用户'], '', UserUtils::get_cached_user_name($uid) )) != mb_strlen(UserUtils::get_cached_user_name($uid))){
  492. // return $this->fail(200041);
  493. // }
  494. $comment_id = _empty_default_($request->comment_id, 0);
  495. if(_empty_($comment_id)){
  496. $comment_id = 0;
  497. }
  498. if($comment_id > 0){
  499. if(!WxUsedComment::where('id', $comment_id)->where('comment_state', 1)->exists()){
  500. return $this->fail(200004, [], '该父级评论不存在');
  501. }
  502. }
  503. $comment_agent_id = _empty_default_($request->comment_agent_id, 0);
  504. if(_empty_($comment_agent_id)){
  505. $comment_agent_id = 0;
  506. }
  507. if($comment_agent_id > 0){
  508. $comment_agent_name = UserUtils::get_cached_user($comment_agent_id)['user_name'];
  509. }
  510. $comment_content = _empty_default_($request->comment_content, '');
  511. $comment_img_url = _empty_default_($request->comment_img_url, '');
  512. if(_empty_($comment_content)){
  513. return $this->fail(200001);
  514. }
  515. $comment_content = strip_tags($comment_content);
  516. if(mb_strlen($comment_content) <= 0 || mb_strlen($comment_content) > 240){
  517. return $this->fail(200004, [], '评论内容过长或过短');
  518. }
  519. global $__MINI_GLOBAL_IP__;
  520. // 百度审核
  521. if(UserUtils::user_permissions_check_by_config($uid, 'audit_used_comment_white_list')){
  522. $need_manual_review = false;
  523. }else{
  524. $need_manual_review = true;
  525. $is_audit_used_comment = Settings::get('is_audit_used_comment', 0);
  526. if ($is_audit_used_comment == 2) {
  527. $filter_result = BaiduUtils::text_filter($comment_content);
  528. if($filter_result){
  529. if($filter_result['hit_level'] == 2){
  530. // 不合规
  531. return $this->fail(200016, ['tip'=>$filter_result['tip_list'], 'hit_word'=>$filter_result['hit_word']]);
  532. }else if($filter_result['hit_level'] == 0){
  533. // 审核通过
  534. $need_manual_review = false;
  535. }
  536. }
  537. }else if($is_audit_used_comment == 0){
  538. $need_manual_review = true;
  539. }else{
  540. $need_manual_review = false;
  541. }
  542. }
  543. // 0:审核中,1:审核通过,2:驳回
  544. $comment_state = 1;
  545. if($need_manual_review){
  546. $comment_state = 0;
  547. }
  548. $model = new WxUsedComment();
  549. $model->user_id = $uid;
  550. $model->used_good_id = $used_good_id;
  551. if($comment_id > 0){
  552. $model->comment_id = $comment_id;
  553. }else{
  554. $model->comment_id = 0;
  555. }
  556. if($comment_agent_id > 0 && $comment_agent_name){
  557. $model->comment_agent_id = $comment_agent_id;
  558. $model->comment_agent_name = $comment_agent_name;
  559. }else{
  560. $model->comment_agent_id = 0;
  561. }
  562. $model->comment_content = $comment_content;
  563. if(!_empty_($comment_img_url)){
  564. $model->comment_img_url = $comment_img_url;
  565. }
  566. if($__MINI_GLOBAL_IP__){
  567. $model->ip = $__MINI_GLOBAL_IP__;
  568. }
  569. $model->comment_state = $comment_state;
  570. $r = $model->save();
  571. if($r){
  572. return $this->success();
  573. }
  574. return $this->fail(200002);
  575. }else if($action == 'delete'){
  576. }
  577. }
  578. public function comment_list(Request $request){
  579. $limit = _between_(_empty_default_($request->limit, 10), 1, 100);
  580. $used_good_id = _empty_default_($request->used_good_id, 0);
  581. if(_empty_($used_good_id)){
  582. $this->fail(200001);
  583. }
  584. $data = WxUsedComment::where('used_good_id', $used_good_id)->where('comment_id', 0)->where('comment_state', 1)->orderBy('id', 'desc')->simplePaginate($limit);
  585. if($data){
  586. $data->map(function ($v, $k){
  587. $v->user = UserUtils::get_cached_user($v->user_id);
  588. if(_empty_($v->comment_id)){
  589. $childData = WxUsedComment::where('comment_id', $v->id)->limit(100)->get();
  590. if($childData){
  591. $childData->map(function ($v2, $k2){
  592. $v2->user = UserUtils::get_cached_user($v2->user_id);
  593. $v2->format_time = format_datetime($v2->created_at);
  594. return $v2;
  595. });
  596. }
  597. $v->child = $childData;
  598. }else{
  599. $v->child = [];
  600. }
  601. $v->format_time = format_datetime($v->created_at);
  602. return $v;
  603. });
  604. return $this->success($data);
  605. }else{
  606. return $this->fail(200003);
  607. }
  608. }
  609. public function status(Request $request){
  610. $uid = $request->uid;
  611. $used_id = _empty_default_($request->id, 0);
  612. $status = _empty_default_($request->status, 0);
  613. if(_empty_($used_id)){
  614. return $this->fail(200001);
  615. }
  616. if(_empty_($status)){
  617. $status = 0;
  618. }
  619. if(WxUsedGood::where('id', $used_id)->value('user_id') != $uid && !UserUtils::is_mini_admin($uid)){
  620. return $this->fail(200000);
  621. }
  622. // 重新上架,未卖出下架
  623. if(!in_array($status, [0, 2])){
  624. return $this->fail(200004);
  625. }
  626. // 0:待审核 1: 推送中 2:提前下架 3:交易完成 4:驳回 5: 买家已付款 6:买家已退款
  627. $old_status = WxUsedGood::where('id', $used_id)->value('status');
  628. if($status == 2){
  629. if($old_status != 1){
  630. return $this->fail(200004, [], '该商品不是推送中状态,无法下线');
  631. }
  632. }else if($status === 0){
  633. if( !in_array($old_status, [2, 6, 4]) ){
  634. return $this->fail(200004, [], '该商品的状态无法再次上架,请重新发布');
  635. }
  636. }
  637. $r = WxUsedGood::where('id', $used_id)->update([
  638. 'status' => $status
  639. ]);
  640. if($r){
  641. return $this->success(['status' => $status]);
  642. }
  643. return $this->fail(200002);
  644. }
  645. public function add(Request $request)
  646. {
  647. global $__MINI_GLOBAL_CURRENT_PLAYER_ID__;
  648. $uid = $request->uid;
  649. $title = _empty_default_($request->title, '');
  650. $classify_id = _empty_default_($request->classify_id, 0);
  651. $video_url = _empty_default_($request->video_url, null);
  652. $video_cover = _empty_default_($request->video_cover, null);
  653. global $__MINI_GLOBAL_IP__;
  654. $sync_to_post = _empty_default_($request->add_post, 0) == 1 ? 1 : 0;
  655. $sync_post_content = _empty_default_($request->post_content, '');
  656. $sync_post_img = _empty_default_($request->post_img, '');
  657. $device = $request->header('device','') ?: 'mp';
  658. if(_empty_($device) || !in_array($device, ['app', 'mp', 'h5', 'pc'])){
  659. return $this->fail(200001);
  660. }
  661. $used_id = _empty_default_($request->id, 0);
  662. if($used_id > 0){
  663. $sync_to_post = 0;
  664. if(WxUsedGood::where('id', $used_id)->value('user_id') != $uid && !UserUtils::is_mini_admin($uid)){
  665. return $this->fail(200000);
  666. }
  667. }
  668. if($sync_to_post != 1){
  669. $sync_post_content = '';
  670. $sync_post_img = '';
  671. }else{
  672. if(_empty_($sync_post_content)){
  673. return $this->fail(200001, '', '同步笔记内容不能为空');
  674. }
  675. $sync_post_content = strip_tags($sync_post_content);
  676. }
  677. // if(mb_strlen( str_replace( [Settings::get('default_user_name', '微信用户'), '微信用户', '普通用户'], '', UserUtils::get_cached_user_name($uid) )) != mb_strlen(UserUtils::get_cached_user_name($uid))){
  678. // return $this->fail(200041);
  679. // }
  680. $user = WxUser::find($uid);
  681. // 验证资料
  682. if(Settings::get('used_mall_push_force_bind_phone', 0) == 1){
  683. if(_empty_($user->phone) && _empty_($__MINI_GLOBAL_CURRENT_PLAYER_ID__)){
  684. return $this->fail(200043, [
  685. 'title' => '未绑定手机号',
  686. 'content' => '前往绑定',
  687. 'confirmText' => '去绑定',
  688. 'target_type' => 6,
  689. 'target_id' => '/pagesA/mine/editmine/editmine?phone=1'
  690. ], '未绑定手机号');
  691. }
  692. }
  693. if(Settings::get('used_mall_push_force_real_name', 0) == 1){
  694. if(_empty_($user->real_name) && _empty_($__MINI_GLOBAL_CURRENT_PLAYER_ID__)){
  695. return $this->fail(200043, [
  696. 'title' => '未实名认证',
  697. 'content' => '您还没有实名认证,是否前往认证',
  698. 'confirmText' => '去认证',
  699. 'target_type' => 6,
  700. 'target_id' => '/pagesA/mine/realname/realname'
  701. ], '未实名认证');
  702. }
  703. }
  704. if(Settings::get('used_mall_push_force_subscribe_mp', 0) == 1){
  705. if(_empty_($user->weixin_mp_openid) && _empty_($__MINI_GLOBAL_CURRENT_PLAYER_ID__)){
  706. $weapp = new WeApp('mp');
  707. $mpServicer = $weapp->getMpServicer();
  708. try {
  709. $url = $mpServicer->getQrCodeWithPara(0, 'user:bind:'.$user->id);
  710. }catch (\Exception $e){
  711. return $this->fail(200006, [], '生成公众号二维码失败,请检查[全局配置-支付-微信-公众号]');
  712. }
  713. if($url){
  714. $qrCode = QrCode::format('png')->size(300)->generate($url);
  715. $image = Image::make($qrCode);
  716. $image->resizeCanvas(300, 300 + 60, 'bottom', false, '#ffffff'); // 增加高度,保持宽高比,背景色为白色
  717. $mp_app_name = Settings::get('mp_app_name', '');
  718. $text_tip = '关注'.$mp_app_name.'公众号,可以更方便通知到您';
  719. if(mb_strlen($mp_app_name) > 4){
  720. $text_tip = '关注'.$mp_app_name.'公众号';
  721. }
  722. $image->text($text_tip, 150, 40, function($font){
  723. $font->file(public_path('storage/font/DingTalk_JinBuTi_Regular.ttf')); // 字体文件路径
  724. $font->size(13); // 字体大小
  725. $font->color('#000000'); // 字体颜色
  726. $font->align('center'); // 水平对齐
  727. $font->valign('top'); // 垂直对齐
  728. });
  729. $base64 = 'data:image/png;base64,' . base64_encode($image->encode('png')->getEncoded());
  730. return $this->fail(200043, [
  731. 'title' => '未关注公众号,无法实时获取通知',
  732. 'content' => '前往关注',
  733. 'confirmText' => '去关注',
  734. 'target_type' => 26,
  735. 'target_id' => $base64
  736. ], '未关注公众号');
  737. }
  738. }
  739. }
  740. if(Settings::get('used_mall_push_force_classify', 0) == 1){
  741. if(_empty_($classify_id)){
  742. return $this->fail(200001, [], '请先选择分类');
  743. }
  744. }
  745. if($classify_id > 0){
  746. if(!WxUsedClassify::where('id', $classify_id)->exists()){
  747. return $this->fail(200004, [], '所选分类无效');
  748. }
  749. }else{
  750. $classify_id = 0;
  751. }
  752. if(_empty_($title)){
  753. return $this->fail(200001, [], '请填写标题');
  754. }
  755. $detail = _empty_default_($request->detail, '');
  756. if(_empty_($detail)){
  757. return $this->fail(200001, [], '请填写宝贝介绍');
  758. }
  759. $price = _empty_default_($request->price, 0);
  760. if(_empty_($price)){
  761. return $this->fail(200001, [], '请填写价格');
  762. }
  763. $image_state_change_list = [];
  764. if(_empty_($video_url)){
  765. $video_cover = null;
  766. }
  767. if(!_empty_($video_url)){
  768. if(_empty_($video_cover)){
  769. $res = ImageUtils::upload_video_screenshot($video_url);
  770. if($res && $res['url']){
  771. $video_cover = $res['url'];
  772. }
  773. }
  774. }
  775. if($video_url){
  776. $image_state_change_list[] = $video_url;
  777. if($video_cover){
  778. $image_state_change_list[] = $video_cover;
  779. }
  780. }
  781. if($sync_post_img){
  782. $image_state_change_list[] = $sync_post_img;
  783. }
  784. $original_price = _empty_default_($request->original_price, 0);
  785. $is_self_pickup = _empty_default_($request->is_self_pickup, 1);
  786. if(!in_array($is_self_pickup, [0, 1])){
  787. return $this->fail(200004);
  788. }
  789. $express_cost = 0;
  790. $is_express_delivery = _empty_default_($request->is_express_delivery, 1);
  791. if(!in_array($is_express_delivery, [0, 1])){
  792. return $this->fail(200004);
  793. }
  794. if($is_express_delivery){
  795. $express_cost = _empty_default_($request->express_cost, 0);
  796. $express_cost = 0;
  797. }
  798. $image_urls = _empty_default_($request->image_urls, []);
  799. if($image_urls && is_string($image_urls)){
  800. $image_urls = json_decode($image_urls, true);
  801. }
  802. if( (_empty_($image_urls) || !is_array($image_urls)) && _empty_($video_url) ){
  803. return $this->fail(200001, [], '请上传宝贝图片');
  804. }
  805. $location = _empty_default_($request->location, []);
  806. if(_empty_($location)){
  807. return $this->fail(200001, [], '请选择地址');
  808. }
  809. $longitude = _array_key($location, 'longitude', 0);
  810. $latitude = _array_key($location, 'latitude', 0);
  811. $address_name = _array_key($location, 'address_name', '');
  812. $address_detailed = _array_key($location, 'address_detailed', '');
  813. if(_empty_($longitude) || _empty_($latitude) || _empty_($address_name) || _empty_($address_detailed)){
  814. return $this->fail(200001, [], '请选择地址');
  815. }
  816. $new_imgages = [];
  817. foreach ($image_urls as $img_obj){
  818. $img_url = $img_obj['url'];
  819. $img_info = ImageUtils::get_url_img_info($img_url);
  820. $obj = [
  821. 'url' => $img_url,
  822. 'width' => 0,
  823. 'height' => 0
  824. ];
  825. if($img_info){
  826. $obj['width'] = $img_info['width'];
  827. $obj['height'] = $img_info['height'];
  828. }
  829. $new_imgages[] = $obj;
  830. $image_state_change_list[] = $img_url;
  831. }
  832. // 百度审核
  833. if(UserUtils::user_permissions_check_by_config($uid, 'audit_used_good_white_list')){
  834. $need_manual_review = false;
  835. }else{
  836. $need_manual_review = true;
  837. $is_audit_used_good = Settings::get('is_audit_used_good', 0);
  838. if ($is_audit_used_good == 2) {
  839. $filter_result = BaiduUtils::text_filter($title. ' ' . $detail. ' '. $sync_post_content);
  840. if($filter_result){
  841. if($filter_result['hit_level'] == 2){
  842. // 不合规
  843. return $this->fail(200016, ['tip'=>$filter_result['tip_list'], 'hit_word'=>$filter_result['hit_word']]);
  844. }else if($filter_result['hit_level'] == 0){
  845. // 审核通过
  846. $need_manual_review = false;
  847. }
  848. }
  849. }else if($is_audit_used_good == 0){
  850. $need_manual_review = true;
  851. }else{
  852. $need_manual_review = false;
  853. }
  854. }
  855. // 0:审核中,1:审核通过
  856. $status = 1;
  857. if($need_manual_review){
  858. $status = 0;
  859. }
  860. DB::beginTransaction();
  861. try {
  862. // todo:
  863. if($used_id > 0){
  864. $model = WxUsedGood::find($used_id);
  865. }else{
  866. $model = new WxUsedGood();
  867. $model->user_id = $uid;
  868. }
  869. $model->title = $title;
  870. $model->detail = $detail;
  871. $model->classify_id = $classify_id;
  872. if($video_url){
  873. $model->video_url = $video_url;
  874. $model->video_cover = $video_cover;
  875. }
  876. $model->price = $price;
  877. $model->original_price = $original_price;
  878. $model->is_self_pickup = $is_self_pickup;
  879. $model->is_express_delivery = $is_express_delivery;
  880. $model->express_cost = $express_cost;
  881. $model->longitude = $longitude;
  882. $model->latitude = $latitude;
  883. $model->address_name = $address_name;
  884. $model->address_detailed = $address_detailed;
  885. $model->status = $status;
  886. if($__MINI_GLOBAL_IP__){
  887. $model->ip = $__MINI_GLOBAL_IP__;
  888. }
  889. $model->image_urls = json_encode($new_imgages);
  890. $r = $model->save();
  891. if($r){
  892. if($sync_to_post == 1){
  893. $post_id = PostsRepositores::add($uid, 1, '', $sync_post_content, 0, null, null, !_empty_($sync_post_img) ? [['url'=>$sync_post_img]] : [], '', null, null, null, null,
  894. null, null, null, null, $device, null, null, null, [$model->id], null);
  895. if ($post_id) {
  896. CalculateLikesNumJob::dispatch($post_id);
  897. UpdatePostVideoIdJob::dispatch($post_id);
  898. CalculateFollowsNumJob::dispatch($uid);
  899. Redis::sadd('realtime:post:set', $post_id);
  900. UpdatePostOnlyTextJob::dispatch(0);
  901. UserUtils::add_user_experience($uid, 15, 40);
  902. }
  903. }else{
  904. if($status == 1){
  905. UserUtils::add_user_experience($uid, 15, 20);
  906. }
  907. }
  908. if($image_state_change_list){
  909. Utils::image_state_change($image_state_change_list, 1);
  910. }
  911. if($used_id > 0){
  912. Cache::forget('used:near:tenant:'.$used_id);
  913. }
  914. if($status === 0){
  915. UserUtils::assistant_notice_review(106, $model->id);
  916. }
  917. DB::commit();
  918. return $this->success(['used_good_id' => $model->id]);
  919. }else{
  920. DB::rollBack();
  921. return $this->fail(200002);
  922. }
  923. } catch (\Exception $e) {
  924. DB::rollBack();
  925. _logger_(__file__, __line__, $e->getMessage());
  926. return $this->fail(200002);
  927. }
  928. }
  929. }