瀏覽代碼

1221xx数据备份恢复

XiaXxxxxx 1 年之前
父節點
當前提交
9ea25c496f

+ 182 - 0
src/api/sys/dataBackUp.ts

@@ -0,0 +1,182 @@
+import { defHttp } from '/@/utils/http/axios';
+
+enum Api {
+    // 数据库操作
+    GetBackupsDatabase = '/DbBackups-center/dbBackups/getBackupsDatabase',
+    DelBackupsDatabase = '/DbBackups-center/dbBackups/DelBackupsDatabase',
+    EditBackupsDatabase = '/DbBackups-center/dbBackups/editBackupsDatabase',
+    // 数据备份
+    GetBackupsDate = '/DbBackups-center/dbBackups/GetBackupsDate',
+    BackupsDate = '/DbBackups-center/dbBackups/BackupsDate',
+    DownloadDBFile = '/DbBackups-center/dbBackups/downloadDBFile',
+    DelBackupsDate = '/DbBackups-center/dbBackups/DelBackupsDate',
+    // 定时策略
+    editScheduledTaskCL = '/DbBackups-center/dbBackups/editScheduledTaskCL',
+    DelScheduledTaskCL = '/DbBackups-center/dbBackups/delScheduledTaskCL',
+    GetScheduledTaskCL = '/DbBackups-center/dbBackups/getScheduledTaskCL',
+    // 数据恢复
+    RestoreDate = '/DbBackups-center/dbBackups/restoreDate'
+}
+
+/**
+ * @description: 获取数据库信息列表
+ * @param page string 页码
+ * @param rows string 每页大小
+ * @param fid string 备份id
+ * @param keyStr string 关键字
+ */
+export const getBackupsDatabaseList = (params: any) => {
+    let param = {
+        page:1,
+        rows:1000000,
+        ...params
+    }
+    return new Promise<void>((resolve) => {
+        defHttp.post({url: Api.GetBackupsDatabase, params: param }).then((res) => {
+            resolve(res)
+        })
+    })
+};
+/**
+ * @description: 删除数据库信息
+ * @param fid string 备份id
+ */
+export const delBackupsDatabase = (params: any) => {
+    return new Promise<void>((resolve) => {
+        defHttp.post({ url: Api.DelBackupsDatabase, params: params }).then((res) => {
+            resolve(res)
+        })
+    })
+};
+/**
+ * @description: 编辑数据库信息
+ * @param dbip string 数据库ip
+ * @param dbloginname string 数据库登录名
+ * @param pwd string 数据库密码
+ * @param dbname string 数据库名
+ * @param fid string 数据库信息fid
+ */
+export const editBackupsDatabase = (params: any) => {
+    return new Promise<void>((resolve) => {
+        defHttp.post({ url: Api.EditBackupsDatabase, params: params }).then((res) => {
+            resolve(res)
+        })
+    })
+};
+
+
+/**
+ * @description: 获取数据备份列表
+ * @param page string 页码
+ * @param rows string 每页大小
+ * @param keyStr string 关键字
+ * @param starttime string 备份开始时间
+ * @param endtime string 备份结束时间
+ */
+export const getBackupsList = (params: any) => {
+    let param = {
+        page:1,
+        rows:1000000,
+        ...params
+    }
+    return new Promise<void>((resolve) => {
+        defHttp.post({url: Api.GetBackupsDate, params: param }).then((res) => {
+            resolve(res)
+        })
+    })
+};
+/**
+ * @description: 新增数据备份
+ * @param dbBackups object 备份参数
+ */
+export const addDataBackup = (params: any) => {
+    return new Promise<void>((resolve) => {
+        defHttp.post({ url: Api.BackupsDate, params: params }).then((res) => {
+            resolve(res)
+        })
+    })
+};
+/**
+ * @description: 下载数据备份
+ * @param fid string 备份数据fid
+ */
+export const downloadDBFile = (params: any) => {
+    return new Promise<void>((resolve) => {
+        defHttp.post({ url: Api.DownloadDBFile, params: params }).then((res) => {
+            resolve(res)
+        })
+    })
+}
+/**
+ * @description: 删除数据备份
+ * @param fid string 备份数据fid
+ */
+export const delDataBackup = (params: any) => {
+    return new Promise<void>((resolve) => {
+        defHttp.post({ url: Api.DelBackupsDate, params: params }).then((res) => {
+            resolve(res)
+        })
+    })
+}
+
+
+
+/**
+ * @description: 新增定时策略
+ * @param bfFid string 备份数据库Fid
+ * @param bfzq number 备份周期(1:周;2:月)
+ * @param sjsz number 时间设置(周:1——7,月:1——31)
+ * @param zxsj string 执行时间(格式必须是10:15)
+ * @param fid string 备份定时任务Fid
+ * @param status number 是否启用(0禁用,1启用) 
+ */
+export const EditScheduledTaskCL = (params: any) => {
+    return new Promise<void>((resolve) => {
+        defHttp.post({ url: Api.editScheduledTaskCL, params: params }).then((res) => {
+            resolve(res)
+        })
+    })
+};
+/**
+ * @description: 获取定时策略
+ * @param page string 页码
+ * @param rows string 每页大小
+ * @param fid string 备份定时任务Fid
+ * @param keyStr string 关键字
+ */
+export const getScheduledTaskCL = (params: any) => {
+    let param = {
+        page:1,
+        rows:1000000,
+        ...params
+    }
+    return new Promise<void>((resolve) => {
+        defHttp.post({url: Api.GetScheduledTaskCL, params: param }).then((res) => {
+            resolve(res)
+        })
+    })
+};
+/**
+ * @description: 删除定时策略
+ * @param fid string 备份定时任务Fid
+ */
+export const delScheduledTaskCL = (params: any) => {
+    return new Promise<void>((resolve) => {
+        defHttp.post({ url: Api.DelScheduledTaskCL, params: params }).then((res) => {
+            resolve(res)
+        })
+    })
+};
+
+/**
+ * @description: 数据恢复
+ * @param bfFid string 数据备份id
+ * @param userid string 人员id
+ */
+export const dataRestore = (params: any) => {
+    return new Promise<void>((resolve) => {
+        defHttp.post({ url: Api.RestoreDate, params: params }).then((res) => {
+            resolve(res)
+        })
+    })
+};

+ 0 - 77
src/api/sys/version copy.ts

