This commit is contained in:
张成
2025-11-21 16:53:49 +08:00
commit 8309808835
286 changed files with 32656 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
const { sys_announcement, op } = require('../../middleware/baseModel')
module.exports = {
'GET /sys_announcement/dtl': async (ctx, next) => {
const resList = await sys_announcement.findOne({ order: [['id', 'DESC']] })
return ctx.success(resList)
},
'POST /sys_announcement/add': async (ctx, next) => {
let row = ctx.getBody()
let dbRow = await sys_announcement.findOne({ order: [['id', 'DESC']] })
if (dbRow) {
await dbRow.update(row)
} else {
await sys_announcement.create(row)
}
return ctx.success()
},
'POST /sys_announcement/edit': async (ctx, next) => {
let row = ctx.getBody()
let id = ctx.get('id')
const resList = await sys_announcement.update(row, {
where: {
id: id
}
})
return ctx.success(resList)
},
}

View File

@@ -0,0 +1,9 @@
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 = {
"POST /sys_build/down": async (ctx, next) => {},
};

View File

@@ -0,0 +1,43 @@
const { sys_control_type, op } = require("../../middleware/baseModel");
module.exports = {
"GET /sys_control_type/all": async (ctx, next) => {
const resList = await sys_control_type.findAll();
return ctx.success(resList);
},
"POST /sys_control_type/page": async (ctx, next) => {
let param = ctx.getPageSize();
let row = ctx.getBody();
let { key, value } = row.seachOption;
let where = {};
if (key && value) {
where[key] = { [op.like]: "%" + value + "%" };
}
const res = await sys_control_type.findAndCountAll({
where,
order: [["id", "DESC"]],
...param,
});
return ctx.success(res);
},
"POST /sys_control_type/add": async (ctx, next) => {
let row = ctx.getBody();
const res = await sys_control_type.create(row);
return ctx.success(res);
},
"POST /sys_control_type/edit": async (ctx, next) => {
let row = ctx.getBody();
let id = ctx.get("id");
const resList = await sys_control_type.update(row, { where: { id: id } });
return ctx.success(resList);
},
"POST /sys_control_type/del": async (ctx, next) => {
let id = ctx.get("id");
const res = await sys_control_type.destroy({ where: { id: id } });
return ctx.success(res);
},
};

View File

@@ -0,0 +1,104 @@
var UUID = require("uuid");
var fs = require("fs");
var path = require("path");
const ossTool = require("../service/ossTool");
const funTool = require("../../tool/funTool");
const { sys_project, sys_project_config } = require("../../middleware/baseModel");
var ejs = require("ejs");
const AdmZip = require("adm-zip");
module.exports = {
"POST /sys_file/upload_img": async (ctx, next) => {
const files = ctx.request.files; // 获取上传文件
let fileArray = [];
let rootPath = path.join(__dirname, "../../upload/imgs");
for (var key in files) {
fileArray.push(files[key]);
}
//创建文件夹
await funTool.mkdirsSync(rootPath);
let resArray = [];
fileArray.forEach((file) => {
// 创建可读流
const reader = fs.createReadStream(file.path);
let filePath = `/${UUID.v1() + "_" + file.name}`;
// 创建可写流
const upStream = fs.createWriteStream(path.join(rootPath, filePath));
// 可读流通过管道写入可写流
reader.pipe(upStream);
resArray.push({ name: file.name, path: path.join("/imgs", filePath) });
});
ctx.success(resArray);
},
"POST /sys_file/upload_oos_img": async (ctx, next) => {
let fileArray = [];
const files = ctx.request.files; // 获取上传文件
for (var key in files) {
fileArray.push(files[key]);
}
let data = await ossTool.putImg(fileArray[0]);
if (data.path) {
return ctx.success(data);
} else {
return ctx.fail();
}
},
"POST /sys_file/get_base_project": async (ctx, next) => {
let project_id = ctx.get("project_id");
const project_row = await sys_project.findOne({ where: { id: project_id } });
const project_config_row = await sys_project_config.findOne({ where: { project_id: project_id } });
if (project_row && project_config_row) {
let tempPath = `./config/template/temp/${project_row.key}/`
const zip = new AdmZip("./config/template/systemWeb.zip");
zip.extractAllTo(tempPath, true);
let apiConfigPath = tempPath + "config/config.js"
let apiTemplateConfig = await fs.readFileSync(apiConfigPath, "utf-8");
let { db, aliyun, redis, wechat } = project_config_row
let apiConfigText = ejs.render(apiTemplateConfig, { project_key: project_row.key, db, aliyun, redis, wechat }, { rmWhitespace: true });
fs.writeFileSync(apiConfigPath, apiConfigText) // 替换api 配置文件
let adminConfigPath = tempPath + "admin/src/config/index.js"
let adminTemplateConfig = await fs.readFileSync(adminConfigPath, "utf-8");
let adminConfigText = ejs.render(adminTemplateConfig, { title: project_row.name }, { rmWhitespace: true });
fs.writeFileSync(adminConfigPath, adminConfigText) // 替换admin 配置文件
const zip2 = new AdmZip();
zip2.addLocalFolder(tempPath);
let buildPath = `./build/${project_row.key}/${project_row.key}.zip`
if (fs.existsSync(buildPath)) {
fs.unlinkSync(buildPath);
}
zip2.writeZip(buildPath); // 重新压缩文件
fs.rmSync(tempPath, { recursive: true, force: true });
return ctx.success({ path: buildPath.substring(2, buildPath.length) });
}
else {
return ctx.fail('获取错误,db 或者项目 配置不正确');
}
}
};

View File

@@ -0,0 +1,46 @@
const { sys_form_field, sys_form, op } = require("../../middleware/baseModel");
const { getMd5 } = require("../../tool/md5");
module.exports = {
"GET /sys_form_field/all": async (ctx, next) => {
let form_id = ctx.get("form_id");
const resList = await sys_form_field.findAll({
where: { form_id },
include: [
{
association: sys_form_field.associations.field,
attributes: ["key", "name"],
},
],
order: [["sort", "asc"]],
});
return ctx.success(resList);
},
"POST /sys_form_field/add": async (ctx, next) => {
let row = ctx.getBody();
const res = await sys_form_field.create(row);
return ctx.success(res);
},
"POST /sys_form_field/edit": async (ctx, next) => {
let row = ctx.getBody();
let { id } = row;
const res = await sys_form_field.update(row, {
where: {
id: id,
},
});
return ctx.success(res);
},
"POST /sys_form_field/del": async (ctx, next) => {
let id = ctx.get("id");
const res = await sys_form_field.destroy({
where: {
id: id,
},
});
return ctx.success(res);
},
};

View File

@@ -0,0 +1,75 @@
const path = require("path");
const autoFile = require("../service/autoFile");
const { sys_form, op } = require("../../middleware/baseModel");
module.exports = {
"GET /sys_form/all": async (ctx, next) => {
let project_id = ctx.getAdminProjectId();
const res = await sys_form.findAll({ where: { project_id } });
return ctx.success(res);
},
"GET /sys_form/detail": async (ctx, next) => {
let id = ctx.get("id");
const res = await sys_form.findOne({
where: { id: id },
include: [{ association: sys_form.associations.model, attributes: ["key", "name"] }],
});
return ctx.success(res);
},
"POST /sys_form/page": async (ctx, next) => {
let project_id = ctx.getAdminProjectId();
let param = ctx.getPageSize();
let row = ctx.getBody();
let { key, value } = row.seachOption;
let where = { project_id };
if (key && value) {
where[key] = { [op.like]: "%" + value + "%" };
}
const res = await sys_form.findAndCountAll({
where,
include: [{ association: sys_form.associations.model, attributes: ["key", "name"] }],
order: [["id", "DESC"]],
...param,
});
return ctx.success(res);
},
"POST /sys_form/add": async (ctx, next) => {
let row = ctx.getBody();
const res = await sys_form.create(row);
return ctx.success(res);
},
"POST /sys_form/edit": async (ctx, next) => {
let row = ctx.getBody();
let id = ctx.get("id");
const res = await sys_form.update(row, { where: { id: id } });
return ctx.success(res);
},
"POST /sys_form/del": async (ctx, next) => {
let id = ctx.get("id");
const res = await sys_form.destroy({ where: { id: id } });
return ctx.success(res);
},
"POST /sys_form/generate": async (ctx, next) => {
let form_id = ctx.get("id");
if (form_id) {
const sysFormRow = await sys_form.findOne({ where: { id: form_id } });
if (sysFormRow) {
await autoFile.createForm(sysFormRow);
let frontApiUrl = await autoFile.autoFrontApi(sysFormRow);
let frontVueUrl = await autoFile.autoFrontVue(sysFormRow);
frontApiUrl = path.normalize(frontApiUrl);
frontVueUrl = path.normalize(frontVueUrl);
return ctx.success({ frontApiUrl, frontVueUrl });
}
}
return ctx.fail("生成失败");
},
};

