Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27ce78597b | ||
|
|
2f40b4f03b |
No files matched your search
+20
-4
@@ -42,6 +42,23 @@ const deleteView = (index: number) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 若存在两个以上标签页可见则除点击的标签页以外其他全部隐藏,若只有一个标签页可见则全部展示
|
||||||
|
// 这个逻辑以后再研究吧,平时感觉用不到
|
||||||
|
const handleClickTitle = (index: number) => {
|
||||||
|
let count = views.filter(v=>v.visible).length
|
||||||
|
let _index = 0
|
||||||
|
while(_index < views.length) {
|
||||||
|
if(_index !== index) {
|
||||||
|
views[_index].visible = count > 1 ? false : true
|
||||||
|
}else {
|
||||||
|
views[_index].visible = true
|
||||||
|
}
|
||||||
|
_index += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 顶部菜单相关
|
||||||
function renderIcon(icon: any) {
|
function renderIcon(icon: any) {
|
||||||
return () => {
|
return () => {
|
||||||
return h(NIcon, null, {
|
return h(NIcon, null, {
|
||||||
@@ -66,7 +83,7 @@ const handleMenuSelect = (key: string) => {
|
|||||||
component: NQrCode,
|
component: NQrCode,
|
||||||
props: {
|
props: {
|
||||||
value: baseUrl,
|
value: baseUrl,
|
||||||
size: 500,
|
size: 300,
|
||||||
errorCorrectionLevel: 'H'
|
errorCorrectionLevel: 'H'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,8 +93,6 @@ const handleMenuSelect = (key: string) => {
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
createView(rootDirectory)
|
createView(rootDirectory)
|
||||||
})
|
})
|
||||||
|
|
||||||
// todo: 让所有伪页面共享一个rootDirectory
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -86,7 +101,7 @@ onMounted(() => {
|
|||||||
<n-scrollbar x-scrollable>
|
<n-scrollbar x-scrollable>
|
||||||
<div class="tags-container">
|
<div class="tags-container">
|
||||||
<div class="tag" v-for="(view, index) of views" :key="view.uid">
|
<div class="tag" v-for="(view, index) of views" :key="view.uid">
|
||||||
<div class="tag-title">{{ view.title }}</div>
|
<div class="tag-title" @click="handleClickTitle(index)">{{ view.title }}</div>
|
||||||
<div class="tag-point" :style="{ backgroundColor: view.color } "></div>
|
<div class="tag-point" :style="{ backgroundColor: view.color } "></div>
|
||||||
<div class="tag-control">
|
<div class="tag-control">
|
||||||
<n-icon class="tag-control-icon icon" @click="view.switchShow()">
|
<n-icon class="tag-control-icon icon" @click="view.switchShow()">
|
||||||
@@ -156,6 +171,7 @@ $controler-height: 25px;
|
|||||||
margin-left: 4px;
|
margin-left: 4px;
|
||||||
// width: 70%;
|
// width: 70%;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag-point {
|
.tag-point {
|
||||||
|
|||||||
@@ -41,15 +41,15 @@ export class UploadQueueItem {
|
|||||||
if (this.status === "uploading") {
|
if (this.status === "uploading") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { abort, status } = miaoFetchApi.upload(this.file, this.targetDirectory, {
|
const { abort, response } = miaoFetchApi.upload(this.file, this.targetDirectory, {
|
||||||
onProcess: percent => {
|
onProcess: percent => {
|
||||||
this.process = percent;
|
this.process = percent;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this._abort = abort;
|
this._abort = abort;
|
||||||
this._status = status;
|
this._status = response;
|
||||||
this.status = "uploading";
|
this.status = "uploading";
|
||||||
status
|
response
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.status = "success";
|
this.status = "success";
|
||||||
this.onSuccess && this.onSuccess();
|
this.onSuccess && this.onSuccess();
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ const dataBus = useDataBus()
|
|||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
download: []
|
download: []
|
||||||
|
delete: []
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -65,9 +66,12 @@ const dropDownOptions = computed(()=> {
|
|||||||
return options
|
return options
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleDropdownSelect = (key: 'download') => {
|
const handleDropdownSelect = (key: 'download' | 'delete') => {
|
||||||
console.log(key)
|
if(key === 'download'){
|
||||||
emit(key)
|
emit('download')
|
||||||
|
} else if (key === 'delete') {
|
||||||
|
emit('delete')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Icon = computed(()=>{
|
const Icon = computed(()=>{
|
||||||
@@ -112,7 +116,7 @@ const handleDragStart = () => {
|
|||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.miao-item {
|
.miao-item {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: calc(100% - 16px);
|
width: calc(100% - 20px);
|
||||||
min-width: 250px;
|
min-width: 250px;
|
||||||
// aspect-ratio: 66/9;
|
// aspect-ratio: 66/9;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
@@ -120,7 +124,7 @@ const handleDragStart = () => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin: 10px 8px;
|
margin: 10px 10px;
|
||||||
.item-main {
|
.item-main {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
+3
-1
@@ -5,7 +5,9 @@ export default {
|
|||||||
uploadSizeLimit: 1024 * 1024 * 100,
|
uploadSizeLimit: 1024 * 1024 * 100,
|
||||||
api: {
|
api: {
|
||||||
get: '/get',
|
get: '/get',
|
||||||
upload: '/upload'
|
upload: '/upload',
|
||||||
|
delete: '/delete',
|
||||||
|
query: '/query'
|
||||||
},
|
},
|
||||||
enableUpload: true,
|
enableUpload: true,
|
||||||
};
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import VirtualDirectory from "@/class/VirtualDirectory";
|
import VirtualDirectory, { VirtualFile } from "@/class/VirtualDirectory";
|
||||||
import { getOption, getResponse, miaoFetchConfig, uploadOption } from "@/types/fetch";
|
import { getOption, getResponse, miaoFetchConfig, deleteOption, uploadOption, queryOption } from "@/types/fetch";
|
||||||
import Config from "@/config";
|
import Config from "@/config";
|
||||||
import axios, { AxiosRequestConfig } from "axios";
|
import axios, { AxiosRequestConfig } from "axios";
|
||||||
|
|
||||||
@@ -55,36 +55,92 @@ const miaoFetchApi = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 上传单个文件到对应文件夹
|
* 上传单个文件到对应文件夹, 后续要将data类型改成buffer以支持分片上传
|
||||||
*/
|
*/
|
||||||
upload(file: File, targetVDir: VirtualDirectory, option?: uploadOption) {
|
upload(data: File, targetVDir: VirtualDirectory, option?: uploadOption) {
|
||||||
const { baseUrl, api } = Config;
|
const { baseUrl, api } = Config;
|
||||||
const url = `${baseUrl}${api.upload}${targetVDir.path}`;
|
const url = `${baseUrl}${api.upload}${targetVDir.path}`;
|
||||||
const retry = option?.retry ?? 0;
|
const retry = option?.retry ?? 0;
|
||||||
const { miaoFetch, abortMiaoFetch } = useMiaoFetch({
|
const { miaoFetch, abortMiaoFetch } = useMiaoFetch({
|
||||||
retry
|
retry
|
||||||
});
|
});
|
||||||
const sizeTotal = file.size
|
const sizeTotal = data.size;
|
||||||
|
|
||||||
const opType = option?.type ?? 'write'
|
const opType = option?.type ?? "write";
|
||||||
|
|
||||||
const data = new FormData()
|
const formData = new FormData();
|
||||||
|
|
||||||
data.append('file', file)
|
formData.append("file", data);
|
||||||
data.append('oprateType', opType)
|
// 必须这样传,不然中文乱码
|
||||||
|
formData.append("fileName", data.name)
|
||||||
|
formData.append("oprateType", opType);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
abort: () => abortMiaoFetch(),
|
abort: () => abortMiaoFetch(),
|
||||||
status: new Promise(async (resolve)=>{
|
response: new Promise<{
|
||||||
|
message: 'success' | 'failed'
|
||||||
|
error?: string
|
||||||
|
}>(async resolve => {
|
||||||
const response = await miaoFetch({
|
const response = await miaoFetch({
|
||||||
url,
|
url,
|
||||||
method: 'post',
|
method: "post",
|
||||||
data: data,
|
data: formData,
|
||||||
onUploadProgress(progressEvent) {
|
onUploadProgress(progressEvent) {
|
||||||
option && option.onProcess && option.onProcess(progressEvent.loaded / sizeTotal)
|
option && option.onProcess && option.onProcess(progressEvent.loaded / sizeTotal);
|
||||||
},
|
}
|
||||||
|
});
|
||||||
|
resolve(response.data);
|
||||||
})
|
})
|
||||||
resolve(response.data)
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除对应的文件或文件夹,若为文件夹会递归删除
|
||||||
|
*/
|
||||||
|
delete(target: VirtualFile | VirtualDirectory, option?: deleteOption) {
|
||||||
|
const { baseUrl, api } = Config;
|
||||||
|
const url = `${baseUrl}${api.delete}${target.path}`;
|
||||||
|
const retry = option?.retry ?? 0;
|
||||||
|
const { miaoFetch } = useMiaoFetch({
|
||||||
|
retry
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
response: new Promise<{
|
||||||
|
eventId: number
|
||||||
|
}>(async resolve => {
|
||||||
|
const response = await miaoFetch({
|
||||||
|
url,
|
||||||
|
method: "post"
|
||||||
|
});
|
||||||
|
resolve(response.data);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询服务端操作事件的进展
|
||||||
|
*/
|
||||||
|
query(eventId: number, option?: queryOption) {
|
||||||
|
const { baseUrl, api } = Config;
|
||||||
|
const url = `${baseUrl}${api.query}`;
|
||||||
|
const retry = option?.retry ?? 0;
|
||||||
|
const { miaoFetch } = useMiaoFetch({
|
||||||
|
retry
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
response: new Promise<{
|
||||||
|
status: 'process' | 'success' | 'failed',
|
||||||
|
error?: unknown
|
||||||
|
}>(async resolve => {
|
||||||
|
const response = await miaoFetch({
|
||||||
|
url,
|
||||||
|
method: "get",
|
||||||
|
params: {
|
||||||
|
id: eventId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
resolve(response.data);
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,3 +22,8 @@ export type uploadOption = {
|
|||||||
*/
|
*/
|
||||||
type?: 'write' | 'append'
|
type?: 'write' | 'append'
|
||||||
} & miaoFetchConfig
|
} & miaoFetchConfig
|
||||||
|
|
||||||
|
export type deleteOption = {
|
||||||
|
} & miaoFetchConfig
|
||||||
|
export type queryOption = {
|
||||||
|
} & miaoFetchConfig
|
||||||
+34
-14
@@ -32,13 +32,21 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="container-items" :style="{ backgroundColor: props.index % 2 === 0 ? '#f8f8f8' : 'rgb(240 240 240)' }">
|
<div class="container-items" :style="{ backgroundColor: props.index % 2 === 0 ? '#f8f8f8' : 'rgb(240 240 240)' }">
|
||||||
<n-scrollbar>
|
<n-scrollbar>
|
||||||
<miaoDirectoryItem v-for="(dir) in currentDirectory?.directorys" @click="setCurrentDirectory(dir)" :item="dir" :key="dir.uid" :color="props.color" />
|
|
||||||
<miaoDirectoryItem
|
<miaoDirectoryItem
|
||||||
v-for="(file) in currentDirectory?.files"
|
v-for="(dir) in showData_directory"
|
||||||
|
@click="setCurrentDirectory(dir)"
|
||||||
|
:item="dir"
|
||||||
|
:key="dir.uid"
|
||||||
|
:color="props.color"
|
||||||
|
@delete="handleItemDelete(dir)"
|
||||||
|
/>
|
||||||
|
<miaoDirectoryItem
|
||||||
|
v-for="(file) in showData_files"
|
||||||
:item="file"
|
:item="file"
|
||||||
:key="file.uid"
|
:key="file.uid"
|
||||||
@click="openUrl(`${baseUrl}${api.get}${file.path}`)"
|
@click="openUrl(`${baseUrl}${api.get}${file.path}`)"
|
||||||
@download="openUrl(`${baseUrl}${api.get}${file.path}`, {download: file.name})"
|
@download="openUrl(`${baseUrl}${api.get}${file.path}`, {download: file.name})"
|
||||||
|
@delete="handleItemDelete(file)"
|
||||||
:color="props.color"
|
:color="props.color"
|
||||||
/>
|
/>
|
||||||
</n-scrollbar>
|
</n-scrollbar>
|
||||||
@@ -51,8 +59,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { NBreadcrumbItem, NBreadcrumb, NIcon, NScrollbar } from 'naive-ui'
|
import { NBreadcrumbItem, NBreadcrumb, NIcon, NScrollbar } from 'naive-ui'
|
||||||
import type { file, directory } from '@/types/type.ts'
|
import type { file, directory } from '@/types/type.ts'
|
||||||
import VirtualDirectory from '@/class/VirtualDirectory';
|
import VirtualDirectory, { VirtualFile } from '@/class/VirtualDirectory';
|
||||||
import { onMounted, ref } from 'vue';
|
import { computed, onMounted, ref } from 'vue';
|
||||||
import Config from '@/config'
|
import Config from '@/config'
|
||||||
import dropHandler, { dropHandlerHooks } from '@/hooks/dropHandler';
|
import dropHandler, { dropHandlerHooks } from '@/hooks/dropHandler';
|
||||||
import miaoMask from '@/components/miaoMask.vue';
|
import miaoMask from '@/components/miaoMask.vue';
|
||||||
@@ -75,12 +83,21 @@ const props = defineProps<{
|
|||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
exit: []
|
exit: []
|
||||||
}>()
|
}>()
|
||||||
|
// 是否显示模态框
|
||||||
|
const showModel = ref(0)
|
||||||
|
|
||||||
// 目前展示的Dir
|
// 目前展示的Dir
|
||||||
const currentDirectory = defineModel<VirtualDirectory | undefined>('currentDirectory', { required: true })
|
const currentDirectory = defineModel<VirtualDirectory | undefined>('currentDirectory', { required: true })
|
||||||
|
|
||||||
// 是否显示模态框
|
// 用于展示的数据,后续会增加排序等操作
|
||||||
const showModel = ref(0)
|
const showData_directory = computed<VirtualDirectory[]>(() => {
|
||||||
|
const data = currentDirectory.value?.directorys ? [...currentDirectory.value?.directorys ] : []
|
||||||
|
return data
|
||||||
|
})
|
||||||
|
const showData_files = computed<VirtualFile[]>(() => {
|
||||||
|
const data = currentDirectory.value?.files ? [...currentDirectory.value?.files ] : []
|
||||||
|
return data
|
||||||
|
})
|
||||||
|
|
||||||
// 用于监听拖拽文件事件
|
// 用于监听拖拽文件事件
|
||||||
const rootDomRef = ref<HTMLDivElement>()
|
const rootDomRef = ref<HTMLDivElement>()
|
||||||
@@ -123,12 +140,6 @@ const openUrl = (href: string, config?: {
|
|||||||
a.setAttribute('target', target ?? '_blank')
|
a.setAttribute('target', target ?? '_blank')
|
||||||
download && a.setAttribute('download', download);
|
download && a.setAttribute('download', download);
|
||||||
a.click();
|
a.click();
|
||||||
// var a = document.createElement("a");
|
|
||||||
// a.setAttribute('href', href)
|
|
||||||
// a.setAttribute('target', target ?? '_blank')
|
|
||||||
// a.setAttribute('download', download ?? '')
|
|
||||||
// console.log({target, download})
|
|
||||||
// a.click();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
@@ -141,6 +152,17 @@ const handleReload = () => {
|
|||||||
reload()
|
reload()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleItemDelete = async (item: VirtualDirectory | VirtualFile) => {
|
||||||
|
const {response} = miaoFetchApi.delete(item)
|
||||||
|
// todo: 将删除事件统一用一个事件管理中心管理
|
||||||
|
const id = (await response).eventId
|
||||||
|
const {response : res} = miaoFetchApi.query(id)
|
||||||
|
const eventResult = await res
|
||||||
|
if(eventResult.status === 'success'){
|
||||||
|
reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
currentDirectory.value && await setCurrentDirectory(currentDirectory.value)
|
currentDirectory.value && await setCurrentDirectory(currentDirectory.value)
|
||||||
// 拖动事件处理
|
// 拖动事件处理
|
||||||
@@ -154,8 +176,6 @@ onMounted(async () => {
|
|||||||
reload()
|
reload()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
const _f = files[0]
|
|
||||||
currentDirectory.value && miaoFetchApi.upload(_f, currentDirectory.value)
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onEnter() {
|
onEnter() {
|
||||||
|
|||||||
+12
-1
@@ -23,7 +23,18 @@ export default defineConfig({
|
|||||||
target: "http://127.0.0.1:17705",
|
target: "http://127.0.0.1:17705",
|
||||||
changeOrigin: true,
|
changeOrigin: true,
|
||||||
rewrite: path => path.replace(/^\/upload/, "/upload")
|
rewrite: path => path.replace(/^\/upload/, "/upload")
|
||||||
}
|
},
|
||||||
|
|
||||||
|
"/delete": {
|
||||||
|
target: "http://127.0.0.1:17705",
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: path => path.replace(/^\/delete/, "/delete")
|
||||||
|
},
|
||||||
|
"/query": {
|
||||||
|
target: "http://127.0.0.1:17705",
|
||||||
|
changeOrigin: true,
|
||||||
|
rewrite: path => path.replace(/^\/query/, "/query")
|
||||||
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
build: {
|
build: {
|
||||||
|
|||||||
Reference in new issue
Block a user