授权转载自:围的围

https://segmentfault.com/a/1190000037621367

前言

团队中会遇到在线文档管理的需求,包括技术文档,接口文档, excel 文档,和产品原型的托管等需求,一直没有找到合适的开源项目来满足需求,所以动手实现了个文档管理系统(实现起来并不复杂,该教程只是提供思路,并非最佳实践)

Github: https://github.com/huangwei9527/Ink-wash-docs

演示地址:http://www.inkwash.online/

功能列表

  • [x] 登录注册

  • [x] 工作台|文档列表

  • [x] 文档编辑预览(支持:md, excel,html产品原型托管)

  • [x] 协作编辑

  • [x] 访问权限设置

  • [x] 团队管理

  • [x] 点赞收藏

  • [x] 模板管理

  • [x] 浏览历史

  • [x] 回收站

  • [ ] 文件夹形式阅读(接口文档)

  • [ ] 编辑历史版本

系统界面预览

阅读前准备

1、了解 vue 技术栈开发 2、了解 koa3、了解 egg4、了解 mongodb

技术栈

前端:vue: 模块化开发少不了angular,react,vue三选一,这里选择了vue。vuex: 状态管理sass: css预编译器element-ui:不造轮子,有现成的优秀的vue组件库当然要用起来。

服务端:egg.js:企业级框架,按照一套统一的约定进行应用开发,开发十分高效。mongodb:一个基于分布式文件存储的数据库,比较灵活。egg-alinode:阿里提供的免费nodejs服务器性能监控。

工程搭建

这里我们将前后端项目放在同一个目录下管理,分别用 egg 脚手架和 vue-cli3 生成初始化项目,拷贝合并到同一个目录下,记得合并下 package.json 内容。(脚手架生成项目就不介绍了,按照文档来就是了),合并后将 vue 项目 src 目录改为 web ,如下:

···
·
|-- app                    // egg 初始化app目录
|-- config                // egg 初始化app目录
|-- public                // vue 静态资源目录
|-- web                    // 原 src 目录,改成 web 用作前端项目目录
·
···

这样的话 我们需要再把我们vue webpack打包配置稍作一下调整,首先是把原先的编译指向src的目录改成 web,其次为了 npm run build 能正常编译 web 我们也需要为 babel-loader 再增加一个编译目录

  • 根目录新增 vue.config.js ,目的是为了改造 vue 项目入口,改为: web/main.js

    module.exports = {    pages: {        index: {            entry: "web/main.js"        }    }
    }
    
  • babel-loader 能正常编译 web 目录, 在 vue.config.js 新增如下配置

