Pub.php 15 KB

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