wenlele 2 years ago
parent
commit
a44d9830a3
  1. 3
      api/app/lib/controllers/backups/index.js
  2. 36
      api/app/lib/controllers/latestMetadata/index.js
  3. 2
      api/app/lib/controllers/metadataAcquisition/adapter.js
  4. 2
      api/app/lib/controllers/metadataSearch/index.js
  5. 29
      api/app/lib/models/backups.js
  6. 18
      scripts/0.0.7/05_alter_backups.sql
  7. 5
      web/client/src/components/UploadLocal/index.js
  8. 3
      web/client/src/sections/backups/components/backupsModal.js
  9. 40
      web/client/src/sections/backups/containers/backupTask.js
  10. 4
      web/client/src/sections/metadataManagement/containers/filesTable.js
  11. 2
      web/routes/attachment/index.js

3
api/app/lib/controllers/backups/index.js

@ -141,7 +141,8 @@ function restore(opts) {
const { code, message } = res.body const { code, message } = res.body
models.Backups.update({ models.Backups.update({
state: code == 200 ? '恢复成功' : '恢复失败', state: code == 200 ? '恢复成功' : '恢复失败',
log: code == 200 ? '' : message log: code == 200 ? '' : message,
restoreDatabases: ctx.request.body.databases
}, { where: { id: id } }) }, { where: { id: id } })
if (code != 200) ctx.fs.logger.error(`path: ${ctx.path}, error: ${message}`); if (code != 200) ctx.fs.logger.error(`path: ${ctx.path}, error: ${message}`);
}) })

36
api/app/lib/controllers/latestMetadata/index.js

