mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-14 21:02:49 +00:00
feat: 增强文件和项目的收藏功能
- 在 UserFavorite 模型中添加文件的 pid 字段以支持层级结构 - 更新前端 Vue 组件以实现文件和项目的收藏状态切换 - 添加检查文件和项目收藏状态的功能 - 优化上下文菜单以支持收藏操作
This commit is contained in:
parent
379d3811a8
commit
11b98978c1
@ -3,6 +3,7 @@
|
|||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use App\Models\File;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App\Models\UserFavorite
|
* App\Models\UserFavorite
|
||||||
@ -211,7 +212,7 @@ class UserFavorite extends AbstractModel
|
|||||||
|
|
||||||
if (!empty($fileIds)) {
|
if (!empty($fileIds)) {
|
||||||
$files = File::select([
|
$files = File::select([
|
||||||
'id', 'name', 'ext', 'size', 'created_at'
|
'id', 'name', 'ext', 'size', 'pid', 'created_at'
|
||||||
])->whereIn('id', $fileIds)->get()->keyBy('id');
|
])->whereIn('id', $fileIds)->get()->keyBy('id');
|
||||||
|
|
||||||
foreach ($favorites->items() as $favorite) {
|
foreach ($favorites->items() as $favorite) {
|
||||||
@ -222,6 +223,7 @@ class UserFavorite extends AbstractModel
|
|||||||
'name' => $file->name,
|
'name' => $file->name,
|
||||||
'ext' => $file->ext,
|
'ext' => $file->ext,
|
||||||
'size' => $file->size,
|
'size' => $file->size,
|
||||||
|
'pid' => $file->pid,
|
||||||
'favorited_at' => Carbon::parse($favorite->created_at)->format('Y-m-d H:i:s'),
|
'favorited_at' => Carbon::parse($favorite->created_at)->format('Y-m-d H:i:s'),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -282,6 +282,7 @@ export default {
|
|||||||
name: file.name,
|
name: file.name,
|
||||||
ext: file.ext,
|
ext: file.ext,
|
||||||
size: file.size,
|
size: file.size,
|
||||||
|
pid: file.pid,
|
||||||
favorited_at: file.favorited_at,
|
favorited_at: file.favorited_at,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -334,7 +335,18 @@ export default {
|
|||||||
this.$emit('on-close');
|
this.$emit('on-close');
|
||||||
break;
|
break;
|
||||||
case 'file':
|
case 'file':
|
||||||
this.$router.push({name: 'manage-file'});
|
this.$router.push({
|
||||||
|
name: 'manage-file',
|
||||||
|
params: {
|
||||||
|
folderId: item.pid || 0,
|
||||||
|
fileId: null,
|
||||||
|
shakeId: item.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.$store.state.fileShakeId = item.id;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.$store.state.fileShakeId = 0;
|
||||||
|
}, 600);
|
||||||
this.$emit('on-close');
|
this.$emit('on-close');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,7 +58,8 @@
|
|||||||
<EDropdownItem command="workflow">{{$L('工作流设置')}}</EDropdownItem>
|
<EDropdownItem command="workflow">{{$L('工作流设置')}}</EDropdownItem>
|
||||||
<EDropdownItem command="user" divided>{{$L('成员管理')}}</EDropdownItem>
|
<EDropdownItem command="user" divided>{{$L('成员管理')}}</EDropdownItem>
|
||||||
<EDropdownItem command="invite">{{$L('邀请链接')}}</EDropdownItem>
|
<EDropdownItem command="invite">{{$L('邀请链接')}}</EDropdownItem>
|
||||||
<EDropdownItem command="log" divided>{{$L('项目动态')}}</EDropdownItem>
|
<EDropdownItem command="favorite" divided>{{$L(projectData.favorited ? '取消收藏' : '收藏项目')}}</EDropdownItem>
|
||||||
|
<EDropdownItem command="log">{{$L('项目动态')}}</EDropdownItem>
|
||||||
<EDropdownItem command="archived_task">{{$L('已归档任务')}}</EDropdownItem>
|
<EDropdownItem command="archived_task">{{$L('已归档任务')}}</EDropdownItem>
|
||||||
<EDropdownItem command="deleted_task">{{$L('已删除任务')}}</EDropdownItem>
|
<EDropdownItem command="deleted_task">{{$L('已删除任务')}}</EDropdownItem>
|
||||||
<EDropdownItem command="transfer" divided>{{$L('移交项目')}}</EDropdownItem>
|
<EDropdownItem command="transfer" divided>{{$L('移交项目')}}</EDropdownItem>
|
||||||
@ -67,7 +68,8 @@
|
|||||||
</EDropdownMenu>
|
</EDropdownMenu>
|
||||||
<EDropdownMenu v-else slot="dropdown">
|
<EDropdownMenu v-else slot="dropdown">
|
||||||
<EDropdownItem command="task_tag">{{$L('任务标签')}}</EDropdownItem>
|
<EDropdownItem command="task_tag">{{$L('任务标签')}}</EDropdownItem>
|
||||||
<EDropdownItem command="log" divided>{{$L('项目动态')}}</EDropdownItem>
|
<EDropdownItem command="favorite" divided>{{$L(projectData.favorited ? '取消收藏' : '收藏项目')}}</EDropdownItem>
|
||||||
|
<EDropdownItem command="log">{{$L('项目动态')}}</EDropdownItem>
|
||||||
<EDropdownItem command="archived_task">{{$L('已归档任务')}}</EDropdownItem>
|
<EDropdownItem command="archived_task">{{$L('已归档任务')}}</EDropdownItem>
|
||||||
<EDropdownItem command="deleted_task">{{$L('已删除任务')}}</EDropdownItem>
|
<EDropdownItem command="deleted_task">{{$L('已删除任务')}}</EDropdownItem>
|
||||||
<EDropdownItem command="exit" divided style="color:#f40">{{$L('退出项目')}}</EDropdownItem>
|
<EDropdownItem command="exit" divided style="color:#f40">{{$L('退出项目')}}</EDropdownItem>
|
||||||
@ -1066,8 +1068,12 @@ export default {
|
|||||||
windowWidth() {
|
windowWidth() {
|
||||||
this.handleColumnDebounce(100);
|
this.handleColumnDebounce(100);
|
||||||
},
|
},
|
||||||
projectData() {
|
projectData(newData, oldData) {
|
||||||
this.sortData = this.getSort();
|
this.sortData = this.getSort();
|
||||||
|
// 当项目数据改变时,检查收藏状态(避免重复调用)
|
||||||
|
if (newData && newData.id && (!oldData || newData.id !== oldData.id)) {
|
||||||
|
this.checkProjectFavoriteStatus();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
projectLoad(n) {
|
projectLoad(n) {
|
||||||
this._loadTimeout && clearTimeout(this._loadTimeout)
|
this._loadTimeout && clearTimeout(this._loadTimeout)
|
||||||
@ -1435,6 +1441,10 @@ export default {
|
|||||||
|
|
||||||
projectDropdown(name) {
|
projectDropdown(name) {
|
||||||
switch (name) {
|
switch (name) {
|
||||||
|
case "favorite":
|
||||||
|
this.toggleProjectFavorite();
|
||||||
|
break;
|
||||||
|
|
||||||
case "setting":
|
case "setting":
|
||||||
Object.assign(this.settingData, {
|
Object.assign(this.settingData, {
|
||||||
name: this.projectData.name,
|
name: this.projectData.name,
|
||||||
@ -1877,6 +1887,50 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换项目收藏状态
|
||||||
|
*/
|
||||||
|
toggleProjectFavorite() {
|
||||||
|
if (!this.projectData.id) return;
|
||||||
|
|
||||||
|
this.$store.dispatch("call", {
|
||||||
|
url: 'users/favorite/toggle',
|
||||||
|
data: {
|
||||||
|
type: 'project',
|
||||||
|
id: this.projectData.id
|
||||||
|
},
|
||||||
|
method: 'post',
|
||||||
|
}).then(({data, msg}) => {
|
||||||
|
// 更新项目的收藏状态
|
||||||
|
this.$set(this.projectData, 'favorited', data.favorited);
|
||||||
|
$A.messageSuccess(msg);
|
||||||
|
}).catch(({msg}) => {
|
||||||
|
$A.modalError(msg || this.$L('操作失败'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查项目收藏状态
|
||||||
|
*/
|
||||||
|
checkProjectFavoriteStatus() {
|
||||||
|
if (!this.projectData.id) return;
|
||||||
|
|
||||||
|
this.$store.dispatch("call", {
|
||||||
|
url: 'users/favorite/check',
|
||||||
|
data: {
|
||||||
|
type: 'project',
|
||||||
|
id: this.projectData.id
|
||||||
|
},
|
||||||
|
method: 'get',
|
||||||
|
spinner: 0, // 静默调用
|
||||||
|
}).then(({data}) => {
|
||||||
|
this.$set(this.projectData, 'favorited', data.favorited || false);
|
||||||
|
}).catch(() => {
|
||||||
|
// 出错时默认为未收藏状态
|
||||||
|
this.$set(this.projectData, 'favorited', false);
|
||||||
|
});
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -218,6 +218,7 @@
|
|||||||
|
|
||||||
<DropdownItem v-if="contextMenuItem.userid == userId" name="share" divided>{{$L('共享')}}</DropdownItem>
|
<DropdownItem v-if="contextMenuItem.userid == userId" name="share" divided>{{$L('共享')}}</DropdownItem>
|
||||||
<DropdownItem v-else-if="contextMenuItem.share" name="outshare" divided>{{$L('退出共享')}}</DropdownItem>
|
<DropdownItem v-else-if="contextMenuItem.share" name="outshare" divided>{{$L('退出共享')}}</DropdownItem>
|
||||||
|
<DropdownItem name="favorite" :disabled="contextMenuItem.type == 'folder'">{{$L(contextMenuItem.favorited ? '取消收藏' : '收藏')}}</DropdownItem>
|
||||||
<DropdownItem name="send" :disabled="contextMenuItem.type == 'folder'">{{$L('发送')}}</DropdownItem>
|
<DropdownItem name="send" :disabled="contextMenuItem.type == 'folder'">{{$L('发送')}}</DropdownItem>
|
||||||
<DropdownItem name="link" :divided="contextMenuItem.userid != userId && !contextMenuItem.share" :disabled="contextMenuItem.type == 'folder'">{{$L('链接')}}</DropdownItem>
|
<DropdownItem name="link" :divided="contextMenuItem.userid != userId && !contextMenuItem.share" :disabled="contextMenuItem.type == 'folder'">{{$L('链接')}}</DropdownItem>
|
||||||
<DropdownItem name="download" :disabled="contextMenuItem.ext == '' || (contextMenuItem.userid != userId && contextMenuItem.permission == 0)">{{$L('下载')}}</DropdownItem>
|
<DropdownItem name="download" :disabled="contextMenuItem.ext == '' || (contextMenuItem.userid != userId && contextMenuItem.permission == 0)">{{$L('下载')}}</DropdownItem>
|
||||||
@ -1011,6 +1012,7 @@ export default {
|
|||||||
this.loadIng--;
|
this.loadIng--;
|
||||||
this.openFileJudge()
|
this.openFileJudge()
|
||||||
this.shakeFile(this.$route.params.shakeId);
|
this.shakeFile(this.$route.params.shakeId);
|
||||||
|
this.checkFileFavoriteStatus(this.fileList);
|
||||||
await $A.IDBSet("fileFolderId", this.pid)
|
await $A.IDBSet("fileFolderId", this.pid)
|
||||||
}).catch(({msg}) => {
|
}).catch(({msg}) => {
|
||||||
this.loadIng--;
|
this.loadIng--;
|
||||||
@ -1302,6 +1304,10 @@ export default {
|
|||||||
this.$refs.forwarder.onSelection()
|
this.$refs.forwarder.onSelection()
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'favorite':
|
||||||
|
this.toggleFileFavorite(item);
|
||||||
|
break;
|
||||||
|
|
||||||
case 'share':
|
case 'share':
|
||||||
this.shareInfo = {
|
this.shareInfo = {
|
||||||
id: item.id,
|
id: item.id,
|
||||||
@ -2072,6 +2078,69 @@ export default {
|
|||||||
handleUploadNext() {
|
handleUploadNext() {
|
||||||
this.uploadShow = true;
|
this.uploadShow = true;
|
||||||
this.packShow = false;
|
this.packShow = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 切换文件收藏状态
|
||||||
|
*/
|
||||||
|
toggleFileFavorite(item) {
|
||||||
|
if (!item.id || item.type === 'folder') return;
|
||||||
|
|
||||||
|
this.$store.dispatch("call", {
|
||||||
|
url: 'users/favorite/toggle',
|
||||||
|
data: {
|
||||||
|
type: 'file',
|
||||||
|
id: item.id
|
||||||
|
},
|
||||||
|
method: 'post',
|
||||||
|
}).then(({data, msg}) => {
|
||||||
|
// 更新文件的收藏状态
|
||||||
|
const fileIndex = this.fileList.findIndex(file => file.id === item.id);
|
||||||
|
if (fileIndex > -1) {
|
||||||
|
this.$set(this.fileList[fileIndex], 'favorited', data.favorited);
|
||||||
|
}
|
||||||
|
// 同时更新上下文菜单项的状态
|
||||||
|
if (this.contextMenuItem.id === item.id) {
|
||||||
|
this.$set(this.contextMenuItem, 'favorited', data.favorited);
|
||||||
|
}
|
||||||
|
$A.messageSuccess(msg);
|
||||||
|
}).catch(({msg}) => {
|
||||||
|
$A.modalError(msg || this.$L('操作失败'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查文件收藏状态
|
||||||
|
*/
|
||||||
|
checkFileFavoriteStatus(files) {
|
||||||
|
if (!Array.isArray(files) || files.length === 0) return;
|
||||||
|
|
||||||
|
const fileIds = files.filter(file => file.type !== 'folder').map(file => file.id);
|
||||||
|
if (fileIds.length === 0) return;
|
||||||
|
|
||||||
|
// 批量检查收藏状态
|
||||||
|
fileIds.forEach(fileId => {
|
||||||
|
this.$store.dispatch("call", {
|
||||||
|
url: 'users/favorite/check',
|
||||||
|
data: {
|
||||||
|
type: 'file',
|
||||||
|
id: fileId
|
||||||
|
},
|
||||||
|
method: 'get',
|
||||||
|
spinner: 0, // 静默调用
|
||||||
|
}).then(({data}) => {
|
||||||
|
const fileIndex = this.fileList.findIndex(file => file.id === fileId);
|
||||||
|
if (fileIndex > -1) {
|
||||||
|
this.$set(this.fileList[fileIndex], 'favorited', data.favorited || false);
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
// 出错时默认为未收藏状态
|
||||||
|
const fileIndex = this.fileList.findIndex(file => file.id === fileId);
|
||||||
|
if (fileIndex > -1) {
|
||||||
|
this.$set(this.fileList[fileIndex], 'favorited', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user