├── .autod.conf.js ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .theia └── settings.json ├── .travis.yml ├── README.md ├── app ├── controller │ ├── admin.js │ ├── block.js │ ├── file.js │ ├── home.js │ └── user.js ├── middleware │ └── error_handler.js ├── model │ ├── block.js │ ├── file.js │ └── user.js ├── router.js ├── service │ ├── block.js │ ├── file.js │ └── user.js └── view │ ├── home.nj │ ├── lowcode.nj │ ├── preview.nj │ └── renderer.nj ├── appveyor.yml ├── bootstrap ├── config ├── config.default.js ├── config.prod.js ├── plugin.js └── secret.js ├── jsconfig.json ├── package.json └── test └── app └── controller └── home.test.js /.autod.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | write: true, 5 | prefix: '^', 6 | plugin: 'autod-egg', 7 | test: [ 8 | 'test', 9 | 'benchmark', 10 | ], 11 | dep: [ 12 | 'egg', 13 | 'egg-scripts', 14 | ], 15 | devdep: [ 16 | 'egg-ci', 17 | 'egg-bin', 18 | 'egg-mock', 19 | 'autod', 20 | 'autod-egg', 21 | 'eslint', 22 | 'eslint-config-egg', 23 | ], 24 | exclude: [ 25 | './test/fixtures', 26 | './dist', 27 | ], 28 | }; 29 | 30 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | coverage 2 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint-config-egg" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs/ 2 | npm-debug.log 3 | yarn-error.log 4 | node_modules/ 5 | package-lock.json 6 | yarn.lock 7 | coverage/ 8 | .idea/ 9 | run/ 10 | .DS_Store 11 | *.sw* 12 | *.un~ 13 | typings/ 14 | .nyc_output/ 15 | -------------------------------------------------------------------------------- /.theia/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.exclude": { 3 | "**/.git": true, 4 | "**/.svn": true, 5 | "**/.hg": true, 6 | "**/CVS": true, 7 | "**/.DS_Store": true, 8 | "**/.ds": true, 9 | "**/.theia": true 10 | }, 11 | "editor.autoSave": "on", 12 | "terminal.integrated.shell.linux": "/bin/bash" 13 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | 2 | language: node_js 3 | node_js: 4 | - '10' 5 | before_install: 6 | - npm i npminstall -g 7 | install: 8 | - npminstall 9 | script: 10 | - npm run ci 11 | after_script: 12 | - npminstall codecov && codecov 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Documents Solution Site 2 | 3 | *before start, you need to fill yuque token and aliyun secret in config.default.js .* -------------------------------------------------------------------------------- /app/controller/admin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const stringToStream = require('string-to-stream'); 3 | 4 | const Controller = require('egg').Controller; 5 | 6 | class AdminController extends Controller { 7 | async lowcode() { 8 | const { ctx } = this; 9 | await ctx.render('lowcode.nj'); 10 | } 11 | 12 | async preview() { 13 | const { ctx } = this; 14 | await ctx.render('preview.nj'); 15 | } 16 | 17 | async schema() { 18 | const { ctx } = this; 19 | const res = await ctx.oss.get('portal/schema.json'); 20 | console.log('res: ', res); 21 | ctx.response.set('content-type', 'json'); 22 | ctx.body = res.content; 23 | } 24 | 25 | async saveSchema() { 26 | const { ctx } = this; 27 | const { page = 'home', schema } = ctx.request.body; 28 | const filename = `${page}.json`; 29 | ctx.response.set('Access-Control-Allow-Origin', '*'); 30 | const res = await ctx.oss.putStream(`portal/${filename}`, stringToStream(JSON.stringify(schema))); 31 | ctx.body = res || 'ok'; 32 | } 33 | 34 | async loginView() { 35 | const { ctx } = this; 36 | const { redirectUrl = '/' } = ctx.request.query; 37 | if (ctx.session.username) { 38 | ctx.redirect(redirectUrl); 39 | return; 40 | } 41 | await ctx.render('renderer.nj', { 42 | data: { 43 | schemaUrl: 'https://i.ablula.tech/portal/login.json', 44 | fullScreen: true, 45 | }, 46 | }); 47 | } 48 | 49 | async logout() { 50 | const { ctx } = this; 51 | ctx.session = null; 52 | ctx.redirect(ctx.get('referer') || '/'); 53 | } 54 | 55 | async login() { 56 | const { ctx } = this; 57 | const { username, password } = ctx.request.body; 58 | const result = await ctx.service.user.login(username, password); 59 | console.log('result: ', result); 60 | ctx.body = { 61 | status: result ? 'success' : 'failed', 62 | }; 63 | } 64 | 65 | } 66 | 67 | module.exports = AdminController; 68 | -------------------------------------------------------------------------------- /app/controller/block.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class BlockController extends Controller { 6 | 7 | async listBlocks() { 8 | const { ctx } = this; 9 | const blocks = await ctx.service.block.listBlock(); 10 | ctx.body = { 11 | code: 0, 12 | data: blocks, 13 | }; 14 | } 15 | async getBlock() { 16 | const { ctx } = this; 17 | const { id } = ctx.params; 18 | const block = await ctx.service.block.getBlockByPk(id); 19 | ctx.body = { 20 | code: 0, 21 | data: block, 22 | }; 23 | } 24 | async createBlock() { 25 | const { ctx } = this; 26 | const { block } = ctx.request.body; 27 | const result = await ctx.service.block.createBlock(block); 28 | ctx.logger.info('create block result: ', result); 29 | ctx.body = { 30 | code: 0, 31 | message: '创建区块成功', 32 | }; 33 | } 34 | async updateBlock() { 35 | const { ctx } = this; 36 | ctx.logger.info('in update block'); 37 | const { id } = ctx.params; 38 | const { block } = ctx.request.body; 39 | ctx.logger.info('update block id: %s, block: %s', id, block); 40 | const result = await ctx.service.block.updateBlock(id, block); 41 | ctx.logger.info('update block result: ', result); 42 | ctx.body = { 43 | code: 0, 44 | message: '更新区块成功', 45 | }; 46 | } 47 | async deleteBlock() { 48 | const { ctx } = this; 49 | const { id } = ctx.params; 50 | const result = await ctx.service.block.deleteBlock(id); 51 | ctx.logger.info('delete block result: ', result); 52 | ctx.body = { 53 | code: 0, 54 | message: '删除区块成功', 55 | }; 56 | } 57 | 58 | } 59 | 60 | module.exports = BlockController; 61 | -------------------------------------------------------------------------------- /app/controller/file.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class AdminController extends Controller { 6 | 7 | async listFiles() { 8 | const { ctx } = this; 9 | const files = await ctx.service.file.listFile(); 10 | ctx.body = { 11 | code: 0, 12 | data: files, 13 | }; 14 | } 15 | async getFile() { 16 | const { ctx } = this; 17 | const { id } = ctx.params; 18 | const file = await ctx.service.file.getFileByPk(id); 19 | ctx.body = { 20 | code: 0, 21 | data: file, 22 | }; 23 | } 24 | async createFile() { 25 | const { ctx } = this; 26 | const { file } = ctx.request.body; 27 | const result = await ctx.service.file.createFile(file); 28 | ctx.logger.info('create file result: ', result); 29 | ctx.body = { 30 | code: 0, 31 | message: '创建文件成功', 32 | }; 33 | } 34 | async updateFile() { 35 | const { ctx } = this; 36 | ctx.logger.info('in update file'); 37 | const { id } = ctx.params; 38 | const { file } = ctx.request.body; 39 | ctx.logger.info('update file id: %s, file: %s', id, file); 40 | const result = await ctx.service.file.updateFile(id, file); 41 | ctx.logger.info('update file result: ', result); 42 | ctx.body = { 43 | code: 0, 44 | message: '更新文件成功', 45 | }; 46 | } 47 | async deleteFile() { 48 | const { ctx } = this; 49 | const { id } = ctx.params; 50 | const result = await ctx.service.file.deleteFile(id); 51 | ctx.logger.info('delete file result: ', result); 52 | ctx.body = { 53 | code: 0, 54 | message: '删除文件成功', 55 | }; 56 | } 57 | 58 | } 59 | 60 | module.exports = AdminController; 61 | -------------------------------------------------------------------------------- /app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class HomeController extends Controller { 6 | async index() { 7 | const { ctx } = this; 8 | const { yuqueViewer } = this.config; 9 | const { 10 | menuDataSource, 11 | darkMode, 12 | headerHeight, 13 | blackColor, 14 | lightColor, 15 | hideLogo, 16 | hideTitle, 17 | logo, 18 | homepage, 19 | logoHref, 20 | logoStyle, 21 | title, 22 | titleHref, 23 | } = yuqueViewer; 24 | 25 | await ctx.render('renderer.nj', { 26 | data: { 27 | schemaUrl: 'https://i.ablula.tech/portal/home.json', 28 | menuDataSource, 29 | darkMode, 30 | headerHeight, 31 | blackColor, 32 | lightColor, 33 | hideLogo, 34 | hideTitle, 35 | logo, 36 | homepage, 37 | logoHref, 38 | logoStyle, 39 | title, 40 | titleHref, 41 | }, 42 | }); 43 | } 44 | } 45 | 46 | module.exports = HomeController; 47 | -------------------------------------------------------------------------------- /app/controller/user.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class AdminController extends Controller { 6 | 7 | async profile() { 8 | const { ctx } = this; 9 | ctx.body = { 10 | username: 'admin', 11 | gender: 3, 12 | avatar: 'https://img.alicdn.com/imgextra/i4/O1CN013w2bmQ25WAIha4Hx9_!!6000000007533-55-tps-137-26.svg', 13 | phone: 123456, 14 | }; 15 | } 16 | 17 | } 18 | 19 | module.exports = AdminController; 20 | -------------------------------------------------------------------------------- /app/middleware/error_handler.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = () => { 4 | return async function errorHandler(ctx, next) { 5 | try { 6 | await next(); 7 | } catch (e) { 8 | console.log('e: ', e); 9 | ctx.body = { 10 | status: 'failed', 11 | }; 12 | } 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /app/model/block.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { INTEGER, STRING, DATE } = app.Sequelize; 5 | 6 | const lowcodeBlock = app.model.define('lowcode-block', { 7 | id: { 8 | type: INTEGER, 9 | autoIncrement: true, 10 | primaryKey: true, 11 | }, 12 | name: STRING, 13 | title: INTEGER, 14 | screenshot: STRING, 15 | schema: STRING, 16 | created_at: DATE, 17 | updated_at: DATE, 18 | }, { 19 | tableName: 'lowcode-block', 20 | }); 21 | return lowcodeBlock; 22 | }; 23 | -------------------------------------------------------------------------------- /app/model/file.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { INTEGER, STRING, DATE } = app.Sequelize; 5 | 6 | const lowcodeFile = app.model.define('lowcode-file', { 7 | id: { 8 | type: INTEGER, 9 | autoIncrement: true, 10 | primaryKey: true, 11 | }, 12 | name: STRING, 13 | parent_id: INTEGER, 14 | type: INTEGER, 15 | icon: STRING, 16 | locator: STRING, 17 | creator: STRING, 18 | schema_url: STRING, 19 | created_at: DATE, 20 | updated_at: DATE, 21 | }, { 22 | tableName: 'lowcode-file', 23 | }); 24 | return lowcodeFile; 25 | }; 26 | -------------------------------------------------------------------------------- /app/model/user.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const { INTEGER, STRING, BOOLEAN, DATE } = app.Sequelize; 5 | 6 | const User = app.model.define('user', { 7 | id: { 8 | type: INTEGER, 9 | autoIncrement: true, 10 | primaryKey: true, 11 | }, 12 | name: STRING, 13 | password: STRING, 14 | gender: BOOLEAN, 15 | phone: STRING, 16 | introduction: STRING, 17 | created_at: DATE, 18 | updated_at: DATE, 19 | }); 20 | return User; 21 | }; 22 | -------------------------------------------------------------------------------- /app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const needLogin = async (ctx, next) => { 4 | if (ctx.session.username) { 5 | await next(); 6 | } else { 7 | ctx.redirect(`/login?redirectUrl=${ctx.request.path}`); 8 | } 9 | }; 10 | 11 | /** 12 | * @param {Egg.Application} app - egg application 13 | */ 14 | module.exports = app => { 15 | const { router, controller } = app; 16 | router.get('/', controller.home.index); 17 | router.get('/admin/lowcode', needLogin, controller.admin.lowcode); 18 | router.get('/admin/schema.json', controller.admin.schema); 19 | router.get('/api/v1/schemas/1', controller.admin.schema); 20 | router.get('/admin/preview.html', controller.admin.preview); 21 | router.get('/admin/preview.html/*', controller.admin.preview); 22 | router.post('/api/v1/schemas', controller.admin.saveSchema); 23 | 24 | /** login start */ 25 | 26 | router.get('/login', controller.admin.loginView); 27 | router.get('/logout', controller.admin.logout); 28 | router.post('/api/login', controller.admin.login); 29 | 30 | /** login end */ 31 | 32 | router.get('/api/v1/profile', needLogin, controller.user.profile); 33 | 34 | /** lowcode file start */ 35 | router.get('/api/v1/files', controller.file.listFiles); 36 | router.get('/api/v1/files/:id', controller.file.getFile); 37 | router.post('/api/v1/files', controller.file.createFile); 38 | router.patch('/api/v1/files/:id', controller.file.updateFile); 39 | router.delete('/api/v1/files/:id', controller.file.deleteFile); 40 | /** lowcode file end */ 41 | 42 | /** lowcode block start */ 43 | router.get('/api/v1/blocks', controller.block.listBlocks); 44 | router.post('/api/v1/blocks', controller.block.createBlock); 45 | /** lowcode block end */ 46 | 47 | }; 48 | -------------------------------------------------------------------------------- /app/service/block.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { Service } = require('egg'); 4 | 5 | class BlockService extends Service { 6 | 7 | constructor(app) { 8 | super(app); 9 | const { ctx } = this; 10 | this.Block = ctx.model.Block; 11 | } 12 | 13 | async listBlock() { 14 | const { ctx } = this; 15 | return this.Block.findAll(); 16 | } 17 | async getBlockByPk(id) { 18 | return this.Block.findByPk(id); 19 | } 20 | async createBlock(file) { 21 | const { ctx } = this; 22 | return this.Block.create(file); 23 | } 24 | async updateBlock(id, file) { 25 | const { ctx } = this; 26 | return this.Block.update(file, { where: { id } }); 27 | } 28 | async deleteBlock(id) { 29 | const { ctx } = this; 30 | return this.Block.destroy({ where: { id } }); 31 | } 32 | 33 | } 34 | 35 | module.exports = BlockService; 36 | -------------------------------------------------------------------------------- /app/service/file.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { Service } = require('egg'); 4 | 5 | class FileService extends Service { 6 | 7 | constructor(app) { 8 | super(app); 9 | const { ctx } = this; 10 | this.File = ctx.model.File; 11 | } 12 | 13 | async listFile() { 14 | const { ctx } = this; 15 | return this.File.findAll(); 16 | } 17 | async getFileByPk(id) { 18 | return this.File.findByPk(id); 19 | } 20 | async createFile(file) { 21 | const { ctx } = this; 22 | return this.File.create(file); 23 | } 24 | async updateFile(id, file) { 25 | const { ctx } = this; 26 | return this.File.update(file, { where: { id } }); 27 | } 28 | async deleteFile(id) { 29 | const { ctx } = this; 30 | return this.File.destroy({ where: { id } }); 31 | } 32 | 33 | } 34 | 35 | module.exports = FileService; 36 | -------------------------------------------------------------------------------- /app/service/user.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const md5 = require('md5'); 4 | const { Service } = require('egg'); 5 | 6 | const users = [ 7 | { 8 | username: 'admin', 9 | password: md5('123456'), 10 | }, 11 | ]; 12 | 13 | class UserService extends Service { 14 | async find(username) { 15 | const user = await users.find(user => { 16 | return user.username === username; 17 | }); 18 | return user; 19 | } 20 | 21 | async login(username, password) { 22 | const { ctx } = this; 23 | console.log('session: ', ctx.session); 24 | if (ctx.session.username === username) { 25 | return true; 26 | } 27 | const user = await this.find(username); 28 | const result = user && (password === user.password); 29 | if (result) { 30 | ctx.session = user; 31 | return true; 32 | } 33 | return false; 34 | } 35 | 36 | } 37 | 38 | module.exports = UserService; 39 | -------------------------------------------------------------------------------- /app/view/home.nj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Egg.js 5 | 6 | 55 | 56 | 88 | 89 | 90 | 91 |
92 |
93 |
94 | 95 | 96 | Group 8 97 | Created with Sketch Beta. 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 |

