diff --git a/app/Http/Controllers/Api/FileController.php b/app/Http/Controllers/Api/FileController.php index 3caa085e..a1545dae 100755 --- a/app/Http/Controllers/Api/FileController.php +++ b/app/Http/Controllers/Api/FileController.php @@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api; use App\Models\File; use App\Models\FileContent; +use App\Models\FileUser; use App\Models\User; use App\Module\Base; use Arr; @@ -21,7 +22,6 @@ class FileController extends AbstractController * 获取文件列表 * * @apiParam {Number} [pid] 父级ID - * @apiParam {String} [key] 关键词 */ public function lists() { @@ -29,28 +29,66 @@ class FileController extends AbstractController // $data = Request::all(); $pid = intval($data['pid']); - $key = trim($data['key']); // - $builder = File::whereUserid($user->userid); - if (Arr::exists($data, 'pid')) { - $builder->wherePid($pid); + if ($pid > 0) { + $file = File::find($pid); + if (empty($file)) { + return Base::retError('Not exist'); + } + $file->chackAllow($user->userid); + // + $builder = File::wherePid($pid); + } else { + $builder = File::whereUserid($user->userid); } - if (Arr::exists($data, 'key')) { - $builder->where('name', 'like', '%' . $key . '%'); - } - $list = $builder->take(500)->get(); - $array = $list->toArray(); + $array = $builder->take(500)->get()->toArray(); // - while ($pid > 0) { - $file = File::whereUserid($user->userid)->whereId($pid)->first(); - if ($file) { + if ($pid > 0) { + // 遍历获取父级 + while ($pid > 0) { + $file = File::whereId($pid)->first(); + if (empty($file)) { + break; + } $array[] = $file->toArray(); $pid = $file->pid; } + } else { + // 获取共享相关 + $list = File::where('userid', '!=', $user->userid)->where(function ($query) use ($user) { + $query->where('share', 1)->orWhere(function ($q2) use ($user) { + $q2->where('share', 2)->whereIn('id', function ($q3) use ($user) { + $q3->select('file_id')->from('file_users')->where('userid', $user->userid); + }); + }); + })->get(); + if ($list->isNotEmpty()) { + $array = array_merge($array, $list->toArray()); + } } return Base::retSuccess('success', $array); } + /** + * 搜索文件列表 + * + * @apiParam {String} [key] 关键词 + */ + public function search() + { + $user = User::auth(); + // + $key = trim(Request::input('key')); + if (empty($key)) { + return Base::retError('请输入关键词'); + } + // + $builder = File::whereUserid($user->userid)->where('name', 'like', '%' . $key . '%'); + $list = $builder->take(50)->get(); + // + return Base::retSuccess('success', $list); + } + /** * 添加、修改文件(夹) * @@ -292,4 +330,99 @@ class FileController extends AbstractController $content->content = $content->formatContent($file->type, $content->content); return Base::retSuccess('保存成功', $content); } + + /** + * 获取共享信息 + * + * @apiParam {Number} id 文件ID + */ + public function share() + { + $user = User::auth(); + // + $id = intval(Request::input('id')); + // + $file = File::whereId($id)->first(); + if (empty($file)) { + return Base::retError('文件不存在或已被删除'); + } + // + if ($file->userid != $user->userid) { + return Base::retError('仅限所有者操作'); + } + // + $userids = FileUser::whereFileId($file->id)->pluck('userid')->toArray(); + // + return Base::retSuccess('success', [ + 'id' => $file->id, + 'userids' => $userids + ]); + } + + /** + * 获取共享信息 + * + * @apiParam {Number} id 文件ID + * @apiParam {String} action 动作 + * - share: 设置共享 + * - unshare: 取消共享 + * @apiParam {Number} [share] 共享方式 + * - 1: 共享给所有人 + * - 2: 共享给指定成员 + * @apiParam {Array} [userids] 共享成员,格式: [userid1, userid2, userid3] + */ + public function share__update() + { + $user = User::auth(); + // + $id = intval(Request::input('id')); + $action = Request::input('action'); + $share = intval(Request::input('share')); + $userids = Request::input('userids'); + // + $file = File::whereId($id)->first(); + if (empty($file)) { + return Base::retError('文件不存在或已被删除'); + } + // + if ($file->userid != $user->userid) { + return Base::retError('仅限所有者操作'); + } + // + if ($file->isNnShare()) { + return Base::retError('已经处于共享目录中'); + } + // + if ($action == 'unshare') { + // 取消共享 + $file->setShare(0); + return Base::retSuccess('取消成功', $file); + } else { + // 设置共享 + if (!in_array($share, [1, 2])) { + return Base::retError('请选择共享类型'); + } + $file->setShare($share); + if ($share == 2) { + $array = []; + if (is_array($userids)) { + foreach ($userids as $userid) { + if (!intval($userid)) continue; + if (!User::whereUserid($userid)->exists()) continue; + FileUser::updateInsert([ + 'file_id' => $file->id, + 'userid' => $userid, + ]); + $array[] = $userid; + } + } + if (empty($array)) { + FileUser::whereFileId($file->id)->delete(); + } else { + FileUser::whereFileId($file->id)->whereNotIn('userid', $array)->delete(); + } + } + return Base::retSuccess('设置成功', $file); + } + } } diff --git a/app/Models/File.php b/app/Models/File.php index f9485f72..ce8257e6 100644 --- a/app/Models/File.php +++ b/app/Models/File.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Exceptions\ApiException; use Illuminate\Database\Eloquent\SoftDeletes; /** @@ -15,6 +16,8 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @property string|null $type 类型 * @property int|null $size 大小(B) * @property int|null $userid 拥有者ID + * @property int|null $share 是否共享(1:共享所有人,2:指定成员) + * @property int|null $created_id 创建者ID * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property \Illuminate\Support\Carbon|null $deleted_at @@ -24,10 +27,12 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @method static \Illuminate\Database\Eloquent\Builder|File query() * @method static \Illuminate\Database\Eloquent\Builder|File whereCid($value) * @method static \Illuminate\Database\Eloquent\Builder|File whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|File whereCreatedId($value) * @method static \Illuminate\Database\Eloquent\Builder|File whereDeletedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|File whereId($value) * @method static \Illuminate\Database\Eloquent\Builder|File whereName($value) * @method static \Illuminate\Database\Eloquent\Builder|File wherePid($value) + * @method static \Illuminate\Database\Eloquent\Builder|File whereShare($value) * @method static \Illuminate\Database\Eloquent\Builder|File whereSize($value) * @method static \Illuminate\Database\Eloquent\Builder|File whereType($value) * @method static \Illuminate\Database\Eloquent\Builder|File whereUpdatedAt($value) @@ -40,6 +45,97 @@ class File extends AbstractModel { use SoftDeletes; + /** + * 是否有访问权限 + * ① 自己的目录 + * ② 共享所有人的目录 + * ③ 在指定共享人员内 + * @param $userid + */ + public function chackAllow($userid) + { + if ($userid == $this->userid) { + // ① 自己的目录 + return; + } + $row = $this->getShareInfo(); + if ($row) { + if ($row->share == 1) { + // ② 共享所有人的目录 + return; + } elseif ($row->share == 2) { + // ③ 在指定共享人员内 + if (FileUser::whereFileId($row->id)->whereUserid($userid)->exists()) { + return; + } + } + } + throw new ApiException('没有访问权限'); + } + + /** + * 获取共享数据(含自身) + * @return $this|null + */ + public function getShareInfo() + { + if ($this->share > 0) { + return $this; + } + $pid = $this->pid; + while ($pid > 0) { + $row = self::whereId($pid)->first(); + if (empty($row)) { + break; + } + if ($row->share > 0) { + return $row; + } + $pid = $row->pid; + } + return null; + } + + /** + * 是否处于共享目录内(不含自身) + * @return bool + */ + public function isNnShare() + { + $pid = $this->pid; + while ($pid > 0) { + $row = self::whereId($pid)->first(); + if (empty($row)) { + break; + } + if ($row->share > 0) { + return true; + } + $pid = $row->pid; + } + return false; + } + + /** + * 设置/关闭 共享(同时遍历取消里面的共享) + * @param $share + * @return bool + */ + public function setShare($share) + { + AbstractModel::transaction(function () use ($share) { + $this->share = $share; + $this->save(); + $list = self::wherePid($this->id)->get(); + if ($list->isNotEmpty()) { + foreach ($list as $item) { + $item->setShare(0); + } + } + }); + return true; + } + /** * 遍历删除文件(夹) * @return bool diff --git a/app/Models/FileUser.php b/app/Models/FileUser.php new file mode 100644 index 00000000..22ecf12f --- /dev/null +++ b/app/Models/FileUser.php @@ -0,0 +1,27 @@ +string('type', 20)->nullable()->default('')->comment('类型'); $table->bigInteger('size')->nullable()->default(0)->comment('大小(B)'); $table->bigInteger('userid')->nullable()->default(0)->comment('拥有者ID'); + $table->tinyInteger('share')->nullable()->default(0)->comment('是否共享'); + $table->bigInteger('created_id')->nullable()->default(0)->comment('创建者'); $table->timestamps(); $table->softDeletes(); }); diff --git a/database/migrations/2021_07_07_085317_create_file_users_table.php b/database/migrations/2021_07_07_085317_create_file_users_table.php new file mode 100644 index 00000000..921b653e --- /dev/null +++ b/database/migrations/2021_07_07_085317_create_file_users_table.php @@ -0,0 +1,33 @@ +bigIncrements('id'); + $table->bigInteger('file_id')->nullable()->default(0)->comment('项目ID'); + $table->bigInteger('userid')->nullable()->default(0)->comment('成员ID'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('file_users'); + } +} diff --git a/database/seeders/FilesTableSeeder.php b/database/seeders/FilesTableSeeder.php index 32e3e10f..5e79dd15 100644 --- a/database/seeders/FilesTableSeeder.php +++ b/database/seeders/FilesTableSeeder.php @@ -30,6 +30,8 @@ class FilesTableSeeder extends Seeder 'type' => 'folder', 'size' => 0, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 14:03:29'), 'updated_at' => seeders_at('2021-07-01 14:03:29'), 'deleted_at' => NULL, @@ -43,6 +45,8 @@ class FilesTableSeeder extends Seeder 'type' => 'document', 'size' => 16976, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 14:03:37'), 'updated_at' => seeders_at('2021-07-01 14:17:28'), 'deleted_at' => NULL, @@ -56,6 +60,8 @@ class FilesTableSeeder extends Seeder 'type' => 'document', 'size' => 11971, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 15:46:59'), 'updated_at' => seeders_at('2021-07-01 15:49:14'), 'deleted_at' => NULL, @@ -69,6 +75,8 @@ class FilesTableSeeder extends Seeder 'type' => 'folder', 'size' => 0, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 15:49:43'), 'updated_at' => seeders_at('2021-07-01 15:49:43'), 'deleted_at' => NULL, @@ -82,6 +90,8 @@ class FilesTableSeeder extends Seeder 'type' => 'document', 'size' => 285, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 15:49:50'), 'updated_at' => seeders_at('2021-07-01 15:53:09'), 'deleted_at' => NULL, @@ -95,6 +105,8 @@ class FilesTableSeeder extends Seeder 'type' => 'mind', 'size' => 1947, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 15:53:50'), 'updated_at' => seeders_at('2021-07-01 16:11:39'), 'deleted_at' => NULL, @@ -108,6 +120,8 @@ class FilesTableSeeder extends Seeder 'type' => 'sheet', 'size' => 0, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 15:54:58'), 'updated_at' => seeders_at('2021-07-01 15:54:58'), 'deleted_at' => NULL, @@ -121,6 +135,8 @@ class FilesTableSeeder extends Seeder 'type' => 'document', 'size' => 8088, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 15:56:09'), 'updated_at' => seeders_at('2021-07-01 16:11:13'), 'deleted_at' => NULL, @@ -134,6 +150,8 @@ class FilesTableSeeder extends Seeder 'type' => 'document', 'size' => 23266, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 15:57:39'), 'updated_at' => seeders_at('2021-07-01 15:57:56'), 'deleted_at' => NULL, @@ -147,6 +165,8 @@ class FilesTableSeeder extends Seeder 'type' => 'sheet', 'size' => 1883759, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 15:58:30'), 'updated_at' => seeders_at('2021-07-01 16:10:17'), 'deleted_at' => NULL, @@ -160,6 +180,8 @@ class FilesTableSeeder extends Seeder 'type' => 'sheet', 'size' => 1771363, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 15:59:59'), 'updated_at' => seeders_at('2021-07-01 16:00:28'), 'deleted_at' => NULL, @@ -173,6 +195,8 @@ class FilesTableSeeder extends Seeder 'type' => 'flow', 'size' => 5418, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 16:01:27'), 'updated_at' => seeders_at('2021-07-01 16:03:06'), 'deleted_at' => NULL, @@ -186,6 +210,8 @@ class FilesTableSeeder extends Seeder 'type' => 'folder', 'size' => 0, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 16:10:08'), 'updated_at' => seeders_at('2021-07-01 16:10:08'), 'deleted_at' => NULL, @@ -199,6 +225,8 @@ class FilesTableSeeder extends Seeder 'type' => 'folder', 'size' => 0, 'userid' => 1, + 'share' => 0, + 'created_id' => 1, 'created_at' => seeders_at('2021-07-01 16:11:08'), 'updated_at' => seeders_at('2021-07-01 16:11:08'), 'deleted_at' => NULL, diff --git a/resources/assets/js/pages/manage/file.vue b/resources/assets/js/pages/manage/file.vue index c103a422..d347a840 100644 --- a/resources/assets/js/pages/manage/file.vue +++ b/resources/assets/js/pages/manage/file.vue @@ -27,7 +27,10 @@