Pub.php 14 KB

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