предисловие
Команда столкнется с потребностями онлайн-управления документами, включая техническую документацию, интерфейсные документы, документы Excel, размещение прототипов продуктов и т. д., и не нашла подходящего проекта с открытым исходным кодом для удовлетворения потребностей, поэтому система управления документами ( реализация Это не сложно, туториал просто предлагает идеи, а не лучшие практики)
Github: портал
Демонстрационный адрес:портал
список функций
- войти Зарегистрироваться
- Таблица |Список документов
- Предварительный просмотр редактирования документа (поддержка: md, excel, размещение прототипов продуктов в формате html)
- Совместное редактирование
- Настройки прав доступа
- Управление командой
- Нравится Избранное
- Управление шаблонами
- История просмотров
- корзина
- Чтение формы папки (документация по интерфейсу)
- Изменить версию истории
Предварительный просмотр интерфейса системы
подготовиться перед чтением
1. Понимание разработки стека технологий vue
2. Понять коа
3. Поймите яйца
4. Понимание монгодб
стек технологий
внешний интерфейс:
vue: Модульная разработка незаменима для angular, react и vue, и здесь выбран vue.
vuex: государственное управление
sass: прекомпилятор css.
element-ui: Не стройте колеса, конечно, есть готовые отличные библиотеки компонентов vue.
Сервер:
egg.js: Фреймворк уровня предприятия, разработка приложений осуществляется в соответствии с унифицированным набором соглашений, и разработка очень эффективна.
mongodb: база данных на основе распределенного хранилища файлов, которая является более гибкой.
egg-alinode: бесплатный мониторинг производительности сервера nodejs, предоставляемый Ali.
Инженерное сооружение
Здесь мы управляем интерфейсными и внутренними проектами в одном каталоге, используем шаблоны egg и vue-cli3 для создания проектов инициализации, копируем и объединяем их в один и тот же каталог и не забываем объединять содержимое package.json. (Проект создания скаффолдинга представлен не будет, просто следуйте документации), после слияния измените каталог src проекта vue на web следующим образом:
···
·
|-- app // egg 初始化app目录
|-- config // egg 初始化app目录
|-- public // vue 静态资源目录
|-- web // 原 src 目录,改成 web 用作前端项目目录
·
···
В этом случае нам нужно внести некоторые коррективы в нашу конфигурацию упаковки vue webpack.Во-первых, изменить каталог, в котором исходная компиляция указывает на src на web.Во-вторых, чтобы npm run build нормально скомпилировал веб, нам также нужно добавить еще одну компиляцию для babel-loader.content:
-
Добавьте vue.config.js в корневой каталог, цель состоит в том, чтобы преобразовать запись проекта vue, изменить ее на: web/main.js
module.exports = { pages: { index: { entry: "web/main.js" } } } -
babel-loader может нормально компилировать веб-каталог, добавьте следующую конфигурацию в 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",
Инициализация back-end проекта завершена, и начинается front-end разработка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. Установите модуль мангуста
npm install egg-mongoose --save
2. Настройте файл конфигурации
// 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.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. Добавьте промежуточное ПО для унифицированной обработки ошибок. Создайте новую папку промежуточного программного обеспечения в папке приложения, создайте новый файл error_handler.js и настройте глобальную конфигурацию промежуточного программного обеспечения configfig.
// 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.
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. Расширьте две функции в контексте, getToken и checkToken используются для создания токена и проверки токена.
// 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. Напишите промежуточное ПО для реализации перехвата проверки входа Создайте новый auth.js в папке app/middleware.
// 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 的路由上添加jwt
router.post('/user/infor',jwt, controller.user.infor);
};
- Затем я приступаю к написанию своего контроллера и записываю содержимое в app/controller/home.ts в корневом каталоге:
Здесь используются два общих метода, которые мы расширяем в app/extend/context.js.
- Через ctx.getToken (объект объекта информации о пользователе) информация о пользователе генерируется jwt, и токен возвращается во внешний интерфейс.
- Возврат данных через 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.body
let userData = await ctx.service.user.createUser(username, password, email);
userData = userData.toObject();
let userDataStr = JSON.parse(JSON.stringify(userData));
// 生成token
let token =await ctx.getToken(userDataStr);
ctx.returnBody(true, {access_token: token, userInfo: userData}, "注册成功!")
}
}
module.exports = AuthController;
- При выполнении внешнего запроса вам необходимо разорвать авторизацию с помощью слова аутентификации по умолчанию в заголовках, например:
axios({
method: 'get',
url: 'http://127.0.0.1:7001/user/info',
headers:{
// 切记 token 不要直接发送,要在前面加上 Bearer 字符串和一个空格
'Authorization':`Bearer ${token}`
}
})
- Интерфейс получает зашифрованную информацию от toen
- Расширьте метод getUser в app/extend/context.js, чтобы получить информацию о шифровании токена.
// app/extend/context.js
// 获取用户信息
async getUserData() {
var token = this.headers.authorization ? this.headers.authorization : '';
token = token.substring(7) //把Bearer 截取掉,解析的时候不需要加上Bearer
let 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, а затем получили информацию о текущем вошедшем в систему пользователе через токен, переданный из внешнего интерфейса.Авторизация входа в jwt должна быть завершена, и другие бизнес-интерфейсы не должны быть сложными для реализации.
MD редактирование документов
Редактор документов Vditor, редактор Markdown на стороне браузера, поддерживает WYSIWYG (форматированный текст), рендеринг в реальном времени (аналогично Typora) и режим предварительного просмотра с разделением экрана. Установка Вдитор
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-таблицу
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-пакет, затем распаковать его в каталог статических ресурсов и вернуть адрес доступа, все в порядке, внешний интерфейс получает адрес прототипа и отображает его с помощью встроенный iframe, это нормально
Компиляция пакетов и настройки статических ресурсов
1. Настройте интерфейсную команду упаковки vue page.
// kage.json script新增打包命令
"build-web": "vue-cli-service build",
2. Запуск npm run build-web В корневом каталоге будет сгенерирован статический файл внешнего кода dist, поскольку egg поддерживает настройку нескольких каталогов статических ресурсов.Здесь непосредственно настройте папку dist в корневом каталоге как статический каталог и настроить конфигурацию
// config/config.default.js
config.static = {
prefix: '/',// 将静态资源前缀改为'/'(默认是 '/public')
dir: [
path.join(__dirname, '../app/public'),
path.join(__dirname, '../dist')
]
}
После того, как упаковка будет завершена, запустите яйцо, вы можете пройти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
мониторинг производительности
Для мониторинга производительности службы узла вы можете использовать бесплатный алинод с открытым исходным кодом Ali. 1. Установите яйцо-алинод
npm i egg-alinode
2. Настройка плагина
// config/plugin.js
exports.alinode = {
enable: true,
package: 'egg-alinode',
};
3. Настройте конфиг
// config/config.default.js
exports.alinode = {
enable: true,
appid: 'my app id',
secret: 'my app secret',
};
Вот и все, данные мониторинга можно увидеть в панели мониторинга консоли платформы производительности Alibaba Node.js.
конец
Это не сложно реализовать, это руководство просто предоставляет идеи, не лучшие практики