egg+vue+mongodb实践开发在线文档管理平台——水墨文档
授权转载自:围的围
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、了解 koa
3、了解 egg
4、了解 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
, getToken
和 checkToken
用于生成 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
上扩展的两个通用方法
通过
ctx.getToken
(用户信息object
对象)将用户信息通过jwt
生成token
返回给前端通过
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
获取加密信息
在
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;}
实现获取个人信息接口
// 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/:7001
会 404
可以再配置个路由重定向,将跟路由 '/'
重定向到 '/index.html'
// app/router.js
// 重定向到index页面
app.router.redirect('/', '/index.html', 302);
部署
服务端部署运行 start
命令
npm run start
性能监控
node
服务性能监控这块可以使用阿里免费开源的 alinode
1、安装 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 MrDoc 地址:https://gitee.com/zmister/M ...
- ssm+Vue计算机毕业设计学生在线请假管理系统(程序+LW文档)
ssm+Vue计算机毕业设计学生在线请假管理系统(程序+LW文档) 项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Ecl ...
- 智慧社区综合管理平台——需求文档(第九组)
目录 1.引言 1.1 项目简介 1.2 目的 1.3 文档的范围 1.4 预期的读者和阅读建议 1.5 产品的范围 1.6 参考文献 2.总体描述 2.1 产品视角 2.2 用户特征 2.3 系统 ...
- Yapieasyapi文档管理平台安装与使用
一.背景 我正在建设一个租房平台,进行基于租房业务的架构实践.我尝试着按照不同领域创建了几个微服务,写了一些接口,准备模拟真正的IT企业开发环境,但是接口多了难免有变更,维护成本,目前一个人的话维护接 ...
- 自建低成本代码托管与文档管理平台经验分享
自建低成本代码托管与文档管理平台经验分享 云服务器选择 搭建Gitea服务 仓库镜像管理 树莓派备份节点 Nextcloud文件管理 写在最后 直入入正题,自建代码托管平台其实市面上早有成熟的方案,s ...
- 魔坊APP项目-11-PyMongo、数据库连接,管理、集合管理、文档管理(添加文档、查询文档、删除文档、更新文档)
PyMongo 安装: pip install pymongo 一.数据库连接 数据库连接,无密码 from pymongo import MongoClient# 数据库链接,必须保证当前系统能正常 ...
- 【云原生之Docker实战】使用Docker部署Mindoc文档管理平台
[云原生之Docker实战]使用Docker部署Mindoc文档管理平台 一.Mindoc介绍 1.Mindoc简介 2.Mindoc功能 二.检查宿主机系统版本 1.检查操作系统版本 2.检查系统内 ...
- RabbitMQ管理平台功能说明文档
**RabbitMQ管理平台功能说明文档**继上篇写的安装文档,在此记录一下RabbitMQ管理平台的一些功能说明.安装好rabbitmq启动之后,访问http://localhost:15672/# ...
- Go搭配mysql_GitHub - goshark/dhs: go语言搭配vue前端实现mysql双机热备管理平台
dhs go语言结合gitee.com/johng/gf的web框架+vue前端实现mysql双机热备管理平台,支持一主多从配置.前期功能简单,持续更新. 架构设计 本项目(newproject)是由 ...
最新文章
- Ant Design 被删代码已恢复,现登顶 GitHub Trending Top 2
- 儿智展---国内首个少儿智能产品专业展11月登陆上海
- PHP JSON 操作总结
- Greenplum【环境搭建 04】使用GPKafka实现Kafka数据导入Greenplum数据库(扩展安装文件网盘分享)
- LeetCode 404. 左叶子之和(Sum of Left Leaves)
- oracle数据库中索值,Oracle数据库中的索引详解
- JS本地加密防止嗅探
- graph driver-device mapper-04libdevmapper基本操作
- apk 签名v1与v2的区别
- 利用vector实现一对一(pair<int,int>)
- java框架白话_Java NIO框架Netty教程(二) 白话概念
- (计算机组成原理)第三章存储系统-第六节2:Cache和主存的映射方式(全相联映射、直接映射和组相连映射)
- 关于layui中lay-verify=required无效的解决办法
- 企业大数据分析平台如何构建
- 6.4信号灯(Semaphores)
- Python 读取数据
- 华为eNSP-基本配置指令
- WPS如何在Word文档中设置多级的连续的标题编号
- ps怎么对比原图快捷键_ps快捷键对比
- Python 学习笔记 - 函数