themblem/web/src/views/estor-files.vue
2024-09-01 21:51:50 +01:00

240 lines
6.9 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>