| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- <script setup xmlns="http://www.w3.org/1999/html">
- import {onMounted, ref} from "vue";
- import {
- Back,
- Delete,
- DocumentCopy,
- Download,
- FolderAdd,
- FolderChecked,
- FolderDelete,
- Hide,
- Search,
- Upload,
- View
- } from '@element-plus/icons-vue'
- import axios from "axios";
- import useClipboard from 'vue-clipboard3';
- import {ElMessage, ElMessageBox, ElNotification} from "element-plus";
- import {md5} from "js-md5";
- let searchIn = ref("")
- let inW = ref(window.innerWidth)
- let menuList = ref([])
- let loading = ref(true)
- let filePath = ref("")
- let uploadVisible = ref(false)
- let openViewVisible = ref(false)
- const tableData = ref([])
- let uploadData = ref({})
- let title = ref("HTTP文件服务器")
- let isUpload = ref(false)
- let isDelete = ref(false)
- let isMkdir = ref(false)
- let showHidden = ref()
- let showDirSize = ref()
- let proxy = ref("/api")
- let sp = ref(18)
- const upload = ref()
- onMounted(() => {
- base(true)
- console.log(inW.value)
- if (inW.value <= 1500) {
- sp.value = 20
- }
- if (inW.value <= 1300) {
- sp.value = 22
- }
- if (inW.value <= 1300) {
- sp.value = 23
- }
- })
- const query = () => {
- tableData.value = null
- loading.value = true
- axios.get(proxy.value + '/query', {
- params: {
- showHidden: showHidden.value,
- showDirSize: showDirSize.value,
- filePath: filePath.value
- }
- }).then(rep => {
- let code = rep.data.code;
- if (code == "1") {
- tableData.value = rep.data.data
- loading.value = false
- return;
- }
- if (code == "-3") {
- setCookie(true, () => {
- ElMessage.error(rep.data.err)
- })
- return
- }
- ElMessage.error(rep.data.err)
- })
- }
- const base = () => {
- axios.get(proxy.value + '/base').then(rep => {
- let code = rep.data.code;
- if (code == "1") {
- title.value = rep.data.data.title
- isUpload.value = rep.data.data.isUpload
- isDelete.value = rep.data.data.isDelete
- isMkdir.value = rep.data.data.isMkdir
- showHidden.value = rep.data.data.showHidden
- showDirSize.value = rep.data.data.showDirSize
- query();
- return
- }
- if (code == "-3") {
- setCookie(true, () => {
- ElMessage.error(rep.data.err)
- })
- return
- }
- ElMessage.error(rep.data.err)
- })
- }
- const setCookie = (tag, callback) => {
- ElMessageBox.prompt('请输入验证密码! ', '验证', {
- type: 'warning',
- confirmButtonText: '确认',
- cancelButtonText: '取消'
- }).then(({value}) => {
- axios.get(proxy.value + '/setCookie', {
- params: {
- password: md5(value)
- }
- }).then(rep => {
- if (rep.data.code == "1") {
- ElMessage.success("验证通过!")
- localStorage.setItem("authCode", md5(value + rep.data.data).substring(0, 8))
- base()
- return
- }
- ElMessageBox.close()
- setCookie(true, () => {
- ElMessage.error(rep.data.err)
- })
- })
- }).catch(() => {
- ElMessageBox.close()
- setCookie(true, () => {
- ElMessage.error("请输入验证密码进行验证!")
- })
- })
- if (tag) {
- callback()
- }
- }
- const openFileOrDir = (row) => {
- if (row.type == 'dir') {
- menuList.value.push(row.name)
- filePath.value = row.path + "/" + row.name
- query()
- } else {
- console.log(111)
- openViewVisible.value = true;
- // TODO 打开相应文件的弹窗
- }
- }
- const back = () => {
- menuList.value.pop();
- filePath.value = filePath.value.substring(0, filePath.value.lastIndexOf("/"))
- query()
- }
- const openUpload = () => {
- uploadVisible.value = true
- uploadData = {
- filePath: filePath.value
- }
- }
- const download = (row) => {
- let authCode = localStorage.getItem("authCode")
- if (row.type == "dir") {
- window.open(proxy.value + "/download/" + authCode + "/" + row.path + "/pkgDir_" + row.name + ".zip", "_self");
- ElNotification.success({
- title: '成功!',
- message: '文件打包中,打包完毕会自动开启下载!',
- })
- return
- }
- window.location.href = proxy.value + "/download/" + authCode + row.path + "/" + row.name
- }
- const copyUrl = (row) => {
- const baseUrl = window.location.href
- let authCode = localStorage.getItem("authCode")
- let url = baseUrl + proxy.value + "/download/" + authCode + "/" + row.name
- if (row.type == "dir") {
- url = baseUrl + proxy.value + "/download/" + authCode + "/" + row.path + "/" + "pkgDir_" + row.name + ".zip"
- }
- useClipboard().toClipboard(url.replaceAll("//", "/"))
- ElMessageBox.alert(
- '链接已复制到剪贴板!',
- '复制成功!',
- {
- type: "success",
- confirmButtonText: '关闭',
- }
- )
- }
- const formatType = (row, column, cellValue) => {
- let result = ""
- switch (cellValue) {
- case "folder":
- result = "文件夹"
- break
- case "rar":
- case "zip":
- case "7z":
- case "gz":
- case "tar":
- result = "压缩文件"
- break
- case "md":
- result = "MarkDown 文件"
- break
- case "":
- result = "其他文件"
- break
- default:
- result = cellValue + " 文件"
- }
- return result
- }
- const clear = () => {
- uploadVisible.value = false
- upload.value.clearFiles()
- }
- const remove = (row) => {
- ElMessageBox.confirm(
- '确认删除文件?',
- '警告',
- {
- confirmButtonText: '确认',
- cancelButtonText: '取消',
- type: 'warning',
- }
- ).then(() => {
- axios.get(proxy.value + '/delete', {
- params: {
- fileName: row.name,
- filePath: row.path
- }
- }).then(rep => {
- let code = rep.data.code
- if (code == "1") {
- ElMessage.success("删除成功!")
- query()
- return
- }
- if (code == "-3") {
- setCookie(true, () => {
- ElMessage.error(rep.data.err)
- })
- return
- }
- ElMessage.error("删除失败, " + rep.data.err)
- })
- }).catch(() => {
- ElMessage.info("操作已取消!")
- })
- }
- const createDir = () => {
- ElMessageBox.prompt('请输入要创建的文件夹名', '创建文件夹', {
- confirmButtonText: '确认',
- cancelButtonText: '取消'
- }).then(({value}) => {
- axios.get(proxy.value + '/createDir', {
- params: {
- dirPath: filePath.value + "/" + value
- }
- }).then(rep => {
- let code = rep.data.code
- if (code == "1") {
- ElMessage.success("目录已创建!")
- query()
- return
- }
- if (code == "-3") {
- setCookie(true, () => {
- ElMessage.error(rep.data.err)
- })
- return
- }
- ElMessage.error("目录创建失败, " + rep.data.err)
- })
- }).catch(() => {
- ElMessage.info("操作已取消!")
- })
- }
- const allDownload = () => {
- const row = {}
- row.type = "dir"
- console.log(filePath.value.indexOf("/"))
- row.name = ""
- row.path = ""
- if (menuList.value.length > 0) {
- row.path = filePath.value.replaceAll("/" + menuList.value[menuList.value.length - 1], "")
- row.name = menuList.value[menuList.value.length - 1]
- }
- download(row)
- }
- </script>
- <template>
- <el-row justify="center">
- <el-col :span="sp"
- style="padding: 10px;display: flex;justify-content: space-between;align-items: center;">
- <div style="display: flex;align-items: center;">
- <el-image style="width: 25px;vertical-align: sub" src="/file_ico.svg"></el-image>
- <span v-if="inW >= 400" style="font-size: 25px;">{{ title }}</span>
- </div>
- <div style="display: flex;align-items: center;">
- <el-image style="width: 25px;height: 25px;margin-right: 5px" src="/qr_code_ico.svg" @click="ac"></el-image>
- <el-input
- v-model="searchIn"
- style="width: 240px"
- placeholder="请输入文件名"
- :suffix-icon="Search"
- />
- </div>
- </el-col>
- <el-col :span="sp" style="padding:10px;">
- <el-card shadow="never" style="border-radius: 10px">
- <el-breadcrumb separator="/" style="margin: 10px 0">
- <el-breadcrumb-item :to="{ path: '/' }">
- <el-icon>
- <HomeFilled/>
- </el-icon>
- </el-breadcrumb-item>
- <el-breadcrumb-item v-for="i in menuList">{{ i }}</el-breadcrumb-item>
- </el-breadcrumb>
- <div style="display: flex;align-items: center;justify-content: space-between;">
- <div>
- <el-button type="primary" :icon="Back" @click="back">返回上层</el-button>
- <el-button type="info" :icon="Download" @click="allDownload">全部下载</el-button>
- <el-button type="warning" :icon="Upload" @click="openUpload" v-if="isUpload">上传文件</el-button>
- <el-button type="success" :icon="FolderAdd" @click="createDir" v-if="isMkdir">创建目录</el-button>
- </div>
- <div>
- <el-switch
- v-model="showHidden"
- size="large"
- :active-action-icon="View"
- :inactive-action-icon="Hide"
- style="--el-switch-on-color: #13ce66; --el-switch-off-color: #D4D7DE;margin: 5px"
- @change="query"
- />
- <el-switch
- v-model="showDirSize"
- size="large"
- :active-action-icon="FolderChecked"
- :inactive-action-icon="FolderDelete"
- style="--el-switch-on-color: #13ce66; --el-switch-off-color: #D4D7DE; margin: 5px"
- @change="query"
- />
- </div>
- </div>
- </el-card>
- </el-col>
- <el-col :span="sp" style="padding: 10px;height:40%;">
- <el-table :data="tableData" v-loading="loading" border style="width: 100%;border-radius: 15px"
- @row-click="openFileOrDir">
- <el-table-column prop="type" width="80px" align="center" label="类型">
- <template #default="scope">
- <el-icon v-if="scope.row.type == 'file'">
- <Files/>
- </el-icon>
- <el-icon v-if="scope.row.type == 'dir'">
- <Folder/>
- </el-icon>
- </template>
- </el-table-column>
- <el-table-column prop="name" header-align="center" label="名称"/>
- <el-table-column prop="size" align="center" width="100px" label="大小"/>
- <el-table-column prop="fileType" align="center" width="150px" label="文件类型" :formatter="formatType"/>
- <el-table-column prop="modified" align="center" width="300px" label="修改时间"/>
- <el-table-column align="center" @click.stop width="200px" label="操作">
- <template #default="scope">
- <el-tooltip content="复制链接地址" placement="top" show-after="3000">
- <el-button type="primary" :icon="DocumentCopy" circle @click.stop="copyUrl(scope.row)"/>
- </el-tooltip>
- <el-tooltip content="下载文件" placement="top" show-after="1000">
- <el-button v-if="scope.row.type == 'file'" type="info" :icon="Download"
- @click.stop="download(scope.row)"
- circle/>
- </el-tooltip>
- <el-tooltip content="打包下载文件夹" placement="top" show-after="3000">
- <el-button v-if="scope.row.type == 'dir'" type="info" :icon="Download" circle
- @click.stop="download(scope.row)"/>
- </el-tooltip>
- <el-tooltip v-if="isDelete" content="删除" placement="top" show-after="3000">
- <el-button type="danger" :icon="Delete" circle @click.stop="remove(scope.row)"/>
- </el-tooltip>
- </template>
- </el-table-column>
- </el-table>
- </el-col>
- <el-backtop :right="100" :bottom="100"/>
- <el-dialog
- v-model="openViewVisible"
- title="Tips"
- width="80vw"
- top="5vh"
- >
- <iframe src="https://www.baidu.com" width="100%" height="670px" frameborder="0"></iframe>
- <template #footer>
- <div class="dialog-footer">
- <el-button @click="openViewVisible = false">Cancel</el-button>
- <el-button type="primary" @click="openViewVisible = false">
- Confirm
- </el-button>
- </div>
- </template>
- </el-dialog>
- <el-dialog
- v-model="uploadVisible"
- title="文件上传"
- width="500"
- >
- <el-upload
- class="upload-demo"
- drag
- :action="proxy+'/upload'"
- multiple
- :data="uploadData"
- ref="upload"
- :on-success="query"
- >
- <el-icon class="el-icon--upload">
- <upload-filled/>
- </el-icon>
- <div class="el-upload__text">
- 拖动至此或 <em>选择文件</em>
- </div>
- </el-upload>
- <template #footer>
- <div class="dialog-footer">
- <el-button type="primary" @click="clear">
- 关闭
- </el-button>
- </div>
- </template>
- </el-dialog>
- </el-row>
- </template>
- <style scoped>
- </style>
|