Procházet zdrojové kódy

0904xx数据备份管理

XiaXxxxxx před 2 roky
rodič
revize
0662e25175

+ 161 - 0
src/views/dataAdmin/dataAdmin/dataBackup/VersionDrawer.vue

@@ -0,0 +1,161 @@
+<template>
+    <a-drawer :title="title" :visible="true" :width="540" :body-style="{ paddingBottom: '80px' }"
+        :footer-style="{ textAlign: 'right' }" @close="onClose">
+        <a-form ref="formRef" :model="form" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol">
+            <!-- 名称 -->
+            <a-form-item label="版本名称" name="name">
+                <a-input v-model:value="form.name" style="width: 100%" placeholder="请输入名称" />
+            </a-form-item>
+            <!-- 说明 -->
+            <a-form-item label="版本说明" name="description">
+                <a-input v-model:value="form.description" style="width: 100%" placeholder="请输入说明" />
+            </a-form-item>
+        </a-form>
+        <div :style="{
+            position: 'absolute',
+            right: 0,
+            bottom: 0,
+            width: '100%',
+            borderTop: '1px solid #e9e9e9',
+            padding: '10px 16px',
+            background: '#fff',
+            textAlign: 'right',
+            zIndex: 1,
+        }">
+            <a-button style="margin-right: 8px" @click="onClose">取消</a-button>
+            <a-button type="primary" @click="onSubmit">确定</a-button>
+        </div>
+    </a-drawer>
+</template>
+<script>
+import { defineComponent, reactive, ref, onMounted, watch } from 'vue';
+import { message } from 'ant-design-vue';
+import { addVersion, updateVersion } from '/@/api/sys/version';
+import { session } from '/@/utils/Memory';
+import moment from 'moment';
+
+const props = {
+    formData: {
+        type: Object,
+        default: () => {
+            return {}
+        }
+    },
+    drawerTitle: {
+        type: String,
+        default: "新增版本"
+    }
+}
+export default defineComponent({
+    name: 'VersionDrawer',
+    components: {},
+    props,
+    setup(props, { emit }) {
+        const form = reactive({
+            dataVersionConfs: [],
+            description: "",
+            insertTime: "",
+            name: "",
+            type: "",
+            updateTime: "",
+            vid: "",
+        });
+        const rules = {
+            name: [{
+                required: true,
+                message: '请输入版本名称',
+                trigger: 'blur'
+            }],
+            description: [{
+                required: true,
+                message: '请选择版本说明',
+                trigger: 'blur'
+            }]
+        };
+        const title = ref(props.drawerTitle)
+        const formRef = ref()
+
+        onMounted(() => {
+            if (Object.keys(props.formData).length) {
+                for (let key in form) {
+                    form[key] = props.formData[key]
+                }
+            };
+        })
+
+        watch(
+            () => [props.formData, props.drawerTitle],
+            ([newF, newD]) => {
+                for (let key in form) {
+                    form[key] = props.formData[key]
+                }
+                title.value = newD
+            },
+            {
+                immediate: true,
+                deep: true
+            }
+        )
+        // 关闭弹窗
+        const onClose = () => {
+            emit('closeDialog')
+            resetForm()
+        };
+        // 提交信息
+        const onSubmit = () => {
+            formRef.value.validate().then(() => {
+                //此处调用新增
+                if (title.value === '新增版本') {
+                    let { name, description } = form
+                    //新增版本
+                    let param = {
+                        1: session.getItem('tokenV2'),
+                        2: JSON.stringify({ name: name, description: description })
+                    }
+                    addVersion(param).then(res => {
+                        if (res.status === "0") {
+                            message.success('操作成功')
+                            resetForm()
+                            emit('onSubmit', true)
+                        } else {
+                            message.error('操作失败')
+                        }
+                    })
+                } else {
+                    form.updateTime = moment().format('YYYY-MM-DD HH:mm:ss')
+                    let param = {
+                        1: session.getItem('tokenV2'),
+                        2: JSON.stringify(form)
+                    }
+                    updateVersion(param).then(res => {
+                        if (res.status === "0") {
+                            message.success('操作成功')
+                            resetForm()
+                            emit('onSubmit', true)
+                        } else {
+                            message.error('操作失败')
+                        }
+                    })
+                }
+            }).catch((error) => {
+                console.log('error', error);
+            });
+        };
+        // 重置表单
+        const resetForm = () => {
+            formRef.value.resetFields();
+        };
+        return {
+            form,
+            rules,
+            title,
+            formRef,
+            labelCol: { span: 6 },
+            wrapperCol: { span: 18 },
+            onClose,
+            onSubmit,
+            resetForm
+        };
+    },
+});
+</script>

+ 72 - 0
src/views/dataAdmin/dataAdmin/dataBackup/VersionModal.vue

@@ -0,0 +1,72 @@
+<template>
+    <a-modal 
+        :visible="true" 
+        :width="width" 
+        :maskClosable="false" 
+        :destroyOnClose="true"
+        :title="title" 
+        :footer="null"
+        :wrapClassName="wrapClassName"
+        @cancel="onClose" 
+    >
+        <slot name="modalContent"></slot>
+    </a-modal>
+</template>
+<script>
+import { defineComponent, reactive, ref, onMounted, watch, toRefs } from 'vue';
+import { message } from 'ant-design-vue';
+import moment from 'moment';
+
+const props = {
+    width: {
+        type: String,
+        default: '1000px'
+    },
+    title:{
+        type:String,
+        default:"版本资源"
+    },
+    wrapClassName:{
+        type:String,
+        default:""
+    }
+}
+export default defineComponent({
+    name: 'modal',
+    components: {},
+    props,
+    setup(props, { emit }) {
+        const propsData = reactive({
+            width: props.width,
+            title: props.title,
+            wrapClassName:props.wrapClassName
+        })
+        watch(
+            () => props.width,
+            (val) => {
+                propsData.width = val
+            }
+        )
+        watch(
+            () => props.title,
+            (val) => {
+                propsData.title = val
+            }
+        )
+        watch(
+            () => props.wrapClassName,
+            (val) => {
+                propsData.wrapClassName = val
+            }
+        )
+        const onClose = (e) => {
+            emit('closeModal')
+        }
+        return {
+            ...toRefs(propsData),
+            //func
+            onClose
+        };
+    },
+});
+</script>

+ 512 - 0
src/views/dataAdmin/dataAdmin/dataBackup/index.vue

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