Forráskód Böngészése

调试分享之后显示保存网盘,保存到网盘调试

tanshanming 8 hónapja
szülő
commit
4ed2c713f5

+ 17 - 14
src/store/myResource.js

@@ -19,7 +19,7 @@ export const useMyResourceStore = defineStore('myResource', {
 		screenWidth: document.body.clientWidth, //  屏幕宽度
 		storageValue: 0, //  文件已占用的存储空间大小
 		totalStorageValue: 0,
-		isLogin: false, //  用户登录状态
+		isLogin: localStorage.getItem('qiwen_isLogin') === 'true', //  用户登录状态
 		userInfoObj: {} //  用户信息
 	}),
 	getters: {
@@ -79,6 +79,7 @@ export const useMyResourceStore = defineStore('myResource', {
 		 * @param {array} data 批量操作模式下,被选中的文件列表
 		 */
 		changeSelectedFiles(data) {
+			console.log('批量操作模式下,被选中的文件列表', data)
 			this.selectedFiles = data
 		},
 		/**
@@ -122,19 +123,21 @@ export const useMyResourceStore = defineStore('myResource', {
 		 * 获取用户信息
 		 */
 		async getUserInfo() {
-			try {
-				const res = await checkUserLoginInfo()
-				if (res.success) {
-					this.isLogin = true
-					this.userInfoObj = Object.assign({}, res.data.userInfoObj, data)
-				} else {
-					this.isLogin = false
-					this.userInfoObj = {}
-				}
-			} catch (error) {
-				this.isLogin = false
-				this.userInfoObj = {}
-			}
+			this.isLogin = true
+			localStorage.setItem('qiwen_isLogin', 'true')
+			// try {
+			// 	const res = await checkUserLoginInfo()
+			// 	if (res.success) {
+			// 		this.isLogin = true
+			// 		this.userInfoObj = Object.assign({}, res.data.userInfoObj, data)
+			// 	} else {
+			// 		this.isLogin = false
+			// 		this.userInfoObj = {}
+			// 	}
+			// } catch (error) {
+			// 	this.isLogin = false
+			// 	this.userInfoObj = {}
+			// }
 		}
 	}
 })

+ 3 - 1
src/views/auth/login/util.js

@@ -4,7 +4,7 @@ import dictApi from '@/api/dev/dictApi'
 import router from '@/router'
 import tool from '@/utils/tool'
 import { message } from 'ant-design-vue'
