156 lines
5.9 KiB
HTML
156 lines
5.9 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}文件浏览{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container-fluid">
|
|
<div class="row">
|
|
<div class="col-12">
|
|
<el-card class="box-card">
|
|
<div slot="header" class="clearfix">
|
|
<span>文件浏览</span>
|
|
<div style="float: right;">
|
|
<el-input
|
|
v-model="currentPath"
|
|
placeholder="当前路径"
|
|
style="width: 300px; margin-right: 10px;"
|
|
readonly>
|
|
</el-input>
|
|
<el-button type="primary" size="small" @click="navigateUp">
|
|
<i class="el-icon-arrow-up"></i> 上级目录
|
|
</el-button>
|
|
</div>
|
|
</div>
|
|
<el-table
|
|
:data="fileList"
|
|
style="width: 100%"
|
|
v-loading="loading">
|
|
<el-table-column
|
|
prop="name"
|
|
label="名称"
|
|
min-width="200">
|
|
<template slot-scope="scope">
|
|
<el-link
|
|
:type="scope.row.is_dir ? 'primary' : 'info'"
|
|
@click="scope.row.is_dir ? navigateTo(scope.row.name) : null">
|
|
<i :class="scope.row.is_dir ? 'el-icon-folder' : 'el-icon-document'"></i>
|
|
[[ scope.row.name ]]
|
|
</el-link>
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="type"
|
|
label="类型"
|
|
width="100">
|
|
<template slot-scope="scope">
|
|
[[ scope.row.is_dir ? '目录' : '文件' ]]
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="size"
|
|
label="大小"
|
|
width="120">
|
|
<template slot-scope="scope">
|
|
[[ scope.row.is_dir ? '-' : formatFileSize(scope.row.size) ]]
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
prop="modified"
|
|
label="修改时间"
|
|
width="180">
|
|
<template slot-scope="scope">
|
|
[[ formatDate(scope.row.modified) ]]
|
|
</template>
|
|
</el-table-column>
|
|
<el-table-column
|
|
label="操作"
|
|
width="120">
|
|
<template slot-scope="scope">
|
|
<el-button
|
|
v-if="!scope.row.is_dir"
|
|
type="primary"
|
|
size="mini"
|
|
@click="downloadFile(scope.row.name)">
|
|
下载
|
|
</el-button>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table>
|
|
</el-card>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
new Vue({
|
|
el: '#app',
|
|
mixins: [baseApp],
|
|
delimiters: ['[[', ']]'],
|
|
data() {
|
|
return {
|
|
currentPath: '',
|
|
fileList: [],
|
|
loading: false
|
|
}
|
|
},
|
|
created() {
|
|
this.currentView = '15';
|
|
this.loadFiles('');
|
|
},
|
|
methods: {
|
|
formatFileSize(bytes) {
|
|
if (bytes === 0) return '0 B';
|
|
const k = 1024;
|
|
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
},
|
|
formatDate(timestamp) {
|
|
return new Date(timestamp * 1000).toLocaleString();
|
|
},
|
|
loadFiles(path) {
|
|
this.loading = true;
|
|
this.currentPath = path || '/';
|
|
|
|
axios.get('/api/list_files', {
|
|
params: { path: path }
|
|
})
|
|
.then(response => {
|
|
if (response.data.success) {
|
|
this.fileList = response.data.data.items;
|
|
} else {
|
|
this.$message.error('加载文件列表失败:' + response.data.message);
|
|
}
|
|
})
|
|
.catch(error => {
|
|
this.$message.error('加载文件列表失败');
|
|
console.error('Error:', error);
|
|
})
|
|
.finally(() => {
|
|
this.loading = false;
|
|
});
|
|
},
|
|
navigateTo(dirName) {
|
|
const newPath = this.currentPath === '/' ? dirName : this.currentPath + '/' + dirName;
|
|
this.loadFiles(newPath);
|
|
},
|
|
navigateUp() {
|
|
if (!this.currentPath) return;
|
|
|
|
const lastSlashIndex = this.currentPath.lastIndexOf('/');
|
|
if (lastSlashIndex === -1) {
|
|
this.loadFiles('');
|
|
} else {
|
|
this.loadFiles(this.currentPath.substring(0, lastSlashIndex));
|
|
}
|
|
},
|
|
downloadFile(fileName) {
|
|
const filePath = this.currentPath === '/' ? fileName : this.currentPath + '/' + fileName;
|
|
window.location.href = '/api/download_file?path=' + encodeURIComponent(filePath);
|
|
}
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %} |