View File

@@ -0,0 +1,41 @@
const fs = require("fs");
const path = require("path");
const funTool = require("../../tool/funTool");
const { sys_log, op } = require("../../middleware/baseModel");
module.exports = {
"GET /sys_log/all": async (ctx, next) => {
let folderPath = path.join(__dirname, `../../logs`);
let files = fs.readdirSync(folderPath);
let newFiles = files.reverse().map((p) => {
return {
title: p,
};
});
return ctx.success(newFiles);
},
"GET /sys_log/detail": async (ctx, next) => {
let title = ctx.get("title");
let filePath = path.join(__dirname, `../../logs/${title}`);
let data = fs.readFileSync(filePath, "utf-8");
// data = data.replace(/\n/g, "</br>");
return ctx.success(data);
},
"GET /sys_log/delete": async (ctx, next) => {
let title = ctx.get("title");
let filePath = path.join(__dirname, `../../logs/${title}`);
if (await funTool.isExist(filePath)) {
fs.unlinkSync(filePath);
}
return ctx.success();
},
"GET /sys_log/operates": async (ctx, next) => {
let param = ctx.getPageSize();
let data = await sys_log.findAndCountAll({ order: [["id", "desc"]], ...param });
return ctx.success(data);
},
};

View File

@@ -0,0 +1,46 @@
const { sys_menu, op } = require("../../middleware/baseModel");
const autoFile = require("../service/autoFile");
const funTool = require("../../tool/funTool");
module.exports = {
"GET /sys_menu/index": async (ctx, next) => {
const menuRows = await sys_menu.findAll({
order: [["sort", "ASC"]],
});
let newMenuRows = menuRows.map((row) => {
let newRow = row.toJSON();
let nodeIds = funTool.getParantNode(newRow, menuRows);
newRow.parent_node_ids = nodeIds.reverse();
return newRow;
});
return ctx.success(newMenuRows);
},
"POST /sys_menu/add": async (ctx, next) => {
let row = ctx.getBody();
const res = await sys_menu.create(row);
return ctx.success(res);
},
"POST /sys_menu/edit": async (ctx, next) => {
let row = ctx.getBody();
let id = ctx.get("id");
const resList = await sys_menu.update(row, {
where: {
id: id,
},
});
return ctx.success(resList);
},
"POST /sys_menu/del": async (ctx, next) => {
let id = ctx.get("id");
const res = await sys_menu.destroy({ where: { id: id } });
return ctx.success(res);
},
};

View File

@@ -0,0 +1,229 @@
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();
},
};

View File

@@ -0,0 +1,90 @@
const { sys_model_field, sys_model, querySql, op } = require("../../middleware/baseModel");
const autoFile = require("../service/autoFile");
const handleRow = (row) => {
let { data_type, defaultValue } = row;
if (data_type === "INTEGER") {
row.defaultValue = row.defaultValue || 0;
if (row.data_length < 1 || row.data_length > 11) {
row.data_length = 11;
}
} else if (data_type === "DOUBLE") {
row.defaultValue = row.defaultValue || 0;
if (row.data_length < 1 || row.data_length > 12) {
row.data_length = 12;
}
}
};
module.exports = {
"GET /sys_model_field/all": async (ctx, next) => {
let model_id = ctx.get("model_id");
let dbColKeys = [];
let modelRow = await sys_model.findOne({ where: { id: model_id } });
if (modelRow) {
let { project_id } = modelRow;
let isExistTableName = await autoFile.querySql(`select TABLE_NAME from information_schema.TABLES where TABLE_NAME ="${modelRow.key}"`, project_id);
if (isExistTableName && isExistTableName.length > 0) {
let colRows = await autoFile.querySql(`show columns from ${modelRow.key}`, project_id);
dbColKeys = colRows.map((p) => p.Field);
}
}
let model_fields = await sys_model_field.findAll({ where: { model_id }, order: [["sort", "asc"]] });
model_fields = model_fields.map((p) => {
let newRow = p.toJSON();
if (dbColKeys.indexOf(newRow.key) > -1) {
newRow.isDbExist = true;
} else {
newRow.isDbExist = false;
}
return newRow;
});
return ctx.success(model_fields);
},
"GET /sys_model_field/allByKey": async (ctx, next) => {
let key = ctx.get("key");
let modelRow = await sys_model.findOne({ where: { key } });
if (modelRow) {
let model_id = modelRow.id;
const resList = await sys_model_field.findAll({ where: { model_id }, order: [["sort", "asc"]] });
return ctx.success(resList);
}
return ctx.fail();
},
"POST /sys_model_field/add": async (ctx, next) => {
let row = ctx.getBody();
handleRow(row);
const res = await sys_model_field.create(row);
return ctx.success(res);
},
"POST /sys_model_field/edit": async (ctx, next) => {
let row = ctx.getBody();
let { id } = row;
handleRow(row);
const res = await sys_model_field.update(row, {
where: {
id: id,
},
});
return ctx.success(res);
},
"POST /sys_model_field/del": async (ctx, next) => {
let id = ctx.get("id");
const res = await sys_model_field.destroy({
where: {
id: id,
},
});
return ctx.success(res);
},
};

View File

@@ -0,0 +1,46 @@
const { sys_parameter, op } = require("../../middleware/baseModel");
module.exports = {
"GET /sys_parameter/index": async (ctx, next) => {
const resList = await sys_parameter.findAll({ where: { is_modified: 0 } });
return ctx.success(resList);
},
"GET /sys_parameter/key": async (ctx, next) => {
let key = ctx.get("key");
const res = await sys_parameter.findOne({ where: { key: key } });
return ctx.success(res);
},
"POST /sys_parameter/setSysConfig": async (ctx, next) => {
let { title, logoUrl } = ctx.getBody();
await sys_parameter.update({ value: title }, { where: { key: "sys_title" } });
await sys_parameter.update({ value: logoUrl }, { where: { key: "sys_logo" } });
return ctx.success();
},
"POST /sys_parameter/add": async (ctx, next) => {
let row = ctx.getBody();
const res = await sys_parameter.create(row);
return ctx.success(res);
},
"POST /sys_parameter/edit": async (ctx, next) => {
let row = ctx.getBody();
let id = ctx.get("id");
const resList = await sys_parameter.update(row, {
where: {
id: id,
},
});
return ctx.success(resList);
},
"POST /sys_parameter/del": async (ctx, next) => {
let id = ctx.get("id");
const res = await sys_parameter.destroy({
where: {
id: id,
},
});
return ctx.success(res);
},
};

View File