// 扩展 webpack 配置
chainWebpack: config => {config.module.rule('js').include.add(/web/).end().use('babel').loader('babel-loader').tap(options => {// 修改它的选项...return options})
}
  • package.json 新增前端项目打包命令

"dev-web": "vue-cli-service serve",
"build-web": "vue-cli-service build",

至此前后端项目初始化工作就完了,前端开发启动npm run dev-web 后端开发启动 npm run dev

工程目录结构

|-- app                    --------服务器端项目代码|--controller                --------用于解析用户的输入,处理后返回相应的结果|--extend                    --------框架的扩展|--middleware                --------编写中间件|--model                    --------Schema数据模型|--public                    --------用于放置静态资源|--service                    --------用于编写业务逻辑层|--router.js                --------用于配置 URL 路由规则
|-- config                    --------egg 配置文件|--config.default.js            --------默认配置|--config.local.js                --------开发环境配置|--config.prod.js                --------生产环境配置|--plugin.js                    --------配置需要加载的插件
|-- web                        --------前端项目界面代码|--common                    --------前端界面对应静态资源|--components                --------组件|--config                    --------配置文件|--filter                    --------过滤器|--pages                    --------页面|--router                    --------路由配置|--store                    --------vuex状态管理|--service                    --------axios封装|--App.vue                    --------App|--main.js                    --------入口文件|--permission.js            --------权限控制
|-- docs                    --------预留编写项目文档目录
|-- vue.config.js            --------vue webpack配置文件
|-- package.json
...
...

完成项目目录初始化后,接下来先把 mongodb 全局得一些中间件、扩展方法给配置上,为接口开发做好准备工作

mongodb配置

1、安装 mongoose模块

npm install egg-mongoose --save

2、配置 config 文件

// config/plugin.js
exports.mongoose = {enable: true,package: 'egg-mongoose',
};// config/config.default.js
config.mongoose = {url: 'mongodb://127.0.0.1:27017/inkwash',options: {},
};

全局中间件和扩展配置

1、统一处理接口

后端接口开发中我们需要一个统一得返回格式,可以在 context 对象下扩展个返回数据 function 用于统一处理接口 response data

app 下新建文件夹 extend 新建 context.js

// app/extend/context.js
module.exports = {/*** 返回客户端的内容* @param status // 接口是否成功* @param body // 返回数据* @param msg // 返回信息提示* @param code // 返回状态码*/returnBody (status = true, body = {}, msg = 'success', code = 200) {this.status = code;this.body = {status: status,body: body,msg,code: code}}
}
// 调用
const { ctx } = this;
ctx.returnBody(true, {}, "成功");

2、添加统一处理错误得中间件

app文件夹下新建 middleware 文件夹,新建 error_handler.js , 并配置 congfig 全局中间件配置

// app/middleware/error_handler.js
module.exports = () => {return async function errorHandler(ctx, next) {try {await next();} catch (err) {// 所有的异常都会在app上出发一个error事件,框架会记录一条错误日志ctx.app.emit('error', err, ctx);const status = err.status || 500;// 如果时生产环境的时候 500错误的详细错误内容不返回给客户端const error = status === 500 && ctx.app.config.env === 'prod' ? '网络错误' : err.message;ctx.body = {msg: error,status: false,body: {},code: status};}};
};// app/middleware/error_handler.js
// config/config.default.js 配置全局中间件
config.middleware = [ 'errorHandler'];

jwt鉴权登录认证

1、安装 egg-jwt token生成以及验证包

npm install egg-jwt --save

2、安装完成后在根目录下的 config/plugin.js 配置一下,如:

'use strict';/** @type Egg.EggPlugin */
module.exports = {jwt: {enable: true,package: "egg-jwt"},mongoose: {enable: true,package: 'egg-mongoose',}
};

3、接下来在 config/config.default.js 里面继续配置:

config.jwt = {secret: "123456"//自定义 token 的加密条件字符串
};

4、在 context 上扩展两个 function , getTokencheckToken 用于生成 token 和验证 token

// app/extend/context.js
async getToken(data) {return await this.app.jwt.sign(data, this.app.config.jwt.secret, {expiresIn: 30* 24 * 60 * 60 + 's'});
},
async checkToken(token) {return await this.app.jwt.verify(token, this.app.config.jwt.secret)
}

5、编写个中间件实现登录验证拦截 在 app/middleware 文件夹下新建 auth.js

// app/middleware/auth.js
module.exports = () => {return async function(ctx, next) {let token = '';if (ctx.headers.authorization && ctx.headers.authorization.split(' ')[0] === 'Bearer') {token = ctx.headers.authorization.split(' ')[1];} else if (ctx.query.accesstoken) {token = ctx.query.accesstoken;} else if (ctx.request.body.accesstoken) {token = ctx.request.body.accesstoken;}let user;try{user = await ctx.checkToken(token);}catch (e) {ctx.returnBody(false,{}, 'Token 无效,请重新登录', 401);}if (!user) {ctx.returnBody(false,{}, 'Token 无效,请重新登录', 401);return;}ctx.request.user = user;await next();};
};

好了以上配置完成后就开始接下来的核心注册功能相关操作了。

  • 首先我在根目录下的 app/router.js 创建访问路由:

import { Application } from 'egg';export default (app: Application) => {const { controller, router, jwt } = app;//正常路由router.post('/auth/register', controller.auth.register);// 只有在需要验证 token 的路由上添加jwtrouter.post('/user/infor',jwt, controller.user.infor);
};
  • 接下来我去编写我的控制器,在根目录下的 app/controller/home.ts 编写内容:这里使用了两个我们在 app/extend/context.js 上扩展的两个通用方法

  1. 通过 ctx.getToken (用户信息 object 对象)将用户信息通过 jwt 生成 token 返回给前端

  2. 通过 ctx.returnBody 返回数据

// app/controller/auth.js
const Controller = require('egg').Controller
class AuthController extends Controller {async login() {//... 略}async register() {const { ctx, service } = this;const { username, password, email } = ctx.request.bodylet userData = await ctx.service.user.createUser(username, password, email);userData = userData.toObject();let userDataStr = JSON.parse(JSON.stringify(userData));// 生成tokenlet token =await ctx.getToken(userDataStr);ctx.returnBody(true, {access_token: token, userInfo: userData}, "注册成功!")}
}module.exports = AuthController;
  • 前端请求的时候需要在 headers 里面上默认的验证字断 Authorization 就可以了,如:

axios({method: 'get',url: 'http://127.0.0.1:7001/user/info',headers:{// 切记 token 不要直接发送,要在前面加上 Bearer 字符串和一个空格'Authorization':`Bearer ${token}`}
})
  • 接口从 token 获取加密信息

  1. app/extend/context.js 再扩展个 getUser 方法获取 token 加密信息

// app/extend/context.js
// 获取用户信息async getUserData() {var token = this.headers.authorization ? this.headers.authorization : '';token = token.substring(7) //把Bearer 截取掉,解析的时候不需要加上Bearerlet user = {}try {user = this.app.jwt.verify(token, this.app.config.jwt.secret);} catch (err) {user = {}}return user;}
  1. 实现获取个人信息接口

// app/controller/user.js
'use strict';const Controller = require('egg').Controller;class UserController extends Controller {async info() {let {ctx} = this;let user = await this.ctx.getUserData()ctx.returnBody(true, user)}
}module.exports = UserController;

至此我们就实现了 jwt 生成 token , 然后通过前端传过来的 token 获取当前登录用户的信息,  jwt 登录授权这块应该是讲完了,其他的业务接口应该实现起来难度不大

md文档编辑

文档编辑器使用 Vdito r, 一款浏览器端的 Markdown 编辑器,支持所见即所得(富文本)、即时渲染(类似 Typora )和分屏预览模式 安装 Vditor

npm install vditor --save

在代码中引入并初始化对象

<template><div class="editor-component editor-md" ref="editor-component"><div id="editor-md-dom"></div></div>
</template><script>import Vditor from 'vditor'import "vditor/src/assets/scss/index.scss"let timer = null;export default {data(){return {contentEditor: '',}},mounted () {this.contentEditor = new Vditor('vditor', {height: 360,toolbarConfig: {pin: true,},cache: {enable: false,},after: () => {this.contentEditor.setValue('hello, Vditor + Vue!')},})},}
</script>

excel表格编辑

安装 x-data-spreadsheet

npm install x-data-spreadsheet
<div id="x-spreadsheet-demo"></div>
import Spreadsheet from "x-data-spreadsheet";
// If you need to override the default options, you can set the override
// const options = {};
// new Spreadsheet('#x-spreadsheet-demo', options);
const s = new Spreadsheet("#x-spreadsheet-demo").loadData({}) // load data.change(data => {// save data to db});// data validation
s.validate()

axure原型托管

原型 axure 页面托管,参考 WuliHub 让用户上传生成的 html 压缩包,然后解压到静态资源目录,返回访问地址就 ok , 前端拿到原型地址用内嵌 iframe 渲染出来就 ok

打包编译&&静态资源设置

1、配置前端 vue 页面打包命令

// kage.json script新增打包命令
"build-web": "vue-cli-service build",

2、运行 npm run build-web  根目录会生成 dist 前端代码静态文件,因为 egg 支持设置多个静态资源目录,这里就直接配置根目录下的dist 文件夹为静态目录, 配置 config

// config/config.default.js
config.static = {prefix: '/',// 将静态资源前缀改为'/'(默认是 '/public')dir: [path.join(__dirname, '../app/public'), path.join(__dirname, '../dist')]}

打包完成后启动 egg , 就可以通过 http://localhost/:7001/index.html 访问到前端页面了


因为直接访问 http://localhost/:7001404可以再配置个路由重定向,将跟路由 '/' 重定向到 '/index.html'

// app/router.js
// 重定向到index页面
app.router.redirect('/', '/index.html', 302);

部署

服务端部署运行 start 命令

npm run start

性能监控

node 服务性能监控这块可以使用阿里免费开源的 alinode1、安装 egg-alinode

npm i egg-alinode

2、插件配置

// config/plugin.js
exports.alinode = {enable: true,package: 'egg-alinode',
};

3、配置config

// config/config.default.js
exports.alinode = {enable: true,appid: 'my app id',secret: 'my app secret',
};

这样就可以了,监控数据可以在阿里 Node.js 性能平台控制台看到监控面板

声明:文章著作权归作者所有,如有侵权,请联系小编删除。

最后

  • 欢迎加我微信(winty230),拉你进技术群,长期交流学习...

  • 欢迎关注「前端Q」,认真学前端,做个专业的技术人...

点个在看支持我吧

egg+vue+mongodb实践开发在线文档管理平台——水墨文档相关推荐

  1. 整理全网文档管理平台,持续跟更新

    文档管理系统 不会写文档得程序猿不是好程序猿,在日常工作中,几乎无时无刻离不开文档,也使用过很多文档管理平台,特此记录下. 1 MrDoc 地址:https://gitee.com/zmister/M ...

  2. ssm+Vue计算机毕业设计学生在线请假管理系统(程序+LW文档)

    ssm+Vue计算机毕业设计学生在线请假管理系统(程序+LW文档) 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Ecl ...

  3. 智慧社区综合管理平台——需求文档(第九组)

    目录 1.引言  1.1 项目简介 1.2 目的 1.3 文档的范围 1.4 预期的读者和阅读建议 1.5 产品的范围 1.6 参考文献 2.总体描述 2.1 产品视角 2.2 用户特征 2.3 系统 ...

  4. Yapieasyapi文档管理平台安装与使用

    一.背景 我正在建设一个租房平台,进行基于租房业务的架构实践.我尝试着按照不同领域创建了几个微服务,写了一些接口,准备模拟真正的IT企业开发环境,但是接口多了难免有变更,维护成本,目前一个人的话维护接 ...

  5. 自建低成本代码托管与文档管理平台经验分享

    自建低成本代码托管与文档管理平台经验分享 云服务器选择 搭建Gitea服务 仓库镜像管理 树莓派备份节点 Nextcloud文件管理 写在最后 直入入正题,自建代码托管平台其实市面上早有成熟的方案,s ...

  6. 魔坊APP项目-11-PyMongo、数据库连接,管理、集合管理、文档管理(添加文档、查询文档、删除文档、更新文档)

    PyMongo 安装: pip install pymongo 一.数据库连接 数据库连接,无密码 from pymongo import MongoClient# 数据库链接,必须保证当前系统能正常 ...

  7. 【云原生之Docker实战】使用Docker部署Mindoc文档管理平台

    [云原生之Docker实战]使用Docker部署Mindoc文档管理平台 一.Mindoc介绍 1.Mindoc简介 2.Mindoc功能 二.检查宿主机系统版本 1.检查操作系统版本 2.检查系统内 ...

  8. RabbitMQ管理平台功能说明文档

    **RabbitMQ管理平台功能说明文档**继上篇写的安装文档,在此记录一下RabbitMQ管理平台的一些功能说明.安装好rabbitmq启动之后,访问http://localhost:15672/# ...

  9. Go搭配mysql_GitHub - goshark/dhs: go语言搭配vue前端实现mysql双机热备管理平台

    dhs go语言结合gitee.com/johng/gf的web框架+vue前端实现mysql双机热备管理平台,支持一主多从配置.前期功能简单,持续更新. 架构设计 本项目(newproject)是由 ...

最新文章

  1. Ant Design 被删代码已恢复,现登顶 GitHub Trending Top 2
  2. 儿智展---国内首个少儿智能产品专业展11月登陆上海
  3. PHP JSON 操作总结
  4. Greenplum【环境搭建 04】使用GPKafka实现Kafka数据导入Greenplum数据库(扩展安装文件网盘分享)
  5. LeetCode 404. 左叶子之和(Sum of Left Leaves)
  6. oracle数据库中索值,Oracle数据库中的索引详解
  7. JS本地加密防止嗅探
  8. graph driver-device mapper-04libdevmapper基本操作
  9. apk 签名v1与v2的区别
  10. 利用vector实现一对一(pair<int,int>)
  11. java框架白话_Java NIO框架Netty教程(二) 白话概念
  12. (计算机组成原理)第三章存储系统-第六节2:Cache和主存的映射方式(全相联映射、直接映射和组相连映射)
  13. 关于layui中lay-verify=required无效的解决办法
  14. 企业大数据分析平台如何构建
  15. 6.4信号灯(Semaphores)
  16. Python 读取数据
  17. 华为eNSP-基本配置指令
  18. WPS如何在Word文档中设置多级的连续的标题编号
  19. ps怎么对比原图快捷键_ps快捷键对比
  20. Python 学习笔记 - 函数

热门文章

  1. 安创安全OA——小程序
  2. 苹果机皇称号实至名归,面临淘汰的它,是不是你心中的机皇
  3. Springboot 导出word,动态填充表格数据
  4. 白嫖几十款的微信红包封面
  5. 设计模式--创建型设计模式
  6. 科普:飞针测试机探针分类概要
  7. php 睡眠,win10睡眠是什么意思
  8. Random Projection 随机投影法
  9. 计算机二级:公共基础部分
  10. windows下编译64位x264