diff --git a/api/app/lib/controllers/dataQuality/index.js b/api/app/lib/controllers/dataQuality/index.js
new file mode 100644
index 0000000..4a628b0
--- /dev/null
+++ b/api/app/lib/controllers/dataQuality/index.js
@@ -0,0 +1,398 @@
+'use strict';
+const moment = require('moment')
+
+function getStandardDocFolders (opts) {
+ return async function (ctx, next) {
+
+ const models = ctx.fs.dc.models;
+ const { keyword, parent } = ctx.query;
+
+ let errMsg = { message: '获取标准文档目录列表失败' }
+ try {
+
+ let option = {
+ where: { parent: parent || null },
+ order: [["id", "desc"]]
+ }
+
+ let folderData = await models.StandardDocFolder.findAll(option) || []
+
+
+ let fileAll = await models.StandardDoc.findAll({})
+ let folderAll = await models.StandardDocFolder.findAll({})
+
+
+ const recursive = (id) => {
+ let show = false
+ let fileOne = fileAll.filter(f => f.folder == id && (f.docName.indexOf(keyword) != -1 || f.standardType.indexOf(keyword) != -1))
+ if (fileOne.length > 0) {
+ return true
+ }
+ let folderList = folderAll.filter(f => f.parent == id)
+ if (folderList.length > 0) {
+ let data = []
+ folderList.map(d => {
+ let datum = recursive(d.id)
+ if (datum) {
+ data.push(d)
+ }
+ })
+ if (data.length > 0) {
+ show = true
+ }
+ } else {
+ return false
+ }
+ return show
+ }
+ let res = []
+
+ if (folderData.length > 0 && keyword) {
+
+ folderData.map(d => {
+ let findOne = recursive(d.id)
+ if (findOne) {
+ res.push(d)
+ }
+ })
+
+ } else {
+ res = folderData
+ }
+
+ ctx.status = 200;
+ ctx.body = res;
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = errMsg
+ }
+ }
+}
+
+
+
+
+// 标准文档目录新增失败
+function postStandardDocFolders (opts) {
+ return async function (ctx, next) {
+
+ try {
+ const models = ctx.fs.dc.models;
+
+ const { name, parent } = ctx.request.body;
+
+
+ await models.StandardDocFolder.create({
+ name, parent, createAt: moment().format('YYYY-MM-DD HH:mm:ss')
+ })
+ ctx.status = 204;
+
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = { message: '标准文档目录新增失败' }
+ }
+ }
+}
+
+
+// 新增标准文档
+function postStandardDocs (opts) {
+ return async function (ctx, next) {
+
+ try {
+ const models = ctx.fs.dc.models;
+
+ const { docName, standardType, tags, folder, path } = ctx.request.body;
+
+
+ await models.StandardDoc.create({
+ docName, standardType, tags, folder, path, createAt: moment().format('YYYY-MM-DD HH:mm:ss')
+ })
+ ctx.status = 204;
+
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = { message: '新增标准文档失败' }
+ }
+ }
+}
+
+function getStandardDocs (opts) {
+ return async function (ctx, next) {
+
+ const models = ctx.fs.dc.models;
+ const { keyword, folder } = ctx.query;
+
+ let errMsg = { message: '获取标准文档列表失败' }
+ try {
+
+ let option = {
+ where: { folder: folder || null },
+ order: [["id", "desc"]],
+
+ }
+ let type = ['国家标准', '行业标准', '地方标准']
+ if (keyword) {
+ option.where['$or'] = [{ docName: { $iLike: `%${keyword}%` } }, { standardType: { $in: type.filter(v => v.indexOf(keyword) != -1) } }]
+ }
+ const res = await models.StandardDoc.findAll(option);
+ ctx.status = 200;
+ ctx.body = res;
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = errMsg
+ }
+ }
+}
+
+function postBusinessRules (opts) {
+ return async function (ctx, next) {
+ let message = (ctx.request.body.id ? '编辑' : '新增') + '业务规则失败'
+ try {
+ const models = ctx.fs.dc.models;
+
+ const { id, name, description, problemType, problemLevel, ruleBasis } = ctx.request.body;
+
+ if (id) {
+ await models.BusinessRule.update({
+ name, description, problemType, problemLevel, ruleBasis
+ }, { where: { id: id } })
+ } else {
+ await models.BusinessRule.create({
+ name, description, problemType, problemLevel, ruleBasis, createAt: moment().format('YYYY-MM-DD HH:mm:ss')
+ })
+ }
+ ctx.status = 204;
+
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = { message: message }
+ }
+ }
+}
+
+function getBusinessRules (opts) {
+ return async function (ctx, next) {
+
+ const models = ctx.fs.dc.models;
+ const { page, limit, keyword, } = ctx.query;
+
+ let errMsg = { message: '查询业务规则列表失败' }
+ try {
+
+ let option = {
+ where: {},
+ order: [["id", "desc"]],
+ distinct: true,
+ include: [{
+ model: models.StandardDoc,
+ attributes: ['id', 'docName', 'path']
+ }]
+ }
+ if (keyword) {
+ option.where.name = { $iLike: `%${keyword}%` }
+ }
+
+ if (limit) {
+ option.limit = Number(limit)
+ }
+ if (page && limit) {
+ option.offset = Number(page) * Number(limit)
+ }
+
+
+ const res = await models.BusinessRule.findAndCount(option);
+ ctx.status = 200;
+ ctx.body = res;
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = errMsg
+ }
+ }
+}
+
+
+function delBusinessRules (opts) {
+ return async function (ctx, next) {
+
+ try {
+ const models = ctx.fs.dc.models;
+ const { id } = ctx.params;
+ await models.BusinessRule.destroy({
+ where: {
+ id: id
+ }
+ })
+ ctx.status = 204;
+ ctx.body = { message: '删除业务规则成功' }
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = { message: '删除业务规则失败' }
+ }
+ }
+}
+
+function getRegularBasis (opts) {
+ return async function (ctx, next) {
+
+ const models = ctx.fs.dc.models;
+ const { } = ctx.query;
+ try {
+
+ let folders = await models.StandardDocFolder.findAll({ attributes: ['id', 'name', 'parent'] }) || []
+ let files = await models.StandardDoc.findAll({ attributes: ['id', 'docName', 'folder'] }) || []
+
+ let res = []
+ let carousel = (id) => {
+ let list = []
+ let data = folders.filter(f => f.parent == id)
+ if (data.length > 0) {
+ data.map(c => {
+ list.push({
+ value: c.id,
+ title: c.name,
+ disabled: true,
+ children: carousel(c.id)
+ })
+
+ })
+ }
+ let filedata = files.filter(f => f.folder == id)
+ if (filedata.length > 0) {
+ filedata.map(f => {
+ list.push({
+ value: f.id,
+ title: f.docName
+ })
+ })
+ }
+
+ return list
+ }
+ if (folders.length > 0) {
+ folders.map(v => {
+ if (v.dataValues.parent == null) {
+ res.push({
+ value: v.id,
+ title: v.name,
+ disabled: true,
+ children: carousel(v.id)
+ })
+ }
+ })
+ }
+ if (files.length > 0) {
+ files.map(v => {
+ if (v.dataValues.folder == null) {
+ res.push({
+ value: v.id,
+ title: v.docName
+ })
+ }
+ })
+ }
+
+
+
+
+ ctx.status = 200;
+ ctx.body = res || [];
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = { message: '查询规则依据列表失败' }
+ }
+ }
+}
+
+
+function postFolderFile (opts) {
+ return async function (ctx, next) {
+ let body = { message: '删除业务规则失败' }
+ try {
+ const models = ctx.fs.dc.models;
+ const { folderId, fileId } = ctx.request.body;
+
+ let folderIds = folderId
+ let fileIds = fileId
+
+ let folderLists = await models.StandardDocFolder.findAll() || []
+
+ let carousel = (id) => {
+ let folderListId = []
+ folderLists.filter(d => {
+ if (id.includes(d.parent)) {
+ folderIds.push(d.id)
+ folderListId.push(d.id)
+ return true
+ } else {
+ return false
+ }
+ })
+
+ if (folderListId.length > 0) {
+ carousel(folderListId)
+ }
+ }
+
+ carousel(folderIds)
+
+ folderIds = [...new Set(folderIds)]
+ let fileList = await models.StandardDoc.findAll({
+ where: { $or: [{ folder: { $in: folderIds } }, { id: { $in: fileIds } }] },
+ distinct: true,
+ include: [{
+ model: models.BusinessRule
+ }]
+ })
+ let url = []
+ fileList.map(v => {
+ if (v.businessRules.length > 0) {
+ body.data = v.businessRules
+ body.message = '当前创建的业务规则与标准文档关联'
+ throw '前创建的业务规则与标准文档关联'
+ }
+ fileIds.push(v.id)
+ url.push(v.path)
+ })
+ fileIds = [...new Set(fileIds)]
+
+ await models.StandardDocFolder.destroy({
+ where: {
+ id: { $in: folderIds }
+ }
+ })
+ await models.StandardDoc.destroy({
+ where: {
+ id: { $in: fileIds }
+ }
+ })
+
+ ctx.status = 200;
+ ctx.body = url
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = body
+ }
+ }
+}
+
+module.exports = {
+ getStandardDocFolders,
+ postStandardDocFolders,
+ postStandardDocs,
+ getStandardDocs,
+ postBusinessRules,
+ getBusinessRules,
+ delBusinessRules,
+ getRegularBasis,
+ postFolderFile
+}
\ No newline at end of file
diff --git a/api/app/lib/controllers/safetySpecification/index.js b/api/app/lib/controllers/safetySpecification/index.js
new file mode 100644
index 0000000..ecc626f
--- /dev/null
+++ b/api/app/lib/controllers/safetySpecification/index.js
@@ -0,0 +1,93 @@
+'use strict';
+const moment = require('moment')
+
+function getSpecifications (opts) {
+ return async function (ctx, next) {
+
+ const models = ctx.fs.dc.models;
+ const { page, limit, keyword, } = ctx.query;
+
+ let errMsg = { message: '查询数据安全规范列表失败' }
+ try {
+
+ let option = {
+ where: {},
+ order: [["id", "desc"]],
+ }
+ if (keyword) {
+ option.where.fileName = { $iLike: `%${keyword}%` }
+ }
+
+ if (limit) {
+ option.limit = Number(limit)
+ }
+ if (page && limit) {
+ option.offset = Number(page) * Number(limit)
+ }
+
+
+ const res = await models.DataSecuritySpecification.findAndCount(option);
+ ctx.status = 200;
+ ctx.body = res;
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = errMsg
+ }
+ }
+}
+
+
+
+function delSpecifications (opts) {
+ return async function (ctx, next) {
+
+ try {
+ const models = ctx.fs.dc.models;
+ const { fileIds } = ctx.params;
+ await models.DataSecuritySpecification.destroy({
+ where: {
+ id: { $in: fileIds.split(',') }
+ }
+ })
+ ctx.status = 204;
+ ctx.body = { message: '删除数据安全规范文件成功' }
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = { message: '删除数据安全规范文件失败' }
+ }
+ }
+}
+
+
+// 新增标准文档
+function postSpecifications (opts) {
+ return async function (ctx, next) {
+
+ try {
+ const models = ctx.fs.dc.models;
+
+ const { fileName, tags, path } = ctx.request.body;
+
+
+ await models.DataSecuritySpecification.create({
+ fileName, tags, path, createAt: moment().format('YYYY-MM-DD HH:mm:ss')
+ })
+ ctx.status = 204;
+
+ } catch (error) {
+ ctx.fs.logger.error(`path: ${ctx.path}, error: ${error}`);
+ ctx.status = 400;
+ ctx.body = { message: '新增数据安全规范失败' }
+ }
+ }
+}
+
+
+
+module.exports = {
+ getSpecifications,
+ postSpecifications,
+ delSpecifications
+}
\ No newline at end of file
diff --git a/api/app/lib/index.js b/api/app/lib/index.js
index 08387ac..eb4331c 100644
--- a/api/app/lib/index.js
+++ b/api/app/lib/index.js
@@ -56,7 +56,7 @@ module.exports.models = function (dc) {
const {
DataSource, AcquisitionTask, Adapter, User, MetadataDatabase, MetadataFile, MetadataRestapi, AcquisitionLog, ResourceCatalog,
- BusinessMetadataDatabase, BusinessMetadataFile, BusinessMetadataRestapi,ResourceConsumption
+ BusinessMetadataDatabase, BusinessMetadataFile, BusinessMetadataRestapi,ResourceConsumption,BusinessRule,StandardDoc
} = dc.models;
AcquisitionTask.belongsTo(DataSource, { foreignKey: 'dataSourceId', targetKey: 'id' });
@@ -88,4 +88,8 @@ module.exports.models = function (dc) {
ResourceConsumption.belongsTo(User, { foreignKey: 'applyBy', targetKey: 'id' ,as:"applyUser"});
ResourceConsumption.belongsTo(User, { foreignKey: 'approveBy', targetKey: 'id',as:'approveUser' });
+
+ BusinessRule.belongsTo(StandardDoc, { foreignKey: 'ruleBasis', targetKey: 'id' });
+ StandardDoc.hasMany(BusinessRule, { foreignKey: 'ruleBasis', targetKey: 'id' });
+
};
diff --git a/api/app/lib/models/business_rule.js b/api/app/lib/models/business_rule.js
new file mode 100644
index 0000000..d74489f
--- /dev/null
+++ b/api/app/lib/models/business_rule.js
@@ -0,0 +1,89 @@
+/* eslint-disable*/
+
+'use strict';
+
+module.exports = dc => {
+ const DataTypes = dc.ORM;
+ const sequelize = dc.orm;
+ const BusinessRule = sequelize.define("businessRule", {
+ id: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ defaultValue: null,
+ comment: "唯一标识",
+ primaryKey: true,
+ field: "id",
+ autoIncrement: true,
+ unique: "t_business_rule_id_uindex"
+ },
+ name: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: "业务规则名称",
+ primaryKey: false,
+ field: "name",
+ autoIncrement: false,
+ },
+ description: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: "业务规则描述",
+ primaryKey: false,
+ field: "description",
+ autoIncrement: false,
+ },
+ problemType: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: "标签",
+ primaryKey: false,
+ field: "problem_type",
+ autoIncrement: false,
+ },
+ ruleBasis: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ defaultValue: null,
+ comment: "制定依据",
+ primaryKey: false,
+ field: "rule_basis",
+ autoIncrement: false,
+ references: {
+ key: "id",
+ model: "tStandardDoc"
+ }
+ },
+ problemLevel: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: "问题级别",
+ primaryKey: false,
+ field: "problem_level",
+ autoIncrement: false,
+ },
+ createAt: {
+ type: DataTypes.DATE,
+ allowNull: false,
+ defaultValue: null,
+ comment: "创建时间",
+ primaryKey: false,
+ field: "create_at",
+ autoIncrement: false,
+ },
+ }, {
+ tableName: "t_business_rule",
+ comment: "",
+ indexes: []
+ });
+ dc.models.BusinessRule = BusinessRule;
+
+ // const { StandardDoc } = dc.models;
+ // BusinessRule.belongsTo(StandardDoc, { foreignKey: 'ruleBasis', targetKey: 'id' });
+ // MetadataDatabase.hasMany(TagDatabase, { foreignKey: 'database', sourceKey: 'id' });
+
+ return BusinessRule;
+};
\ No newline at end of file
diff --git a/api/app/lib/models/data_security_specification.js b/api/app/lib/models/data_security_specification.js
new file mode 100644
index 0000000..6f65d69
--- /dev/null
+++ b/api/app/lib/models/data_security_specification.js
@@ -0,0 +1,67 @@
+/* eslint-disable*/
+
+'use strict';
+
+module.exports = dc => {
+ const DataTypes = dc.ORM;
+ const sequelize = dc.orm;
+ const DataSecuritySpecification = sequelize.define("dataSecuritySpecification", {
+ id: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ defaultValue: null,
+ comment: "唯一标识",
+ primaryKey: true,
+ field: "id",
+ autoIncrement: true,
+ unique: "t_data_security_specification_id_uindex"
+ },
+ fileName: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: "文件名",
+ primaryKey: false,
+ field: "file_name",
+ autoIncrement: false,
+ },
+ tags: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: null,
+ comment: "标签",
+ primaryKey: false,
+ field: "tags",
+ autoIncrement: false,
+ },
+ createAt: {
+ type: DataTypes.DATE,
+ allowNull: false,
+ defaultValue: null,
+ comment: "文件创建时间",
+ primaryKey: false,
+ field: "create_at",
+ autoIncrement: false,
+ },
+ path: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: "文件路径",
+ primaryKey: false,
+ field: "path",
+ autoIncrement: false,
+ },
+ }, {
+ tableName: "t_data_security_specification",
+ comment: "",
+ indexes: []
+ });
+ dc.models.DataSecuritySpecification = DataSecuritySpecification;
+
+ // const { StandardDoc } = dc.models;
+ // BusinessRule.belongsTo(StandardDoc, { foreignKey: 'ruleBasis', targetKey: 'id' });
+ // MetadataDatabase.hasMany(TagDatabase, { foreignKey: 'database', sourceKey: 'id' });
+
+ return DataSecuritySpecification;
+};
\ No newline at end of file
diff --git a/api/app/lib/models/standard_doc.js b/api/app/lib/models/standard_doc.js
new file mode 100644
index 0000000..52d8207
--- /dev/null
+++ b/api/app/lib/models/standard_doc.js
@@ -0,0 +1,89 @@
+/* eslint-disable*/
+
+'use strict';
+
+module.exports = dc => {
+ const DataTypes = dc.ORM;
+ const sequelize = dc.orm;
+ const StandardDoc = sequelize.define("standardDoc", {
+ id: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ defaultValue: null,
+ comment: "唯一标识",
+ primaryKey: true,
+ field: "id",
+ autoIncrement: true,
+ unique: "t_standard_doc__id_uindex"
+ },
+ docName: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: "文档名称",
+ primaryKey: false,
+ field: "doc_name",
+ autoIncrement: false,
+ },
+ standardType: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: "标准类型",
+ primaryKey: false,
+ field: "standard_type",
+ autoIncrement: false,
+ },
+ tags: {
+ type: DataTypes.STRING,
+ allowNull: true,
+ defaultValue: null,
+ comment: "标签",
+ primaryKey: false,
+ field: "tags",
+ autoIncrement: false,
+ },
+ folder: {
+ type: DataTypes.INTEGER,
+ allowNull: true,
+ defaultValue: null,
+ comment: "归属的文件夹",
+ primaryKey: false,
+ field: "folder",
+ autoIncrement: false,
+ references: {
+ key: "id",
+ model: "tStandardDocFolder"
+ }
+ },
+ path: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: "文档存储路径",
+ primaryKey: false,
+ field: "path",
+ autoIncrement: false,
+ },
+ createAt: {
+ type: DataTypes.DATE,
+ allowNull: false,
+ defaultValue: null,
+ comment: "文件夹创建时间",
+ primaryKey: false,
+ field: "create_at",
+ autoIncrement: false,
+ },
+ }, {
+ tableName: "t_standard_doc",
+ comment: "",
+ indexes: []
+ });
+ dc.models.StandardDoc = StandardDoc;
+
+ // const { StandardDocFolder } = dc.models;
+ // StandardDoc.belongsTo(StandardDocFolder, { foreignKey: 'folder', targetKey: 'id' });
+ // MetadataDatabase.hasMany(TagDatabase, { foreignKey: 'database', sourceKey: 'id' });
+
+ return StandardDoc;
+};
\ No newline at end of file
diff --git a/api/app/lib/models/standard_doc_folder.js b/api/app/lib/models/standard_doc_folder.js
new file mode 100644
index 0000000..7b3cedf
--- /dev/null
+++ b/api/app/lib/models/standard_doc_folder.js
@@ -0,0 +1,62 @@
+/* eslint-disable*/
+
+'use strict';
+
+module.exports = dc => {
+ const DataTypes = dc.ORM;
+ const sequelize = dc.orm;
+ const StandardDocFolder = sequelize.define("standardDocFolder", {
+ id: {
+ type: DataTypes.INTEGER,
+ allowNull: false,
+ defaultValue: null,
+ comment: "唯一标识",
+ primaryKey: true,
+ field: "id",
+ autoIncrement: true,
+ unique: "t_standard_doc_folder_id_uindex"
+ },
+ name: {
+ type: DataTypes.STRING,
+ allowNull: false,
+ defaultValue: null,
+ comment: "文件夹名称",
+ primaryKey: false,
+ field: "name",
+ autoIncrement: false,
+ },
+ createAt: {
+ type: DataTypes.DATE,
+ allowNull: false,
+ defaultValue: null,
+ comment: "文件夹创建时间",
+ primaryKey: false,
+ field: "create_at",
+ autoIncrement: false,
+ },
+ parent: {
+ type: DataTypes.INTEGER,
+ allowNull: true,
+ defaultValue: null,
+ comment: "父级文件夹",
+ primaryKey: false,
+ field: "parent",
+ autoIncrement: false,
+ references: {
+ key: "id",
+ model: "tStandardDocFolder"
+ }
+ }
+ }, {
+ tableName: "t_standard_doc_folder",
+ comment: "",
+ indexes: []
+ });
+ dc.models.StandardDocFolder = StandardDocFolder;
+
+ // const { MetadataDatabase } = dc.models;
+ // StandardDocFolder.belongsTo(StandardDocFolder, { foreignKey: 'parent', targetKey: 'id' });
+ // MetadataDatabase.hasMany(TagDatabase, { foreignKey: 'database', sourceKey: 'id' });
+
+ return StandardDocFolder;
+};
\ No newline at end of file
diff --git a/api/app/lib/routes/dataQuality/index.js b/api/app/lib/routes/dataQuality/index.js
new file mode 100644
index 0000000..e308158
--- /dev/null
+++ b/api/app/lib/routes/dataQuality/index.js
@@ -0,0 +1,34 @@
+'use strict';
+
+const model = require('../../controllers/dataQuality/index');
+
+module.exports = function (app, router, opts, AuthCode) {
+
+ app.fs.api.logAttr['POST/standard-doc-folders'] = { content: '标准文档目录新增', visible: true };
+ router.post('/standard-doc-folders', model.postStandardDocFolders(opts))
+
+ app.fs.api.logAttr['GET/standard-doc-folders'] = { content: '标准文档目录列表', visible: true };
+ router.get('/standard-doc-folders', model.getStandardDocFolders(opts));
+
+
+ app.fs.api.logAttr['POST/standard-docs'] = { content: '新增标准文档', visible: true };
+ router.post('/standard-docs', model.postStandardDocs(opts))
+
+ app.fs.api.logAttr['GET/standard-docs'] = { content: '标准文档列表', visible: true };
+ router.get('/standard-docs', model.getStandardDocs(opts));
+
+ app.fs.api.logAttr['POST/postFolderFile'] = { content: '删除文件夹或文件', visible: true };
+ router.post('/postFolderFile', model.postFolderFile(opts))
+
+ app.fs.api.logAttr['POST/business-rules'] = { content: '新增/修改业务规则', visible: true };
+ router.post('/business-rules', model.postBusinessRules(opts))
+
+ app.fs.api.logAttr['GET/business-rules'] = { content: '查询业务规则列表', visible: true };
+ router.get('/business-rules', model.getBusinessRules(opts));
+
+ app.fs.api.logAttr['DEL/business-rules/:id'] = { content: '删除业务规则', visible: true };
+ router.del('/business-rules/:id', model.delBusinessRules(opts))
+
+ app.fs.api.logAttr['GET/regular-basis'] = { content: '查询规则依据列表', visible: true };
+ router.get('/regular-basis', model.getRegularBasis(opts));
+};
diff --git a/api/app/lib/routes/safetySpecification/index.js b/api/app/lib/routes/safetySpecification/index.js
new file mode 100644
index 0000000..8b4c0ba
--- /dev/null
+++ b/api/app/lib/routes/safetySpecification/index.js
@@ -0,0 +1,22 @@
+'use strict';
+
+const model = require('../../controllers/safetySpecification/index');
+
+module.exports = function (app, router, opts, AuthCode) {
+
+ // app.fs.api.logAttr['POST/meta/model'] = { content: '增加模型信息', visible: true };
+ // router.post('/meta/model', model.addModelManagement(opts))
+
+
+
+
+ app.fs.api.logAttr['POST/data-security/specifications'] = { content: '新增数据安全规范', visible: true };
+ router.post('/data-security/specifications', model.postSpecifications(opts))
+
+ app.fs.api.logAttr['GET/data-security/specifications'] = { content: '查询数据安全规范列表', visible: true };
+ router.get('/data-security/specifications', model.getSpecifications(opts));
+
+ app.fs.api.logAttr['del/data-security/specifications/:fileIds'] = { content: '查询数据安全规范列表', visible: true };
+ router.del('/data-security/specifications/:fileIds', model.delSpecifications(opts));
+
+};
diff --git a/scripts/0.0.8/01_alter_t_standard_doc_folder.sql b/scripts/0.0.8/01_alter_t_standard_doc_folder.sql
new file mode 100644
index 0000000..11199e6
--- /dev/null
+++ b/scripts/0.0.8/01_alter_t_standard_doc_folder.sql
@@ -0,0 +1,25 @@
+create table t_standard_doc_folder
+(
+ id serial not null,
+ name varchar(255) not null,
+ create_at timestamp with time zone not null,
+ parent integer
+);
+
+comment on table t_standard_doc_folder is '标准文档文件夹';
+
+comment on column t_standard_doc_folder.id is 'ID唯一标识';
+
+comment on column t_standard_doc_folder.name is '文件夹名称';
+
+comment on column t_standard_doc_folder.create_at is '文件夹创建时间';
+
+comment on column t_standard_doc_folder.parent is '父级文件夹';
+
+create unique index t_standard_doc_folder_id_uindex
+ on t_standard_doc_folder (id);
+
+alter table t_standard_doc_folder
+ add constraint t_standard_doc_folder_pk
+ primary key (id);
+
diff --git a/scripts/0.0.8/02_alter_t_standard_doc.sql b/scripts/0.0.8/02_alter_t_standard_doc.sql
new file mode 100644
index 0000000..2e88909
--- /dev/null
+++ b/scripts/0.0.8/02_alter_t_standard_doc.sql
@@ -0,0 +1,41 @@
+
+CREATE TYPE public."enum_standard_type" AS ENUM (
+'国家标准',
+'行业标准',
+'地方标准'
+);
+
+create table t_standard_doc
+(
+ id serial not null,
+ doc_name varchar(255) not null,
+ standard_type enum_standard_type not null,
+ tags varchar(255),
+ folder integer,
+ path varchar(255) not null,
+ create_at timestamp with time zone not null
+);
+
+comment on table t_standard_doc is '文档管理文件';
+
+comment on column t_standard_doc.id is 'ID唯一标识';
+
+comment on column t_standard_doc.doc_name is '文档名称';
+
+comment on column t_standard_doc.standard_type is '标准类型';
+
+comment on column t_standard_doc.tags is '标签';
+
+comment on column t_standard_doc.folder is '归属的文件夹';
+
+comment on column t_standard_doc.path is '文档存储路径';
+
+comment on column t_standard_doc.create_at is '文档创建时间';
+
+create unique index t_standard_doc_id_uindex
+ on t_standard_doc (id);
+
+alter table t_standard_doc
+ add constraint t_standard_doc_pk
+ primary key (id);
+
diff --git a/scripts/0.0.8/03_alter_ t_business_rule.sql b/scripts/0.0.8/03_alter_ t_business_rule.sql
new file mode 100644
index 0000000..6137e00
--- /dev/null
+++ b/scripts/0.0.8/03_alter_ t_business_rule.sql
@@ -0,0 +1,51 @@
+CREATE TYPE public."enum_problem_type" AS ENUM (
+'一致性',
+'准确性',
+'完整性',
+'有效性',
+'及时性',
+'规范性'
+);
+
+CREATE TYPE public."enum_problem_level" AS ENUM (
+'一般',
+'重要',
+'严重'
+);
+
+
+
+create table t_business_rule
+(
+ id serial not null,
+ name varchar(255) not null,
+ description varchar(255) not null,
+ problem_type enum_problem_type not null,
+ problem_level enum_problem_level not null,
+ rule_basis integer not null,
+ create_at timestamp with time zone not null
+);
+
+comment on table t_business_rule is '业务规则表';
+
+comment on column t_business_rule.id is 'ID唯一标识';
+
+comment on column t_business_rule.name is '业务规则名称';
+
+comment on column t_business_rule.description is '业务规则描述';
+
+comment on column t_business_rule.problem_type is '问题类型';
+
+comment on column t_business_rule.problem_level is '问题级别';
+
+comment on column t_business_rule.rule_basis is '制定依据';
+
+comment on column t_business_rule.create_at is '创建时间';
+
+create unique index t_business_rule_id_uindex
+ on t_business_rule (id);
+
+alter table t_business_rule
+ add constraint t_business_rule_pk
+ primary key (id);
+
diff --git a/scripts/0.0.8/04_alter_t_data_security_specification .sql b/scripts/0.0.8/04_alter_t_data_security_specification .sql
new file mode 100644
index 0000000..a39ab3c
--- /dev/null
+++ b/scripts/0.0.8/04_alter_t_data_security_specification .sql
@@ -0,0 +1,28 @@
+create table t_data_security_specification
+(
+ id serial not null,
+ file_name varchar(255) not null,
+ tags varchar(255),
+ create_at timestamp with time zone not null,
+ path varchar(255) not null
+);
+
+comment on table t_data_security_specification is '数据安全规范';
+
+comment on column t_data_security_specification.id is 'ID唯一标识';
+
+comment on column t_data_security_specification.file_name is '文件名';
+
+comment on column t_data_security_specification.tags is '标签';
+
+comment on column t_data_security_specification.create_at is '文件创建时间';
+
+comment on column t_data_security_specification.path is '文件路径';
+
+create unique index t_data_security_specification_id_uindex
+ on t_data_security_specification (id);
+
+alter table t_data_security_specification
+ add constraint t_data_security_specification_pk
+ primary key (id);
+
diff --git a/web/client/assets/files/common/1687322895851_3.jpg b/web/client/assets/files/common/1687322895851_3.jpg
new file mode 100644
index 0000000..8fe90ea
Binary files /dev/null and b/web/client/assets/files/common/1687322895851_3.jpg differ
diff --git a/web/client/assets/files/common/1687322905542_2.jpg b/web/client/assets/files/common/1687322905542_2.jpg
new file mode 100644
index 0000000..3f96826
Binary files /dev/null and b/web/client/assets/files/common/1687322905542_2.jpg differ
diff --git a/web/client/assets/files/common/1687654158463_1.jpg b/web/client/assets/files/common/1687654158463_1.jpg
new file mode 100644
index 0000000..e2c29e8
Binary files /dev/null and b/web/client/assets/files/common/1687654158463_1.jpg differ
diff --git a/web/client/assets/files/common/readme.txt b/web/client/assets/files/common/readme.txt
deleted file mode 100644
index a685d95..0000000
--- a/web/client/assets/files/common/readme.txt
+++ /dev/null
@@ -1 +0,0 @@
-03专项三期文件本地上传默认路径
\ No newline at end of file
diff --git a/web/client/src/layout/containers/layout/index.less b/web/client/src/layout/containers/layout/index.less
index d55219a..ce3bc72 100644
--- a/web/client/src/layout/containers/layout/index.less
+++ b/web/client/src/layout/containers/layout/index.less
@@ -1,2 +1,3 @@
@import '~perfect-scrollbar/css/perfect-scrollbar.css';
-@import '~nprogress/nprogress.css';
\ No newline at end of file
+@import '~nprogress/nprogress.css';
+@import '~simplebar-react/dist/simplebar.min.css';
\ No newline at end of file
diff --git a/web/client/src/sections/dataQuality/actions/approve.js b/web/client/src/sections/dataQuality/actions/approve.js
deleted file mode 100644
index 9f21dbd..0000000
--- a/web/client/src/sections/dataQuality/actions/approve.js
+++ /dev/null
@@ -1,29 +0,0 @@
-'use strict';
-
-import { basicAction } from '@peace/utils'
-import { ApiTable } from '$utils'
-
-export function getApproveList (query = {}) {
- return dispatch => basicAction({
- type: 'get',
- query,
- dispatch: dispatch,
- actionType: 'GET_APPROVE_LIST',
- url: `${ApiTable.approveList}`,
- msg: { error: '获取资源消费列表失败' },
- reducer: { name: '' }
- });
-}
-
-
-export function postApprove (data = {}) {
- return dispatch => basicAction({
- type: 'post',
- data,
- dispatch: dispatch,
- actionType: 'POST_APPROVE',
- url: `${ApiTable.approveList}`,
- msg: { option: '资源审批' },
- reducer: { name: '' }
- });
-}
diff --git a/web/client/src/sections/dataQuality/actions/documentLibrary.js b/web/client/src/sections/dataQuality/actions/documentLibrary.js
new file mode 100644
index 0000000..1d4eed1
--- /dev/null
+++ b/web/client/src/sections/dataQuality/actions/documentLibrary.js
@@ -0,0 +1,66 @@
+'use strict';
+
+import { basicAction } from '@peace/utils'
+import { ApiTable } from '$utils'
+
+export function getStandardDocFolders (query = {}) {
+ return dispatch => basicAction({
+ type: 'get',
+ query,
+ dispatch: dispatch,
+ actionType: 'GET_STANDARD_DOC_FOLDERS',
+ url: `${ApiTable.standardDocFolders}`,
+ msg: { error: '获取标准文档目录列表失败' },
+ reducer: { name: '' }
+ });
+}
+
+
+export function postStandardDocFolders (data = {}) {
+ return dispatch => basicAction({
+ type: 'post',
+ data,
+ dispatch: dispatch,
+ actionType: 'POST_STANDARD_DOC_FOLDERS',
+ url: `${ApiTable.standardDocFolders}`,
+ msg: { option: '标准文档目录新增' },
+ reducer: { name: '' }
+ });
+}
+
+export function postStandardDocs (data = {}) {
+ return dispatch => basicAction({
+ type: 'post',
+ data,
+ dispatch: dispatch,
+ actionType: 'POST_STANDARD_DOCS',
+ url: `${ApiTable.standardDocs}`,
+ msg: { option: '新增标准文档' },
+ reducer: { name: '' }
+ });
+}
+
+export function getStandardDocs (query = {}) {
+ return dispatch => basicAction({
+ type: 'get',
+ query,
+ dispatch: dispatch,
+ actionType: 'GET_STANDARD_DOCS',
+ url: `${ApiTable.standardDocs}`,
+ msg: { error: '获取标准文档列表失败' },
+ reducer: { name: '' }
+ });
+}
+
+export function postFolderFile (data) {
+ return dispatch => basicAction({
+ type: 'post',
+ data,
+ dispatch: dispatch,
+ actionType: 'POST_FOLDER_FILE',
+ url: ApiTable.postFolderFile,
+ msg: { option: '删除文件夹或文件' },
+ reducer: { name: '' }
+ });
+}
+
diff --git a/web/client/src/sections/dataQuality/actions/index.js b/web/client/src/sections/dataQuality/actions/index.js
index f233405..bb9a933 100644
--- a/web/client/src/sections/dataQuality/actions/index.js
+++ b/web/client/src/sections/dataQuality/actions/index.js
@@ -1,9 +1,11 @@
'use strict';
import * as example from './example'
-import * as approve from './approve'
+import * as documentLibrary from './documentLibrary'
+import * as ruleLibrary from './ruleLibrary'
export default {
...example,
- ...approve,
+ ...documentLibrary,
+ ...ruleLibrary,
}
\ No newline at end of file
diff --git a/web/client/src/sections/dataQuality/actions/ruleLibrary.js b/web/client/src/sections/dataQuality/actions/ruleLibrary.js
new file mode 100644
index 0000000..b3182d5
--- /dev/null
+++ b/web/client/src/sections/dataQuality/actions/ruleLibrary.js
@@ -0,0 +1,52 @@
+'use strict';
+
+import { basicAction } from '@peace/utils'
+import { ApiTable } from '$utils'
+
+export function postBusinessRules (data = {}) {
+ let reminder = data?.id ? '修改业务规则' : '新增业务规则'
+ return dispatch => basicAction({
+ type: 'post',
+ data,
+ dispatch: dispatch,
+ actionType: 'POST_BUSINESS_RULES',
+ url: `${ApiTable.businessRules}`,
+ msg: { option: reminder },
+ reducer: { name: '' }
+ });
+}
+
+export function getBusinessRules (query = {}) {
+ return dispatch => basicAction({
+ type: 'get',
+ query,
+ dispatch: dispatch,
+ actionType: 'GET_BUSINESS_RULES',
+ url: `${ApiTable.businessRules}`,
+ msg: { error: '查询业务规则列表失败' },
+ reducer: { name: '' }
+ });
+}
+
+export function delBusinessRules (id) {
+ return dispatch => basicAction({
+ type: 'del',
+ dispatch: dispatch,
+ actionType: 'del_BUSINESS_RULES',
+ url: `${ApiTable.delBusinessRules.replace('{id}', id)}`,
+ msg: { option: '删除业务规则' },
+ reducer: { name: '' }
+ });
+}
+
+export function getRegularBasis (query = {}) {
+ return dispatch => basicAction({
+ type: 'get',
+ query,
+ dispatch: dispatch,
+ actionType: 'GET_REGULAR_BASIS',
+ url: `${ApiTable.regularBasis}`,
+ msg: { error: '查询规则依据列表失败' },
+ reducer: { name: '' }
+ });
+}
diff --git a/web/client/src/sections/dataQuality/components/approveModal.js b/web/client/src/sections/dataQuality/components/approveModal.js
deleted file mode 100644
index 4d01719..0000000
--- a/web/client/src/sections/dataQuality/components/approveModal.js
+++ /dev/null
@@ -1,94 +0,0 @@
-import React, { useEffect, useState } from 'react'
-import { connect } from 'react-redux';
-import moment from 'moment';
-import { v4 as uuidv4 } from 'uuid'
-
-import { Tabs, Form, Input, DatePicker, Button, Modal, Radio } from 'antd';
-
-
-function ApproveModal ({ loading, clientHeight, user, actions, dispatch, close, success, editData, }) {
-
- const { resourceConsumption } = actions
- const [tabsKey, setTabsKey] = useState("stay")
- const [query, setQuery] = useState({ page: 0, limit: 10 });
- const [proTableList, setProTableList] = useState({ rows: [], count: 0 });
- const [approve, setApprove] = useState()
-
- const [form] = Form.useForm();
- useEffect(() => {
-
- }, [])
-
-
-
-
-
-
- return <>
-