diff --git a/app/Http/Controllers/Api/DialogController.php b/app/Http/Controllers/Api/DialogController.php index f96ac2e38..51fef5486 100755 --- a/app/Http/Controllers/Api/DialogController.php +++ b/app/Http/Controllers/Api/DialogController.php @@ -53,24 +53,7 @@ class DialogController extends AbstractController // $timerange = TimeRange::parse(Request::input()); // - $builder = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.updated_at as user_at']) - ->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id') - ->where('u.userid', $user->userid); - if ($timerange->updated) { - $builder->where('u.updated_at', '>', $timerange->updated); - } - $list = $builder - ->orderByDesc('u.top_at') - ->orderByDesc('web_socket_dialogs.last_at') - ->paginate(Base::getPaginate(100, 50)); - $list->transform(function (WebSocketDialog $item) use ($user) { - return $item->formatData($user->userid); - }); - // - $data = $list->toArray(); - if ($list->currentPage() === 1) { - $data['deleted_id'] = Deleted::ids('dialog', $user->userid, $timerange->deleted); - } + $data = (new WebSocketDialog)->getDialogList($user->userid,$timerange->updated,$timerange->deleted); // return Base::retSuccess('success', $data); } diff --git a/app/Http/Controllers/Api/FileController.php b/app/Http/Controllers/Api/FileController.php index 4f778cbff..052df1432 100755 --- a/app/Http/Controllers/Api/FileController.php +++ b/app/Http/Controllers/Api/FileController.php @@ -44,72 +44,7 @@ class FileController extends AbstractController $data = Request::all(); $pid = intval($data['pid']); // - $permission = 1000; - $userids = $user->isTemp() ? [$user->userid] : [0, $user->userid]; - $builder = File::wherePid($pid); - if ($pid > 0) { - File::permissionFind($pid, $userids, 0, $permission); - } else { - $builder->whereUserid($user->userid); - } - // - $array = $builder->take(500)->get()->toArray(); - foreach ($array as &$item) { - $item['permission'] = $permission; - } - // - if ($pid > 0) { - // 遍历获取父级 - while ($pid > 0) { - $file = File::whereId($pid)->first(); - if (empty($file)) { - break; - } - $pid = $file->pid; - $temp = $file->toArray(); - $temp['permission'] = $file->getPermission($userids); - $array[] = $temp; - } - // 去除没有权限的文件 - $isUnset = false; - foreach ($array as $index1 => $item1) { - if ($item1['permission'] === -1) { - foreach ($array as $index2 => $item2) { - if ($item2['pid'] === $item1['id']) { - $array[$index2]['pid'] = 0; - } - } - $isUnset = true; - unset($array[$index1]); - } - } - if ($isUnset) { - $array = array_values($array); - } - } else { - // 获取共享相关 - DB::statement("SET SQL_MODE=''"); - $pre = DB::connection()->getTablePrefix(); - $list = File::select(["files.*", DB::raw("MAX({$pre}file_users.permission) as permission")]) - ->join('file_users', 'files.id', '=', 'file_users.file_id') - ->where('files.userid', '!=', $user->userid) - ->whereIn('file_users.userid', $userids) - ->groupBy('files.id') - ->take(100) - ->get(); - if ($list->isNotEmpty()) { - foreach ($list as $file) { - $temp = $file->toArray(); - $temp['pid'] = 0; - $array[] = $temp; - } - } - } - // 图片直接返回预览地址 - foreach ($array as &$item) { - $item = File::handleImageUrl($item); - } - return Base::retSuccess('success', $array); + return Base::retSuccess('success', (new File)->getFileList($user,$pid) ); } /** @@ -743,140 +678,10 @@ class FileController extends AbstractController public function content__upload() { $user = User::auth(); - // $pid = intval(Request::input('pid')); $webkitRelativePath = Request::input('webkitRelativePath'); - // - $userid = $user->userid; - if ($pid > 0) { - if (File::wherePid($pid)->count() >= 300) { - return Base::retError('每个文件夹里最多只能创建300个文件或文件夹'); - } - $row = File::permissionFind($pid, $user, 1); - $userid = $row->userid; - } else { - if (File::whereUserid($user->userid)->wherePid(0)->count() >= 300) { - return Base::retError('每个文件夹里最多只能创建300个文件或文件夹'); - } - } - // - $dirs = explode("/", $webkitRelativePath); - $addItem = []; - while (count($dirs) > 1) { - $dirName = array_shift($dirs); - if ($dirName) { - AbstractModel::transaction(function () use ($dirName, $user, $userid, &$pid, &$addItem) { - $dirRow = File::wherePid($pid)->whereType('folder')->whereName($dirName)->lockForUpdate()->first(); - if (empty($dirRow)) { - $dirRow = File::createInstance([ - 'pid' => $pid, - 'type' => 'folder', - 'name' => $dirName, - 'userid' => $userid, - 'created_id' => $user->userid, - ]); - $dirRow->handleDuplicateName(); - if ($dirRow->saveBeforePP()) { - $addItem[] = File::find($dirRow->id); - } - } - if (empty($dirRow)) { - throw new ApiException('创建文件夹失败'); - } - $pid = $dirRow->id; - }); - foreach ($addItem as $tmpRow) { - $tmpRow->pushMsg('add', $tmpRow); - } - } - } - // - $path = 'uploads/tmp/' . date("Ym") . '/'; - $data = Base::upload([ - "file" => Request::file('files'), - "type" => 'more', - "autoThumb" => false, - "path" => $path, - ]); - if (Base::isError($data)) { - return $data; - } - $data = $data['data']; - // - $type = match ($data['ext']) { - 'text', 'md', 'markdown' => 'document', - 'drawio' => 'drawio', - 'mind' => 'mind', - 'doc', 'docx' => "word", - 'xls', 'xlsx' => "excel", - 'ppt', 'pptx' => "ppt", - 'wps' => "wps", - 'jpg', 'jpeg', 'webp', 'png', 'gif', 'bmp', 'ico', 'raw', 'svg' => "picture", - 'rar', 'zip', 'jar', '7-zip', 'tar', 'gzip', '7z', 'gz', 'apk', 'dmg' => "archive", - 'tif', 'tiff' => "tif", - 'dwg', 'dxf' => "cad", - 'ofd' => "ofd", - 'pdf' => "pdf", - 'txt' => "txt", - 'htaccess', 'htgroups', 'htpasswd', 'conf', 'bat', 'cmd', 'cpp', 'c', 'cc', 'cxx', 'h', 'hh', 'hpp', 'ino', 'cs', 'css', - 'dockerfile', 'go', 'golang', 'html', 'htm', 'xhtml', 'vue', 'we', 'wpy', 'java', 'js', 'jsm', 'jsx', 'json', 'jsp', 'less', 'lua', 'makefile', 'gnumakefile', - 'ocamlmakefile', 'make', 'mysql', 'nginx', 'ini', 'cfg', 'prefs', 'm', 'mm', 'pl', 'pm', 'p6', 'pl6', 'pm6', 'pgsql', 'php', - 'inc', 'phtml', 'shtml', 'php3', 'php4', 'php5', 'phps', 'phpt', 'aw', 'ctp', 'module', 'ps1', 'py', 'r', 'rb', 'ru', 'gemspec', 'rake', 'guardfile', 'rakefile', - 'gemfile', 'rs', 'sass', 'scss', 'sh', 'bash', 'bashrc', 'sql', 'sqlserver', 'swift', 'ts', 'typescript', 'str', 'vbs', 'vb', 'v', 'vh', 'sv', 'svh', 'xml', - 'rdf', 'rss', 'wsdl', 'xslt', 'atom', 'mathml', 'mml', 'xul', 'xbl', 'xaml', 'yaml', 'yml', - 'asp', 'properties', 'gitignore', 'log', 'bas', 'prg', 'python', 'ftl', 'aspx', 'plist' => "code", - 'mp3', 'wav', 'mp4', 'flv', - 'avi', 'mov', 'wmv', 'mkv', '3gp', 'rm' => "media", - 'xmind' => "xmind", - 'rp' => "axure", - default => "", - }; - if ($data['ext'] == 'markdown') { - $data['ext'] = 'md'; - } - $file = File::createInstance([ - 'pid' => $pid, - 'name' => Base::rightDelete($data['name'], '.' . $data['ext']), - 'type' => $type, - 'ext' => $data['ext'], - 'userid' => $userid, - 'created_id' => $user->userid, - ]); - $file->handleDuplicateName(); - // 开始创建 - return AbstractModel::transaction(function () use ($addItem, $webkitRelativePath, $type, $user, $data, $file) { - $file->size = $data['size'] * 1024; - $file->saveBeforePP(); - // - $data = Base::uploadMove($data, "uploads/file/" . $file->type . "/" . date("Ym") . "/" . $file->id . "/"); - $content = [ - 'from' => '', - 'type' => $type, - 'ext' => $data['ext'], - 'url' => $data['path'], - ]; - if (isset($data['width'])) { - $content['width'] = $data['width']; - $content['height'] = $data['height']; - } - $content = FileContent::createInstance([ - 'fid' => $file->id, - 'content' => $content, - 'text' => '', - 'size' => $file->size, - 'userid' => $user->userid, - ]); - $content->save(); - // - $tmpRow = File::find($file->id); - $tmpRow->pushMsg('add', $tmpRow); - // - $data = File::handleImageUrl($tmpRow->toArray()); - $data['full_name'] = $webkitRelativePath ?: $data['name']; - // - $addItem[] = $data; - return Base::retSuccess($data['name'] . ' 上传成功', $addItem); - }); + $data = (new File)->contentUpload($user,$pid,$webkitRelativePath); + return Base::retSuccess($data['data']['name'] . ' 上传成功', $data['addItem']); } /** diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index 761ccae01..15f3404a7 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -1816,58 +1816,65 @@ class UsersController extends AbstractController public function share__list() { $user = User::auth(); - $userids = $user->isTemp() ? [$user->userid] : [0, $user->userid]; - //目录列表 - $dir = Base::list2Tree( - File::select('files.id','files.pid','files.name') - ->leftJoin('file_users', 'files.id', '=', 'file_users.file_id') - ->where('files.type','folder') - ->where(function ($q) use ($userids) { - $q->whereIn('files.userid',$userids); - $q->orWhere(function ($qq) use ($userids) { - $qq->where('file_users.permission',1); - $qq->whereIn('file_users.userid',$userids); - }); - }) - ->get() - ->toArray() - ); - //聊天列表 - $chatList = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.silence', 'u.updated_at as user_at']) - ->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id') - ->where('u.userid', $user->userid) - ->orderByDesc('u.top_at') - ->orderByDesc('web_socket_dialogs.last_at') - ->get() - ->transform(function (WebSocketDialog $item) use ($user) { - $item = $item->formatData($user->userid); - $item->last_msg = []; - if(!$item->avatar){ - $item->avatar = 'avatar/'.$item->name.'.png'; + $pid = intval( Request::input('pid',-1) ); + $uploadFileId = intval(Request::input('upload_file_id',-1)); + // 上传文件 + if($uploadFileId !== -1){ + $webkitRelativePath = Request::input('webkitRelativePath'); + $data = (new File)->contentUpload($user,$pid,$webkitRelativePath); + return Base::retSuccess('success', $data); + } + // 获取数据 + if ($pid !== -1) { + $lists = []; + $fileList = (new File)->getFileList($user,$pid,'dir',false); + foreach($fileList as $file){ + if($file['id'] != $pid){ + $lists[] = [ + 'type' => count((new File)->getFileList($user,$file['id'],'dir',false)) > 0 ? 'children' : 'item', + 'url' => Base::fillUrl("api/users/share/list") . "?pid=" . $file['id'], + 'icon' => url("/images/file/light/folder.svg"), + 'extend' => ['upload_file_id'=>$file['id']], + 'name' => $file['name'], + ]; } - return $item; - }) - ->toArray(); - // 用户列表 - $notUserIds = [$user->userid]; - foreach($chatList as $chat){ - if($chat['type'] == 'user'){ - $notUserIds[] = $chat['dialog_user']['userid']; } - } - $userList = User::select('userid','email','nickname','userimg') - ->where('bot',0) - ->where('changepass',0) - ->whereNull('disable_at') - ->whereNotIn('userid',$notUserIds) - ->get() - ->transform(function (User $item) { - $item->name = $item->nickname; - $item->avatar = $item->userimg; - return $item; - }) - ->toArray(); + + }else{ + $lists = [[ + 'type' => 'children', + 'url' => Base::fillUrl("api/users/share/list")."?pid=0", + 'icon' => url("/images/file/light/folder.svg"), + 'extend' => ['file'=>true], + 'name' => '全部文件', + ]]; + $dialogList = (new WebSocketDialog)->getDialogList($user->userid); + foreach($dialogList['data'] as $dialog){ + if($dialog['type'] == 'user'){ + $avatar = User::getAvatar($dialog['dialog_user']['userid'], $dialog['avatar'], $dialog['email'], $dialog['name']); + }else{ + switch ( $dialog['group_type'] ) { + case 'department': + $avatar = url("images/avatar/default_department.png"); + case 'project': + $avatar = url("images/avatar/default_project.png"); + case 'task': + $avatar = url("images/avatar/default_task.png"); + default: + $avatar = url("images/avatar/default_people.png"); + break; + } + } + $lists[] = [ + 'type' => 'item', + 'name' => $dialog['name'], + 'icon' => $avatar, + 'url' => Base::fillUrl("api/dialog/msg/sendfiles"), + 'extend' => [ 'dialog_ids' => $dialog['id'] ] + ]; + } + } // 返回 - return Base::retSuccess('success', ["dir"=>$dir,"chatList"=>$chatList,"userList"=>$userList]); + return Base::retSuccess('success', $lists); } } diff --git a/app/Models/File.php b/app/Models/File.php index 621a7788c..0911b0524 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -2,12 +2,13 @@ namespace App\Models; -use App\Exceptions\ApiException; +use Request; use App\Module\Base; use App\Tasks\PushTask; +use App\Exceptions\ApiException; +use Illuminate\Support\Facades\DB; use Hhxsv5\LaravelS\Swoole\Task\Task; use Illuminate\Database\Eloquent\SoftDeletes; -use Request; /** * App\Models\File @@ -94,6 +95,233 @@ class File extends AbstractModel 'avi', 'mov', 'wmv', 'mkv', '3gp', 'rm', ]; + + /** + * 获取文件列表 + * @param user $user + * @param int $pid + * @return array + */ + public function getFileList($user, int $pid, $type = "all", $isGetparent = true) + { + $permission = 1000; + $userids = $user->isTemp() ? [$user->userid] : [0, $user->userid]; + $builder = File::wherePid($pid) + ->when($type== 'dir',function($q){ + $q->whereType('folder'); + }); + if ($pid > 0) { + File::permissionFind($pid, $userids, 0, $permission); + } else { + $builder->whereUserid($user->userid); + } + // + $array = $builder->take(500)->get()->toArray(); + foreach ($array as &$item) { + $item['permission'] = $permission; + } + // + if ($pid > 0) { + // 遍历获取父级 + if($isGetparent){ + while ($pid > 0) { + $file = File::whereId($pid)->first(); + if (empty($file)) { + break; + } + $pid = $file->pid; + $temp = $file->toArray(); + $temp['permission'] = $file->getPermission($userids); + $array[] = $temp; + } + } + // 去除没有权限的文件 + $isUnset = false; + foreach ($array as $index1 => $item1) { + if ($item1['permission'] === -1) { + foreach ($array as $index2 => $item2) { + if ($item2['pid'] === $item1['id']) { + $array[$index2]['pid'] = 0; + } + } + $isUnset = true; + unset($array[$index1]); + } + } + if ($isUnset) { + $array = array_values($array); + } + } else { + // 获取共享相关 + DB::statement("SET SQL_MODE=''"); + $pre = DB::connection()->getTablePrefix(); + $list = File::select(["files.*", DB::raw("MAX({$pre}file_users.permission) as permission")]) + ->join('file_users', 'files.id', '=', 'file_users.file_id') + ->where('files.userid', '!=', $user->userid) + ->whereIn('file_users.userid', $userids) + ->groupBy('files.id') + ->take(100) + ->when($type== 'dir',function($q){ + $q->where('files.type','folder'); + }) + ->get(); + if ($list->isNotEmpty()) { + foreach ($list as $file) { + $temp = $file->toArray(); + $temp['pid'] = 0; + $array[] = $temp; + } + } + } + // 图片直接返回预览地址 + foreach ($array as &$item) { + $item = File::handleImageUrl($item); + } + return $array; + } + + /** + * 保存文件内容(上传文件) + * @param user $user + * @param int $pid + * @param string $webkitRelativePath + * @return array + */ + public function contentUpload($user, int $pid, $webkitRelativePath) + { + $userid = $user->userid; + if ($pid > 0) { + if (File::wherePid($pid)->count() >= 300) { + return Base::retError('每个文件夹里最多只能创建300个文件或文件夹'); + } + $row = File::permissionFind($pid, $user, 1); + $userid = $row->userid; + } else { + if (File::whereUserid($user->userid)->wherePid(0)->count() >= 300) { + return Base::retError('每个文件夹里最多只能创建300个文件或文件夹'); + } + } + // + $dirs = explode("/", $webkitRelativePath); + $addItem = []; + while (count($dirs) > 1) { + $dirName = array_shift($dirs); + if ($dirName) { + AbstractModel::transaction(function () use ($dirName, $user, $userid, &$pid, &$addItem) { + $dirRow = File::wherePid($pid)->whereType('folder')->whereName($dirName)->lockForUpdate()->first(); + if (empty($dirRow)) { + $dirRow = File::createInstance([ + 'pid' => $pid, + 'type' => 'folder', + 'name' => $dirName, + 'userid' => $userid, + 'created_id' => $user->userid, + ]); + $dirRow->handleDuplicateName(); + if ($dirRow->saveBeforePP()) { + $addItem[] = File::find($dirRow->id); + } + } + if (empty($dirRow)) { + throw new ApiException('创建文件夹失败'); + } + $pid = $dirRow->id; + }); + foreach ($addItem as $tmpRow) { + $tmpRow->pushMsg('add', $tmpRow); + } + } + } + // + $path = 'uploads/tmp/' . date("Ym") . '/'; + $data = Base::upload([ + "file" => Request::file('files'), + "type" => 'more', + "autoThumb" => false, + "path" => $path, + ]); + if (Base::isError($data)) { + return $data; + } + $data = $data['data']; + // + $type = match ($data['ext']) { + 'text', 'md', 'markdown' => 'document', + 'drawio' => 'drawio', + 'mind' => 'mind', + 'doc', 'docx' => "word", + 'xls', 'xlsx' => "excel", + 'ppt', 'pptx' => "ppt", + 'wps' => "wps", + 'jpg', 'jpeg', 'webp', 'png', 'gif', 'bmp', 'ico', 'raw', 'svg' => "picture", + 'rar', 'zip', 'jar', '7-zip', 'tar', 'gzip', '7z', 'gz', 'apk', 'dmg' => "archive", + 'tif', 'tiff' => "tif", + 'dwg', 'dxf' => "cad", + 'ofd' => "ofd", + 'pdf' => "pdf", + 'txt' => "txt", + 'htaccess', 'htgroups', 'htpasswd', 'conf', 'bat', 'cmd', 'cpp', 'c', 'cc', 'cxx', 'h', 'hh', 'hpp', 'ino', 'cs', 'css', + 'dockerfile', 'go', 'golang', 'html', 'htm', 'xhtml', 'vue', 'we', 'wpy', 'java', 'js', 'jsm', 'jsx', 'json', 'jsp', 'less', 'lua', 'makefile', 'gnumakefile', + 'ocamlmakefile', 'make', 'mysql', 'nginx', 'ini', 'cfg', 'prefs', 'm', 'mm', 'pl', 'pm', 'p6', 'pl6', 'pm6', 'pgsql', 'php', + 'inc', 'phtml', 'shtml', 'php3', 'php4', 'php5', 'phps', 'phpt', 'aw', 'ctp', 'module', 'ps1', 'py', 'r', 'rb', 'ru', 'gemspec', 'rake', 'guardfile', 'rakefile', + 'gemfile', 'rs', 'sass', 'scss', 'sh', 'bash', 'bashrc', 'sql', 'sqlserver', 'swift', 'ts', 'typescript', 'str', 'vbs', 'vb', 'v', 'vh', 'sv', 'svh', 'xml', + 'rdf', 'rss', 'wsdl', 'xslt', 'atom', 'mathml', 'mml', 'xul', 'xbl', 'xaml', 'yaml', 'yml', + 'asp', 'properties', 'gitignore', 'log', 'bas', 'prg', 'python', 'ftl', 'aspx', 'plist' => "code", + 'mp3', 'wav', 'mp4', 'flv', + 'avi', 'mov', 'wmv', 'mkv', '3gp', 'rm' => "media", + 'xmind' => "xmind", + 'rp' => "axure", + default => "", + }; + if ($data['ext'] == 'markdown') { + $data['ext'] = 'md'; + } + $file = File::createInstance([ + 'pid' => $pid, + 'name' => Base::rightDelete($data['name'], '.' . $data['ext']), + 'type' => $type, + 'ext' => $data['ext'], + 'userid' => $userid, + 'created_id' => $user->userid, + ]); + $file->handleDuplicateName(); + // 开始创建 + return AbstractModel::transaction(function () use ($addItem, $webkitRelativePath, $type, $user, $data, $file) { + $file->size = $data['size'] * 1024; + $file->saveBeforePP(); + // + $data = Base::uploadMove($data, "uploads/file/" . $file->type . "/" . date("Ym") . "/" . $file->id . "/"); + $content = [ + 'from' => '', + 'type' => $type, + 'ext' => $data['ext'], + 'url' => $data['path'], + ]; + if (isset($data['width'])) { + $content['width'] = $data['width']; + $content['height'] = $data['height']; + } + $content = FileContent::createInstance([ + 'fid' => $file->id, + 'content' => $content, + 'text' => '', + 'size' => $file->size, + 'userid' => $user->userid, + ]); + $content->save(); + // + $tmpRow = File::find($file->id); + $tmpRow->pushMsg('add', $tmpRow); + // + $data = File::handleImageUrl($tmpRow->toArray()); + $data['full_name'] = $webkitRelativePath ?: $data['name']; + // + $addItem[] = $data; + + return ['data'=>$data,'addItem'=>$addItem]; + }); + } + /** * 是否有访问权限 * @param array $userids diff --git a/app/Models/WebSocketDialog.php b/app/Models/WebSocketDialog.php index ffc5f4486..a75a5f3a1 100644 --- a/app/Models/WebSocketDialog.php +++ b/app/Models/WebSocketDialog.php @@ -66,6 +66,38 @@ class WebSocketDialog extends AbstractModel return $this->hasMany(WebSocketDialogUser::class, 'dialog_id', 'id'); } + + /** + * 格式化对话 + * @param int $userid 会员ID + * @param bool $hasData + * @return $this + */ + public function getDialogList($userid, $updated="", $deleted="") + { + $builder = WebSocketDialog::select(['web_socket_dialogs.*', 'u.top_at', 'u.mark_unread', 'u.silence', 'u.updated_at as user_at']) + ->join('web_socket_dialog_users as u', 'web_socket_dialogs.id', '=', 'u.dialog_id') + ->where('u.userid', $userid); + if ($updated) { + $builder->where('u.updated_at', '>', $updated); + } + $list = $builder + ->orderByDesc('u.top_at') + ->orderByDesc('web_socket_dialogs.last_at') + ->paginate(Base::getPaginate(100, 50)); + $list->transform(function (WebSocketDialog $item) use ($userid) { + return $item->formatData($userid); + }); + // + $data = $list->toArray(); + if ($list->currentPage() === 1) { + $data['deleted_id'] = Deleted::ids('dialog', $userid, $deleted); + } + return $data; + } + + + /** * 格式化对话 * @param int $userid 会员ID @@ -118,7 +150,9 @@ class WebSocketDialog extends AbstractModel } $basic = User::userid2basic($dialog_user->userid); if ($basic) { + $this->avatar = $basic->userimg; $this->name = $basic->nickname; + $this->email = $basic->email; $this->bot = $basic->getBotOwner(); $this->quick_msgs = UserBot::quickMsgs($basic->email); } else {