2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 09:13:49 +08:00
Files
panel/web/src/views/backup/ListView.vue
2024-10-13 22:44:42 +08:00

166 lines
4.0 KiB
Vue

<script setup lang="ts">
import backup from '@/api/panel/backup'
import { renderIcon } from '@/utils'
import type { MessageReactive } from 'naive-ui'
import { NButton, NInput, NPopconfirm } from 'naive-ui'
import type { Backup } from './types'
const type = defineModel<string>('type', { type: String, required: true })
let messageReactive: MessageReactive | null = null
const restoreModal = ref(false)
const restoreModel = ref({
file: '',
target: ''
})
const columns: any = [
{ title: '文件名', key: 'name', fixed: 'left', resizable: true, ellipsis: { tooltip: true } },
{ title: '大小', key: 'size', width: 200, ellipsis: { tooltip: true } },
{
title: '操作',
key: 'actions',
width: 200,
align: 'center',
fixed: 'right',
hideInExcel: true,
render(row: any) {
return [
h(
NButton,
{
size: 'small',
type: 'warning',
secondary: true,
onClick: () => {
restoreModel.value.file = row.path
restoreModal.value = true
}
},
{
default: () => '恢复',
icon: renderIcon('material-symbols:settings-backup-restore-rounded', { size: 14 })
}
),
h(
NPopconfirm,
{
onPositiveClick: () => handleDelete(row.name)
},
{
default: () => {
return '确定删除备份吗?'
},
trigger: () => {
return h(
NButton,
{
size: 'small',
type: 'error',
style: 'margin-left: 15px;'
},
{
default: () => '删除',
icon: renderIcon('material-symbols:delete-outline', { size: 14 })
}
)
}
}
)
]
}
}
]
const data = ref<Backup[]>([])
const pagination = reactive({
page: 1,
pageCount: 1,
pageSize: 10,
itemCount: 0,
showQuickJumper: true,
showSizePicker: true,
pageSizes: [10, 20, 50, 100]
})
const getList = async (page: number, limit: number) => {
const { data } = await backup.list(type.value, page, limit)
return data
}
const onPageChange = (page: number) => {
pagination.page = page
getList(page, pagination.pageSize).then((res) => {
data.value = res.items
pagination.itemCount = res.total
pagination.pageCount = res.total / pagination.pageSize + 1
})
}
const onPageSizeChange = (pageSize: number) => {
pagination.pageSize = pageSize
onPageChange(1)
}
const handleRestore = async () => {
messageReactive = window.$message.loading('恢复中...', {
duration: 0
})
await backup.restore(type.value, restoreModel.value.file, restoreModel.value.target).then(() => {
messageReactive?.destroy()
window.$message.success('恢复成功')
onPageChange(pagination.page)
})
}
const handleDelete = async (file: string) => {
await backup.delete(type.value, file).then(() => {
window.$message.success('删除成功')
onPageChange(pagination.page)
})
}
onMounted(() => {
onPageChange(pagination.page)
})
</script>
<template>
<n-data-table
striped
remote
:loading="false"
:columns="columns"
:data="data"
:row-key="(row: any) => row.name"
@update:page="onPageChange"
@update:page-size="onPageSizeChange"
/>
<n-modal
v-model:show="restoreModal"
preset="card"
title="恢复备份"
style="width: 60vw"
size="huge"
:bordered="false"
:segmented="false"
@close="restoreModal = false"
>
<n-form :model="restoreModel">
<n-form-item path="name" label="恢复目标">
<n-input v-model:value="restoreModel.target" type="text" @keydown.enter.prevent />
</n-form-item>
</n-form>
<n-row :gutter="[0, 24]">
<n-col :span="24">
<n-button type="info" block @click="handleRestore">提交</n-button>
</n-col>
</n-row>
</n-modal>
</template>
<style scoped lang="scss"></style>