feat: 文件支持只读、读/写细化设置
This commit is contained in:
parent
cef6646f50
commit
2b0467e00f
@ -35,12 +35,7 @@ class FileController extends AbstractController
|
||||
$pid = intval($data['pid']);
|
||||
//
|
||||
if ($pid > 0) {
|
||||
$file = File::find($pid);
|
||||
if (empty($file)) {
|
||||
return Base::retError('Not exist');
|
||||
}
|
||||
$file->exceAllow($user->userid);
|
||||
//
|
||||
File::allowFind($pid);
|
||||
$builder = File::wherePid($pid);
|
||||
} else {
|
||||
$builder = File::whereUserid($user->userid);
|
||||
@ -61,13 +56,11 @@ class FileController extends AbstractController
|
||||
}
|
||||
} 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();
|
||||
$list = File::select(['files.*', 'file_users.permission'])
|
||||
->join('file_users', 'files.id', '=', 'file_users.file_id')
|
||||
->where('files.userid', '!=', $user->userid)
|
||||
->where('file_users.userid', $user->userid)
|
||||
->get();
|
||||
if ($list->isNotEmpty()) {
|
||||
foreach ($list as $file) {
|
||||
$temp = $file->toArray();
|
||||
@ -512,34 +505,35 @@ class FileController extends AbstractController
|
||||
return Base::retError('仅限所有者操作');
|
||||
}
|
||||
//
|
||||
$userids = FileUser::whereFileId($file->id)->pluck('userid')->toArray();
|
||||
$list = FileUser::whereFileId($file->id)->get();
|
||||
//
|
||||
return Base::retSuccess('success', [
|
||||
'id' => $file->id,
|
||||
'userids' => $userids
|
||||
'list' => $list
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取共享信息
|
||||
* 设置共享
|
||||
*
|
||||
* @apiParam {Number} id 文件ID
|
||||
* @apiParam {String} action 动作
|
||||
* - share: 设置共享
|
||||
* - unshare: 取消共享
|
||||
* @apiParam {Number} [share] 共享对象
|
||||
* - 1: 共享给所有人(限管理员)
|
||||
* - 2: 共享给指定成员
|
||||
* @apiParam {Array} [userids] 共享成员,格式: [userid1, userid2, userid3]
|
||||
* @apiParam {Number} [permission] 共享方式
|
||||
* - 0:只读
|
||||
* - 1:读写
|
||||
* - -1: 删除
|
||||
*/
|
||||
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');
|
||||
$permission = intval(Request::input('permission'));
|
||||
//
|
||||
if (!in_array($permission, [-1, 0, 1])) {
|
||||
return Base::retError('参数错误');
|
||||
}
|
||||
//
|
||||
$file = File::whereId($id)->first();
|
||||
if (empty($file)) {
|
||||
@ -553,56 +547,45 @@ class FileController extends AbstractController
|
||||
return Base::retError('已经处于共享文件夹中');
|
||||
}
|
||||
//
|
||||
if ($action == 'unshare') {
|
||||
// 取消共享
|
||||
if ($file->share == 1) {
|
||||
$uids = WebSocket::select(['userid'])->pluck('userid')->toArray();
|
||||
} else {
|
||||
$uids = FileUser::whereFileId($file->id)->pluck('userid')->toArray();
|
||||
}
|
||||
$uids = array_values(array_diff($uids, [$user->userid]));
|
||||
//
|
||||
$file->setShare(0);
|
||||
$message = '取消成功';
|
||||
} else {
|
||||
// 设置共享
|
||||
switch ($share) {
|
||||
case 1:
|
||||
$user->isAdmin();
|
||||
break;
|
||||
|
||||
case 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)) {
|
||||
return Base::retError('请选择共享成员');
|
||||
}
|
||||
$builder = FileUser::whereFileId($file->id)->whereNotIn('userid', $array);
|
||||
$uids = (clone $builder)->pluck('userid')->toArray();
|
||||
$builder->delete();
|
||||
break;
|
||||
|
||||
default:
|
||||
return Base::retError('请选择共享对象');
|
||||
}
|
||||
$file->setShare($share);
|
||||
$message = '设置成功';
|
||||
if (!is_array($userids) || empty($userids)) {
|
||||
return Base::retError('请选择共享对象');
|
||||
}
|
||||
//
|
||||
$file->pushMsg('update', $file);
|
||||
if (isset($uids)) {
|
||||
$file->pushMsg('delete', null, $uids);
|
||||
$array = [];
|
||||
if ($permission === -1) {
|
||||
// 取消共享
|
||||
$action = "delete";
|
||||
foreach ($userids as $userid) {
|
||||
if (!intval($userid)) continue;
|
||||
if (FileUser::where([
|
||||
'file_id' => $file->id,
|
||||
'userid' => $userid,
|
||||
])->delete()) {
|
||||
$array[] = $userid;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// 设置共享
|
||||
$action = "update";
|
||||
if (FileUser::whereFileId($file->id)->count() + count($userids) > 100) {
|
||||
return Base::retError('共享人数上限100个成员');
|
||||
}
|
||||
foreach ($userids as $userid) {
|
||||
if (!intval($userid)) continue;
|
||||
if (!User::whereUserid($userid)->exists()) continue;
|
||||
if (FileUser::updateInsert([
|
||||
'file_id' => $file->id,
|
||||
'userid' => $userid,
|
||||
], [
|
||||
'permission' => $permission,
|
||||
])) {
|
||||
$array[] = $userid;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Base::retSuccess($message, $file);
|
||||
//
|
||||
$file->setShare();
|
||||
$file->pushMsg($action, $action == "delete" ? null : $file, $array);
|
||||
return Base::retSuccess($action == "delete" ? "删除成功" : "设置成功", $file);
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ class File extends AbstractModel
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
* 是否有访问权限(没有时抛出异常)
|
||||
* 是否有访问权限
|
||||
* @param $userid
|
||||
*/
|
||||
public function exceAllow($userid)
|
||||
@ -64,8 +64,7 @@ class File extends AbstractModel
|
||||
/**
|
||||
* 是否有访问权限
|
||||
* ① 自己的文件夹
|
||||
* ② 共享所有人的文件夹
|
||||
* ③ 在指定共享人员内
|
||||
* ② 在指定共享成员内
|
||||
* @param $userid
|
||||
* @return bool
|
||||
*/
|
||||
@ -77,14 +76,9 @@ class File extends AbstractModel
|
||||
}
|
||||
$row = $this->getShareInfo();
|
||||
if ($row) {
|
||||
if ($row->share == 1) {
|
||||
// ② 共享所有人的文件夹
|
||||
if (FileUser::whereFileId($row->id)->whereUserid($userid)->exists()) {
|
||||
// ② 在指定共享成员内
|
||||
return true;
|
||||
} elseif ($row->share == 2) {
|
||||
// ③ 在指定共享人员内
|
||||
if (FileUser::whereFileId($row->id)->whereUserid($userid)->exists()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -96,7 +90,7 @@ class File extends AbstractModel
|
||||
*/
|
||||
public function getShareInfo()
|
||||
{
|
||||
if ($this->share > 0) {
|
||||
if ($this->share) {
|
||||
return $this;
|
||||
}
|
||||
$pid = $this->pid;
|
||||
@ -105,7 +99,7 @@ class File extends AbstractModel
|
||||
if (empty($row)) {
|
||||
break;
|
||||
}
|
||||
if ($row->share > 0) {
|
||||
if ($row->share) {
|
||||
return $row;
|
||||
}
|
||||
$pid = $row->pid;
|
||||
@ -125,7 +119,7 @@ class File extends AbstractModel
|
||||
if (empty($row)) {
|
||||
break;
|
||||
}
|
||||
if ($row->share > 0) {
|
||||
if ($row->share) {
|
||||
return true;
|
||||
}
|
||||
$pid = $row->pid;
|
||||
@ -138,18 +132,23 @@ class File extends AbstractModel
|
||||
* @param $share
|
||||
* @return bool
|
||||
*/
|
||||
public function setShare($share)
|
||||
public function setShare($share = null)
|
||||
{
|
||||
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);
|
||||
if ($share === null) {
|
||||
$share = FileUser::whereFileId($this->id)->count() == 0 ? 0 : 1;
|
||||
}
|
||||
if ($this->share != $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;
|
||||
}
|
||||
|
||||
|
@ -4,12 +4,12 @@ namespace App\Models;
|
||||
|
||||
|
||||
/**
|
||||
* Class FileUser
|
||||
* App\Models\FileUser
|
||||
*
|
||||
* @package App\Models
|
||||
* @property int $id
|
||||
* @property int|null $file_id 项目ID
|
||||
* @property int|null $userid 成员ID
|
||||
* @property int|null $permission 权限:0只读,1读写
|
||||
* @property \Illuminate\Support\Carbon|null $created_at
|
||||
* @property \Illuminate\Support\Carbon|null $updated_at
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser newModelQuery()
|
||||
@ -18,6 +18,7 @@ namespace App\Models;
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereCreatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereFileId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereId($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser wherePermission($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereUpdatedAt($value)
|
||||
* @method static \Illuminate\Database\Eloquent\Builder|FileUser whereUserid($value)
|
||||
* @mixin \Eloquent
|
||||
|
@ -5,6 +5,7 @@
|
||||
:transfer="transfer"
|
||||
:remote-method="searchUser"
|
||||
:placeholder="placeholder"
|
||||
:size="size"
|
||||
:loading="loading"
|
||||
:loading-text="$L('加载中...')"
|
||||
:default-label="value"
|
||||
@ -17,6 +18,7 @@
|
||||
@on-open-change="openChange"
|
||||
@on-set-default-options="setDefaultOptions">
|
||||
<div v-if="multipleMax" slot="drop-prepend" class="user-drop-prepend">{{$L('最多只能选择' + multipleMax + '个')}}</div>
|
||||
<slot name="option-prepend"></slot>
|
||||
<Option
|
||||
v-for="(item, key) in list"
|
||||
:value="item.userid"
|
||||
@ -60,6 +62,9 @@
|
||||
placeholder: {
|
||||
default: ''
|
||||
},
|
||||
size: {
|
||||
default: 'default'
|
||||
},
|
||||
transfer: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
|
@ -198,21 +198,46 @@
|
||||
<Modal
|
||||
v-model="shareShow"
|
||||
:title="$L('共享设置')"
|
||||
:mask-closable="false">
|
||||
<Form ref="addProject" :model="shareInfo" label-width="auto" @submit.native.prevent>
|
||||
<FormItem prop="type" :label="$L('共享对象')">
|
||||
<RadioGroup v-model="shareInfo.share">
|
||||
<Radio v-if="userIsAdmin" :label="1">{{$L('所有人')}}</Radio>
|
||||
<Radio :label="2">{{$L('指定成员')}}</Radio>
|
||||
</RadioGroup>
|
||||
:mask-closable="false"
|
||||
footer-hide>
|
||||
<Form class="page-file-share-form" :model="shareInfo" @submit.native.prevent inline>
|
||||
<FormItem prop="userids" class="share-userid">
|
||||
<UserInput
|
||||
v-model="shareInfo.userids"
|
||||
:disabledChoice="shareAlready"
|
||||
:multiple-max="100"
|
||||
:placeholder="$L('选择共享成员')">
|
||||
<Option slot="option-prepend" :value="0" :label="$L('所有人')">
|
||||
<div class="user-input-option">
|
||||
<div class="user-input-avatar"><EAvatar class="avatar" style="line-height:26px" icon="el-icon-s-custom"/></div>
|
||||
<div class="user-input-nickname">{{ $L('所有人') }}</div>
|
||||
<div class="user-input-userid">All</div>
|
||||
</div>
|
||||
</Option>
|
||||
</UserInput>
|
||||
</FormItem>
|
||||
<FormItem v-if="shareInfo.share === 2" prop="userids" :label="$L('共享成员')">
|
||||
<UserInput v-if="!shareInfo.userTmpHide" v-model="shareInfo.userids" :disabledChoice="[shareInfo.userid]" :multiple-max="100" :placeholder="$L('选择共享成员')"/>
|
||||
<FormItem>
|
||||
<Select v-model="shareInfo.permission" :placeholder="$L('权限')">
|
||||
<Option :value="1">{{$L('读/写')}}</Option>
|
||||
<Option :value="0">{{$L('只读')}}</Option>
|
||||
</Select>
|
||||
</FormItem>
|
||||
<FormItem>
|
||||
<Button type="primary" :loading="shareLoad > 0" @click="onShare">{{$L('共享')}}</Button>
|
||||
</FormItem>
|
||||
</Form>
|
||||
<div slot="footer" class="adaption">
|
||||
<Button type="default" :loading="shareLoad > 0" @click="onShare(false)">{{$L('取消共享')}}</Button>
|
||||
<Button type="primary" :loading="shareLoad > 0" @click="onShare(true)">{{$L('设置共享')}}</Button>
|
||||
<div v-if="shareList.length > 0">
|
||||
<div class="page-file-share-title">{{ $L('已共享成员') }}:</div>
|
||||
<ul class="page-file-share-list">
|
||||
<li v-for="item in shareList">
|
||||
<UserAvatar :size="32" :userid="item.userid" show-name tooltip-disabled/>
|
||||
<Select v-model="item.permission" :placeholder="$L('权限')" @on-change="upShare(item)">
|
||||
<Option :value="1">{{ $L('读/写') }}</Option>
|
||||
<Option :value="0">{{ $L('只读') }}</Option>
|
||||
<Option :value="-1" class="delete">{{ $L('删除') }}</Option>
|
||||
</Select>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Modal>
|
||||
|
||||
@ -308,7 +333,8 @@ export default {
|
||||
columns: [],
|
||||
|
||||
shareShow: false,
|
||||
shareInfo: {},
|
||||
shareInfo: {id: 0, userid: 0, permission: 1},
|
||||
shareList: [],
|
||||
shareLoad: 0,
|
||||
|
||||
editShow: false,
|
||||
@ -381,6 +407,14 @@ export default {
|
||||
return null;
|
||||
},
|
||||
|
||||
shareAlready() {
|
||||
let data = this.shareList ? this.shareList.map(({userid}) => userid) : [];
|
||||
if (this.shareInfo.userid) {
|
||||
data.push(this.shareInfo.userid);
|
||||
}
|
||||
return data
|
||||
},
|
||||
|
||||
fileList() {
|
||||
const {files, searchKey, pid} = this;
|
||||
return sortBy(files.filter((file) => {
|
||||
@ -747,15 +781,10 @@ export default {
|
||||
case 'share':
|
||||
this.shareInfo = {
|
||||
id: item.id,
|
||||
name: item.name,
|
||||
userid: item.userid,
|
||||
share: item.share,
|
||||
_share: item.share,
|
||||
permission: 1,
|
||||
};
|
||||
if (!this.userIsAdmin) {
|
||||
// 不是管理员只能共享给指定人
|
||||
this.shareInfo.share = 2;
|
||||
}
|
||||
this.shareList = [];
|
||||
this.shareShow = true;
|
||||
this.getShare();
|
||||
break;
|
||||
@ -899,10 +928,10 @@ export default {
|
||||
}).then(({data}) => {
|
||||
this.shareLoad--;
|
||||
if (data.id == this.shareInfo.id) {
|
||||
this.shareInfo = Object.assign({userTmpHide: true}, this.shareInfo, data);
|
||||
this.$nextTick(() => {
|
||||
this.$set(this.shareInfo, 'userTmpHide', false);
|
||||
})
|
||||
this.shareList = data.list.map(item => {
|
||||
item._permission = item.permission;
|
||||
return item;
|
||||
});
|
||||
}
|
||||
}).catch(({msg}) => {
|
||||
this.shareLoad--;
|
||||
@ -911,32 +940,58 @@ export default {
|
||||
})
|
||||
},
|
||||
|
||||
onShare(share) {
|
||||
if (!share && !this.shareInfo._share) {
|
||||
this.shareShow = false;
|
||||
return;
|
||||
}
|
||||
if (![1, 2].includes(this.shareInfo.share)) {
|
||||
$A.messageWarning("请选择共享对象")
|
||||
onShare() {
|
||||
if (this.shareInfo.userids.length == 0) {
|
||||
$A.messageWarning("请选择共享成员")
|
||||
return;
|
||||
}
|
||||
this.shareLoad++;
|
||||
this.$store.dispatch("call", {
|
||||
url: 'file/share/update',
|
||||
data: Object.assign(this.shareInfo, {
|
||||
action: share ? 'share' : 'unshare'
|
||||
}),
|
||||
data: this.shareInfo,
|
||||
}).then(({data, msg}) => {
|
||||
this.shareLoad--;
|
||||
this.shareShow = false;
|
||||
$A.messageSuccess(msg)
|
||||
this.$store.dispatch("saveFile", data);
|
||||
this.$set(this.shareInfo, 'userids', []);
|
||||
this.getShare();
|
||||
}).catch(({msg}) => {
|
||||
this.shareLoad--;
|
||||
$A.modalError(msg)
|
||||
})
|
||||
},
|
||||
|
||||
upShare(item) {
|
||||
if (item.loading === true) {
|
||||
return;
|
||||
}
|
||||
item.loading = true;
|
||||
//
|
||||
this.$store.dispatch("call", {
|
||||
url: 'file/share/update',
|
||||
data: {
|
||||
id: this.shareInfo.id,
|
||||
userids: [item.userid],
|
||||
permission: item.permission,
|
||||
},
|
||||
}).then(({data, msg}) => {
|
||||
item.loading = false;
|
||||
item._permission = item.permission;
|
||||
$A.messageSuccess(msg);
|
||||
this.$store.dispatch("saveFile", data);
|
||||
if (item.permission === -1) {
|
||||
let index = this.shareList.findIndex(({userid}) => userid == item.userid);
|
||||
if (index > -1) {
|
||||
this.shareList.splice(index, 1)
|
||||
}
|
||||
}
|
||||
}).catch(({msg}) => {
|
||||
item.loading = false;
|
||||
item.permission = item._permission;
|
||||
$A.modalError(msg)
|
||||
})
|
||||
},
|
||||
|
||||
/********************文件上传部分************************/
|
||||
|
||||
uploadUpdate(fileList) {
|
||||
|
38
resources/assets/sass/pages/page-file.scss
vendored
38
resources/assets/sass/pages/page-file.scss
vendored
@ -703,6 +703,44 @@
|
||||
}
|
||||
}
|
||||
|
||||
.page-file-share-form {
|
||||
display: flex;
|
||||
margin-bottom: 12px;
|
||||
.share-userid {
|
||||
flex: 1;
|
||||
}
|
||||
> div {
|
||||
flex-shrink: 0;
|
||||
&:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.page-file-share-title {
|
||||
margin-top: -8px;
|
||||
margin-bottom: 14px;
|
||||
padding: 0 2px;
|
||||
}
|
||||
.page-file-share-list {
|
||||
max-height: 500px;
|
||||
margin-bottom: 24px;
|
||||
> li {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
.common-avatar {
|
||||
flex: 1;
|
||||
}
|
||||
.ivu-select {
|
||||
width: auto;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.delete {
|
||||
color: #ff0000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.page-file-drawer {
|
||||
.overlay-content {
|
||||
border-radius: 20px 20px 0 0 !important;
|
||||
|
Loading…
x
Reference in New Issue
Block a user