11 changed files with 1293 additions and 0 deletions
@ -0,0 +1,105 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace app\common\controller; |
||||
|
|
||||
|
use think\App; |
||||
|
use app\enterprise\model\{User,Group}; |
||||
|
use app\index\controller\Extension; |
||||
|
use think\facade\Session; |
||||
|
use think\facade\Cache; |
||||
|
use think\facade\Db; |
||||
|
use GatewayClient\Gateway; |
||||
|
use app\manage\model\Config; |
||||
|
use thans\jwt\facade\JWTAuth; |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* API接口类 |
||||
|
*/ |
||||
|
class Api |
||||
|
{ |
||||
|
/** |
||||
|
* Request实例 |
||||
|
* @var \think\Request |
||||
|
*/ |
||||
|
protected $request; |
||||
|
|
||||
|
/** |
||||
|
* 应用实例 |
||||
|
* @var \think\App |
||||
|
*/ |
||||
|
protected $app; |
||||
|
|
||||
|
protected $middleware=['apiAuth']; |
||||
|
|
||||
|
/** |
||||
|
* 构造方法 |
||||
|
* @access public |
||||
|
* @param App $app 应用对象 |
||||
|
*/ |
||||
|
public function __construct(App $app) |
||||
|
{ |
||||
|
$this->app = $app; |
||||
|
$this->request = $this->app->request; |
||||
|
} |
||||
|
|
||||
|
// 创建用户 |
||||
|
public function createUser() |
||||
|
{ |
||||
|
$data = $this->request->param(); |
||||
|
if(!isset($data['account']) || !isset($data['realname'])){ |
||||
|
return warning(lang('system.parameterError')); |
||||
|
} |
||||
|
$user=new User(); |
||||
|
$verify=$user->checkAccount($data); |
||||
|
if(!$verify){ |
||||
|
return success(lang('user.exist')); |
||||
|
} |
||||
|
$salt=\utils\Str::random(4); |
||||
|
$data['password'] = password_hash_tp(rand(100000,999999),$salt); |
||||
|
$data['salt'] =$salt; |
||||
|
$data['register_ip'] =$this->request->ip(); |
||||
|
$data['name_py'] = pinyin_sentence($data['realname']); |
||||
|
$user->save($data); |
||||
|
$data['user_id']=$user->user_id; |
||||
|
$data['open_id']=encryptIds($user->user_id); |
||||
|
// 监听用户注册后的操作 |
||||
|
event('UserRegister',$data); |
||||
|
return success(lang('user.registerOk'), $data); |
||||
|
} |
||||
|
|
||||
|
// 用户登录 |
||||
|
public function login() |
||||
|
{ |
||||
|
$param=$this->request->param(); |
||||
|
$isMobile=$param['is_mobile'] ?? false; |
||||
|
if(!isset($param['account']) || !isset($param['open_id'])){ |
||||
|
return warning(lang('system.parameterError')); |
||||
|
} |
||||
|
$userInfo=User::where(['account'=> $param['account']])->withoutField('register_ip,login_count,update_time,create_time')->find(); |
||||
|
if(!$userInfo){ |
||||
|
return warning(lang('user.exist')); |
||||
|
} |
||||
|
try{ |
||||
|
$hash_id=decryptIds($param['open_id']); |
||||
|
if($hash_id!=$userInfo['user_id']){ |
||||
|
return warning(lang('user.exist')); |
||||
|
} |
||||
|
}catch (\Exception $e){ |
||||
|
return error($e->getMessage()); |
||||
|
} |
||||
|
$md5=md5(json_encode($userInfo)); |
||||
|
// 将用户信息缓存5分钟 |
||||
|
Cache::set($md5,$userInfo,300); |
||||
|
// 生成Url |
||||
|
if($isMobile){ |
||||
|
$url=getMainHost().'/h5/#/pages/login/index?token='.$md5; |
||||
|
}else{ |
||||
|
$url=getMainHost().'/#/login?token='.$md5; |
||||
|
} |
||||
|
return success(lang('user.loginOk'),$url); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
@ -0,0 +1,390 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace app\common\controller; |
||||
|
|
||||
|
use think\App; |
||||
|
use app\enterprise\model\{User,Group}; |
||||
|
use app\index\controller\Extension; |
||||
|
use think\facade\Session; |
||||
|
use think\facade\Cache; |
||||
|
use think\facade\Db; |
||||
|
use GatewayClient\Gateway; |
||||
|
use app\manage\model\Config; |
||||
|
use thans\jwt\facade\JWTAuth; |
||||
|
|
||||
|
use function Hyperf\Coroutine\wait; |
||||
|
|
||||
|
/** |
||||
|
* 控制器基础类 |
||||
|
*/ |
||||
|
class Pub |
||||
|
{ |
||||
|
/** |
||||
|
* Request实例 |
||||
|
* @var \think\Request |
||||
|
*/ |
||||
|
protected $request; |
||||
|
|
||||
|
/** |
||||
|
* 应用实例 |
||||
|
* @var \think\App |
||||
|
*/ |
||||
|
protected $app; |
||||
|
|
||||
|
/** |
||||
|
* 构造方法 |
||||
|
* @access public |
||||
|
* @param App $app 应用对象 |
||||
|
*/ |
||||
|
public function __construct(App $app) |
||||
|
{ |
||||
|
Gateway::$registerAddress = config('gateway.registerAddress'); |
||||
|
$this->app = $app; |
||||
|
$this->request = $this->app->request; |
||||
|
|
||||
|
// 控制器初始化 |
||||
|
// $this->initialize(); |
||||
|
} |
||||
|
|
||||
|
public function login(){ |
||||
|
$param=request()->param(); |
||||
|
$token=$param['token'] ?? ''; |
||||
|
// token一键登录 |
||||
|
if($token){ |
||||
|
$apiStatus=config('app.api_status'); |
||||
|
if(!$apiStatus){ |
||||
|
return warning(lang('system.apiClose')); |
||||
|
} |
||||
|
$userInfo=Cache::get($token); |
||||
|
if(!$userInfo){ |
||||
|
return warning(lang('user.tokenFailure')); |
||||
|
} |
||||
|
}else{ |
||||
|
$verifyTime=md5(request()->ip()); |
||||
|
$hasError=Cache::get($verifyTime); |
||||
|
if($hasError && $hasError>5){ |
||||
|
return warning(lang('user.loginLimit')); |
||||
|
} |
||||
|
$userInfo=User::where(['account'=> $param['account']])->withoutField('register_ip,login_count,update_time,create_time')->find(); |
||||
|
if($userInfo==null){ |
||||
|
return warning(lang('user.exist')); |
||||
|
} |
||||
|
if($userInfo['status']==0){ |
||||
|
return warning(lang('user.forbid')); |
||||
|
} |
||||
|
$password=password_hash_tp($param['password'],$userInfo['salt']); |
||||
|
$code=$param['code'] ?? ''; |
||||
|
if($code){ |
||||
|
if($code!=Cache::get($param['account'])){ |
||||
|
return warning(lang('user.codeErr')); |
||||
|
} |
||||
|
Cache::delete($param['account']); |
||||
|
}else{ |
||||
|
if($password!=$userInfo['password']){ |
||||
|
$hasError++; |
||||
|
Cache::set($verifyTime,$hasError,300); |
||||
|
return warning(lang('user.passError')); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
$userInfo['avatar']=avatarUrl($userInfo['avatar'],$userInfo['realname'],$userInfo['user_id']); |
||||
|
// 如果用户已经有设置 |
||||
|
$setting=$userInfo['setting'] ?: ''; |
||||
|
if($setting){ |
||||
|
$setting['hideMessageName']= $setting['hideMessageName']=='true' ? true : false; |
||||
|
$setting['hideMessageTime']= $setting['hideMessageTime']=='true' ? true : false; |
||||
|
$setting['avatarCricle']= $setting['avatarCricle']=='true' ? true : false; |
||||
|
$setting['isVoice']= $setting['isVoice']=='true' ? true : false; |
||||
|
$setting['sendKey']=(int)$setting['sendKey']; |
||||
|
$userInfo['setting']=$setting; |
||||
|
} |
||||
|
//如果登录信息中含有client——id则自动进行绑定 |
||||
|
$client_id=$this->request->param('client_id'); |
||||
|
if($client_id){ |
||||
|
$cid=$this->request->header('cid',''); |
||||
|
$this->doBindUid($userInfo['user_id'],$client_id,$cid); |
||||
|
} |
||||
|
$update=[ |
||||
|
'last_login_time'=>time(), |
||||
|
'last_login_ip'=>$this->request->ip(), |
||||
|
'login_count'=>Db::raw('login_count+1') |
||||
|
]; |
||||
|
User::where('user_id',$userInfo['user_id'])->update($update); |
||||
|
$userInfo['qrUrl']=getMainHost().'/scan/u/'.encryptIds($userInfo['user_id']); |
||||
|
unset($userInfo['password'],$userInfo['salt']); |
||||
|
$userInfo['displayName']=$userInfo['realname']; |
||||
|
$userInfo['id']=$userInfo['user_id']; |
||||
|
$authToken=User::refreshToken($userInfo,$param['terminal'] ?? 'web'); |
||||
|
$data=[ |
||||
|
'sessionId'=>Session::getId(), |
||||
|
'authToken'=>$authToken, |
||||
|
'userInfo'=>$userInfo |
||||
|
]; |
||||
|
return success(lang('user.loginOk'),$data); |
||||
|
} |
||||
|
|
||||
|
//退出登录 |
||||
|
public function logout(){ |
||||
|
try { |
||||
|
$jwtData = JWTAuth::auth(); |
||||
|
} catch (\Exception $e) { |
||||
|
return success(lang('user.logoutOk')); |
||||
|
} |
||||
|
|
||||
|
$userInfo = $jwtData['info']->getValue(); |
||||
|
//解密token中的用户信息 |
||||
|
$userInfo = str_encipher($userInfo,false, config('app.aes_token_key')); |
||||
|
|
||||
|
if (!$userInfo) { |
||||
|
return success(lang('user.logoutOk')); |
||||
|
} |
||||
|
//解析json |
||||
|
$userInfo = (array)json_decode($userInfo, true); |
||||
|
if($userInfo){ |
||||
|
$client_id=$this->request->param('client_id',''); |
||||
|
if($client_id){ |
||||
|
Gateway::unbindUid($client_id,$userInfo['user_id']); |
||||
|
// 查询团队,如果有团队则加入团队 |
||||
|
$group=Group::getMyGroup(['gu.user_id'=>$userInfo['user_id'],'gu.status'=>1]); |
||||
|
if($group){ |
||||
|
$group=$group->toArray(); |
||||
|
$group_ids=arrayToString($group,'group_id',false); |
||||
|
foreach($group_ids as $v){ |
||||
|
Gateway::leaveGroup($client_id, $v); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
wsSendMsg(0,'isOnline',['id'=>$userInfo['user_id'],'is_online'=>0]); |
||||
|
} |
||||
|
JWTAuth::invalidate(JWTAuth::token()->get()); |
||||
|
return success(lang('user.logoutOk')); |
||||
|
} |
||||
|
|
||||
|
// 注册用户 |
||||
|
public function register(){ |
||||
|
if(env('app.demon_mode',false)){ |
||||
|
return warning(lang('system.demoMode')); |
||||
|
} |
||||
|
try{ |
||||
|
$data = $this->request->param(); |
||||
|
$ip = $this->request->ip(); |
||||
|
$systemInfo=Config::getSystemInfo(); |
||||
|
$registerInterval=$systemInfo['sysInfo']['registerInterval'] ? : 0; |
||||
|
if(Cache::has('register_'.md5($ip)) && $registerInterval>0){ |
||||
|
return warning(lang('user.registerLimit',['time'=>floor($registerInterval/60)])); |
||||
|
} |
||||
|
// 判断系统是否开启注册 |
||||
|
if($systemInfo['sysInfo']['regtype']==2){ |
||||
|
$inviteCode=$data['inviteCode'] ?? ''; |
||||
|
if(!$inviteCode){ |
||||
|
return warning(lang('user.closeRegister')); |
||||
|
} |
||||
|
if(!Cache::get($inviteCode)){ |
||||
|
return warning(lang('user.inviteCode')); |
||||
|
} |
||||
|
} |
||||
|
$code=$data['code'] ?? ''; |
||||
|
if($code){ |
||||
|
if($code!=Cache::get($data['account'])){ |
||||
|
return warning(lang('user.codeErr')); |
||||
|
} |
||||
|
Cache::delete($data['account']); |
||||
|
} |
||||
|
// 接入用户名检测服务 |
||||
|
event('GreenText',['content'=>$data['realname'],'service'=>"nickname_detection"]); |
||||
|
$user=new User(); |
||||
|
$verify=$user->checkAccount($data); |
||||
|
if(!$verify){ |
||||
|
return warning($user->getError()); |
||||
|
} |
||||
|
$salt=\utils\Str::random(4); |
||||
|
$data['password'] = password_hash_tp($data['password'],$salt); |
||||
|
$data['salt'] =$salt; |
||||
|
$data['register_ip'] =$this->request->ip(); |
||||
|
$data['name_py'] = pinyin_sentence($data['realname']); |
||||
|
$user->save($data); |
||||
|
$data['user_id']=$user->user_id; |
||||
|
// 监听用户注册后的操作 |
||||
|
event('UserRegister',$data); |
||||
|
// x分钟后才能再注册 |
||||
|
if($registerInterval){ |
||||
|
Cache::set('register_'.md5($ip),$ip,$registerInterval); |
||||
|
} |
||||
|
return success(lang('user.registerOk'), $data); |
||||
|
}catch (\Exception $e){ |
||||
|
return error($e->getMessage()); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
//头像生成 |
||||
|
public function avatar(){ |
||||
|
circleAvatar(input('str'),input('s')?:80,input('uid'));die; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将用户UId绑定到消息推送服务中 |
||||
|
* @return \think\response\Json |
||||
|
*/ |
||||
|
public function bindUid(){ |
||||
|
$client_id=$this->request->param('client_id'); |
||||
|
$user_id=$this->request->param('user_id'); |
||||
|
$cid=$this->request->param('cid',''); |
||||
|
try{ |
||||
|
$this->doBindUid($user_id,$client_id,$cid); |
||||
|
}catch(\Exception $e){ |
||||
|
// 未找到用户 |
||||
|
} |
||||
|
return success(''); |
||||
|
} |
||||
|
|
||||
|
// 执行绑定 |
||||
|
public function doBindUid($user_id,$client_id,$cid=''){ |
||||
|
// 如果当前ID在线,将其他地方登陆挤兑下线 |
||||
|
if(Gateway::isUidOnline($user_id)){ |
||||
|
wsSendMsg($user_id,'offline',['id'=>$user_id,'client_id'=>$client_id,'isMobile'=>$this->request->isMobile()]); |
||||
|
} |
||||
|
Gateway::bindUid($client_id, $user_id); |
||||
|
// 查询团队,如果有团队则加入团队 |
||||
|
$group=Group::getMyGroup(['gu.user_id'=>$user_id,'gu.status'=>1]); |
||||
|
if($group){ |
||||
|
$group=$group->toArray(); |
||||
|
$group_ids=arrayToString($group,'group_id',false); |
||||
|
foreach($group_ids as $v){ |
||||
|
Gateway::joinGroup($client_id, $v); |
||||
|
} |
||||
|
} |
||||
|
if($cid){ |
||||
|
bindCid($user_id,$cid); |
||||
|
} |
||||
|
wsSendMsg(0,'isOnline',['id'=>$user_id,'is_online'=>1]); |
||||
|
} |
||||
|
|
||||
|
// 下线通知 |
||||
|
public function offline(){ |
||||
|
$user_id=input('user_id'); |
||||
|
try{ |
||||
|
$client_ids=Gateway::getClientIdByUid($user_id); |
||||
|
// 一个终端登录时才发送下线通知 |
||||
|
if(count($client_ids)<2){ |
||||
|
wsSendMsg(0,'isOnline',['id'=>$user_id,'is_online'=>0]); |
||||
|
} |
||||
|
}catch(\Exception $e){ |
||||
|
// 未找到用户 |
||||
|
} |
||||
|
return success(''); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将用户团队绑定到消息推送服务中 |
||||
|
* @return \think\response\Json |
||||
|
*/ |
||||
|
public function bindGroup(){ |
||||
|
$client_id=input('client_id'); |
||||
|
$group_id=input('group_id'); |
||||
|
$group_id = explode('-', $group_id)[1]; |
||||
|
Gateway::joinGroup($client_id, $group_id); |
||||
|
return success(''); |
||||
|
} |
||||
|
|
||||
|
// 获取系统配置信息 |
||||
|
public function getSystemInfo(){ |
||||
|
$systemInfo=Config::getSystemInfo(); |
||||
|
$systemInfo['demon_mode']=env('app.demon_mode',false); |
||||
|
return success('',$systemInfo); |
||||
|
} |
||||
|
|
||||
|
// 发送验证码 |
||||
|
public function sendCode(){ |
||||
|
$account=$this->request->param('account'); |
||||
|
$type=$this->request->param('type',1); |
||||
|
if(in_array($type,[3,4]) && !$account){ |
||||
|
$userInfo=request()->userInfo; |
||||
|
$acType=\utils\Regular::check_account($userInfo['account']); |
||||
|
if($acType){ |
||||
|
$account=$userInfo['account']; |
||||
|
}else{ |
||||
|
$account=$userInfo['email']; |
||||
|
} |
||||
|
}; |
||||
|
$acType=\utils\Regular::check_account($account); |
||||
|
if(!$acType){ |
||||
|
return warning(lang('user.accountVerify')); |
||||
|
} |
||||
|
if(Cache::get($account.'_time')) return warning(lang('user.waitMinute')); |
||||
|
if($type==1){ |
||||
|
$text=lang('user.loginAccount'); |
||||
|
$actions="login"; |
||||
|
}elseif($type==2){ |
||||
|
$text=lang('user.registerAccount'); |
||||
|
$actions="register"; |
||||
|
}elseif($type==3){ |
||||
|
$text=lang('user.editPass'); |
||||
|
$actions="changePassword"; |
||||
|
}else{ |
||||
|
$text=lang('user.editAccount'); |
||||
|
$actions="changeUserinfo"; |
||||
|
} |
||||
|
$code=rand(100000,999999); |
||||
|
Cache::set($account,$code,300); |
||||
|
Cache::set($account.'_time',$code,60); |
||||
|
if($acType==2){ |
||||
|
$conf=Config::where(['name'=>'smtp'])->value('value'); |
||||
|
$conf['temp']='code'; |
||||
|
$mail=new \mail\Mail($conf); |
||||
|
$mail->sendEmail([$account],$text,$code); |
||||
|
return success(lang('system.sendOk')); |
||||
|
}else{ |
||||
|
$parmes=[ |
||||
|
'code'=>$code |
||||
|
]; |
||||
|
$res=sendSms($account,$actions,$parmes); |
||||
|
return success($res['msg']); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 检查app版本升级 |
||||
|
public function checkVersion(){ |
||||
|
$oldRelease=$this->request->param('release',0); |
||||
|
$setupPage=$this->request->param('setupPage',false); |
||||
|
$platform=$this->request->param('platform',1101); |
||||
|
$name=config('version.app_name'); |
||||
|
$packageName=''; |
||||
|
if($platform==1101){ |
||||
|
$teminal='andriod'; |
||||
|
}else{ |
||||
|
$teminal='ios'; |
||||
|
} |
||||
|
$versionInfo=config('version.'.$teminal); |
||||
|
$data=[ |
||||
|
'versionName'=>$versionInfo['version'], |
||||
|
'versionCode'=>$versionInfo['release'], |
||||
|
'updateType'=>$versionInfo['update_type'], |
||||
|
'versionInfo'=>$versionInfo['update_info'], |
||||
|
'downloadUrl'=>'', |
||||
|
]; |
||||
|
// 是否手动检测更新,是的话就不能强制更新或者静默更新 |
||||
|
if($setupPage){ |
||||
|
$data['updateType']='solicit'; |
||||
|
} |
||||
|
// 如果旧版本大于等于当前版本则不更新 |
||||
|
if($oldRelease>=$versionInfo['release']){ |
||||
|
return success('',$data); |
||||
|
} |
||||
|
$downUrl=''; |
||||
|
$andriod=''; |
||||
|
// 如果是ios则返回ios地址 |
||||
|
if($platform==1101){ |
||||
|
$packageName=$name."_Setup_".$versionInfo['version'].".apk"; |
||||
|
if(is_file(PACKAGE_PATH . $packageName)){ |
||||
|
$andriod = getMainHost().'/unpackage/'.$packageName; |
||||
|
} |
||||
|
$downUrl=env('app.andriod_webclip','') ? : $andriod; |
||||
|
}else{ |
||||
|
$downUrl=env('app.ios_webclip',''); |
||||
|
} |
||||
|
$data['downloadUrl']=$downUrl; |
||||
|
return success('',$data); |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,346 @@ |
|||||
|
<?php |
||||
|
/** |
||||
|
* lvzheAdmin [a web admin based ThinkPHP5] |
||||
|
* @author xiekunyu<raingad@foxmail.com> |
||||
|
*/ |
||||
|
namespace app\common\controller; |
||||
|
|
||||
|
use app\BaseController; |
||||
|
use app\enterprise\model\{File as FileModel,Message,User,Emoji}; |
||||
|
use app\manage\model\{Config}; |
||||
|
use think\facade\Filesystem; |
||||
|
use think\facade\Request; |
||||
|
use think\File; |
||||
|
use FFMpeg\FFMpeg; |
||||
|
use FFMpeg\FFProbe; |
||||
|
use FFMpeg\Coordinate\TimeCode; |
||||
|
|
||||
|
class Upload extends BaseController |
||||
|
{ |
||||
|
protected $middleware = ['checkAuth']; |
||||
|
protected $disk=''; |
||||
|
protected $url=''; |
||||
|
|
||||
|
public function __construct() |
||||
|
{ |
||||
|
parent::__construct(app()); |
||||
|
$this->disk=env('filesystem.driver','local'); |
||||
|
$this->url=getDiskUrl().'/'; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 文件上传 |
||||
|
*/ |
||||
|
public function upload($data,$path,$prefix = "",$fileObj = true) |
||||
|
{ |
||||
|
$message=$data['message'] ?? ''; |
||||
|
if($message){ |
||||
|
$message=json_decode($message,true); |
||||
|
} |
||||
|
$uid=request()->userInfo['user_id'] ?? 1; |
||||
|
if($fileObj){ |
||||
|
$filePath = $path; |
||||
|
}else{ |
||||
|
$filePath = new File($path); |
||||
|
} |
||||
|
$info=$this->getFileInfo($filePath,$path,$fileObj); |
||||
|
if($info['ext']=='' && $message){ |
||||
|
$pathInfo = pathinfo($message['fileName'] ?? ''); |
||||
|
$info['ext'] = $pathInfo['extension']; |
||||
|
$info['name'] =$message['fileName'] ?? ''; |
||||
|
} |
||||
|
$conf=Config::where(['name'=>'fileUpload'])->value('value'); |
||||
|
if($conf['size']*1024*1024 < $info['size']){ |
||||
|
return shutdown(lang('file.uploadLimit',['size'=>$conf['size']])); |
||||
|
} |
||||
|
// 兼容uniapp文件上传 |
||||
|
if($info['ext']=='' && isset($data['ext'])){ |
||||
|
$info['ext']=$data['ext']; |
||||
|
} |
||||
|
$info['ext']=strtolower($info['ext']); |
||||
|
if(!in_array($info['ext'],$conf['fileExt'])){ |
||||
|
return shutdown(lang('file.typeNotSupport')); |
||||
|
} |
||||
|
$fileType=getFileType($info['ext']); |
||||
|
$imageInfo=[]; |
||||
|
if($fileType==2){ |
||||
|
$filecate="image"; |
||||
|
$imageInfo=$this->getImageSizeInfo($info['path']); |
||||
|
}elseif($fileType==3){ |
||||
|
$msgType=$message['type'] ?? ''; |
||||
|
// 如果是语音消息,类型才为语音,否者为文件,主要是兼容发送音频文件 |
||||
|
if($msgType=='voice'){ |
||||
|
$filecate="voice"; |
||||
|
}else{ |
||||
|
$filecate="file"; |
||||
|
} |
||||
|
}elseif($fileType==4){ |
||||
|
$filecate="video"; |
||||
|
}else{ |
||||
|
$filecate="file"; |
||||
|
} |
||||
|
if(!$prefix){ |
||||
|
$prefix=$filecate.'/'.date('Y-m-d').'/'.$uid."/"; |
||||
|
} |
||||
|
$name=str_replace('.'.$info['ext'],'',$info['name']); |
||||
|
$file=FileModel::where(['md5'=>$info['md5']])->find(); |
||||
|
// 判断文件是否存在,如果有则不再上传 |
||||
|
if(!$file){ |
||||
|
$newName = uniqid() . '.' . $info['ext']; |
||||
|
$object = $prefix . $newName; |
||||
|
if($this->disk=='local'){ |
||||
|
$object='storage/'.$object; |
||||
|
} |
||||
|
Filesystem::disk($this->disk)->putFileAs($prefix, $filePath, $newName); |
||||
|
}else{ |
||||
|
$object = $file['src']; |
||||
|
} |
||||
|
// 把左边的/去掉再加上,避免有些有/有些没有 |
||||
|
$object='/'.ltrim($object,'/'); |
||||
|
$ret = [ |
||||
|
"src" => $object, |
||||
|
"name" => $name, |
||||
|
"cate" => $fileType, |
||||
|
"size" => $info['size'], |
||||
|
"md5" => $info['md5'], |
||||
|
"file_type" => $info['mime'], |
||||
|
"ext" => $info['ext'], |
||||
|
"type" =>2, |
||||
|
'user_id'=>$uid, |
||||
|
'videoInfo'=>$imageInfo |
||||
|
]; |
||||
|
|
||||
|
if($message){ |
||||
|
// 自动获取视频第一帧,视频并且是使用的阿里云 |
||||
|
if($message['type']=='video'){ |
||||
|
$videoInfo=$this->getVideoCover($filePath); |
||||
|
if($videoInfo){ |
||||
|
$extends=$videoInfo['videoInfo']; |
||||
|
$extends['poster']=$this->url.$videoInfo['src']; |
||||
|
$message['extends']=$extends; |
||||
|
}else{ |
||||
|
$message['extends']['poster']=getMainHost().'/static/common/img/video.png'; |
||||
|
} |
||||
|
// if($this->disk=='aliyun'){ |
||||
|
// $message['extends']['poster']=$this->url.$ret['src'].'?x-oss-process=video/snapshot,t_1000,m_fast,w_800,f_png'; |
||||
|
// }else{ |
||||
|
// $message['extends']['poster']=getMainHost().'/static/common/img/video.png'; |
||||
|
// } |
||||
|
} |
||||
|
// 如果发送的文件是图片、视频、音频则将消息类型改为对应的类型 |
||||
|
if(in_array($fileType,[2,3,4])){ |
||||
|
$message['type']=$filecate; |
||||
|
} |
||||
|
if($message['type']=='image'){ |
||||
|
$message['extends']=$imageInfo; |
||||
|
} |
||||
|
$newFile=new FileModel; |
||||
|
// 录音就不保存了 |
||||
|
if($message['type']!='voice'){ |
||||
|
$newFile->save($ret); |
||||
|
} |
||||
|
$message['content']=$ret['src']; |
||||
|
$message['file_id']=$newFile->file_id ?? 0; |
||||
|
$message['file_cate']=$fileType; |
||||
|
$message['file_size']=$info['size']; |
||||
|
$message['file_name']= $name.'.'.$info['ext']; |
||||
|
$message['user_id']= $uid; |
||||
|
$messageModel=new Message(); |
||||
|
$data=$messageModel->sendMessage($message,$this->globalConfig); |
||||
|
if(!$data){ |
||||
|
return shutdown($messageModel->getError()); |
||||
|
} |
||||
|
return $data; |
||||
|
}else{ |
||||
|
return $ret; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// 上传一般文件 |
||||
|
public function uploadFile(){ |
||||
|
$param=$this->request->param(); |
||||
|
try{ |
||||
|
$file=request()->file('file'); |
||||
|
$info=$this->upload($param,$file); |
||||
|
return success(lang('file.uploadOk'),$info); |
||||
|
} catch(\Exception $e) { |
||||
|
return error($e->getMessage().$e->getLine()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
// 获取上传文件的信息 |
||||
|
protected function getFileInfo($file,$path,$isObj=false){ |
||||
|
$info= [ |
||||
|
'path'=>$file->getRealPath(), |
||||
|
'size'=>$file->getSize(), |
||||
|
'mime'=>$file->getMime(), |
||||
|
'ext'=>$file->extension(), |
||||
|
'md5'=>$file->md5(), |
||||
|
]; |
||||
|
if($isObj){ |
||||
|
$info['name']=$file->getOriginalName(); |
||||
|
}else{ |
||||
|
// 根据路径获取文件名 |
||||
|
$pathInfo = pathinfo($path); |
||||
|
$info['name'] = $pathInfo['basename']; |
||||
|
} |
||||
|
return $info; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// 上传图片 |
||||
|
public function uploadImage(){ |
||||
|
$param=request::param(); |
||||
|
try{ |
||||
|
$file=request()->file('file'); |
||||
|
$info=$this->upload($param,$file,'image/'.date('Y-m-d').'/'); |
||||
|
$url=$this->url.$info['src']; |
||||
|
return success(lang('file.uploadOk'),$url); |
||||
|
} catch(\Exception $e) { |
||||
|
return error($e->getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 普通上传头像 |
||||
|
public function uploadAvatar(){ |
||||
|
$param=request::param(); |
||||
|
try{ |
||||
|
$file=request()->file('file'); |
||||
|
$uid=request()->userInfo['user_id']; |
||||
|
$info=$this->upload($param,$file,'avatar/'.$uid.'/'); |
||||
|
User::where(['user_id'=>$uid])->update(['avatar'=>$info['src']]); |
||||
|
$url=$this->url.$info['src']; |
||||
|
return success(lang('file.uploadOk'),$url); |
||||
|
} catch(\Exception $e) { |
||||
|
return error($e->getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 服务器上传头像 |
||||
|
public function uploadLocalAvatar($file,$param,$uid){ |
||||
|
try{ |
||||
|
$info=$this->upload($param,$file,'avatar/'.$uid.'/',false); |
||||
|
return $info['src']; |
||||
|
} catch(\Exception $e) { |
||||
|
return $e->getMessage().$e->getLine(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 上传表情 |
||||
|
public function uploadEmoji(){ |
||||
|
$param=request::param(); |
||||
|
try{ |
||||
|
$file=request()->file('file'); |
||||
|
$filePath = $file; |
||||
|
$uid=request()->userInfo['user_id'] ?? 1; |
||||
|
$info=$this->getFileInfo($filePath,$file,true); |
||||
|
if($info['ext']==''){ |
||||
|
$pathInfo = pathinfo($message['fileName'] ?? ''); |
||||
|
$info['ext'] = $pathInfo['extension']; |
||||
|
$info['name'] =$message['fileName'] ?? ''; |
||||
|
} |
||||
|
// 表情不能大于1m |
||||
|
if(2*1024*1024 < $info['size']){ |
||||
|
return shutdown(lang('file.uploadLimit',['size'=>2])); |
||||
|
} |
||||
|
// 兼容uniapp文件上传 |
||||
|
if($info['ext']=='' && isset($param['ext'])){ |
||||
|
$info['ext']=$param['ext']; |
||||
|
} |
||||
|
$info['ext']=strtolower($info['ext']); |
||||
|
if(!in_array($info['ext'],['jpg','jpeg','gif','png'])){ |
||||
|
return shutdown(lang('file.typeNotSupport')); |
||||
|
} |
||||
|
$prefix='emoji/'.$uid.'/'; |
||||
|
$name=str_replace('.'.$info['ext'],'',$info['name']); |
||||
|
$fileInfo=FileModel::where(['md5'=>$info['md5']])->find(); |
||||
|
// 判断文件是否存在,如果有则不再上传 |
||||
|
if(!$fileInfo){ |
||||
|
$newName = uniqid() . '.' . $info['ext']; |
||||
|
$object = $prefix . $newName; |
||||
|
if($this->disk=='local'){ |
||||
|
$object='storage/'.$object; |
||||
|
} |
||||
|
Filesystem::disk($this->disk)->putFileAs($prefix, $filePath, $newName); |
||||
|
$ret = [ |
||||
|
"src" => $object, |
||||
|
"name" => $name, |
||||
|
"cate" => 1, |
||||
|
"size" => $info['size'], |
||||
|
"md5" => $info['md5'], |
||||
|
"file_type" => $info['mime'], |
||||
|
"ext" => $info['ext'], |
||||
|
"type" =>2, |
||||
|
'user_id'=>$uid, |
||||
|
]; |
||||
|
$fileInfo=new FileModel; |
||||
|
$fileInfo->save($ret); |
||||
|
}else{ |
||||
|
$object = $fileInfo->src; |
||||
|
} |
||||
|
// 把左边的/去掉再加上,避免有些有/有些没有 |
||||
|
$object='/'.ltrim($object,'/'); |
||||
|
$emojiInfo=[ |
||||
|
'user_id' => $uid, |
||||
|
"src" => $object, |
||||
|
"name" => $name, |
||||
|
"type" => 2, |
||||
|
"file_id" => $fileInfo->file_id, |
||||
|
]; |
||||
|
Emoji::create($emojiInfo); |
||||
|
return success('',$this->url.$object); |
||||
|
} catch(\Exception $e) { |
||||
|
return $e->getMessage().$e->getLine(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 获取图片的尺寸 |
||||
|
protected function getImageSizeInfo($file){ |
||||
|
$extends=[]; |
||||
|
// 如果图片获取图片的尺寸 |
||||
|
$imageSize = getimagesize($file); |
||||
|
$extends['width']=$imageSize[0]; |
||||
|
$extends['height']=$imageSize[1]; |
||||
|
// 如果宽大于高则为横图,宽度填充模式,否则为竖图,高度填充模式 |
||||
|
if($imageSize[0]>=$imageSize[1]){ |
||||
|
$extends['fixMode']=1; // 宽度填充 |
||||
|
}else{ |
||||
|
$extends['fixMode']=2; // 高度填充 |
||||
|
} |
||||
|
if($imageSize[0]<200 && $imageSize[1]<240){ |
||||
|
$extends['fixMode']=3; // 小图 |
||||
|
} |
||||
|
return $extends; |
||||
|
} |
||||
|
|
||||
|
// 获取视频封面 |
||||
|
public function getVideoCover($filePath){ |
||||
|
$fileName=pathinfo($filePath,PATHINFO_FILENAME).'.jpg'; |
||||
|
$ffmpegPath=env('ffmpeg.bin_path',''); |
||||
|
if(!$ffmpegPath){ |
||||
|
return false; |
||||
|
} |
||||
|
$path=array( |
||||
|
'ffmpeg.binaries' => $ffmpegPath.'/ffmpeg', |
||||
|
'ffprobe.binaries' => $ffmpegPath.'/ffprobe', |
||||
|
'timeout' => 3600, // 进程超时时间 |
||||
|
'ffmpeg.threads' => 12, // FFMpeg应使用的线程数 |
||||
|
); |
||||
|
$ffmpeg = FFMpeg::create($path); |
||||
|
$ffprobe = FFProbe::create($path); |
||||
|
$duration=$ffprobe->format($filePath)->get('duration');// 获取 duration 属性 |
||||
|
$video = $ffmpeg->open($filePath); |
||||
|
$frame = $video->frame(TimeCode::fromSeconds(1)); |
||||
|
$tempPath=root_path().'public/temp'; |
||||
|
$savePath=$tempPath. '/' .$fileName; |
||||
|
$frame->save($savePath); |
||||
|
$info=$this->upload([],$savePath,'cover/'.date('Y-m-d').'/',false); |
||||
|
$info['videoInfo']['duration']= ceil($duration); |
||||
|
unlink($savePath); |
||||
|
return $info; |
||||
|
} |
||||
|
|
||||
|
} |
||||
@ -0,0 +1,54 @@ |
|||||
|
<?php |
||||
|
namespace app\common\listener; |
||||
|
|
||||
|
use think\api\Client; |
||||
|
|
||||
|
// 检测敏感词 |
||||
|
class GreenText |
||||
|
{ |
||||
|
protected $contentTypes = [ |
||||
|
'ad' => '广告引流', |
||||
|
'political_content' => '涉政内容', |
||||
|
'profanity' => '辱骂内容', |
||||
|
'contraband' => '违禁内容', |
||||
|
'sexual_content' => '色情内容', |
||||
|
'violence' => '暴恐内容', |
||||
|
'nonsense' => '无意义内容', |
||||
|
'negative_content' => '不良内容', |
||||
|
'religion' => '宗教内容', |
||||
|
'cyberbullying' => '网络暴力', |
||||
|
'ad_compliance' => '广告法合规' |
||||
|
]; |
||||
|
|
||||
|
public function handle($data){ |
||||
|
$token = config('app.thinkapi_token'); |
||||
|
if(!$token){ |
||||
|
return true; |
||||
|
} |
||||
|
$client = new Client($token); |
||||
|
$pattern = '/<[^>]*>/'; |
||||
|
$content = preg_replace($pattern, '', $data['content']); |
||||
|
$result = $client->greenText() |
||||
|
->withService($data['service']) |
||||
|
->withContent(\utils\Str::msubstr($content,0,500)) |
||||
|
->request(); |
||||
|
|
||||
|
if($result && $result['code']==0){ |
||||
|
$data=$result['data'] ?? ''; |
||||
|
$labels=$data['labels'] ?? ''; |
||||
|
if(!$labels){ |
||||
|
return true; |
||||
|
} |
||||
|
$labels=explode(',',$labels); |
||||
|
$keywords=[]; |
||||
|
if($labels){ |
||||
|
foreach($labels as $v){ |
||||
|
$keywords[]=$this->contentTypes[$v] ?? $v; |
||||
|
} |
||||
|
$msg="您发布的内容包含".implode('、',$keywords)."等违规内容,系统已自动清除!"; |
||||
|
return shutdown($msg,500); |
||||
|
} |
||||
|
} |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
<?php |
||||
|
namespace app\common\listener; |
||||
|
|
||||
|
// 群聊变更 |
||||
|
class GroupChange |
||||
|
{ |
||||
|
public function handle($data){ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,141 @@ |
|||||
|
<?php |
||||
|
namespace app\common\listener; |
||||
|
|
||||
|
use app\enterprise\model\{User,Message,Group,GroupUser}; |
||||
|
use app\manage\model\{Config}; |
||||
|
|
||||
|
// 监听用户注册后的操作 |
||||
|
class UserRegister |
||||
|
{ |
||||
|
|
||||
|
public function handle(User $user,$data){ |
||||
|
try{ |
||||
|
// 查询相关配置信息 |
||||
|
$sysInfo=Config::where(['name'=>'sysInfo'])->value('value'); |
||||
|
if($sysInfo['runMode']!=2){ |
||||
|
return true; |
||||
|
} |
||||
|
// 获取聊天设置 |
||||
|
$chatInfo=Config::where(['name'=>'chatInfo'])->value('value'); |
||||
|
$autoAdduser=$chatInfo['autoAddUser'] ?? []; |
||||
|
$autoTask=$this->createConf(); |
||||
|
// 是否开启自动客服 |
||||
|
if($autoAdduser && $autoAdduser['status']==1){ |
||||
|
// 获取客服ID |
||||
|
if($autoTask['user_id']!=0){ |
||||
|
$autoTask['user_id']=$this->findNextOrFirstId($autoAdduser['user_ids'], $autoTask['user_id'] ? : $autoAdduser['user_ids'][0]); |
||||
|
}else{ |
||||
|
$autoTask['user_id']=$autoAdduser['user_ids'][0] ?? ''; |
||||
|
} |
||||
|
if($autoTask['user_id']){ |
||||
|
$user->update(['cs_uid'=>$autoTask['user_id']],['user_id'=>$data['user_id']]); |
||||
|
// 如果设置了欢迎语则发送欢迎语 |
||||
|
if($autoAdduser['welcome'] ?? ''){ |
||||
|
$userInfo=$user->field('user_id,realname,avatar')->where(['user_id'=>$autoTask['user_id']])->find(); |
||||
|
if($userInfo){ |
||||
|
$userInfo['dispalayName']=$userInfo['realname']; |
||||
|
$userInfo['id']=$userInfo['user_id']; |
||||
|
$userInfo['avatar']=avatarUrl($userInfo['avatar'],$userInfo['realname'],$userInfo['user_id']); |
||||
|
$msg=[ |
||||
|
'id'=>\utils\Str::getUuid(), |
||||
|
'user_id'=>$autoTask['user_id'], |
||||
|
'content'=>$autoAdduser['welcome'], |
||||
|
'toContactId'=>$data['user_id'], |
||||
|
'sendTime'=>time()*1000, |
||||
|
'type'=>'text', |
||||
|
'is_group'=>0, |
||||
|
'status'=>'succeed', |
||||
|
'fromUser'=>$userInfo, |
||||
|
'at'=>[] |
||||
|
]; |
||||
|
Message::sendMsg($msg); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
$autoAddGroup=$chatInfo['autoAddGroup'] ?? []; |
||||
|
// 是否自动加入群聊 |
||||
|
if($autoAddGroup && $autoAddGroup['status']==1){ |
||||
|
$group_id=$autoTask['group_id']??0; |
||||
|
$uid=$autoAddGroup['owner_uid'] ?? 0; |
||||
|
// 未设置群主就不能生成群 |
||||
|
if($uid){ |
||||
|
$userInfo=$user->field('user_id,realname,avatar')->where(['user_id'=>$uid])->find(); |
||||
|
// 成员不存在也不进行操作了 |
||||
|
if(!$userInfo){ |
||||
|
return false; |
||||
|
} |
||||
|
$groupInfo=Group::where(['group_id'=>$group_id])->find(); |
||||
|
// 如果没有群ID就需要创建 |
||||
|
if(!$groupInfo){ |
||||
|
$groupInfo=$this->createGroup($autoAddGroup,$userInfo,$autoTask['group_num']); |
||||
|
} |
||||
|
$groupUserCount=GroupUser::where(['group_id'=>$group_id,'status'=>1])->count(); |
||||
|
if($groupUserCount > ($autoAddGroup['userMax'] ?? 100) - 1 ){ |
||||
|
// 创建下一个群聊 |
||||
|
$groupInfo=$this->createGroup($autoAddGroup,$userInfo,++$autoTask['group_num']); |
||||
|
} |
||||
|
$groupInfo['joinerName']=$data['realname']; |
||||
|
// 进入群聊并发送通知 |
||||
|
GroupUser::joinGroup($data['user_id'],$uid,$groupInfo,'autoAddGroup'); |
||||
|
// 记录本次的群聊ID |
||||
|
$autoTask['group_id']=$groupInfo['group_id']; |
||||
|
} |
||||
|
} |
||||
|
Config::update(['value'=>$autoTask],['name'=>'autoTask']); |
||||
|
return true; |
||||
|
}catch(\Exception $e){ |
||||
|
return shutdown($e->getMessage().$e->getLine()); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// 创建配置文件 |
||||
|
public function createConf(){ |
||||
|
$autoTask=Config::where(['name'=>'autoTask'])->value('value'); |
||||
|
if($autoTask){ |
||||
|
return $autoTask; |
||||
|
}else{ |
||||
|
$autoTask=[ |
||||
|
'group_id'=>0, //群聊ID |
||||
|
'group_num'=>1, //群聊序号 |
||||
|
'user_id'=>0, //上一次的客服ID |
||||
|
]; |
||||
|
Config::create(['name'=>'autoTask','value'=>$autoTask]); |
||||
|
return $autoTask; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 查找ID的下一个值,如果未找到则使用第一个ID |
||||
|
public function findNextOrFirstId($ids, $searchId) { |
||||
|
if(!$ids){ |
||||
|
return 0; |
||||
|
} |
||||
|
// 遍历数组查找$searchId |
||||
|
foreach ($ids as $k => $v) { |
||||
|
// 如果找到了$searchId,则返回它的下一个值(如果存在) |
||||
|
if ($v == $searchId && isset($ids[$k + 1])) { |
||||
|
return $ids[$k + 1]; |
||||
|
} |
||||
|
} |
||||
|
// 如果未找到$searchId,则返回第一个元素 |
||||
|
return $ids[0]; |
||||
|
} |
||||
|
|
||||
|
// 自动创建群聊 |
||||
|
public function createGroup($autoAddGroup,$userInfo,$group_num){ |
||||
|
$data=[ |
||||
|
'create_user'=>$userInfo['user_id'], |
||||
|
'owner_id'=>$userInfo['user_id'], |
||||
|
'name'=>($autoAddGroup['name'] ?? lang('group.name')).$group_num, |
||||
|
'name_py'=>pinyin_sentence($autoAddGroup['name'].$group_num), |
||||
|
'setting'=>json_encode(['manage' => 0, 'invite' => 1, 'nospeak' => 0]), |
||||
|
]; |
||||
|
$group=new Group; |
||||
|
$group->save($data); |
||||
|
// 群主首先进群 |
||||
|
$group->joinerName=$userInfo['realname']; |
||||
|
GroupUser::joinGroup($userInfo['user_id'],$userInfo['user_id'],$group,'autoCreateGroup'); |
||||
|
return $group; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,35 @@ |
|||||
|
<?php |
||||
|
namespace app\common\middleware; |
||||
|
|
||||
|
//验证权限 |
||||
|
class ApiAuth |
||||
|
{ |
||||
|
public function handle($request, \Closure $next) |
||||
|
{ |
||||
|
$apiStatus=config('app.api_status'); |
||||
|
if(!$apiStatus){ |
||||
|
return shutdown(lang('system.apiClose')); |
||||
|
} |
||||
|
$appId=config('app.app_id'); |
||||
|
$appSecret=config('app.app_secret'); |
||||
|
$header = $request->header(); |
||||
|
$app_id=$header['x-im-appid'] ?? ''; |
||||
|
$timeStamp=$header['x-im-timestamp'] ?? 0; |
||||
|
$sign=$header['x-im-sign'] ?? ''; |
||||
|
if(!$app_id || !$timeStamp || !$sign){ |
||||
|
return shutdown(lang('system.parameterError')); |
||||
|
} |
||||
|
// 时间戳不能大约60秒 |
||||
|
if(time()-$timeStamp>60){ |
||||
|
return shutdown(lang('system.longTime')); |
||||
|
} |
||||
|
if($appId!=$app_id){ |
||||
|
return shutdown(lang('system.appIdError')); |
||||
|
} |
||||
|
$signStr=md5($appId.$timeStamp.$appSecret); |
||||
|
if($sign!=$signStr){ |
||||
|
return shutdown(lang('system.signError')); |
||||
|
} |
||||
|
return $next($request); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
<?php |
||||
|
namespace app\common\middleware; |
||||
|
|
||||
|
use Exception; |
||||
|
use thans\jwt\exception\TokenInvalidException; |
||||
|
use thans\jwt\facade\JWTAuth; |
||||
|
use think\facade\Cache; |
||||
|
//验证权限 |
||||
|
class CheckAuth |
||||
|
{ |
||||
|
public function handle($request, \Closure $next) |
||||
|
{ |
||||
|
try { |
||||
|
$jwtData = JWTAuth::auth(); |
||||
|
} catch (Exception $exception) { |
||||
|
|
||||
|
//token有误 |
||||
|
if (get_class($exception) == TokenInvalidException::class) { |
||||
|
return shutdown(lang('user.loginError'), -1); |
||||
|
} |
||||
|
|
||||
|
$errorMsgArr = [ |
||||
|
'Must have token' => lang('user.mustToken'), |
||||
|
'The token is in blacklist.' => lang('user.blacklist'), |
||||
|
'The token is expired.' => lang('user.expired'), |
||||
|
'The token is in blacklist grace period list.' => lang('user.expired') |
||||
|
]; |
||||
|
return shutdown($errorMsgArr[$exception->getMessage()] ?? $exception->getMessage(), -1); |
||||
|
} |
||||
|
|
||||
|
$userInfo = $jwtData['info']->getValue(); |
||||
|
//解密token中的用户信息 |
||||
|
$userInfo = str_encipher($userInfo,false, config('app.aes_token_key')); |
||||
|
|
||||
|
if (!$userInfo) { |
||||
|
return shutdown(lang('user.loginError'), -1); |
||||
|
} |
||||
|
//解析json |
||||
|
$userInfo = (array)json_decode($userInfo, true); |
||||
|
|
||||
|
if(cache('forbidUser_'.$userInfo['id'])){ |
||||
|
JWTAuth::invalidate(JWTAuth::token()->get()); |
||||
|
Cache::delete('forbidUser_'.$userInfo['id']); |
||||
|
return shutdown(lang('user.forbid'), -1); |
||||
|
} |
||||
|
//已经登陆,将用户信息存入请求头 |
||||
|
$request->userInfo = $userInfo; |
||||
|
$request->uid = $userInfo['id']; |
||||
|
$request->userToken = JWTAuth::token()->get(); |
||||
|
return $next($request); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,43 @@ |
|||||
|
<?php |
||||
|
namespace app\common\middleware; |
||||
|
//验证权限 |
||||
|
class ManageAuth |
||||
|
{ |
||||
|
public function handle($request, \Closure $next) |
||||
|
{ |
||||
|
|
||||
|
// 设置演示模式,演示模式下无法修改配置 |
||||
|
$request->demonMode=env('app.demon_mode',false); |
||||
|
if($request->userInfo['user_id']!=1){ |
||||
|
if(!$request->demonMode){ |
||||
|
if($request->userInfo['role']==0){ |
||||
|
shutdown(lang('system.notAuth'),-1); |
||||
|
} |
||||
|
}else{ |
||||
|
$rules=[ |
||||
|
'user/add', |
||||
|
'user/edit', |
||||
|
'user/del', |
||||
|
'user/setrole', |
||||
|
'user/setstatus', |
||||
|
'user/editpassword', |
||||
|
'group/del', |
||||
|
'group/changeowner', |
||||
|
'group/delgroupuser', |
||||
|
'task/starttask', |
||||
|
'task/stoptask', |
||||
|
'config/setconfig', |
||||
|
'index/publishnotice', |
||||
|
'index/delnotice', |
||||
|
'message/dealmsg', |
||||
|
]; |
||||
|
// 获取pathinfo信息 |
||||
|
$pathinfo = strtolower($request->pathinfo()); |
||||
|
if(in_array($pathinfo,$rules)){ |
||||
|
return shutdown(lang('system.demoMode'),400); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return $next($request); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,66 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace app\common\task; |
||||
|
|
||||
|
use yunwuxin\cron\Task; |
||||
|
use think\Exception; |
||||
|
use app\manage\model\{Config}; |
||||
|
use app\enterprise\model\Message; |
||||
|
|
||||
|
// 自动清理消息定时任务 |
||||
|
class ClearMessage extends Task |
||||
|
{ |
||||
|
|
||||
|
// 定时任务日志内容 |
||||
|
protected $content=''; |
||||
|
protected $path=''; |
||||
|
protected $daytime=86400; |
||||
|
|
||||
|
/** |
||||
|
* 自动写入定时任务日志 |
||||
|
* @return \think\response\Json |
||||
|
*/ |
||||
|
protected function writeLog($text) |
||||
|
{ |
||||
|
$this->path = root_path() . 'crontab.txt'; |
||||
|
|
||||
|
$content = '重置中!'; |
||||
|
if (!file_exists($this->path)) { |
||||
|
fopen($this->path, 'w'); |
||||
|
} |
||||
|
if (date('d') != 10) { |
||||
|
$content = file_get_contents($this->path); |
||||
|
} |
||||
|
file_put_contents($this->path, $content . date('Y-m-d H:i:s') . ':' . $text . PHP_EOL); |
||||
|
} |
||||
|
|
||||
|
public function configure() |
||||
|
{ |
||||
|
//设置每天2点执行 |
||||
|
$this->dailyAt('02:00'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 执行任务 |
||||
|
* @return mixed |
||||
|
*/ |
||||
|
protected function execute() |
||||
|
{ |
||||
|
if(date('H:i')!='02:00'){ |
||||
|
return false; |
||||
|
} |
||||
|
try { |
||||
|
$config=Config::getSystemInfo(); |
||||
|
$status=$config['chatInfo']['msgClear'] ?? false; |
||||
|
$days=$config['chatInfo']['msgClearDay'] ?? 0; |
||||
|
if($status && $days){ |
||||
|
$time=time() - ($days * $this->daytime); |
||||
|
$where[]=['create_time','<',$time]; |
||||
|
Message::where($where)->delete(); |
||||
|
} |
||||
|
print "****************消息清理成功******************\n"; |
||||
|
} catch (Exception $e) { |
||||
|
print '消息清理失败:'.$e->getMessage()."\n"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace app\common\task; |
||||
|
|
||||
|
use yunwuxin\cron\Task; |
||||
|
use think\Exception; |
||||
|
use think\facade\Cache; |
||||
|
use app\manage\model\{Config}; |
||||
|
use app\enterprise\model\Message; |
||||
|
|
||||
|
// 自动清理消息定时任务 |
||||
|
class SetAtRead extends Task |
||||
|
{ |
||||
|
|
||||
|
// 定时任务日志内容 |
||||
|
protected $content=''; |
||||
|
protected $path=''; |
||||
|
protected $daytime=86400; |
||||
|
|
||||
|
public function configure() |
||||
|
{ |
||||
|
//设置每天8点执行 |
||||
|
$this->everyMinute(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 执行任务 |
||||
|
* @return mixed |
||||
|
*/ |
||||
|
protected function execute() |
||||
|
{ |
||||
|
try { |
||||
|
$atListQueue=Cache::get('atListQueue'); |
||||
|
if($atListQueue){ |
||||
|
foreach ($atListQueue as $key=>$val){ |
||||
|
$message=Message::where('msg_id',$key)->value('at'); |
||||
|
$atList=($message ?? null) ? explode(',',$message): []; |
||||
|
// 两个数组取差集 |
||||
|
$uniqueArr=array_unique($val); |
||||
|
$newAtList = array_filter($atList, function ($value) use ($uniqueArr) { |
||||
|
return !in_array($value, $uniqueArr); |
||||
|
}); |
||||
|
Message::where('msg_id',$key)->update(['at'=>implode(',',$newAtList)]); |
||||
|
} |
||||
|
Cache::delete('atListQueue'); |
||||
|
} |
||||
|
print "****************设置已读成功******************\n"; |
||||
|
} catch (Exception $e) { |
||||
|
print '设置已读失败:'.$e->getMessage()."\n"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue