diff --git a/api/app/lib/controllers/backups/index.js b/api/app/lib/controllers/backups/index.js index a545f1a..e7ce69f 100644 --- a/api/app/lib/controllers/backups/index.js +++ b/api/app/lib/controllers/backups/index.js @@ -141,7 +141,8 @@ function restore(opts) { const { code, message } = res.body models.Backups.update({ state: code == 200 ? '恢复成功' : '恢复失败', - log: code == 200 ? '' : message + log: code == 200 ? '' : message, + restoreDatabases: ctx.request.body.databases }, { where: { id: id } }) if (code != 200) ctx.fs.logger.error(`path: ${ctx.path}, error: ${message}`); }) diff --git a/api/app/lib/controllers/latestMetadata/index.js b/api/app/lib/controllers/latestMetadata/index.js index d2e54e4..bd24ff8 100644 --- a/api/app/lib/controllers/latestMetadata/index.js +++ b/api/app/lib/controllers/latestMetadata/index.js @@ -538,20 +538,28 @@ async function postMetadataResourceApplications (ctx) { }); if (postOne) { ctx.status = 400; - ctx.body = { message: '该用户已申请过该元数据资源' } - } else { - await models.ResourceConsumption.create({ applyAt: moment(), approveState: '审批中', ...ctx.request.body }); - ctx.body = { message: '申请资源成功' } - ctx.status = 200; - } - } - } catch (error) { - ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); - ctx.status = 400; - ctx.body = { - "message": "申请资源失败" - } - } + ctx.body = { message: '参数不全,请重新申请资源' } + } else { + const models = ctx.fs.dc.models; + const postOne = await models.ResourceConsumption.findOne({ + where: { applyBy: applyBy, resourceName: resourceName, resourceId, resourceType, approve_remarks: null } + }); + if (postOne) { + ctx.status = 400; + ctx.body = { message: '该用户已申请过该元数据资源' } + } else { + await models.ResourceConsumption.create({ applyAt: moment(), approveState: '审批中', ...ctx.request.body }); + ctx.body = { message: '申请资源成功' } + ctx.status = 200; + } + } + } catch (error) { + ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); + ctx.status = 400; + ctx.body = { + "message": "申请资源失败" + } + } } //获取元数据资源申请记录 diff --git a/api/app/lib/controllers/metadataAcquisition/adapter.js b/api/app/lib/controllers/metadataAcquisition/adapter.js index b25ef50..5fad233 100644 --- a/api/app/lib/controllers/metadataAcquisition/adapter.js +++ b/api/app/lib/controllers/metadataAcquisition/adapter.js @@ -1,6 +1,6 @@ 'use strict'; const { Pool } = require('pg'); -// 新增模型 +// 测试数据库连接 function checkConnect(opts) { return async function (ctx, next) { diff --git a/api/app/lib/controllers/metadataSearch/index.js b/api/app/lib/controllers/metadataSearch/index.js index a8b5a74..6b69440 100644 --- a/api/app/lib/controllers/metadataSearch/index.js +++ b/api/app/lib/controllers/metadataSearch/index.js @@ -67,7 +67,7 @@ function searchMeta(opts) { } } -// 新增模型 +// 下载表数据 function getTableData(opts) { return async function (ctx, next) { diff --git a/api/app/lib/models/backups.js b/api/app/lib/models/backups.js index f205c39..78bb7db 100644 --- a/api/app/lib/models/backups.js +++ b/api/app/lib/models/backups.js @@ -88,7 +88,34 @@ module.exports = dc => { field: "log", autoIncrement: false }, - + restoreDatabases: { + type: DataTypes.JSONB, + allowNull: true, + defaultValue: null, + comment: null, + primaryKey: false, + field: "restore_databases", + autoIncrement: false + }, + restoreStart: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: null, + comment: "恢复开始时间", + primaryKey: false, + field: "restore_start", + autoIncrement: false + }, + restoreEnd: { + type: DataTypes.DATE, + allowNull: true, + defaultValue: null, + comment: "恢复结束时间", + primaryKey: false, + field: "restore_end", + autoIncrement: false + }, + }, { tableName: "backups", comment: "", diff --git a/scripts/0.0.7/05_alter_backups.sql b/scripts/0.0.7/05_alter_backups.sql new file mode 100644 index 0000000..5a40fba --- /dev/null +++ b/scripts/0.0.7/05_alter_backups.sql @@ -0,0 +1,18 @@ + +comment on column backups.databases is '备份数据源地址'; + + +alter table backups + add restore_databases jsonb; + + +alter table backups + add restore_start timestamp with time zone; + +comment on column backups.restore_start is '备份开始时间'; + +alter table backups + add restore_end timestamp with time zone; + +comment on column backups.restore_end is '备份结束时间'; + diff --git a/web/client/src/components/UploadLocal/index.js b/web/client/src/components/UploadLocal/index.js index 0af35e2..abd1dfa 100644 --- a/web/client/src/components/UploadLocal/index.js +++ b/web/client/src/components/UploadLocal/index.js @@ -214,7 +214,7 @@ class Uploads extends Component { }); } if (status === 'done') { - let { filename } = info.file.response; + let { filename, realName } = info.file.response; let size = info.file.size; let nextFileList = fileList; nextFileList[nextFileList.length - 1] = { @@ -223,7 +223,8 @@ class Uploads extends Component { status: 'done', storageUrl: filename, url: filename, - size: size + size: size, + realName: realName }; onChange(nextFileList); that.setState({ diff --git a/web/client/src/sections/backups/components/backupsModal.js b/web/client/src/sections/backups/components/backupsModal.js index 2da7418..67bddf3 100644 --- a/web/client/src/sections/backups/components/backupsModal.js +++ b/web/client/src/sections/backups/components/backupsModal.js @@ -33,7 +33,8 @@ export default (props) => { onCancel: () => { }, }} onFinish={async (values) => { - values.databases = dataSources?.rows?.find(s => s.id == values?.databases?.value)?.config; + let database = dataSources?.rows?.find(s => s.id == values?.databases?.value) + values.databases = { displayName: database?.name, ...database?.config }; values.createTime = moment(); values.state = '备份中'; values.title = title; diff --git a/web/client/src/sections/backups/containers/backupTask.js b/web/client/src/sections/backups/containers/backupTask.js index 51c06cc..adf2242 100644 --- a/web/client/src/sections/backups/containers/backupTask.js +++ b/web/client/src/sections/backups/containers/backupTask.js @@ -49,46 +49,77 @@ function Member(props) { { title: '序号', dataIndex: 'index', + fixed: 'left', + width: '7%', render: (text, record, index) => { return index + 1 } }, { title: '备份数据源', dataIndex: 'database', - render: (text, record) => record?.databases?.database - + fixed: 'left', + width: '7%', + render: (text, record) => record?.databases?.displayName }, { title: '备份信息', dataIndex: 'note', + fixed: 'left', + width: '7%', }, { title: '备份大小', dataIndex: 'size', + fixed: 'left', + width: '7%', }, { title: '备份时间', dataIndex: 'createTime', + fixed: 'left', + width: '7%', render: (text, record) => { return moment(record?.createTime).format('YYYY-MM-DD HH:mm:ss') } }, { title: '备份完成时间', dataIndex: 'completeTime', + fixed: 'left', + width: '7%', render: (text, record) => { return record?.completeTime ? moment(record?.completeTime).format('YYYY-MM-DD HH:mm:ss') : '-' } }, { title: '状态', dataIndex: 'state', + fixed: 'left', + width: '7%', + }, + { + title: '恢复数据源', + dataIndex: 'restoreDatabases', + width: '8%', + render: (text, record) => record?.restoreDatabases?.database + }, + { + title: '恢复开始时间', + width: '7%', + dataIndex: 'restoreStart', + }, + { + title: '恢复结束时间', + width: '7%', + dataIndex: 'restoreEnd', }, { title: '异常日志', dataIndex: 'log', + width: '7%', ellipsis: true, }, { title: '操作', - width: 160, + width: '8%', key: 'option', valueType: 'option', + fixed: 'right', render: (text, record) => { const options = []; options.push( @@ -208,7 +239,8 @@ function Member(props) { scroll={ { scrollToFirstRowOnChange: true, - y: clientHeight - 260 + y: clientHeight - 260, + x: 1800 } } pagination={{ diff --git a/web/client/src/sections/metadataManagement/containers/filesTable.js b/web/client/src/sections/metadataManagement/containers/filesTable.js index a7ae2d6..72e925b 100644 --- a/web/client/src/sections/metadataManagement/containers/filesTable.js +++ b/web/client/src/sections/metadataManagement/containers/filesTable.js @@ -279,7 +279,7 @@ const FilesTable = (props) => { if (values.files && values.files.length) { obj.type = values.files[0].name.split('.').pop(); obj.size = values.files[0].size; - obj.fileName = values.files[0].url.split('\\').pop(); + obj.fileName = values.files[0].realName; } dispatch(metadataManagement.postMetadataFiles(obj)).then(res => { if (res.success) { @@ -293,7 +293,7 @@ const FilesTable = (props) => { if (values.files[0].size) { obj.size = values.files[0].size; } - obj.fileName = values.files[0].url.split('\\').pop(); + obj.fileName = values.files[0].realName; } dispatch(metadataManagement.putMetadataFiles(editData.record.id, obj)).then(res => { if (res.success) { diff --git a/web/routes/attachment/index.js b/web/routes/attachment/index.js index 14df35b..bfcf516 100644 --- a/web/routes/attachment/index.js +++ b/web/routes/attachment/index.js @@ -104,7 +104,7 @@ module.exports = { app.fs.logger.log('error', '[Upload Heatmap]', err); }); ctx.status = 200; - ctx.body = { filename: path.join(`/assets/files/${fileFolder}`, fileName), name: 'UploadSuccess', message: '上传成功' }; + ctx.body = { realName: fileName, filename: path.join(`/assets/files/${fileFolder}`, fileName), name: 'UploadSuccess', message: '上传成功' }; } catch (err) { ctx.status = 500; ctx.fs.logger.error(err);