diff --git a/app/Models/UserFavorite.php b/app/Models/UserFavorite.php index 4fe06e826..d42eb8530 100644 --- a/app/Models/UserFavorite.php +++ b/app/Models/UserFavorite.php @@ -3,6 +3,7 @@ namespace App\Models; use Carbon\Carbon; +use App\Models\File; /** * App\Models\UserFavorite @@ -211,7 +212,7 @@ class UserFavorite extends AbstractModel if (!empty($fileIds)) { $files = File::select([ - 'id', 'name', 'ext', 'size', 'created_at' + 'id', 'name', 'ext', 'size', 'pid', 'created_at' ])->whereIn('id', $fileIds)->get()->keyBy('id'); foreach ($favorites->items() as $favorite) { @@ -222,6 +223,7 @@ class UserFavorite extends AbstractModel 'name' => $file->name, 'ext' => $file->ext, 'size' => $file->size, + 'pid' => $file->pid, 'favorited_at' => Carbon::parse($favorite->created_at)->format('Y-m-d H:i:s'), ]; } diff --git a/resources/assets/js/pages/manage/components/FavoriteManagement.vue b/resources/assets/js/pages/manage/components/FavoriteManagement.vue index 2fab4aa2f..9a0e10145 100644 --- a/resources/assets/js/pages/manage/components/FavoriteManagement.vue +++ b/resources/assets/js/pages/manage/components/FavoriteManagement.vue @@ -282,6 +282,7 @@ export default { name: file.name, ext: file.ext, size: file.size, + pid: file.pid, favorited_at: file.favorited_at, }); }); @@ -334,7 +335,18 @@ export default { this.$emit('on-close'); break; 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'); break; } diff --git a/resources/assets/js/pages/manage/components/ProjectPanel.vue b/resources/assets/js/pages/manage/components/ProjectPanel.vue index 7a171ddb2..a30260f33 100644 --- a/resources/assets/js/pages/manage/components/ProjectPanel.vue +++ b/resources/assets/js/pages/manage/components/ProjectPanel.vue @@ -58,7 +58,8 @@ {{$L('工作流设置')}} {{$L('成员管理')}} {{$L('邀请链接')}} - {{$L('项目动态')}} + {{$L(projectData.favorited ? '取消收藏' : '收藏项目')}} + {{$L('项目动态')}} {{$L('已归档任务')}} {{$L('已删除任务')}} {{$L('移交项目')}} @@ -67,7 +68,8 @@ {{$L('任务标签')}} - {{$L('项目动态')}} + {{$L(projectData.favorited ? '取消收藏' : '收藏项目')}} + {{$L('项目动态')}} {{$L('已归档任务')}} {{$L('已删除任务')}} {{$L('退出项目')}} @@ -1066,8 +1068,12 @@ export default { windowWidth() { this.handleColumnDebounce(100); }, - projectData() { + projectData(newData, oldData) { this.sortData = this.getSort(); + // 当项目数据改变时,检查收藏状态(避免重复调用) + if (newData && newData.id && (!oldData || newData.id !== oldData.id)) { + this.checkProjectFavoriteStatus(); + } }, projectLoad(n) { this._loadTimeout && clearTimeout(this._loadTimeout) @@ -1435,6 +1441,10 @@ export default { projectDropdown(name) { switch (name) { + case "favorite": + this.toggleProjectFavorite(); + break; + case "setting": Object.assign(this.settingData, { 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); + }); + }, } } diff --git a/resources/assets/js/pages/manage/file.vue b/resources/assets/js/pages/manage/file.vue index 050de4fd4..349c948e7 100644 --- a/resources/assets/js/pages/manage/file.vue +++ b/resources/assets/js/pages/manage/file.vue @@ -218,6 +218,7 @@ {{$L('共享')}} {{$L('退出共享')}} + {{$L(contextMenuItem.favorited ? '取消收藏' : '收藏')}} {{$L('发送')}} {{$L('链接')}} {{$L('下载')}} @@ -1011,6 +1012,7 @@ export default { this.loadIng--; this.openFileJudge() this.shakeFile(this.$route.params.shakeId); + this.checkFileFavoriteStatus(this.fileList); await $A.IDBSet("fileFolderId", this.pid) }).catch(({msg}) => { this.loadIng--; @@ -1302,6 +1304,10 @@ export default { this.$refs.forwarder.onSelection() break; + case 'favorite': + this.toggleFileFavorite(item); + break; + case 'share': this.shareInfo = { id: item.id, @@ -2072,6 +2078,69 @@ export default { handleUploadNext() { this.uploadShow = true; 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); + } + }); + }); } } }