188 | Greetings from Egg.js! 189 |

190 |

191 | The web app is hosted on Aliyun FunctionCompute. 192 |

193 | 209 |
210 |
211 |
212 | 213 | 214 | 215 | 216 | 217 | -------------------------------------------------------------------------------- /app/view/lowcode.nj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 阿里低代码引擎 Demo 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/view/preview.nj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 预览低代码 7 | 8 | 9 | 10 | 11 |
12 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/view/renderer.nj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 预览低代码 7 | 8 | 9 | 10 |
11 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - nodejs_version: '10' 4 | 5 | install: 6 | - ps: Install-Product node $env:nodejs_version 7 | - npm i npminstall && node_modules\.bin\npminstall 8 | 9 | test_script: 10 | - node --version 11 | - npm --version 12 | - npm run test 13 | 14 | build: off 15 | -------------------------------------------------------------------------------- /bootstrap: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | export PORT=9000 3 | export EGG_SERVER_ENV=prod 4 | npx --no-install egg-scripts start --workers=1 5 | -------------------------------------------------------------------------------- /config/config.default.js: -------------------------------------------------------------------------------- 1 | /* eslint valid-jsdoc: "off" */ 2 | 3 | 'use strict'; 4 | const path = require('path'); 5 | const { ossConfig, yuqueSecret, mysql } = require('./secret'); 6 | 7 | /** 8 | * @param {Egg.EggAppInfo} appInfo app info 9 | */ 10 | module.exports = appInfo => { 11 | /** 12 | * built-in config 13 | * @type {Egg.EggAppConfig} 14 | **/ 15 | const config = exports = {}; 16 | config.middleware = [ 'errorHandler' ]; 17 | 18 | // use for cookie sign key, should change to your own and keep security 19 | config.keys = appInfo.name + '_1586592205046_9870'; 20 | 21 | // add your middleware config here 22 | config.middleware = []; 23 | 24 | config.view = { 25 | root: [ 26 | path.join(appInfo.baseDir, 'app/view'), 27 | ].join(','), 28 | 29 | mapping: { 30 | '.nj': 'nunjucks', 31 | }, 32 | 33 | defaultViewEngine: 'nunjucks', 34 | defaultExtension: '.nj', 35 | }; 36 | 37 | // add your user config here 38 | const userConfig = { 39 | yuqueViewer: { 40 | npm: '@ablula/document-client@0.2.9-beta.4', 41 | onlyDoc: false, 42 | noHeader: false, 43 | showSearch: true, 44 | showEditor: true, 45 | darkMode: false, 46 | lightColor: '#ffffff00', 47 | headerHeight: 48, 48 | blackColor: 'black', 49 | token: yuqueSecret.token, 50 | title: '文档站点解决方案', 51 | documents: { 52 | help: { 53 | baseUrl: 'https://www.yuque.com/api/v2', 54 | namespace: 'mark.ck/ds', 55 | search: '/documents/search', 56 | homepage: '', 57 | title: '文档体系解决方案', 58 | hideTitle: true, 59 | prefix: '/api/documents', 60 | view: '/doc', 61 | }, 62 | spec: { 63 | baseUrl: 'https://www.yuque.com/api/v2', 64 | namespace: 'mark.ck/spec', 65 | search: '/spec/search', 66 | homepage: '', 67 | title: '规范协议', 68 | hideTitle: true, 69 | prefix: '/api/spec', 70 | view: '/spec', 71 | }, 72 | }, 73 | menuDataSource: [ 74 | { 75 | label: '首页', 76 | target: '_self', 77 | url: '/', 78 | }, 79 | { 80 | label: '文档', 81 | target: '_self', 82 | url: '/doc', 83 | }, 84 | { 85 | label: '协议', 86 | target: '_self', 87 | url: '/spec', 88 | }, 89 | ], 90 | }, 91 | }; 92 | 93 | config.security = { 94 | xframe: { 95 | enable: false, 96 | }, 97 | csrf: { 98 | ignoreJSON: true, // 默认为 false,当设置为 true 时,将会放过所有 content-type 为 `application/json` 的请求 99 | }, 100 | }; 101 | 102 | config.oss = { 103 | client: { 104 | ...ossConfig, 105 | }, 106 | }; 107 | 108 | config.sequelize = { 109 | ...mysql, 110 | }; 111 | 112 | return { 113 | ...config, 114 | ...userConfig, 115 | }; 116 | }; 117 | -------------------------------------------------------------------------------- /config/config.prod.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = { 3 | rundir: '/tmp/run', 4 | logger: { 5 | dir: '/tmp/log', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** @type Egg.EggPlugin */ 4 | module.exports = { 5 | // had enabled by egg 6 | // static: { 7 | // enable: true, 8 | // } 9 | nunjucks: { 10 | enable: true, 11 | package: 'egg-view-nunjucks', 12 | }, 13 | yuqueViewer: { 14 | enable: true, 15 | package: '@ablula/egg-yuque-viewer', 16 | }, 17 | oss: { 18 | enable: true, 19 | package: 'egg-oss', 20 | }, 21 | }; 22 | -------------------------------------------------------------------------------- /config/secret.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | ossConfig: { 5 | accessKeyId: '', 6 | accessKeySecret: '', 7 | bucket: '', 8 | endpoint: '', 9 | timeout: '', 10 | }, 11 | yuqueSecret: { 12 | token: '', 13 | }, 14 | mysql: { 15 | dialect: 'mysql', // support: mysql, mariadb, postgres, mssql 16 | database: '', 17 | host: '', 18 | port: 3306, 19 | username: '', 20 | password: '', 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "**/*" 4 | ] 5 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ablula/document-sites", 3 | "version": "1.0.0", 4 | "description": "", 5 | "private": true, 6 | "egg": { 7 | "declarations": true 8 | }, 9 | "dependencies": { 10 | "@ablula/egg-yuque-viewer": "^0.2.1", 11 | "egg": "^2.15.1", 12 | "egg-oss": "^2.0.0", 13 | "egg-scripts": "^2.11.0", 14 | "egg-sequelize": "^6.0.0", 15 | "egg-view-nunjucks": "^2.2.0", 16 | "md5": "^2.3.0", 17 | "mysql2": "^2.3.3", 18 | "string-to-stream": "^3.0.1" 19 | }, 20 | "devDependencies": { 21 | "autod": "^3.0.1", 22 | "autod-egg": "^1.1.0", 23 | "egg-bin": "^4.11.0", 24 | "egg-ci": "^1.11.0", 25 | "egg-mock": "^3.21.0", 26 | "eslint": "^5.13.0", 27 | "eslint-config-egg": "^7.1.0" 28 | }, 29 | "engines": { 30 | "node": ">=10.0.0" 31 | }, 32 | "scripts": { 33 | "start": "egg-scripts start --daemon --title=egg-server-eggjs", 34 | "stop": "egg-scripts stop --title=egg-server-eggjs", 35 | "dev": "egg-bin dev", 36 | "debug": "egg-bin debug", 37 | "test": "npm run lint -- --fix && npm run test-local", 38 | "test-local": "egg-bin test", 39 | "cov": "egg-bin cov", 40 | "lint": "eslint .", 41 | "ci": "npm run lint && npm run cov", 42 | "autod": "autod" 43 | }, 44 | "ci": { 45 | "version": "10" 46 | }, 47 | "repository": { 48 | "type": "git", 49 | "url": "" 50 | }, 51 | "author": "vangie", 52 | "license": "MIT" 53 | } 54 | -------------------------------------------------------------------------------- /test/app/controller/home.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const { app, assert } = require('egg-mock/bootstrap'); 4 | 5 | describe('test/app/controller/home.test.js', () => { 6 | it('should assert', () => { 7 | const pkg = require('../../../package.json'); 8 | assert(app.config.keys.startsWith(pkg.name)); 9 | 10 | // const ctx = app.mockContext({}); 11 | // yield ctx.service.xx(); 12 | }); 13 | 14 | it('should GET /', () => { 15 | return app.httpRequest() 16 | .get('/') 17 | .expect('hi, egg') 18 | .expect(200); 19 | }); 20 | }); 21 | --------------------------------------------------------------------------------