Pub.php 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. <?php
  2. namespace app\common\controller;
  3. use think\App;
  4. use app\enterprise\model\{User,Group,GroupUser};
  5. use think\facade\Session;
  6. use think\facade\Cache;
  7. use think\facade\Db;
  8. use GatewayClient\Gateway;
  9. use app\manage\model\Config;
  10. use thans\jwt\facade\JWTAuth;
  11. /**
  12. * 控制器基础类
  13. */
  14. class Pub
  15. {
  16. /**
  17. * Request实例
  18. * @var \think\Request
  19. */
  20. protected $request;
  21. /**
  22. * 应用实例
  23. * @var \think\App
  24. */
  25. protected $app;
  26. protected $lang;
  27. /**
  28. * 构造方法
  29. * @access public
  30. * @param App $app 应用对象
  31. */
  32. public function __construct(App $app)
  33. {
  34. Gateway::$registerAddress = config('gateway.registerAddress');
  35. $this->app = $app;
  36. $this->request = $this->app->request;
  37. //获取header里面的语言
  38. $this->lang = request()->header('Lang', 'en');
  39. // 控制器初始化
  40. // $this->initialize();
  41. }
  42. public function login(){
  43. $param=request()->param();
  44. $token=$param['token'] ?? '';
  45. // token一键登录
  46. if($token){
  47. $apiStatus=config('app.api_status');
  48. if(!$apiStatus){
  49. return warning(lang('system.apiClose'));
  50. }
  51. $userInfo=Cache::get($token);
  52. if(!$userInfo){
  53. return warning(lang('user.tokenFailure'));
  54. }
  55. }else{
  56. $verifyTime=md5(request()->ip());
  57. $hasError=Cache::get($verifyTime);
  58. if($hasError && $hasError>5){
  59. return warning(lang('user.loginLimit'));
  60. }
  61. $userInfo=User::where(['account'=> $param['account']])->withoutField('register_ip,login_count,update_time,create_time')->find();
  62. if($userInfo==null){
  63. return warning(lang('user.exist'));
  64. }
  65. if($userInfo['status']==0){
  66. return warning(lang('user.forbid'));
  67. }
  68. $password=password_hash_tp($param['password'],$userInfo['salt']);
  69. $code=$param['code'] ?? '';
  70. if($code){
  71. if($code!=Cache::get($param['account'])){
  72. return warning(lang('user.codeErr'));
  73. }
  74. Cache::delete($param['account']);
  75. }else{
  76. if($password!=$userInfo['password']){
  77. $hasError++;
  78. Cache::set($verifyTime,$hasError,300);
  79. return warning(lang('user.passError'));
  80. }
  81. }
  82. }
  83. $userInfo['avatar']=avatarUrl($userInfo['avatar'],$userInfo['realname'],$userInfo['user_id']);
  84. // 如果用户已经有设置
  85. $setting=$userInfo['setting'] ?: '';
  86. if($setting){
  87. $setting['hideMessageName']= $setting['hideMessageName']=='true' ? true : false;
  88. $setting['hideMessageTime']= $setting['hideMessageTime']=='true' ? true : false;
  89. $setting['avatarCricle']= $setting['avatarCricle']=='true' ? true : false;
  90. $setting['isVoice']= $setting['isVoice']=='true' ? true : false;
  91. $setting['sendKey']=1;//(int)$setting['sendKey'];
  92. $userInfo['setting']=$setting;
  93. }
  94. //如果登录信息中含有client——id则自动进行绑定
  95. $client_id=$this->request->param('client_id');
  96. if($client_id){
  97. $cid=$this->request->header('cid','');
  98. $this->doBindUid($userInfo['user_id'],$client_id,$cid);
  99. }
  100. $update=[
  101. 'last_login_time'=>time(),
  102. 'last_login_ip'=>$this->request->ip(),
  103. 'login_count'=>Db::raw('login_count+1')
  104. ];
  105. User::where('user_id',$userInfo['user_id'])->update($update);
  106. $userInfo['qrUrl']=getMainHost().'/scan/u/'.encryptIds($userInfo['user_id']);
  107. unset($userInfo['password'],$userInfo['salt']);
  108. $userInfo['displayName']=$userInfo['realname'];
  109. $userInfo['id']=$userInfo['user_id'];
  110. $authToken=User::refreshToken($userInfo,$param['terminal'] ?? 'web');
  111. $data=[
  112. 'sessionId'=>Session::getId(),
  113. 'authToken'=>$authToken,
  114. 'userInfo'=>$userInfo
  115. ];
  116. return success(lang('user.loginOk'),$data);
  117. }
  118. //退出登录
  119. public function logout(){
  120. try {
  121. $jwtData = JWTAuth::auth();
  122. } catch (\Exception $e) {
  123. return success(lang('user.logoutOk'));
  124. }
  125. $userInfo = $jwtData['info']->getValue();
  126. //解密token中的用户信息
  127. $userInfo = str_encipher($userInfo,false, config('app.aes_token_key'));
  128. if (!$userInfo) {
  129. return success(lang('user.logoutOk'));
  130. }
  131. //解析json
  132. $userInfo = (array)json_decode($userInfo, true);
  133. if($userInfo){
  134. $client_id=$this->request->param('client_id','');
  135. if($client_id){
  136. Gateway::unbindUid($client_id,$userInfo['user_id']);
  137. // 查询团队,如果有团队则加入团队
  138. $group=Group::getMyGroup(['gu.user_id'=>$userInfo['user_id'],'gu.status'=>1]);
  139. if($group){
  140. $group=$group->toArray();
  141. $group_ids=arrayToString($group,'group_id',false);
  142. foreach($group_ids as $v){
  143. Gateway::leaveGroup($client_id, $v);
  144. }
  145. }
  146. }
  147. wsSendMsg(0,'isOnline',['id'=>$userInfo['user_id'],'is_online'=>0]);
  148. }
  149. JWTAuth::invalidate(JWTAuth::token()->get());
  150. return success(lang('user.logoutOk'));
  151. }
  152. // 注册用户
  153. public function register(){
  154. if(env('app.demon_mode',false)){
  155. return warning(lang('system.demoMode'));
  156. }
  157. try{
  158. $data = $this->request->param();
  159. $ip = $this->request->ip();
  160. $systemInfo=Config::getSystemInfo();
  161. $registerInterval=$systemInfo['sysInfo']['registerInterval'] ? : 0;
  162. if(Cache::has('register_'.md5($ip)) && $registerInterval>0){
  163. return warning(lang('user.registerLimit',['time'=>floor($registerInterval/60)]));
  164. }
  165. // 判断系统是否开启注册
  166. if($systemInfo['sysInfo']['regtype']==2){
  167. $inviteCode=$data['inviteCode'] ?? '';
  168. if(!$inviteCode){
  169. return warning(lang('user.closeRegister'));
  170. }
  171. if(!Cache::get($inviteCode)){
  172. return warning(lang('user.inviteCode'));
  173. }
  174. }
  175. $code=$data['code'] ?? '';
  176. if($code){
  177. if($code!=Cache::get($data['account'])){
  178. return warning(lang('user.codeErr'));
  179. }
  180. Cache::delete($data['account']);
  181. }
  182. // 接入用户名检测服务
  183. event('GreenText',['content'=>$data['realname'],'service'=>"nickname_detection"]);
  184. $user=new User();
  185. $verify=$user->checkAccount($data);
  186. if(!$verify){
  187. return warning($user->getError());
  188. }
  189. $salt=\utils\Str::random(4);
  190. if(isset($data['user_id'])){
  191. unset($data['user_id']);
  192. }
  193. if(isset($data['role'])){
  194. unset($data['role']);
  195. }
  196. $data['password'] = password_hash_tp($data['password'],$salt);
  197. $data['salt'] =$salt;
  198. $data['register_ip'] =$this->request->ip();
  199. $data['name_py'] = pinyin_sentence($data['realname']);
  200. $user->save($data);
  201. $data['user_id']=$user->user_id;
  202. $data['language_code'] = $this->lang;
  203. // 监听用户注册后的操作
  204. event('UserRegister',$data);
  205. // x分钟后才能再注册
  206. if($registerInterval){
  207. Cache::set('register_'.md5($ip),$ip,$registerInterval);
  208. }
  209. return success(lang('user.registerOk'), $data);
  210. }catch (\Exception $e){
  211. return error($e->getMessage());
  212. }
  213. }
  214. //头像生成
  215. public function avatar(){
  216. // 图像生成函数
  217. circleAvatar(input('str'),input('s')?:80,input('uid'));die;
  218. }
  219. /**
  220. * 将用户UId绑定到消息推送服务中
  221. * @return \think\response\Json
  222. */
  223. public function bindUid(){
  224. $client_id=$this->request->param('client_id');
  225. $user_id=$this->request->param('user_id');
  226. $cid=$this->request->param('cid','');
  227. try{
  228. $this->doBindUid($user_id,$client_id,$cid);
  229. }catch(\Exception $e){
  230. // 未找到用户
  231. }
  232. return success('');
  233. }
  234. // 执行绑定
  235. public function doBindUid($user_id,$client_id,$cid=''){
  236. // 如果当前ID在线,将其他地方登陆挤兑下线
  237. if(Gateway::isUidOnline($user_id)){
  238. wsSendMsg($user_id,'offline',['id'=>$user_id,'client_id'=>$client_id,'isMobile'=>$this->request->isMobile()]);
  239. }
  240. Gateway::bindUid($client_id, $user_id);
  241. // 查询团队,如果有团队则加入团队
  242. $group=Group::getMyGroup(['gu.user_id'=>$user_id,'gu.status'=>1]);
  243. if($group){
  244. $group=$group->toArray();
  245. $group_ids=arrayToString($group,'group_id',false);
  246. foreach($group_ids as $v){
  247. Gateway::joinGroup($client_id, $v);
  248. }
  249. }
  250. if($cid){
  251. bindCid($user_id,$cid);
  252. }
  253. wsSendMsg(0,'isOnline',['id'=>$user_id,'is_online'=>1]);
  254. }
  255. // 下线通知
  256. public function offline(){
  257. $user_id=input('user_id');
  258. try{
  259. $client_ids=Gateway::getClientIdByUid($user_id);
  260. // 一个终端登录时才发送下线通知
  261. if(count($client_ids)<2){
  262. wsSendMsg(0,'isOnline',['id'=>$user_id,'is_online'=>0]);
  263. }
  264. }catch(\Exception $e){
  265. // 未找到用户
  266. }
  267. return success('');
  268. }
  269. // 设置在线状态
  270. public function setOnline(){
  271. $user_id= (int)input('user_id');
  272. $is_online= (int)input('is_online',1);
  273. try{
  274. // $client_ids=Gateway::getClientIdByUid($user_id);
  275. // // 一个终端登录时才发送下线通知
  276. // if(count($client_ids)<2){
  277. wsSendMsg(0,'isOnline',['id'=>$user_id,'is_online'=>$is_online]);
  278. // }
  279. }catch(\Exception $e){
  280. // 未找到用户
  281. }
  282. return success('');
  283. }
  284. /**
  285. * 将用户团队绑定到消息推送服务中
  286. * @return \think\response\Json
  287. */
  288. public function bindGroup(){
  289. $client_id=input('client_id');
  290. $group_id=input('group_id');
  291. $group_id = explode('-', $group_id)[1];
  292. $user_id=Gateway::getUidByClientId($client_id);
  293. if($user_id){
  294. // 是群成员才能加入群组推送
  295. $groupUser=GroupUser::where(['group_id'=>$group_id,'status'=>1,'user_id'=>$user_id])->find();
  296. if($groupUser){
  297. Gateway::joinGroup($client_id, $group_id);
  298. }
  299. }
  300. return success('');
  301. }
  302. // 获取系统配置信息
  303. public function getSystemInfo(){
  304. $systemInfo=Config::getSystemInfo();
  305. $systemInfo['demon_mode']=env('app.demon_mode',false);
  306. return success('',$systemInfo);
  307. }
  308. // 发送验证码
  309. public function sendCode(){
  310. $account=$this->request->param('account');
  311. $type=$this->request->param('type',1);
  312. if(in_array($type,[3,4]) && !$account){
  313. $userInfo=request()->userInfo;
  314. $acType=\utils\Regular::check_account($userInfo['account']);
  315. if($acType){
  316. $account=$userInfo['account'];
  317. }else{
  318. $account=$userInfo['email'];
  319. }
  320. };
  321. $acType=\utils\Regular::check_account($account);
  322. if(!$acType){
  323. return warning(lang('user.accountVerify'));
  324. }
  325. if(Cache::get($account.'_time')) return warning(lang('user.waitMinute'));
  326. if($type==1){
  327. $text=lang('user.loginAccount');
  328. $actions="login";
  329. }elseif($type==2){
  330. $text=lang('user.registerAccount');
  331. $actions="register";
  332. }elseif($type==3){
  333. $text=lang('user.editPass');
  334. $actions="changePassword";
  335. }else{
  336. $text=lang('user.editAccount');
  337. $actions="changeUserinfo";
  338. }
  339. $code=rand(100000,999999);
  340. Cache::set($account,$code,300);
  341. Cache::set($account.'_time',$code,60);
  342. if($acType==2){
  343. $conf=Config::getFieldValue('smtp');
  344. $conf['temp']='code';
  345. $mail=new \mail\Mail($conf);
  346. $mail->sendEmail([$account],$text,$code);
  347. return success(lang('system.sendOk'));
  348. }else{
  349. $parmes=[
  350. 'code'=>$code
  351. ];
  352. $res=sendSms($account,$actions,$parmes);
  353. return success($res['msg']);
  354. }
  355. }
  356. // 检查app版本升级
  357. public function checkVersion(){
  358. $oldRelease=$this->request->param('release',0);
  359. $setupPage=$this->request->param('setupPage',false);
  360. $platform=$this->request->param('type',1101);
  361. $name=config('version.app_name');
  362. $packageName='';
  363. if($platform==1101){
  364. $teminal='android';
  365. }else{
  366. $teminal='ios';
  367. }
  368. $versionInfo=config('version.'.$teminal);
  369. $data=[
  370. 'versionName'=>$versionInfo['version'],
  371. 'versionCode'=>$versionInfo['release'],
  372. 'updateType'=>$versionInfo['update_type'],
  373. 'versionInfo'=>$versionInfo['update_info'],
  374. 'downloadUrl'=>'',
  375. ];
  376. // 是否手动检测更新,是的话就不能强制更新或者静默更新
  377. if($setupPage){
  378. $data['updateType']='solicit';
  379. }
  380. // 如果旧版本大于等于当前版本则不更新
  381. if($oldRelease>=$versionInfo['release']){
  382. return success('',$data);
  383. }
  384. $downUrl='';
  385. $android='';
  386. // 如果是ios则返回ios地址
  387. if($platform==1101){
  388. $packageName=$name."_Setup_".$versionInfo['version'].".apk";
  389. if(is_file(PACKAGE_PATH . $packageName)){
  390. $android = getMainHost().'/unpackage/'.$packageName;
  391. }
  392. $downUrl=env('app.android_webclip','') ? : $android;
  393. }else{
  394. $downUrl=env('app.ios_webclip','');
  395. }
  396. $data['downloadUrl']=$downUrl;
  397. return success('',$data);
  398. }
  399. }