政务数据资源中心(Government data Resource center) 03专项3期主要建设内容
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

564 lines
20 KiB

'use strict';
const moment = require("moment/moment");
//获取资源目录
async function getResourceCatalog(ctx) {
try {
const models = ctx.fs.dc.models;
const rslt = await models.ResourceCatalog.findAll({
order: [['id', 'asc']],
});
ctx.status = 200;
ctx.body = rslt;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "获取资源目录失败"
}
}
}
//新建资源目录
async function postResourceCatalog(ctx) {
try {
const { name, code } = ctx.request.body;
const models = ctx.fs.dc.models;
const postOne = await models.ResourceCatalog.findOne({
where: { $or: [{ name: name }, { code: code }] }
});
if (postOne) {
ctx.status = 400;
ctx.body = { message: '该资源目录名称或代码已存在' }
} else {
if (!name || !code) {
ctx.body = { message: '参数不全,请重新配置' }
ctx.status = 400;
} else {
await models.ResourceCatalog.create(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": "新建资源目录失败"
}
}
}
//修改资源目录
async function putResourceCatalog(ctx) {
try {
const { id } = ctx.params;
const { name, code, description } = ctx.request.body;
const models = ctx.fs.dc.models;
let resourceCatalogInfo = await models.ResourceCatalog.findOne({ where: { id } });
if (resourceCatalogInfo) {
const putOne = await models.ResourceCatalog.findOne({ where: { id: { $not: id }, $or: [{ name: name }, { code: code }] } });
if (putOne) {
ctx.status = 400;
ctx.body = { message: '该资源目录名称或代码已存在' }
} else {
await models.ResourceCatalog.update(ctx.request.body, { where: { id: id } });
ctx.status = 200;
ctx.body = { message: '修改资源目录成功' }
}
} else {
ctx.status = 400;
ctx.body = { message: '该资源目录不存在' }
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "修改资源目录失败"
}
}
}
//删除资源目录
async function delResourceCatalog(ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const models = ctx.fs.dc.models;
const { id } = ctx.params;
let resourceCatalogInfo = await models.ResourceCatalog.findOne({ where: { id } });
if (resourceCatalogInfo) {
let deletable = true;
let childResourceCatalogInfo = await models.ResourceCatalog.findOne({ where: { parent: id } });
let databaseInfo = await models.MetadataDatabase.findOne({ where: { catalog: id } });
let fileInfo = await models.MetadataFile.findOne({ where: { catalog: id } });
let restapiInfo = await models.MetadataRestapi.findOne({ where: { catalog: id } });
if (childResourceCatalogInfo || databaseInfo || fileInfo || restapiInfo) {
ctx.status = 400;
ctx.body = { message: '存在关联子类目录或元数据,请删除相关数据,再删除该资源目录' }
deletable = false;
}
if (deletable) {
await models.ResourceCatalog.destroy({
where: { id: id },
transaction
})
await transaction.commit();
ctx.status = 200;
ctx.body = { message: '删除资源目录成功' }
}
} else {
ctx.status = 400;
ctx.body = { message: '该资源目录不存在' }
}
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = { message: '删除资源目录失败' }
}
}
//获取库表元数据列表
async function getMetadataDatabases(ctx) {
try {
const models = ctx.fs.dc.models;
const { catalog, limit, offset, keywords, orderBy = 'createAt', orderDirection = 'desc', id = null } = ctx.query;
const where = {};
if (catalog) {
where.catalog = catalog;
}
if (id) {
where.parent = id;
}
if (keywords) {
where['$or'] = [{ name: { $iLike: `%${keywords}%` } },
{ code: { $iLike: `%${keywords}%` } },
{ type: { $iLike: `%${keywords}%` } }]
}
const findObj = {
include: [
{
model: models.User,
attributes: ['id', 'name', 'username'],
},
{
model: models.TagDatabase,
include: [{
model: models.Tag,
}]
}],
where: where,
order: [[orderBy, orderDirection]],
distinct: true
}
if (Number(limit) > 0 && Number(offset) >= 0) {
findObj.offset = Number(offset) * Number(limit);
findObj.limit = Number(limit);
}
const rslt = await models.MetadataDatabase.findAndCountAll(findObj);
ctx.status = 200;
ctx.body = rslt;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "获取库表元数据列表失败"
}
}
}
//获取文件元数据列表
async function getMetadataFiles(ctx) {
try {
const models = ctx.fs.dc.models;
const { catalog, limit, offset, keywords, orderBy = 'createAt', orderDirection = 'desc' } = ctx.query;
const where = { catalog: catalog };
if (keywords) {
where['$or'] = [{ name: { $iLike: `%${keywords}%` } }, { type: { $iLike: `%${keywords}%` } }]
}
const findObj = {
include: [
{
model: models.User,
attributes: ['id', 'name', 'username'],
},
{
model: models.TagFile,
include: [{
model: models.Tag,
}]
}],
where: where,
order: [[orderBy, orderDirection]],
distinct: true
};
if (Number(limit) > 0 && Number(offset) >= 0) {
findObj.offset = Number(offset) * Number(limit);
findObj.limit = Number(limit);
}
const rslt = await models.MetadataFile.findAndCountAll(findObj);
ctx.status = 200;
ctx.body = rslt;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "获取文件元数据列表失败"
}
}
}
//获取接口元数据列表
async function getMetadataRestapis(ctx) {
try {
const models = ctx.fs.dc.models;
const { catalog, limit, offset, keywords, orderBy = 'createAt', orderDirection = 'desc' } = ctx.query;
const where = { catalog: catalog };
if (keywords) {
where.name = { $iLike: `%${keywords}%` };
}
const findObj = {
include: [
{
model: models.User,
attributes: ['id', 'name', 'username'],
},
{
model: models.TagRestapi,
include: [{
model: models.Tag,
}]
}],
where: where,
order: [[orderBy, orderDirection]],
distinct: true
};
if (Number(limit) > 0 && Number(offset) >= 0) {
findObj.offset = Number(offset) * Number(limit);
findObj.limit = Number(limit);
}
const rslt = await models.MetadataRestapi.findAndCountAll(findObj);
ctx.status = 200;
ctx.body = rslt;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "获取接口元数据列表失败"
}
}
}
//获取元数据模型
async function getMetadataModels(ctx) {
try {
const models = ctx.fs.dc.models;
const { modelTypes } = ctx.query;
const rslt = await models.MetaModel.findAll({
where: {
modelType: { $in: modelTypes }
}
});
ctx.status = 200;
ctx.body = rslt;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "获取元数据模型失败"
}
}
}
//新建库表元数据
async function postMetadataDatabases(ctx) {
try {
const { name, code, catalog } = ctx.request.body;
const models = ctx.fs.dc.models;
const postOne = await models.MetadataDatabase.findOne({
where: { $or: [{ name: name }, { code: code }], catalog: catalog }
});
if (postOne) {
ctx.status = 400;
ctx.body = { message: '该资源目录下元数据名称或代码已存在' }
} else {
if (!name || !code || !catalog) {
ctx.body = { message: '参数不全,请重新配置' }
ctx.status = 400;
} else {
await models.MetadataDatabase.create({ createAt: moment(), ...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": "新建元数据失败"
}
}
}
//修改库表元数据
async function putMetadataDatabases(ctx) {
try {
const { id } = ctx.params;
const { catalog, name, code } = ctx.request.body;
const models = ctx.fs.dc.models;
let metadataDatabaseInfo = await models.MetadataDatabase.findOne({ where: { id } });
if (metadataDatabaseInfo) {
const putOne = await models.MetadataDatabase.findOne({ where: { id: { $not: id }, catalog: catalog, $or: [{ name: name }, { code: code }] } });
if (putOne) {
ctx.status = 400;
ctx.body = { message: '该元数据名称或代码已存在' }
} else {
await models.MetadataDatabase.update(ctx.request.body, { where: { id: id } });
ctx.status = 200;
ctx.body = { message: '修改元数据成功' }
}
} else {
ctx.status = 400;
ctx.body = { message: '该元数据不存在' }
}
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "修改元数据失败"
}
}
}
//删除库表元数据
async function delMetadataDatabases(ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const models = ctx.fs.dc.models;
const { id } = ctx.params;
let metadataDatabaseInfo = await models.MetadataDatabase.findOne({ where: { id } });
if (metadataDatabaseInfo) {
let deletable = true;
let childMetadataDatabaseInfo = await models.MetadataDatabase.findOne({ where: { parent: id } });
if (childMetadataDatabaseInfo) {
ctx.status = 400;
ctx.body = { message: '存在关联子类元数据,请删除相关数据,再删除该元数据' }
deletable = false;
} else {
let tagDatabaseInfo = await models.TagDatabase.findOne({ where: { database: id } });
if (tagDatabaseInfo) {
ctx.status = 400;
ctx.body = { message: '该元数据已被打标' }
deletable = false;
} else {
let resourceConsumptionInfo = await models.ResourceConsumption.findOne({
where: {
resourceName: metadataDatabaseInfo.name,
resourceType: '库表'
}
});
if (resourceConsumptionInfo) {
ctx.status = 400;
ctx.body = { message: '该元数据存在资源申请' }
deletable = false;
}
}
}
if (deletable) {
await models.MetadataDatabase.destroy({
where: { id: id },
transaction
})
await transaction.commit();
ctx.status = 200;
ctx.body = { message: '删除元数据成功' }
}
} else {
ctx.status = 400;
ctx.body = { message: '该元数据不存在' }
}
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = { message: '删除元数据失败' }
}
}
//获取库表元数据基本信息
async function getMetadataDatabasesById(ctx) {
try {
const models = ctx.fs.dc.models;
const { id } = ctx.params;
const findObj = {
include: [
{
model: models.User,
attributes: ['id', 'name', 'username'],
},
{
model: models.TagDatabase,
include: [{
model: models.Tag,
}]
}],
where: { id: id },
}
const rslt = await models.MetadataDatabase.findOne(findObj);
ctx.status = 200;
ctx.body = rslt;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "获取元数据基本信息失败"
}
}
}
//打标元数据
async function postTagMetadata(ctx) {
const transaction = await ctx.fs.dc.orm.transaction();
try {
const { tags, database, file, restapi } = ctx.request.body;
const models = ctx.fs.dc.models;
if (tags.length && (database || file || restapi)) {
if (database) {
await models.TagDatabase.destroy({ where: { database: database }, transaction });
const data = tags.map(tag => { return { tagId: tag, database: database } });
if (data.length)
await models.TagDatabase.bulkCreate(data, { transaction });
}
if (file) {
await models.TagFile.destroy({ where: { file: file }, transaction });
const data = tags.map(tag => { return { tagId: tag, file: file } });
if (data.length)
await models.TagFile.bulkCreate(data, { transaction });
}
if (restapi) {
await models.TagRestapi.destroy({ where: { restapi: restapi }, transaction });
const data = tags.map(tag => { return { tagId: tag, restapi: restapi } });
if (data.length)
await models.TagRestapi.bulkCreate(data, { transaction });
}
await transaction.commit();
ctx.status = 204;
} else {
ctx.body = { message: '参数不全,请重新配置' }
ctx.status = 400;
}
} catch (error) {
await transaction.rollback();
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "打标元数据失败"
}
}
}
//获取元数据已打标数据
async function getTagMetadata(ctx) {
try {
const models = ctx.fs.dc.models;
const { id } = ctx.params;
const { type } = ctx.query;
let rslt = [];
if (type === 'database') {
rslt = await models.Tag.findAll({
where: { '$tagDatabases.database$': id },
include: [{
model: models.TagDatabase,
}],
order: [['id', 'asc']],
});
}
if (type === 'file') {
rslt = await models.Tag.findAll({
where: { '$tagFiles.file$': id },
include: [{
model: models.TagFile,
}],
order: [['id', 'asc']],
});
}
if (type === 'restapi') {
rslt = await models.Tag.findAll({
where: { '$tagRestapis.restapi$': id },
include: [{
model: models.TagRestapi,
}],
order: [['id', 'asc']],
});
}
ctx.status = 200;
ctx.body = rslt;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "获取元数据已打标数据失败"
}
}
}
//申请资源
async function postMetadataResourceApplications(ctx) {
try {
const { resourceName, applyBy } = ctx.request.body;
if (!resourceName || !applyBy) {
ctx.status = 400;
ctx.body = { message: '参数不全,请重新申请资源' }
} else {
const models = ctx.fs.dc.models;
const postOne = await models.ResourceConsumption.findOne({
where: { applyBy: applyBy, resourceName: resourceName }
});
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": "申请资源失败"
}
}
}
//获取元数据资源申请记录
async function getMetadataResourceApplications(ctx) {
try {
const models = ctx.fs.dc.models;
const { resourceNames, type } = ctx.query;
let rslt = [];
if (resourceNames && type) {
rslt = await models.ResourceConsumption.findAll({
where: { resourceName: { $in: resourceNames.split(',') }, resourceType: type }
});
}
ctx.status = 200;
ctx.body = rslt;
} catch (error) {
ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
ctx.status = 400;
ctx.body = {
"message": "获取元数据资源申请记录失败"
}
}
}
module.exports = {
getResourceCatalog,
postResourceCatalog,
putResourceCatalog,
delResourceCatalog,
getMetadataDatabases,
getMetadataFiles,
getMetadataRestapis,
getMetadataModels,
postMetadataDatabases,
putMetadataDatabases,
delMetadataDatabases,
getMetadataDatabasesById,
postTagMetadata,
getTagMetadata,
postMetadataResourceApplications,
getMetadataResourceApplications
}