背景
最近在做一个部门外部简略的知识库零碎,便于新人入职理解与一些常见问题的解答,知识库的模式是以文档为主,为了疾速实现文档性能,决定采纳markdown模式录入,生成本地文件后以html形式展示,档次清晰便于查看
表结构设计
文档信息表
DROP TABLE IF EXISTS `knowledge_documentinfo`;CREATE TABLE `knowledge_documentinfo` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `UnitGuid` varchar(50) DEFAULT NULL, `AddDate` datetime DEFAULT NULL, `DocName` varchar(50) DEFAULT NULL, `DocType` int(11) DEFAULT NULL, `DocRemark` varchar(500) DEFAULT NULL, `DocTag` varchar(100) DEFAULT NULL, `DocClass` int(11) DEFAULT NULL, `GroupGuid` varchar(50) DEFAULT NULL, `SortNum` int(11) DEFAULT NULL, KEY `ID` (`ID`)) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4;
文档内容表
DROP TABLE IF EXISTS `knowledge_documentcontentinfo`;CREATE TABLE `knowledge_documentcontentinfo` ( `ID` int(11) NOT NULL AUTO_INCREMENT, `UnitGuid` varchar(50) DEFAULT NULL, `DocGuid` varchar(50) DEFAULT NULL, `DocClass` int(11) DEFAULT NULL, `DocContent` longtext, KEY `ID` (`ID`)) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4;
前端集成
前端为了markdown编辑操作便捷,集成了toastui-edit编辑器,具备所见即所得模式,和typora一样的成果。因为咱们前端是本人开发,基于vue+html本地化形式开发,就简略封装了控件应用,同时须要援用zh-cn.js汉化,指定initialEditType模式为wysiwyg
template
<div v-if="!readonly" id="markdownedit"></div><div v-else id="markdownedit_viewer"> </div>
index.js
var mdeditortemplatepath = GetRootPath() + 'component/commonmdeditor/template.html';Vue.component('common-markdowneditor', function(resolve, reject) { $.get(mdeditortemplatepath).then(function(res) { resolve({ template: res, model: { prop: 'value', //要存在于props event: 'change' //当组件的值产生扭转时要emit的事件名 }, props: { value: {}, height: { default: '300px' }, readonly: { default: false } }, data() { return { editorID: getNewGuid(), editorImageStoreGroupType: "edtior", editContent: this.value, editorOption: {}, editorEntity: null, editorViewEntity: null } }, watch: { //组件输出同步到页面绑定的变量 editContent: function(newVal, oldVal) { this.$emit('change', newVal) }, //页面变量同步到组件显示 value: function(newVal, oldVal) { //从页面向组件更新时 if (this.editContent != newVal) { this.editContent = newVal; if (this.editorEntity != null) { this.editorEntity.setMarkdown(newVal, false) } if (this.editorViewEntity != null) { this.editorViewEntity.setMarkdown(newVal, false) } } }, }, created() { var page = this; }, mounted() { var page = this; this.$nextTick(function() { if (!page.readonly) { page.editorEntity = new toastui.Editor({ el: document.querySelector('#markdownedit'), height: this.height, initialValue: '', initialEditType: 'wysiwyg', hideModeSwitch: true, language: "zh-CN", events: { change: function() { page.editContent = page.editorEntity.getMarkdown(); } } }) page.editorEntity.setMarkdown(page.editContent, true) } else { page.editorViewEntity = toastui.Editor.factory({ el: document.querySelector('#markdownedit_viewer'), viewer: true, initialValue: page.editContent }); } }); }, methods: { }, }) });});
理论应用
<common-markdowneditor v-model="form.docContent" ></common-markdowneditor>
后端集成
在把markdonw的内容保留到数据库后,同时同步生成本地markdown文件,为后续html展现做筹备
public void creatMarkdownFile(DocumentContentInfoDO entity) { if (entity.getDocClass() == DocEnum.DocClass.Markdown.get_value()) { try { //生成markdown文件 String dicPath = "tempfiles/markdown/"; String filePath = dicPath + entity.getDocGuid() + ".md"; File dicInfo = new File(dicPath); if (!dicInfo.exists()) { dicInfo.mkdirs(); } File file = new File(filePath); if (file.exists()) { file.delete(); } file.createNewFile(); BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(filePath)),"utf-8")); out.write(entity.getDocContent()); out.close(); } catch (Exception e) { e.printStackTrace(); } } }
文档显示
前端显示集成了docsify@4.js,通过动静的指定homepage主页markdown文件地址达到一个index.html页面依据文档标识显示不同内容的成果
<script> var showDocUrl = apiFrameUrl + "/foundation/documentinfo/getMarkdownUrl"; var docTag = getUrlParam("docTag") $(function() { var data = { docTag: docTag, }; JsonAjax_Sync(JSON.stringify(data), showDocUrl, function(result, status) { var mdFileUrl = GetRootPath() + result.data.obj; window.$docsify = { homepage: mdFileUrl } }) })</script>