@@ -0,0 +1,152 @@
const { sys_project, sys_project_config, op } = require("../../middleware/baseModel");
const autoFile = require("../service/autoFile");
module.exports = {
"GET /sys_project/all": async (ctx, next) => {
const res = await sys_project.findAll();
return ctx.success(res);
},
"GET /sys_project/detail": async (ctx, next) => {
let id = ctx.get("id");
const res = await sys_project.findOne({ where: { id: id } });
return ctx.success(res);
},
"POST /sys_project/detailConfig": async (ctx, next) => {
let project_id = ctx.get("project_id");
const res = await sys_project_config.findOne({ where: { project_id } });
return ctx.success(res);
},
"POST /sys_project/autoInitDb": async (ctx, next) => {
let project_id = ctx.get("project_id");
await autoFile.autoInitDb(project_id)
return ctx.success();
},
"POST /sys_project/editDbConfig": async (ctx, next) => {
let { project_id, username, password, database, host, port, dialect } = ctx.getBody();
const projectRow = await sys_project_config.findOne({ where: { project_id: project_id } });
if (projectRow) {
const res = await projectRow.update({ db: { username, password, database, host, port, dialect } }, { individualHooks: true });
await autoFile.autoDbConfig(project_id);
await autoFile.autoConfig(project_id);
return ctx.success(res);
} else {
return ctx.fail("未存在项目配置")
}
},
"POST /sys_project/editWxConfig": async (ctx, next) => {
let { project_id, appid, secret, mch_id, partner_key, partnerV3_key, notify_url, refund_notify_url } = ctx.getBody();
const projectRow = await sys_project_config.findOne({ where: { project_id: project_id } });
if (projectRow) {
const res = await projectRow.update({ wechat: { appid, secret, mch_id, partner_key, partnerV3_key, notify_url, refund_notify_url } }, { individualHooks: true });
await autoFile.autoConfig(project_id);
return ctx.success(res);
} else {
return ctx.fail("未存在项目配置")
}
},
"POST /sys_project/editRedisConfig": async (ctx, next) => {
let { project_id, host, pwd, port } = ctx.getBody();
const projectRow = await sys_project_config.findOne({ where: { project_id: project_id } });
if (projectRow) {
const res = await projectRow.update({ redis: { host, pwd, port } }, { individualHooks: true });
await autoFile.autoConfig(project_id);
return ctx.success(res);
}
else {
return ctx.fail("未存在项目配置")
}
},
"POST /sys_project/editAliyunConfig": async (ctx, next) => {
let { project_id, accessKeyId, accessKeySecret, ossUrl, } = ctx.getBody();
const projectRow = await sys_project_config.findOne({ where: { project_id: project_id } });
if (projectRow) {
const res = await projectRow.update({ aliyun: { accessKeyId, accessKeySecret, ossUrl } }, { individualHooks: true });
await autoFile.autoConfig(project_id);
return ctx.success(res);
} else {
return ctx.fail("未存在项目配置")
}
},
"POST /sys_project/export": async (ctx, next) => {
let rows = [];
let cols = [];
let title = "sys_project";
let tableAttributes = sys_project.tableAttributes;
let colKeys = Object.keys(tableAttributes);
colKeys.forEach((key) => {
let row = tableAttributes[key];
let caption = row.comment ? row.comment : row.fieldName;
cols.push({ caption, type: row.type.__proto__.key === "INTEGER" ? "number" : "string", key: row.field });
});
const dbRows = await sys_project.findAll({});
rows = dbRows.map((p) => {
let tempRow = p.toJSON();
let row = [];
cols.forEach((col) => {
row.push(tempRow[col.key]);
});
return row;
});
return ctx.downFile({ title, rows, cols });
},
"POST /sys_project/page": async (ctx, next) => {
let param = ctx.getPageSize();
let row = ctx.getBody();
let { key, value } = row.seachOption;
let where = {};
if (key && value) {
where[key] = { [op.like]: "%" + value + "%" };
}
const res = await sys_project.findAndCountAll({
where,
order: [["id", "DESC"]],
...param,
});
return ctx.success(res);
},
"POST /sys_project/add": async (ctx, next) => {
let row = ctx.getBody();
const res = await sys_project.create(row);
await sys_project_config.create({ project_id: res.id });
return ctx.success(res);
},
"POST /sys_project/edit": async (ctx, next) => {
let row = ctx.getBody();
let id = ctx.get("id");
const res = await sys_project.update(row, { where: { id: id }, individualHooks: true });
return ctx.success(res);
},
"POST /sys_project/del": async (ctx, next) => {
let id = ctx.get("id");
const res = await sys_project.destroy({ where: { id: id }, individualHooks: true });
return ctx.success(res);
},
};

View File

@@ -0,0 +1,77 @@
const {sys_project_type, op } = require('../../middleware/baseModel');
module.exports = {
'GET /sys_project_type/all' : async (ctx, next) => {
const res = await sys_project_type.findAll();
return ctx.success(res);
},
'GET /sys_project_type/detail' : async (ctx, next) => {
let id = ctx.get('id')
const res = await sys_project_type.findOne({where:{id:id}});
return ctx.success(res);
},
"POST /sys_project_type/export": async (ctx, next) => {
let rows = [];
let cols = [];
let title='sys_project_type';
let tableAttributes = sys_project_type.tableAttributes;
let colKeys = Object.keys(tableAttributes);
colKeys.forEach((key) => {
let row = tableAttributes[key];
let caption = row.comment ? row.comment : row.fieldName;
cols.push({ caption, type: row.type.__proto__.key === "INTEGER" ? "number" : "string", key: row.field });
});
const dbRows = await sys_project_type.findAll({});
rows = dbRows.map((p) => {
let tempRow = p.toJSON();
let row = [];
cols.forEach((col) => {
row.push(tempRow[col.key]);
});
return row;
});
return ctx.downFile({title, rows, cols });
},
'POST /sys_project_type/page' : async (ctx, next) => {
let param = ctx.getPageSize()
let row = ctx.getBody();
let {key,value}=row.seachOption
let where={}
if(key&&value){
where[key]={ [op.like]:'%' +value + '%'}
}
const res = await sys_project_type.findAndCountAll({
where,
order: [["id", "DESC"]],
...param,
});
return ctx.success(res);
},
'POST /sys_project_type/add': async (ctx, next) => {
let row = ctx.getBody();
const res = await sys_project_type.create(row);
return ctx.success(res);
},
'POST /sys_project_type/edit': async (ctx, next) => {
let row = ctx.getBody();
let id = ctx.get('id')
const res = await sys_project_type.update(row, { where: { id: id }, individualHooks: true });
return ctx.success(res);
},
'POST /sys_project_type/del': async (ctx, next) => {
let id = ctx.get('id')
const res = await sys_project_type.destroy({ where: { id: id }, individualHooks: true });
return ctx.success(res);
}
};

View File

@@ -0,0 +1,39 @@
const { sys_role, op } = require("../../middleware/baseModel");
const { getMd5 } = require("../../tool/md5");
module.exports = {
"GET /sys_role/index": async (ctx, next) => {
const resList = await sys_role.findAll({ where: {} });
return ctx.success(resList);
},
"POST /sys_role/add": async (ctx, next) => {
let row = ctx.getBody();
let { name, menus } = row;
const res = await sys_role.create({ name, menus });
return ctx.success(res);
},
"POST /sys_role/edit": async (ctx, next) => {
let row = ctx.getBody();
let { id, name, menus } = row;
const res = await sys_role.update(
{ name, menus },
{
where: {
id: id,
},
}
);
return ctx.success(res);
},
"POST /sys_role/del": async (ctx, next) => {
let id = ctx.get("id");
const res = await sys_role.destroy({
where: {
id: id,
},
});
return ctx.success(res);
},
};

View File

@@ -0,0 +1,132 @@
const { sys_user, sys_role, sys_log, sys_menu, op } = require("../../middleware/baseModel");
const tokenService = require("../service/token");
const { getMd5 } = require("../../tool/md5");
const dayjs = require("dayjs");
module.exports = {
"GET /sys_user/index": async (ctx, next) => {
const resList = await sys_user.findAll({
where: {
name: { [op.not]: "zc" },
},
include: [{ association: sys_user.associations.role, attributes: ["id", "name"] }],
});
return ctx.success(resList);
},
"POST /sys_user/login": async (ctx, next) => {
let name = ctx.get("name");
let password = ctx.get("password");
const userRow = await sys_user.findOne({
where: { name: name, password: getMd5(password) },
});
if (userRow) {
let { id, name, password, roleId } = userRow;
let role = await sys_role.findOne({ where: { id: roleId } });
let token = await tokenService.create({ id, name, password });
let nowDateStr = dayjs().format("YYYY-MM-DD HH:mm:ss");
await sys_log.create({ table_name: "sys_user", operate: "登录", content: `用户<span class="bold"> ${name} </span> 于 ${nowDateStr} 登录系统` });
return ctx.success({ token: token, user: userRow, authorityMenus: role.menus });
}
return ctx.fail("账号或密码错误!");
},
"POST /sys_user/export": async (ctx, next) => {
let rows = [];
let cols = [];
let title = "sys_user";
let tableAttributes = sys_user.tableAttributes;
let colKeys = Object.keys(tableAttributes);
colKeys.forEach((key) => {
let row = tableAttributes[key];
let caption = row.comment ? row.comment : row.fieldName;
cols.push({ caption, type: row.type.__proto__.key === "INTEGER" ? "number" : "string", key: row.field });
});
const userRows = await sys_user.findAll({});
rows = userRows.map((p) => {
let tempRow = p.toJSON();
let row = [];
cols.forEach((col) => {
row.push(tempRow[col.key]);
});
return row;
});
return ctx.downFile({ title, rows, cols });
},
"POST /sys_user/authorityMenus": async (ctx, next) => {
let user_id = ctx.getAdminUserId();
if (user_id) {
const userRow = await sys_user.findOne({ where: { id: user_id } });
if (userRow) {
let { id, roleId } = userRow;
let where = {};
let role = await sys_role.findOne({ where: { id: roleId } });
// 系统角色 不用授权
if (role.type === 0) {
let menuIds = JSON.parse(role.menus);
where = {
id: {
[op.in]: menuIds,
},
};
}
let munuRows = await sys_menu.findAll({
where,
order: [["sort", "ASC"]],
});
return ctx.success(munuRows);
}
}
return ctx.success();
},
"POST /sys_user/add": async (ctx, next) => {
let row = ctx.getBody();
// md5 加密
if (row && row.password) {
row.password = getMd5(row.password);
}
const res = await sys_user.create(row);
return ctx.success(res);
},
"POST /sys_user/edit": async (ctx, next) => {
let row = ctx.getBody();
let id = ctx.get("id");
let { name, roleId, password } = row;
if (password.length !== 32) {
password = getMd5(password);
}
const resList = await sys_user.update(
{ name, roleId, password },
{
where: {
id: id,
},
}
);
return ctx.success(resList);
},
"POST /sys_user/del": async (ctx, next) => {
let id = ctx.get("id");
const res = await sys_user.destroy({
where: { id: id },
});
return ctx.success(res);
},
};

View File

@@ -0,0 +1,149 @@
const dayjs = require("dayjs");
const fs = require('fs')
const path = require('path')
const { plu_api_linkjs, plu_ga, plu_func, plu_func_type, plu_version, querySql, op } = require("../../middleware/baseModel");
module.exports = {
"GET /config/v3_test": async (ctx, next) => {
let data = [
{
create_time: "2021-11-23 16:27:06",
last_modify_time: "2021-11-23 16:27:06",
id: 1,
name: "数据银行",
platformUrl: "databank.tmall.com",
linkUrl: "https://yunzhuan.light120.com/platform/databank/index.js",
inline: true,
},
{
create_time: "2021-11-23 16:26:38",
last_modify_time: "2021-11-23 16:26:38",
id: 2,
name: "生意参谋",
platformUrl: "sycm.taobao.com",
linkUrl: "https://yunzhuan.light120.com/platform/businessStaff/index.js",
inline: false,
},
{
create_time: "2021-11-23 16:26:03",
last_modify_time: "2021-11-23 16:26:03",
id: 3,
name: "策略中心",
platformUrl: "strategy.tmall.com",
linkUrl: "https://yunzhuan.light120.com/platform/strategy/index.js",
inline: false,
},
{
create_time: "2021-11-24 19:13:00",
last_modify_time: "2021-11-24 19:13:00",
id: 4,
name: "淘宝直播",
platformUrl: "market.m.taobao.com",
linkUrl: "https://yunzhuan.light120.com/platform/tbLive/index.js",
inline: true,
},
{
create_time: "2021-11-24 19:13:00",
last_modify_time: "2021-11-24 19:13:00",
id: 5,
name: "达摩盘",
platformUrl: "dmp.taobao.com",
linkUrl: "https://yunzhuan.light120.com/platform/dmp/index.js",
inline: true,
},
{
create_time: "2021-11-24 19:13:00",
last_modify_time: "2021-11-24 19:13:00",
id: 5,
name: "淘宝光合",
platformUrl: "creator.guanghe.taobao.com",
linkUrl: "https://yunzhuan.light120.com/platform/guanghe/index.js",
inline: true,
},
{
create_time: "2021-11-24 19:13:00",
last_modify_time: "2021-11-24 19:13:00",
id: 5,
name: "抖音电商",
platformUrl: "compass.jinritemai.com",
linkUrl: "https://yunzhuan.light120.com/platform/tikTok/index.js",
inline: true,
},
{
create_time: "2021-11-24 19:13:00",
last_modify_time: "2021-11-24 19:13:00",
id: 6,
name: "天猫详情",
platformUrl: "detail.tmall.com",
linkUrl: "https://yunzhuan.light120.com/platform/tmall/index.js",
inline: true,
},
];
return ctx.success(data);
},
"GET /config/v3": async (ctx, next) => {
const res = await plu_api_linkjs.findAll({ where: {} });
return ctx.success(res);
},
"GET /config/ga": async (ctx, next) => {
let ip = ctx.getIp();
let { title, brand, type, postion, parentSelector: parent_selector, className: class_name, icon, path, browser } = ctx.getQuery();
let res = await plu_ga.create({ title, type, brand, postion, parent_selector, class_name, icon, path, ip, browser });
return ctx.success(res);
},
"GET /config/funType": async (ctx, next) => {
const res = await plu_func_type.findAll({ where: { is_enable: 1 } });
let rows = res.map(p => {
return { key: p.id, value: p.value }
})
return ctx.success(rows);
},
"GET /config/funAll": async (ctx, next) => {
let rows = await plu_func.findAll({ where: { is_enable: 1 }, order: [["sort", "asc"]] });
return ctx.success(rows);
},
"GET /config/lastPlug": async (ctx, next) => {
const replaceUrl = (url) => {
url = url.replace('https:', '')
url = url.replace('http:', '')
return url
}
let defaultRow = {
plugVersion: '2.7.5',
plugUpdateDate: '2023-06-09',
officialUrl: "//shopant.baozun.com/plug/#/",
downUrl: '//bztic-shopant-files.oss-cn-shanghai.aliyuncs.com/front/plug/business-staff-extension_2.7.5.zip',
helpUrl: '//bztic-shopant-files.oss-cn-shanghai.aliyuncs.com/front/plug/helpDoc.pdf'
}
let row = await plu_version.findOne({ where: { is_enable: 1 }, order: [["id", "desc"]] })
if (row) {
let { plugVersion, plugUpdateDate, downUrl, helpUrl } = row
plugUpdateDate = dayjs(plugUpdateDate).format('YYYY-MM-DD')
downUrl = replaceUrl(downUrl)
helpUrl = replaceUrl(helpUrl)
defaultRow = Object.assign({}, defaultRow, { plugVersion, plugUpdateDate, downUrl, helpUrl })
}
return ctx.success(defaultRow);
},
};

