|
|
@@ -0,0 +1,512 @@
|
|
|
+<template>
|
|
|
+ <div class="p-4">
|
|
|
+ <div class="backup-header">
|
|
|
+ <div class="backup-title">
|
|
|
+ <div class="search-name">数据库</div>
|
|
|
+ <a-input v-model:value="searchValue" placeholder="输入关键字查询" allow-clear />
|
|
|
+ </div>
|
|
|
+ <div class="handle-btns">
|
|
|
+ <!-- <span class="label">版本名称:</span> -->
|
|
|
+ <a-button class="btn" @click="searchTable">重置</a-button>
|
|
|
+ <a-button class="btn" type="primary" @click="searchTable">查询</a-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="backup-body">
|
|
|
+ <BasicTable @register="registerTable">
|
|
|
+ <template #toolbar>
|
|
|
+ <Button type="primary" @click="openDialog(null)">
|
|
|
+ 新增备份
|
|
|
+ </Button>
|
|
|
+ <Button type="primary" danger :disabled="hasSelected" @click="delAllData">
|
|
|
+ 批量删除
|
|
|
+ </Button>
|
|
|
+ </template>
|
|
|
+ <template #restore="{record}">
|
|
|
+ <TableAction :actions="[
|
|
|
+ {
|
|
|
+ label: '查看',
|
|
|
+ tooltip: '查看',
|
|
|
+ onClick: openModal.bind(null, record),
|
|
|
+ }
|
|
|
+ ]" />
|
|
|
+ </template>
|
|
|
+ <template #action="{ record }">
|
|
|
+ <TableAction :actions="[
|
|
|
+ {
|
|
|
+ label: '删除',
|
|
|
+ tooltip: '删除',
|
|
|
+ onClick: openModal.bind(null, record.vid),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '下载',
|
|
|
+ tooltip: '下载',
|
|
|
+ onClick: openDialog.bind(null, record),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '恢复',
|
|
|
+ tooltip: '恢复',
|
|
|
+ onClick: onDelete.bind(null, record.vid),
|
|
|
+ },
|
|
|
+ ]" />
|
|
|
+ </template>
|
|
|
+ </BasicTable>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <VersionDrawer v-if="ifShowDialog" @closeDialog="ifShowDialog = false" :formData="formData"
|
|
|
+ :drawerTitle="drawerTitle" @onSubmit="onSubmit" ref="drawerRef">
|
|
|
+ </VersionDrawer>
|
|
|
+ <VersionModal v-if="ifShowModal" @closeModal="ifShowModal = false" :width="modalWidth" :title="sourcesTableTitle">
|
|
|
+ <template #modalContent>
|
|
|
+ <div class="sources-body" style="padding: 20px;">
|
|
|
+ <!-- <div class="sources-title" style="margin-bottom: 20px;font-size: 16px;">资源列表</div> -->
|
|
|
+ <a-table :columns="sourcesColumns" :data-source="sourcesTableData"></a-table>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </VersionModal>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { defineComponent, reactive, ref, toRefs, computed, onMounted, watch, createVNode } from 'vue';
|
|
|
+// 导入表格组件,表格事件
|
|
|
+import { BasicTable, useTable, TableAction } from '/@/components/Table';
|
|
|
+import { Button, notification } from 'ant-design-vue';
|
|
|
+
|
|
|
+import VersionDrawer from './VersionDrawer.vue';
|
|
|
+import VersionModal from './VersionModal.vue';
|
|
|
+import { getVersionList, delVersionByIds, getVersionDetail } from '/@/api/sys/version';
|
|
|
+import { message, Modal } from 'ant-design-vue';
|
|
|
+import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
|
|
|
+import moment from 'moment'
|
|
|
+import { session } from '/@/utils/Memory';
|
|
|
+
|
|
|
+const restoreData = []
|
|
|
+for (let i = 0; i < 20; i++) {
|
|
|
+ restoreData.push({
|
|
|
+ id: i + 1,
|
|
|
+ dbName: 'TB12113414',
|
|
|
+ description: 'TB12113414',
|
|
|
+ optUser: '李某某',
|
|
|
+ optTime: '2023.01.01 12:00:00'
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'backup',
|
|
|
+ components: { VersionDrawer, ExclamationCircleOutlined, VersionModal, BasicTable, TableAction, Button },
|
|
|
+ setup() {
|
|
|
+ const drawerRef = ref(null)
|
|
|
+ const data = reactive({
|
|
|
+ searchValue: "",//查询值
|
|
|
+ formData: {
|
|
|
+ dataVersionConfs: [],
|
|
|
+ description: "",
|
|
|
+ insertTime: "",
|
|
|
+ name: "",
|
|
|
+ type: "",
|
|
|
+ updateTime: "",
|
|
|
+ vid: "",
|
|
|
+ },
|
|
|
+ drawerTitle: "新增版本",
|
|
|
+ ifShowDialog: false,
|
|
|
+ ifShowModal: false
|
|
|
+ });
|
|
|
+ //资源列表数据
|
|
|
+ const sourcesData = reactive({
|
|
|
+ sourcesTableData: [
|
|
|
+ {
|
|
|
+ idx:"1",
|
|
|
+ key:"1",
|
|
|
+ optTime:"2023.08.15 12:00:00",
|
|
|
+ optUser:"李某某",
|
|
|
+ restoreDes:"/",
|
|
|
+ restoreStatus:"已恢复"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ idx:"2",
|
|
|
+ key:"2",
|
|
|
+ optTime:"2023.08.15 12:00:00",
|
|
|
+ optUser:"李某某",
|
|
|
+ restoreDes:"/",
|
|
|
+ restoreStatus:"已恢复"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ idx:"3",
|
|
|
+ key:"3",
|
|
|
+ optTime:"2023.08.15 12:00:00",
|
|
|
+ optUser:"李某某",
|
|
|
+ restoreDes:"/",
|
|
|
+ restoreStatus:"已恢复"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ idx:"4",
|
|
|
+ key:"4",
|
|
|
+ optTime:"2023.08.15 12:00:00",
|
|
|
+ optUser:"李某某",
|
|
|
+ restoreDes:"/",
|
|
|
+ restoreStatus:"已恢复"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ idx:"5",
|
|
|
+ key:"5",
|
|
|
+ optTime:"2023.08.15 12:00:00",
|
|
|
+ optUser:"李某某",
|
|
|
+ restoreDes:"/",
|
|
|
+ restoreStatus:"已恢复"
|
|
|
+ },
|
|
|
+ ],//资源表格数据
|
|
|
+ sourcesColumns: [
|
|
|
+ {
|
|
|
+ title: '序号',
|
|
|
+ align: 'center',
|
|
|
+ dataIndex: 'idx',
|
|
|
+ key: 'idx'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '操作时间',
|
|
|
+ align: 'center',
|
|
|
+ dataIndex: 'optTime',
|
|
|
+ key: 'optTime'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '操作人',
|
|
|
+ align: 'center',
|
|
|
+ dataIndex: 'optUser',
|
|
|
+ key: 'optUser'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '恢复说明',
|
|
|
+ align: 'center',
|
|
|
+ dataIndex: 'restoreDes',
|
|
|
+ key: 'restoreDes'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '恢复状态',
|
|
|
+ align: 'center',
|
|
|
+ dataIndex: 'restoreStatus',
|
|
|
+ key: 'restoreStatus'
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ sourcesTableTitle: "恢复记录",
|
|
|
+ modalWidth: '1200px',
|
|
|
+ wrapClassName: "sources-body"
|
|
|
+ })
|
|
|
+ //获取所有标签
|
|
|
+ const getVersionData = () => {
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ let param = {
|
|
|
+ 1: session.getItem('tokenV2'),
|
|
|
+ 2: JSON.stringify({}),
|
|
|
+ 3: 1,
|
|
|
+ 4: 10000000
|
|
|
+ }
|
|
|
+ getVersionList(param).then(res => {
|
|
|
+ let resData = JSON.parse(res.result)
|
|
|
+ resolve(resData)
|
|
|
+ })
|
|
|
+ })
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ //筛选数据,用于表格
|
|
|
+ // const filteredInfo = ref({
|
|
|
+ // name: null
|
|
|
+ // });
|
|
|
+ //表格列
|
|
|
+ const columns = computed(() => {
|
|
|
+ // const filtered = filteredInfo.value || {};
|
|
|
+ return [
|
|
|
+ {
|
|
|
+ title: '数据库',
|
|
|
+ align: 'center',
|
|
|
+ dataIndex: 'dbName',
|
|
|
+ key: 'dbName',
|
|
|
+ // filteredValue: filtered.name || null,
|
|
|
+ // onFilter: (value, record) => record.name.includes(value)
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '备份说明',
|
|
|
+ align: 'center',
|
|
|
+ dataIndex: 'description',
|
|
|
+ key: 'description'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '操作人',
|
|
|
+ align: 'center',
|
|
|
+ dataIndex: 'optUser',
|
|
|
+ key: 'optUser'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '操作时间',
|
|
|
+ align: 'center',
|
|
|
+ dataIndex: 'optTime',
|
|
|
+ key: 'optTime'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '恢复记录',
|
|
|
+ align: 'center',
|
|
|
+ dataIndex: 'restore',
|
|
|
+ slots: {
|
|
|
+ customRender: 'restore',
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ];
|
|
|
+ });
|
|
|
+ //表格查询功能
|
|
|
+ const searchTable = () => {
|
|
|
+ // filteredInfo.value.name = [data.searchValue]
|
|
|
+ }
|
|
|
+ //判断是否选中数据
|
|
|
+ const hasSelected = computed(() => {
|
|
|
+ const rowSelection = getRowSelection();
|
|
|
+ return !rowSelection.selectedRowKeys?.length;
|
|
|
+ });
|
|
|
+ //删除所有选中的数据
|
|
|
+ const delAllData = () => {
|
|
|
+ Modal.confirm({
|
|
|
+ title: '删除提示',
|
|
|
+ icon: createVNode(ExclamationCircleOutlined),
|
|
|
+ content: '确定删除版本?',
|
|
|
+ centered: true,
|
|
|
+ okText: '确定',
|
|
|
+ okType: 'danger',
|
|
|
+ cancelText: '取消',
|
|
|
+ onOk: (() => {
|
|
|
+ const rowKeys = getSelectRowKeys();
|
|
|
+ let ids = rowKeys.toString()
|
|
|
+ let param = {
|
|
|
+ 1: session.getItem('tokenV2'),
|
|
|
+ 2: ids,
|
|
|
+ }
|
|
|
+ delVersionByIds(param).then(res => {
|
|
|
+ if (res.status === "0") {
|
|
|
+ message.success('操作成功');
|
|
|
+ reload();
|
|
|
+ setSelectedRowKeys([])
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ });
|
|
|
+ };
|
|
|
+ //新增或修改数据,打开弹窗
|
|
|
+ const openDialog = (record) => {
|
|
|
+ if (!record) {
|
|
|
+ data.formData = {
|
|
|
+ dataVersionConfs: [],
|
|
|
+ description: "",
|
|
|
+ insertTime: "",
|
|
|
+ name: "",
|
|
|
+ type: "",
|
|
|
+ updateTime: "",
|
|
|
+ vid: "",
|
|
|
+ }
|
|
|
+ data.drawerTitle = '新增版本'
|
|
|
+ data.ifShowDialog = true
|
|
|
+ } else {
|
|
|
+ data.formData = {
|
|
|
+ dataVersionConfs: record.dataVersionConfs,
|
|
|
+ description: record.description,
|
|
|
+ insertTime: record.insertTime,
|
|
|
+ name: record.name,
|
|
|
+ type: record.type,
|
|
|
+ updateTime: record.updateTime,
|
|
|
+ vid: record.vid,
|
|
|
+ }
|
|
|
+ data.drawerTitle = '修改版本'
|
|
|
+ data.ifShowDialog = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //删除单个数据
|
|
|
+ const onDelete = (id) => {
|
|
|
+ Modal.confirm({
|
|
|
+ title: '删除提示',
|
|
|
+ icon: createVNode(ExclamationCircleOutlined),
|
|
|
+ content: '确定删除版本?',
|
|
|
+ centered: true,
|
|
|
+ okText: '确定',
|
|
|
+ okType: 'danger',
|
|
|
+ cancelText: '取消',
|
|
|
+ onOk: (() => {
|
|
|
+ let param = {
|
|
|
+ 1: session.getItem('tokenV2'),
|
|
|
+ 2: id,
|
|
|
+ }
|
|
|
+ delVersionByIds(param).then(res => {
|
|
|
+ if (res.status === "0") {
|
|
|
+ message.success('操作成功');
|
|
|
+ reload();
|
|
|
+ }
|
|
|
+ })
|
|
|
+ })
|
|
|
+ });
|
|
|
+
|
|
|
+ }
|
|
|
+ //打开弹窗展示资源
|
|
|
+ const openModal = (id) => {
|
|
|
+ data.ifShowModal = true
|
|
|
+ // let param = {
|
|
|
+ // 1: session.getItem('tokenV2'),
|
|
|
+ // 2: id,
|
|
|
+ // }
|
|
|
+ // getVersionDetail(param).then(res => {
|
|
|
+ // if (res.status === "0") {
|
|
|
+ // let resData = JSON.parse(res.result)
|
|
|
+ // if (resData.dataVersionConfs.length) {
|
|
|
+ // sourcesData.sourcesTableData = []
|
|
|
+ // sourcesData.sourcesTableTitle = `版本:${resData.name}`
|
|
|
+ // resData.dataVersionConfs.forEach(item => {
|
|
|
+ // sourcesData.sourcesTableData.push({
|
|
|
+ // isNew: item.active === 'N' ? '否' : '是',
|
|
|
+ // key: item.id,
|
|
|
+ // ...item
|
|
|
+ // })
|
|
|
+ // })
|
|
|
+ // data.ifShowModal = true
|
|
|
+ // } else {
|
|
|
+ // message.info('该版本暂无资源')
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ }
|
|
|
+ //弹窗确认
|
|
|
+ const onSubmit = (e) => {
|
|
|
+ data.ifShowDialog = false
|
|
|
+ if (e) {
|
|
|
+ reload();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const [
|
|
|
+ registerTable,
|
|
|
+ { reload, collapseAll, getRowSelection, getSelectRowKeys, setSelectedRowKeys },
|
|
|
+ ] = useTable({
|
|
|
+ title: '数据备份列表', //'菜单列表'
|
|
|
+ // api: getVersionData, //加载数据,暂时没有接口用假数据
|
|
|
+ dataSource: restoreData,//假数据
|
|
|
+ columns: columns,
|
|
|
+ useSearchForm: false, //开启搜索区域
|
|
|
+ bordered: true,
|
|
|
+ showTableSetting: true, // 显示表格设置
|
|
|
+ tableSetting: { fullScreen: false },
|
|
|
+ showIndexColumn: true,
|
|
|
+ pagination: {
|
|
|
+ pageSize: 10,
|
|
|
+ hideOnSinglePage: false
|
|
|
+ },
|
|
|
+ rowKey: (record) => record.id,
|
|
|
+ actionColumn: {
|
|
|
+ width: 200,
|
|
|
+ title: '操作',
|
|
|
+ dataIndex: 'action',
|
|
|
+ slots: { customRender: 'action' },
|
|
|
+ },
|
|
|
+ rowSelection: {
|
|
|
+ type: 'checkbox',
|
|
|
+ },
|
|
|
+ });
|
|
|
+ return {
|
|
|
+ drawerRef,
|
|
|
+ // filteredInfo,
|
|
|
+ columns,
|
|
|
+ hasSelected,
|
|
|
+ ...toRefs(data),
|
|
|
+ ...toRefs(sourcesData),
|
|
|
+ // func
|
|
|
+ registerTable,
|
|
|
+ getVersionData,
|
|
|
+ searchTable,
|
|
|
+ delAllData,
|
|
|
+ onDelete,
|
|
|
+ openModal,
|
|
|
+ openDialog,
|
|
|
+ onSubmit
|
|
|
+ };
|
|
|
+ },
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+.p-4 {
|
|
|
+ height: 100%;
|
|
|
+
|
|
|
+ .backup-header {
|
|
|
+ padding: 10px;
|
|
|
+ width: 100%;
|
|
|
+ height: 70px;
|
|
|
+ background-color: #fff;
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .backup-title {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 500;
|
|
|
+ margin-left: 20px;
|
|
|
+ user-select: none;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .search-name {
|
|
|
+ width: 100px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .handle-btns {
|
|
|
+ margin-right: 20px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .label {
|
|
|
+ width: 150px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .btn {
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .backup-body {
|
|
|
+ padding: 0 30px;
|
|
|
+ margin-top: 20px;
|
|
|
+ width: 100%;
|
|
|
+ // height: 800px;
|
|
|
+ height: calc(100% - 90px);
|
|
|
+ background-color: #fff;
|
|
|
+
|
|
|
+ .body-header {
|
|
|
+ display: flex;
|
|
|
+ height: 80px;
|
|
|
+ width: 100%;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .item-title {
|
|
|
+ height: 40px;
|
|
|
+ line-height: 40px;
|
|
|
+ font-size: 16px;
|
|
|
+ user-select: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .table-btns {
|
|
|
+ .btn {
|
|
|
+ margin-right: 10px;
|
|
|
+
|
|
|
+ &:last-child {
|
|
|
+ margin-right: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .body-content {
|
|
|
+ padding-bottom: 20px;
|
|
|
+ height: calc(100% - 80px);
|
|
|
+
|
|
|
+ a {
|
|
|
+ margin-right: 10px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|