fix: 修改分享逻辑

This commit is contained in:
weifashi 2023-06-09 15:05:09 +08:00
parent 95d3c7dfce
commit 8c6f1120e4
5 changed files with 325 additions and 268 deletions

View File

@ -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);
}

View File

@ -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']);
}
/**

View File

@ -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);
}
}

View File

@ -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

View File

@ -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 {