好多年没碰过前端jquery了,用一两天时间重温一下,刚好写个小工具, 不递归取文件夹和文件,只写一层,保持足够简单,验证和参数判断暂不写,毕竟只写了几个小时而已,功能算完备了,添加一个简单的管理员权限管理修改的所有功能即可放出去了,看来还不错
1. 后台


var fs = require('fs') var path = require('path') var basePath = 'docs' let markdown = require('markdown-it') var md = new markdown({ html: true, langPrefix: 'code-', }) function mkCate(cate) { fs.mkdir(path.join(basePath, cate), function (err) { }) } function getDirsInDocsFolder() { var paths = fs.readdirSync(basePath) return paths } function getMdsInFolder(folderName) { let paths = fs.readdirSync(path.join(basePath, folderName)) return paths } function writeMdFile(folderPath, fileName, content) { fs.writeFile(path.join(basePath, folderPath, fileName), content, function (err) { console.error(err) }) } function readMd(fileName, folderPath) { let content = fs.readFileSync(path.join(basePath, folderPath, fileName), 'utf-8') return content } function readMdFileToHtml(fileName, folderPath) { var content = readMd(fileName, folderPath) var html = md.render(content) return html } function main() { console.log('Starting web server') var express = require('express') var app = express() app.use(express.static('.')) const bodyParser = require('body-parser'); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.get('/', function (req, res, next) { }) app.get('/cates', function (req, res, next) { var list = getDirsInDocsFolder() res.send(list) }) app.post('/cate', function (req, res, next) { const { cate } = req.body mkCate(cate) }) app.get('/mds', function (req, res, next) { const { cate } = req.query if (!cate) res.send([]) var mds = getMdsInFolder(cate) res.send(mds) }) app.get('/mdhtml', function (req, res, next) { const { cate, name } = req.query var html = readMdFileToHtml(`${name}`, cate) res.send(html) }) app.get('/md', function (req, res, next) { const { cate, name } = req.query var md = readMd(`${name}`, cate) res.send(md) }) app.post('/md', function (req, res, next) { const { cate, name, content } = req.body writeMdFile(cate, name, content) res.send(content) }) var server = app.listen(8081, function () { const { address, port } = server.address() console.log('Listening on http://%s:%s', address, port) }) } main();
2. 前台


DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Documenttitle>
<link rel="stylesheet" href="index.css">
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js">script>
head>
<body>
<h1>Caloch开洛奇h1>
<nav>
<button onclick="add('c',prompt('Category:'));">+button>
<ul id="cates">
<li><a href="#" data-cate="cate">catea>li>
ul>
nav>
<hr>
<div class="menu">
<button onclick="add('a',prompt('Name:'));">+button>
<ul id="mds">
<li><a href="view.html?name='a1'" target="mainframe">文章.1a>li>
ul>
div>
<div id="main" class="main">
<iframe id="#mainframe" name="mainframe" src="" frameborder="0">iframe>
div>
<div id="main1" class="main">
<textarea id="content" cols="20" rows="10">textarea>
<button id="save">Savebutton>
div>
<footer>
©Caloch开洛奇 2019~
<span id="today">span>
footer>
<script>
var current = {}
function add(key, val) {
var iframe = document.getElementById('#mainframe')
switch (key) {
case 'c':
if (val) {
mkCate(val)
getCates()
}
break;
case 'a':
iframe.src = "view.html?name=" + val;
break;
default:
break;
}
}
function getCates() {
$.get('/cates', function (data) {
let $el = $('#cates')
$el.empty()
data.forEach(cate => {
$el.append(`<li><a href="#" data-cate="${cate}">${cate}</a></li>`);
});
current.cate = data[0]
getMds(data[0])
})
}
function mkCate(cate) {
if (!cate) return
$.post('/cate', { cate }, function (data) {
})
}
function getMds(cate) {
$.get('/mds?cate=' + cate, function (data) {
let $el = $('#mds')
$el.empty()
data.forEach(function (md) {
$el.append(`<li><a href="javascript:void(0)" data-name=${md} >${md}</a>Edit</span></li>`)
})
})
}
function getMdHtml(cate, name) {
$.get('/mdhtml?cate=' + cate + '&name=' + name, function (data) {
let $el = $('#main')
$el.html(data)
})
}
function getMd(cate, name, callback) {
$.get('/md?cate=' + cate + '&name=' + name, function (data) {
let $el = $('#content')
$el.text(data)
})
}
function save(cate, name, content) {
if (!name) return
$.post('/md', { cate, name, content }, function (data) {
})
}
$.fn.timelyfy = function () {
let $this = $(this)
$this.html(new Date().toLocaleDateString())
}
function showContent() {
$('#main').show()
$('#main1').hide()
}
function showEditor() {
$('#main1').show()
$('#main').hide()
}
$(document).ready(function () {
$.ajaxSetup({
beforeSend: function (xhr, settings) {
console.log(xhr)
},
dataFilter: function (data) {
console.log(data)
return data
}
})
$('#today').timelyfy()
$('#main1').hide()
getCates()
$('#cates').on('click', 'a', function () {
let $this = $(this)
current.cate = $this.data().cate
getMds(current.cate)
})
$('#mds').on('click', 'a', function () {
let $this = $(this)
current.name = $this.data().name
console.log(current);
getMdHtml(current.cate, current.name)
showContent()
})
$('#mds').on('click', 'span', function () {
let $this = $(this)
getMd(current.cate, $this.data().name)
showEditor()
})
$('#save').on('click', function () {
save(current.cate, current.name, $('#content').val())
})
})
script>
body>
html>
3. scss样式


$common-height: 150px; @mixin with100minus($px) { width: calc(100% - #{$px}); } @mixin height100($px) { height: calc(100% - #{$px}); } * { box-sizing: border-box; } h1 { color: red; } ul li { list-style-type: none; } nav { width: 100%; display: flex; flex-direction: row; justify-content: flex-start; text-align: right; a { margin-left: 15px; display: block; } a:first-child { margin-left: 0; } } div { float: left; } .menu { width: 200px; height: $common-height; } .main { @include with100minus(200px); @include height100(200px); background-color: orange; } iframe { width: 100%; min-height: 500px; } footer { position: fixed; bottom: 0px; text-align: center; width: 100%; } button { border-radius: 5px; }
github repository:
https://github.com/CalosChen/mementowriter