Files
platformV2Web/api/service/autoFile.js
张成 8309808835 1
2025-11-21 16:53:49 +08:00

427 lines
14 KiB
JavaScript

var ejs = require("ejs");
const path = require("path");
const fs = require("fs");
const db = require("../../middleware/db");
const funTool = require("../../tool/funTool");
const logsUtil = require("../../tool/logs");
const Sequelize = require("sequelize");
const { sys_project, sys_model, sys_model_field, sys_form, sys_form_field, op, querySql } = require("../../middleware/baseModel");
module.exports = {
configTemplate(curPath) {
let tempPath = path.join(__dirname, `../../config/template/${curPath}`);
return tempPath;
},
mapMySQLTypeToSequelize(mysqlType) {
const typeMapping = {
'INT': "INTEGER",
'VARCHAR': "STRING",
'TEXT': "TEXT",
'DATE': "DATE",
'DATETIME': "DATE",
'TIMESTAMP': "DATE",
'BOOLEAN': "BOOLEAN",
'FLOAT': "FLOAT",
'DOUBLE': "DOUBLE",
'DECIMAL': "DECIMAL",
'BLOB': "BLOB",
'JSON': "JSON",
};
const baseType = mysqlType.replace(/\(.*?\)/, '').toUpperCase();
return typeMapping[baseType] || "STRING";
},
async outBuildPath(curPath, projectId) {
let PROJECT_PATH = ``;
if (projectId) {
let projectRow = await sys_project.findOne({ where: { id: projectId } });
if (projectRow) {
let { key } = projectRow;
PROJECT_PATH = `${key}/`;
}
}
let tempPath = path.join(__dirname, `../../build/${PROJECT_PATH}${curPath}`);
let directoryPath = path.dirname(tempPath);
if (!fs.existsSync(directoryPath)) {
// 如果目录不存在,创建目录
fs.mkdirSync(directoryPath, { recursive: true });
console.log("目录已创建");
}
return tempPath;
},
getBuildUrl(curPath) {
let dirPath = path.join(__dirname, "../../");
let newFilePath = curPath.replace(dirPath, "");
newFilePath = newFilePath.replace("build", "");
return newFilePath;
},
async querySql(sql, project_id) {
let dbPath = await this.outBuildPath(`api/db.js`, project_id);
let db = require(dbPath);
return await db.sequelize.query(sql, { type: Sequelize.QueryTypes.RAW });
},
async ddlSql(sql, project_id) {
let dbPath = await this.outBuildPath(`api/db.js`, project_id);
let db = require(dbPath);
return await db.sequelize.query(sql, { type: Sequelize.QueryTypes.RAW });
},
async autoConfig(project_id) {
let projectRow = await sys_project.findOne({ where: { id: project_id } });
if (projectRow) {
let { key: project_key } = projectRow
let projectConfig = await sys_project_config.findOne({ where: { project_id: project_id } });
let tempPath = this.configTemplate(`config.ejs`);
let dbTxt = await fs.readFileSync(tempPath, "utf-8");
let htmlDbConnect = ejs.render(dbTxt, { project_key, config: projectConfig }, { rmWhitespace: true });
let dbTempBuildPath = await this.outBuildPath(`config/config.json`, project_id);
await fs.writeFileSync(dbTempBuildPath, htmlDbConnect);
}
},
async autoDbConfig(project_id) {
let projectRow = await sys_project.findOne({ where: { id: project_id } });
if (projectRow) {
let projectConfigRow = await sys_project_config.findOne({ where: { project_id } });
if (projectConfigRow) {
let dbConfig = projectConfigRow.db;
let tempPath = this.configTemplate(`db.ejs`);
let dbTxt = await fs.readFileSync(tempPath, "utf-8");
let htmlDbConnect = ejs.render(dbTxt, { dbConfig }, { rmWhitespace: true });
let dbTempBuildPath = await this.outBuildPath(`api/db.js`, project_id);
if (await funTool.isExist(dbTempBuildPath)) {
fs.unlinkSync(dbTempBuildPath);
}
await fs.writeFileSync(dbTempBuildPath, htmlDbConnect);
}
}
},
async autoInitDb(project_id) {
let dbDdlPath = this.configTemplate(`dbInit/ddl.db`);
let ddlSql = await fs.readFileSync(dbDdlPath, "utf-8");
let ddlRows = ddlSql.split(';')
// 创建ddl表
if (ddlRows && ddlRows.length > 0) {
for (let i = 0; i < ddlRows.length; i++) {
try {
let sql = ddlRows[i].trim()
await this.ddlSql(sql, project_id)
}
catch (e) {
logsUtil.errError(e.message)
}
}
}
let dbInsertPath = this.configTemplate(`dbInit/insert.db`);
let insertSql = await fs.readFileSync(dbInsertPath, "utf-8");
let insertRows = insertSql.split(';')
// 初始化表 数据
if (insertRows && insertRows.length > 0) {
for (let i = 0; i < insertRows.length; i++) {
try {
let sql = insertRows[i].trim()
let projectRow = await sys_project.findOne({ where: { id: project_id } });
if (projectRow) {
sql = sql.replace("${demo系统管理}", projectRow.name)
}
await this.ddlSql(sql, project_id)
}
catch (e) {
logsUtil.errError(e.message)
}
}
}
},
async autoModel(id, uuid) {
let modelRow = await sys_model.findOne({ where: { id: id } });
if (modelRow) {
let tempPath = this.configTemplate(`model.ejs`);
let modelTxt = await fs.readFileSync(tempPath, "utf-8");
let columnsRows = await sys_model_field.findAll({
where: {
model_id: id,
key: {
[op.notIn]: ["id", "create_time", "last_modify_time"]
}
}, order: [["sort", "asc"]]
});
if (columnsRows) {
let html = ejs.render(modelTxt, { columns: columnsRows, table_name: modelRow.key, isProjectDb: false }, { rmWhitespace: true });
let modelBuildPath = await this.outBuildPath(`api/model/${modelRow.key}.js`, modelRow.project_id);
await fs.writeFileSync(modelBuildPath, html);
let htmlDb = ejs.render(modelTxt, { columns: columnsRows, table_name: modelRow.key, isProjectDb: true }, { rmWhitespace: true });
let modelTempBuildPath = await this.outBuildPath(`api/model/${modelRow.key}_${uuid}.js`, modelRow.project_id);
await fs.writeFileSync(modelTempBuildPath, htmlDb);
}
}
},
async autoDb(id, uuid) {
let modelRow = await sys_model.findOne({ where: { id: id } });
if (modelRow) {
let { project_id, key } = modelRow;
let modelPath = await this.outBuildPath(`api/model/${key}_${uuid}.js`, project_id);
try {
// 延时调用 重新生成数据库
let modelDb = require(modelPath);
await modelDb.sync({ force: true });
fs.unlinkSync(modelPath); // 重新删除文件
} catch (e) {
console.error(e.message);
fs.unlinkSync(modelPath); // 重新删除文件
}
}
},
async autoController(id) {
let modelRow = await sys_model.findOne({ where: { id: id } });
if (modelRow) {
let { key: table_name } = modelRow.toJSON();
let controllerPath = this.configTemplate("controller.ejs");
let controllerTxt = await fs.readFileSync(controllerPath, "utf-8", { rmWhitespace: true });
let html = ejs.render(controllerTxt, { table_name });
let controllerAdminPath = await this.outBuildPath(`api/controller_admin/${table_name}.js`, modelRow.project_id);
await fs.writeFileSync(controllerAdminPath, html);
}
},
async getFrontTemplatePath(form_id) {
let fileName = "";
let model_id = "";
let modelName = "custom_template";
let sysFormRow = await sys_form.findOne({ where: { id: form_id } });
if (sysFormRow) {
fileName = path.basename(sysFormRow.component).replace(".vue", "");
model_id = sysFormRow.model_id;
let modelRow = await sys_model.findOne({ where: { id: model_id } });
if (modelRow) {
modelName = modelRow.key;
}
}
return { modelName, fileName, model_id };
},
async createForm(row) {
if (row) {
let { model_id, component, api_path } = row;
let formRow = await sys_form.findOne({ where: { model_id, component, api_path } });
if (formRow) {
await sys_form_field.destroy({ where: { form_id: formRow.id } }); // 删除所有字段
} else {
let modelRow = await sys_model.findOne({ where: { id: model_id } });
let { name, project_id } = modelRow;
formRow = await sys_form.create({ name, project_id, model_id, component, api_path });
}
// 创建表单
if (formRow) {
let form_id = formRow.id;
let fieldRows = await sys_model_field.findAll({ where: { model_id: model_id }, order: [["sort", "asc"]] });
if (fieldRows && fieldRows.length > 0) {
for (let i = 0; i < fieldRows.length; i++) {
let { id: model_field_id, name: model_field_name, control, data_type } = fieldRows[i];
let is_show_list = data_type === "TEXT" ? 0 : 1;
await sys_form_field.create({ form_id, model_field_id, model_field_name, control, is_show_edit: 1, is_edit_disable: 0, is_show_list, is_show_seach: 1, sort: i });
}
}
}
}
},
// 生成前端文件Api
async autoFrontApi(row) {
if (row) {
let { id: form_id, api_path, project_id } = row;
let api_path_index = api_path.lastIndexOf("/");
let folderPath = await this.outBuildPath(`admin/src/api/${api_path.substr(0, api_path_index)}`, project_id);
let filePath = api_path.substr(api_path_index, api_path.length - 1);
let apihtml = "";
let { modelName, fileName } = await this.getFrontTemplatePath(form_id);
if (fileName) {
let apiServerPath = this.configTemplate("vue_file/apiServer.ejs");
let controllerTxt = await fs.readFileSync(apiServerPath, "utf-8");
apihtml = ejs.render(controllerTxt, { modelName, fileName });
}
//创建文件夹
await funTool.mkdirsSync(folderPath);
let newFilePath = `${folderPath}/${filePath}`;
// 创建api文件
await fs.writeFileSync(newFilePath, apihtml);
let buildUrl = this.getBuildUrl(newFilePath);
return buildUrl;
}
},
// 创建page 下Vue文件
async autoFrontVue(row) {
if (row) {
let { id: form_id, component, api_path } = row;
let component_index = component.lastIndexOf("/");
let folderRoot = `${component.substr(0, component_index)}`;
let { fileName, model_id } = await this.getFrontTemplatePath(form_id);
if (fileName) {
let sysFormRow = await sys_form.findOne({ where: { id: form_id } });
if (sysFormRow && sysFormRow.id) {
let sysFormFields = await sys_form_field.findAll({
where: { form_id: sysFormRow.id },
include: [
{
association: sys_form_field.associations.field,
attributes: ["key", "name", "data_type", "default_value"],
},
],
order: [["sort", "asc"]],
});
let newcolumnsRows = sysFormFields.map((p) => {
let newRow = p.toJSON();
// 设置默认值
if (newRow.field && newRow.field.default_value) {
newRow.default_value = newRow.field.default_value;
} else {
newRow.default_value = "";
}
newRow.name = newRow.model_field_name;
if (newRow.field && newRow.field.key) {
newRow.key = newRow.field.key;
newRow.data_type = newRow.field.data_type;
}
if (typeof newRow.control === "string") {
newRow.control = JSON.parse(newRow.control);
}
if (newRow.control.interfaceType === "本地数据") {
newRow.source = newRow.control.localData || [];
} else {
newRow.source = [];
}
return newRow;
});
let pagePath = this.configTemplate(`vue_file/page.ejs`);
let controllerTxt = await fs.readFileSync(pagePath, "utf-8");
let pageHtml = ejs.render(controllerTxt, { api_path, fileName, columns: newcolumnsRows, model_id }, { rmWhitespace: true });
let folderPath = await this.outBuildPath(`admin/src/view/${folderRoot}`, sysFormRow.project_id);
//创建文件夹
await funTool.mkdirsSync(folderPath);
let filePath = `${folderPath}/${fileName}.vue`;
await fs.writeFileSync(filePath, pageHtml);
let buildUrl = this.getBuildUrl(filePath);
return buildUrl;
}
}
}
},
// 删除vueApiServer文件
async destroyApiFile(form_id) {
try {
let formRow = await sys_form.findOne({ where: { id: form_id } });
if (formRow) {
let { model_id, project_id } = formRow;
let modelRow = await sys_model.findOne({ where: { id: model_id } });
if (modelRow) {
let modelKey = modelRow.key;
// 删除后端 controller
let controller_admin_path = await this.outBuildPath(`api/controller_admin/${modelKey}.js`, project_id);
if (await funTool.isExist(controller_admin_path)) {
fs.unlinkSync(controller_admin_path);
}
// 删除后端 modelPath
let modelPath = await this.outBuildPath(`api/model/${modelKey}.js`, project_id);
if (await funTool.isExist(modelPath)) {
fs.unlinkSync(modelPath);
}
// 删除数据库
await ddlSql(`DROP TABLE ${modelKey}`);
}
}
} catch (error) {
logsUtil.errError(error.message);
return false;
}
return true;
},
// 删除vue文件
async destroyVueFile(form_id) {
let formRow = await sys_form.findOne({ where: { id: form_id } });
if (formRow) {
let { id, component, api_path, project_id } = formRow;
// 删除前端page
if (component) {
let pagePath = await this.outBuildPath(`admin/src/view/${component}`, project_id);
if (await funTool.isExist(pagePath)) {
fs.unlinkSync(pagePath);
}
}
// 删除前端apiServe
if (api_path) {
let apiPath = await this.outBuildPath(`admin/src/api/${api_path}`, project_id);
if (await funTool.isExist(apiPath)) {
fs.unlinkSync(apiPath);
}
}
// 删除表单
let formRow = await sys_form.findOne({ where: { id } });
if (formRow) {
await sys_form_field.destroy({ where: { form_id: formRow.id } });
await formRow.destroy({});
}
}
},
};