View File

@@ -0,0 +1,159 @@
const fs = require("fs");
const path = require("path");
const { sys_model, sys_project, 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 = {
"POST /model/all": async (ctx, next) => {
let { projectKey } = ctx.getBody();
let projectRow = await sys_project.findOne({ where: { key: projectKey } });
if (projectRow) {
let project_id = projectRow.id;
let resList = await sys_model.findAll({ where: { project_id } });
let resPromise = resList.map(async (row) => {
let newRow = row.toJSON();
let isExistTableName = await querySql(`select TABLE_NAME from information_schema.TABLES where TABLE_NAME ="${newRow.key}"`);
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 querySql(`show columns from ${modelRow.key}`);
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 = newFielRow.toJSON();
if (dbColKeys.indexOf(newFielRow.key) === -1) {
isDbFielExist = false;
}
});
newRow.isDbFielExist = isDbFielExist;
return newRow;
});
let newResList = await Promise.all(resPromise);
return ctx.success(newResList);
} else {
return ctx.fail("未找到项目key");
}
},
"POST /model/detailPath": async (ctx, next) => {
let { id } = ctx.getBody();
let modelRow = await sys_model.findOne({ where: { id } });
if (modelRow) {
let { key, project_id } = modelRow;
let projectRow = await sys_project.findOne({ where: { id: project_id } });
if (projectRow) {
let controllerPath = path.normalize(`/${projectRow.key}/api/controller_admin/${key}.js`);
let modelPath = path.normalize(`/${projectRow.key}/api/model/${key}.js`);
return ctx.success({ controllerPath, modelPath });
}
}
return ctx.success({ controllerPath: "", modelPath: "" });
},
"POST /form/updateForm": async (ctx, next) => {
let { id, name, model_id, api_path, component } = ctx.getBody();
let formRow = await sys_form.findOne({ where: { id: id } });
if (formRow) {
let res = await sys_form.update({ name: `${name}_表单`, model_id, api_path, component }, { where: { id } });
return ctx.success(res);
} else {
return ctx.fail("未找到指定项目");
}
},
"POST /form/createForm": async (ctx, next) => {
let { name, project_key, model_id, api_path, component } = ctx.getBody();
let projectRow = await sys_project.findOne({ where: { key: project_key } });
if (projectRow) {
let project_id = projectRow.id;
let res = await sys_form.create({ name: `${name}_表单`, project_id, model_id, api_path, component });
return ctx.success(res);
} else {
return ctx.fail("未找到指定项目");
}
},
"POST /form/generate": async (ctx, next) => {
let form_id = ctx.get("id");
if (form_id) {
const sysFormRow = await sys_form.findOne({ where: { id: form_id } });
if (sysFormRow) {
await autoFile.createForm(sysFormRow);
let frontApiUrl = await autoFile.autoFrontApi(sysFormRow);
let frontVueUrl = await autoFile.autoFrontVue(sysFormRow);
frontApiUrl = path.normalize(frontApiUrl);
frontVueUrl = path.normalize(frontVueUrl);
return ctx.success({ frontApiUrl, frontVueUrl });
}
}
return ctx.fail("生成失败");
},
// 生成model
"POST /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);
// 创建apiServer
await autoFile.autoController(id);
let modelRow = await sys_model.findOne({ where: { id } });
if (modelRow) {
let { key, project_id } = modelRow;
let projectRow = await sys_project.findOne({ where: { id: project_id } });
if (projectRow) {
let controllerPath = path.normalize(`/${projectRow.key}/api/controller_admin/${key}.js`);
let modelPath = path.normalize(`/${projectRow.key}/api/model/${key}.js`);
return ctx.success({ controllerPath, modelPath });
}
else {
return ctx.fail("未找到项目");
}
}
else {
return ctx.fail("未找到模型文件");
}
} else {
return ctx.fail("字段未添加,无效生成");
}
}
return ctx.fail("参数错误 id");
},
};

View File

@@ -0,0 +1,14 @@
const dayjs = require("dayjs");
const fs = require("fs");
const path = require("path");
const autoFile = require("../service/autoFile");
const { querySql, sys_project, op } = require("../../middleware/baseModel");
module.exports = {
"POST /project/down": async (ctx, next) => {
let { model_id } = ctx.getBody();
},
"POST /project/build": async (ctx, next) => {
let { model_id } = ctx.getBody();
},
};

View File

@@ -0,0 +1,15 @@
const dayjs = require("dayjs");
const { querySql, sof_sofawa_ga, op } = require("../../middleware/baseModel");
module.exports = {
"POST /sofaware/last": async (ctx, next) => {
let row = { version: "1.5.0", officialUrl: "https://shopant.baozun.com/plug/#/", updateDate: "2024-05-10", downUrl: "https://bztic-shopant-files.oss-cn-shanghai.aliyuncs.com/prod/split_video/split_video_latest.zip" }
return ctx.success(row)
},
"POST /sofaware/ga": async (ctx, next) => {
let row = ctx.getBody();
const res = await sof_sofawa_ga.create(row);
return ctx.success(res);
},
};

View File

@@ -0,0 +1,49 @@
var UUID = require("uuid");
var fs = require("fs");
var path = require("path");
const ossTool = require("../service/ossTool");
const funTool = require("../../tool/funTool");
module.exports = {
"POST /sys_file/upload_img": async (ctx, next) => {
const files = ctx.request.files; // 获取上传文件
let fileArray = [];
let rootPath = path.join(__dirname, "../../upload/imgs");
for (var key in files) {
fileArray.push(files[key]);
}
//创建文件夹
await funTool.mkdirsSync(rootPath);
let resArray = [];
fileArray.forEach((file) => {
// 创建可读流
const reader = fs.createReadStream(file.path);
let filePath = `/${UUID.v1() + "_" + file.name}`;
// 创建可写流
const upStream = fs.createWriteStream(path.join(rootPath, filePath));
// 可读流通过管道写入可写流
reader.pipe(upStream);
resArray.push({ name: file.name, path: path.join("/imgs", filePath) });
});
ctx.success(resArray);
},
"POST /sys_file/upload_oos_img": async (ctx, next) => {
let fileArray = [];
const files = ctx.request.files; // 获取上传文件
for (var key in files) {
fileArray.push(files[key]);
}
let data = await ossTool.putImg(fileArray[0]);
if (data.path) {
return ctx.success(data);
} else {
return ctx.fail();
}
},
};

View File

@@ -0,0 +1,24 @@
const { plu_upgrade, op } = require("../../middleware/baseModel");
module.exports = {
"POST /upgrade/add": async (ctx, next) => {
let row = ctx.getBody();
let { fingerPrintKey, newVersion, oldVersion } = row;
let upgradeRow = await plu_upgrade.findOne({ where: { fingerPrintKey, newVersion } });
if (upgradeRow) {
await plu_upgrade.update({ fingerPrintKey, newVersion, oldVersion, whetherTip: true }, { where: { id: upgradeRow.id }, individualHooks: true });
return ctx.success();
} else {
const res = await plu_upgrade.create(row);
return ctx.success(res);
}
},
"GET /upgrade/detail": async (ctx, next) => {
let fingerPrintKey = ctx.get("fingerPrintKey");
let newVersion = ctx.get("newVersion");
const res = await plu_upgrade.findOne({ where: { fingerPrintKey, newVersion } });
return ctx.success(res);
},
};

View File