@@ -1,77 +0,0 @@
-import { defHttp } from '/@/utils/http/axios';
-
-enum Api {
-    GetVersionList = '/sdataversion/SDataVersionProvider/pageList',
-    AddVersion = '/sdataversion/SDataVersionProvider/add',
-    DelVersion = '/sdataversion/SDataVersionProvider/deleteByIds',
-    GetVersionDetail = '/sdataversion/SDataVersionProvider/getDetailById',
-    UpdateVersion = '/sdataversion/SDataVersionProvider/updateById'
-}
-const locationType = { apiUrl2: true };
-
-/**
- * @description: 获取所有版本
- * @param: 1:用户登录tokenV2
- * @param: 2:实体json {}
- * @param: 3:页码
- * @param: 4.每页大小
- */
-export const getVersionList = (params: any) => {
-    return new Promise<void>((resolve) => {
-        defHttp.post({ ...locationType, url: Api.GetVersionList, params: params }, { joinParamsToUrl: true }).then((res) => {
-            resolve(res)
-        })
-    })
-};
-
-/**
- * @description: 新增版本
- * @param: 1:用户登录tokenV2
- * @param: 2:实体json {}
- */
-export const addVersion = (params: any) => {
-    return new Promise<void>((resolve) => {
-        defHttp.post({ ...locationType, url: Api.AddVersion, params: params }, { joinParamsToUrl: true }).then((res) => {
-            resolve(res)
-        })
-    })
-};
-
-/**
- * @description: 根据ids删除版本
- * @param: 1:用户登录tokenV2
- * @param: 2:ids
- */
-export const delVersionByIds = (params: any) => {
-    return new Promise<void>((resolve) => {
-        defHttp.post({ ...locationType, url: Api.DelVersion, params: params }, { joinParamsToUrl: true }).then((res) => {
-            resolve(res)
-        })
-    })
-};
-
-/**
- * @description: 更新版本信息
- * @param: 1: 用户登录tokenV2
- * @param: 2: 实体json {}
- */
-export const updateVersion = (params: any) => {
-    return new Promise<void>((resolve) => {
-        defHttp.post({ ...locationType, url: Api.UpdateVersion, params: params }, { joinParamsToUrl: true }).then((res) => {
-            resolve(res)
-        })
-    })
-};
-
-/**
- * @description: 获取版本下的资源详情
- * @param: 1: 用户登录tokenV2
- * @param: 2: id
- */
-export const getVersionDetail = (params: any) => {
-    return new Promise<void>((resolve) => {
-        defHttp.post({ ...locationType, url: Api.GetVersionDetail, params: params }, { joinParamsToUrl: true }).then((res) => {
-            resolve(res)
-        })
-    })
-};

+ 1 - 1
src/layouts/default/header/index.vue

@@ -224,7 +224,7 @@ export default defineComponent({
         } else {
           getSmsNum()
           smsTimer.value = setInterval(() => {
-            getSmsNum()
+            // getSmsNum()
           }, 5000)
         }
       },

+ 75 - 0
src/views/dataAdmin/dataAdmin/dataBackup/AddDataBackUpModal.vue

@@ -0,0 +1,75 @@
+<template>
+    <BasicModal :maskClosable="false" :width="440" @register="registerModal" v-bind="$attrs" title="数据备份" centered
+        @ok="handleSubmit">
+        <BasicForm @register="registerForm" />
+    </BasicModal>
+</template>
+<script>
+import { defineComponent, reactive, ref, onMounted, watch, computed } from 'vue';
+import { BasicModal, useModalInner } from '/@/components/Modal';
+import { BasicForm, useForm } from '/@/components/Form/index';
+import { message } from 'ant-design-vue';
+import { formSchema } from './dataBackup.data';
+import { editBackupsDatabase, addDataBackup } from '/@/api/sys/dataBackUp';
+
+export default defineComponent({
+    name: 'addDataBackup',
+    components: { BasicModal, BasicForm },
+    setup(_, { emit }) {
+        const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+            console.log(data)
+            resetForm();
+        });
+        const [registerForm, { setFieldsValue, updateSchema, resetFields, validate, getFieldsValue }] = useForm({
+            schemas: formSchema,
+            labelCol: { span: 6 },
+            wrapperCol: { span: 16 },
+            showActionButtonGroup: false
+        });
+        const resetForm = () => {
+            resetFields();
+            updateSchema([
+                { field: 'addType', ifShow: true },
+                { field: 'dbip', ifShow: true },
+                { field: 'dbloginname', ifShow: true },
+                { field: 'pwd', ifShow: true },
+                { field: 'dbname', ifShow: true },
+                { field: 'dbid', ifShow: false }
+            ])
+        }
+        // 提交信息
+        const handleSubmit = () => {
+            validate().then(async (res) => {
+                if (res) {
+                    // 新增数据库,需要先保存数据库信息
+                    // if (res.dbType === '0') {
+                    //     let { dbip, dbloginname, pwd, dbname, bfsm } = getFieldsValue();
+                    //     let dbInfo = await editBackupsDatabase({ dbip, dbloginname, pwd, dbname });
+                    //     if (dbInfo.resp_code === 0 && dbInfo.datas) {
+                    //         let dbid = dbInfo.datas.dbid;
+                    //         await addDataBackup({ dbBackups:{dbid, bfsm}});
+                    //     } else {
+                    //         message.error('保存数据库信息失败');
+                    //     }
+                    // } 
+                    // // 已有数据库,直接用dbid备份
+                    // else {
+                    //     let { dbid, bfsm } = getFieldsValue();
+                    //     await addDataBackup({ dbBackups:{dbid, bfsm}});
+                    // }
+                    console.log('res', res);
+                    // 关闭弹窗
+                    closeModal();
+                    // 触发父组件事件
+                    emit('success', res);
+                }
+            });
+        };
+        return {
+            registerModal,
+            registerForm,
+            handleSubmit,
+        };
+    },
+});
+</script>

+ 99 - 0
src/views/dataAdmin/dataAdmin/dataBackup/ScheduledTaskManageModal.vue

