WxUserController.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. <?php
  2. namespace App\Admin\Controllers\User;
  3. use App\Admin\Actions\Extensions\ImportRobotUserButton;
  4. use App\Admin\Actions\Extensions\UserNoticeButton;
  5. use App\Admin\Actions\Grid\User\UserBanAndMuteAction;
  6. use App\Admin\Actions\Grid\User\UserGenderManAction;
  7. use App\Admin\Actions\Grid\User\UserGenderWomanAction;
  8. use App\Admin\Actions\Grid\User\UserCoinAction;
  9. use App\Admin\Actions\Grid\User\UserFinancialAction;
  10. use App\Admin\Actions\Grid\User\UserJewelryAction;
  11. use App\Admin\Actions\Grid\User\UserMemberAction;
  12. use App\Admin\Actions\Grid\User\UserPaycodeUpdateAction;
  13. use App\Admin\Actions\Grid\User\UserRealNameAction;
  14. use App\Admin\Actions\Grid\User\UserShareAction;
  15. use App\Admin\Metrics\Users\AuthUsers;
  16. use App\Admin\Repositories\User\WxUser;
  17. use App\Jobs\UpdateUserInfoJob;
  18. use App\Models\User\WxUserOnline;
  19. use App\Wen\Utils\GatewayUtils;
  20. use App\Wen\Utils\Settings;
  21. use App\Wen\Utils\UserUtils;
  22. use Dcat\Admin\Form;
  23. use Dcat\Admin\Grid;
  24. use Dcat\Admin\Show;
  25. use Dcat\Admin\Http\Controllers\AdminController;
  26. use App\Admin\Metrics\Users\TotalUsers;
  27. use App\Admin\Metrics\Users\VipUsers;
  28. use Dcat\Admin\Layout\Content;
  29. use Dcat\Admin\Layout\Row;
  30. use Illuminate\Http\Request;
  31. use Illuminate\Support\Facades\Cache;
  32. use App\Models\Conditions;
  33. use App\Http\Controllers\Api\ConditionsController;
  34. class WxUserController extends AdminController
  35. {
  36. public function users(Request $request)
  37. {
  38. $q = $request->get('q');
  39. global $__MINI_GLOBAL_TENANT_ID__;
  40. if($__MINI_GLOBAL_TENANT_ID__ > 0){
  41. return \App\Models\User\WxUser::where('tenant_id', $__MINI_GLOBAL_TENANT_ID__)->where('user_name', 'like', "%$q%")->where(
  42. function ($query) use ($q){
  43. $query->orWhere('id', (int)$q);
  44. }
  45. )->paginate(null, ['id', 'user_name as text']);
  46. }
  47. return \App\Models\User\WxUser::where('user_name', 'like', "%$q%")->orWhere('id', (int)$q)->paginate(null, ['id', 'user_name as text']);
  48. }
  49. public function index(Content $content)
  50. {
  51. return $content
  52. ->header('用户')
  53. ->description('全部用户')
  54. ->body(function (Row $row) {
  55. $row->column(4,new TotalUsers());
  56. $row->column(4,new AuthUsers());
  57. $row->column(4,new VipUsers());
  58. })
  59. ->body($this->grid());
  60. }
  61. /**
  62. * Make a grid builder.
  63. *
  64. * @return Grid
  65. */
  66. protected function grid()
  67. {
  68. $ip_show = Settings::get('app_ip_user_show', 3);
  69. return Grid::make(new WxUser(), function (Grid $grid) use ($ip_show){
  70. $grid->simplePaginate();
  71. $grid->model()->leftJoin('wx_user_online', 'wx_user.id', '=', 'wx_user_online.user_id');
  72. global $__MINI_GLOBAL_TENANT_ID__;
  73. if($__MINI_GLOBAL_TENANT_ID__ > 0){
  74. $grid->model()->where('tenant_id', '=', $__MINI_GLOBAL_TENANT_ID__);
  75. }
  76. $grid->quickSearch(['id', 'user_name', 'phone', 'email', 'weixin_openid', 'weixin_unionid', 'weixin_app_openid', 'weixin_mp_openid', 'weixin_web_openid', 'weixin_shop_openid'])->placeholder('搜索与用户id,用户名,手机号,邮箱...')->width(35);
  77. $grid->model()->orderBy('id','desc');
  78. $grid->showColumnSelector();
  79. $grid->column('id')->sortable();
  80. $grid->column('user_name');
  81. $grid->column('user_avatar')->image('',50);
  82. // $grid->column('user_background_maps')->image('',50);
  83. // $grid->column('user_background_maps');
  84. // $grid->column('user_introduce');
  85. // $grid->column('user_birthday');
  86. // $grid->column('user_mobile');
  87. // $grid->column('weixin_name')->explode()->label();
  88. // $grid->column('weixin_openid');
  89. $grid->column('a','其他')->display('更多内容')->modal('详情',function ($res){
  90. $user = $this;
  91. $user->origin_phone = _get_origin_attribute('wx_user', [['id', '=', $user->id]], 'phone');
  92. $user->online = WxUserOnline::where('user_id', $user->id)->first();
  93. return view('admin/user/info',compact('user'));
  94. });
  95. // $grid->column('country');
  96. // $grid->column('province');
  97. // $grid->column('city');
  98. // $grid->column('others')->display(function () {
  99. // return '认证:'. $this->is_authentication .'<br/>'.
  100. // '会员' . $this->is_member.'<br/>'.
  101. // '官方' . $this->is_official ? '是':'否';
  102. // });
  103. $grid->column('gender')->using([0 => '未知',1 => '男',2 => '女'])->label([
  104. 0 => 'default',
  105. 1 => '#1E9FFF',
  106. 2 => '#FF69B4'
  107. ])->sortable();
  108. // $grid->column('authentication_id');
  109. if($__MINI_GLOBAL_TENANT_ID__ > 0){
  110. $grid->column('is_official')->display(function ($v) use ($__MINI_GLOBAL_TENANT_ID__){
  111. if(get_user_meta($this->id, 'tenant_id_'.$__MINI_GLOBAL_TENANT_ID__, 'n') == 1){
  112. return true;
  113. }else{
  114. return false;
  115. }
  116. })->switch();
  117. }else{
  118. $grid->column('is_official')->switch()->sortable();
  119. }
  120. $grid->column('is_authentication')->switch()->sortable();;
  121. $grid->column('is_yy')->switch()->sortable();
  122. $grid->column('real_name','真实姓名');
  123. $grid->column('is_member')->using([0=>'否',1=>'是'])->label([
  124. 0 => 'gray',
  125. 1 => 'primary'
  126. ])->sortable();
  127. $grid->column('is_xiangqin_status','相亲展示')->switch()->sortable();
  128. if($ip_show == 1){
  129. $grid->column('country')->display(function ($v){
  130. return '<span title="'.($this->country.'-'.$this->province.'-'.$this->city.'-'.$this->district).'">'.$v.'</span>';
  131. });
  132. }else if($ip_show == 2){
  133. $grid->column('province')->display(function ($v){
  134. return '<span title="'.($this->country.'-'.$this->province.'-'.$this->city.'-'.$this->district).'">'.$v.'</span>';
  135. });
  136. }else if($ip_show == 3){
  137. $grid->column('city')->display(function ($v){
  138. return '<span title="'.($this->country.'-'.$this->province.'-'.$this->city.'-'.$this->district).'">'.$v.'</span>';
  139. });
  140. }else if($ip_show == 3){
  141. $grid->column('district')->display(function ($v){
  142. return '<span title="'.($this->country.'-'.$this->province.'-'.$this->city.'-'.$this->district).'">'.$v.'</span>';
  143. });
  144. }else{
  145. $grid->column('city')->display(function ($v){
  146. return '<span title="'.($this->country.'-'.$this->province.'-'.$this->city.'-'.$this->district).'">'.$v.'</span>';
  147. });
  148. }
  149. $grid->column('user_state')->using([0=>'正常',1=>'用户注销',2=>'管理员封号', 3=>'禁言'])->label([
  150. 0 => 'primary',
  151. 1 => 'red',
  152. 2 =>'gray',
  153. 3 => 'gray'
  154. ])->sortable();
  155. // $grid->column('follow_mp_state', '服务号')->using([0=>'未知',1=>'取关',2=>'已关'])->label([
  156. // 0 => 'gray',
  157. // 1 => 'gray',
  158. // 2 =>'primary'
  159. // ]);
  160. // $grid->column('push_client_id', '推送cid');
  161. $grid->column('who')->display(function ($v){
  162. if($v > 0){
  163. return '<a href="'.admin_url('users?id='.$v).'" target="_blank">'.UserUtils::get_cached_user_name($v).'</a>';
  164. }
  165. return '';
  166. })->sortable();
  167. if($__MINI_GLOBAL_TENANT_ID__ === 0){
  168. $grid->column('invite_benefit')->display(function ($v){
  169. if($v == -1){
  170. return '';
  171. }
  172. return $v;
  173. })->editable()->sortable();
  174. $grid->column('invite_benefit_layer')->select([1=>'普通用户', 2=>'推广专员', 3=>'合伙人']);
  175. }
  176. $grid->column('invite_count')->display(function ($v){
  177. return $v > 0 ? $v.'人' : 0;
  178. })->modal('邀请列表',function ($res){
  179. $user_list = \App\Models\User\WxUser::where('who', $this->id)->where('user_state', 0)->orderBy('created_at', 'desc')->get()->toArray();
  180. return view('admin/user/invite',compact('user_list'));
  181. });
  182. $grid->column('created_at','注册于')->sortable()->display(function ($v){
  183. if($v){
  184. return format_datetime($v->timestamp, 2);
  185. }
  186. return '未知';
  187. });
  188. //$grid->column('online', '最后在线')->display(function ($v){
  189. // return UserUtils::get_user_online_time($this->id, true);
  190. // });
  191. $grid->column('online', '最后在线')->sortable()->display(function ($v){
  192. return UserUtils::get_user_online_time($this->id, true);
  193. });
  194. // $grid->model()->with('online')
  195. // ->leftJoin('wx_user_online', 'wx_user.id', '=', 'wx_user_online.user_id')
  196. // ->orderBy('wx_user_online.online', 'desc');
  197. $grid->column('b','相亲信息')->display('相亲详情')->modal('相亲详情',function ($res){
  198. $user = $this;
  199. $user->origin_phone = _get_origin_attribute('wx_user', [['id', '=', $user->id]], 'phone');
  200. $user->online = WxUserOnline::where('user_id', $user->id)->first();
  201. $conditions = (new ConditionsController())->getConditionsDetailAdmin($user->id);
  202. $getSettings = (new ConditionsController())->getSettings(2);
  203. // 获取 choose_content 所选中的数据
  204. $choose_content = $conditions['choose_content'] ?? [];
  205. $arr_ss = array_filter($getSettings['choose_content'], function($val) use ($choose_content) {
  206. return in_array(trim($val['id']), $choose_content);
  207. });
  208. $arr_ss = array_values($arr_ss);
  209. $conditions['choose_content_list'] = $arr_ss;
  210. //print_r($conditions);exit;
  211. return view('admin/user/xiangqin',compact('user','conditions'));
  212. });
  213. $grid->filter(function (Grid\Filter $filter) {
  214. $filter->equal('id');
  215. $filter->like('user_name');
  216. $filter->equal('gender')->select([0 => '未知',1 => '男',2 => '女']);
  217. $filter->equal('is_official')->select([0=>'否',1=>'是']);
  218. $filter->equal('is_robot')->select([0=>'普通用户', 1=>'待绑定机器人', 2=>'已绑定机器人']);
  219. $filter->equal('who');
  220. $filter->equal('user_state')->select([0=>'正常',1 => '用户注销', 2 => '管理员封号', 3 => '禁言']);
  221. });
  222. // $grid->disableBatchDelete();
  223. // $grid->disableDeleteButton();
  224. if($__MINI_GLOBAL_TENANT_ID__ > 0){
  225. $grid->disableCreateButton();
  226. $grid->disableDeleteButton();
  227. $grid->disableBatchDelete();
  228. }
  229. $grid->batchActions(function ($batch) {
  230. $batch->add(new UserGenderManAction());
  231. $batch->add(new UserGenderWomanAction());
  232. });
  233. $grid->actions(function (Grid\Displayers\Actions $actions) {
  234. global $__MINI_GLOBAL_TENANT_ID__;
  235. if($__MINI_GLOBAL_TENANT_ID__ === 0){
  236. // 编辑
  237. $actions->edit();
  238. $actions->append((new UserPaycodeUpdateAction())->setKey($this->id));
  239. $actions->append((new UserMemberAction())->setKey($this->id));
  240. $actions->append((new UserCoinAction())->setKey($this->id));
  241. $actions->append((new UserFinancialAction())->setKey($this->id));
  242. $actions->append((new UserRealNameAction())->setKey($this->id));
  243. }
  244. $actions->append((new UserJewelryAction())->setKey($this->id));
  245. $actions->append((new UserBanAndMuteAction())->setKey($this->id));
  246. $actions->append((new UserShareAction())->setKey($this->id));
  247. });
  248. if($__MINI_GLOBAL_TENANT_ID__ === 0){
  249. $grid->tools([
  250. new UserNoticeButton(),
  251. new ImportRobotUserButton(),
  252. ]);
  253. }
  254. });
  255. }
  256. /**
  257. * Make a show builder.
  258. *
  259. * @param mixed $id
  260. *
  261. * @return Show
  262. */
  263. protected function detail($id)
  264. {
  265. return Show::make($id, new WxUser(), function (Show $show) {
  266. global $__MINI_GLOBAL_TENANT_ID__;
  267. $show->field('id');
  268. $show->field('user_name');
  269. $show->field('user_avatar');
  270. $show->field('user_background_maps')->image();
  271. $show->field('user_introduce');
  272. $show->field('user_birthday');
  273. $show->field('user_mobile');
  274. $show->field('weixin_name');
  275. $show->field('weixin_openid');
  276. $show->field('weixin_unionid');
  277. $show->field('weixin_mp_openid');
  278. $show->field('weixin_app_openid');
  279. $show->field('weixin_web_openid');
  280. $show->field('weixin_shop_openid');
  281. $show->field('phone');
  282. $show->field('real_name');
  283. $show->field('real_id_card');
  284. $show->field('country_code');
  285. $show->field('email');
  286. $show->field('country');
  287. $show->field('province');
  288. $show->field('city');
  289. $show->field('authentication_id');
  290. $show->field('is_authentication');
  291. $show->field('is_yy');
  292. $show->field('is_xiangqin_status');
  293. $show->field('is_member');
  294. $show->field('is_official');
  295. $show->field('who');
  296. $show->field('invite_benefit');
  297. $show->field('invite_benefit_layer');
  298. $show->field('user_state');
  299. $show->field('shop_id');
  300. $show->field('push_client_id');
  301. $show->field('is_robot');
  302. $show->field('black_reason');
  303. $show->field('created_at');
  304. $show->field('updated_at');
  305. $show->disableDeleteButton();
  306. if($__MINI_GLOBAL_TENANT_ID__ > 0){
  307. $show->disableEditButton();
  308. }
  309. });
  310. }
  311. /**
  312. * Make a form builder.
  313. *
  314. * @return Form
  315. */
  316. protected function form()
  317. {
  318. global $__MINI_GLOBAL_REQUEST_ENV__;
  319. $__MINI_GLOBAL_REQUEST_ENV__ = 'api';
  320. return Form::make(new WxUser(), function (Form $form) {
  321. $uid = $form->model()->id;
  322. $tenant_id = $form->model()->tenant_id;
  323. global $__MINI_GLOBAL_TENANT_ID__;
  324. if($__MINI_GLOBAL_TENANT_ID__ > 0){
  325. if(get_user_meta($uid, 'tenant_id_'.$__MINI_GLOBAL_TENANT_ID__, 'n') == 1){
  326. $form->model()->is_official = 1;
  327. }else{
  328. $form->model()->is_official = 0;
  329. }
  330. }
  331. $is_xiangqin_status = $form->input('is_xiangqin_status');
  332. if (isset($is_xiangqin_status)) {
  333. if ($is_xiangqin_status == 1) {
  334. Conditions::where('user_id', $uid)->update(['is_xiangqin_status' => 1]);
  335. } else {
  336. Conditions::where('user_id', $uid)->update(['is_xiangqin_status' => 0]);
  337. }
  338. // 更新当前用户 is_xiangqin_status 状态
  339. \App\Models\User\WxUser::where('id', $uid)->update(['is_xiangqin_status' => $is_xiangqin_status]);
  340. }
  341. // 获取提交的值
  342. $is_yy = $form->input('is_yy');
  343. // 检测is_yy 是否提交
  344. if (isset($is_yy)) {
  345. if ($is_yy == 1) {
  346. // 更新亿友
  347. Conditions::where('user_id', $uid)->update(['is_yy' => 1]);
  348. } else {
  349. Conditions::where('user_id', $uid)->update(['is_yy' => 0]);
  350. }
  351. // 更新当前用户 is_yy 状态
  352. \App\Models\User\WxUser::where('id', $uid)->update(['is_yy' => $is_yy]);
  353. }
  354. // 修改性别
  355. $gender = $form->input('gender');
  356. if (isset($gender)) {
  357. if ($gender != 0) {
  358. Conditions::where('user_id', $uid)->update(['sex' => $gender]);
  359. }
  360. \App\Models\User\WxUser::where('id', $uid)->update(['gender' => $gender]);
  361. }
  362. $old_user_name = $form->model()->user_name;
  363. $old_user_avatar = $form->model()->user_avatar;
  364. $old_user_state = $form->model()->user_state;
  365. $form->display('id');
  366. $form->radio('gender')->options([0 => '未知',1 => '男',2 => '女']);
  367. $form->text('user_name');
  368. $form->image('user_avatar')->url('files/uploads')->uniqueName()->autoUpload()->default(Settings::get('img_default_avatar', ''));
  369. $form->image('user_background_maps')->url('files/uploads')->uniqueName()->autoUpload()->default(Settings::get('user_background_maps', ''));
  370. $form->radio('is_authentication')->options([0=>'否',1=>'是'])->default(0);
  371. $form->radio('is_official')->options([0=>'否',1=>'是'])->default(0);
  372. // $form->radio('user_state')->options([0=>'正常',1=>'用户注销',2=>'管理员封号', 3=>'禁言']);
  373. // $form->text('black_reason');
  374. if($__MINI_GLOBAL_TENANT_ID__ === 0){
  375. $form->select('who')->options(function ($id) {
  376. if($id){
  377. $user = \App\Models\User\WxUser::find($id);
  378. if ($user) {
  379. return [$user->id => $user->user_name];
  380. }
  381. }
  382. return null;
  383. })->ajax('select/users');
  384. $form->decimal('invite_benefit')->help('-1代表默认同步 [<a href="'.admin_url('invite_benefit/config').'" target="_blank">邀请裂变-配置</a>]中的即时邀请收益,但这里的优先级更高,比如你配置为0.5,则该用户邀请每人获益0.5元');
  385. $form->select('invite_benefit_layer')->options([1=>'普通用户', 2=>'推广专员', 3=>'合伙人'])->default(1);
  386. }
  387. global $__MINI_GLOBAL_TENANT_ID__;
  388. if($__MINI_GLOBAL_TENANT_ID__ > 0){
  389. $form->text('tenant_id', '本站分应用id')->help('忽略这个配置')->default($__MINI_GLOBAL_TENANT_ID__);
  390. }
  391. $form->saving(function (Form $form) use ($uid, $tenant_id){
  392. if(!_empty_($form->input('user_name'))){
  393. $form->user_name = str_replace([' 💙🤖', ' 💗🤖', ' 🤖'], '', $form->input('user_name'));
  394. if(\App\Models\User\WxUser::where('id', '<>', $uid)->where('user_name', $form->input('user_name'))->exists()){
  395. return $form->response()->error('该用户名已存在,请换个名称');
  396. }
  397. }
  398. global $__MINI_GLOBAL_TENANT_ID__;
  399. if($form->isEditing()){
  400. if($__MINI_GLOBAL_TENANT_ID__ > 0){
  401. if($tenant_id != $__MINI_GLOBAL_TENANT_ID__){
  402. return $form->response()->warning('分站不能修改其他分站的用户信息');
  403. }
  404. }
  405. }else if($form->isCreating()){
  406. $form->tenant_id = $__MINI_GLOBAL_TENANT_ID__;
  407. }
  408. if($__MINI_GLOBAL_TENANT_ID__ === 0){
  409. if(_empty_($form->input('who'))){
  410. $form->who = 0;
  411. }
  412. if(_empty_($form->input('invite_benefit')) || $form->input('invite_benefit') < 0){
  413. $form->invite_benefit = -1;
  414. }else{
  415. $form->invite_benefit = round($form->input('invite_benefit'), 2);
  416. }
  417. }else{
  418. $form->deleteInput('who');
  419. $form->deleteInput('invite_benefit');
  420. $form->deleteInput('invite_benefit_layer');
  421. }
  422. $form->weixin_openid = null;
  423. $form->weixin_shop_openid = null;
  424. if(!_empty_($form->is_official, true)){
  425. if($__MINI_GLOBAL_TENANT_ID__ > 0){
  426. if($form->is_official){
  427. update_user_meta($uid, 'tenant_id_'.$__MINI_GLOBAL_TENANT_ID__, 1, 'n');
  428. }else{
  429. update_user_meta($uid, 'tenant_id_'.$__MINI_GLOBAL_TENANT_ID__, null, 'n');
  430. }
  431. $form->deleteInput('is_official');
  432. }
  433. }
  434. });
  435. $form->saved(function (Form $form) use ($old_user_name, $old_user_avatar, $uid, $old_user_state){
  436. $data = $form->updates();
  437. if(isset($data['user_name']) && ($old_user_name != $data['user_name'] || $old_user_avatar != $data['user_avatar'])){
  438. UpdateUserInfoJob::dispatch($uid);
  439. }
  440. Cache::forget('get:cached:user:'.$uid);
  441. GatewayUtils::success(GatewayUtils::uid2client_id($uid), 12);
  442. // if($old_user_state == 2 && $data['user_state'] != 2){
  443. // update_user_meta($uid, 'sql_injection_times', 0, 'n');
  444. // }
  445. $is_official = \App\Models\User\WxUser::where('is_official', 1)->pluck('id')->toArray();
  446. if($is_official){
  447. _update_env([
  448. 'APP_ADMIN_USER_ID' => implode(',', $is_official),
  449. ], [], 1);
  450. }else{
  451. _update_env([
  452. 'APP_ADMIN_USER_ID' => '',
  453. ], [], 1);
  454. }
  455. });
  456. $form->deleting(function (Form $form){
  457. global $__MINI_GLOBAL_TENANT_ID__;
  458. if($__MINI_GLOBAL_TENANT_ID__ > 0){
  459. return $form->response()->error('权限不足,不可以删除其他分站对象');
  460. }
  461. });
  462. });
  463. }
  464. }