@@ -0,0 +1,78 @@
const { plu_upgrade, op } = require("../../middleware/baseModel");
const { encoder } = require("../service/ffmpeg/encoder");
const fs = require('fs');
const stream = require("stream");
const path = require("path");
const getStreamContentTobase64Stream = async (file) => {
let p = new Promise((resolve, reject) => {
const readStream = fs.createReadStream(file.path)
const readStream2 = new stream.Readable();
let str = ''
readStream.on('data', data => {
str += data.toString()
})
readStream.on('end', () => {
let base64Array = str.split('data:image/png;base64,')
console.log('count', base64Array.length)
for (let i = 0; i < base64Array.length; i++) {
let base64 = base64Array[i].replace(/^data:\w+\/\w+;base64,/, '')
const buffer = Buffer.from(base64, "base64");
readStream2.push(buffer);
}
readStream2.push(null)
resolve(readStream2)
})
readStream.on('error', err => {
reject(err)
console.log(err)
})
})
return p
}
module.exports = {
"POST /video_effects/build": async (ctx, next) => {
const files = ctx.request.files; // 获取上传文件
let file = files.file
let frameStream = await getStreamContentTobase64Stream(file)
const output = await encoder({
silent: false,
frameStream: frameStream,
backgroundVideo: {
videoPath: path.join(__dirname, "../../config/media/demo_out.mp4"),
inSeconds: 1,
outSeconds: 30,
},
output: "output/test.mp4",
fps: {
input: 30,
output: 30,
},
});
console.log("process done,", output.path);
return ctx.success({ path: output.path });
},
};

41
api/model/sof_sofawa.js Normal file
View File

@@ -0,0 +1,41 @@
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
module.exports = sof_sofawa = db.define("sof_sofawa", {
sofaKey: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "软件key",
},
title: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "软件名称",
},
version: {
type: Sequelize.STRING(50),
allowNull: false,
defaultValue: "",
comment: "软件版本",
},
down_url: {
type: Sequelize.STRING(500),
allowNull: false,
defaultValue: "",
comment: "软件版本",
},
file_size: {
type: Sequelize.STRING(500),
allowNull: false,
defaultValue: "",
comment: "软件大小",
}
})
// sof_sofawa.sync({ force: true });

View File

@@ -0,0 +1,64 @@
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
module.exports = sof_sofawa_ga = db.define("sof_sofawa_ga", {
sofaKey: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "软件key",
},
version: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "版本号",
},
serialNumber: {
type: Sequelize.STRING(200),
allowNull: false,
defaultValue: "",
comment: "硬盘序列号",
},
ip: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "ip",
},
position: {
type: Sequelize.STRING(200),
allowNull: false,
defaultValue: "",
comment: "功能位置",
},
type: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "类型",
},
msg: {
type: Sequelize.JSON,
allowNull: false,
defaultValue: "{}",
comment: "详细信息",
set(value) {
this.setDataValue('msg', { value });
},
get() {
let jsonValue = this.getDataValue("msg")
if (jsonValue && jsonValue.value !== undefined) {
return jsonValue.value;
}
else {
return jsonValue
}
}
},
});
//sof_sofawa_ga.sync({ force: true });

View File

@@ -0,0 +1,24 @@
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
module.exports = sys_control_type = db.define("sys_control_type", {
name: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "控件名称",
},
module_key: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "组件key",
},
data_lenght: {
type: Sequelize.INTEGER(11),
allowNull: false,
defaultValue: "50",
comment: "数据长度",
},
});
// sys_control_type.sync({ force: true });

42
api/model/sys_form.js Normal file
View File

@@ -0,0 +1,42 @@
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
// 表单表
module.exports = sys_form = db.define("sys_form", {
// 表单名称
name: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "表单名称",
},
// 模型id
model_id: {
type: Sequelize.INTEGER(11).UNSIGNED,
allowNull: true,
defaultValue: 0,
comment: "模型id",
},
// 项目id
project_id: {
type: Sequelize.INTEGER(11).UNSIGNED,
allowNull: true,
defaultValue: 0,
comment: "项目id",
},
// 组件地址
component: {
type: Sequelize.STRING(100),
allowNull: true,
defaultValue: 0,
comment: "组件地址",
},
//api地址
api_path: {
type: Sequelize.STRING(100),
allowNull: true,
defaultValue: 0,
comment: "api地址",
},
});
// sys_form.sync({ force: true });

View File

@@ -0,0 +1,78 @@
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
module.exports = sys_form_field = db.define("sys_form_field", {
form_id: {
type: Sequelize.INTEGER(11).UNSIGNED,
allowNull: false,
defaultValue: "0",
comment: "表单id",
},
model_field_id: {
type: Sequelize.INTEGER(11).UNSIGNED,
allowNull: false,
defaultValue: "0",
comment: "字段id",
},
model_field_name: {
type: Sequelize.STRING(50),
allowNull: false,
defaultValue: "",
comment: "字段名称",
},
control: {
type: Sequelize.JSON,
allowNull: false,
defaultValue: "{}",
comment: "控件",
set(value) {
this.setDataValue('control', { value });
},
get() {
let jsonValue = this.getDataValue("control")
if (jsonValue && jsonValue.value !== undefined) {
return jsonValue.value;
}
else {
return jsonValue
}
}
},
is_show_edit: {
type: Sequelize.INTEGER(1),
allowNull: false,
defaultValue: 0,
comment: "是否显示在编辑界面",
},
is_edit_disable: {
type: Sequelize.INTEGER(1),
allowNull: false,
defaultValue: 0,
comment: "编辑界面是否禁用",
},
is_show_list: {
type: Sequelize.INTEGER(1),
allowNull: false,
defaultValue: 0,
comment: "是否显示在列表",
},
is_show_seach: {
type: Sequelize.INTEGER(1),
allowNull: false,
defaultValue: 0,
comment: "是否显示在搜索",
},
sort: {
type: Sequelize.INTEGER(11).UNSIGNED,
allowNull: false,
defaultValue: "0",
comment: "排序",
},
});
// sys_form_field.sync({ force: true });

35
api/model/sys_log.js Normal file
View File

@@ -0,0 +1,35 @@
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
// db日志管理
module.exports = sys_log = db.define("sys_log", {
table_name: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "表名",
},
operate: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "操作",
},
content: {
type: Sequelize.JSON,
allowNull: false,
defaultValue: "",
comment: "内容",
set(value) {
this.setDataValue("content", { value });
},
get() {
let jsonValue = this.getDataValue("content");
if (jsonValue && jsonValue.value !== undefined) {
return jsonValue.value;
} else {
return jsonValue;
}
},
},
});
// sys_log.sync({ force: true });

87
api/model/sys_menu.js Normal file
View File

@@ -0,0 +1,87 @@
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
// 菜单表
module.exports = sys_menu = db.define("sys_menu", {
// 菜单名称
name: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "菜单名称",
},
// 父id
parent_id: {
type: Sequelize.INTEGER(11).UNSIGNED,
allowNull: true,
defaultValue: 0,
comment: "父id",
},
// 图标
icon: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "图标",
},
path: {
type: Sequelize.STRING(255),
allowNull: false,
defaultValue: "",
comment: "路径",
},
// 菜单类型 "菜单", "页面", "外链", "功能"
type: {
type: Sequelize.STRING(255),
allowNull: false,
defaultValue: "页面",
comment: "菜单类型",
},
//模型id
model_id: {
type: Sequelize.INTEGER(11).UNSIGNED,
allowNull: true,
defaultValue: 0,
comment: "模型id",
},
// 组件地址
component: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "组件地址",
},
// api地址
api_path: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "api地址",
},
// 是否显示在菜单中
is_show_menu: {
type: Sequelize.INTEGER(1),
allowNull: false,
defaultValue: true,
comment: "是否显示在菜单中",
},
is_show: {
type: Sequelize.INTEGER(1),
allowNull: false,
defaultValue: true,
comment: "是否展示",
},
// 菜单类型
sort: {
type: Sequelize.INTEGER(11),
allowNull: false,
defaultValue: "0",
comment: "菜单类型",
},
});
// sys_menu.sync({ force: true })

