Skip to content

Commit

Permalink
新增系统安装模块
Browse files Browse the repository at this point in the history
  • Loading branch information
yafoo committed Sep 5, 2022
1 parent 597e149 commit 3c129e8
Show file tree
Hide file tree
Showing 5 changed files with 264 additions and 3 deletions.
5 changes: 5 additions & 0 deletions config/install.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// 本文件用来标识系统已安装,不可删除。如需重新安装,请删除本文件并重启系统。
module.exports = {
install: true,
version: '3.0.0'
};
6 changes: 3 additions & 3 deletions config/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ routes = [
{url: '/article/:id.html', path: 'article/article', name: 'article'},
{url: '/search', path: 'search/search', name: 'search'},
{url: '/special/:id.html', path: 'special/special', name: 'special'},
{url: '/:cate((?!admin)\\S*)/', path: 'cate/cate', name: 'cate'}, // 会匹配到自定义后台地址,所以程序内需执行this.$next()
{url: '/:cate((?!admin)\\S*)/list_:page.html', path: 'cate/cate', name: 'cate_page'},
{url: '/:app/:controller?/:action?', path: 'admin/auth/index', type: 'middleware'} // 后台验证中间件
{url: '/:cate((?!admin|install)\\S*)/', path: 'cate/cate', name: 'cate'}, // 会匹配到自定义后台地址,所以程序内需执行this.$next()
{url: '/:cate((?!admin|install)\\S*)/list_:page.html', path: 'cate/cate', name: 'cate_page'},
{url: '/:app((?!install)\\S*)/:controller?/:action?', path: 'admin/auth/index', type: 'middleware'} // 后台验证中间件
];

module.exports = routes;
121 changes: 121 additions & 0 deletions install/controller/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
const {Controller} = require('jj.js');
const pjson = require('../../package.json');

class Index extends Controller
{
async _init() {
this.config = {
db: this.$config.db.default,
VERSION: pjson.version,
APP_TIME: this.ctx.APP_TIME
};

this.base_dir = this.$config.app.base_dir;
this.installFile = this.base_dir + '/config/install.js';
this.dbFile = this.base_dir + '/config/db.js';
this.sqlFile = this.base_dir + '/melog.sql';

if(await this._isInstalled()) {
this.$error('系统已安装!');
return false;
}

this.$assign('title', 'Melog系统安装');
this.$assign('description', 'melog,一个基于jj.js(nodejs)构建的简单轻量级blog系统。代码极简,无需编译,方便二次开发。');
this.$assign('keywords', 'melog');
this.$assign('config', this.config);
}

async _isInstalled() {
if(this.$config.install) {
return true;
}

if(await this.$.utils.fs.isFile(this.installFile)) {
return true;
}

return false;
}

async _writeInstallFile(config_db) {
const install_content = `// 本文件用来标识系统已安装,不可删除。如需重新安装,请删除本文件并重启系统。
module.exports = {
install: true,
version: '${this.config.VERSION}'
};`;
await this.$.utils.fs.writeFile(this.installFile, install_content);

const db_content = `module.exports = {
default: {
type : 'mysql', // 数据库类型
host : '${config_db.host}', // 服务器地址
database : '${config_db.database}', // 数据库名
user : '${config_db.user}', // 数据库用户名
password : '${config_db.password}', // 数据库密码
port : '${config_db.port}', // 数据库连接端口
charset : 'utf8', // 数据库编码默认采用utf8
prefix : 'melog_' // 数据库表前缀
}
};`;
await this.$.utils.fs.writeFile(this.dbFile, db_content);
}

async index() {
await this.$fetch();
}

async install() {
if(this.ctx.method != 'POST') {
return this.$error('非法请求!');
}

const form_data = this.ctx.request.body;
let db = null;
let error = '';

try {
const config_db = {...this.config.db, ...form_data};
delete config_db.database;
const database = form_data.database;

// 新建db实例
db = new this.$db(this.ctx, config_db);
// 创建数据库
await db.query(`create database if not exists \`${database}\` DEFAULT CHARACTER SET utf8mb4;`);
// 设置数据库并重新连接
config_db.database = database;
(await db.close()).connect(config_db);
// 获取sql文件
let sql_data = await this.$.utils.fs.readFile(this.sqlFile);
sql_data = sql_data.split(/;\r\n/);
// 使用事务执行sql语句
await db.startTrans(async () => {
for(let i=0; i<sql_data.length; i++) {
await db.query(sql_data[i]);
}
});

// 写入安装文件
await this._writeInstallFile(config_db);

// 修改默认db配置
this.$config.db.default.host = config_db.host;
this.$config.db.default.database = config_db.database;
this.$config.db.default.user = config_db.user;
this.$config.db.default.password = config_db.password;
this.$config.db.default.port = config_db.port;
// 重启默认数据库连接
(await this.$db.close()).connect();
} catch(e) {
this.$logger.debug(e);
error = e.message || '安装出错!';
}

db && db.close();

error ? this.$error(error) : this.$success('安装成功!');
}
}

