好多年没碰过前端jquery了,用一两天时间重温一下,刚好写个小工具, 不递归取文件夹和文件,只写一层,保持足够简单,验证和参数判断暂不写,毕竟只写了几个小时而已,功能算完备了,添加一个简单的管理员权限管理修改的所有功能即可放出去了,看来还不错
1. 后台
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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. 前台
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!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>Document</title> <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">cate</a></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">文章.1</a></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">Save</button> </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><span data-name=${md}>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样式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
$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