@@ -0,0 +1,99 @@
+<template>
+    <BasicModal :maskClosable="false" :width="440" @register="registerModal" v-bind="$attrs" :title="getTitle" centered
+        @ok="handleSubmit">
+        <BasicForm @register="registerForm" />
+    </BasicModal>
+</template>
+<script>
+import { defineComponent, reactive, ref, onMounted, watch, computed } from 'vue';
+import { BasicModal, useModalInner } from '/@/components/Modal';
+import { BasicForm, useForm } from '/@/components/Form/index';
+import { message } from 'ant-design-vue';
+import { scheduledTaskformSchema } from './dataBackup.data';
+import { editBackupsDatabase, EditScheduledTaskCL } from '/@/api/sys/dataBackUp';
+
+export default defineComponent({
+    name: 'scheduledTaskManageModal',
+    components: { BasicModal, BasicForm },
+    setup(_, { emit }) {
+        const modalStatus = ref('add')
+        const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+            console.log(data)
+            resetForm();
+            if (data.status === 'add') {
+                updateSchema({ field: 'dbType', ifShow: true })
+            } else if (data.status === 'edit') {
+                updateSchema([
+                    { field: 'dbType', ifShow: false }
+                ])
+                // const { FID, VERSION_NAME, VERSION_NO, VERSION_DISP } = data.form;
+                // setFieldsValue({
+                //     fid: FID,
+                //     version_NAME: VERSION_NAME,
+                //     version_NO: VERSION_NO,
+                //     version_DISP: VERSION_DISP
+                // })
+            }
+            modalStatus.value = data.status;
+        });
+        const [registerForm, { setFieldsValue, updateSchema, resetFields, validate, getFieldsValue }] = useForm({
+            schemas: scheduledTaskformSchema,
+            labelCol: { span: 6 },
+            wrapperCol: { span: 16 },
+            showActionButtonGroup: false
+        });
+        const getTitle = computed(() => {
+            if (modalStatus.value === 'add') {
+                return '新增任务'
+            } else if (modalStatus.value === 'edit') {
+                return '编辑任务'
+            }
+        })
+        const resetForm = () => {
+            resetFields();
+            updateSchema([
+                { field: 'dbip', ifShow: true },
+                { field: 'dbloginname', ifShow: true },
+                { field: 'pwd', ifShow: true },
+                { field: 'dbname', ifShow: true },
+                { field: 'bfFid', ifShow: false },
+                { field: 'sjsz', componentProps: { options: [] } }
+            ])
+        }
+        // 提交信息
+        const handleSubmit = () => {
+            validate().then(async (res) => {
+                if (res) {
+                    // 新增数据库,需要先保存数据库信息
+                    // if (res.dbType === '0') {
+                    //     let { dbip, dbloginname, pwd, dbname, bfzq, sjsz, zxsj, status } = getFieldsValue();
+                    //     let dbInfo = await editBackupsDatabase({ dbip, dbloginname, pwd, dbname });
+                    //     if (dbInfo.resp_code === 0 && dbInfo.datas) {
+                    //         let bfFid = dbInfo.datas.dbid;
+                    //         await EditScheduledTaskCL({ bfFid, bfsm });
+                    //     } else {
+                    //         message.error('保存数据库信息失败');
+                    //     }
+                    // }
+                    // // 已有数据库,直接用dbid备份
+                    // else {
+                    //     let { bfFid, bfzq, sjsz, zxsj, status } = getFieldsValue();
+                    //     await EditScheduledTaskCL({ bfFid, bfzq, sjsz, zxsj, status });
+                    // }
+                    console.log('res', res);
+                    // 关闭弹窗
+                    closeModal();
+                    // 触发父组件事件
+                    emit('success', res);
+                }
+            });
+        };
+        return {
+            getTitle,
+            registerModal,
+            registerForm,
+            handleSubmit,
+        };
+    },
+});
+</script>

+ 236 - 0
src/views/dataAdmin/dataAdmin/dataBackup/ScheduledTaskModal.vue

@@ -0,0 +1,236 @@
+<template>
+    <BasicModal :maskClosable="false" :width="1430" @register="registerModal" v-bind="$attrs" title="定时备份任务" centered
+        :showOkBtn="false" :showCancelBtn="false" wrapClassName="scheduled-task-modal" :footer="null">
+        <div class="custom-content">
+            <div class="right-header">
+                <div class="search">
+                    <span class="label">关键字:</span>
+                    <a-input v-model:value="searchValue" placeholder="输入关键字查询" allow-clear />
+                </div>
+                <div class="handle-btns">
+                    <a-button class="btn" @click="resetTable">重置</a-button>
+                    <a-button class="btn" type="primary" @click="searchTable">查询</a-button>
+                </div>
+            </div>
+            <div class="right-body">
+                <BasicTable @register="registerTable">
+                    <template #toolbar>
+                        <Button type="primary" @click="handleAddTask">
+                            新增任务
+                        </Button>
+                    </template>
+                    <template #action="{ record }">
+                        <TableAction :actions="[
+                            {
+                                label: '编辑',
+                                tooltip: '编辑',
+                                onClick: handleEditTask.bind(null, record),
+                            },
+                            {
+                                label: '删除',
+                                tooltip: '删除',
+                                onClick: handleDelTask.bind(null, record),
+                            }
+                        ]" />
+                    </template>
+                </BasicTable>
+            </div>
+        </div>
+    </BasicModal>
+    <ScheduledTaskManageModal @register="registerManageModal"></ScheduledTaskManageModal>
+</template>
+<script>
+import { defineComponent, reactive, ref, onMounted, watch, computed } from 'vue';
+import { BasicModal, useModalInner, useModal } from '/@/components/Modal';
+// 导入表格组件,表格事件
+import { BasicTable, useTable, TableAction } from '/@/components/Table';
+import { Button, message } from 'ant-design-vue';
+import { getScheduledTaskCL } from '/@/api/sys/dataBackUp';
+import moment from 'moment';
+import ScheduledTaskManageModal from './ScheduledTaskManageModal.vue';
+
+export default defineComponent({
+    name: 'scheduledTaskModal',
+    components: { BasicModal, BasicTable, TableAction, Button, ScheduledTaskManageModal },
+    setup(_, { emit }) {
+        const searchValue = ref('')
+        const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
+            console.log(data)
+            reload();
+        });
+        const [registerManageModal, { openModal: openManageModal }] = useModal();
+
+        const getScheduledTaskData = () => {
+            return new Promise((resolve, reject) => {
+                let params = {
+                    keyStr: searchValue.value
+                }
+                getScheduledTaskCL(params).then(res => {
+                    if (res.resp_code === 0 && res.datas) {
+                        let resData = res.datas.pageData;
+                        resolve(resData)
+                    }
+                    else {
+                        resolve([])
+                        message.error(res.resp_msg)
+                    }
+                })
+            })
+        }
+        //表格列
+        const columns = [
+            {
+                title: '资源类型',
+                align: 'center',
+                dataIndex: 'type',
+                key: 'type'
+            },
+            {
+                title: '资源名称',
+                align: 'center',
+                dataIndex: 'SERVICENAME',
+                key: 'SERVICENAME'
+            },
+            {
+                title: '版本',
+                align: 'center',
+                dataIndex: 'VERSION_NAME',
+                key: 'VERSION_NAME'
+            },
+            {
+                title: '版本号',
+                align: 'center',
+                dataIndex: 'VERSION',
+                key: 'VERSION'
+            },
+            {
+                title: '操作时间',
+                align: 'center',
+                dataIndex: 'MODIFY_DATE',
+                key: 'MODIFY_DATE'
+            },
+            {
+                title: '操作人',
+                align: 'center',
+                dataIndex: 'USER_NAME',
+                key: 'USER_NAME'
+            }
+        ];
+        const [
+            registerTable,
+            { reload, collapseAll, getRowSelection, getSelectRowKeys, setSelectedRowKeys },
+        ] = useTable({
+            title: '定时备份任务列表',
+            api: getScheduledTaskData,
+            columns: columns,
+            useSearchForm: false,
+            bordered: false,
+            showTableSetting: true,
+            tableSetting: {
+                redo: true,
+                size: true,
+                setting: false,
+                fullScreen: false
+            },
+            showIndexColumn: true,
+            pagination: {
+                hideOnSinglePage: false
+            },
+            rowKey: (record) => record.fid,
+            actionColumn: {
+                width: 200,
+                title: '操作',
+                dataIndex: 'action',
+                slots: { customRender: 'action' },
+            }
+        });
+        //表格查询功能
+        const searchTable = () => {
+            reload()
+        }
+        //重置
+        const resetTable = () => {
+            searchValue.value = '';
+            reload();
+        }
+        const handleAddTask = () => {
+            openManageModal(true,{
+                status:'add'
+            });
+        }
+        const handleEditTask = () => {
+            openManageModal(true,{
+                status:'edit'
+            });
+        }
+        const handleDelTask = () => {
+
+        }
+        return {
+            searchValue,
+            registerModal,
+            registerManageModal,
+            registerTable,
+            resetTable,
+            searchTable,
+            handleAddTask,
+            handleEditTask,
+            handleDelTask
+        };
+    },
+});
+</script>
+<style lang="less">
+.scheduled-task-modal {
+
+    .ant-modal-content {
+        background-color: #eff0f5;
+
+        .scroll-container .scrollbar__wrap {
+            margin-bottom: 0 !important;
+        }
+    }
+}
+</style>
+<style lang="less" scoped>
+.custom-content {
+
+    .right-header {
+        margin-bottom: 10px;
+        height: 74px;
+        padding: 0 20px;
+        display: flex;
+        align-items: center;
+        background-color: #ffffff;
+        border-radius: 6px;
+        justify-content: space-between;
+
+        .search {
+            display: flex;
+            align-items: center;
+
+            .label {
+                // width: 120px;
+                margin-right: 10px;
+                white-space: nowrap;
+            }
+        }
+
+        .handle-btns {
+            display: flex;
+            align-items: center;
+
+            .btn {
+                margin-left: 10px;
+            }
+        }
+    }
+
+    .right-body {
+        padding: 0 20px;
+        height: calc(100% - 84px);
+        background-color: #ffffff;
+        border-radius: 6px;
+    }
+}
+</style>

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