module.exports = Index;
134 changes: 134 additions & 0 deletions install/view/index_index.htm
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>{{title}}</title>
<meta name="description" content="{{description}}"/>
<meta name="keywords" content="{{keywords}}"/>
<link rel="stylesheet" href="/static/melog.css">
<style>
.content {
width: 600px;
max-width: 100%;
margin: auto;
}
.form-item {
display: flex;
align-items: center;
height: 32px;
margin: 10px 0;
}
.form-item .label {
width: 80px;
}
.form-item .data {
flex: 1;
width: 200px;
max-width: 100%;
}
.form-item .input {
height: 32px;
}
.form-item .button {
margin: auto;
}
.form-tips {
margin: auto;
color: red;
margin-bottom: 10px;
display: none;
}
</style>
</head>
<body>
<header id="header">
<nav class="container navbar">
<div class="navbar-header">
<a class="logo" href="/">Melog</a>
<div class="navbar-menu"></div>
</div>
<ul class="navbar-item">
<li><a href="/install">系统安装</a></li>
<li><a href="https://me.i-i.me/special/melog.html">melog文档</a></li>
</ul>
</nav>
<div class="container jumbotron">
<h1>{{title}}</h1>
</div>
</header>

<div class="container row">
<main class="main">
<div class="content">
<h2>数据库设置</h2>
<form class="form" action="{{url('install')}}">
<div class="form-item">
<div class="label">数据库类型</div><div class="data">mysql</div>
</div>
<div class="form-item">
<div class="label">数据库主机</div><div class="data"><input class="input" type="text" name="host" value="{{config.db.host}}"></div>
</div>
<div class="form-item">
<div class="label">数据库用户</div><div class="data"><input class="input" type="text" name="user" value="{{config.db.user}}"></div>
</div>
<div class="form-item">
<div class="label">数据库密码</div><div class="data"><input class="input" type="text" name="password" value="{{config.db.password}}"></div>
</div>
<div class="form-item">
<div class="label">数据库名字</div><div class="data"><input class="input" type="text" name="database" value="{{config.db.database}}"></div>
</div>
<div class="form-item">
<div class="label">数据库端口</div><div class="data"><input class="input" type="text" name="port" value="{{config.db.port}}"></div>
</div>
<div class="form-item">
<div class="button">安装</div>
</div>
<div class="tips"></div>
</form>
</div>
</main>
</div>

<footer id="footer">
<div class="container">
<p class="beian">{{description}}</p>
</div>
<div class="copy-right">
<span>© 2020 <span>Powered by <a href="https://me.i-i.me/special/melog.html" target="_blank">Melog</a> · {{config.VERSION}} · {{new Date() - config.APP_TIME}}ms</span>
</div>
</footer>

<div id="go-top"></div>
<script src="https://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="/static/melog.js?v=0.1"></script>
<script>
$(function() {
$('.button').click(function() {
var button = $(this);
if(button.hasClass('hover')) {
return;
} else {
button.addClass('hover').text('安装中..');
$('.form-tips').hide();
}

var $form = $(".form");
var data = $form.serializeObject();

$.post($form.attr("action"), data, function(re) {
button.removeClass('hover').text('安装');
if(re.state) {
tips(re.msg, 2000, function() {
location.href = '/';
});
} else {
tips(re.msg);
$('.form-tips').show().text(re.msg);
}
});
});
})
</script>
</body>
</html>
1 change: 1 addition & 0 deletions public/static/melog.css
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ ul>li {list-style: none;}
.danger {
background-color: #f63;
}
.button.hover,
.button:hover {
opacity: .8;
}
Expand Down

0 comments on commit 3c129e8

Please sign in to comment.