mirror of
https://github.com/jiangrui1994/CloudSaver.git
synced 2026-01-11 23:58:46 +08:00
feat:增加转存资源列表展示与选择
This commit is contained in:
2
frontend/auto-imports.d.ts
vendored
2
frontend/auto-imports.d.ts
vendored
@@ -5,5 +5,5 @@
|
|||||||
// Generated by unplugin-auto-import
|
// Generated by unplugin-auto-import
|
||||||
export {}
|
export {}
|
||||||
declare global {
|
declare global {
|
||||||
const ElMessage: (typeof import("element-plus/es"))["ElMessage"]
|
const ElMessage: typeof import('element-plus/es')['ElMessage']
|
||||||
}
|
}
|
||||||
|
|||||||
2
frontend/components.d.ts
vendored
2
frontend/components.d.ts
vendored
@@ -8,6 +8,7 @@ export {}
|
|||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
AsideMenu: typeof import('./src/components/AsideMenu.vue')['default']
|
AsideMenu: typeof import('./src/components/AsideMenu.vue')['default']
|
||||||
|
copy: typeof import('./src/components/Home/FolderSelect copy.vue')['default']
|
||||||
DoubanMovie: typeof import('./src/components/Home/DoubanMovie.vue')['default']
|
DoubanMovie: typeof import('./src/components/Home/DoubanMovie.vue')['default']
|
||||||
ElAside: typeof import('element-plus/es')['ElAside']
|
ElAside: typeof import('element-plus/es')['ElAside']
|
||||||
ElBacktop: typeof import('element-plus/es')['ElBacktop']
|
ElBacktop: typeof import('element-plus/es')['ElBacktop']
|
||||||
@@ -39,6 +40,7 @@ declare module 'vue' {
|
|||||||
ElTree: typeof import('element-plus/es')['ElTree']
|
ElTree: typeof import('element-plus/es')['ElTree']
|
||||||
FolderSelect: typeof import('./src/components/Home/FolderSelect.vue')['default']
|
FolderSelect: typeof import('./src/components/Home/FolderSelect.vue')['default']
|
||||||
ResourceCard: typeof import('./src/components/Home/ResourceCard.vue')['default']
|
ResourceCard: typeof import('./src/components/Home/ResourceCard.vue')['default']
|
||||||
|
ResourceSelect: typeof import('./src/components/Home/ResourceSelect.vue')['default']
|
||||||
ResourceTable: typeof import('./src/components/Home/ResourceTable.vue')['default']
|
ResourceTable: typeof import('./src/components/Home/ResourceTable.vue')['default']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
|
|||||||
@@ -31,6 +31,9 @@ import { quarkApi } from "@/api/quark";
|
|||||||
import type { TreeInstance } from "element-plus";
|
import type { TreeInstance } from "element-plus";
|
||||||
import type { Folder } from "@/types";
|
import type { Folder } from "@/types";
|
||||||
import { type RequestResult } from "@/types/response";
|
import { type RequestResult } from "@/types/response";
|
||||||
|
import { useResourceStore } from "@/stores/resource";
|
||||||
|
|
||||||
|
const resourceStore = useResourceStore();
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -59,10 +62,12 @@ const cloudTypeApiMap = {
|
|||||||
quark: quarkApi,
|
quark: quarkApi,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
const loadNode = async (node: any, resolve: (list: Folder[]) => void) => {
|
const loadNode = async (node: any, resolve: (list: Folder[]) => void) => {
|
||||||
const api = cloudTypeApiMap[props.cloudType as keyof typeof cloudTypeApiMap];
|
const api = cloudTypeApiMap[props.cloudType as keyof typeof cloudTypeApiMap];
|
||||||
try {
|
try {
|
||||||
let res: RequestResult<Folder[]> = { code: 0, data: [] as Folder[], message: "" };
|
let res: RequestResult<Folder[]> = { code: 0, data: [] as Folder[], message: "" };
|
||||||
|
resourceStore.setLoadTree(true);
|
||||||
if (node.level === 0) {
|
if (node.level === 0) {
|
||||||
if (api.getFolderList) {
|
if (api.getFolderList) {
|
||||||
// 使用类型保护检查方法是否存在
|
// 使用类型保护检查方法是否存在
|
||||||
@@ -79,10 +84,12 @@ const loadNode = async (node: any, resolve: (list: Folder[]) => void) => {
|
|||||||
} else {
|
} else {
|
||||||
throw new Error(res.message);
|
throw new Error(res.message);
|
||||||
}
|
}
|
||||||
|
resourceStore.setLoadTree(false);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error(error instanceof Error ? `${error.message}` : "获取目录失败");
|
ElMessage.error(error instanceof Error ? `${error.message}` : "获取目录失败");
|
||||||
// 关闭模态框
|
// 关闭模态框
|
||||||
emit("close");
|
emit("close");
|
||||||
|
resourceStore.setLoadTree(false);
|
||||||
resolve([]);
|
resolve([]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
82
frontend/src/components/Home/ResourceSelect.vue
Normal file
82
frontend/src/components/Home/ResourceSelect.vue
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
<template>
|
||||||
|
<div class="folder-select">
|
||||||
|
<el-tree
|
||||||
|
ref="treeRef"
|
||||||
|
:data="resourceStore.shareInfo.list"
|
||||||
|
:props="defaultProps"
|
||||||
|
:default-checked-keys="resourceStore.shareInfo.list?.map((x) => x.fileId) || []"
|
||||||
|
node-key="fileId"
|
||||||
|
show-checkbox
|
||||||
|
highlight-current
|
||||||
|
@check-change="handleCheckChange"
|
||||||
|
>
|
||||||
|
<template #default="{ node }">
|
||||||
|
<span class="folder-node">
|
||||||
|
<el-icon><Folder /></el-icon>
|
||||||
|
{{ node.data.fileName }}
|
||||||
|
<span v-if="node.data.fileSize" style="font-weight: bold"
|
||||||
|
>({{ formattedFileSize(node.data.fileSize) }})</span
|
||||||
|
>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-tree>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { useResourceStore } from "@/stores/resource";
|
||||||
|
import { formattedFileSize } from "@/utils/index";
|
||||||
|
import type { ShareInfo } from "@/types";
|
||||||
|
|
||||||
|
const resourceStore = useResourceStore();
|
||||||
|
const selectedResource = ref<ShareInfo[]>([]);
|
||||||
|
|
||||||
|
const defaultProps = {
|
||||||
|
isLeaf: "leaf",
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCheckChange = (data: ShareInfo) => {
|
||||||
|
selectedResource.value = [...resourceStore.resourceSelect, ...selectedResource.value];
|
||||||
|
if (selectedResource.value.findIndex((x) => x.fileId === data.fileId) === -1) {
|
||||||
|
selectedResource.value.push(data);
|
||||||
|
} else {
|
||||||
|
selectedResource.value = selectedResource.value.filter((x) => x.fileId !== data.fileId);
|
||||||
|
}
|
||||||
|
resourceStore.setSelectedResource(selectedResource.value);
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.folder-select {
|
||||||
|
min-height: 300px;
|
||||||
|
max-height: 500px;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-node {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.folder-path {
|
||||||
|
color: #999;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-tree-node__content) {
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
.folder-select-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
border: 1px solid #e5e6e8;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -7,6 +7,7 @@ import type {
|
|||||||
ShareInfoResponse,
|
ShareInfoResponse,
|
||||||
Save115FileParams,
|
Save115FileParams,
|
||||||
SaveQuarkFileParams,
|
SaveQuarkFileParams,
|
||||||
|
ShareInfo,
|
||||||
ResourceItem,
|
ResourceItem,
|
||||||
} from "@/types";
|
} from "@/types";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
@@ -101,13 +102,18 @@ export const useResourceStore = defineStore("resource", {
|
|||||||
},
|
},
|
||||||
resources: lastResource.list,
|
resources: lastResource.list,
|
||||||
lastUpdateTime: lastResource.lastUpdateTime || "",
|
lastUpdateTime: lastResource.lastUpdateTime || "",
|
||||||
selectedResources: [] as Resource[],
|
shareInfo: {} as ShareInfoResponse,
|
||||||
|
resourceSelect: [] as ShareInfo[],
|
||||||
loading: false,
|
loading: false,
|
||||||
lastKeyWord: "",
|
lastKeyWord: "",
|
||||||
backupPlan: false,
|
backupPlan: false,
|
||||||
|
loadTree: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
setLoadTree(loadTree: boolean) {
|
||||||
|
this.loadTree = loadTree;
|
||||||
|
},
|
||||||
// 搜索资源
|
// 搜索资源
|
||||||
async searchResources(keyword?: string, isLoadMore = false, channelId?: string): Promise<void> {
|
async searchResources(keyword?: string, isLoadMore = false, channelId?: string): Promise<void> {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
@@ -153,6 +159,11 @@ export const useResourceStore = defineStore("resource", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 设置选择资源
|
||||||
|
async setSelectedResource(resourceSelect: ShareInfo[]) {
|
||||||
|
this.resourceSelect = resourceSelect;
|
||||||
|
},
|
||||||
|
|
||||||
// 转存资源
|
// 转存资源
|
||||||
async saveResource(resource: ResourceItem, folderId: string): Promise<void> {
|
async saveResource(resource: ResourceItem, folderId: string): Promise<void> {
|
||||||
const savePromises: Promise<void>[] = [];
|
const savePromises: Promise<void>[] = [];
|
||||||
@@ -178,25 +189,12 @@ export const useResourceStore = defineStore("resource", {
|
|||||||
const match = link.match(drive.regex);
|
const match = link.match(drive.regex);
|
||||||
if (!match) throw new Error("链接解析失败");
|
if (!match) throw new Error("链接解析失败");
|
||||||
|
|
||||||
const parsedCode = drive.parseShareCode(match);
|
const shareInfo = {
|
||||||
|
...this.shareInfo,
|
||||||
|
list: this.resourceSelect,
|
||||||
|
};
|
||||||
|
|
||||||
if (this.is115Drive(drive)) {
|
if (this.is115Drive(drive)) {
|
||||||
let shareInfo = await drive.api.getShareInfo(
|
|
||||||
parsedCode as { shareCode: string; receiveCode: string }
|
|
||||||
);
|
|
||||||
if (shareInfo) {
|
|
||||||
if (Array.isArray(shareInfo)) {
|
|
||||||
shareInfo = {
|
|
||||||
list: shareInfo,
|
|
||||||
...parsedCode,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
shareInfo = {
|
|
||||||
...shareInfo,
|
|
||||||
...parsedCode,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const params = drive.getSaveParams(shareInfo, folderId);
|
const params = drive.getSaveParams(shareInfo, folderId);
|
||||||
const result = await drive.api.saveFile(params);
|
const result = await drive.api.saveFile(params);
|
||||||
|
|
||||||
@@ -206,16 +204,6 @@ export const useResourceStore = defineStore("resource", {
|
|||||||
ElMessage.error(result.message);
|
ElMessage.error(result.message);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let shareInfo = this.is115Drive(drive)
|
|
||||||
? await drive.api.getShareInfo(parsedCode as { shareCode: string; receiveCode: string })
|
|
||||||
: await drive.api.getShareInfo(parsedCode as { pwdId: string });
|
|
||||||
if (shareInfo) {
|
|
||||||
if (Array.isArray(shareInfo)) {
|
|
||||||
shareInfo = {
|
|
||||||
list: shareInfo,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const params = drive.getSaveParams(shareInfo, folderId);
|
const params = drive.getSaveParams(shareInfo, folderId);
|
||||||
const result = await drive.api.saveFile(params);
|
const result = await drive.api.saveFile(params);
|
||||||
|
|
||||||
@@ -283,6 +271,49 @@ export const useResourceStore = defineStore("resource", {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 获取资源列表并选择
|
||||||
|
async getResourceListAndSelect(resource: ResourceItem): Promise<void> {
|
||||||
|
const { cloudType } = resource;
|
||||||
|
const drive = CLOUD_DRIVES.find((x) => x.type === cloudType);
|
||||||
|
if (!drive) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const link = resource.cloudLinks.find((link) => drive.regex.test(link));
|
||||||
|
if (!link) return;
|
||||||
|
|
||||||
|
const match = link.match(drive.regex);
|
||||||
|
if (!match) throw new Error("链接解析失败");
|
||||||
|
|
||||||
|
const parsedCode = drive.parseShareCode(match);
|
||||||
|
let shareInfo = {} as ShareInfoResponse;
|
||||||
|
this.setLoadTree(true);
|
||||||
|
if (this.is115Drive(drive)) {
|
||||||
|
shareInfo = await drive.api.getShareInfo(
|
||||||
|
parsedCode as { shareCode: string; receiveCode: string }
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
shareInfo = this.is115Drive(drive)
|
||||||
|
? await drive.api.getShareInfo(parsedCode as { shareCode: string; receiveCode: string })
|
||||||
|
: await drive.api.getShareInfo(parsedCode as { pwdId: string });
|
||||||
|
}
|
||||||
|
if (shareInfo) {
|
||||||
|
if (Array.isArray(shareInfo)) {
|
||||||
|
shareInfo = {
|
||||||
|
list: shareInfo,
|
||||||
|
...parsedCode,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
shareInfo = {
|
||||||
|
...shareInfo,
|
||||||
|
...parsedCode,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.shareInfo = shareInfo;
|
||||||
|
this.setSelectedResource(this.shareInfo.list);
|
||||||
|
this.setLoadTree(false);
|
||||||
|
},
|
||||||
|
|
||||||
// 统一错误处理
|
// 统一错误处理
|
||||||
handleError(message: string, error: unknown): void {
|
handleError(message: string, error: unknown): void {
|
||||||
console.error(message, error);
|
console.error(message, error);
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export interface Resource {
|
|||||||
export interface ShareInfo {
|
export interface ShareInfo {
|
||||||
fileId: string;
|
fileId: string;
|
||||||
fileName: string;
|
fileName: string;
|
||||||
fileSize: number;
|
fileSize?: number;
|
||||||
fileIdToken?: string;
|
fileIdToken?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,6 +36,7 @@ export interface ShareInfoResponse {
|
|||||||
stoken?: string;
|
stoken?: string;
|
||||||
shareCode?: string;
|
shareCode?: string;
|
||||||
receiveCode?: string;
|
receiveCode?: string;
|
||||||
|
fileSize?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Folder {
|
export interface Folder {
|
||||||
|
|||||||
9
frontend/src/utils/index.ts
Normal file
9
frontend/src/utils/index.ts
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
export const formattedFileSize = (size: number): string => {
|
||||||
|
if (size < 1024 * 1024) {
|
||||||
|
return `${(size / 1024).toFixed(2)}KB`;
|
||||||
|
}
|
||||||
|
if (size < 1024 * 1024 * 1024) {
|
||||||
|
return `${(size / 1024 / 1024).toFixed(2)}MB`;
|
||||||
|
}
|
||||||
|
return `${(size / 1024 / 1024 / 1024).toFixed(2)}GB`;
|
||||||
|
};
|
||||||
@@ -4,7 +4,7 @@ import { RequestResult } from "../types/response";
|
|||||||
|
|
||||||
const axiosInstance = axios.create({
|
const axiosInstance = axios.create({
|
||||||
baseURL: import.meta.env.VITE_API_BASE_URL as string,
|
baseURL: import.meta.env.VITE_API_BASE_URL as string,
|
||||||
timeout: 9000,
|
timeout: 16000,
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
|||||||
@@ -32,7 +32,11 @@
|
|||||||
@save="handleSave"
|
@save="handleSave"
|
||||||
></ResourceCard>
|
></ResourceCard>
|
||||||
<el-empty v-if="resourceStore.resources.length === 0" :image-size="200" />
|
<el-empty v-if="resourceStore.resources.length === 0" :image-size="200" />
|
||||||
<el-dialog v-if="currentResource" v-model="folderDialogVisible" title="选择保存目录">
|
<el-dialog
|
||||||
|
v-if="currentResource"
|
||||||
|
v-model="saveDialogVisible"
|
||||||
|
:title="saveDialogMap[saveDialogStep].title"
|
||||||
|
>
|
||||||
<template #header="{ titleId }">
|
<template #header="{ titleId }">
|
||||||
<div class="my-header">
|
<div class="my-header">
|
||||||
<div :id="titleId">
|
<div :id="titleId">
|
||||||
@@ -43,19 +47,34 @@
|
|||||||
>
|
>
|
||||||
{{ currentResource.cloudType }}
|
{{ currentResource.cloudType }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
选择保存目录
|
{{ saveDialogMap[saveDialogStep].title }}
|
||||||
|
<span
|
||||||
|
v-if="resourceStore.shareInfo.fileSize && saveDialogStep === 1"
|
||||||
|
style="font-weight: bold"
|
||||||
|
>
|
||||||
|
({{ formattedFileSize(resourceStore.shareInfo.fileSize || 0) }})
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<div v-loading="resourceStore.loadTree">
|
||||||
|
<resource-select
|
||||||
|
v-if="saveDialogVisible && saveDialogStep === 1"
|
||||||
|
:cloud-type="currentResource.cloudType"
|
||||||
|
/>
|
||||||
<folder-select
|
<folder-select
|
||||||
v-if="folderDialogVisible"
|
v-if="saveDialogVisible && saveDialogStep === 2"
|
||||||
:cloud-type="currentResource.cloudType"
|
:cloud-type="currentResource.cloudType"
|
||||||
@select="handleFolderSelect"
|
@select="handleFolderSelect"
|
||||||
@close="folderDialogVisible = false"
|
@close="saveDialogVisible = false"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<el-button @click="folderDialogVisible = false">取消</el-button>
|
<el-button @click="saveDialogVisible = false">取消</el-button>
|
||||||
<el-button type="primary" @click="handleSaveBtnClick">保存</el-button>
|
<el-button type="primary" @click="handleConfirmClick">{{
|
||||||
|
saveDialogMap[saveDialogStep].buttonText
|
||||||
|
}}</el-button>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -66,25 +85,43 @@ import { ref } from "vue";
|
|||||||
import { useResourceStore } from "@/stores/resource";
|
import { useResourceStore } from "@/stores/resource";
|
||||||
import { useUserSettingStore } from "@/stores/userSetting";
|
import { useUserSettingStore } from "@/stores/userSetting";
|
||||||
import FolderSelect from "@/components/Home/FolderSelect.vue";
|
import FolderSelect from "@/components/Home/FolderSelect.vue";
|
||||||
|
import ResourceSelect from "@/components/Home/ResourceSelect.vue";
|
||||||
import ResourceTable from "@/components/Home/ResourceTable.vue";
|
import ResourceTable from "@/components/Home/ResourceTable.vue";
|
||||||
|
import { formattedFileSize } from "@/utils/index";
|
||||||
import type { ResourceItem, TagColor } from "@/types";
|
import type { ResourceItem, TagColor } from "@/types";
|
||||||
|
|
||||||
import ResourceCard from "@/components/Home/ResourceCard.vue";
|
import ResourceCard from "@/components/Home/ResourceCard.vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
const resourceStore = useResourceStore();
|
const resourceStore = useResourceStore();
|
||||||
const userStore = useUserSettingStore();
|
const userStore = useUserSettingStore();
|
||||||
const folderDialogVisible = ref(false);
|
const saveDialogVisible = ref(false);
|
||||||
const currentResource = ref<ResourceItem | null>(null);
|
const currentResource = ref<ResourceItem | null>(null);
|
||||||
const currentFolderId = ref<string | null>(null);
|
const currentFolderId = ref<string | null>(null);
|
||||||
|
const saveDialogStep = ref<1 | 2>(1);
|
||||||
|
|
||||||
const refreshResources = async () => {
|
const refreshResources = async () => {
|
||||||
resourceStore.searchResources("", false);
|
resourceStore.searchResources("", false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const saveDialogMap = {
|
||||||
|
1: {
|
||||||
|
title: "选择资源",
|
||||||
|
buttonText: "下一步",
|
||||||
|
},
|
||||||
|
2: {
|
||||||
|
title: "选择保存目录",
|
||||||
|
buttonText: "保存",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const handleSave = (resource: ResourceItem) => {
|
const handleSave = (resource: ResourceItem) => {
|
||||||
currentResource.value = resource;
|
currentResource.value = resource;
|
||||||
folderDialogVisible.value = true;
|
saveDialogVisible.value = true;
|
||||||
|
saveDialogStep.value = 1;
|
||||||
|
resourceStore.getResourceListAndSelect(currentResource.value);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleFolderSelect = async (folderId: string) => {
|
const handleFolderSelect = async (folderId: string) => {
|
||||||
@@ -92,9 +129,21 @@ const handleFolderSelect = async (folderId: string) => {
|
|||||||
currentFolderId.value = folderId;
|
currentFolderId.value = folderId;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleConfirmClick = async () => {
|
||||||
|
if (saveDialogStep.value === 1) {
|
||||||
|
if (resourceStore.resourceSelect.length === 0) {
|
||||||
|
ElMessage.warning("请选择要保存的资源");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
saveDialogStep.value = 2;
|
||||||
|
} else {
|
||||||
|
handleSaveBtnClick();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleSaveBtnClick = async () => {
|
const handleSaveBtnClick = async () => {
|
||||||
if (!currentResource.value || !currentFolderId.value) return;
|
if (!currentResource.value || !currentFolderId.value) return;
|
||||||
folderDialogVisible.value = false;
|
saveDialogVisible.value = false;
|
||||||
await resourceStore.saveResource(currentResource.value, currentFolderId.value);
|
await resourceStore.saveResource(currentResource.value, currentFolderId.value);
|
||||||
};
|
};
|
||||||
const setDisplayStyle = (style: string) => {
|
const setDisplayStyle = (style: string) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cloud-saver",
|
"name": "cloud-saver",
|
||||||
"version": "0.1.0",
|
"version": "0.1.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"frontend",
|
"frontend",
|
||||||
|
|||||||
Reference in New Issue
Block a user