-import { useGlobalStore } from '@/store'
+import { useGlobalStore, useMyResourceStore } from '@/store'
 import routerUtil from '@/utils/routerUtil'
 
 export const afterLogin = async (loginToken) => {
@@ -14,7 +14,9 @@ export const afterLogin = async (loginToken) => {
 	// 获取登录的用户信息
 	const loginUser = await loginApi.getLoginUser()
 	const globalStore = useGlobalStore()
+	const myResourceStore = useMyResourceStore()
 	globalStore.setUserInfo(loginUser)
+	myResourceStore.getUserInfo()
 	tool.data.set('USER_INFO', loginUser)
 
 	// 获取用户的菜单

+ 1 - 1
src/views/myResource/Share.vue

@@ -67,7 +67,6 @@
 	const router = useRouter()
 	const myResourceStore = useMyResourceStore()
 	const { getIsLogin } = storeToRefs(myResourceStore)
-
 	// 文件分享对话框数据
 	const dialogShareFile = ref({
 		visible: false,
@@ -228,6 +227,7 @@
 	 * 保存到网盘按钮点击事件
 	 */
 	const handleSaveBtnClick = () => {
+		console.log('selectedFiles', selectedFiles.value)
 		if (selectedFiles.value.length) {
 			proxy.$openDialog
 				.saveShareFile({

+ 9 - 18
src/views/myResource/common/FileTable.vue

@@ -8,6 +8,7 @@
 			:loading="loading"
 			:data-source="fileList"
 			:columns="columns"
+			:row-key="(record) => record.userFileId"
 			:row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
 			:pagination="false"
 			:custom-row="customRow"
@@ -345,28 +346,13 @@
 		myResourceStore.changeIsBatchOperation(false)
 	}
 
-	// 表格选择项发生变化时的回调函数
-	// const onSelectChange = (selectedRowKeys, selectedRows) => {
-	// 	console.log('表格选择项发生变化时的回调函数', selectedRowKeys, selectedRows)
-	// 	// selectedRowKeys.value = selectedKeys
-	// 	// myResourceStore.changeSelectedFiles(selectedRows)
-	// 	// myResourceStore.changeIsBatchOperation(selectedRows.length !== 0)
-	// }
 	const onSelectChange = (changableRowKeys) => {
 		console.log('selectedRowKeys changed: ', changableRowKeys)
 		selectedRowKeys.value = changableRowKeys
-		let list = []
-		for (let i = 0; i < props.fileList.length; i++) {
-			const element = props.fileList[i]
-			for (let j = 0; j < changableRowKeys.length; j++) {
-				const element2 = changableRowKeys[j]
-				if (element.key === element2) {
-					list.push(element)
-				}
-			}
-		}
+		const list = changableRowKeys.map((id) => props.fileList.find((file) => file.userFileId === id)).filter(Boolean)
+		console.log('list', list)
 		myResourceStore.changeSelectedFiles(list)
-		myResourceStore.changeIsBatchOperation(list.length !== 0)
+		myResourceStore.changeIsBatchOperation(changableRowKeys.length !== 0)
 	}
 	// 更多图标点击事件
 	const handleClickMore = (record, event) => {
@@ -384,6 +370,11 @@
 				}
 			})
 	}
+
+	// 暴露方法给父组件
+	defineExpose({
+		clearSelectedTable
+	})
 </script>
 
 <style lang="less" scoped>

+ 201 - 78
src/views/myResource/file/dialog/saveShareFile/Dialog.vue

@@ -1,39 +1,43 @@
 <template>
+	<!-- 查看他人的分享时,保存文件到个人网盘 -->
 	<a-modal
 		title="保存文件到网盘"
-		v-model:visible="visible"
-		:maskClosable="false"
+		:visible="internalVisible"
+		:confirm-loading="sureBtnLoading"
+		@ok="handleDialogSure"
 		@cancel="handleDialogClose"
-		@afterVisibleChange="handleVisibleChange"
+		:afterClose="handleDialogClose"
+		:maskClosable="false"
 	>
-		<div class="dialog-content">
+		<div class="dialog-div-custom">
+			<!-- 选择的目标路径 -->
 			<div class="target-path">
 				<span class="label">目标路径:</span>
-				<a-input v-model:value="targetPath" readonly size="small" />
+				<a-input class="content" v-model:value="targetPath" readonly size="small"></a-input>
 			</div>
-
+			<!-- 文件目录树 -->
 			<a-spin :spinning="loading">
-				<a-directory-tree
-					:treeData="fileTree"
-					:fieldNames="{
-						children: 'children',
-						title: 'label'
-					}"
-					:defaultExpandedKeys="defaultExpandedKeys"
+				<a-tree
+					:tree-data="fileTree"
+					:field-names="{ children: 'children', title: 'label', key: 'id' }"
+					highlight-current
+					:expandedKeys="defaultExpandedKeys"
+					@update:expandedKeys="(val) => (defaultExpandedKeys = val)"
+					node-key="id"
 					@select="handleNodeClick"
+					:showLine="true"
 				>
-					<template #title="{ node, data }">
-						<div class="custom-tree-node">
-							<span class="label">{{ node.title }}</span>
-							<a-button type="link" size="small" class="add-folder-btn" @click.stop="handleAddFolderBtnClick(data)">
+					<template #title="{ dataRef }">
+						<span class="custom-tree-node">
+							<span class="label">{{ dataRef.label }}</span>
+							<a-button class="add-folder-btn" type="link" size="small" @click.stop="handleAddFolderBtnClick(dataRef)">
 								新建文件夹
 							</a-button>
-						</div>
+						</span>
 					</template>
-				</a-directory-tree>
+				</a-tree>
 			</a-spin>
 		</div>
-
 		<template #footer>
 			<a-button @click="handleDialogClose">取 消</a-button>
 			<a-button type="primary" :loading="sureBtnLoading" @click="handleDialogSure"> 确 定 </a-button>
@@ -42,65 +46,124 @@
 </template>
 
 <script setup>
-	import { ref } from 'vue'
-	import { message } from 'ant-design-vue'
+	import { ref, getCurrentInstance, watch } from 'vue'
 	import { getFoldTree, saveShareFile } from '@/api/myResource/file'
+	import { message } from 'ant-design-vue'
 	const { proxy } = getCurrentInstance()
+
 	const props = defineProps({
-		userFileIds: String,
-		shareBatchNum: String,
+		visible: {
+			type: Boolean,
+			default: false
+		},
+		userFileIds: {
+			type: String,
+			default: ''
+		},
+		shareBatchNum: {
+			type: String,
+			default: ''
+		},
 		callback: Function
 	})
 
-	const visible = ref(false)
-	const targetPath = ref('/')
-	const fileTree = ref([])
-	const loading = ref(false)
+	const emit = defineEmits(['update:visible'])
+	const internalVisible = ref(props.visible) // 使用 internalVisible 作为主要的响应式状态
+	const targetPath = ref('/') //  目标路径
+	const fileTree = ref([]) //  文件夹目录树
+	const loading = ref(false) //  文件夹目录树 loading 状态
 	const defaultExpandedKeys = ref([])
-	const sureBtnLoading = ref(false)
+	const sureBtnLoading = ref(false) //  确定按钮 loading 状态
 
+	watch(
+		internalVisible, // 监听内部的 internalVisible ref
+		(newVal, oldVal) => {
+			if (newVal && !oldVal) {
+				// 仅在从 false 变为 true 时调用,即对话框打开时
+				handleDialogOpen()
+			}
+		}
+	)
+
+	// 如果父组件通过 prop 更新 visible,也需要同步到 internalVisible
+	watch(
+		() => props.visible,
+		(newVal) => {
+			internalVisible.value = newVal
+		}
+	)
+
+	/**
+	 * 取消按钮点击事件 & 对话框关闭的回调
+	 */
 	const handleDialogClose = () => {
-		visible.value = false
+		internalVisible.value = false
+		emit('update:visible', false) // 如果父组件需要 .sync 修饰符或者 v-model:visible
 		props.callback('cancel')
 	}
 
-	const handleVisibleChange = (val) => {
-		if (val) {
-			initFileTree()
-		}
+	/**
+	 * 对话框打开的回调
+	 */
+	const handleDialogOpen = () => {
+		initFileTree()
+		targetPath.value = '/' // 重置目标路径
 	}
 
+	/**
+	 * 初始化文件目录树
+	 */
 	const initFileTree = async (id) => {
+		loading.value = true
 		try {
-			loading.value = true
 			const res = await getFoldTree()
 			if (res.success) {
 				fileTree.value = [res.data]
-				defaultExpandedKeys.value = id ? [id] : [fileTree.value[0].id]
+				defaultExpandedKeys.value = id ? [id] : fileTree.value.length > 0 ? [fileTree.value[0].id] : []
 			} else {
 				message.error(res.message)
 			}
+		} catch (error) {
+			message.error('获取文件夹树失败')
+			console.error(error)
 		} finally {
 			loading.value = false
 		}
 	}
 
-	const handleNodeClick = (selectedKeys, { node }) => {
-		targetPath.value = node.filePath || '/'
+	/**
+	 * 目录树节点点击回调函数
+	 * @param {Array} selectedKeys 当前选中的节点的 key
+	 * @param {object} e event 对象,包含 {selected: bool, selectedNodes, node, event}
+	 */
+	const handleNodeClick = (selectedKeys, e) => {
+		if (e.node && e.node.dataRef) {
+			targetPath.value = e.node.dataRef.filePath ? e.node.dataRef.filePath : '/'
+		}
 	}
 
+	/**
+	 * 新建文件夹按钮点击事件
+	 * @description 调用新建文件夹服务,并在弹窗确认回调事件中刷新文件夹树
+	 */
 	const handleAddFolderBtnClick = async (data) => {
-		const result = await proxy.$openDialog.addFolder({
-			filePath: data.filePath || '/'
-		})
-		if (result === 'confirm') {
+		try {
+			await proxy.$openDialog.addFolder({
+				filePath: data.filePath || '/'
+			})
 			initFileTree(data.id)
+		} catch (error) {
+			console.log('Add folder cancelled or failed', error)
 		}
 	}
 
+	/**
+	 * 确定按钮点击事件
+	 * @description 调用保存分享文件接口
+	 */
 	const handleDialogSure = async () => {
+		sureBtnLoading.value = true
 		try {
-			sureBtnLoading.value = true
 			const res = await saveShareFile({
 				filePath: targetPath.value,
 				userFileIds: props.userFileIds,
@@ -108,19 +171,24 @@
 			})
 
 			if (res.success) {
-				visible.value = false
 				message.success('保存成功')
+				internalVisible.value = false
+				emit('update:visible', false)
 				props.callback('confirm')
 			} else {
 				message.error(res.message)
 			}
+		} catch (error) {
+			message.error('保存文件失败')
+			console.error(error)
 		} finally {
 			sureBtnLoading.value = false
 		}
 	}
 
+	// 暴露给模板或者父组件(如果需要ref访问)
 	defineExpose({
-		visible
+		visible: internalVisible // 暴露 internalVisible
 	})
 </script>
 
@@ -128,50 +196,105 @@
 	@import '@/style/myResource/varibles.less';
 	@import '@/style/myResource/mixins.less';
 
-	.dialog-content {
-		height: 300px;
-		overflow: auto;
+	// 使用 :deep 替代 >>>
+	:deep(.ant-modal) {
+		.ant-modal-header {
+			display: flex; // antd 默认就是 flex,可能不需要
+		}
 
-		.target-path {
-			display: flex;
-			align-items: center;
-			margin-bottom: 16px;
+		.ant-modal-body {
+			padding: 10px 30px;
 
-			.label {
-				width: 80px;
-			}
+			.dialog-div-custom {
+				// 修改类名以避免与 antd 内部类名冲突
+				height: 300px;
+				overflow: auto;
+				&::-webkit-scrollbar {
+					width: 6px;
+				}
+				&::-webkit-scrollbar-thumb {
+					background: #ccc; // 滚动条颜色
+					border-radius: 3px;
+				}
+				&::-webkit-scrollbar-track {
+					background: #f1f1f1; // 轨道颜色
+				}
 
-			.ant-input {
-				flex: 1;
-			}
-		}
+				.target-path {
+					display: flex;
+					align-items: center;
+					margin-bottom: 10px; // 增加一些间距
 
-		.custom-tree-node {
-			width: 100%;
-			display: flex;
-			align-items: center;
-			justify-content: space-between;
+					.label {
+						width: 80px;
+						flex-shrink: 0; // 防止被压缩
+					}
 
-			.add-folder-btn {
-				display: none;
-			}
+					.content {
+						flex: 1;
+					}
+				}
+
+				.ant-tree {
+					.ant-tree-treenode {
+						width: 100%;
+						// antd v4+ 使用 .ant-tree-treenode
+						.ant-tree-node-content-wrapper {
+							height: 34px;
+							font-size: 16px;
+							display: flex; // 确保自定义内容能正确布局
+							align-items: center;
+						}
+						&:hover {
+							.add-folder-btn {
+								display: inline-block; // 或者 block,取决于布局需求
+							}
+						}
 
-			&:hover .add-folder-btn {
-				display: inline-block;
+						.ant-tree-switcher .ant-tree-switcher-icon svg {
+							font-size: 18px; // 调整展开/折叠图标大小
+						}
+
+						.custom-tree-node {
+							flex: 1;
+							display: flex;
+							align-items: center;
+							justify-content: space-between;
+							font-size: 14px;
+							padding-right: 8px;
+
+							.add-folder-btn {
+								color: #000000;
+								display: none; // 默认隐藏
+								margin-left: 8px; // 给按钮一些左边距
+							}
+						}
+					}
+				}
 			}
 		}
 	}
+	:deep(.ant-tree .ant-tree-treenode .custom-tree-node) {
+		display: flex;
+		justify-content: space-between;
+		width: 100%;
+	}
 
-	.ant-btn-primary {
-		&,
-		&:hover,
-		&:focus {
-			background-color: @primary-color;
-			border-color: @primary-color;
-		}
+	:deep(.ant-tree .ant-tree-treenode:hover .custom-tree-node .add-folder-btn) {
+		color: #29175b !important;
+		display: inline-block !important;
 	}
 
-	.ant-tree-node-selected {
-		// background-color: .fade(@primary-color, 10%) !important;
+	:deep(.ant-tree .ant-tree-treenode .custom-tree-node .add-folder-btn) {
+		color: #000000;
+		display: none !important;
+		margin-left: 8px;
+	}
+	:deep(.ant-tree) {
+		.ant-tree-treenode,
+		.ant-tree-node-content-wrapper,
+		.ant-tree-title {
+			width: 100%;
+		}
 	}
 </style>