@@ -1,161 +0,0 @@
-<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>

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

@@ -1,72 +0,0 @@
-<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>

+ 378 - 0
src/views/dataAdmin/dataAdmin/dataBackup/dataBackup.data.ts

@@ -0,0 +1,378 @@
+import { FormSchema } from '/@/components/Table';
+import { getBackupsDatabaseList } from '/@/api/sys/dataBackUp';
+import moment from 'moment';
+
+const getBackupsDatabaseSelect = () => {
+    return new Promise((resolve) => {
+        let params = {
+            keyStr: ""
+        }
+        getBackupsDatabaseList(params).then(res => {
+            if (res.resp_code === 0 && res.datas) {
+                let resData: Array<{ label: string, value: string }> = []
+                res.datas.pageData.forEach(element => {
+                    resData.push(
+                        {
+                            label: element.dbname,
+                            value: element.fid
+                        }
+                    )
+                });
+                resolve(resData)
+            }
+            else {
+                resolve([])
+            }
+        })
+    })
+}
+export const formSchema: FormSchema[] = [
+    {
+        field: 'fid',
+        label: '备份id',
+        component: 'Input',
+        ifShow: false
+    },
+    {
+        field: 'dbType',
+        label: '数据库',
+        component: 'RadioGroup',
+        ifShow: true,
+        required: true,
+        defaultValue: '0',
+        componentProps({ formActionType }) {
+            const { updateSchema } = formActionType;
+            return {
+                options: [
+                    {
+                        label: '新增记录',
+                        value: '0'
+                    },
+                    {
+                        label: '已有记录',
+                        value: '1'
+                    }
+                ],
+                onChange(event: ChangeEvent) {
+                    if ((event.target as HTMLInputElement).value === "0") {
+                        updateSchema([
+                            { field: 'dbip', ifShow: true },
+                            { field: 'dbloginname', ifShow: true },
+                            { field: 'pwd', ifShow: true },
+                            { field: 'dbname', ifShow: true },
+                            { field: 'dbid', ifShow: false }
+                        ])
+                    } else {
+                        updateSchema([
+                            { field: 'dbip', ifShow: false },
+                            { field: 'dbloginname', ifShow: false },
+                            { field: 'pwd', ifShow: false },
+                            { field: 'dbname', ifShow: false },
+                            { field: 'dbid', ifShow: true }
+                        ])
+                    }
+                },
+                disabled: false
+            };
+        },
+    },
+    {
+        field: 'dbip',
+        label: '数据库ip',
+        component: 'Input',
+        ifShow: true,
+        required: true,
+        componentProps: {
+            maxLength: 36,
+            placeholder: '请输入数据库ip',
+            disabled: false
+        },
+    },
+    {
+        field: 'dbloginname',
+        label: '数据库登录名',
+        component: 'Input',
+        ifShow: true,
+        required: true,
+        componentProps: {
+            maxLength: 36,
+            placeholder: '请输入数据库登录名',
+            disabled: false
+        },
+    },
+    {
+        field: 'pwd',
+        label: '数据库密码',
+        component: 'Input',
+        ifShow: true,
+        required: true,
+        componentProps: {
+            maxLength: 36,
+            placeholder: '请输入数据库密码',
+            disabled: false
+        },
+    },
+    {
+        field: 'dbname',
+        label: '数据库名称',
+        component: 'Input',
+        ifShow: true,
+        required: true,
+        componentProps: {
+            maxLength: 36,
+            placeholder: '请输入数据库名称',
+            disabled: false
+        },
+    },
+    {
+        field: 'dbid',
+        label: '数据库名称',
+        component: 'ApiSelect',
+        ifShow: false,
+        required: true,
+        componentProps: {
+            api: getBackupsDatabaseSelect,
+            placeholder: '请选择数据库',
+            disabled: false
+        },
+    },
+    {
+        field: 'bfsm',
+        label: '备份说明',
+        component: 'Input',
+        ifShow: true,
+        required: true,
+        componentProps: {
+            maxLength: 255,
+            placeholder: '请输入备份说明',
+            disabled: false
+        },
+    },
+];
+
+const weeks = [
+    {
+        label: "星期一",
+        value: 1
+    },
+    {
+        label: "星期二",
+        value: 2
+    },
+    {
+        label: "星期三",
+        value: 3
+    },
+    {
+        label: "星期四",
+        value: 4
+    },
+    {
+        label: "星期五",
+        value: 5
+    },
+    {
+        label: "星期六",
+        value: 6
+    },
+    {
+        label: "星期日",
+        value: 7
+    }
+];
+const days = [];
+for (let i = 1; i <= 31; i++) {
+    days.push({
+        label: i.toString() + '号',
+        value: i
+    });
+}
+
+export const scheduledTaskformSchema: FormSchema[] = [
+    {
+        field: 'fid',
+        label: '定时任务id',
+        component: 'Input',
+        ifShow: false
+    },
+    {
+        field: 'dbType',
+        label: '数据库',
+        component: 'RadioGroup',
+        ifShow: true,
+        required: true,
+        defaultValue: '0',
+        componentProps({ formActionType }) {
+            const { updateSchema } = formActionType;
+            return {
+                options: [
+                    {
+                        label: '新增记录',
+                        value: '0'
+                    },
+                    {
+                        label: '已有记录',
+                        value: '1'
+                    }
+                ],
+                onChange(event: ChangeEvent) {
+                    if ((event.target as HTMLInputElement).value === "0") {
+                        updateSchema([
+                            { field: 'dbip', ifShow: true },
+                            { field: 'dbloginname', ifShow: true },
+                            { field: 'pwd', ifShow: true },
+                            { field: 'dbname', ifShow: true },
+                            { field: 'bfFid', ifShow: false }
+                        ])
+                    } else {
+                        updateSchema([
+                            { field: 'dbip', ifShow: false },
+                            { field: 'dbloginname', ifShow: false },
+                            { field: 'pwd', ifShow: false },
+                            { field: 'dbname', ifShow: false },
+                            { field: 'bfFid', ifShow: true }
+                        ])
+                    }
+                },
+                disabled: false
+            };
+        },
+    },
+    {
+        field: 'dbip',
+        label: '数据库ip',
+        component: 'Input',
+        ifShow: true,
+        required: true,
+        componentProps: {
+            maxLength: 36,
+            placeholder: '请输入数据库ip',
+            disabled: false
+        },
+    },
+    {
+        field: 'dbloginname',
+        label: '数据库登录名',
+        component: 'Input',
+        ifShow: true,
+        required: true,
+        componentProps: {
+            maxLength: 36,
+            placeholder: '请输入数据库登录名',
+            disabled: false
+        },
+    },
+    {
+        field: 'pwd',
+        label: '数据库密码',
+        component: 'Input',
+        ifShow: true,
+        required: true,
+        componentProps: {
+            maxLength: 36,
+            placeholder: '请输入数据库密码',
+            disabled: false
+        },
+    },
+    {
+        field: 'dbname',
+        label: '数据库名称',
+        component: 'Input',
+        ifShow: true,
+        required: true,
+        componentProps: {
+            maxLength: 36,
+            placeholder: '请输入数据库名称',
+            disabled: false
+        },
+    },
+    {
+        field: 'bfFid',
+        label: '数据库名称',
+        component: 'ApiSelect',
+        ifShow: false,
+        required: true,
+        componentProps: {
+            api: getBackupsDatabaseSelect,
+            placeholder: '请选择数据库',
+            disabled: false
+        },
+    },
+    {
+        field: 'bfzq',
+        label: '备份周期',
+        component: 'Select',
+        ifShow: true,
+        required: true,
+        componentProps({ formActionType }) {
+            const { updateSchema, setFieldsValue } = formActionType;
+            return {
+                options: [
+                    {
+                        label: '每周',
+                        value: 1
+                    },
+                    {
+                        label: '每月',
+                        value: 2
+                    }
+                ],
+                onChange(event) {
+                    if (event === 1) {
+                        updateSchema({ field: 'sjsz', componentProps: { options: weeks } })
+                        setFieldsValue({ sjsz: '' })
+                    } else {
+                        updateSchema({ field: 'sjsz', componentProps: { options: days } })
+                        setFieldsValue({ sjsz: '' })
+                    }
+                },
+                disabled: false
+            };
+        },
+    },
+    {
+        field: 'sjsz',
+        label: '时间设置',
+        component: 'Select',
+        ifShow: true,
+        required: true,
+        componentProps: {
+            options: [],
+            placeholder: '请选择备份周期',
+            disabled: false
+        },
+    },
+    {
+        field: 'zxsj',
+        label: '执行时间',
+        component: 'TimePicker',
+        ifShow: true,
+        required: true,
+        defaultValue: moment('00:00', 'HH:mm'),
+        componentProps: {
+            format: "HH:mm",
+            placeholder: '请选择执行时间',
+            disabled: false
+        },
+    },
+    {
+        field: 'status',
+        label: '是否启用',
+        component: 'RadioGroup',
+        ifShow: true,
+        required: true,
+        defaultValue: '1',
+        componentProps: {
+            options: [
+                {
+                    label: '禁用',
+                    value: '0'
+                },
+                {
+                    label: '启用',
+                    value: '1'
+                }
+            ],
+        },
+    },
+];

