240 lines
6.9 KiB
Vue
240 lines
6.9 KiB
Vue
<template>
|
||
<h3>
|
||
批次文件
|
||
</h3>
|
||
<hr>
|
||
<div class="fade-in">
|
||
<div>
|
||
<div class="my-4">
|
||
当前路径: {{ position_text }}
|
||
<button @click="show_upload" class="mx-3 btn btn-success btn-sm">上传</button>
|
||
</div>
|
||
<div v-if="loading" class="alert alert-secondary">
|
||
<CSpinner />
|
||
读取中...
|
||
</div>
|
||
<table v-else class="table">
|
||
<thead>
|
||
<th>
|
||
第 {{ offset + 1 }} ~ {{ last_offset }}条
|
||
/
|
||
{{ total_items }}条记录
|
||
<span>
|
||
<button class="mx-1 btn btn-secondary btn-sm" :disabled="!has_prev_page" @click="prev_page" href="javascript:void(0)">上一页</button>
|
||
<button class="mx-1 btn btn-secondary btn-sm" :disabled="!has_next_page" @click="next_page" href="javascript:void(0)">下一页</button>
|
||
<input class="jump-page" type="number" v-model="jump_to_page"/>
|
||
<button class="mx-1 btn btn-secondary btn-sm" @click="jump_page" href="javascript:void(0)">跳转</button>
|
||
</span>
|
||
</th>
|
||
<th>大小</th>
|
||
<th>操作</th>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>
|
||
<a v-if="show_go_up" href="javascript:void(0)" @click="go_up">
|
||
上一级
|
||
</a>
|
||
</td>
|
||
<td></td>
|
||
<td></td>
|
||
</tr>
|
||
<tr v-for="(e, i) in entries" :key="i">
|
||
<td>
|
||
<div v-if="e.renaming" class="input-group">
|
||
<input class="form-control" type="text" v-model="e.new_name" />
|
||
<button class="btn btn-primary" @click="rename_file(e)">修改</button>
|
||
</div>
|
||
<div v-else>
|
||
<a v-if="e.dir" href="javascript:void(0)" @click="enter_dir(e.name)">{{ e.name }}</a>
|
||
<a v-else :href="file_link(e.name)" target="_blank">{{ e.name }}</a>
|
||
</div>
|
||
</td>
|
||
<td>{{ e.size }}</td>
|
||
<td>
|
||
<CDropdown>
|
||
<CDropdownToggle size="sm" color="secondary">操作</CDropdownToggle>
|
||
<CDropdownMenu>
|
||
<CDropdownItem @click="e.new_name = e.name; e.renaming = true">重命名</CDropdownItem>
|
||
<CDropdownItem @click="show_move(e.name)">移动</CDropdownItem>
|
||
<CDropdownItem @click="show_copy(e.name)">复制</CDropdownItem>
|
||
<CDropdownItem class="text-danger" @click="delete_file(e)">删除</CDropdownItem>
|
||
</CDropdownMenu>
|
||
</CDropdown>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<FileSelector ref="move_selector" dironly=1 :fsdriver="$root.estor_fs" @ok="move_ok">
|
||
</FileSelector>
|
||
<FileSelector ref="copy_selector" dironly=1 :fsdriver="$root.estor_fs" @ok="copy_ok">
|
||
</FileSelector>
|
||
<input type="file" multiple hidden ref="upload" @change="upload_file_change"/>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import FileSelector from '@/components/file-selector.vue';
|
||
export default {
|
||
name: 'EstorFiles',
|
||
props: [],
|
||
components: {
|
||
FileSelector,
|
||
},
|
||
data: function () {
|
||
return {
|
||
root: this.$root.estor_batches_path.slice(),
|
||
path: this.$root.estor_batches_path.slice(),
|
||
entries: [],
|
||
moving_file: null,
|
||
copying_file: null,
|
||
loading: false,
|
||
offset: 0,
|
||
pagesize: 100,
|
||
total_items: 0,
|
||
jump_to_page: 0,
|
||
};
|
||
},
|
||
computed: {
|
||
has_next_page() {
|
||
return this.last_offset < this.total_items;
|
||
},
|
||
has_prev_page() {
|
||
return this.offset > 0;
|
||
},
|
||
last_offset() {
|
||
var r = this.offset + this.pagesize;
|
||
if (r > this.total_items) {
|
||
r = this.total_items;
|
||
}
|
||
return r;
|
||
},
|
||
total_pages() {
|
||
return Math.ceil(this.total_items / this.pagesize);
|
||
},
|
||
show_go_up() {
|
||
return this.root.length < this.path.length;
|
||
},
|
||
position_text() {
|
||
var p = this.path.slice(this.root.length);
|
||
return p.join('/') + "/";
|
||
},
|
||
path_text() {
|
||
if (!this.path.length)
|
||
return '/';
|
||
return '/' + this.path.join('/') + "/";
|
||
},
|
||
},
|
||
methods: {
|
||
prev_page() {
|
||
this.offset -= this.pagesize;
|
||
if (this.offset < 0)
|
||
this.offset = 0;
|
||
this.reload();
|
||
},
|
||
next_page() {
|
||
if (this.offset + this.pagesize >= this.total_items) return;
|
||
this.offset += this.pagesize;
|
||
this.reload();
|
||
},
|
||
jump_page() {
|
||
var new_offset = this.pagesize * this.jump_to_page;
|
||
if (new_offset < 0) {
|
||
new_offset = 0;
|
||
}
|
||
if (new_offset > this.total_items) {
|
||
new_offset = Math.round(this.total_items / this.pagesize);
|
||
}
|
||
this.offset = new_offset;
|
||
this.reload();
|
||
},
|
||
file_link(fn) {
|
||
return this.$root.estor_file_link(this.path_text + fn);
|
||
},
|
||
go_up() {
|
||
if (!this.path) return;
|
||
this.path.pop();
|
||
this.offset = 0;
|
||
this.total_items = 0;
|
||
this.reload();
|
||
},
|
||
async reload() {
|
||
this.loading = true;
|
||
var r = await this.$root.estor_list(this.path_text, this.offset, this.pagesize);
|
||
this.entries = r;
|
||
r = await this.$root.estor_stat(this.path_text);
|
||
this.total_items = r.nr_entries;
|
||
this.loading = false;
|
||
},
|
||
delete_file(e) {
|
||
var fn = e.name;
|
||
this.sms_verified_action("删除文件",
|
||
"确定删除文件吗?" + fn,
|
||
() => this.do_delete_file(fn),
|
||
);
|
||
},
|
||
async do_delete_file(fn) {
|
||
await this.$root.estor_delete(this.path_text + fn);
|
||
this.reload();
|
||
},
|
||
async rename_file(e) {
|
||
var oldname = this.path_text + e.name;
|
||
var newname = this.path_text + e.new_name;
|
||
await this.$root.estor_move(oldname, newname);
|
||
this.reload();
|
||
},
|
||
enter_dir(name) {
|
||
this.path.push(name);
|
||
this.offset = 0;
|
||
this.total_items = 0;
|
||
this.reload();
|
||
},
|
||
show_move(name) {
|
||
this.moving_file = name;
|
||
this.$refs.move_selector.show();
|
||
},
|
||
move_ok(selection) {
|
||
if (!selection) return;
|
||
var dest = selection[0];
|
||
var src = this.path_text + this.moving_file;
|
||
console.log(src, dest);
|
||
this.$root.estor_move(src, dest);
|
||
this.reload();
|
||
},
|
||
show_copy(name) {
|
||
this.copying_file = name;
|
||
this.$refs.copy_selector.show();
|
||
},
|
||
copy_ok(selection) {
|
||
if (!selection) return;
|
||
var dest = selection[0];
|
||
var src = this.path_text + this.copying_file;
|
||
console.log(src, dest);
|
||
this.$root.estor_copy(src, dest);
|
||
this.reload();
|
||
},
|
||
show_upload() {
|
||
this.$refs.upload.click();
|
||
},
|
||
async upload_file_change() {
|
||
for (var file of this.$refs.upload.files) {
|
||
await this.$root.estor_put(this.path_text + file.name, file);
|
||
}
|
||
this.offset = 0;
|
||
this.total_items = 0;
|
||
this.reload();
|
||
}
|
||
},
|
||
mounted() {
|
||
this.reload();
|
||
},
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
input.jump-page {
|
||
width: 70px;
|
||
}
|
||
</style>
|