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