19 changed files with 3549 additions and 0 deletions
@ -0,0 +1,99 @@ |
|||
<?php |
|||
|
|||
namespace app\enterprise\controller; |
|||
|
|||
use app\BaseController; |
|||
|
|||
use app\enterprise\model\{Emoji as EmojiModel,File,Message}; |
|||
use think\facade\Filesystem; |
|||
use think\facade\View; |
|||
class Emoji extends BaseController |
|||
{ |
|||
// 表情列表 |
|||
public function index() |
|||
{ |
|||
$map=['status'=>1,'user_id'=>$this->uid,'type'=>2]; |
|||
$list = EmojiModel::where($map)->field('id,name,src,file_id')->order('update_time desc')->select(); |
|||
$data=[]; |
|||
if($list){ |
|||
$data=$list->toArray(); |
|||
foreach ($data as $k => $v) { |
|||
$url=getFileUrl($v['src']); |
|||
$data[$k]['src'] =$url; |
|||
$data[$k]['title'] =$v['name']; |
|||
} |
|||
} |
|||
return success('', $data, count($data)); |
|||
} |
|||
|
|||
// 添加表情 |
|||
public function add(){ |
|||
$param = $this->request->param(); |
|||
$file_id=$param['file_id']; |
|||
$fileInfo=File::find($file_id); |
|||
if(!$fileInfo){ |
|||
return warning(lang('system.exits')); |
|||
} |
|||
$exist=EmojiModel::where(['user_id'=>$this->uid,'file_id'=>$file_id])->find(); |
|||
// 判断是否已经有了当前表情,有了就更新 |
|||
if($exist){ |
|||
EmojiModel::where(['id'=>$exist['id']])->update(['update_time'=>time()]); |
|||
}else{ |
|||
$info=[ |
|||
'user_id'=>$this->uid, |
|||
'type'=>2, |
|||
'file_id'=>$file_id, |
|||
'name'=>$fileInfo->name, |
|||
'src'=>$fileInfo->src, |
|||
]; |
|||
EmojiModel::create($info); |
|||
} |
|||
return success(lang('system.addOk')); |
|||
} |
|||
|
|||
// 删除表情 |
|||
public function del(){ |
|||
$ids = $this->request->param('ids',[]); |
|||
if(!is_array($ids) || $ids==[]){ |
|||
return warning(lang('system.parameterError')); |
|||
} |
|||
foreach($ids as $id){ |
|||
$emoji=EmojiModel::where(['id'=>$id,'user_id'=>$this->uid])->find(); |
|||
if(!$emoji){ |
|||
continue; |
|||
} |
|||
$res=EmojiModel::where(['id'=>$id])->delete(); |
|||
if($res){ |
|||
$exist=EmojiModel::where(['file_id'=>$emoji['file_id']])->find(); |
|||
$exist2=Message::where(['file_id'=>$emoji['file_id']])->find(); |
|||
// 如果文件没有引用了,就删除掉源文件 |
|||
if(!$exist || !$exist2){ |
|||
$disk=env('filesystem.driver','local'); |
|||
$file=File::find($emoji['file_id']); |
|||
Filesystem::disk($disk)->delete($file->src); |
|||
} |
|||
} |
|||
} |
|||
return success(lang('system.delOk')); |
|||
|
|||
} |
|||
|
|||
// 移动表情 |
|||
public function move(){ |
|||
$ids = $this->request->param('ids',[]); |
|||
if(!is_array($ids) || $ids==[]){ |
|||
return warning(lang('system.parameterError')); |
|||
} |
|||
foreach($ids as $id){ |
|||
$emoji=EmojiModel::where(['id'=>$id,'user_id'=>$this->uid])->find(); |
|||
if(!$emoji){ |
|||
continue; |
|||
} |
|||
EmojiModel::where(['id'=>$id])->update(['update_time'=>time()]); |
|||
} |
|||
return success(lang('system.success')); |
|||
|
|||
} |
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,92 @@ |
|||
<?php |
|||
|
|||
namespace app\enterprise\controller; |
|||
|
|||
use app\BaseController; |
|||
|
|||
use app\enterprise\model\{File,User,Message}; |
|||
use think\facade\View; |
|||
class Files extends BaseController |
|||
{ |
|||
// 文件列表 |
|||
public function index() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$is_all = $param['is_all'] ?? 0; |
|||
$map = []; |
|||
$data=[]; |
|||
// 如果是查询全部,就查询file表,否则查询message表 |
|||
if ($is_all) { |
|||
if ($param['cate'] ?? 0) { |
|||
$map[] = ['cate', '=', $param['cate']]; |
|||
} |
|||
$model = new File(); |
|||
if ($param['keywords'] ?? '') { |
|||
$model = $model->where('name', 'like', '%' . $param['keywords'] . '%'); |
|||
} |
|||
$list = $this->paginate($model->where($map)->order('file_id desc')); |
|||
|
|||
if ($list) { |
|||
$data = $list->toArray()['data']; |
|||
$userList = User::matchUser($data, true, 'user_id', 120); |
|||
foreach ($data as $k => $v) { |
|||
$url=getFileUrl($v['src']); |
|||
$data[$k]['src'] =$url; |
|||
$data[$k]['preview'] = previewUrl($url); |
|||
$data[$k]['extUrl'] = getExtUrl($v['src']); |
|||
$data[$k]['name'] = $v['name'].'.'.$v['ext']; |
|||
$data[$k]['msg_type'] = getFileType($v['ext'],true); |
|||
$data[$k]['user_id_info'] = $userList[$v['user_id']] ?? []; |
|||
$data[$k]['download'] = getMainHost().'/filedown/'.encryptIds($v['file_id']); |
|||
} |
|||
|
|||
} |
|||
} else { |
|||
$map = [ |
|||
['file_id', '>', 0], |
|||
['type', '<>', 'voice'], |
|||
['is_group', '=', 0], |
|||
['is_undo', '=', 0], |
|||
]; |
|||
if ($param['cate'] ?? 0) { |
|||
$map[] = ['file_cate', '=', $param['cate']]; |
|||
} |
|||
$user_id = $this->uid; |
|||
$model = new Message(); |
|||
if ($param['keywords'] ?? '') { |
|||
$map[] = ['file_name', 'like', '%' . $param['keywords'] . '%']; |
|||
} |
|||
$role = $param['role'] ?? 0; |
|||
$where=[]; |
|||
if($role==1){ |
|||
$map[] = ['from_user', '=', $user_id]; |
|||
}elseif($role==2){ |
|||
$map[] = ['to_user', '=', $user_id]; |
|||
}else{ |
|||
$where='(from_user='.$user_id.' or to_user='.$user_id.')'; |
|||
} |
|||
|
|||
$list = $this->paginate($model->where($map)->where($where)->order('create_time desc')); |
|||
if ($list) { |
|||
$data = $list->toArray()['data']; |
|||
$userList = User::matchUser($data, true, 'from_user', 120); |
|||
foreach ($data as $k => $v) { |
|||
$content=str_encipher($v['content'],false); |
|||
$url=getFileUrl($content); |
|||
$data[$k]['src'] = $url; |
|||
$data[$k]['preview'] = previewUrl($url); |
|||
$data[$k]['extUrl'] = getExtUrl($content); |
|||
$data[$k]['cate'] = $v['file_cate']; |
|||
$data[$k]['name'] = $v['file_name']; |
|||
$data[$k]['size'] = $v['file_size']; |
|||
$data[$k]['msg_type'] = $v['type']; |
|||
$ext=explode('.',$content); |
|||
$data[$k]['ext'] = end($ext); |
|||
$data[$k]['user_id_info'] = $userList[$v['from_user']] ?? []; |
|||
$data[$k]['download'] = getMainHost().'/filedown/'.encryptIds($v['file_id']); |
|||
} |
|||
} |
|||
} |
|||
return success('', $data, $list->total(), $list->currentPage()); |
|||
} |
|||
} |
|||
@ -0,0 +1,181 @@ |
|||
<?php |
|||
|
|||
namespace app\enterprise\controller; |
|||
|
|||
use app\BaseController; |
|||
|
|||
use app\enterprise\model\{Friend as FriendModel,User}; |
|||
|
|||
class Friend extends BaseController |
|||
{ |
|||
// 好友申请列表 |
|||
public function index() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$map = []; |
|||
$map[]=['is_invite','=',1]; |
|||
$isMine=$param['is_mine'] ?? 0; |
|||
if($isMine){ |
|||
// 我发起的 |
|||
$map[]=['create_user','=',$this->uid]; |
|||
}else{ |
|||
// 我收到的 |
|||
$map[]=['friend_user_id','=',$this->uid]; |
|||
} |
|||
$data=[]; |
|||
$model = new FriendModel(); |
|||
$list = $this->paginate($model->where($map)->order('friend_id desc')); |
|||
if ($list) { |
|||
$data = $list->toArray()['data']; |
|||
$userList = User::matchUser($data, true, ['create_user','friend_user_id'], 120); |
|||
foreach ($data as $k => $v) { |
|||
$data[$k]['create_user_info'] = $userList[$v['create_user']] ?? []; |
|||
$data[$k]['user_id_info'] = $userList[$v['friend_user_id']] ?? []; |
|||
$data[$k]['is_group'] = 0; |
|||
} |
|||
} |
|||
return success('', $data,$list->total(),$list->currentPage()); |
|||
} |
|||
|
|||
// 添加好友 |
|||
public function add() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$user_id=$param['user_id'] ?? 0; |
|||
if($user_id==$this->uid){ |
|||
return warning(lang('friend.notAddOwn')); |
|||
} |
|||
// 查看是否限制了好友上限 |
|||
if($this->userInfo['friend_limit']!=0 && $this->userInfo['role']==0){ |
|||
$myFriend=FriendModel::where(['create_user'=>$this->userInfo['user_id']])->count(); |
|||
// 好友已达上限 |
|||
if($myFriend>$this->userInfo['friend_limit'] || $this->userInfo['friend_limit']<0){ |
|||
return warning(lang('friend.limit')); |
|||
} |
|||
} |
|||
$friend=FriendModel::where(['friend_user_id'=>$user_id,'create_user'=>$this->uid])->find(); |
|||
if($friend){ |
|||
if($friend->status==1){ |
|||
return warning(lang('friend.already')); |
|||
}elseif($friend->status==2){ |
|||
return warning(lang('friend.repeatApply')); |
|||
} |
|||
} |
|||
$status=2; |
|||
$otherFriend=FriendModel::where(['friend_user_id'=>$this->uid,'create_user'=>$user_id])->find(); |
|||
if($otherFriend){ |
|||
if($otherFriend->status>0){ |
|||
$status=1; |
|||
} |
|||
} |
|||
$model = new FriendModel(); |
|||
$data=[ |
|||
'friend_user_id'=>$user_id, |
|||
'status'=>$status, |
|||
'create_user'=>$this->uid, |
|||
'remark'=>$param['remark'], |
|||
'is_invite'=>1 // 是否为发起方 |
|||
]; |
|||
$model->save($data); |
|||
$msg=[ |
|||
'fromUser'=>[ |
|||
'id'=>'system', |
|||
'displayName'=>lang('friend.new'), |
|||
'avatar'=>'', |
|||
], |
|||
'toContactId'=>'system', |
|||
'id'=>uniqid(), |
|||
'is_group'=>2, |
|||
'content'=>lang('friend.apply'), |
|||
'status'=>'succeed', |
|||
'sendTime'=>time()*1000, |
|||
'type'=>'event', |
|||
'fileSize'=>0, |
|||
'fileName'=>'', |
|||
]; |
|||
// 发送好友申请 |
|||
wsSendMsg($user_id,'simple',$msg); |
|||
return success(lang('system.addOk')); |
|||
} |
|||
|
|||
// 接受或者拒绝好友申请 |
|||
public function update() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$friend=FriendModel::find($param['friend_id']); |
|||
if(!$friend){ |
|||
return warning(lang('friend.notApply')); |
|||
} |
|||
$map=[ |
|||
'friend_id'=>$param['friend_id'] |
|||
]; |
|||
FriendModel::where($map)->update(['status'=>$param['status']]); |
|||
// 如果是接收,就添加到好友列表 |
|||
if($param['status']){ |
|||
$data=[ |
|||
'friend_user_id'=>$friend->create_user, |
|||
'create_user'=>$this->uid, |
|||
]; |
|||
$newFriend=FriendModel::where($data)->find(); |
|||
if($newFriend){ |
|||
FriendModel::where($data)->update(['status'=>1]); |
|||
return success(lang('friend.already')); |
|||
}else{ |
|||
$data['status']=1; |
|||
FriendModel::create($data); |
|||
} |
|||
$content=lang('friend.newChat'); |
|||
$userM=new User; |
|||
// 将对方的信息发送给我,把我的信息发送对方 |
|||
$user=$userM->setContact($friend->create_user,0,'event',$content); |
|||
if($user){ |
|||
wsSendMsg($this->uid,'appendContact',$user); |
|||
} |
|||
$myInfo=$userM->setContact($this->uid,0,'event',$content); |
|||
if($myInfo){ |
|||
wsSendMsg($friend->create_user,'appendContact',$myInfo); |
|||
} |
|||
|
|||
} |
|||
return success(''); |
|||
} |
|||
|
|||
|
|||
// 删除好友 |
|||
public function del() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$map=['friend_user_id'=>$param['id'],'create_user'=>$this->uid]; |
|||
$friend=FriendModel::where($map)->find(); |
|||
if(!$friend){ |
|||
return warning(lang('friend.not')); |
|||
} |
|||
// 需要删除双方的好友关系 |
|||
FriendModel::where($map)->delete(); |
|||
FriendModel::where(['friend_user_id'=>$this->uid,'create_user'=>$param['id']])->delete(); |
|||
// 性质和删除群聊一样 |
|||
wsSendMsg($param['id'],'removeGroup',['group_id'=>$this->uid]); |
|||
return success(lang('system.delOk')); |
|||
} |
|||
|
|||
// 设置好友备注 |
|||
public function setNickname() |
|||
{ |
|||
$param = $this->request->param(); |
|||
if(!$param['nickname']){ |
|||
return warning(lang('system.notNull')); |
|||
} |
|||
FriendModel::update(['nickname'=>$param['nickname']],['friend_id'=>$param['friend_id']]); |
|||
return success(lang('system.editOk')); |
|||
} |
|||
|
|||
// 获取最新的一条和申请的总数 |
|||
public function getApplyMsg(){ |
|||
$model = new FriendModel(); |
|||
$map[]=['friend_user_id','=',$this->uid]; |
|||
$map[]=['status','=',2]; |
|||
$count=$model->where($map)->count(); |
|||
return success('', $count); |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,528 @@ |
|||
<?php |
|||
|
|||
namespace app\enterprise\controller; |
|||
|
|||
use app\BaseController; |
|||
use app\enterprise\model\{User,Group as GroupModel,GroupUser,Message}; |
|||
use think\Exception; |
|||
use think\facade\Db; |
|||
use app\common\controller\Upload; |
|||
use GatewayClient\Gateway; |
|||
use utils\Str; |
|||
|
|||
class Group extends BaseController |
|||
{ |
|||
|
|||
protected $setting=['manage' => 0, 'invite' => 1, 'nospeak' => 0]; |
|||
// 获取联系人列表 |
|||
public function getAllUser(){ |
|||
$param=$this->request->param(); |
|||
$user_ids=isset($param['user_ids'])?$param['user_ids']:[]; |
|||
$groupId=$param['group_id'] ?? ''; |
|||
$group_id=''; |
|||
if($groupId){ |
|||
$group_id=explode('-',$groupId)[1]; |
|||
} |
|||
$data=User::getAllUser([['status','=',1],['user_id','<>',$this->userInfo['user_id']]],$user_ids,$this->uid,$group_id); |
|||
return success('',$data); |
|||
} |
|||
|
|||
// 获取群成员 |
|||
public function groupUserList() |
|||
{ |
|||
$param = $this->request->param(); |
|||
try { |
|||
$group_id = explode('-', $param['group_id'])[1]; |
|||
$listRows = $this->request->param('limit',0); |
|||
$pageSize = $this->request->param('page',1); |
|||
$map=['group_id' => $group_id]; |
|||
if($listRows){ |
|||
$list=GroupUser::where($map)->order('role asc')->paginate(['list_rows'=>$listRows,'page'=>$pageSize]); |
|||
$data=$list->toArray()['data']; |
|||
$count=$list->total(); |
|||
}else{ |
|||
$data=GroupUser::where($map)->order('role asc')->select(); |
|||
$count=count($data); |
|||
} |
|||
$data =User::matchAllUser($data,true,'user_id'); |
|||
return success('', $data,$count); |
|||
} catch (Exception $e) { |
|||
return error($e->getMessage()); |
|||
} |
|||
} |
|||
|
|||
// 获取群基本信息 |
|||
public function groupInfo() |
|||
{ |
|||
$param = $this->request->param(); |
|||
try { |
|||
$jm='qr'; |
|||
$groupId=$param['group_id'] ?? ''; |
|||
$groupInfo = explode('-', $groupId); |
|||
$group_id=$groupInfo[1]; |
|||
$group=GroupModel::find($group_id)->toArray(); |
|||
$userList=User::matchUser($group,false,'owner_id'); |
|||
$userCount=GroupUser::where(['group_id'=>$group_id])->count(); |
|||
$userInfo=$userList[$group['owner_id']]; |
|||
$expire=time()+7*86400; |
|||
$token=urlencode(authcode($this->uid.'-'.$group_id,'ENCODE', $jm,7*86400)); |
|||
$qrUrl=getMainHost().'/scan/g/'.$token; |
|||
$group['id']=$groupId; |
|||
$group['qrUrl']=$qrUrl; |
|||
$group['qrExpire']=date('m月d日',$expire); |
|||
$group['userInfo']=$userInfo; |
|||
$group['ownerName']=$userInfo['realname']; |
|||
$group['groupUserCount']=$userCount; |
|||
$group['displayName']=$group['name']; |
|||
$group['avatar']=avatarUrl($group['avatar'],$group['name'],$group['group_id'],120); |
|||
$group['setting']=$group['setting']?json_decode($group['setting'],true):['manage' => 0, 'invite' => 1, 'nospeak' => 0]; |
|||
$group['isJoin']=GroupUser::where(['group_id'=>$group_id,'user_id'=>$this->uid])->value('role') ?: 0; |
|||
return success('', $group); |
|||
} catch (Exception $e) { |
|||
return error($e->getMessage()); |
|||
} |
|||
} |
|||
|
|||
// 修改团队名称 |
|||
public function editGroupName() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$group_id = explode('-', $param['id'])[1]; |
|||
$role=GroupUser::where(['group_id'=>$group_id,'user_id'=>$this->userInfo['user_id']])->value('role'); |
|||
if($role>2){ |
|||
return warning(lang('group.notAuth')); |
|||
} |
|||
GroupModel::where(['group_id' => $group_id])->update(['name' => $param['displayName'],'name_py'=>pinyin_sentence($param['displayName'])]); |
|||
$param['editUserName'] = $this->userInfo['realname']; |
|||
$action='editGroupName'; |
|||
event('GroupChange', ['action' => $action, 'group_id' => $group_id, 'param' => $param]); |
|||
wsSendMsg($group_id, $action, $param, 1); |
|||
return success(lang('system.editOk')); |
|||
} |
|||
|
|||
// 添加群成员 |
|||
public function addGroupUser(){ |
|||
$param = $this->request->param(); |
|||
$uid=$this->userInfo['user_id']; |
|||
$group_id = explode('-', $param['id'])[1] ?? 0; |
|||
if(!$group_id){ |
|||
return warning(lang('system.exits')); |
|||
} |
|||
$groupInfo=GroupModel::where(['group_id'=>$group_id])->find(); |
|||
if(!$groupInfo){ |
|||
return warning(lang('system.exits')); |
|||
} |
|||
$user_ids=$param['user_ids']; |
|||
$groupUserCount=GroupUser::where(['group_id'=>$group_id,'status'=>1])->count(); |
|||
if((count($user_ids) + $groupUserCount) > $this->chatSetting['groupUserMax'] && $this->chatSetting['groupUserMax']!=0){ |
|||
return warning(lang('group.userLimit',['userMax'=>$this->chatSetting['groupUserMax']])); |
|||
} |
|||
if(count($user_ids)>20){ |
|||
return warning(lang('group.inviteLimit',['limit'=>20])); |
|||
} |
|||
try{ |
|||
foreach($user_ids as $k=>$v){ |
|||
$item=[ |
|||
'group_id'=>$group_id, |
|||
'user_id'=>$v, |
|||
'role'=>3, |
|||
'invite_id'=>$uid |
|||
]; |
|||
$hasUser=GroupUser::where(['group_id'=>$group_id,'user_id'=>$v])->find(); |
|||
// 查询是否有人 |
|||
if(!$hasUser){ |
|||
GroupUser::create($item); |
|||
} |
|||
} |
|||
$url=GroupModel::setGroupAvatar($group_id); |
|||
// 更新原来群聊的头像和成员列表 |
|||
wsSendMsg($group_id,"addGroupUser",['group_id'=>$param['id'],'avatar'=>$url],1); |
|||
// 给新成员添加新群聊信息 |
|||
$user=new User(); |
|||
$data=$user->setContact($group_id,1,'text',lang('group.invite',['username'=>$this->userInfo['realname']]),$groupInfo); |
|||
wsSendMsg($user_ids, 'addGroup', $data); |
|||
return success(lang('system.addOk')); |
|||
}catch(Exception $e){ |
|||
return error($e->getMessage()); |
|||
} |
|||
} |
|||
|
|||
// 设置管理员 |
|||
public function setManager(){ |
|||
$param = $this->request->param(); |
|||
$uid=$this->userInfo['user_id']; |
|||
$group_id = explode('-', $param['id'])[1]; |
|||
$user_id=$param['user_id']; |
|||
$role=$param['role']; |
|||
if(!GroupUser::checkAuth(['group_id'=>$group_id,'user_id'=>$uid])){ |
|||
return warning(lang('system.notAuth')); |
|||
} |
|||
$groupUser=GroupUser::where(['group_id'=>$group_id,'user_id'=>$user_id])->find(); |
|||
if($groupUser){ |
|||
$groupUser->role=$role; |
|||
$groupUser->save(); |
|||
$avatar=GroupModel::where(['group_id'=>$group_id])->value('avatar'); |
|||
$url=avatarUrl($avatar); |
|||
wsSendMsg($group_id,"setManager",['group_id'=>$param['id'],'user_id'=>$user_id,'avatar'=>$url],1); |
|||
return success(lang('system.settingOk')); |
|||
}else{ |
|||
return warning(''); |
|||
} |
|||
|
|||
} |
|||
|
|||
// 添加群聊 |
|||
public function add(){ |
|||
$param = $this->request->param(); |
|||
$uid=$this->userInfo['user_id']; |
|||
$user_ids=$param['user_ids'] ?? []; |
|||
if($this->chatSetting['groupChat']==0){ |
|||
return warning(lang('system.notAuth')); |
|||
} |
|||
// 查看是否限制了群聊创建的个数 |
|||
if($this->userInfo['group_limit']!=0 && $this->userInfo['role']==0){ |
|||
$myGroup=GroupModel::where(['owner_id'=>$uid])->count(); |
|||
// 群聊已达上限 |
|||
if($myGroup>$this->userInfo['group_limit'] || $this->userInfo['group_limit']<0){ |
|||
return warning(lang('group.limit')); |
|||
} |
|||
} |
|||
if(count($user_ids)>$this->chatSetting['groupUserMax'] && $this->chatSetting['groupUserMax']!=0){ |
|||
return warning(lang('group.userLimit',['userMax'=>$this->chatSetting['groupUserMax']])); |
|||
} |
|||
// 管理员可以单独创建一个人的群 |
|||
if(count($user_ids)<=1 && $this->userInfo['role']>=2){ |
|||
return warning(lang('group.atLeast')); |
|||
} |
|||
// 将自己也加入群聊 |
|||
$user_ids[]=$uid; |
|||
Db::startTrans(); |
|||
$setting=$this->setting; |
|||
try{ |
|||
$create=[ |
|||
'create_user'=>$uid, |
|||
'owner_id'=>$uid, |
|||
'name'=>lang('group.name'), |
|||
'name_py'=>"qunliao", |
|||
'setting'=>json_encode($setting), |
|||
]; |
|||
$name=$param['name'] ?? ''; |
|||
if($name){ |
|||
$create['name']=$name; |
|||
$create['name_py']=pinyin_sentence($name); |
|||
} |
|||
$group=new GroupModel(); |
|||
$group->save($create); |
|||
$group_id=$group->group_id; |
|||
$data=[]; |
|||
array_unique($user_ids); |
|||
sort($user_ids); |
|||
foreach($user_ids as $k=>$v){ |
|||
$info=[ |
|||
'user_id'=>$v, |
|||
'invite_id'=>$uid, |
|||
'status'=>1, |
|||
'role'=>3, |
|||
'group_id'=>$group_id |
|||
]; |
|||
if($v==$uid){ |
|||
$info['invite_id']=0; |
|||
$info['role']=1; |
|||
} |
|||
$data[]=$info; |
|||
} |
|||
$groupUser=new GroupUser(); |
|||
$groupUser->saveAll($data); |
|||
$url=GroupModel::setGroupAvatar($group_id); |
|||
$groupInfo=[ |
|||
'displayName'=>$create['name'], |
|||
'owner_id'=>$create['owner_id'], |
|||
'role'=>3, |
|||
'name_py'=>$create['name_py'], |
|||
'id'=>'group-'.$group_id, |
|||
'avatar'=>avatarUrl($url,$create['name'],$group_id,120), |
|||
'is_group'=>1, |
|||
'lastContent'=>lang('group.add',['username'=>$this->userInfo['realname']]), |
|||
'lastSendTime'=>time()*1000, |
|||
'index'=>"[2]".lang('group.name'), |
|||
'is_notice'=>1, |
|||
'is_top'=>0, |
|||
'setting'=>$setting, |
|||
|
|||
]; |
|||
Message::create([ |
|||
'from_user'=>$uid, |
|||
'to_user'=>$group_id, |
|||
'content'=>str_encipher(lang('group.add',['username'=>''])), |
|||
'type'=>'event', |
|||
'is_group'=>1, |
|||
'is_read'=>1, |
|||
'is_last'=>1, |
|||
'chat_identify'=>'group-'.$group_id |
|||
]); |
|||
wsSendMsg($user_ids, 'addGroup', $groupInfo); |
|||
Db::commit(); |
|||
$groupInfo['role']=1; |
|||
return success('',$groupInfo); |
|||
}catch(Exception $e){ |
|||
Db::rollback(); |
|||
return error($e->getMessage()); |
|||
} |
|||
} |
|||
|
|||
// 移除成员 |
|||
public function removeUser(){ |
|||
$param = $this->request->param(); |
|||
$uid=$this->userInfo['user_id']; |
|||
$group_id = explode('-', $param['id'])[1]; |
|||
$user_id=$param['user_id']; |
|||
$role=GroupUser::where(['group_id'=>$group_id,'user_id'=>$uid])->value('role'); |
|||
if($role>2 && $user_id!=$uid){ |
|||
return warning(lang('system.notAuth')); |
|||
} |
|||
$groupUser=GroupUser::where(['group_id'=>$group_id,'user_id'=>$user_id])->find(); |
|||
if(($groupUser && $groupUser['role']>$role) || $user_id==$uid){ |
|||
GroupUser::destroy($groupUser->id); |
|||
Gateway::$registerAddress = config('gateway.registerAddress'); |
|||
$clientIds=Gateway::getClientIdByUid($user_id); |
|||
// 解绑群组 |
|||
if($clientIds){ |
|||
foreach($clientIds as $k=>$v){ |
|||
Gateway::leaveGroup($v, $group_id); |
|||
} |
|||
} |
|||
}else{ |
|||
return warning(lang('system.notAuth')); |
|||
} |
|||
$url=GroupModel::setGroupAvatar($group_id); |
|||
wsSendMsg($group_id,"removeUser",['group_id'=>$param['id'],'avatar'=>$url,'user_id'=>$user_id],1); |
|||
return success(lang('system.delOk')); |
|||
} |
|||
|
|||
// 设置群成员禁言 |
|||
public function setNoSpeak(){ |
|||
$param = $this->request->param(); |
|||
$uid=$this->userInfo['user_id']; |
|||
$group_id = explode('-', $param['id'])[1]; |
|||
$user_id=$param['user_id']; |
|||
$role=GroupUser::where(['group_id'=>$group_id,'user_id'=>$uid])->value('role'); |
|||
if($role>2 && $user_id!=$uid){ |
|||
return warning(lang('system.notAuth')); |
|||
} |
|||
$groupUser=GroupUser::where(['group_id'=>$group_id,'user_id'=>$user_id])->find(); |
|||
if(!$groupUser){ |
|||
return warning(lang('system.notAuth')); |
|||
} |
|||
$noSpeakTimer=$param['noSpeakTimer'] ?? 0; |
|||
$noSpeakList=[600,3600,10800,86400]; |
|||
$noSpeakDay=$param['noSpeakDay'] ?? 1; |
|||
$noSpeakTime=$noSpeakDay*86400; |
|||
if($noSpeakTimer>0){ |
|||
$noSpeakTime=$noSpeakList[$noSpeakTimer-1]; |
|||
} |
|||
wsSendMsg($group_id,"setNoSpeak",['group_id'=>$param['id'],'user_id'=>$user_id],1); |
|||
GroupUser::where(['group_id'=>$group_id,'user_id'=>$user_id])->update(['no_speak_time'=>time()+$noSpeakTime]); |
|||
return success(lang('system.success')); |
|||
} |
|||
|
|||
// 解散团队 |
|||
public function removeGroup(){ |
|||
$param = $this->request->param(); |
|||
$uid=$this->userInfo['user_id']; |
|||
$group_id = explode('-', $param['id'])[1]; |
|||
$role=GroupUser::where(['group_id'=>$group_id,'user_id'=>$uid])->value('role'); |
|||
if($role>1){ |
|||
return warning(lang('system.notAuth')); |
|||
} |
|||
Db::startTrans(); |
|||
try{ |
|||
// 删除团队成员 |
|||
GroupUser::where(['group_id'=>$group_id])->delete(); |
|||
// 删除团队 |
|||
GroupModel::destroy($group_id); |
|||
wsSendMsg($group_id,"removeGroup",['group_id'=>$param['id']],1); |
|||
Db::commit(); |
|||
return success(''); |
|||
}catch(Exception $e){ |
|||
Db::rollback(); |
|||
return error($e->getMessage()); |
|||
} |
|||
} |
|||
|
|||
// 设置公告 |
|||
public function setNotice(){ |
|||
$param = $this->request->param(); |
|||
$uid=$this->userInfo['user_id']; |
|||
// 公告内容检测服务 |
|||
event('GreenText',['content'=>$param['notice'],'service'=>"comment_detection"]); |
|||
$group_id = explode('-', $param['id'])[1]; |
|||
if($param['notice']==''){ |
|||
return warning(lang('system.notNull')); |
|||
} |
|||
$role=GroupUser::where(['group_id'=>$group_id,'user_id'=>$uid])->value('role'); |
|||
if($role>2){ |
|||
return warning(lang('system.notAuth')); |
|||
} |
|||
GroupModel::update(['notice'=>$param['notice']],['group_id'=>$group_id]); |
|||
$msg=[ |
|||
'id'=>\utils\Str::getUuid(), |
|||
'user_id'=>$uid, |
|||
'content'=>'<b>'.lang('group.notice').':</b> @'.lang('group.all').'<br/>'.$param['notice'].'<br/>', |
|||
'toContactId'=>$param['id'], |
|||
'sendTime'=>time()*1000, |
|||
'type'=>'text', |
|||
'is_group'=>1, |
|||
'status'=>'succeed', |
|||
'fromUser'=>$this->userInfo, |
|||
'at'=>[0] |
|||
]; |
|||
$message=new Message(); |
|||
$data = $message->sendMessage($msg,$this->globalConfig); |
|||
if (!$data) { |
|||
return warning($message->getError()); |
|||
} |
|||
return success(''); |
|||
} |
|||
|
|||
// 群聊设置 |
|||
public function groupSetting(){ |
|||
$param = $this->request->param(); |
|||
$uid=$this->userInfo['user_id']; |
|||
$group_id = explode('-', $param['id'])[1]; |
|||
$role=GroupUser::where(['group_id'=>$group_id,'user_id'=>$uid])->value('role'); |
|||
if($role!=1){ |
|||
return warning(lang('system.notAuth')); |
|||
} |
|||
$setting=json_encode($param['setting']); |
|||
GroupModel::update(['setting'=>$setting],['group_id'=>$group_id]); |
|||
wsSendMsg($group_id,"groupSetting",['group_id'=>$param['id'],'setting'=>$param['setting']],1); |
|||
return success(''); |
|||
} |
|||
|
|||
//生成群聊头像 |
|||
protected function setGroupAvatar($group_id){ |
|||
$userList=GroupUser::where('group_id',$group_id)->limit(9)->column('user_id'); |
|||
$userList=User::where('user_id','in',$userList)->select()->toArray(); |
|||
$imgList=[]; |
|||
$dirPath=app()->getRootPath().'public/temp'; |
|||
foreach($userList as $k=>$v){ |
|||
if($v['avatar']){ |
|||
$imgList[]=avatarUrl($v['avatar'],$v['realname'],$v['user_id']); |
|||
}else{ |
|||
$imgList[]=circleAvatar($v['realname'],80,$v['user_id'],1,$dirPath); |
|||
} |
|||
} |
|||
$groupId='group_'.$group_id; |
|||
$path=$dirPath.'/'.$groupId.'.jpg'; |
|||
$a = getGroupAvatar($imgList,1,$path); |
|||
$url=''; |
|||
if($a){ |
|||
$upload=new Upload(); |
|||
$newPath=$upload->uploadLocalAvatar($path,[],$groupId); |
|||
if($newPath){ |
|||
GroupModel::where('group_id',$group_id)->update(['avatar'=>$newPath]); |
|||
$url=avatarUrl($newPath); |
|||
} |
|||
} |
|||
// 删除目录下的所有文件 |
|||
$files = glob($dirPath . '/*'); // 获取目录下所有文件路径 |
|||
foreach ($files as $file) { |
|||
if (is_file($file)) { // 如果是文件则删除 |
|||
unlink($file); |
|||
} |
|||
} |
|||
return $url; |
|||
} |
|||
|
|||
// 加入群 |
|||
public function joinGroup(){ |
|||
$param = $this->request->param(); |
|||
$uid=$this->userInfo['user_id']; |
|||
try{ |
|||
$group_id = explode('-', $param['group_id'])[1]; |
|||
$inviteUid=$param['inviteUid'] ?? ''; |
|||
$groupUserCount=GroupUser::where(['group_id'=>$group_id,'status'=>1])->count(); |
|||
$groupUser=GroupUser::where(['group_id'=>$group_id,'user_id'=>$uid])->find(); |
|||
$groupInfo=GroupModel::where(['group_id'=>$group_id])->find(); |
|||
if(!$groupInfo){ |
|||
return warning(lang('group.exist')); |
|||
} |
|||
if($groupUser){ |
|||
return warning(lang('group.alreadyJoin')); |
|||
} |
|||
if(($groupUserCount+1) > $this->chatSetting['groupUserMax'] && $this->chatSetting['groupUserMax']!=0){ |
|||
return warning(lang('group.userLimit',['userMax'=>$this->chatSetting['groupUserMax']])); |
|||
} |
|||
// 加入者的名称 |
|||
$groupInfo['joinerName']=$this->userInfo['realname']; |
|||
GroupUser::joinGroup($uid,$inviteUid,$groupInfo); |
|||
return success(lang('system.joinOk')); |
|||
}catch(Exception $e){ |
|||
return error($e->getMessage()); |
|||
} |
|||
} |
|||
|
|||
// 更换群主 |
|||
public function changeOwner() |
|||
{ |
|||
$user_id = $this->request->param('user_id'); |
|||
$id = $this->request->param('id'); |
|||
$group_id = explode('-', $id)[1]; |
|||
$uid=$this->userInfo['user_id']; |
|||
$group=GroupModel::where('group_id',$group_id)->find(); |
|||
if(!$group){ |
|||
return warning(lang('group.exist')); |
|||
} |
|||
$user=User::where('user_id',$user_id)->find(); |
|||
if(!$user){ |
|||
return warning(lang('user.exist')); |
|||
} |
|||
$role=GroupUser::where(['group_id'=>$group_id,'user_id'=>$uid])->value('role'); |
|||
if($role>1){ |
|||
return warning(lang('system.notAuth')); |
|||
} |
|||
Db::startTrans(); |
|||
try{ |
|||
GroupUser::where('group_id',$group_id)->where('user_id',$user_id)->update(['role'=>1]); |
|||
GroupUser::where('group_id',$group_id)->where('user_id',$group->owner_id)->update(['role'=>3]); |
|||
$group->owner_id=$user_id; |
|||
$group->save(); |
|||
wsSendMsg($group_id,"changeOwner",['group_id'=>'group-'.$group_id,'user_id'=>$user_id],1); |
|||
Db::commit(); |
|||
return success(''); |
|||
}catch (\Exception $e){ |
|||
Db::rollback(); |
|||
return warning(''); |
|||
} |
|||
} |
|||
|
|||
// 清理群消息 |
|||
public function clearMessage() |
|||
{ |
|||
$id = $this->request->param('id'); |
|||
$group_id = explode('-', $id)[1]; |
|||
$uid=$this->userInfo['user_id']; |
|||
$group=GroupModel::where('group_id',$group_id)->find(); |
|||
if(!$group){ |
|||
return warning(lang('group.exist')); |
|||
} |
|||
$role=GroupUser::where(['group_id'=>$group_id,'user_id'=>$uid])->value('role'); |
|||
// 如果是群主或者后台管理员才有权限 |
|||
if($role>1 && $this->userInfo['role']==0){ |
|||
return warning(lang('system.notAuth')); |
|||
} |
|||
Db::startTrans(); |
|||
try{ |
|||
// 删除所有消息 |
|||
Message::where(['chat_identify'=>$id])->delete(); |
|||
// 该群聊的所有未读置为0 |
|||
GroupUser::where('group_id',$group_id)->update(['unread'=>0]); |
|||
wsSendMsg($group_id,"clearMessage",['group_id'=>'group-'.$group_id],1); |
|||
Db::commit(); |
|||
return success(''); |
|||
}catch (\Exception $e){ |
|||
Db::rollback(); |
|||
return warning(''); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,835 @@ |
|||
<?php |
|||
|
|||
namespace app\enterprise\controller; |
|||
|
|||
use app\BaseController; |
|||
use think\facade\Request; |
|||
use think\facade\Db; |
|||
use app\enterprise\model\{User, Message, GroupUser, Friend,Group}; |
|||
use GatewayClient\Gateway; |
|||
use Exception; |
|||
use League\Flysystem\Util; |
|||
use think\facade\Cache; |
|||
|
|||
class Im extends BaseController |
|||
{ |
|||
protected $fileType = ['file', 'image','video','voice','emoji']; |
|||
// 获取联系人列表 |
|||
public function getContacts() |
|||
{ |
|||
$data = User::getUserList([['status', '=', 1], ['user_id', '<>', $this->userInfo['user_id']]], $this->userInfo['user_id']); |
|||
$count=Friend::where(['status'=>2,'friend_user_id'=>$this->uid])->count(); |
|||
$time=Friend::where(['friend_user_id'=>$this->uid,'is_invite'=>1])->order('create_time desc')->value('create_time'); |
|||
return success('', $data,$count,$time*1000); |
|||
} |
|||
|
|||
// 获取单个人员的信息 |
|||
public function getContactInfo(){ |
|||
$id = $this->request->param('id'); |
|||
$is_group = is_string($id) ? 1 : 0; |
|||
$user=new User; |
|||
$data=$user->setContact($id,$is_group); |
|||
if(!$data){ |
|||
return warning($user->getError()); |
|||
} |
|||
return success('',$data); |
|||
} |
|||
|
|||
|
|||
//发送消息 |
|||
public function sendMessage() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$param['user_id'] = $this->userInfo['user_id']; |
|||
$message=new Message(); |
|||
$data = $message->sendMessage($param,$this->globalConfig); |
|||
if ($data) { |
|||
return success('', $data); |
|||
} else { |
|||
return warning($message->getError()); |
|||
} |
|||
} |
|||
|
|||
//转发消息 |
|||
public function forwardMessage() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$userIds=$param['user_ids'] ?? []; |
|||
if(!$userIds || count($userIds)>5){ |
|||
return warning(lang('im.forwardLimit',['count'=>5])); |
|||
} |
|||
$msg_id=$param['msg_id'] ?? 0; |
|||
$message=Message::find($msg_id); |
|||
if(!$message){ |
|||
return warning(lang('im.exist')); |
|||
} |
|||
$message=$message->toArray(); |
|||
|
|||
$userInfo=$this->userInfo; |
|||
try{ |
|||
$is_group=0; |
|||
$error=0; |
|||
$chatSetting=$this->chatSetting; |
|||
foreach($userIds as $k=>$v){ |
|||
$msgInfo=$message; |
|||
if(strpos($v,'group')!==false){ |
|||
$is_group=1; |
|||
}else{ |
|||
$is_group=0; |
|||
} |
|||
if($is_group==0 && $chatSetting['simpleChat']==0){ |
|||
$error++; |
|||
continue; |
|||
} |
|||
$msgInfo['id']=\utils\Str::getUuid(); |
|||
$msgInfo['status']='successd'; |
|||
$msgInfo['user_id']=$userInfo['user_id']; |
|||
$msgInfo['sendTime']=time()*1000; |
|||
$msgInfo['toContactId']=$v; |
|||
$msgInfo['content']=str_encipher($msgInfo['content'],false); |
|||
$msgInfo['fromUser']=[ |
|||
'id'=>$userInfo['user_id'], |
|||
'avatar'=>avatarUrl($userInfo['avatar'],$userInfo['realname'],$userInfo['user_id'],120), |
|||
'displayName'=>$userInfo['realname'] |
|||
]; |
|||
$msgInfo['is_group']=$is_group; |
|||
$message=new Message(); |
|||
$data=$message->sendMessage($msgInfo,$this->globalConfig); |
|||
if(!$data){ |
|||
return warning($message->getError()); |
|||
} |
|||
} |
|||
}catch(\Exception $e){ |
|||
return error($e->getMessage()); |
|||
} |
|||
if ($error) { |
|||
$text=lang('im.forwardRule',['count'=>$error]); |
|||
} else { |
|||
$text=lang('im.forwardOk'); |
|||
} |
|||
return success($text); |
|||
} |
|||
|
|||
// 获取用户信息 |
|||
public function getUserInfo() |
|||
{ |
|||
$user_id = $this->request->param('user_id'); |
|||
$user=User::find($user_id); |
|||
if(!$user){ |
|||
return error(lang('user.exist')); |
|||
} |
|||
$user->avatar=avatarUrl($user->avatar,$user->realname,$user->user_id,120); |
|||
// 账号前面截取3位,后面截取两位,中间星号展示 |
|||
$user->account=substr($user->account, 0, 3).'******'.substr($user->account, -2, 2); |
|||
// 查询好友关系 |
|||
$friend=Friend::where(['friend_user_id'=>$user_id,'create_user'=>$this->userInfo['user_id'],'status'=>1])->find(); |
|||
$user->friend=$friend ? : ''; |
|||
$location=''; |
|||
if($user->last_login_ip){ |
|||
$location=implode(" ", \Ip::find($user->last_login_ip)); |
|||
} |
|||
$user->location=$location; |
|||
$user->password=''; |
|||
return success('', $user); |
|||
} |
|||
|
|||
// 搜索用户 |
|||
public function searchUser(){ |
|||
$keywords=$this->request->param('keywords',''); |
|||
if(!$keywords){ |
|||
return success('',[]); |
|||
} |
|||
$map=['status'=>1,'account'=>$keywords]; |
|||
$list=User::where($map)->field(User::$defaultField)->where([['account','<>',$this->userInfo['account']]])->select()->toArray(); |
|||
if($list){ |
|||
$ids=array_column($list,'user_id'); |
|||
$friendList=Friend::getFriend([['create_user','=',$this->uid],['friend_user_id','in',$ids]]); |
|||
foreach($list as $k=>$v){ |
|||
$list[$k]['avatar']=avatarUrl($v['avatar'],$v['realname'],$v['user_id'],120); |
|||
$list[$k]['friend']=$friendList[$v['user_id']] ?? ''; |
|||
} |
|||
} |
|||
return success('', $list); |
|||
} |
|||
|
|||
// 获取系统所有人员加搜索 |
|||
public function userList(){ |
|||
$keywords=$this->request->param('keywords',''); |
|||
$listRows=$this->request->param('limit',20); |
|||
$page=$this->request->param('page',1); |
|||
$map=['status'=>1]; |
|||
$field="user_id,realname,avatar"; |
|||
if(!$keywords){ |
|||
$list=User::where($map)->field($field)->order('user_id asc')->limit(20)->paginate(['list_rows'=>$listRows,'page'=>$page]);; |
|||
if($list){ |
|||
$list=$list->toArray()['data']; |
|||
} |
|||
}else{ |
|||
$list=User::where($map)->field($field)->where([['account','<>',$this->userInfo['account']]])->whereLike('account|realname|name_py','%'.$keywords.'%')->select()->toArray(); |
|||
} |
|||
if($list){ |
|||
foreach($list as $k=>$v){ |
|||
$list[$k]['avatar']=avatarUrl($v['avatar'],$v['realname'],$v['user_id'],120); |
|||
$list[$k]['id']=$v['user_id']; |
|||
} |
|||
} |
|||
return success('', $list); |
|||
} |
|||
|
|||
// 获取聊天记录 |
|||
public function getMessageList() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$is_group = isset($param['is_group']) ? $param['is_group'] : 0; |
|||
// 如果toContactId是数字,绝对是单聊 |
|||
$is_group = is_numeric($param['toContactId']) ? 0 : $is_group; |
|||
// 设置当前聊天消息为已读 |
|||
$chat_identify = $this->setIsRead($is_group, $param['toContactId']); |
|||
$type = isset($param['type']) ? $param['type'] : ''; |
|||
$is_at = isset($param['is_at']) ? $param['is_at'] : ''; |
|||
$map = ['chat_identify' => $chat_identify, 'status' => 1]; |
|||
$where = []; |
|||
if ($type && $type != "all") { |
|||
$map['type'] = $type; |
|||
} else { |
|||
if (isset($param['type'])) { |
|||
$where[] = ['type', '<>', 'event']; |
|||
} |
|||
} |
|||
// 群聊查询入群时间以后的消息 |
|||
if($is_group==1){ |
|||
$group_id = explode('-', $param['toContactId'])[1]; |
|||
$group=Group::where(['group_id'=> $group_id])->find(); |
|||
if($group && $group['setting']){ |
|||
$groupSetting=json_decode($group['setting'],true); |
|||
$history=$groupSetting['history'] ?? false; |
|||
// 如果开启了历史记录才可以查看所有记录,否者根据进群时间查询记录 |
|||
if(!$history){ |
|||
$createTime=GroupUser::where(['group_id'=> $group_id,'user_id'=>$this->userInfo['user_id']])->value('create_time'); |
|||
$where[] = ['create_time', '>=', $createTime ? : 0]; |
|||
} |
|||
} |
|||
} |
|||
$keywords = isset($param['keywords']) ? $param['keywords'] : ''; |
|||
if ($keywords && in_array($type, ['text', 'all'])) { |
|||
$where[] = ['content', 'like', '%' . $keywords . '%']; |
|||
} |
|||
// 如果是查询@数据 |
|||
if($is_at){ |
|||
$atList=Db::name('message')->where($map)->where($where)->whereFindInSet('at',$this->userInfo['user_id'])->order('msg_id desc')->select()->toArray(); |
|||
if($atList){ |
|||
$data = $this->recombileMsg($atList,false); |
|||
Message::setAtread($data,$this->userInfo['user_id']); |
|||
return success('', $data, count($data)); |
|||
}else{ |
|||
return success('', [], 0); |
|||
} |
|||
} |
|||
$listRows = $param['limit'] ?: 20; |
|||
$pageSize = $param['page'] ?: 1; |
|||
$last_id = $param['last_id'] ?? 0; |
|||
if($last_id){ |
|||
$where[]=['msg_id','<',$last_id]; |
|||
} |
|||
$list = Message::getList($map, $where, 'msg_id desc', $listRows, $pageSize); |
|||
$data = $this->recombileMsg($list); |
|||
// 如果是群聊并且是第一页消息,需要推送@数据给用户 |
|||
if($param['is_group']==1 && $param['page']==1){ |
|||
$isPush=Cache::get('atMsgPush'.$chat_identify) ?? ''; |
|||
$atList=Db::name('message')->where(['chat_identify'=>$chat_identify,'is_group'=>1])->whereFindInSet('at',$this->userInfo['user_id'])->order('msg_id desc')->select()->toArray(); |
|||
$msgIda=array_column($atList,'msg_id'); |
|||
// 如果两次推送at数据的列表不一样,则推送 |
|||
if($isPush!=json_encode($msgIda)){ |
|||
$atData=$this->recombileMsg($atList,false); |
|||
wsSendMsg($this->userInfo['user_id'],'atMsgList',[ |
|||
'list'=>$atData, |
|||
'count'=>count($atData), |
|||
'toContactId'=>$param['toContactId'] |
|||
]); |
|||
Cache::set('atMsgPush'.$chat_identify,json_encode($msgIda),60); |
|||
} |
|||
} |
|||
// 如果是消息管理器则不用倒序 |
|||
if (!isset($param['type'])) { |
|||
$data = array_reverse($data); |
|||
} |
|||
return success('', $data, $list->total()); |
|||
} |
|||
|
|||
protected function recombileMsg($list,$isPagination=true) |
|||
{ |
|||
$data = []; |
|||
$userInfo = $this->userInfo; |
|||
if ($list) { |
|||
$listData = $isPagination ? $list->toArray()['data'] : $list; |
|||
$userList = User::matchUser($listData, true, 'from_user', 120); |
|||
foreach ($listData as $k => $v) { |
|||
// 屏蔽已删除的消息 |
|||
if ($v['del_user']) { |
|||
$delUser = explode(',', $v['del_user']); |
|||
if (in_array($userInfo['user_id'], $delUser)) { |
|||
unset($list[$k]); |
|||
continue; |
|||
// $v['type']="event"; |
|||
// $v['content']="删除了一条消息"; |
|||
} |
|||
} |
|||
$content = str_encipher($v['content'],false); |
|||
$preview = ''; |
|||
$ext=''; |
|||
if (in_array($v['type'], $this->fileType)) { |
|||
$content = getFileUrl($content); |
|||
$preview = previewUrl($content); |
|||
$ext=getExtUrl($content); |
|||
} |
|||
|
|||
$fromUser = $userList[$v['from_user']]; |
|||
// 处理撤回的消息 |
|||
if ($v['type'] == "event" && $v['is_undo']==1) { |
|||
if ($v['from_user'] == $userInfo['user_id']) { |
|||
$content = lang('im.you'). $content; |
|||
} elseif ($v['is_group'] == 1) { |
|||
$content = $fromUser['realname'] . $content; |
|||
} else { |
|||
$content = lang('im.other') . $content; |
|||
} |
|||
} |
|||
$toContactId=$v['is_group'] ==1 ? 'group-'.$v['to_user'] : $v['to_user']; |
|||
$atList=($v['at'] ?? null) ? explode(',',$v['at']): []; |
|||
$data[] = [ |
|||
'msg_id' => $v['msg_id'], |
|||
'id' => $v['id'], |
|||
'status' => "succeed", |
|||
'type' => $v['type'], |
|||
'sendTime' => $v['create_time'] * 1000, |
|||
'content' => $content, |
|||
'preview' => $preview, |
|||
'download' => $v['file_id'] ? getMainHost().'/filedown/'.encryptIds($v['file_id']) : '', |
|||
'is_read' => $v['is_read'], |
|||
'is_group' => $v['is_group'], |
|||
'at' => $atList, |
|||
'toContactId' => $toContactId, |
|||
'from_user' => $v['from_user'], |
|||
'file_id' => $v['file_id'], |
|||
'file_cate' => $v['file_cate'], |
|||
'fileName' => $v['file_name'], |
|||
'fileSize' => $v['file_size'], |
|||
'fromUser' => $fromUser, |
|||
'extUrl'=>$ext, |
|||
'extends'=>is_string($v['extends'])?json_decode($v['extends'],true) : $v['extends'] |
|||
]; |
|||
} |
|||
} |
|||
return $data; |
|||
} |
|||
|
|||
// 设置当前窗口的消息默认为已读 |
|||
public function setMsgIsRead() |
|||
{ |
|||
$param = $this->request->param(); |
|||
|
|||
// 判断是否是一个二维数组 |
|||
if (is_array($param['messages'][0] ?? '')) { |
|||
$messages=$param['messages']; |
|||
} else { |
|||
$messages=[$param['messages']]; |
|||
} |
|||
$this->setIsRead($param['is_group'], $param['toContactId'],$messages); |
|||
if (!$param['is_group']) { |
|||
wsSendMsg($param['fromUser'], 'isRead', $messages, 0); |
|||
} |
|||
return success(''); |
|||
} |
|||
|
|||
// 设置消息已读 |
|||
protected function setIsRead($is_group, $to_user,$messages=[]) |
|||
{ |
|||
if ($is_group==1) { |
|||
$chat_identify = $to_user; |
|||
$toContactId = explode('-', $to_user)[1]; |
|||
// 将@消息放到定时任务中逐步清理 |
|||
if($messages){ |
|||
Message::setAtRead($messages,$this->userInfo['user_id']); |
|||
} |
|||
// 更新群里面我的所有未读消息为0 |
|||
GroupUser::editGroupUser(['user_id' => $this->userInfo['user_id'], 'group_id' => $toContactId], ['unread' => 0]); |
|||
} else if($is_group==0) { |
|||
$chat_identify = chat_identify($this->userInfo['user_id'], $to_user); |
|||
// 更新我的未读消息为0 |
|||
Message::update(['is_read' => 1], [['chat_identify', '=', $chat_identify], ['to_user', '=', $this->userInfo['user_id']]]); |
|||
// 告诉对方我阅读了消息 |
|||
wsSendMsg($to_user, 'readAll', ['toContactId' => $this->userInfo['user_id']]); |
|||
} else if($is_group==2){ |
|||
$chat_identify = $to_user; |
|||
} |
|||
return $chat_identify; |
|||
} |
|||
|
|||
// 聊天设置 |
|||
public function setting() |
|||
{ |
|||
$param = $this->request->param(); |
|||
if ($param) { |
|||
User::where(['user_id' => $this->userInfo['user_id']])->update(['setting' => $param]); |
|||
return success(''); |
|||
} |
|||
return warning(''); |
|||
} |
|||
|
|||
// 撤回消息 |
|||
public function undoMessage() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$id = $param['id']; |
|||
$message = Message::where(['id' => $id])->find(); |
|||
if ($message) { |
|||
// 如果时间超过了2分钟也不能撤回 |
|||
$createTime=is_string($message['create_time']) ? strtotime($message['create_time']) : $message['create_time']; |
|||
if(time()-$createTime>120 && $message['is_group']==0){ |
|||
return warning(lang('im.redoLimitTime',['limit'=>2])); |
|||
} |
|||
$text = lang('im.redo'); |
|||
$fromUserName = lang('im.other'); |
|||
$toContactId = $message['to_user']; |
|||
if ($message['is_group'] == 1) { |
|||
$fromUserName = $this->userInfo['realname']; |
|||
$toContactId = explode('-', $message['chat_identify'])[1]; |
|||
// 如果是群聊消息撤回,需要判断是否是群主或者管理员,如果是则可以撤回 |
|||
if($message['from_user']!=$this->userInfo['user_id']){ |
|||
$groupUser=GroupUser::where(['user_id'=>$this->userInfo['user_id'],'group_id'=>$toContactId])->find(); |
|||
if(!$groupUser || !in_array($groupUser['role'],[1,2])){ |
|||
return warning(lang('system.notAuth')); |
|||
} |
|||
$text=lang('im.manageRedo'); |
|||
} |
|||
} |
|||
$message->content = str_encipher($text); |
|||
$message->type = 'event'; |
|||
$message->is_undo = 1; |
|||
//@的数据清空 |
|||
$message->at = ''; |
|||
$message->save(); |
|||
$info = $message->toArray(); |
|||
// $data = $info; |
|||
$data['content'] = $fromUserName . $text; |
|||
$data['sendTime'] = $createTime * 1000; |
|||
$data['id'] = $info['id']; |
|||
$data['from_user'] = $info['from_user']; |
|||
$data['msg_id'] = $info['msg_id']; |
|||
$data['status'] = $info['status']; |
|||
$data['type'] = 'event'; |
|||
$data['is_last'] = $info['is_last']; |
|||
$data['toContactId'] = $message['is_group'] == 1 ? $info['chat_identify'] : $toContactId; |
|||
$data['isMobile'] = $this->request->isMobile() ? 1 : 0; |
|||
wsSendMsg($toContactId, 'undoMessage', $data, $info['is_group']); |
|||
if($info['is_group']==0){ |
|||
// 给自己也发一份推送,多端同步 |
|||
$data['content'] =lang('im.you'). $text; |
|||
wsSendMsg($this->userInfo['user_id'], 'undoMessage', $data, $info['is_group']); |
|||
} |
|||
return success(''); |
|||
} else { |
|||
return warning(); |
|||
} |
|||
} |
|||
|
|||
// 删除消息 |
|||
public function removeMessage() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$id = $param['id']; |
|||
$map = ['id' => $id]; |
|||
$message = Message::where($map)->find(); |
|||
if ($message) { |
|||
$message->del_user = $this->userInfo['user_id']; |
|||
if ($message['is_group'] == 1) { |
|||
if ($message['del_user']) { |
|||
$message->del_user .= ',' . $this->userInfo['user_id']; |
|||
} |
|||
} else { |
|||
if ($message['del_user'] > 0) { |
|||
$message->where($map)->delete(); |
|||
return success(lang('system.delOk')); |
|||
} |
|||
} |
|||
$message->save(); |
|||
return success(''); |
|||
} else { |
|||
return warning(''); |
|||
} |
|||
} |
|||
|
|||
// 消息免打扰 |
|||
public function isNotice() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$user_id = $this->userInfo['user_id']; |
|||
$id = $param['id']; |
|||
if ($param['is_group'] == 1) { |
|||
$group_id = explode('-', $param['id'])[1]; |
|||
GroupUser::update(['is_notice' => $param['is_notice']], ['user_id' => $user_id, 'group_id' => $group_id]); |
|||
} else { |
|||
$map = ['create_user' => $user_id, 'friend_user_id' => $id]; |
|||
$friend = Friend::where($map)->find(); |
|||
try { |
|||
if ($friend) { |
|||
$friend->is_notice = $param['is_notice']; |
|||
$friend->save(); |
|||
} else { |
|||
$info = [ |
|||
'create_user' => $user_id, |
|||
'friend_user_id' => $id, |
|||
'is_notice' => $param['is_notice'] |
|||
]; |
|||
Friend::create($info); |
|||
} |
|||
return success(''); |
|||
} catch (Exception $e) { |
|||
return error($e->getMessage()); |
|||
} |
|||
} |
|||
wsSendMsg($user_id,"setIsNotice",['id'=>$id,'is_notice'=>$param['is_notice'],'is_group'=>$param['is_group']]); |
|||
return success(''); |
|||
} |
|||
|
|||
// 设置聊天置顶 |
|||
public function setChatTop() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$user_id = $this->userInfo['user_id']; |
|||
$is_group = $param['is_group'] ?: 0; |
|||
$id = $param['id']; |
|||
|
|||
try { |
|||
if ($is_group == 1) { |
|||
$group_id = explode('-', $param['id'])[1]; |
|||
GroupUser::update(['is_top' => $param['is_top']], ['user_id' => $user_id, 'group_id' => $group_id]); |
|||
} else { |
|||
$map = ['create_user' => $user_id, 'friend_user_id' => $id]; |
|||
$friend = Friend::where($map)->find(); |
|||
if ($friend) { |
|||
$friend->is_top = $param['is_top']; |
|||
$friend->save(); |
|||
} else { |
|||
$info = [ |
|||
'create_user' => $user_id, |
|||
'friend_user_id' => $id, |
|||
'is_top' => $param['is_top'] |
|||
]; |
|||
Friend::create($info); |
|||
} |
|||
} |
|||
wsSendMsg($user_id,"setChatTop",['id'=>$id,'is_top'=>$param['is_top'],'is_group'=>$is_group]); |
|||
return success(''); |
|||
} catch (Exception $e) { |
|||
return error($e->getMessage()); |
|||
} |
|||
} |
|||
|
|||
// 删除聊天 |
|||
public function delChat() |
|||
{ |
|||
$param = $this->request->param(); |
|||
$user_id = $this->userInfo['user_id']; |
|||
$is_group = $param['is_group'] ?: 0; |
|||
$id = $param['id']; |
|||
if(!$is_group){ |
|||
$chat_identify=chat_identify($user_id,$id); |
|||
}else{ |
|||
return success(''); |
|||
} |
|||
Message::where(['chat_identify' => $chat_identify])->update(['is_last' => 0]); |
|||
return success(''); |
|||
} |
|||
|
|||
// 向用户发送消息 |
|||
public function sendToMsg(){ |
|||
$param=$this->request->param(); |
|||
$toContactId=$param['toContactId']; |
|||
|
|||
$type=$param['type']; |
|||
$status=$param['status']; |
|||
$event=$param['event'] ?? 'calling'; |
|||
if($event=='calling'){ |
|||
$status=3; |
|||
} |
|||
$sdp=$param['sdp'] ?? ''; |
|||
$iceCandidate=$param['iceCandidate'] ?? ''; |
|||
$callTime=$param['callTime'] ?? ''; |
|||
$msg_id=$param['msg_id'] ?? ''; |
|||
$id=$param['id'] ?? ''; |
|||
$code=($param['code'] ?? '') ?: 901; |
|||
// 如果该用户不在线,则发送忙线 |
|||
Gateway::$registerAddress = config('gateway.registerAddress'); |
|||
if(!Gateway::isUidOnline($toContactId)){ |
|||
$toContactId=$this->userInfo['user_id']; |
|||
$code=907; |
|||
$event='busy'; |
|||
sleep(1); |
|||
} |
|||
switch($code){ |
|||
case 902: |
|||
$content=lang('webRtc.cancel'); |
|||
break; |
|||
case 903: |
|||
$content=lang('webRtc.refuse'); |
|||
break; |
|||
case 905: |
|||
$content=lang('webRtc.notConnected'); |
|||
break; |
|||
case 906: |
|||
$content=lang('webRtc.duration',['time'=>date("i:s",$callTime)]); |
|||
break; |
|||
case 907: |
|||
$content=lang('webRtc.busy'); |
|||
break; |
|||
case 908: |
|||
$content=lang('webRtc.other'); |
|||
break; |
|||
default: |
|||
$content=$type==1 ?lang('webRtc.video') : lang('webRtc.audio'); |
|||
break; |
|||
} |
|||
switch($event){ |
|||
case 'calling': |
|||
$content=$type==1 ?lang('webRtc.video'): lang('webRtc.audio'); |
|||
break; |
|||
case 'acceptRtc': |
|||
$content=lang('webRtc.answer'); |
|||
break; |
|||
case 'iceCandidate': |
|||
$content=lang('webRtc.exchange'); |
|||
break; |
|||
} |
|||
$userInfo=$this->userInfo; |
|||
$userInfo['id']=$userInfo['user_id']; |
|||
$user = new User(); |
|||
$data=[ |
|||
'id'=>$id, |
|||
'msg_id'=>$msg_id, |
|||
'sendTime'=>time()*1000, |
|||
'toContactId'=>$toContactId, |
|||
'content'=>$content, |
|||
'type'=>'webrtc', |
|||
'status'=>'succeed', |
|||
'is_group'=>0, |
|||
'is_read'=>0, |
|||
'fromUser'=>$userInfo, |
|||
'at'=>[], |
|||
'extends'=>[ |
|||
'type'=>$type, //通话类型,1视频,0语音。 |
|||
'status'=>$status, //,1拨打方,2接听方 |
|||
'event'=>$event, |
|||
'callTime'=>$callTime, |
|||
'sdp'=>$sdp, |
|||
'code'=>$code, //通话状态:呼叫901,取消902,拒绝903,接听904,未接通905,接通后挂断906,忙线907,其他端操作908 |
|||
'iceCandidate'=>$iceCandidate, |
|||
'isMobile'=>$this->request->isMobile() ? 1 : 0, |
|||
] |
|||
]; |
|||
if($event=='calling'){ |
|||
$chat_identify=chat_identify($userInfo['id'],$toContactId); |
|||
$msg=[ |
|||
'from_user'=>$userInfo['id'], |
|||
'to_user'=>$toContactId, |
|||
'id'=>$id, |
|||
'content'=>str_encipher($content), |
|||
'chat_identify'=>$chat_identify, |
|||
'create_time'=>time(), |
|||
'type'=>$data['type'], |
|||
'is_group'=>0, |
|||
'is_read'=>0, |
|||
'extends'=>$data['extends'], |
|||
]; |
|||
$message=new Message(); |
|||
$message->update(['is_last'=>0],['chat_identify'=>$chat_identify]); |
|||
$message->save($msg); |
|||
$msg_id=$message->msg_id; |
|||
$data['msg_id']=$msg_id; |
|||
// 将接收人设置为发送人才能定位到该消息 |
|||
$data['toContactId']=$userInfo['id']; |
|||
$data['toUser']=$toContactId; |
|||
}elseif($event=='hangup'){ |
|||
$message=Message::where(['id'=>$id])->find(); |
|||
if(!$message){ |
|||
return error(lang('webRtc.fail')); |
|||
} |
|||
if($message){ |
|||
$message->content=str_encipher($content); |
|||
$extends=$message->extends; |
|||
$extends['code']=$code; |
|||
$extends['callTime']=$callTime; |
|||
$message->extends=$extends; |
|||
$message->save(); |
|||
} |
|||
} |
|||
wsSendMsg($toContactId,'webrtc',$data); |
|||
$wsData=$data; |
|||
if(in_array($event,['calling','acceptRtc','hangup'])){ |
|||
if(in_array($event,['acceptRtc','hangup'])){ |
|||
$data['extends']['event']='otherOpt'; //其他端操作 |
|||
} |
|||
$data['toContactId']=$toContactId; |
|||
$data['contactInfo']=$user->setContact($toContactId,0,'webrtc',$content) ? : []; |
|||
wsSendMsg($userInfo['id'],'webrtc',$data); |
|||
} |
|||
return success('',$wsData); |
|||
} |
|||
|
|||
// 修改密码 |
|||
public function editPassword() |
|||
{ |
|||
if(env('app.demon_mode',false)){ |
|||
return warning(lang('system.demoMode')); |
|||
} |
|||
|
|||
$user_id = $this->userInfo['user_id']; |
|||
$user=User::find($user_id); |
|||
if(!$user){ |
|||
return warning(lang('user.exist')); |
|||
} |
|||
$account=$user->account; |
|||
$code=$this->request->param('code',''); |
|||
$originalPassword = $this->request->param('originalPassword', ''); |
|||
if($code){ |
|||
if(Cache::get($account)!=$code){ |
|||
return warning(lang('user.codeErr')); |
|||
} |
|||
}elseif($originalPassword){ |
|||
if(password_hash_tp($originalPassword,$user->salt)!= $user->password){ |
|||
return warning(lang('user.passErr')); |
|||
} |
|||
}else{ |
|||
return warning(lang('system.parameterError')); |
|||
} |
|||
try{ |
|||
$password = $this->request->param('password',''); |
|||
if($password){ |
|||
$salt=$user->salt; |
|||
$user->password= password_hash_tp($password,$salt); |
|||
} |
|||
$user->save(); |
|||
return success(lang('system.editOk')); |
|||
}catch (\Exception $e){ |
|||
return error(lang('system.editFail')); |
|||
} |
|||
} |
|||
|
|||
// 修改用户信息 |
|||
public function updateUserInfo(){ |
|||
try{ |
|||
$data = $this->request->param(); |
|||
$user=User::find($this->uid); |
|||
if(!$user){ |
|||
return warning(lang('user.exist')); |
|||
} |
|||
// 接入用户名检测服务 |
|||
event('GreenText',['content'=>$data['realname'],'service'=>"nickname_detection"]); |
|||
// 个性签名检测服务 |
|||
event('GreenText',['content'=>$data['motto'],'service'=>"comment_detection"]); |
|||
$user->realname =$data['realname']; |
|||
$user->email =$data['email']; |
|||
$user->motto=$data['motto']; |
|||
$user->sex =$data['sex']; |
|||
$user->name_py= pinyin_sentence($data['realname']); |
|||
$user->save(); |
|||
return success(lang('system.editOk'), $data); |
|||
}catch (\Exception $e){ |
|||
return error($e->getMessage()); |
|||
} |
|||
} |
|||
|
|||
// 修改账户 |
|||
public function editAccount(){ |
|||
if(env('app.demon_mode',false)){ |
|||
return warning(lang('system.demoMode')); |
|||
} |
|||
$code=$this->request->param('code',''); |
|||
$newCode=$this->request->param('newCode',''); |
|||
$account=$this->request->param('account',''); |
|||
$isUser=User::where('account',$account)->find(); |
|||
if($isUser){ |
|||
return warning(lang('user.already')); |
|||
} |
|||
$user=User::find($this->uid); |
|||
if(!$user){ |
|||
return warning(lang('user.exist')); |
|||
} |
|||
// 如果已经认证过了,则需要验证验证码 |
|||
if($user->is_auth){ |
|||
if(Cache::get($user->account)!=$code){ |
|||
return warning(lang('user.codeErr')); |
|||
} |
|||
} |
|||
if(Cache::get($account)!=$newCode){ |
|||
return warning(lang('user.newCodeErr')); |
|||
} |
|||
try{ |
|||
$user->account=$account; |
|||
$user->is_auth=1; |
|||
$user->save(); |
|||
return success(lang('system.editOk')); |
|||
}catch (\Exception $e){ |
|||
return error(lang('system.editFail')); |
|||
} |
|||
} |
|||
|
|||
// 阅读@消息 |
|||
public function readAtMsg(){ |
|||
$param = $this->request->param(); |
|||
$atList=Db::name('message')->where(['chat_identify'=>$param['toContactId'],'is_group'=>1])->whereFindInSet('at',$this->userInfo['user_id'])->order('msg_id desc')->select(); |
|||
$atData=$this->recombileMsg($atList,false); |
|||
Message::setAtRead($atData,$this->userInfo['user_id']); |
|||
// $message=Message::where('msg_id',$param['msg_id'])->select(); |
|||
// $atList=($message ?? null) ? explode(',',$message): []; |
|||
// // 两个数组取差集 |
|||
// $newAtList = array_diff($atList, [$this->userInfo['user_id']]); |
|||
// Message::where('msg_id',$param['msg_id'])->update(['at'=>implode(',',$newAtList)]); |
|||
return success(''); |
|||
} |
|||
|
|||
// 获取系统公告 |
|||
public function getAdminNotice(){ |
|||
$data=Message::where(['chat_identify'=>'admin_notice'])->order('msg_id desc')->find(); |
|||
$extends=$data['extends'] ?? []; |
|||
if(!$extends){ |
|||
$extends['title']=''; |
|||
} |
|||
$createTime=$data['create_time'] ?? 0; |
|||
if(!$createTime){ |
|||
$extends['create_time']=$createTime; |
|||
}else{ |
|||
$extends['create_time']=is_string($data['create_time']) ? strtotime($data['create_time']) : $data['create_time']; |
|||
} |
|||
|
|||
return success('',$extends); |
|||
} |
|||
|
|||
// 双向删除消息 |
|||
public function delMessage(){ |
|||
$param = $this->request->param(); |
|||
$id = $param['id']; |
|||
if(!$this->globalConfig['chatInfo']['dbDelMsg']){ |
|||
return warning(lang('system.noAuth')); |
|||
} |
|||
$message = Message::where(['id' => $id])->find(); |
|||
if ($message) { |
|||
if($message['from_user']!=$this->userInfo['user_id']){ |
|||
return warning(lang('system.noAuth')); |
|||
} |
|||
Message::where(['id' => $id])->delete(); |
|||
// 如果是最后一条消息,需要将上一条设置为最后一条 |
|||
if($message['is_last']){ |
|||
Message::where(['chat_identify'=>$message['chat_identify']])->order('msg_id desc')->limit(1)->update(['is_last'=>1]); |
|||
} |
|||
$toContactId = $message['to_user']; |
|||
if ($message['is_group'] == 1) { |
|||
$toContactId = explode('-', $message['chat_identify'])[1]; |
|||
} |
|||
wsSendMsg($toContactId, 'delMessage', $message, $message['is_group']); |
|||
return success(''); |
|||
} else { |
|||
return warning(lang('im.exist')); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
<?php |
|||
namespace app\enterprise\listener; |
|||
|
|||
use app\enterprise\model\{Group,User,Message}; |
|||
use app\manage\model\Config; |
|||
use GatewayClient\Gateway; |
|||
|
|||
// 监听群聊变更事件 |
|||
class GroupChange |
|||
{ |
|||
public function handle(Group $group,User $user,$data){ |
|||
Gateway::$registerAddress = config('gateway.registerAddress'); |
|||
$groupInfo=$data['param']; |
|||
// 如果是扫码进群,表示手动操作,手动操作需要触发客户端ID推送 |
|||
if($data['action'] == 'joinGroup'){ |
|||
Gateway::joinGroup(request()->header('clientId'),$data['group_id']); |
|||
}elseif($data['action'] == 'autoCreateGroup'){ |
|||
// 自动创建的群通知群主,如果在线则推送 |
|||
if(Gateway::isUidOnline($groupInfo['owner_uid'])){ |
|||
wsSendMsg([$groupInfo['owner_uid']], 'addGroup', $groupInfo); |
|||
} |
|||
}elseif($data['action'] == 'editGroupName'){ |
|||
return; |
|||
} |
|||
$uid=$groupInfo['owner_uid'] ?? 1; |
|||
$userInfo=$user->field('user_id,realname,avatar')->where(['user_id'=>$uid])->find(); |
|||
if($userInfo){ |
|||
$userInfo=$userInfo->toArray(); |
|||
$userInfo['id']=$userInfo['user_id']; |
|||
$userInfo['avatar']=avatarUrl($userInfo['avatar'],$userInfo['realname'],$userInfo['user_id']); |
|||
// 发送入群事件 |
|||
$msg=[ |
|||
'id'=>\utils\Str::getUuid(), |
|||
'user_id'=>$uid, |
|||
'content'=>lang('group.join',['username'=>$groupInfo['joinerName'] ?? 'xxx ']), |
|||
'toContactId'=>'group-'.$data['group_id'], |
|||
'sendTime'=>time()*1000, |
|||
'type'=>'event', |
|||
'is_group'=>1, |
|||
'status'=>'succeed', |
|||
'fromUser'=>$userInfo, |
|||
'at'=>[], |
|||
'action'=>$data['action'], |
|||
]; |
|||
Message::sendMsg($msg,1); |
|||
} |
|||
return true; |
|||
} |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
<?php |
|||
return [ |
|||
"checkAuth" |
|||
]; |
|||
@ -0,0 +1,12 @@ |
|||
<?php |
|||
/** |
|||
* raingad IM [ThinkPHP6] |
|||
* @author xiekunyu <raingad@foxmail.com> |
|||
*/ |
|||
namespace app\enterprise\model; |
|||
|
|||
use app\BaseModel; |
|||
class Emoji extends BaseModel |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
<?php |
|||
/** |
|||
* raingad IM [ThinkPHP6] |
|||
* @author xiekunyu <raingad@foxmail.com> |
|||
*/ |
|||
namespace app\enterprise\model; |
|||
|
|||
use app\BaseModel; |
|||
class File extends BaseModel |
|||
{ |
|||
protected $pk="file_id"; |
|||
|
|||
|
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
<?php |
|||
/** |
|||
* raingad IM [ThinkPHP6] |
|||
* @author xiekunyu <raingad@foxmail.com> |
|||
*/ |
|||
namespace app\enterprise\model; |
|||
|
|||
use app\BaseModel; |
|||
use think\facade\Db; |
|||
|
|||
class Friend extends BaseModel |
|||
{ |
|||
protected $pk="friend_id"; |
|||
|
|||
|
|||
public static function getFriend($map){ |
|||
$list=self::where($map)->select(); |
|||
$data=[]; |
|||
if($list){ |
|||
$list=$list->toArray(); |
|||
foreach($list as $k=>$v){ |
|||
$data[$v['friend_user_id']]=$v; |
|||
} |
|||
} |
|||
return $data; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,60 @@ |
|||
<?php |
|||
/** |
|||
* raingad IM [ThinkPHP6] |
|||
* @author xiekunyu <raingad@foxmail.com> |
|||
*/ |
|||
namespace app\enterprise\model; |
|||
|
|||
use app\BaseModel; |
|||
use think\facade\Db; |
|||
use app\common\controller\Upload; |
|||
class Group extends BaseModel |
|||
{ |
|||
protected $pk="group_id"; |
|||
|
|||
// 获取我的团队 |
|||
public static function getMyGroup($map){ |
|||
return Db::name('group_user') |
|||
->alias('gu') |
|||
->field('gr.group_id,gr.avatar,gr.name as displayName,gu.unread,gr.name_py,gr.owner_id,gr.notice,gu.role,gu.is_notice,gu.is_top,gr.setting') |
|||
->join('group gr','gu.group_id=gr.group_id','left') |
|||
->where($map) |
|||
->select(); |
|||
} |
|||
|
|||
//生成群聊头像 |
|||
public static function setGroupAvatar($group_id){ |
|||
$userList=GroupUser::where('group_id',$group_id)->limit(9)->column('user_id'); |
|||
$userList=User::where('user_id','in',$userList)->select()->toArray(); |
|||
$imgList=[]; |
|||
$dirPath=app()->getRootPath().'public/temp'; |
|||
foreach($userList as $k=>$v){ |
|||
if($v['avatar']){ |
|||
$imgList[]=avatarUrl($v['avatar'],$v['realname'],$v['user_id']); |
|||
}else{ |
|||
$imgList[]=circleAvatar($v['realname'],80,$v['user_id'],1,$dirPath); |
|||
} |
|||
} |
|||
$groupId='group_'.$group_id; |
|||
$path=$dirPath.'/'.$groupId.'.jpg'; |
|||
$a = getGroupAvatar($imgList,1,$path); |
|||
$url=''; |
|||
if($a){ |
|||
$upload=new Upload(); |
|||
$newPath=$upload->uploadLocalAvatar($path,[],$groupId); |
|||
if($newPath){ |
|||
Group::where('group_id',$group_id)->update(['avatar'=>$newPath]); |
|||
$url=avatarUrl($newPath); |
|||
} |
|||
} |
|||
// 删除目录下的所有文件 |
|||
$files = glob($dirPath . '/*'); // 获取目录下所有文件路径 |
|||
foreach ($files as $file) { |
|||
if (is_file($file)) { // 如果是文件则删除 |
|||
unlink($file); |
|||
} |
|||
} |
|||
return $url; |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,66 @@ |
|||
<?php |
|||
/** |
|||
* raingad IM [ThinkPHP6] |
|||
* @author xiekunyu <raingad@foxmail.com> |
|||
*/ |
|||
namespace app\enterprise\model; |
|||
|
|||
use app\BaseModel; |
|||
use think\facade\Db; |
|||
|
|||
class GroupUser extends BaseModel |
|||
{ |
|||
protected $pk="id"; |
|||
|
|||
// 编辑团队信息 |
|||
public static function editGroupUser($map,$data){ |
|||
return self::where($map)->update($data); |
|||
} |
|||
|
|||
// 获取团队成员列表 |
|||
public static function getGroupUser($map,$listRows,$pageSize=1){ |
|||
if($listRows){ |
|||
$list=self::where($map)->order('role asc')->paginate(['list_rows'=>$listRows,'page'=>$pageSize]); |
|||
$data=$list->toArray()['data']; |
|||
}else{ |
|||
$data=self::where($map)->order('role asc')->select(); |
|||
} |
|||
return User::matchAllUser($data,true,'user_id'); |
|||
} |
|||
|
|||
// 验证权限 |
|||
public static function checkAuth($map,$role=1){ |
|||
$info=self::where($map)->find()->toArray(); |
|||
if($info['role']<=$role){ |
|||
return true; |
|||
}else{ |
|||
return false; |
|||
} |
|||
} |
|||
|
|||
// 加入群聊,发送加入消息 |
|||
public static function joinGroup($uid,$inviteId,$groupInfo,$action='joinGroup'){ |
|||
$group_id=$groupInfo['group_id']; |
|||
GroupUser::create([ |
|||
'user_id'=>$uid, |
|||
'invite_id'=>$inviteId, |
|||
'status'=>1, |
|||
'role'=>$action=='autoCreateGroup' ? 1 : 3, |
|||
'group_id'=>$group_id, |
|||
]); |
|||
$url=Group::setGroupAvatar($group_id); |
|||
event('GroupChange', ['action' => $action, 'group_id' => $group_id, 'param' => $groupInfo]); |
|||
wsSendMsg($group_id,"addGroupUser",['group_id'=>$group_id,'avatar'=>$url],1); |
|||
return true; |
|||
} |
|||
|
|||
// 获取群管理 |
|||
public static function getGroupManage($group_id){ |
|||
$list=self::where([['group_id','=',$group_id],['role','<',3],['status','=',1]])->select()->toArray(); |
|||
$data=[]; |
|||
foreach($list as $k=>$v){ |
|||
$data[$v['user_id']]=$v['role']; |
|||
} |
|||
return $data; |
|||
} |
|||
} |
|||
@ -0,0 +1,263 @@ |
|||
<?php |
|||
/** |
|||
* raingad IM [ThinkPHP6] |
|||
* @author xiekunyu <raingad@foxmail.com> |
|||
*/ |
|||
namespace app\enterprise\model; |
|||
|
|||
use app\BaseModel; |
|||
use think\facade\Db; |
|||
use think\facade\Cache; |
|||
class Message extends BaseModel |
|||
{ |
|||
protected $pk="msg_id"; |
|||
protected $json = ["extends"]; |
|||
protected $jsonAssoc = true; |
|||
protected static $fileType=['file','image','video','voice','emoji']; |
|||
|
|||
// 添加聊天记录 |
|||
public static function addData($data){ |
|||
return Db::name('message')->insert($data); |
|||
} |
|||
|
|||
// 更新消息状态 |
|||
public static function editData($update,$map){ |
|||
return Db::name('message')->where($map)->update($update); |
|||
} |
|||
|
|||
// 查询聊天记录 |
|||
public static function getList($map,$where,$sort,$listRows,$pageSize){ |
|||
$list= Db::name('message') |
|||
->where($map) |
|||
->where($where) |
|||
->order($sort) |
|||
->paginate(['list_rows'=>$listRows,'page'=>$pageSize]); |
|||
return $list; |
|||
} |
|||
|
|||
// 发送消息 |
|||
public function sendMessage($param,$globalConfig=false){ |
|||
$is_group = $param['is_group'] ?? 0; |
|||
$uid=self::$uid; |
|||
if($param['toContactId']==-1){ |
|||
$is_group=0; |
|||
} |
|||
// 如果是系统账号,直接禁言 |
|||
if($is_group>1){ |
|||
$this->error=lang('im.forbidChat'); |
|||
return false; |
|||
} |
|||
$sendInterval = $globalConfig['chatInfo']['sendInterval'] ?? 0; |
|||
// 如果设置了消息频率则验证 |
|||
if ($sendInterval) { |
|||
if (Cache::has('send_' . $uid)) { |
|||
$this->error=lang('im.sendTimeLimit',['time'=>$sendInterval]); |
|||
return false; |
|||
} |
|||
} |
|||
if($param['type']=='text'){ |
|||
// 限制文字内容长度 |
|||
$text = strip_tags($param['content']); |
|||
$textLen = mb_strlen($text); |
|||
if ($textLen > 2048) { |
|||
$this->error=lang('im.msgContentLimit') . $textLen; |
|||
return false; |
|||
} |
|||
$param['content'] = preg_link($param['content']); |
|||
// 接入聊天内容检测服务 |
|||
event('GreenText',['content'=>$param['content'],'service'=>"chat_detection"]); |
|||
} |
|||
$chatSetting = $globalConfig['chatInfo']; |
|||
if($param['toContactId']!=-1){ |
|||
if ($is_group == 0) { |
|||
$kefuUser=$chatSetting['autoAddUser']['user_ids'] ?? []; |
|||
$manageUser=User::where([['status','=',1],['role','>',0]])->column('user_id'); |
|||
$kefu=array_unique(array_merge($kefuUser,$manageUser)); |
|||
$csUid = self::$userInfo['cs_uid'] ?? 0; |
|||
$manage=false; |
|||
// 发送者和接受者是客服或者管理员也可以发送消息 |
|||
if(in_array($uid,$kefu) || in_array($param['toContactId'],$kefu)){ |
|||
$manage=true; |
|||
} |
|||
if($chatSetting['simpleChat'] == 0 && !$manage){ |
|||
$this->error=lang('im.forbidChat'); |
|||
return false; |
|||
} |
|||
// 如果是单聊,并且是社区模式和不是自己的客服、需要判断是否是好友 |
|||
if ($globalConfig['sysInfo']['runMode'] == 2 && $csUid != $param['toContactId'] && !$manage) { |
|||
// 判断我是不是对方的客服 |
|||
$cus = User::where(['user_id' => $param['toContactId']])->value('cs_uid'); |
|||
if ($cus != $uid) { |
|||
$friend = Friend::where(['friend_user_id' => $uid, 'create_user' => $param['toContactId']])->find(); |
|||
if (!$friend) { |
|||
$this->error=lang('im.notFriend'); |
|||
return false; |
|||
} |
|||
$otherFriend = Friend::where(['friend_user_id' => $param['toContactId'], 'create_user' => $uid])->find(); |
|||
if (!$otherFriend) { |
|||
$this->error=lang('im.friendNot'); |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
}else{ |
|||
// 群聊必须群成员才能发送消息 |
|||
$group_id = explode('-', $param['toContactId'])[1] ?? ''; |
|||
$toContactId=$group_id; |
|||
if(!$group_id){ |
|||
$this->error=lang('system.parameterError'); |
|||
return false; |
|||
} |
|||
if(!self::nospeak($group_id,$uid)){ |
|||
return shutdown(lang('group.notSpeak')); |
|||
} |
|||
// 群聊必须群成员才能发送消息 |
|||
$groupUser=GroupUser::where(['user_id'=>$uid,'status'=>1,'group_id'=>$group_id,'delete_time'=>0])->find(); |
|||
if(!$groupUser){ |
|||
$this->error = lang('group.notCustom'); |
|||
return false; |
|||
} |
|||
if($groupUser['no_speak_time']>time()){ |
|||
$this->error = lang('group.notSpeak',['time'=>date('Y-m-d H:i:s',$groupUser['no_speak_time'])]); |
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
|
|||
if ($sendInterval) { |
|||
Cache::set('send_' . $uid, time(), $sendInterval); |
|||
} |
|||
return self::sendMsg($param,$is_group); |
|||
} |
|||
|
|||
//实际发送消息 |
|||
public static function sendMsg($param,$is_group=0){ |
|||
$uid=self::$uid ?: ($param['user_id'] ?? 1); |
|||
$toContactId=$param['toContactId']; |
|||
$manage=[]; |
|||
if($is_group==1){ |
|||
$group_id = explode('-', $param['toContactId'])[1] ?? ''; |
|||
$chat_identify=$toContactId; |
|||
$toContactId=$group_id; |
|||
$manage=GroupUser::getGroupManage($group_id); |
|||
}else{ |
|||
$chat_identify=chat_identify($param['user_id'],$toContactId); |
|||
} |
|||
$fileSzie=isset($param['file_size'])?$param['file_size']:''; |
|||
$fileName=isset($param['file_name'])?$param['file_name']:''; |
|||
$ossUrl=getDiskUrl(); |
|||
// 如果是转发图片文件的消息,必须把域名去除掉 |
|||
$content=$param['content']; |
|||
if(in_array($param['type'],self::$fileType)){ |
|||
if(strpos($param['content'],$ossUrl)!==false){ |
|||
$content=str_replace($ossUrl,'',$param['content']); |
|||
} |
|||
} |
|||
$param['content']=$content; |
|||
$atList=($param['at'] ?? null) ? array_map('intval', $param['at']): []; |
|||
// 如果at里面有0,代表@所有人 |
|||
if($atList && in_array(0,$atList)){ |
|||
$atList=GroupUser::where([['group_id','=',$toContactId],['status','=',1],['user_id','<>',$param['user_id']]])->column('user_id'); |
|||
} |
|||
$at=$atList ? implode(',',$atList) : null; |
|||
$data=[ |
|||
'from_user'=>$param['user_id'], |
|||
'to_user'=>$toContactId, |
|||
'id'=>$param['id'], |
|||
'content'=>str_encipher($param['content'],true), |
|||
'chat_identify'=>$chat_identify, |
|||
'create_time'=>time(), |
|||
'type'=>$param['type'], |
|||
'is_group'=>$toContactId==-1 ? 3 : $is_group, |
|||
'is_read'=>$is_group ? 1 : 0, |
|||
'file_id'=>$param['file_id'] ?? 0, |
|||
"file_cate"=>$param['file_cate'] ?? 0, |
|||
'file_size'=>$fileSzie, |
|||
'file_name'=>$fileName, |
|||
'at'=>$at, |
|||
'pid'=>$param['pid'] ?? 0, |
|||
'extends'=>($param['extends'] ?? null) ? $param['extends'] : null, |
|||
]; |
|||
$message=new self(); |
|||
$message->update(['is_last'=>0],['chat_identify'=>$chat_identify]); |
|||
$message->save($data); |
|||
|
|||
// 拼接消息推送 |
|||
$type=$is_group?'group':'simple'; |
|||
$sendData=$param; |
|||
$sendData['status']='succeed'; |
|||
$sendData['at']=$atList; |
|||
$sendData['msg_id']=$message->msg_id; |
|||
$sendData['is_read']=0; |
|||
$sendData['to_user']=$toContactId; |
|||
$sendData['role']=$manage[self::$uid] ?? 3; |
|||
$sendData['sendTime']=(int)$sendData['sendTime']; |
|||
//这里单聊中发送对方的消息,对方是接受状态,自己是对方的联系人,要把发送对象设置为发送者的ID。 |
|||
if($is_group){ |
|||
$sendData['toContactId']=$param['toContactId']; |
|||
// 将团队所有成员的未读状态+1 |
|||
GroupUser::editGroupUser([['group_id','=',$toContactId],['user_id','<>',$uid]],['unread'=>Db::raw('unread+1')]); |
|||
}else{ |
|||
$sendData['toContactId']=$uid; |
|||
} |
|||
$sendData['fromUser']['id']=(int)$sendData['fromUser']['id']; |
|||
$sendData['fileSize']=$fileSzie; |
|||
$sendData['fileName']=$fileName; |
|||
if(in_array($sendData['type'],self::$fileType)){ |
|||
$sendData['content']=getFileUrl($sendData['content']); |
|||
if($sendData['type']=='image'){ |
|||
$pre=1; |
|||
}else{ |
|||
$pre=2; |
|||
} |
|||
$sendData['preview']=previewUrl($sendData['content'],$pre); |
|||
$sendData['extUrl']=getExtUrl($sendData['content']); |
|||
$sendData['download']= $sendData['file_id'] ? getMainHost().'/filedown/'.encryptIds($sendData['file_id']) : ''; |
|||
} |
|||
if($is_group==0){ |
|||
$toContactId=[$toContactId,$param['user_id']]; |
|||
} |
|||
$sendData['toUser']=$param['toContactId']; |
|||
$user=new User(); |
|||
// 将聊天窗口的联系人信息带上,方便临时会话 |
|||
$sendData['contactInfo']=$user->setContact($sendData['toContactId'],$is_group,$sendData['type'],$sendData['content']); |
|||
// 向发送方发送消息 |
|||
wsSendMsg($toContactId,$type,$sendData,$is_group); |
|||
$sendData['toContactId']=$param['toContactId']; |
|||
return $sendData; |
|||
} |
|||
|
|||
// 群禁言 |
|||
public static function nospeak($group_id,$user_id){ |
|||
$group=Group::find($group_id); |
|||
if($group->owner_id==$user_id){ |
|||
return true; |
|||
} |
|||
if($group->setting){ |
|||
$setting=json_decode($group->setting,true); |
|||
$nospeak=isset($setting['nospeak'])?$setting['nospeak']:0; |
|||
$role=GroupUser::where(['group_id'=>$group_id,'user_id'=>$user_id])->value('role'); |
|||
if($nospeak==1 && $role>2){ |
|||
return false; |
|||
}elseif($nospeak==2 && $role!=1){ |
|||
return false; |
|||
} |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
// 将消息中的@用户加入到atListQueue中 |
|||
public static function setAtread($messages,$user_id){ |
|||
foreach($messages as $k=>$v){ |
|||
if(!isset($v['at'])){ |
|||
continue; |
|||
} |
|||
if($v['at'] && in_array($user_id,$v['at'])){ |
|||
$atListQueue=Cache::get("atListQueue"); |
|||
$atListQueue[$v['msg_id']][]=$user_id; |
|||
Cache::set("atListQueue",$atListQueue); |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -0,0 +1,515 @@ |
|||
<?php |
|||
|
|||
/** |
|||
* raingad IM [ThinkPHP6] |
|||
* @author xiekunyu <raingad@foxmail.com> |
|||
*/ |
|||
|
|||
namespace app\enterprise\model; |
|||
|
|||
use GatewayClient\Gateway; |
|||
use app\BaseModel; |
|||
use think\facade\Db; |
|||
use think\facade\Request; |
|||
use think\model\concern\SoftDelete; |
|||
use app\manage\model\Config; |
|||
use thans\jwt\facade\JWTAuth; |
|||
|
|||
class User extends BaseModel |
|||
{ |
|||
use SoftDelete; |
|||
|
|||
protected $pk = "user_id"; |
|||
|
|||
public static $defaultField = 'user_id,realname,realname as displayName,account,avatar,name_py,email,last_login_ip'; |
|||
|
|||
protected $json = ['setting']; |
|||
protected $jsonAssoc = true; |
|||
|
|||
// 系统人员或者其他静态人员 |
|||
public static function staticUser(){ |
|||
return [ |
|||
'adminNotice'=>[ |
|||
'id'=>'admin_notice', |
|||
'displayName'=>'系统通知', |
|||
'avatar'=>getMainHost().'/static/common/img/notice.png', |
|||
'name_py'=>'xitongtongzhi', |
|||
], |
|||
'fileTransfer'=>[ |
|||
'id'=>-1, |
|||
'displayName'=>'我的收藏', |
|||
'avatar'=>getMainHost().'/static/common/img/file_transfer.png', |
|||
'name_py'=>'wodeshoucang', |
|||
] |
|||
]; |
|||
} |
|||
|
|||
public function getUid() |
|||
{ |
|||
return self::$uid; |
|||
} |
|||
|
|||
//查询用户信息 |
|||
public static function getUserInfo($map=[]) |
|||
{ |
|||
if(!$map){ |
|||
return self::$userInfo; |
|||
} |
|||
$data = self::where($map)->find(); |
|||
if ($data) { |
|||
$data = $data->toArray(); |
|||
} |
|||
return $data; |
|||
} |
|||
|
|||
/** |
|||
* 刷新用户token 之前token将被拉黑 |
|||
* 修改用户数据后 调用该方法 并返回前台更新token |
|||
* @param array $info 用户信息 |
|||
* @param string $terminal 客户端标识 |
|||
* @return string |
|||
* @throws \think\db\exception\DataNotFoundException |
|||
* @throws \think\db\exception\DbException |
|||
* @throws \think\db\exception\ModelNotFoundException |
|||
*/ |
|||
public static function refreshToken($info,$terminal) |
|||
{ |
|||
$info = str_encipher(json_encode($info),true, config('app.aes_token_key')); |
|||
$authToken = 'bearer '.JWTAuth::builder(['info' => $info, 'terminal' => $terminal]); |
|||
return $authToken; |
|||
} |
|||
|
|||
// 获取所有用户列表 |
|||
public static function getAllUser($map, $user_ids = [],$user_id,$group_id = 0) |
|||
{ |
|||
$field = self::$defaultField; |
|||
$list=[]; |
|||
if($group_id){ |
|||
$groupUser=GroupUser::where([['group_id','=',$group_id],['role','<>',1],['status','=',1]])->column('user_id'); |
|||
if($groupUser){ |
|||
$list=User::where([['user_id','in',$groupUser]])->field($field)->select()->toArray(); |
|||
} |
|||
}else{ |
|||
$config=Config::getSystemInfo(); |
|||
// 如果是社区模式,就只查询自己的好友,如果是企业模式,就查询所有用户 |
|||
if($config['sysInfo']['runMode']==1){ |
|||
$list = self::where($map)->field($field)->select()->toArray(); |
|||
}else{ |
|||
$friendList = Friend::getFriend(['create_user' => $user_id,'status'=>1]); |
|||
$userList = array_keys($friendList); |
|||
$list = self::where($map)->where('user_id', 'in', $userList)->field($field)->select()->toArray(); |
|||
} |
|||
} |
|||
foreach ($list as $k => $v) { |
|||
$list[$k]['disabled'] = false; |
|||
$list[$k]['avatar'] = avatarUrl($v['avatar'], $v['realname'], $v['user_id']); |
|||
if ($user_ids) { |
|||
if (in_array($v['user_id'], $user_ids)) { |
|||
$list[$k]['disabled'] = true; |
|||
} |
|||
} |
|||
} |
|||
return $list; |
|||
} |
|||
|
|||
//查询用户列表 |
|||
public static function getUserList($map, $user_id, $field = "") |
|||
{ |
|||
if (!$field) { |
|||
$field = self::$defaultField; |
|||
} |
|||
|
|||
$config=Config::getSystemInfo(); |
|||
// 如果是社区模式,就只查询自己的好友,如果是企业模式,就查询所有用户 |
|||
if($config['sysInfo']['runMode']==1){ |
|||
$friendList = Friend::getFriend(['create_user' => $user_id]); |
|||
$list = self::where($map)->field($field)->select(); |
|||
}else{ |
|||
$friendList = Friend::getFriend(['create_user' => $user_id,'status'=>1]); |
|||
$userList = array_keys($friendList); |
|||
// 将专属客服设置为好友 |
|||
$csUid=request()->userInfo['cs_uid'] ?? 0; |
|||
if($csUid){ |
|||
$userList[]=$csUid; |
|||
} |
|||
$list = self::where($map)->where('user_id', 'in', $userList)->field($field)->select(); |
|||
} |
|||
$list_chart = chartSort($list, 'realname', false, 'index'); |
|||
// 查询未读消息 |
|||
$unread = Db::name('message') |
|||
->field('from_user,count(msg_id) as unread') |
|||
->where([['to_user', '=', $user_id], ['is_read', '=', 0], ['is_group', '=', 0]]) |
|||
->group('from_user') |
|||
->select(); |
|||
// 查询最近的联系人 |
|||
$map1 = [['to_user', '=', $user_id], ['is_last', '=', 1], ['is_group', '=', 0]]; |
|||
$map2 = [['from_user', '=', $user_id], ['is_last', '=', 1], ['is_group', '=', 0]]; |
|||
$msgField = 'from_user,to_user,content as lastContent,create_time as lastSendTime,chat_identify,type,del_user'; |
|||
$lasMsgList = Db::name('message') |
|||
->field($msgField) |
|||
->whereOr([$map1, $map2]) |
|||
->order('create_time desc') |
|||
->select(); |
|||
// 查询群聊 |
|||
$group = Group::getMyGroup(['gu.user_id' => $user_id, 'gu.status' => 1]); |
|||
if ($group) { |
|||
$group = $group->toArray(); |
|||
$group_ids = arrayToString($group, 'group_id'); |
|||
$getGroupLastMsg = Db::name('message')->field($msgField)->where([['to_user', 'in', $group_ids], ['is_group', '=', 1], ['is_last', '=', 1]])->select(); |
|||
$getAtMsg=Db::name('message')->field($msgField)->where([['to_user', 'in', $group_ids], ['is_group', '=', 1]])->whereFindInSet('at',$user_id)->select(); |
|||
|
|||
// halt($getAtMsg); |
|||
foreach ($group as $k => $v) { |
|||
$setting = $v['setting'] ? json_decode($v['setting'], true) : ['manage' => 0, 'invite' => 1, 'nospeak' => 0]; |
|||
$group_id = 'group-' . $v['group_id']; |
|||
$group[$k]['id'] = $group_id; |
|||
$group[$k]['account'] = $group_id; |
|||
$group[$k]['avatar'] = avatarUrl($v['avatar'], $v['displayName'], $v['group_id'], 120); |
|||
$group[$k]['name_py'] = $v['name_py']; |
|||
$group[$k]['owner_id'] = $v['owner_id']; |
|||
$group[$k]['role'] = $v['role']; |
|||
$group[$k]['is_group'] = 1; |
|||
$group[$k]['setting'] = $setting; |
|||
$group[$k]['index'] = "[2]群聊"; |
|||
$group[$k]['realname'] = $v['displayName'] . " [群聊]"; |
|||
$group[$k]['is_notice'] = $v['is_notice']; |
|||
$group[$k]['is_top'] = $v['is_top']; |
|||
$group[$k]['is_online'] = 1; |
|||
$group[$k]['is_at'] = 0; |
|||
if ($getGroupLastMsg) { |
|||
foreach ($getGroupLastMsg as $key=>$val) { |
|||
if ($val['to_user'] == $v['group_id']) { |
|||
$group[$k]['type'] =$val['type']; |
|||
$group[$k]['lastContent'] = str_encipher($val['lastContent'],false); |
|||
$group[$k]['lastSendTime'] = $val['lastSendTime'] * 1000; |
|||
// 已经赋值了删除掉提升下次循环的性能 |
|||
unset($getGroupLastMsg[$key]); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
if($getAtMsg){ |
|||
foreach ($getAtMsg as $key=> $val) { |
|||
if ($val['to_user'] == $v['group_id']) { |
|||
++$group[$k]['is_at']; |
|||
// 已经赋值了删除掉提升下次循环的性能 |
|||
unset($getAtMsg[$key]); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
try{ |
|||
Gateway::$registerAddress = config('gateway.registerAddress'); |
|||
$onlineList=Gateway::getAllUidList(); |
|||
}catch(\Exception $e){ |
|||
$onlineList=[]; |
|||
} |
|||
foreach ($list_chart as $k => $v) { |
|||
// 是否有消息通知或者置顶聊天 |
|||
$friend = isset($friendList[$v['user_id']]) ? $friendList[$v['user_id']] : []; |
|||
$list_chart[$k]['id'] = $v['user_id']; |
|||
$list_chart[$k]['displayName'] = ($friend['nickname'] ?? '') ? : $v['realname']; |
|||
$list_chart[$k]['name_py'] = $v['name_py']; |
|||
$list_chart[$k]['avatar'] = avatarUrl($v['avatar'], $v['realname'], $v['user_id'], 120); |
|||
$list_chart[$k]['lastContent'] = ''; |
|||
$list_chart[$k]['unread'] = 0; |
|||
$list_chart[$k]['lastSendTime'] = time() * 1000; |
|||
$list_chart[$k]['is_group'] = 0; |
|||
$list_chart[$k]['setting'] = []; |
|||
$list_chart[$k]['is_at'] = 0; |
|||
$list_chart[$k]['last_login_ip'] = $v['last_login_ip']; |
|||
$list_chart[$k]['location'] =$v['last_login_ip'] ? implode(" ", \Ip::find($v['last_login_ip'])) : "未知"; |
|||
$is_online=0; |
|||
if(isset($onlineList[$v['user_id']])){ |
|||
$is_online=1; |
|||
} |
|||
$list_chart[$k]['is_online'] = $is_online; |
|||
|
|||
$is_top = 0; |
|||
$is_notice = 1; |
|||
if ($friend) { |
|||
$is_top = $friend['is_top']; |
|||
$is_notice = $friend['is_notice']; |
|||
} |
|||
$list_chart[$k]['is_top'] = $is_top; |
|||
$list_chart[$k]['is_notice'] = $is_notice; |
|||
if ($unread) { |
|||
foreach ($unread as $val) { |
|||
if ($val['from_user'] == $v['user_id']) { |
|||
$list_chart[$k]['unread'] = $val['unread']; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
if ($lasMsgList) { |
|||
foreach ($lasMsgList as $val) { |
|||
if ($val['from_user'] == $v['user_id'] || $val['to_user'] == $v['user_id']) { |
|||
$content = str_encipher($val['lastContent'],false); |
|||
// 屏蔽已删除的消息 |
|||
if ($val['del_user']) { |
|||
$delUser = explode(',', $val['del_user']); |
|||
if (in_array($user_id, $delUser)) { |
|||
$content = ""; |
|||
} |
|||
} |
|||
$list_chart[$k]['type'] = $val['type']; |
|||
$list_chart[$k]['lastContent'] = $content; |
|||
$list_chart[$k]['lastSendTime'] = $val['lastSendTime'] * 1000; |
|||
|
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
// 合并群聊和联系人 |
|||
$data = array_merge($list_chart, $group); |
|||
// 合并助手消息和聊天消息 |
|||
$helper=self::otherChat($user_id); |
|||
$data=array_merge($data,$helper); |
|||
return $data; |
|||
} |
|||
|
|||
// 获取机器人聊天消息 |
|||
public static function otherChat($uid){ |
|||
$staticList=self::staticUser(); |
|||
$adminNotice=$staticList['adminNotice']; |
|||
$fileTransfer=$staticList['fileTransfer']; |
|||
$count=Message::where(['chat_identify'=>$adminNotice['id']])->count(); |
|||
$createTime=Message::where(['chat_identify'=>$adminNotice['id']])->order('id desc')->value('create_time'); |
|||
$sendTime=0; |
|||
if($createTime){ |
|||
$sendTime=is_string($createTime) ? strtotime($createTime) : $createTime; |
|||
} |
|||
$chat_identify=chat_identify($uid,$fileTransfer['id']); |
|||
$fileLast=Message::where(['is_last'=>1,'chat_identify'=>$chat_identify])->find(); |
|||
$fileSendTime=$fileLast['create_time'] ?? ''; |
|||
$content =$fileLast['content'] ?? ''; |
|||
$friend=Friend::where(['create_user'=>$uid,'friend_user_id'=>$fileTransfer['id']])->find(); |
|||
$notice=[ |
|||
[ |
|||
'id'=>$adminNotice['id'], |
|||
'user_id'=>$adminNotice['id'], |
|||
'displayName'=>$adminNotice['displayName'], |
|||
'realname'=>$adminNotice['displayName'], |
|||
'name_py'=>$adminNotice['name_py'], |
|||
'avatar'=>$adminNotice['avatar'], |
|||
'lastContent'=>$sendTime ? $count.'条公告' :'', |
|||
'unread'=>0, |
|||
'lastSendTime'=>$sendTime * 1000, |
|||
'is_group'=>2, |
|||
'setting'=>[], |
|||
'type'=>'text', |
|||
'is_top'=>0, |
|||
'is_notice'=>1, |
|||
'is_online'=>0, |
|||
'index'=>"[1]系统消息", |
|||
], |
|||
[ |
|||
'id'=>$fileTransfer['id'], |
|||
'user_id'=>$fileTransfer['id'], |
|||
'displayName'=>$fileTransfer['displayName'], |
|||
'realname'=>$fileTransfer['displayName'], |
|||
'name_py'=>$fileTransfer['name_py'], |
|||
'avatar'=>$fileTransfer['avatar'], |
|||
'lastContent'=> str_encipher($content,false) ?: '传输你的文件', |
|||
'unread'=>0, |
|||
'lastSendTime'=>((is_string($fileSendTime) ? strtotime($fileSendTime) : $fileSendTime) * 1000) ?: time() * 1000, |
|||
'is_group'=>3, |
|||
'setting'=>[], |
|||
'type'=>$fileLast['type'] ?? 'text', |
|||
'is_top'=>$friend['is_top'] ?? 0, |
|||
'is_notice'=>$friend['is_notice'] ?? 1, |
|||
'is_online'=>0, |
|||
'index'=>"[1]系统消息", |
|||
], |
|||
]; |
|||
|
|||
return $notice; |
|||
|
|||
} |
|||
|
|||
public static function getList($map) |
|||
{ |
|||
return self::field(self::$defaultField)->where($map)->select(); |
|||
} |
|||
|
|||
// 匹配用户列表信息(返回用户信息) |
|||
|
|||
public static function matchUser($data, $many = false, $field = 'user_id', $cs = 80) |
|||
{ |
|||
if ($many) { |
|||
$idr = arrayToString($data, $field, false); |
|||
} else { |
|||
$idr = []; |
|||
if (is_array($field)) { |
|||
foreach ($field as $v) { |
|||
$idr[] = $data[$v]; |
|||
} |
|||
} else { |
|||
$idr = [$data[$field]]; |
|||
} |
|||
} |
|||
$key = array_search(0, $idr); |
|||
if ($key) { |
|||
array_splice($idr, $key, 1); |
|||
} |
|||
$userList = self::where([['user_id', 'in', $idr]])->field(self::$defaultField)->select()->toArray(); |
|||
$friend = Friend::where([['friend_user_id', 'in', $idr],['create_user','=',self::$uid]])->field('friend_user_id,nickname')->select()->toArray(); |
|||
$list = []; |
|||
foreach ($userList as $v) { |
|||
$v['avatar'] = avatarUrl($v['avatar'], $v['realname'], $v['user_id'], $cs); |
|||
$v['id'] = $v['user_id']; |
|||
if($friend){ |
|||
foreach($friend as $key=>$val){ |
|||
if($val['friend_user_id']==$v['user_id']){ |
|||
$v['realname']=$val['nickname'] ? : $v['displayName']; |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
$list[$v['user_id']] = $v; |
|||
} |
|||
return $list; |
|||
} |
|||
|
|||
// 匹配用户列表信息(返回data) |
|||
public static function matchAllUser($data, $many = false, $field = 'user_id', $key = "userInfo", $cs = 80) |
|||
{ |
|||
if ($many) { |
|||
$idr = arrayToString($data, $field); |
|||
$userList = self::getList([['user_id', 'in', $idr]]); |
|||
foreach ($data as $k => $v) { |
|||
foreach ($userList as $vv) { |
|||
if ($v[$field] == $vv['user_id']) { |
|||
$data[$k][$key] = [ |
|||
'id' => $vv['user_id'], |
|||
'displayName' => $vv['realname'], |
|||
'account' => $vv['account'], |
|||
'name_py' => $vv['name_py'], |
|||
'avatar' => avatarUrl($vv['avatar'], $vv['realname'], $vv['user_id'], $cs), |
|||
]; |
|||
} |
|||
} |
|||
} |
|||
} else { |
|||
$user = self::getUserInfo(['user_id' => $data[$field]]); |
|||
$data[$key] = [ |
|||
'id' => $user['user_id'], |
|||
'displayName' => $user['realname'], |
|||
'account' => $user['account'], |
|||
'name_py' => $user['name_py'], |
|||
'avatar' => avatarUrl($user['avatar'], $user['realname'], $user['user_id']), |
|||
]; |
|||
} |
|||
return $data; |
|||
} |
|||
|
|||
|
|||
// 将id转换成联系人信息 |
|||
public function setContact($id,$is_group=0,$type='text',$content='',$contactInfo=null){ |
|||
$data=[ |
|||
'id'=>$id, |
|||
'lastContent'=>$content, |
|||
'unread'=>0, |
|||
'lastSendTime'=> time() * 1000, |
|||
'is_group'=>$is_group, |
|||
'is_top'=>0, |
|||
'is_notice'=>1, |
|||
'is_top'=>0, |
|||
'is_at'=>0, |
|||
'setting'=>[], |
|||
'type'=>$type, |
|||
'location'=>'', |
|||
]; |
|||
if($is_group==0){ |
|||
$user=$contactInfo ?: User::where('user_id',$id)->find(); |
|||
if(!$user){ |
|||
$this->error=lang('user.exist'); |
|||
return false; |
|||
} |
|||
$user->avatar=avatarUrl($user->avatar,$user->realname,$user->user_id,120); |
|||
// 查询好友关系 |
|||
$friend= self::$userInfo ? Friend::where(['friend_user_id'=>$id,'create_user'=>self::$userInfo['user_id']])->find() : []; |
|||
$data['displayName'] = ($friend['nickname'] ?? '') ? : $user['realname']; |
|||
$data['avatar'] = avatarUrl($user['avatar'], $user['realname'], $user['user_id'], 120); |
|||
$data['location'] =$user['last_login_ip'] ? implode(" ", \Ip::find($user['last_login_ip'])) : "未知"; |
|||
$data['name_py'] = $user['name_py']; |
|||
}else{ |
|||
$group_id=is_numeric($id) ? $id : (explode('-',$id)[1] ?? 0); |
|||
$group=$contactInfo ?: Group::where(['group_id'=>$group_id])->find(); |
|||
if(!$group){ |
|||
$this->error=lang('group.exist'); |
|||
return false; |
|||
} |
|||
$data['id'] = 'group-'.$group_id; |
|||
$data['displayName'] = $group['name']; |
|||
$data['avatar'] = avatarUrl($group['avatar'], $group['name'], $group['group_id'], 120); |
|||
$data['name_py'] = $group['name_py']; |
|||
$data['setting'] = $group['setting']; |
|||
$data['role'] = 3; |
|||
} |
|||
$data['index'] =getFirstChart($data['displayName']); |
|||
return $data; |
|||
} |
|||
|
|||
// 验证账号的合法性 |
|||
public function checkAccount(&$data){ |
|||
$user_id=$data['user_id'] ?? 0; |
|||
if($user_id){ |
|||
$user=self::find($data['user_id']); |
|||
if(!$user){ |
|||
$this->error='账户不存在'; |
|||
return false; |
|||
} |
|||
if($user->user_id==1 && self::$uid!=1){ |
|||
$this->error='超管账户只有自己才能修改'; |
|||
return false; |
|||
} |
|||
$other=self::where([['account','=',$data['account']],['user_id','<>',$data['user_id']]])->find(); |
|||
if($other){ |
|||
$this->error='账户已存在'; |
|||
return false; |
|||
} |
|||
}else{ |
|||
$user=self::where('account',$data['account'])->find(); |
|||
if($user){ |
|||
$this->error='账户已存在'; |
|||
return false; |
|||
} |
|||
} |
|||
$config=Config::getSystemInfo(); |
|||
$regauth=$config['sysInfo']['regauth'] ?? 0; |
|||
$acType=\utils\Regular::check_account($data['account']); |
|||
switch($regauth){ |
|||
case 1: |
|||
if($acType!=1){ |
|||
$this->error='当前系统只允许账号为手机号!'; |
|||
return false; |
|||
} |
|||
break; |
|||
case 2: |
|||
if($acType!=2){ |
|||
$this->error='当前系统只允许账号为邮箱!'; |
|||
return false; |
|||
} |
|||
break; |
|||
case 3: |
|||
// 验证账号是否为手机号或者邮箱 |
|||
if(!$acType){ |
|||
$this->error='账户必须为手机号或者邮箱'; |
|||
return false; |
|||
} |
|||
break; |
|||
default: |
|||
break; |
|||
} |
|||
|
|||
$data['is_auth'] =$regauth ? 1 : 0; |
|||
$email=$data['email'] ?? ''; |
|||
if($data['is_auth'] && $acType==2 && !$email){ |
|||
$data['email'] =$data['account']; |
|||
} |
|||
return true; |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
<?php |
|||
|
|||
namespace app\enterprise\model; |
|||
|
|||
use app\BaseModel; |
|||
|
|||
class WechatMoments extends BaseModel |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
<?php |
|||
/** |
|||
* lvzhe [a web admin based ThinkPHP5] |
|||
*/ |
|||
|
|||
namespace app\enterprise\validate; |
|||
|
|||
use think\Validate; |
|||
|
|||
class User extends Validate |
|||
{ |
|||
protected $rule = [ |
|||
'account|帐号' => 'require', |
|||
'password|密码' => 'require', |
|||
'captcha|验证码' => 'require|captcha', |
|||
'oldpassword|旧密码' => 'require', |
|||
'repassword|重复密码' => 'require', |
|||
]; |
|||
|
|||
protected $scene = [ |
|||
'password' => ['password', 'oldpassword', 'repassword'], |
|||
'login' => ['account', 'password'], |
|||
]; |
|||
} |
|||
@ -0,0 +1,184 @@ |
|||
<?php |
|||
namespace app\index\controller; |
|||
|
|||
use app\enterprise\model\{File,Group,User}; |
|||
use think\facade\View; |
|||
use app\manage\model\Config; |
|||
use app\Request; |
|||
|
|||
class Index |
|||
{ |
|||
|
|||
public function index() |
|||
{ |
|||
if (!file_exists(PACKAGE_PATH . "install.lock")) { |
|||
return redirect(url('index/install/index')); |
|||
} |
|||
// 自动跳转后无法注册 |
|||
// if(request()->isMobile() && !env('app.demon_mode',false)){ |
|||
// return redirect("/h5"); |
|||
// } |
|||
return redirect("/index.html"); |
|||
} |
|||
|
|||
public function view() |
|||
{ |
|||
$url=request()->param('src'); |
|||
$suffix=explode('.',$url); |
|||
$ext=$suffix[count($suffix)-1]; |
|||
return View::fetch('',[ |
|||
'url' => $url, |
|||
'ext'=>$ext, |
|||
'name'=>lang('file.preview') |
|||
]); |
|||
} |
|||
|
|||
// 头像生成 |
|||
public function avatar() |
|||
{ |
|||
circleAvatar(input('str'), input('s') ?: 80, input('uid'));die; |
|||
} |
|||
|
|||
// 文件下载 |
|||
public function download() |
|||
{ |
|||
|
|||
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) { |
|||
throw new \think\Exception(lang('file.browserDown'),400); |
|||
} |
|||
$param = request()->param(); |
|||
$file_id = $param['file_id'] ?? 0; |
|||
if (!$file_id) { |
|||
throw new \think\Exception(lang('system.parameterError'), 502); |
|||
} |
|||
try { |
|||
$file_id = decryptIds($file_id); |
|||
} catch (\Exception $e) { |
|||
throw new \think\Exception($e->getMessage(), 400); |
|||
} |
|||
$file = File::find($file_id); |
|||
if (!$file) { |
|||
throw new \think\Exception(lang('file.exist'),404); |
|||
} |
|||
$file = $file->toArray(); |
|||
// 兼容本地文件下载 |
|||
$fileUrl=getDiskUrl(); |
|||
if($fileUrl==getMainHost()){ |
|||
$url=rtrim(public_path(),'/').$file['src']; |
|||
}else{ |
|||
$url= getFileUrl($file['src']); |
|||
} |
|||
return \utils\File::download($url, $file['name'] . '.' . $file['ext'], $file['size'], $file['ext']); |
|||
} |
|||
|
|||
// 扫码获取信息 |
|||
public function scanQr(){ |
|||
$param=request()->param(); |
|||
$action=$param['action'] ?? ''; |
|||
$token=$param['token'] ?? ''; |
|||
$realToken=$param['realToken'] ?? ''; |
|||
if(request()->isPost() && $action && $token && $realToken){ |
|||
$actions=[ |
|||
'g'=>'group', |
|||
'u'=>'user', |
|||
]; |
|||
$a=$actions[$action] ?? ''; |
|||
if(!$a){ |
|||
return warning(lang('scan.failure')); |
|||
} |
|||
return $this->$a($param); |
|||
}else{ |
|||
return $this->index(); |
|||
} |
|||
} |
|||
|
|||
protected function group($param) |
|||
{ |
|||
$token=authcode(urldecode($param['realToken']),"DECODE", 'qr'); |
|||
if(!$token){ |
|||
return warning(lang('scan.failure')); |
|||
} |
|||
$groupInfo=explode('-',$token); |
|||
$uid=$groupInfo[0]; |
|||
$group_id=$groupInfo[1]; |
|||
$group=Group::find($group_id); |
|||
if($group){ |
|||
$group=$group->toArray(); |
|||
$group['avatar']=avatarUrl($group['avatar'],$group['name'],$group_id,120); |
|||
$group['invite_id']=$uid; |
|||
$group['id']='group-'.$group_id; |
|||
$group['action']='groupInfo'; |
|||
return success('',$group); |
|||
}else{ |
|||
return warning(lang('scan.failure')); |
|||
} |
|||
} |
|||
|
|||
protected function user($param) |
|||
{ |
|||
$id=decryptIds($param['token']); |
|||
if(!$id){ |
|||
return warning(lang('scan.failure')); |
|||
} |
|||
$user=User::where(['user_id'=>$id])->field(User::$defaultField)->find(); |
|||
if($user){ |
|||
$user=$user->toArray(); |
|||
$user['avatar']=avatarUrl($user['avatar'],$user['realname'],$user['user_id'],120); |
|||
$user['id']=$user['user_id']; |
|||
$user['action']='userInfo'; |
|||
return success('',$user); |
|||
}else{ |
|||
return warning(lang('scan.failure')); |
|||
} |
|||
} |
|||
|
|||
// app下载页 |
|||
public function downApp(){ |
|||
// echo request()->domain(true); |
|||
$downAppUrl=env('app.downApp_url',''); |
|||
if($downAppUrl){ |
|||
return redirect($downAppUrl); |
|||
} |
|||
$config=Config::where('name','sysInfo')->value('value'); |
|||
$andriod=getAppDowmUrl('andriod'); |
|||
$winUrl=getAppDowmUrl('windows'); |
|||
$macUrl=getAppDowmUrl('mac'); |
|||
$client=[ |
|||
'andriod_appid'=>env('app.andriod_appid',''), |
|||
'andriod_webclip'=>env('app.andriod_webclip','') ? : $andriod, |
|||
'ios_appid'=>env('app.ios_appid',''), |
|||
'ios_webclip'=>env('app.ios_webclip',''), |
|||
'win_webclip'=>env('app.win_webclip','') ? : $winUrl, |
|||
'mac_webclip'=>env('app.mac_webclip','') ? : $macUrl |
|||
]; |
|||
$noUrl=false; |
|||
if(!$client['andriod_appid'] && !$client['andriod_webclip'] && !$client['ios_appid'] && !$client['ios_webclip']){ |
|||
$noUrl=true; |
|||
} |
|||
View::assign('noUrl',$noUrl); |
|||
View::assign('client',$client); |
|||
View::assign('config',$config); |
|||
return View::fetch(); |
|||
} |
|||
|
|||
// 下载APP |
|||
public function downloadApp(){ |
|||
|
|||
$platform=request()->param('platform','windows'); |
|||
$config=config('version.'.$platform); |
|||
$name=config('version.app_name'); |
|||
if($platform=='andriod'){ |
|||
$packageName=$name."_Setup_".$config['version'].".apk"; |
|||
}elseif($platform=='mac'){ |
|||
$packageName=$name."_Setup_".$config['version'].".dmg"; |
|||
}else{ |
|||
$packageName=$name."_Setup_".$config['version'].".exe"; |
|||
} |
|||
$file=PACKAGE_PATH . $packageName; |
|||
if(is_file($file)){ |
|||
return \utils\File::download($file, $packageName); |
|||
}else{ |
|||
return shutdown(lang('file.exist')); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,568 @@ |
|||
<?php |
|||
// +---------------------------------------------------------------------- |
|||
// | Description: 安装 |
|||
// +---------------------------------------------------------------------- |
|||
// | Author: xiekunyu | raingad@foxmail.com |
|||
// +---------------------------------------------------------------------- |
|||
|
|||
namespace app\index\controller; |
|||
use think\facade\Request; |
|||
use think\facade\Db; |
|||
use think\facade\View; |
|||
use think\facade\Config; |
|||
use Env; |
|||
|
|||
class Install |
|||
{ |
|||
// private $count = 100; |
|||
// private $now = 0; |
|||
protected $status=1; |
|||
|
|||
public function _initialize() |
|||
{ |
|||
/*防止跨域*/ |
|||
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']); |
|||
header('Access-Control-Allow-Credentials: true'); |
|||
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS'); |
|||
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, authKey, sessionId"); |
|||
} |
|||
|
|||
/** |
|||
* [index 安装步骤] |
|||
* @author Michael_xu |
|||
* @param |
|||
*/ |
|||
public function index() |
|||
{ |
|||
$protocol = strpos(strtolower($_SERVER['SERVER_PROTOCOL']), 'https') === false ? 'http' : 'https'; |
|||
|
|||
if (file_exists(PACKAGE_PATH . "install.lock")) { |
|||
echo "<meta http-equiv='content-type' content='text/html; charset=UTF-8'> <script>alert('请勿重复安装!');location.href='".$protocol."://".$_SERVER["HTTP_HOST"]."';</script>"; |
|||
die(); |
|||
} |
|||
|
|||
if (!file_exists(PUBLIC_PATH . "sql/database.sql")) { |
|||
echo "<meta http-equiv='content-type' content='text/html; charset=UTF-8'> <script>alert('缺少必要的数据库文件!');location.href='".$protocol."://".$_SERVER["HTTP_HOST"]."';</script>"; |
|||
die(); |
|||
} |
|||
|
|||
return View::fetch('index'); |
|||
} |
|||
|
|||
// 检测环境配置和文件夹读写权限 |
|||
public function getEnv() |
|||
{ |
|||
$data = []; |
|||
$data['env'] = self::checkEnv(); |
|||
$data['dir'] = self::checkDir(); |
|||
$data['version'] = $this->version(); |
|||
$data['status'] = $this->status; |
|||
return success('',$data); |
|||
} |
|||
|
|||
//版本 |
|||
public function version() |
|||
{ |
|||
$res = include(CONF_PATH.'app.php'); |
|||
$data=[ |
|||
'VERSION'=>$res['app_version'], |
|||
'RELEASE'=>$res['app_release'], |
|||
]; |
|||
return $data ? : array('VERSION' => '0.5.18','RELEASE' => '20210518'); |
|||
} |
|||
|
|||
// 检查数据库 |
|||
public function checkDatabase(){ |
|||
|
|||
if (file_exists(PACKAGE_PATH . "install.lock")) { |
|||
return warning('请勿重复安装!'); |
|||
} |
|||
if (!file_exists(PUBLIC_PATH . "sql/database.sql")) { |
|||
return warning('缺少必要的数据库文件!'); |
|||
} |
|||
$temp = request()->param(); |
|||
$db_config = $temp['form']; |
|||
$db_config['type'] = 'mysql'; |
|||
if (empty($db_config['hostname'])) { |
|||
return warning('请填写数据库主机!'); |
|||
} |
|||
if (empty($db_config['hostport'])) { |
|||
return warning('请填写数据库端口!'); |
|||
} |
|||
if (preg_match('/[^0-9]/', $db_config['hostport'])) { |
|||
return warning('数据库端口只能是数字!'); |
|||
} |
|||
if (empty($db_config['database'])) { |
|||
return warning('请填写数据库名!'); |
|||
} |
|||
if (empty($db_config['username'])) { |
|||
return warning('请填写数据库用户名!'); |
|||
} |
|||
if (empty($db_config['password'])) { |
|||
return warning('请填写数据库密码!'); |
|||
} |
|||
if (empty($db_config['prefix'])) { |
|||
return warning('请填写表前缀!'); |
|||
} |
|||
if (empty($db_config['redishost'])) { |
|||
return warning('请填写redis主机地址!'); |
|||
} |
|||
if (empty($db_config['redisport'])) { |
|||
return warning('请填写redis端口!'); |
|||
} |
|||
if (preg_match('/[^a-z0-9_]/i', $db_config['prefix'])) { |
|||
return warning('表前缀只能包含数字、字母和下划线!'); |
|||
} |
|||
|
|||
// 创建数据库配置文件 |
|||
self::mkDatabase($db_config); |
|||
// 检测数据库连接 |
|||
try{ |
|||
$conn=mysqli_connect($db_config['hostname'], $db_config['username'], $db_config['password'],'',$db_config['hostport']); |
|||
// 检测连接 |
|||
if ($conn->connect_error) { |
|||
return warning("连接失败: " . $conn->connect_error); |
|||
} |
|||
// 创建数据库 |
|||
$sql = "CREATE DATABASE IF NOT EXISTS `".$db_config['database']."` default collate utf8_general_ci "; |
|||
if ($conn->query($sql) === TRUE) { |
|||
return success('数据库连接成功',['status'=>1]); |
|||
} else{ |
|||
return warning('没有找到您填写的数据库名且无法创建!请检查连接账号是否有创建数据库的权限!'); |
|||
} |
|||
}catch(\Exception $e){ |
|||
return warning('数据库连接失败,请检查数据库配置!'); |
|||
} |
|||
|
|||
} |
|||
|
|||
// 执行安装 |
|||
public function install(){ |
|||
$db_config=Config::get('database.connections.mysql'); |
|||
$sql = file_get_contents( PUBLIC_PATH . "sql/database.sql"); |
|||
$sqlList = parse_sql($sql, 0, ['yu_' => $db_config['prefix']]); |
|||
$install_count=0; |
|||
if ($sqlList) { |
|||
$sqlList = array_filter($sqlList); |
|||
$install_count = count($sqlList); |
|||
foreach ($sqlList as $k=>$v) { |
|||
try { |
|||
$temp_sql = $v.';'; |
|||
Db::query($temp_sql); |
|||
} catch(\Exception $e) { |
|||
touch(PACKAGE_PATH . "install.lock"); |
|||
return error('数据库sql安装出错,请操作数据库手动导入sql文件'.$e->getMessage()); |
|||
} |
|||
} |
|||
} |
|||
touch(PACKAGE_PATH . "install.lock"); |
|||
return success('安装成功',['status'=>$this->status],$install_count); |
|||
} |
|||
|
|||
//ajax 进度条 |
|||
public function progress() |
|||
{ |
|||
$data['length'] = session('install_count'); |
|||
$data['now'] = session('install_now'); |
|||
return success('',$data); |
|||
} |
|||
|
|||
//添加database.php文件 |
|||
private function mkDatabase(array $data) |
|||
{ |
|||
$code = <<<INFO |
|||
APP_DEBUG = true |
|||
|
|||
[APP] |
|||
NAME = IM |
|||
LOGO = |
|||
VERSION = 5.4.0 |
|||
RELEASE = 20241226 |
|||
# 主域名必填 |
|||
HOST = |
|||
DEFAULT_TIMEZONE = Asia/Shanghai |
|||
ID = a1b2c3d4e5f |
|||
SECRET = GHJKUG123456sdfghjkl |
|||
API_STATUS = true |
|||
|
|||
# thinkapi的令牌,目前只用于敏感词过滤,其他接口自行接入 |
|||
THINKAPI_TOKEN = |
|||
|
|||
# 下载页分发链接 |
|||
DOWNAPP_URL = |
|||
# 安卓包名,如果上架了市场,根据市场ID跳转市场 |
|||
ANDRIOD_APPID = |
|||
#安卓下载地址,如果未设置会检测根目录是否有app.apk |
|||
ANDRIOD_WEBCLIP = |
|||
#APPSTORE市场ID |
|||
IOS_APPID = |
|||
#IOS下载地址,如果没有市场的ID则使用下载地址 |
|||
IOS_WEBCLIP = |
|||
#windows下载地址 |
|||
WIN_WEBCLIP = |
|||
#mac下载地址 |
|||
MAC_WEBCLIP = |
|||
|
|||
[DATABASE] |
|||
TYPE = {$data['type']} |
|||
HOSTNAME = {$data['hostname']} |
|||
DATABASE = {$data['database']} |
|||
USERNAME = {$data['username']} |
|||
PASSWORD = {$data['password']} |
|||
HOSTPORT = {$data['hostport']} |
|||
CHARSET = utf8mb4 |
|||
DEBUG = true |
|||
prefix = {$data['prefix']} |
|||
[LANG] |
|||
default_lang = zh-cn |
|||
|
|||
[REDIS] |
|||
HOST = {$data['redishost']} |
|||
PORT = {$data['redisport']} |
|||
PASSWORD ={$data['redispass']} |
|||
|
|||
视频封面截取配置,需要单独安装,宝塔安装默认地址为/www/server/ffmpeg/ffmpeg-6.1 |
|||
[FFMPEG] |
|||
BIN_PATH = |
|||
|
|||
[AES] |
|||
TOKEN_KEY = tHTi8USApxsdfnhTM |
|||
LOGIN_KEY = t2fe6HMnmssswDVi2 |
|||
#最好是自定义自己能记的,不要太长,不要太短,不要太简单,不要太复杂,不要太难记,一旦确定之后就不需要再修改。否者无法解析聊天记录,开启后聊天记录不可被搜索 |
|||
CHAT_KEY = |
|||
|
|||
[JWT] |
|||
SECRET = 17b190c0d612321f94f57325ae5a8b4c |
|||
TTL = 2592000 |
|||
|
|||
[WORKER] |
|||
NAME = businessWorker |
|||
PORT = 8282 |
|||
# 根据自己的核心数而配置 |
|||
COUNT = 1 |
|||
START_PORT = 2300 |
|||
REGISTER_ADDRESS =127.0.0.1:1236 |
|||
lAN_IP = 127.0.0.1 |
|||
# 分部署部署只需要启动一个gateway,其他的gateway只需要配置register_address即可 |
|||
REGISTER_DEPLOY = true |
|||
|
|||
#配置预览功能,本系统主要使用第三方的预览工具,比如永中云转换,自带预览系统 |
|||
[PREVIEW] |
|||
# 自带预览系统URL,主要用于预览媒体文件,已内置,必须要有最后的/斜杠 |
|||
own= |
|||
# 永中云文件预览,主要用于文档预览,必须要有最后的/斜杠 |
|||
yzdcs= |
|||
# 永中云api code |
|||
keycode=17444844212312 |
|||
|
|||
[UNIPUSH] |
|||
# unipush的云函数转url地址,主要用于推送 |
|||
URL= |
|||
# unipush直接推送通知栏还是app接收后再创建通知栏 |
|||
IS_FORCE=false |
|||
|
|||
# 配置对象储存,主要用于聊天文件储存,可以通过后台进行配置 |
|||
|
|||
[FILESYSTEM] |
|||
driver=local |
|||
aliyun_accessId=false |
|||
aliyun_accessSecret=false |
|||
aliyun_bucket=false |
|||
aliyun_endpoint=false |
|||
aliyun_url=false |
|||
qiniu_accessKey=false |
|||
qiniu_secretKey=false |
|||
qiniu_bucket=false |
|||
qiniu_url=false |
|||
qcloud_region=false |
|||
qcloud_appId=false |
|||
qcloud_secretId=false |
|||
qcloud_secretKey=false |
|||
qcloud_bucket=false |
|||
qcloud_cdn=false |
|||
INFO; |
|||
|
|||
@file_put_contents( root_path().'.env', $code); |
|||
$database=env('database.database'); |
|||
// 判断写入是否成功 |
|||
if (empty($database) || $database != $data['database']) { |
|||
return warning('[.env]数据库配置写入失败!'); |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
//添加database.php文件 |
|||
private function mkDatabase1(array $data) |
|||
{ |
|||
$code = <<<INFO |
|||
<?php |
|||
return [ |
|||
// 自定义时间查询规则 |
|||
'time_query_rule' => [], |
|||
|
|||
// 自动写入时间戳字段 |
|||
// true为自动识别类型 false关闭 |
|||
// 字符串则明确指定时间字段类型 支持 int timestamp datetime date |
|||
'auto_timestamp' => true, |
|||
|
|||
// 时间字段取出后的默认时间格式 |
|||
'datetime_format' => 'Y-m-d H:i:s', |
|||
'default' => '{$data['type']}', |
|||
'connections' => [ |
|||
'mysql' => [ |
|||
// 数据库类型 |
|||
'type' =>env('database.type', '{$data['type']}'), |
|||
// 服务器地址 |
|||
'hostname' => env('database.hostname','{$data['hostname']}'), |
|||
// 数据库名 |
|||
'database' => env('database.database','{$data['database']}'), |
|||
// 用户名 |
|||
'username' => env('database.username','{$data['username']}'), |
|||
// 密码 |
|||
'password' => env('database.password','{$data['password']}'), |
|||
// 端口 |
|||
'hostport' => env('database.hostport','{$data['hostport']}'), |
|||
// 数据库连接参数 |
|||
'params' => [], |
|||
// 数据库编码默认采用utf8 |
|||
'charset' => env('database.charset', 'utf8'), |
|||
// 数据库表前缀 |
|||
'prefix' => env('database.prefix', '{$data['prefix']}'), |
|||
|
|||
// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) |
|||
'deploy' => 0, |
|||
// 数据库读写是否分离 主从式有效 |
|||
'rw_separate' => false, |
|||
// 读写分离后 主服务器数量 |
|||
'master_num' => 1, |
|||
// 指定从服务器序号 |
|||
'slave_no' => '', |
|||
// 是否严格检查字段是否存在 |
|||
'fields_strict' => true, |
|||
// 是否需要断线重连 |
|||
'break_reconnect' => false, |
|||
// 监听SQL |
|||
'trigger_sql' => env('app_debug', true), |
|||
// 开启字段缓存 |
|||
'fields_cache' => false, |
|||
// 字段缓存路径 |
|||
'schema_cache_path' => app()->getRuntimePath() . 'schema' . DIRECTORY_SEPARATOR, |
|||
] |
|||
] |
|||
|
|||
]; |
|||
|
|||
INFO; |
|||
file_put_contents( CONF_PATH.'database.php', $code); |
|||
// 判断写入是否成功 |
|||
$config = include CONF_PATH.'database.php'; |
|||
if (empty($config['database']) || $config['database'] != $data['database']) { |
|||
return warning('[config/database.php]数据库配置写入失败!'); |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
//检查目录权限 |
|||
public function check_dir_iswritable($dir_path){ |
|||
$dir_path=str_replace( '\\','/',$dir_path); |
|||
$is_writale=1; |
|||
if (!is_dir($dir_path)) { |
|||
$is_writale=0; |
|||
return $is_writale; |
|||
} else { |
|||
$file_hd=@fopen($dir_path.'/test.txt','w'); |
|||
if (!$file_hd) { |
|||
@fclose($file_hd); |
|||
@unlink($dir_path.'/test.txt'); |
|||
$is_writale=0; |
|||
return $is_writale; |
|||
} |
|||
$dir_hd = opendir($dir_path); |
|||
while (false !== ($file=readdir($dir_hd))) { |
|||
if ($file != "." && $file != "..") { |
|||
if (is_file($dir_path.'/'.$file)) { |
|||
//文件不可写,直接返回 |
|||
if (!is_writable($dir_path.'/'.$file)) { |
|||
return 0; |
|||
} |
|||
} else { |
|||
$file_hd2=@fopen($dir_path.'/'.$file.'/test.txt','w'); |
|||
if (!$file_hd2) { |
|||
@fclose($file_hd2); |
|||
@unlink($dir_path.'/'.$file.'/test.txt'); |
|||
$is_writale=0; |
|||
return $is_writale; |
|||
} |
|||
//递归 |
|||
$is_writale=$this->check_dir_iswritable($dir_path.'/'.$file); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
return $is_writale; |
|||
} |
|||
|
|||
/** |
|||
* 环境检测 |
|||
* @return array |
|||
*/ |
|||
private function checkEnv() |
|||
{ |
|||
// $items = [ |
|||
// 'os' => ['操作系统', PHP_OS, '类Unix', 'ok'], |
|||
// 'php' => ['PHP版本', PHP_VERSION, '7.3 ( <em style="color: #888; font-size: 12px;">>= 7.0</em> )', 'ok','性能更佳'], |
|||
// 'gd' => ['gd', '开启', '开启', 'ok'], |
|||
// 'openssl' => ['openssl', '开启', '开启', 'ok'], |
|||
// 'pdo' => ['pdo', '开启', '开启', 'ok'], |
|||
// ]; |
|||
$items = [ |
|||
['name'=>'操作系统','alias'=>'os','value'=>PHP_OS,'status'=> 'ok','description'=>"操作系统需要类Unix"], |
|||
['name'=>'PHP版本','alias'=>'version','value'=> PHP_VERSION, 'status'=>'ok','description'=>"PHP版本必须大于7.0"], |
|||
['name'=>'gd库','alias'=>'gd', 'value'=>'开启', 'status'=>'ok','description'=>"开启GD库"], |
|||
['name'=>'pdo','alias'=>'pdo', 'value'=>'开启', 'status'=>'ok','description'=>"PDO扩展"], |
|||
['name'=>'openssl','alias'=>'openssl', 'value'=>'开启', 'status'=>'ok','description'=>"OPENSSL扩展"], |
|||
['name'=>'pcntl','alias'=>'pcntl', 'value'=>'开启', 'status'=>'ok','description'=>"pcntl扩展,消息推送必须开启"], |
|||
['name'=>'posix','alias'=>'posix', 'value'=>'开启', 'status'=>'ok','description'=>"posix扩展,消息推送必须开启"], |
|||
['name'=>'event','alias'=>'event', 'value'=>'开启', 'status'=>'ok','description'=>"event扩展(可选安装),处理消息推送高并发"], |
|||
]; |
|||
foreach($items as $k=>$v){ |
|||
$status='ok'; |
|||
switch($v['alias']){ |
|||
case 'php': |
|||
if (substr($v['value'],0,3) < '7.0') { |
|||
$status='no'; |
|||
$this->status=0; |
|||
} |
|||
break; |
|||
case 'gd': |
|||
if (!extension_loaded('gd')) { |
|||
$items[$k]['value'] = '未开启'; |
|||
$status='no'; |
|||
$this->status=0; |
|||
} |
|||
break; |
|||
case 'openssl': |
|||
if (!extension_loaded('openssl')) { |
|||
$items[$k]['value'] = '未开启'; |
|||
$status='no'; |
|||
$this->status=0; |
|||
} |
|||
break; |
|||
case 'pdo': |
|||
if (!extension_loaded('pdo')) { |
|||
$this->status=0; |
|||
$items[$k]['value'] = '未开启'; |
|||
$status='no'; |
|||
} |
|||
break; |
|||
case 'pcntl': |
|||
if (PHP_OS === 'Linux') { |
|||
if (!extension_loaded('pcntl')) { |
|||
$items[$k]['value'] = '未开启'; |
|||
$status='no'; |
|||
} |
|||
} else { |
|||
$items[$k]['value'] = 'win无需开启'; |
|||
} |
|||
break; |
|||
case 'posix': |
|||
if (PHP_OS === 'Linux') { |
|||
if (!extension_loaded('posix')) { |
|||
$this->status=0; |
|||
$items[$k]['value'] = '未开启'; |
|||
$status='no'; |
|||
} |
|||
} else { |
|||
$items[$k]['value'] = 'win无需开启'; |
|||
} |
|||
|
|||
break; |
|||
case 'event': |
|||
if (PHP_OS === 'Linux') { |
|||
if (!extension_loaded('event')) { |
|||
$items[$k]['value'] = '未开启'; |
|||
$status='no'; |
|||
} |
|||
} else { |
|||
$items[$k]['value'] = 'win无需开启'; |
|||
} |
|||
break; |
|||
} |
|||
|
|||
$items[$k]['status'] = $status; |
|||
} |
|||
return $items; |
|||
} |
|||
|
|||
/** |
|||
* 目录权限检查 |
|||
* @return array |
|||
*/ |
|||
private function checkDir() |
|||
{ |
|||
$items = [ |
|||
['dir', root_path().'app', 'app', '读写', '读写', 'ok'], |
|||
['dir', root_path().'extend', 'extend', '读写', '读写', 'ok'], |
|||
['dir', root_path().'runtime', './temp', '读写', '读写', 'ok'], |
|||
['dir', root_path().'public', './upload', '读写', '读写', 'ok'], |
|||
['file', root_path().'config', 'config', '读写', '读写', 'ok'], |
|||
]; |
|||
$items = [ |
|||
['path'=>root_path().'app', 'dir'=>'app', 'value'=>'读写', 'type'=>'dir','status'=>'ok'], |
|||
['path'=>root_path().'extend', 'dir'=>'extend', 'value'=>'读写', 'type'=>'dir','status'=>'ok'], |
|||
['path'=> root_path().'runtime', 'dir'=>'runtime', 'value'=>'读写', 'type'=>'dir','status'=>'ok'], |
|||
['path'=>root_path().'public', 'dir'=>'public', 'value'=>'读写', 'type'=>'dir','status'=>'ok'], |
|||
['path'=>root_path().'config', 'dir'=>'config', 'value'=>'读写', 'type'=>'file','status'=>'ok'], |
|||
]; |
|||
$status=1; |
|||
foreach ($items as $k=>$v) { |
|||
if ($v['type'] == 'dir') {// 文件夹 |
|||
if (!is_writable($v['path'])) { |
|||
if (is_dir($v['path'])) { |
|||
$items[$k]['value'] = '不可写'; |
|||
$items[$k]['status'] = 'no'; |
|||
} else { |
|||
$items[$k]['value'] = '不存在'; |
|||
$items[$k]['status'] = 'no'; |
|||
} |
|||
$this->status=0; |
|||
} |
|||
} else {// 文件 |
|||
if (!is_writable($v['path'])) { |
|||
$items[$k]['value'] = '不可写'; |
|||
$items[$k]['status'] = 'no'; |
|||
$this->status=0; |
|||
} |
|||
} |
|||
} |
|||
return $items; |
|||
} |
|||
|
|||
/** |
|||
* 验证序列号 |
|||
* @param |
|||
* @return |
|||
*/ |
|||
public function checkCodeOld($username) { |
|||
$encryption = md5($username); |
|||
$substr = substr($username, strlen($username)-6); |
|||
$subArr = str_split($substr, 1); |
|||
$code = ''; |
|||
for ($i = 0; $i <= 5; $i++) { |
|||
$code .= $encryption[$subArr[$i]]; |
|||
} |
|||
return $code; |
|||
} |
|||
|
|||
//写入license文件 |
|||
private function mkLicense($wkcode) |
|||
{ |
|||
file_put_contents( CONF_PATH.'license.dat', $wkcode); |
|||
// 判断写入是否成功 |
|||
// $config = include CONF_PATH.'license.dat'; |
|||
// if (empty($config)) { |
|||
// return resultArray(['error' => 'license配置写入失败!']); |
|||
// } |
|||
return true; |
|||
} |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
<?php |
|||
// +---------------------------------------------------------------------- |
|||
// | ThinkPHP [ WE CAN DO IT JUST THINK ] |
|||
// +---------------------------------------------------------------------- |
|||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved. |
|||
// +---------------------------------------------------------------------- |
|||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 ) |
|||
// +---------------------------------------------------------------------- |
|||
// | Author: liu21st <liu21st@gmail.com> |
|||
// +---------------------------------------------------------------------- |
|||
use think\facade\Route; |
|||
Route::rule('avatar/:str/:s/:uid','index/avatar'); |
|||
Route::rule('view','index/index/view'); |
|||
Route::rule('filedown/:file_id','index/download'); |
|||
Route::rule('scan/:action/:token','index/scanQr'); |
|||
Route::rule('downapp','index/index/downapp'); |
|||
Route::rule('downloadApp/:platform','index/index/downloadApp'); |
|||
Loading…
Reference in new issue