+ 176 - 342
src/views/dataAdmin/dataAdmin/dataBackup/index.vue

@@ -1,13 +1,19 @@
 <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 class="search-box">
+                <div class="search-item">
+                    <div class="search-name">数据库:</div>
+                    <a-input v-model:value="searchValue" placeholder="输入关键字查询" allow-clear />
+                </div>
+                <div class="search-item">
+                    <div class="search-name">备份时间:</div>
+                    <a-range-picker style="width: 400px" v-model:value="searchDate" :disabled-date="disabledDate"
+                        :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss" />
+                </div>
             </div>
             <div class="handle-btns">
-                <!-- <span class="label">版本名称:</span> -->
-                <a-button class="btn" @click="searchTable">重置</a-button>
+                <a-button class="btn" @click="resetTable">重置</a-button>
                 <a-button class="btn" type="primary" @click="searchTable">查询</a-button>
             </div>
         </div>
@@ -15,385 +21,205 @@
         <div class="backup-body">
             <BasicTable @register="registerTable">
                 <template #toolbar>
-                    <Button type="primary" @click="openDialog(null)">
+                    <Button type="primary" @click="handleSetScheduledTask">
+                        定时备份策略
+                    </Button>
+                    <Button type="primary" @click="handleAddDataBackUp">
                         新增备份
                     </Button>