26
api/model/sys_model.js Normal file
View File

@@ -0,0 +1,26 @@
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
module.exports = sys_model = db.define("sys_model", {
key: {
type: Sequelize.STRING(50),
allowNull: false,
defaultValue: "",
comment: "模型key",
},
name: {
type: Sequelize.STRING(50),
allowNull: false,
defaultValue: 0,
comment: "模型名称",
},
// 项目id
project_id: {
type: Sequelize.INTEGER(11).UNSIGNED,
allowNull: true,
defaultValue: 0,
comment: "项目id",
},
});
// sys_model.sync({ force: true });

View File

@@ -0,0 +1,82 @@
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
module.exports = sys_model_field = db.define("sys_model_field", {
model_id: {
type: Sequelize.INTEGER(11).UNSIGNED,
allowNull: false,
defaultValue: "0",
comment: "模型Id",
},
key: {
type: Sequelize.STRING(50),
allowNull: false,
defaultValue: "",
comment: "字段Key",
},
name: {
type: Sequelize.STRING(50),
allowNull: false,
defaultValue: 0,
comment: "名称",
},
// 控件
control: {
type: Sequelize.JSON,
allowNull: false,
defaultValue: "{}",
comment: "控件",
set(value) {
this.setDataValue("control", { value });
},
get() {
let jsonValue = this.getDataValue("control");
if (jsonValue && jsonValue.value !== undefined) {
return jsonValue.value;
} else {
return jsonValue;
}
},
},
// 排序
sort: {
type: Sequelize.INTEGER(11),
allowNull: false,
defaultValue: 1,
comment: "排序",
},
// 类型
data_type: {
type: Sequelize.STRING(50),
allowNull: false,
defaultValue: "0",
comment: "数据类型",
},
//数据长度
data_length: {
type: Sequelize.INTEGER(11),
allowNull: false,
defaultValue: 50,
comment: "数据长度",
},
//是否为空 0 为空 1 不允许为空
allow_null: {
type: Sequelize.INTEGER(1),
allowNull: false,
defaultValue: 0,
comment: "是否为空",
},
// 默认值
default_value: {
type: Sequelize.STRING(50),
allowNull: false,
defaultValue: "",
comment: "默认值",
},
});
// sys_model_field.sync({ force: true });

View File

@@ -0,0 +1,35 @@
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
// 字典表
module.exports = sys_parameter = db.define("sys_parameter", {
key: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "字典key",
},
value: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "值",
},
remark: {
type: Sequelize.STRING(500),
allowNull: false,
defaultValue: "",
comment: "备注",
},
// 是否允许修改 0 允许1 不允许
is_modified: {
type: Sequelize.INTEGER(2),
allowNull: false,
defaultValue: 0,
comment: "是否允许修改",
},
});
// sys_parameter.sync({ force: true })

33
api/model/sys_project.js Normal file
View File

@@ -0,0 +1,33 @@
const dayjs = require("dayjs");
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
module.exports = sys_project = db.define("sys_project", {
name: {
comment: "项目名称",
type: Sequelize.STRING(50),
allowNull: false,
defaultValue: "",
},
key: {
comment: "项目key",
type: Sequelize.STRING(50),
allowNull: false,
defaultValue: "",
},
project_type_id: {
comment: "项目类型",
type: Sequelize.INTEGER(11),
allowNull: false,
defaultValue: "0",
},
remark: {
comment: "备注",
type: Sequelize.STRING(500),
allowNull: 1,
defaultValue: "",
},
});
// sys_project.sync({ force: true });

View File

@@ -0,0 +1,141 @@
const dayjs = require("dayjs");
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
module.exports = sys_project_config = db.define("sys_project_config", {
project_id: {
comment: "项目id",
type: Sequelize.INTEGER(11),
allowNull: false,
defaultValue: "0",
},
config_env_type: {
comment: "环境类型",
type: Sequelize.INTEGER(2),
allowNull: false,
defaultValue: "0",
},
db: {
comment: "db配置",
type: Sequelize.JSON,
allowNull: false,
set(value) {
this.setDataValue("db", { value });
},
get() {
let jsonValue = this.getDataValue("db");
if (jsonValue && jsonValue.value !== undefined) {
return jsonValue.value;
} else {
return jsonValue;
}
},
defaultValue: {
username: "",
password: "",
database: "",
host: "",
port: 3306,
dialect: "mysql",
},
},
aliyun: {
comment: "阿里云配置",
type: Sequelize.JSON,
allowNull: false,
set(value) {
this.setDataValue("aliyun", { value });
},
get() {
let jsonValue = this.getDataValue("aliyun");
if (jsonValue && jsonValue.value !== undefined) {
return jsonValue.value;
} else {
return jsonValue;
}
},
defaultValue: {
accessKeyId: "",
accessKeySecret: "",
ossUrl: "",
},
},
redis: {
comment: "redis配置",
type: Sequelize.JSON,
allowNull: false,
set(value) {
this.setDataValue("redis", { value });
},
get() {
let jsonValue = this.getDataValue("redis");
if (jsonValue && jsonValue.value !== undefined) {
return jsonValue.value;
} else {
return jsonValue;
}
},
defaultValue: {
host: "",
port: "",
pwd: "",
opt: {},
},
},
file: {
comment: "文件配置",
type: Sequelize.JSON,
allowNull: false,
set(value) {
this.setDataValue("file", { value });
},
get() {
let jsonValue = this.getDataValue("file");
if (jsonValue && jsonValue.value !== undefined) {
return jsonValue.value;
} else {
return jsonValue;
}
},
defaultValue: {
vue: {
api: "../../admin/src/api/",
view: "../../admin/src/view/",
},
node: {
controller: "../controller_admin/",
model: "../model/",
},
},
},
wechat: {
comment: "微信配置",
type: Sequelize.JSON,
allowNull: false,
set(value) {
this.setDataValue("wechat", { value });
},
get() {
let jsonValue = this.getDataValue("wechat");
if (jsonValue && jsonValue.value !== undefined) {
return jsonValue.value;
} else {
return jsonValue;
}
},
defaultValue: {
appid: "",
secret: "",
mch_id: "",
partner_key: "",
partnerV3_key: "",
notify_url: "",
refund_notify_url: "",
},
},
});
// sys_project_config.sync({ force: true });

View File

@@ -0,0 +1,19 @@
const dayjs = require("dayjs");
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
module.exports = sys_project_type = db.define("sys_project_type", {
name: {
comment: "类型名称",
type: Sequelize.STRING(50),
allowNull: false,
defaultValue: "",
},
remark: {
comment: "备注",
type: Sequelize.STRING(500),
allowNull: false,
defaultValue: "",
},
});
// sys_project_type.sync({ force: true });

39
api/model/sys_role.js Normal file
View File

@@ -0,0 +1,39 @@
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
//角色表
module.exports = sys_role = db.define("sys_role", {
name: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "角色名称",
},
// 0 普通角色 1 系统角色
type: {
type: Sequelize.INTEGER(1),
allowNull: false,
defaultValue: "0",
comment: "角色类型",
},
menus: {
type: Sequelize.JSON,
allowNull: false,
defaultValue: "",
comment: "权限菜单",
set(value) {
this.setDataValue('menus', { value });
},
get() {
let jsonValue = this.getDataValue("menus")
if (jsonValue && jsonValue.value !== undefined) {
return jsonValue.value;
}
else {
return jsonValue
}
}
},
});
// sys_role.sync({ force: true })

24
api/model/sys_user.js Normal file
View File