@ -538,20 +538,28 @@ async function postMetadataResourceApplications (ctx) {
}); });
if (postOne) { if (postOne) {
ctx.status = 400; ctx.status = 400;
ctx.body = { message: '该用户已申请过该元数据资源' } ctx.body = { message: '参数不全,请重新申请资源' }
} else { } else {
await models.ResourceConsumption.create({ applyAt: moment(), approveState: '审批中', ...ctx.request.body }); const models = ctx.fs.dc.models;
ctx.body = { message: '申请资源成功' } const postOne = await models.ResourceConsumption.findOne({
ctx.status = 200; where: { applyBy: applyBy, resourceName: resourceName, resourceId, resourceType, approve_remarks: null }
} });
} if (postOne) {
} catch (error) { ctx.status = 400;
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`); ctx.body = { message: '该用户已申请过该元数据资源' }
ctx.status = 400; } else {
ctx.body = { await models.ResourceConsumption.create({ applyAt: moment(), approveState: '审批中', ...ctx.request.body });
"message": "申请资源失败" ctx.body = { message: '申请资源成功' }
} ctx.status = 200;
} }
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "申请资源失败"
}
}
} }
//获取元数据资源申请记录 //获取元数据资源申请记录

2
api/app/lib/controllers/metadataAcquisition/adapter.js

@ -1,6 +1,6 @@
'use strict'; 'use strict';
const { Pool } = require('pg'); const { Pool } = require('pg');
// 新增模型 // 测试数据库连接
function checkConnect(opts) { function checkConnect(opts) {
return async function (ctx, next) { return async function (ctx, next) {

2
api/app/lib/controllers/metadataSearch/index.js

@ -67,7 +67,7 @@ function searchMeta(opts) {
} }
} }
// 新增模型 // 下载表数据
function getTableData(opts) { function getTableData(opts) {
return async function (ctx, next) { return async function (ctx, next) {

29
api/app/lib/models/backups.js

@ -88,7 +88,34 @@ module.exports = dc => {
field: "log", field: "log",
autoIncrement: false 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", tableName: "backups",
comment: "", comment: "",

18
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 '备份结束时间';

5
web/client/src/components/UploadLocal/index.js

@ -214,7 +214,7 @@ class Uploads extends Component {
}); });
} }
if (status === 'done') { if (status === 'done') {
let { filename } = info.file.response; let { filename, realName } = info.file.response;
let size = info.file.size; let size = info.file.size;
let nextFileList = fileList; let nextFileList = fileList;
nextFileList[nextFileList.length - 1] = { nextFileList[nextFileList.length - 1] = {
@ -223,7 +223,8 @@ class Uploads extends Component {
status: 'done', status: 'done',
storageUrl: filename, storageUrl: filename,
url: filename, url: filename,
size: size size: size,
realName: realName
}; };
onChange(nextFileList); onChange(nextFileList);
that.setState({ that.setState({

3
web/client/src/sections/backups/components/backupsModal.js

@ -33,7 +33,8 @@ export default (props) => {
onCancel: () => { }, onCancel: () => { },
}} }}
onFinish={async (values) => { 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.createTime = moment();
values.state = '备份中'; values.state = '备份中';
values.title = title; values.title = title;

40
web/client/src/sections/backups/containers/backupTask.js

@ -49,46 +49,77 @@ function Member(props) {
{ {
title: '序号', title: '序号',
dataIndex: 'index', dataIndex: 'index',
fixed: 'left',
width: '7%',
render: (text, record, index) => { return index + 1 } render: (text, record, index) => { return index + 1 }
}, },
{ {
title: '备份数据源', title: '备份数据源',
dataIndex: 'database', dataIndex: 'database',
render: (text, record) => record?.databases?.database fixed: 'left',
width: '7%',
render: (text, record) => record?.databases?.displayName
}, },
{ {
title: '备份信息', title: '备份信息',
dataIndex: 'note', dataIndex: 'note',
fixed: 'left',
width: '7%',
}, },
{ {
title: '备份大小', title: '备份大小',
dataIndex: 'size', dataIndex: 'size',
fixed: 'left',
width: '7%',
}, },
{ {
title: '备份时间', title: '备份时间',
dataIndex: 'createTime', dataIndex: 'createTime',
fixed: 'left',
width: '7%',
render: (text, record) => { return moment(record?.createTime).format('YYYY-MM-DD HH:mm:ss') } render: (text, record) => { return moment(record?.createTime).format('YYYY-MM-DD HH:mm:ss') }
}, },
{ {
title: '备份完成时间', title: '备份完成时间',
dataIndex: 'completeTime', dataIndex: 'completeTime',
fixed: 'left',
width: '7%',
render: (text, record) => { return record?.completeTime ? moment(record?.completeTime).format('YYYY-MM-DD HH:mm:ss') : '-' } render: (text, record) => { return record?.completeTime ? moment(record?.completeTime).format('YYYY-MM-DD HH:mm:ss') : '-' }
}, },
{ {
title: '状态', title: '状态',
dataIndex: 'state', 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: '异常日志', title: '异常日志',
dataIndex: 'log', dataIndex: 'log',
width: '7%',
ellipsis: true, ellipsis: true,
}, },
{ {
title: '操作', title: '操作',
width: 160, width: '8%',
key: 'option', key: 'option',
valueType: 'option', valueType: 'option',
fixed: 'right',
render: (text, record) => { render: (text, record) => {
const options = []; const options = [];
options.push( options.push(
@ -208,7 +239,8 @@ function Member(props) {
scroll={ scroll={
{ {
scrollToFirstRowOnChange: true, scrollToFirstRowOnChange: true,
y: clientHeight - 260 y: clientHeight - 260,
x: 1800
} }
} }
pagination={{ pagination={{

4
web/client/src/sections/metadataManagement/containers/filesTable.js

@ -279,7 +279,7 @@ const FilesTable = (props) => {
if (values.files && values.files.length) { if (values.files && values.files.length) {
obj.type = values.files[0].name.split('.').pop(); obj.type = values.files[0].name.split('.').pop();
obj.size = 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.postMetadataFiles(obj)).then(res => { dispatch(metadataManagement.postMetadataFiles(obj)).then(res => {
if (res.success) { if (res.success) {
@ -293,7 +293,7 @@ const FilesTable = (props) => {
if (values.files[0].size) { if (values.files[0].size) {
obj.size = 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 => { dispatch(metadataManagement.putMetadataFiles(editData.record.id, obj)).then(res => {
if (res.success) { if (res.success) {

2
web/routes/attachment/index.js

@ -104,7 +104,7 @@ module.exports = {
app.fs.logger.log('error', '[Upload Heatmap]', err); app.fs.logger.log('error', '[Upload Heatmap]', err);
}); });
ctx.status = 200; 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) { } catch (err) {
ctx.status = 500; ctx.status = 500;
ctx.fs.logger.error(err); ctx.fs.logger.error(err);

Loading…
Cancel
Save