const fs = require("fs"); const path = require("path"); const { sys_model, querySql, sys_model_field, op } = require("../../middleware/baseModel"); const autoFile = require("../service/autoFile"); const funTool = require("../../tool/funTool"); const uuid = require("node-uuid"); module.exports = { "GET /sys_model/detail": async (ctx, next) => { let id = ctx.get("id"); let res = await sys_model.findOne({ where: { id } }); return ctx.success(res); }, "GET /sys_model/all": async (ctx, next) => { let project_id = ctx.getAdminProjectId(); let resList = await sys_model.findAll({ where: { project_id } }); let resPromise = resList.map(async (row) => { let newRow = row.toJSON(); let isExistTableName = await autoFile.querySql(`select TABLE_NAME from information_schema.TABLES where TABLE_NAME ="${newRow.key}"`, project_id); if (isExistTableName && isExistTableName.length > 0) { newRow.isTableExist = true; } else { newRow.isTableExist = false; } let modelPath = await autoFile.outBuildPath(`api/model/${newRow.key}.js`, project_id); let isExistModel = await funTool.isExist(modelPath); newRow.isExistModel = isExistModel; // 查询模型下所有字段 let dbColKeys = []; let modelRow = await sys_model.findOne({ where: { id: newRow.id } }); if (modelRow && newRow.isTableExist) { let colRows = await autoFile.querySql(`show columns from ${modelRow.key}`, project_id); dbColKeys = colRows.map((p) => p.Field); } let isDbFielExist = true; let model_fields = await sys_model_field.findAll({ where: { model_id: newRow.id } }); model_fields.forEach((newFielRow) => { let curRow = newFielRow.toJSON(); if (dbColKeys.indexOf(curRow.key) === -1) { isDbFielExist = false; } }); newRow.isDbFielExist = isDbFielExist; return newRow; }); let newResList = await Promise.all(resPromise); return ctx.success(newResList); }, // 从db中同步模型 "POST /sys_model/autoModelBydb": async (ctx, next) => { let project_id = ctx.getAdminProjectId(); let rows = await autoFile.querySql(`select TABLE_NAME,TABLE_COMMENT from information_schema.TABLES`, project_id) let notNeedPrefix = ["sys", "usr", "dtl"] const checkNeedPrefix = (item) => { let isCheck = true for (let i = 0; i < notNeedPrefix.length; i++) { let str = notNeedPrefix[i] if (item.indexOf(str) > -1) { isCheck = false break; } } return isCheck } let needKeys = rows.filter(item => item.TABLE_NAME.charAt(3) === '_' && /^[a-z_]+$/.test(item.TABLE_NAME) && checkNeedPrefix(item.TABLE_NAME)); if (needKeys && needKeys.length > 0) { // 删除已存在的 model let model_rows = await sys_model.findAll({ where: { project_id } }) if (model_rows && model_rows.length > 0) { for (let i = 0; i < model_rows.length; i++) { let model_row = model_rows[i] await sys_model_field.destroy({ where: { model_id: model_row.id } }) await model_row.destroy() } } for (let i = 0; i < needKeys.length; i++) { let needKey = needKeys[i].TABLE_NAME let needName = needKeys[i].TABLE_COMMENT || '' let modelRow = await sys_model.findOne({ where: { key: needKey, project_id } }); // 不存在,则创建model if (!modelRow) { let res = await sys_model.create({ key: needKey, name: needName, project_id: project_id }) let sql = `SELECT COLUMN_NAME AS Field,COLUMN_TYPE AS Type,COLUMN_COMMENT AS Comment, IS_NULLABLE AS 'NULL',COLUMN_DEFAULT AS 'Default' FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '${needKey}'` console.warn(`\nautoModelBydb:${sql}\n`) let colRows = await autoFile.querySql(sql, project_id); // 过滤掉id主键 colRows = colRows.filter(p => p.Field !== "id" || p.Field !== "last_modify_time" || p.Field !== "create_time") if (colRows && colRows.length > 0) { for (let j = 0; j < colRows.length; j++) { let colRow = colRows[j] let sort = (j + 1) * 10 let default_value = colRow.Default ? colRow.Default : "" let allow_null = colRow.Null === "NO" ? false : true let data_length = 0 if (colRow.Type) { let regex = /\((\d+)\)/g; let match = regex.exec(colRow.Type) if (match && match.length === 2 && match[1]) { data_length = parseInt(match[1]) } } let data_type = autoFile.mapMySQLTypeToSequelize(colRow.Type) // 映射前端组件 const dataTypeToComponentMap = { STRING: 'Input', TEXT: 'Editor', INTEGER: 'InputNumber', BOOLEAN: 'i-switch', DATE: 'DatePicker' }; let comType = dataTypeToComponentMap[data_type] || "Input" let control = { "comType": comType } await sys_model_field.create({ model_id: res.id, key: colRow.Field, name: colRow.Comment, data_type, data_length, control, allow_null, default_value: default_value, sort }) } } } } } return ctx.success(); }, "POST /sys_model/interface": async (ctx, next) => { let row = ctx.getBody(); const baseModel = require("../../middleware/baseModel"); let { model_key, map_option } = row; let { key, value } = map_option; if (baseModel[model_key]) { let dataRows = await baseModel[model_key].findAll({ attributes: [key, value] }); dataRows = dataRows.map((p) => { return { key: p[key], value: p[value] }; }); return ctx.success(dataRows); } return ctx.fail("数据模型不存在"); }, "POST /sys_model/add": async (ctx, next) => { let row = ctx.getBody(); let project_id = ctx.getAdminProjectId(); let { key, name } = row; key = key.trim(); const res = await sys_model.create({ key, name, project_id }); return ctx.success(res); }, "POST /sys_model/edit": async (ctx, next) => { let row = ctx.getBody(); let { id, key, name } = row; key = key.trim(); const res = await sys_model.update( { id, key, name }, { where: { id: id, }, } ); return ctx.success(res); }, "POST /sys_model/del": async (ctx, next) => { let id = ctx.get("id"); await autoFile.destroyApiFile(id); // 删除字段表 await sys_model_field.destroy({ where: { model_id: id } }); // 删除主数据 const res = await sys_model.destroy({ where: { id: id } }); return ctx.success(res); }, // 生成model "POST /sys_model/regenerate": async (ctx, next) => { let row = ctx.getBody(); let { id } = row; if (id) { let sysModelFields = await sys_model_field.findAll({ where: { model_id: id } }); if (sysModelFields && sysModelFields.length > 0) { let tempUUid = uuid.v4(); // 创建model await autoFile.autoModel(id, tempUUid); // 创建db await autoFile.autoDb(id, tempUUid); // 创建apiServer await autoFile.autoController(id); } else { return ctx.fail("字段未添加,无效生成"); } } return ctx.success(); }, };