@@ -0,0 +1,24 @@
const db = require("../../middleware/db");
const Sequelize = require("sequelize");
// 系统用户表
module.exports = sys_user = db.define("sys_user", {
name: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "名称",
},
password: {
type: Sequelize.STRING(100),
allowNull: false,
defaultValue: "",
comment: "密码",
},
roleId: {
type: Sequelize.INTEGER,
allowNull: false,
comment: "角色id",
},
});
// sys_user.sync({ force: true });

426
api/service/autoFile.js Normal file
View File

@@ -0,0 +1,426 @@
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({});
}
}
},
};

View File

@@ -0,0 +1,113 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ffmpeg = require("fluent-ffmpeg");
var fs = require("fs");
var path = require("path");
var cliProgress = require("cli-progress");
var stream_1 = require("stream");
var progressBar = new cliProgress.SingleBar({
format: "Processing | {bar} | {percentage}%",
barCompleteChar: "\u2588",
barIncompleteChar: "\u2591",
hideCursor: true,
});
var typeCheck = function (reject, config) {
var frameStream = config.frameStream, output = config.output, backgroundVideo = config.backgroundVideo, fps = config.fps;
if (!(frameStream instanceof stream_1.Readable)) {
reject(new Error("frameStream should be in type Readable. You provided " + typeof frameStream));
}
if (!(typeof output === "string")) {
reject(new Error("output should be a string. You provided " + typeof output));
}
if (!(fps && fps.input && fps.output)) {
reject(new Error("fps should be an object with input and output properties"));
}
if (backgroundVideo) {
var inSeconds = backgroundVideo.inSeconds, videoPath = backgroundVideo.videoPath, outSeconds = backgroundVideo.outSeconds;
if (typeof inSeconds !== "number" ||
typeof outSeconds !== "number" ||
typeof videoPath !== "string") {
reject(new Error("backgroundVideo property is not correctly set"));
}
}
};
var createDir = function (reject, silent, output) {
try {
var outDir = path.dirname(output);
if (!fs.existsSync(outDir)) {
fs.mkdirSync(outDir, { recursive: true });
}
}
catch (e) {
if (!silent)
console.log("Could not create/access output directory");
reject(new Error("Cannot create/access output directory"));
}
};
var createFilter = function (backgroundVideo) {
var inSeconds = backgroundVideo.inSeconds, outSeconds = backgroundVideo.outSeconds;
return [
"[1:v]setpts=PTS+" + inSeconds + "/TB[out]",
{
filter: "overlay",
options: {
enable: "between(t," + inSeconds + "," + outSeconds + ")",
x: "0",
y: "0",
},
inputs: "[0:v][out]",
outputs: "tmp",
},
];
};
var percent = function (percent) {
return percent ? parseFloat(percent.toFixed(2)) : 0;
};
var outputOptions = [
"-preset veryfast",
"-crf 24",
"-f mp4",
"-vcodec libx264",
"-movflags frag_keyframe+empty_moov",
"-pix_fmt yuv420p",
];
var encoder = function (config) {
return new Promise(function (resolve, reject) {
var frameStream = config.frameStream, output = config.output, backgroundVideo = config.backgroundVideo, fps = config.fps, _a = config.silent, silent = _a === void 0 ? true : _a;
typeCheck(reject, config);
createDir(reject, silent, output);
var outputStream = fs.createWriteStream(output);
var command = ffmpeg();
if (backgroundVideo)
command.input(backgroundVideo.videoPath);
command.input(frameStream).inputFPS(fps.input);
command.outputOptions(outputOptions);
command.fps(fps.output);
if (backgroundVideo)
command.complexFilter(createFilter(backgroundVideo), "tmp");
command.output(outputStream);
command.on("start", function (commandLine) {
console.log("ffmpeg started with command: ", commandLine);
if (!silent)
progressBar.start(100, 0);
});
command.on("end", function (str) {
if (!silent)
progressBar.stop();
if (!silent)
console.log("Processing complete...," + str);
resolve({ path: output, stream: outputStream });
});
command.on("progress", function (progress) {
if (!silent)
progressBar.update(percent(progress.percent));
});
command.on("error", function (err) {
if (!silent)
console.log("An error occured while processing,", err.message);
reject(new Error(err.message));
});
command.run();
});
};
module.exports = { encoder };

61
api/service/http.js Normal file
View File

@@ -0,0 +1,61 @@
const logsUtil = require("../../tool/logs");
const axios = require("axios");
const request = require("request");
const instanceRequest = (options) => {
let promise = new Promise(function (resolve, reject) {
request.post(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
resolve(body);
}
reject(error);
});
});
return promise;
};
module.exports = {
async postFormData(url, param) {
const options = {
method: "POST",
url: url,
headers: { "Content-Type": "multipart/form-data" },
formData: param,
json: true,
};
return await instanceRequest(options);
},
async post(url, param) {
const options = {
method: "POST",
url: url,
body: param,
json: true,
encoding: null,
};
return await instanceRequest(options);
},
async get(url, param) {
const options = {
method: "GET",
url: url,
qs: param,
json: true,
encoding: null,
};
let promise = new Promise(function (resolve, reject) {
request.get(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
resolve(body);
}
reject(error);
});
});
return promise;
},
};

47
api/service/ossTool.js Normal file
View File

@@ -0,0 +1,47 @@
let OSS = require('ali-oss')
var fs = require('fs')
const config = require('../../config/config')['aliyun']
const uuid = require('node-uuid')
let client = new OSS({
region: 'oss-cn-shanghai',
accessKeyId: config.accessKeyId,
accessKeySecret: config.accessKeySecret,
bucket: 'bztic-shopant-files'
})
module.exports = {
async putImg(file) {
const stream = fs.createReadStream(file.path)
let uid = uuid.v4()
let lastIndex = file.name.lastIndexOf('.')
let suffix = file.name.substring(lastIndex, file.name.length)
let result = await client.put('/front/plug/images/' + uid + suffix, stream, { headers: { 'content-disposition': 'inline', "content-type": file.type } })
if (result.res.status === 200) {
let ossPath = config.ossUrl + '/' + result.name
return { name: result.name, path: result.url, ossPath }
} else {
return {}
}
},
async putImgStream(stream, suffix = 'png') {
let uid = uuid.v4()
let result = await client.put('front/plug/images/' + uid + '.' + suffix, stream, { headers: { 'content-disposition': 'inline', "content-type": `image/${suffix}` } })
if (result.res.status === 200) {
let ossPath = config.ossUrl + result.name
return { name: result.name, path: result.url, ossPath }
} else {
return {}
}
},
}

50
api/service/redis.js Normal file
View File

@@ -0,0 +1,50 @@
const redis = require("redis");
const config = require("../../config/config");
let rclient = null;
module.exports = {
getConfig() {
let { port, host, opt } = config.redis || {}
return { port, host, opt }
},
init() {
let { port, host, opt } = this.getConfig()
if (host && port) {
rclient = redis.createClient(port, host, opt);
rclient.auth(config.pwd, function () {
console.log("redis通过认证");
});
rclient.on("connect", function () {
console.log("redis连接成功");
});
}
},
// 设置key值
set(key, value, expire = 0) {
if (!rclient) {
this.init();
}
rclient.set(key, value); //赋值
if (expire) {
rclient.expire(key, expire); //60秒自动过期
}
},
get(key) {
if (!rclient) {
this.init();
}
return new Promise((resolve, reject) => {
rclient.get(key, function (err, data) {
resolve(data);
});
});
},
};

27
api/service/token.js Normal file
View File

@@ -0,0 +1,27 @@
const jwt = require('jsonwebtoken');
const secret = 'SLDLKKDS323ssdd@#@@gf';
module.exports = {
create (userInfo) {
const token = jwt.sign(userInfo, secret);
return token;
},
parse (token) {
if (token) {
try {
return jwt.verify(token, secret);
} catch (err) {
return null;
}
}
return null;
},
verify (token) {
const result = this.parse(token);
if (!result) {
return false;
}
return true;
}
};