-                    <Button type="primary" danger :disabled="hasSelected" @click="delAllData">
+                    <Button type="primary" danger :disabled="hasSelected" @click="handleDelAllDataBackUp">
                         批量删除
                     </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),
+                            onClick: handleDelDataBackUp.bind(null, record),
                         },
                         {
                             label: '下载',
                             tooltip: '下载',
-                            onClick: openDialog.bind(null, record),
-                        },
-                        {
-                            label: '恢复',
-                            tooltip: '恢复',
-                            onClick: onDelete.bind(null, record.vid),
-                        },
+                            onClick: handleDownloadDataBackUp.bind(null, record),
+                        }
                     ]" />
                 </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> -->
+        <AddDataBackUpModal @register="registerModal" @success="onSubmit"></AddDataBackUpModal>
+        <ScheduledTaskModal @register="registerTaskModal" @success="onSubmit"></ScheduledTaskModal>
     </div>
 </template>
 
 <script>
-import { defineComponent, reactive, ref, toRefs, computed, onMounted, watch, createVNode } from 'vue';
+import { defineComponent, reactive, ref, toRefs, computed, onMounted } 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 { useModal } from '/@/components/Modal';
+import { Button, message } from 'ant-design-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'
-    })
-}
+import { getBackupsList, downloadDBFile, delDataBackup } from '/@/api/sys/dataBackUp';
+import uiTool from '/@/utils/uiTool';
+import AddDataBackUpModal from './AddDataBackUpModal.vue';
+import ScheduledTaskModal from './ScheduledTaskModal.vue';
 
 export default defineComponent({
     name: 'backup',
-    // components: { VersionDrawer, ExclamationCircleOutlined, VersionModal, BasicTable, TableAction, Button },
-    components: {  ExclamationCircleOutlined, BasicTable, TableAction, Button },
+    components: { BasicTable, TableAction, Button, AddDataBackUpModal, ScheduledTaskModal },
     setup() {
-        const drawerRef = ref(null)
+        const [registerModal, { openModal }] = useModal();
+        const [registerTaskModal, { openModal: openTaskModal }] = useModal();
+        // 搜索数据
         const data = reactive({
             searchValue: "",//查询值
-            formData: {
-                dataVersionConfs: [],
-                description: "",
-                insertTime: "",
-                name: "",
-                type: "",
-                updateTime: "",
-                vid: "",
-            },
-            drawerTitle: "新增版本",
-            ifShowDialog: false,
-            ifShowModal: false
+            searchDate: []
         });
-        //资源列表数据
-        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'
+        // 禁选时间
+        const disabledDate = (current) => {
+            return current && current > moment().endOf('day');
+        };
+        //获取所有备份数据
+        const getDataBackUp = () => {
+            return new Promise((resolve, reject) => {
+                resolve([])
+                let params = {
+                    keyStr: data.searchValue,
+                    satrttime: data.searchDate.length ? moment(data.searchDate[0]).format('YYYY-MM-DD HH:mm:ss') : null,
+                    endtime: data.searchDate.length ? moment(data.searchDate[1]).format('YYYY-MM-DD HH:mm:ss') : null
                 }
-            ],
-            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)
-        //         })
-        //     })
-
-        // }
+                getBackupsList(params).then((res) => {
+                    if (res.resp_code === 0 && res.datas) {
+                        resolve(res.datas.pageData)
+                    }
+                    else {
+                        resolve([])
+                        message.error(res.resp_msg)
+                    }
+                })
+            })
 
-        //筛选数据,用于表格
-        // 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 columns = [
+            {
+                title: '数据库IP',
+                align: 'center',
+                dataIndex: 'dbIp',
+                key: 'dbIp',
+            },
+            {
+                title: '数据库名称',
+                align: 'center',
+                dataIndex: 'dbName',
+                key: 'dbName',
+            },
+            {
+                title: '备份说明',
+                align: 'center',
+                dataIndex: 'description',
+                key: 'description'
+            },
+            {
+                title: '操作人',
+                align: 'center',
+                dataIndex: 'optUser',
+                key: 'optUser'
+            },
+            {
+                title: '备份时间',
+                align: 'center',
+                dataIndex: 'optTime',
+                key: 'optTime'
+            }
+        ];
+        // 重置
+        const resetTable = () => {
+            data.searchValue = '';
+            data.searchDate = [];
+            reload();
+        }
+        // 查询
         const searchTable = () => {
-            // filteredInfo.value.name = [data.searchValue]
+            reload();
         }
-        //判断是否选中数据
+        // 判断是否选中数据
         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 handleSetScheduledTask = () => {
+            openTaskModal(true)
+        }
+        // 新增备份数据
+        const handleAddDataBackUp = () => {
+            openModal(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 handleDelAllDataBackUp = () => {
+            uiTool.delModal('确定删除选中的备份数据?', (() => {
+                const rowKeys = getSelectRowKeys();
+                let ids = rowKeys.toString()
+                let param = {
+                    fid: ids
+                }
+                delDataBackup(param).then(res => {
+                    if (res.resp_code === 0) {
+                        message.success('操作成功');
+                        reload();
+                        setSelectedRowKeys([])
+                    }
                 })
-            });
-
+            }))
         }
-        //打开弹窗展示资源
-        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 handleDelDataBackUp = (record) => {
+            uiTool.delModal('确定删除该备份数据?', (() => {
+                let param = {
+                    fid: record.fid
+                }
+                delDataBackup(param).then(res => {
+                    if (res.resp_code === 0) {
+                        reload();
+                        setSelectedRowKeys([])
+                    }
+                })
+            }))
         }
-        //弹窗确认
-        const onSubmit = (e) => {
-            data.ifShowDialog = false
-            if (e) {
-                reload();
+        // 下载备份数据
+        const handleDownloadDataBackUp = (record) => {
+            let param = {
+                fid: record.fid
             }
+            downloadDBFile(param).then(res => {
+                if (res.resp_code === 0) {
+                    reload();
+                    setSelectedRowKeys([])
+                }
+            })
+        }
+        // 弹窗确认
+        const onSubmit = () => {
+            reload();
         }
         const [
             registerTable,
             { reload, collapseAll, getRowSelection, getSelectRowKeys, setSelectedRowKeys },
         ] = useTable({
             title: '数据备份列表', //'菜单列表'
-            // api: getVersionData, //加载数据,暂时没有接口用假数据
-            dataSource: restoreData,//假数据
+            api: getDataBackUp, //加载数据,暂时没有接口用假数据
+            // dataSource: restoreData,//假数据
             columns: columns,
             useSearchForm: false,     //开启搜索区域
-            bordered: true,
+            bordered: false,
             showTableSetting: true,  // 显示表格设置
             showIndexColumn: true,
             pagination: {
                 // pageSize: 10,
                 hideOnSinglePage: false
             },
-            rowKey: (record) => record.id,
+            rowKey: (record) => record.fid,
             actionColumn: {
                 width: 200,
                 title: '操作',
@@ -411,20 +237,21 @@ export default defineComponent({
             },
         });
         return {
-            drawerRef,
-            // filteredInfo,
+            disabledDate,
             columns,
             hasSelected,
             ...toRefs(data),
-            ...toRefs(sourcesData),
             // func
             registerTable,
-            // getVersionData,
+            registerModal,
+            registerTaskModal,
+            resetTable,
             searchTable,
-            delAllData,
-            onDelete,
-            openModal,
-            openDialog,
+            handleSetScheduledTask,
+            handleAddDataBackUp,
+            handleDelAllDataBackUp,
+            handleDelDataBackUp,
+            handleDownloadDataBackUp,
             onSubmit
         };
     },
@@ -436,7 +263,8 @@ export default defineComponent({
     height: 100%;
 
     .backup-header {
-        padding: 10px;
+        // padding: 10px;
+        padding: 0 20px;
         width: 100%;
         height: 70px;
         background-color: #fff;
@@ -444,21 +272,27 @@ export default defineComponent({
         justify-content: space-between;
         align-items: center;
 
-        .backup-title {
-            font-size: 16px;
-            font-weight: 500;
-            margin-left: 20px;
-            user-select: none;
+        .search-box {
             display: flex;
-            align-items: center;
 
-            .search-name {
-                width: 100px;
+            .search-item {
+                display: flex;
+                align-items: center;
+
+                &:last-child {
+                    margin-left: 20px;
+                }
+
+                .search-name {
+                    margin-right: 10px;
+                    // width: 100px;
+                    white-space: nowrap
+                }
             }
         }
 
         .handle-btns {
-            margin-right: 20px;
+            // margin-right: 20px;
             display: flex;
             align-items: center;
 

+ 55 - 0
src/views/dataAdmin/dataAdmin/dataRestore/DataRestoreModal.vue

@@ -0,0 +1,55 @@
+<template>
+    <BasicModal :maskClosable="false" :width="440" @register="registerModal" v-bind="$attrs" title="数据恢复" centered
+        @ok="handleSubmit">
+        <BasicForm @register="registerForm" />
+    </BasicModal>
+</template>
+<script>
+import { defineComponent, reactive, ref, onMounted, watch, computed } from 'vue';
+import { BasicModal, useModalInner } from '/@/components/Modal';
+import { BasicForm, useForm } from '/@/components/Form/index';
+import { message } from 'ant-design-vue';
+import { formSchema } from './dataRestore.data';
+import { dataRestore } from '/@/api/sys/dataBackUp';
+import { session } from '/@/utils/Memory';
+
+export default defineComponent({
+    name: 'scheduledTaskManageModal',
+    components: { BasicModal, BasicForm },
+    setup(_, { emit }) {
+        const [registerModal, { closeModal }] = useModalInner(async (data) => {
+            console.log(data)
+            resetFields();
+            setFieldsValue({
+                bfFid: data.bfFid
+            });
+        });
+        const [registerForm, { setFieldsValue, updateSchema, resetFields, validate, getFieldsValue }] = useForm({
+            schemas: formSchema,
+            labelCol: { span: 6 },
+            wrapperCol: { span: 16 },
+            showActionButtonGroup: false
+        });
+        // 提交信息
+        const handleSubmit = () => {
+            validate().then(async (res) => {
+                if (res) {
+                    // const { bfFid, bfsm } = getFieldsValue();
+                    // const userid = session.getItem('userId')
+                    // await dataRestore({bfFid, bfsm, userid})
+                    console.log('res', res);
+                    // 关闭弹窗
+                    closeModal();
+                    // 触发父组件事件
+                    emit('success', res);
+                }
+            });
+        };
+        return {
+            registerModal,
+            registerForm,
+            handleSubmit,
+        };
+    },
+});
+</script>

+ 22 - 0
src/views/dataAdmin/dataAdmin/dataRestore/dataRestore.data.ts

@@ -0,0 +1,22 @@
+import { FormSchema } from '/@/components/Table';
+
+export const formSchema: FormSchema[] = [
+    {
+        field: 'bfFid',
+        label: '数据库id',
+        component: 'Input',
+        ifShow: false
+    },
+    {
+        field: 'bfsm',
+        label: '恢复说明',
+        component: 'InputTextArea',
+        ifShow: true,
+        required: true,
+        componentProps: {
+            maxLength: 255,
+            placeholder: '请输入恢复说明',
+            disabled: false
+        },
+    }
+];

+ 304 - 0
src/views/dataAdmin/dataAdmin/dataRestore/index.vue

@@ -0,0 +1,304 @@
+<template>
+    <div class="p-4">
+        <div class="backup-header">
+            <div class="search-box">
+                <div class="search-item">
+                    <div class="search-name">数据库:</div>
+                    <a-input v-model:value="searchValue" placeholder="输入关键字查询" allow-clear />
+                </div>
+                <div class="search-item">
+                    <div class="search-name">备份时间:</div>
+                    <a-range-picker style="width: 400px" v-model:value="searchDate" :disabled-date="disabledDate"
+                        :show-time="{ format: 'HH:mm:ss' }" format="YYYY-MM-DD HH:mm:ss" />
+                </div>
+                <div class="search-item">
+                    <div class="search-name">恢复状态:</div>
+                    <a-radio-group v-model:value="searchStatus" style="display: flex;">
+                        <a-radio :value="0">未恢复</a-radio>
+                        <a-radio :value="1">已恢复</a-radio>
+                    </a-radio-group>
+                </div>
+            </div>
+            <div class="handle-btns">
+                <a-button class="btn" @click="resetTable">重置</a-button>
+                <a-button class="btn" type="primary" @click="searchTable">查询</a-button>
+            </div>
+        </div>
+
+        <div class="backup-body">
+            <BasicTable @register="registerTable">
+                <template #action="{ record }">
+                    <TableAction :actions="[
+                        {
+                            label: '恢复',
+                            tooltip: '恢复',
+                            onClick: handleRestore.bind(null, record),
+                        }
+                    ]" />
+                </template>
+            </BasicTable>
+        </div>
+        <DataRestoreModal @register="registerModal" @success="onSubmit"></DataRestoreModal>
+    </div>
+</template>
+
+<script>
+import { defineComponent, reactive, ref, toRefs, computed, onMounted } from 'vue';
+// 导入表格组件,表格事件
+import { BasicTable, useTable, TableAction } from '/@/components/Table';
+import { useModal } from '/@/components/Modal';
+import { Button, message } from 'ant-design-vue';
+import moment from 'moment'
+import { getBackupsList } from '/@/api/sys/dataBackUp';
+import DataRestoreModal from './DataRestoreModal.vue';
+
+export default defineComponent({
+    name: 'dataRestore',
+    components: { BasicTable, TableAction, Button, DataRestoreModal },
+    setup() {
+        const [registerModal, { openModal }] = useModal();
+        // 搜索数据
+        const data = reactive({
+            searchValue: "",//查询值
+            searchDate: [],
+            searchStatus: 0,
+        });
+        // 禁选时间
+        const disabledDate = (current) => {
+            return current && current > moment().endOf('day');
+        };
+        //获取所有备份数据
+        const getDataBackUp = () => {
+            return new Promise((resolve, reject) => {
+                resolve([])
+                let params = {
+                    keyStr: data.searchValue,
+                    satrttime: data.searchDate.length ? moment(data.searchDate[0]).format('YYYY-MM-DD HH:mm:ss') : null,
+                    endtime: data.searchDate.length ? moment(data.searchDate[1]).format('YYYY-MM-DD HH:mm:ss') : null
+                }
+                getBackupsList(params).then((res) => {
+                    if (res.resp_code === 0 && res.datas) {
+                        resolve(res.datas.pageData)
+                    }
+                    else {
+                        resolve([])
+                        message.error(res.resp_msg)
+                    }
+                })
+            })
+        }
+        //表格列
+        const columns = [
+            {
+                title: '数据库IP',
+                align: 'center',
+                dataIndex: 'dbIp',
+                key: 'dbIp',
+            },
+            {
+                title: '数据库名称',
+                align: 'center',
+                dataIndex: 'dbName',
+                key: 'dbName',
+            },
+            {
+                title: '备份说明',
+                align: 'center',
+                dataIndex: 'bfsm',
+                key: 'bfsm'
+            },
+            {
+                title: '备份人',
+                align: 'center',
+                dataIndex: 'czr',
+                key: 'czr'
+            },
+            {
+                title: '备份时间',
+                align: 'center',
+                dataIndex: 'czsj',
+                key: 'czsj'
+            },
+            {
+                title: '恢复时间',
+                align: 'center',
+                dataIndex: 'hfsj',
+                key: 'hfsj'
+            },
+            {
+                title: '恢复人',
+                align: 'center',
+                dataIndex: 'hfr',
+                key: 'hfr'
+            },
+            {
+                title: '恢复说明',
+                align: 'center',
+                dataIndex: 'hfjgsm',
+                key: 'hfjgsm'
+            },
+            {
+                title: '恢复结果',
+                align: 'center',
+                dataIndex: 'hfjg',
+                key: 'hfjg'
+            },
+        ];
+        // 重置
+        const resetTable = () => {
+            data.searchValue = '';
+            data.searchDate = [];
+            data.searchStatus = 0;
+            reload();
+        }
+        // 查询
+        const searchTable = () => {
+            reload();
+        }
+        // 备份数据恢复
+        const handleRestore = (record) => {
+            openModal(true, {
+                bfFid: record.dbid
+            })
+        }
+        // 弹窗确认
+        const onSubmit = () => {
+            reload();
+        }
+        const [registerTable, { reload }] = useTable({
+            title: '数据备份列表', //'菜单列表'
+            api: getDataBackUp, //加载数据,暂时没有接口用假数据
+            columns: columns,
+            useSearchForm: false,     //开启搜索区域
+            bordered: false,
+            showTableSetting: true,  // 显示表格设置
+            showIndexColumn: true,
+            pagination: {
+                hideOnSinglePage: false
+            },
+            rowKey: (record) => record.fid,
+            actionColumn: {
+                width: 200,
+                title: '操作',
+                dataIndex: 'action',
+                slots: { customRender: 'action' },
+            },
+            rowSelection: {
+                type: 'checkbox',
+            },
+            tableSetting: {
+                redo: true,
+                size: true,
+                setting: false,
+                fullScreen: false
+            },
+        });
+        return {
+            disabledDate,
+            columns,
+            ...toRefs(data),
+            // func
+            registerTable,
+            registerModal,
+            resetTable,
+            searchTable,
+            handleRestore,
+            onSubmit
+        };
+    },
+});
+</script>
+
+<style lang="less" scoped>
+.p-4 {
+    height: 100%;
+
+    .backup-header {
+        // padding: 10px;
+        padding: 0 20px;
+        width: 100%;
+        height: 70px;
+        background-color: #fff;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+
+        .search-box {
+            display: flex;
+
+            .search-item {
+                display: flex;
+                align-items: center;
+                margin-left: 20px;
+
+                &:first-child {
+                    margin-left: 0;
+                }
+
+                .search-name {
+                    margin-right: 10px;
+                    // width: 100px;
+                    white-space: nowrap
+                }
+            }
+        }
+
+        .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>

+ 26 - 2
src/views/dataAdmin/dataAdmin/resVersion/ResVersionManageAllModal.vue

@@ -1,5 +1,5 @@
 <template>
-    <BasicModal :maskClosable="false" :width="750" @register="registerModal" v-bind="$attrs" title="资源版本管理" centered
+    <BasicModal :maskClosable="false" :width="440" @register="registerModal" v-bind="$attrs" title="资源版本管理" centered
         @ok="handleSubmit">
         <div class="content">
             <div class="form-item">
@@ -116,4 +116,28 @@ export default defineComponent({
         }
     }
 })
-</script>
+</script>
+<style lang="less" scoped>
+.content{
+    padding: 10px;
+    .form-item{
+        display: flex;
+        align-items: center;
+        margin-bottom: 20px;
+        
+        &:last-child{
+            margin-bottom: 0;
+        }
+
+        .label{
+            width: 20%;
+        }
+        .select{
+            width: 80%;
+        }
+        .input{
+            width: 80%;
+        }
+    }
+}
+</style>