├── .autod.conf.js ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .travis.yml ├── README.md ├── app ├── controller │ ├── ImageController.js │ ├── activityDataController.js │ ├── activityObjectController.js │ ├── complateController.js │ ├── templateController.js │ └── testController.js ├── model │ ├── activityData.js │ ├── activityObject.js │ ├── complateData.js │ ├── templateData.js │ └── templateObject.js ├── router.js └── service │ ├── activityDataService.js │ ├── activityObjectService.js │ ├── complateDataService.js │ ├── templateDataService.js │ └── templateObjectService.js ├── appveyor.yml ├── config ├── config.default.js └── plugin.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 | // "allowEmptyReject": true 4 | } 5 | -------------------------------------------------------------------------------- /.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 | app/static/ 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 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 | # example 2 | 3 | 4 | 5 | ## QuickStart 6 | 7 | 8 | 9 | see [egg docs][egg] for more detail. 10 | 11 | ### Development 12 | 13 | ```bash 14 | $ npm i 15 | $ npm run dev 16 | $ open http://localhost:7001/ 17 | ``` 18 | 19 | ### Deploy 20 | 21 | ```bash 22 | $ npm start 23 | $ npm stop 24 | ``` 25 | 26 | ### npm scripts 27 | 28 | - Use `npm run lint` to check code style. 29 | - Use `npm test` to run unit test. 30 | - Use `npm run autod` to auto detect dependencies upgrade, see [autod](https://www.npmjs.com/package/autod) for more detail. 31 | 32 | 33 | [egg]: https://eggjs.org -------------------------------------------------------------------------------- /app/controller/ImageController.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | const path = require('path') 3 | const fs = require('fs') 4 | const sendToWormhole = require('stream-wormhole') 5 | const Controller = require('egg').Controller 6 | 7 | class ImageController extends Controller { 8 | async upload() { 9 | const { ctx } = this 10 | const stream = await ctx.getFileStream() 11 | const fileName = stream.filename.split('.')[0] // 用户名 12 | const fileType = stream.filename.split('.')[1] // 用户名 13 | const photoName = `${fileName + new Date().getTime() + '.' + fileType}` 14 | const target = path.join( 15 | this.config.baseDir, 16 | `app/static/upload/${photoName}` 17 | ) 18 | const result = await new Promise((resolve, reject) => { 19 | // 创建可写流 20 | const remoteFileStream = fs.createWriteStream(target) 21 | // 写入流 22 | stream.pipe(remoteFileStream) 23 | let errFlag 24 | // 监听失败 25 | remoteFileStream.on('error', err => { 26 | errFlag = true 27 | sendToWormhole(stream) 28 | remoteFileStream.destroy() 29 | reject(err) 30 | }) 31 | // 监听完成 32 | remoteFileStream.on('finish', async () => { 33 | if (errFlag) return 34 | resolve({ 35 | data: `http://${ctx.header.host}/static/upload/${photoName}` 36 | }) 37 | }) 38 | }) 39 | ctx.body = { 40 | data: result, 41 | code: 200 42 | } 43 | } 44 | async uptitleimage() { 45 | const { ctx } = this 46 | const stream = await ctx.getFileStream() 47 | const fileName = stream.filename.split('.')[0] // 用户名 48 | const fileType = stream.filename.split('.')[1] // 用户名 49 | const photoName = `${fileName + new Date().getTime() + '.' + fileType}` 50 | const target = path.join( 51 | this.config.baseDir, 52 | `app/static/title/${photoName}` 53 | ) 54 | const result = await new Promise((resolve, reject) => { 55 | // 创建可写流 56 | const remoteFileStream = fs.createWriteStream(target) 57 | // 写入流 58 | stream.pipe(remoteFileStream) 59 | let errFlag 60 | // 监听失败 61 | remoteFileStream.on('error', err => { 62 | errFlag = true 63 | sendToWormhole(stream) 64 | remoteFileStream.destroy() 65 | reject(err) 66 | }) 67 | // 监听完成 68 | remoteFileStream.on('finish', async () => { 69 | if (errFlag) return 70 | resolve({ 71 | data: `http://${ctx.header.host}/static/title/${photoName}` 72 | }) 73 | }) 74 | }) 75 | ctx.body = { 76 | data: result, 77 | code: 200 78 | } 79 | } 80 | async getImage() { 81 | const { ctx } = this 82 | let data = await new Promise((resolve, reject) => { 83 | var filePath = path.join(this.config.baseDir, `app/static/upload/`) 84 | fs.readdir(filePath, function(err, path) { 85 | let paths = [] 86 | if (!err) { 87 | path.map((e, i) => { 88 | if (e != '.DS_Store') { 89 | paths.push(`http://${ctx.header.host}/static/upload/${e}`) 90 | } 91 | }) 92 | resolve(paths) 93 | } else { 94 | reject(err) 95 | } 96 | }) 97 | }) 98 | ctx.body = { 99 | data, 100 | code: 200 101 | } 102 | } 103 | async getDefaultImg() { 104 | const { ctx } = this 105 | let data = await new Promise((resolve, reject) => { 106 | var filePath = path.join(this.config.baseDir, `app/static/default/`) 107 | fs.readdir(filePath, function(err, path) { 108 | let paths = [] 109 | if (!err) { 110 | path.map((e, i) => { 111 | if (e != '.DS_Store') { 112 | paths.push(`http://${ctx.header.host}/static/default/${e}`) 113 | } 114 | }) 115 | resolve(paths) 116 | } else { 117 | reject(err) 118 | } 119 | }) 120 | }) 121 | ctx.body = { 122 | data, 123 | code: 200 124 | } 125 | } 126 | } 127 | 128 | module.exports = ImageController 129 | -------------------------------------------------------------------------------- /app/controller/activityDataController.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-02-22 12:50:34 4 | * @LastEditTime: 2020-03-12 08:37:40 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/controller/activityDataController.js 8 | */ 9 | 'use strict' 10 | 11 | const Controller = require('egg').Controller 12 | 13 | class activityDataController extends Controller { 14 | async getActivity() { 15 | const { ctx } = this 16 | try { 17 | const result = await ctx.service.activityDataService.findById( 18 | ctx.params.id 19 | ) 20 | ctx.body = { 21 | data: result, 22 | code: 200 23 | } 24 | } catch (error) { 25 | ctx.body = { 26 | data: String(error), 27 | code: 500 28 | } 29 | } 30 | } 31 | async saveActivity() { 32 | const { ctx } = this 33 | const data = ctx.request.body 34 | const result = await ctx.service.activityDataService.setActivityData(data) 35 | ctx.body = { 36 | data: result, 37 | code: 200 38 | } 39 | } 40 | async getMobileData() { 41 | const { ctx } = this 42 | const { name } = ctx.request.body 43 | await ctx.service.activityDataService 44 | .getMobileData(name) 45 | .then(res => { 46 | ctx.body = { 47 | data: res, 48 | code: 200 49 | } 50 | }) 51 | .catch(error => { 52 | ctx.body = { 53 | data: String(error), 54 | code: 500 55 | } 56 | }) 57 | } 58 | } 59 | 60 | module.exports = activityDataController 61 | -------------------------------------------------------------------------------- /app/controller/activityObjectController.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-02-22 12:50:34 4 | * @LastEditTime: 2020-03-20 09:05:30 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/controller/activityObjectController.js 8 | */ 9 | 'use strict' 10 | 11 | const Controller = require('egg').Controller 12 | 13 | class activityObjectController extends Controller { 14 | async getAllObject() { 15 | const { ctx } = this 16 | const data = await ctx.service.activityObjectService.FindAll() 17 | ctx.body = { 18 | data, 19 | code: 200 20 | } 21 | } 22 | async setObject() { 23 | const { ctx } = this 24 | await ctx.service.activityObjectService 25 | .setActivityData(ctx.request.body) 26 | .then(result => { 27 | ctx.body = { 28 | data: result, 29 | code: 200 30 | } 31 | }) 32 | .catch(err => { 33 | ctx.body = { 34 | data: String(err), 35 | code: 500 36 | } 37 | }) 38 | } 39 | // 删除项目 以及组件 40 | async deleteObj() { 41 | const { ctx } = this 42 | await ctx.service.activityObjectService 43 | .deleteObj(ctx.request.body) 44 | .then(data => { 45 | ctx.body = { 46 | data, 47 | code: 200 48 | } 49 | }) 50 | .catch(err => { 51 | ctx.body = { 52 | data: err, 53 | code: 500 54 | } 55 | }) 56 | } 57 | // 更新项目相关信息 58 | async updateObject() { 59 | const { ctx } = this 60 | await ctx.service.activityObjectService 61 | .updateById(ctx.request.body) 62 | .then(result => { 63 | ctx.body = { 64 | data: result, 65 | code: 200 66 | } 67 | }) 68 | .catch(err => { 69 | ctx.body = { 70 | data: String(err), 71 | code: 500 72 | } 73 | }) 74 | } 75 | async objectAuth() { 76 | const { ctx } = this 77 | await ctx.service.activityObjectService 78 | .objectAuth(ctx.request.body) 79 | .then(result => { 80 | ctx.body = { 81 | data: result, 82 | code: 200 83 | } 84 | }) 85 | .catch(err => { 86 | ctx.body = { 87 | data: String(err), 88 | code: 500 89 | } 90 | }) 91 | } 92 | } 93 | 94 | module.exports = activityObjectController 95 | -------------------------------------------------------------------------------- /app/controller/complateController.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-02-22 12:50:34 4 | * @LastEditTime: 2020-03-11 20:38:33 5 | * @LastEditors: your name 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/controller/complateController.js 8 | */ 9 | 'use strict' 10 | 11 | const Controller = require('egg').Controller 12 | 13 | class complateController extends Controller { 14 | async save() { 15 | const { ctx } = this 16 | let { complate } = ctx.request.body 17 | return this.ctx.service.complateDataService 18 | .saveComplate(complate) 19 | .then(res => { 20 | ctx.body = { 21 | data: '保存成功', 22 | code: 200 23 | } 24 | }) 25 | .catch(err => { 26 | console.log(err) 27 | ctx.body = { 28 | data: err, 29 | code: 500 30 | } 31 | }) 32 | } 33 | async getComplate() { 34 | const { ctx } = this 35 | return this.ctx.service.complateDataService 36 | .getComplate() 37 | .then(data => { 38 | ctx.body = { 39 | data: data, 40 | code: 200 41 | } 42 | }) 43 | .catch(err => { 44 | console.log(err) 45 | ctx.body = { 46 | data: err, 47 | code: 500 48 | } 49 | }) 50 | } 51 | async updatesingComp() { 52 | const { ctx } = this 53 | let { id, compName } = ctx.request.body 54 | return this.ctx.service.complateDataService 55 | .updatesingComp(id, compName) 56 | .then(() => { 57 | ctx.body = { 58 | data: '修改成功', 59 | code: 200 60 | } 61 | }) 62 | .catch(err => { 63 | console.log(err) 64 | ctx.body = { 65 | data: err, 66 | code: 500 67 | } 68 | }) 69 | } 70 | async deleteSingComp() { 71 | const { ctx } = this 72 | let { id } = ctx.request.body 73 | return this.ctx.service.complateDataService 74 | .deletesingComp(id) 75 | .then(() => { 76 | ctx.body = { 77 | data: '删除成功', 78 | code: 200 79 | } 80 | }) 81 | .catch(err => { 82 | console.log(err) 83 | ctx.body = { 84 | data: err, 85 | code: 500 86 | } 87 | }) 88 | } 89 | } 90 | 91 | module.exports = complateController 92 | -------------------------------------------------------------------------------- /app/controller/templateController.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-03-11 20:30:30 4 | * @LastEditTime: 2020-03-12 23:33:21 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/controller/templateController.js 8 | */ 9 | 'use strict' 10 | 11 | const Controller = require('egg').Controller 12 | /** 13 | * 模板统一处理控制层 14 | */ 15 | class templateController extends Controller { 16 | // 获取模板列表 17 | async getAllObject() { 18 | const { ctx } = this 19 | const data = await ctx.service.templateObjectService.FindAll() 20 | ctx.body = { 21 | data, 22 | code: 200 23 | } 24 | } 25 | // 保存模板 26 | async setTemplate() { 27 | const { ctx } = this 28 | const { templateId, template } = ctx.request.body 29 | await ctx.service.templateObjectService 30 | .setTemplateData(ctx.request.body) 31 | .then(result => { 32 | // 异步存储模板数据 33 | ctx.service.templateDataService.setTemplateData(templateId, template) 34 | ctx.body = { 35 | data: result, 36 | code: 200 37 | } 38 | }) 39 | .catch(err => { 40 | ctx.body = { 41 | data: String(err), 42 | code: 500 43 | } 44 | }) 45 | } 46 | // 删除项目 以及组件 47 | async deleteTemplate() { 48 | const { ctx } = this 49 | const { id } = ctx.request.body 50 | await ctx.service.templateObjectService 51 | .deleteTemplate(id) 52 | .then(data => { 53 | ctx.body = { 54 | data, 55 | code: 200 56 | } 57 | }) 58 | .catch(err => { 59 | ctx.body = { 60 | data: err, 61 | code: 500 62 | } 63 | }) 64 | } 65 | // 获取模板数据 66 | async getTempData() { 67 | const { ctx } = this 68 | try { 69 | const result = await ctx.service.templateDataService.findById( 70 | ctx.params.id 71 | ) 72 | ctx.body = { 73 | data: result, 74 | code: 200 75 | } 76 | } catch (error) { 77 | ctx.body = { 78 | data: String(error), 79 | code: 500 80 | } 81 | } 82 | } 83 | } 84 | 85 | module.exports = templateController 86 | -------------------------------------------------------------------------------- /app/controller/testController.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Controller = require('egg').Controller; 4 | 5 | class testController extends Controller { 6 | async test() { 7 | const { ctx } = this; 8 | const { cardNo } = ctx.request.body; 9 | ctx.body = { 10 | data: cardNo, 11 | code: 200, 12 | }; 13 | } 14 | } 15 | 16 | module.exports = testController; 17 | -------------------------------------------------------------------------------- /app/model/activityData.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-02-22 12:50:34 4 | * @LastEditTime: 2020-03-13 17:21:43 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/model/activityData.js 8 | */ 9 | 'use strict' 10 | /** 11 | * @param {Egg.model} app - 项目具体布局表 12 | */ 13 | module.exports = app => { 14 | const mongoose = app.mongoose 15 | const Schema = mongoose.Schema 16 | /** 17 | * 项目内部数据模型 18 | */ 19 | const DataSchema = new Schema({ 20 | parentId: { type: String }, // 项目id 21 | parentRouterName: { type: String }, // 项目路由名 22 | activityId: { type: String }, // 组件id 23 | name: { type: String }, // dom元素映射关系 24 | text: { type: String }, // dom元素具体文字 25 | css: { type: Object }, // 样式集合 26 | option: { type: Object }, // 数据集合 27 | animation: { type: Object } // 动画集合 28 | }) 29 | 30 | return mongoose.model('activityData', DataSchema) 31 | } 32 | -------------------------------------------------------------------------------- /app/model/activityObject.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-02-22 12:50:34 4 | * @LastEditTime: 2020-03-19 17:14:47 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/model/activityObject.js 8 | */ 9 | 'use strict' 10 | 11 | /** 12 | * @param {Egg.model} app - 项目表 13 | */ 14 | module.exports = app => { 15 | const mongoose = app.mongoose 16 | const Schema = mongoose.Schema 17 | /** 18 | * 项目表 19 | */ 20 | const ObjectSchema = new Schema({ 21 | textName: { type: String }, // 项目中文名 22 | name: { type: String }, // 项目路由名 23 | titlePage: { type: String }, // 项目缩略图 24 | disp: { type: String }, // 项目描述 25 | height: { type: Number }, // 页面高度 26 | background: { type: String }, // 项目背景色 27 | password: { type: Number }, // 项目密码 28 | time: { type: Number } // 项目创建的时间 29 | }) 30 | return mongoose.model('activityObject', ObjectSchema) 31 | } 32 | -------------------------------------------------------------------------------- /app/model/complateData.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-02-22 12:50:34 4 | * @LastEditTime: 2020-03-18 17:27:15 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/model/complateData.js 8 | */ 9 | 'use strict' 10 | 11 | /** 12 | * @param {Egg.model} app - 项目表 13 | */ 14 | module.exports = app => { 15 | const mongoose = app.mongoose 16 | const Schema = mongoose.Schema 17 | /** 18 | * 插件市场 19 | */ 20 | const complateData = new Schema({ 21 | compName: { type: String }, // 自定义组件名 22 | name: { type: String }, // dom元素映射关系 23 | text: { type: String }, // dom元素具体文字 24 | css: { type: Object }, // 数据 25 | animation: { type: Object } // 动画 26 | }) 27 | return mongoose.model('complateData', complateData) 28 | } 29 | -------------------------------------------------------------------------------- /app/model/templateData.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-02-22 12:50:34 4 | * @LastEditTime: 2020-03-12 09:12:39 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/model/activityData.js 8 | */ 9 | 'use strict' 10 | /** 11 | * @param {Egg.model} app - 项目具体布局表 12 | */ 13 | module.exports = app => { 14 | const mongoose = app.mongoose 15 | const Schema = mongoose.Schema 16 | /** 17 | * 模板数据模型 18 | */ 19 | const DataSchema = new Schema({ 20 | templateId: { type: String }, // 模板名称 21 | activityId: { type: String }, // 组件id 22 | name: { type: String }, // dom元素映射关系 23 | text: { type: String }, // dom元素具体文字 24 | css: { type: Object }, // 样式集合 25 | option: { type: Object }, // 数据集合 26 | animation: { type: Object } // 动画集合 27 | }) 28 | 29 | return mongoose.model('templateData', DataSchema) 30 | } 31 | -------------------------------------------------------------------------------- /app/model/templateObject.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-03-11 11:36:58 4 | * @LastEditTime: 2020-03-12 14:47:44 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/model/templateObject.js 8 | */ 9 | 'use strict' 10 | 11 | /** 12 | * @param {Egg.model} app - 项目表 13 | */ 14 | module.exports = app => { 15 | const mongoose = app.mongoose 16 | const Schema = mongoose.Schema 17 | /** 18 | * 项目数据模型 19 | */ 20 | const ObjectSchema = new Schema({ 21 | templateId: { type: String }, // 模板id 22 | name: { type: String }, // 模板名称 23 | author: { type: String }, // 作者 24 | titlePage: { type: String }, // 项目缩略图 25 | height: { type: Number }, // 页面高度 26 | background: { type: String }, // 项目背景色 27 | time: { type: Number } // 模板创建的时间 28 | }) 29 | return mongoose.model('templateObject', ObjectSchema) 30 | } 31 | -------------------------------------------------------------------------------- /app/router.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-03-01 16:48:52 4 | * @LastEditTime: 2020-03-20 09:06:20 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/router.js 8 | */ 9 | 'use strict' 10 | 11 | /** 12 | * @param {Egg.Application} app - egg application 13 | */ 14 | module.exports = app => { 15 | const { router, controller } = app 16 | // 项目相关接口 17 | router.get('/getObject', controller.activityObjectController.getAllObject) // 获取全部项目 18 | router.post('/setObject', controller.activityObjectController.setObject) // 新建项目 19 | router.post('/deleteObj', controller.activityObjectController.deleteObj) // 删除项目 20 | router.post('/getActivity/:id', controller.activityDataController.getActivity) // 获取项目 21 | router.post('/saveActivity', controller.activityDataController.saveActivity) // 保存/更新项目组件数据 22 | router.post('/getMobileTemp', controller.activityDataController.getMobileData) // 客户端获取接口 23 | router.post('/updateObj', controller.activityObjectController.updateObject) // 更新项目表数据 24 | router.post('/objectAuth', controller.activityObjectController.objectAuth) // 效验项目权限 25 | // 图片 26 | router.post('/upimage', controller.imageController.upload) // 上传图片接口 27 | router.post('/uptitleimage', controller.imageController.uptitleimage) // 上传封面图片接口 28 | router.get('/getImage', controller.imageController.getImage) // 获取图片接口 29 | router.get('/getDefaultImg', controller.imageController.getDefaultImg) // 获取推荐图片接口 30 | // 插件相关接口 31 | router.post('/saveSingleComplate', controller.complateController.save) // 保存单个插件 32 | router.get('/getSingleComplate', controller.complateController.getComplate) // 获取插件列表 33 | router.post('/updateSingComp', controller.complateController.updatesingComp) // 修改插件名称 34 | router.post('/deleteSingComp', controller.complateController.deleteSingComp) // 删除插件 35 | // 模板相关接口 36 | router.get('/getTemplate', controller.templateController.getAllObject) // 获取全部模板 37 | router.post('/setTemplate', controller.templateController.setTemplate) // 存储模板 38 | router.get( 39 | '/getTemplateDataById/:id', 40 | controller.templateController.getTempData 41 | ) // 获取模板数据 42 | router.post('/deleteTemplate', controller.templateController.deleteTemplate) // 删除模板 43 | // 测试域名 44 | router.post('/test', controller.testController.test) 45 | } 46 | -------------------------------------------------------------------------------- /app/service/activityDataService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-03-01 16:48:58 4 | * @LastEditTime: 2020-03-20 14:44:28 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/service/activityDataService.js 8 | */ 9 | 'use strict' 10 | 11 | const Service = require('egg').Service 12 | 13 | class activityDataService extends Service { 14 | /** 15 | * 回显数据 16 | * @param {string} objectName 项目名 17 | */ 18 | async findById(parentId) { 19 | let object = await this.ctx.model.ActivityObject.find({ 20 | _id: parentId 21 | }) 22 | if (object.length > 0) { 23 | let data = await this.ctx.model.ActivityData.find({ parentId }) 24 | console.log(JSON.parse(JSON.stringify(object))) 25 | object = JSON.parse(JSON.stringify(object)) 26 | object.map(res => { 27 | if (res.password) { 28 | res.isAuth = true 29 | } else { 30 | res.isAuth = false 31 | } 32 | delete res.password 33 | }) 34 | return { ...object[0], data } 35 | } 36 | return Promise.reject(Error('无此项目,请检查项目名')) 37 | } 38 | /** 39 | * 移动端获取数据 包括组件数据 以及页面高度 40 | * @param {string} name 项目名称 41 | */ 42 | async getMobileData(name) { 43 | const object = await this.ctx.model.ActivityObject.find({ name }) 44 | if (object.length > 0) { 45 | const data = await this.ctx.model.ActivityData.find({ 46 | parentRouterName: name 47 | }) 48 | const objData = { 49 | objHeight: object[0].height, 50 | background: object[0].background, 51 | textName: object[0].textName 52 | } 53 | return Promise.resolve({ ...objData, datas: data }) 54 | } 55 | return Promise.reject(new Error('无此项目,请检查项目名')) 56 | } 57 | // 更新项目数据 58 | async setActivityData(data) { 59 | const { 60 | titlePage, 61 | password, 62 | parentId, 63 | parentName, 64 | parentRouterName, 65 | commHeight, 66 | template, 67 | background, 68 | parentDisp 69 | } = data 70 | let objectData = await this.ctx.model.ActivityObject.findOne({ 71 | _id: parentId 72 | }) 73 | // 效验密码 74 | if (objectData.password == null || objectData.password == password) { 75 | // 更新项目数据 76 | await this.ctx.model.ActivityObject.update( 77 | { _id: parentId }, 78 | { 79 | height: commHeight, 80 | background, 81 | titlePage, 82 | textName: parentName, 83 | name: parentRouterName, 84 | disp: parentDisp 85 | } 86 | ) 87 | // 删除项目之前的数据 88 | await this.ctx.model.ActivityData.remove({ parentId: parentId }) 89 | const newData = [] 90 | template.map(temp => { 91 | newData.push({ 92 | parentId: parentId, 93 | parentRouterName: parentRouterName, 94 | ...temp 95 | }) 96 | return true 97 | }) 98 | // 更新项目组件数据 99 | return await this.ctx.model.ActivityData.create(newData).then( 100 | () => parentRouterName // 将项目名称返回出去 101 | ) 102 | } else { 103 | return Promise.reject(new Error('密码错误不允许修改')) 104 | } 105 | } 106 | } 107 | 108 | module.exports = activityDataService 109 | -------------------------------------------------------------------------------- /app/service/activityObjectService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-02-22 12:50:34 4 | * @LastEditTime: 2020-03-20 09:20:59 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/service/activityObjectService.js 8 | */ 9 | 'use strict' 10 | 11 | const Service = require('egg').Service 12 | 13 | class activityObjectService extends Service { 14 | /** 15 | * 查询全部项目 16 | */ 17 | async FindAll() { 18 | let objetcList = await this.ctx.model.ActivityObject.find({}) 19 | objetcList = JSON.parse(JSON.stringify(objetcList)) 20 | objetcList.map((res, index) => { 21 | if (res.password) { 22 | res.isAuth = true 23 | } else { 24 | res.isAuth = false 25 | } 26 | delete res.password 27 | }) 28 | return objetcList 29 | } 30 | /** 31 | * 新建项目 32 | * @param {String} name 33 | * @param {String} disp 34 | * @param {Number} height 35 | * @param {String} background 36 | * @param {String} textName 37 | */ 38 | async setActivityData(data) { 39 | const ActivityList = await this.ctx.model.ActivityObject.find({ 40 | name: data.name 41 | }) 42 | 43 | if (ActivityList.length > 0) { 44 | return Promise.reject(new Error('当前项目已经存在')) 45 | } 46 | return await this.ctx.model.ActivityObject.create({ 47 | ...data, 48 | height: 667, 49 | background: 'rgba(255, 255, 255, 1)', 50 | time: new Date().getTime() 51 | }).then(data => { 52 | return data._id 53 | }) 54 | } 55 | /** 56 | * 更新项目数据 57 | */ 58 | async updateById(data) { 59 | const { 60 | objectId, 61 | height, 62 | background, 63 | textName, 64 | name, 65 | titlePage, 66 | parentDisp 67 | } = data 68 | try { 69 | let res = await this.ctx.model.ActivityObject.findOne({ name }) 70 | if (res == null || res._id == objectId) { 71 | await this.ctx.model.ActivityObject.update( 72 | { _id: objectId }, 73 | { height, background, titlePage, textName, name, disp: parentDisp } 74 | ) 75 | return '更新项目成功' 76 | } else { 77 | return Promise.reject(new Error('路由名称重复,请修改路由名')) 78 | } 79 | } catch (err) { 80 | return err 81 | } 82 | } 83 | /** 84 | * 项目效验 85 | * @param {String}} pass 86 | */ 87 | async objectAuth(data) { 88 | let objectData = await this.ctx.model.ActivityObject.findOne({ 89 | _id: data.id 90 | }) 91 | if (objectData.password == data.password) { 92 | return true 93 | } else { 94 | return Promise.reject(new Error('密码错误')) 95 | } 96 | } 97 | /** 98 | * 删除项目 99 | * @param {String} data // 包含项目id与密码 100 | */ 101 | async deleteObj(data) { 102 | let { id, password } = data 103 | try { 104 | let objectData = await this.ctx.model.ActivityObject.findOne({ _id: id }) 105 | console.log(objectData, password) 106 | if (objectData.password == null || objectData.password == password) { 107 | await this.ctx.model.ActivityObject.remove({ _id: id }) 108 | await this.ctx.model.ActivityData.remove({ parentId: id }) 109 | return '删除成功' 110 | } else { 111 | return Promise.reject(new Error('密码错误')) 112 | } 113 | } catch (err) { 114 | return err 115 | } 116 | } 117 | } 118 | 119 | module.exports = activityObjectService 120 | -------------------------------------------------------------------------------- /app/service/complateDataService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-02-22 12:50:34 4 | * @LastEditTime: 2020-03-18 17:27:57 5 | * @LastEditors: your name 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/service/complateDataService.js 8 | */ 9 | 'use strict' 10 | 11 | const Service = require('egg').Service 12 | 13 | class complateDataService extends Service { 14 | // 保存单个组件 15 | async saveComplate(data) { 16 | if (data.compName == '') { 17 | return Promise.reject('请填写组件保存名') 18 | } 19 | let isexist = await this.ctx.model.ComplateData.find({ 20 | compName: data.compName 21 | }) 22 | if (isexist.length > 0) { 23 | return Promise.reject('该组件名已经存在') 24 | } 25 | return await this.ctx.model.ComplateData.create(data) 26 | } 27 | async getComplate() { 28 | return await this.ctx.model.ComplateData.find() 29 | } 30 | async updatesingComp(id, name) { 31 | return await this.ctx.model.ComplateData.update( 32 | { _id: id }, 33 | { compName: name } 34 | ) 35 | } 36 | async deletesingComp(id) { 37 | return await this.ctx.model.ComplateData.deleteOne({ 38 | _id: id 39 | }) 40 | } 41 | } 42 | 43 | module.exports = complateDataService 44 | -------------------------------------------------------------------------------- /app/service/templateDataService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-03-11 20:23:20 4 | * @LastEditTime: 2020-03-12 20:52:49 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/service/templateDataService.js 8 | */ 9 | 'use strict' 10 | 11 | const Service = require('egg').Service 12 | 13 | class templateDataService extends Service { 14 | /** 15 | * 回显数据 16 | * @param {string} templateId 模板id 17 | */ 18 | async findById(templateId) { 19 | const data = await this.ctx.model.TemplateData.find({ templateId }) 20 | return Promise.resolve(data) 21 | } 22 | // 保存模板数据 23 | async setTemplateData(templateId, template) { 24 | const newData = [] 25 | template.map(data => { 26 | newData.push({ 27 | templateId: templateId, 28 | ...data 29 | }) 30 | }) 31 | return await this.ctx.model.TemplateData.create(newData).then( 32 | () => templateId // 将项目名称返回出去 33 | ) 34 | } 35 | } 36 | 37 | module.exports = templateDataService 38 | -------------------------------------------------------------------------------- /app/service/templateObjectService.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @Author: your name 3 | * @Date: 2020-03-11 20:19:39 4 | * @LastEditTime: 2020-03-12 23:27:11 5 | * @LastEditors: Please set LastEditors 6 | * @Description: In User Settings Edit 7 | * @FilePath: /activity_server/app/service/templateObjectService.js 8 | */ 9 | 'use strict' 10 | 11 | const Service = require('egg').Service 12 | 13 | class templateObjectService extends Service { 14 | /** 15 | * 查询全部项目 16 | */ 17 | async FindAll() { 18 | return await this.ctx.model.TemplateObject.find({}, { _id: 0, __v: 0 }) 19 | } 20 | /** 21 | * 保存模板 22 | * @param {String} name 23 | * @param {Number} height 24 | * @param {String} background 25 | */ 26 | async setTemplateData(data) { 27 | const TemplateList = await this.ctx.model.TemplateObject.find({ 28 | name: data.name 29 | }) 30 | if (TemplateList.length > 0) { 31 | return Promise.reject(new Error('当前项目已经存在')) 32 | } 33 | return await this.ctx.model.TemplateObject.create({ 34 | ...data, 35 | time: new Date().getTime() 36 | }).then(() => { 37 | return '模板创建完成' 38 | }) 39 | } 40 | /** 41 | * 删除模板 42 | * @param {number} id 43 | */ 44 | async deleteTemplate(id) { 45 | try { 46 | console.log(id); 47 | await this.ctx.model.TemplateObject.remove({ templateId: id }) 48 | await this.ctx.model.TemplateData.remove({ templateId: id }) 49 | return '删除成功' 50 | } catch (err) { 51 | return err 52 | } 53 | } 54 | } 55 | 56 | module.exports = templateObjectService 57 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /config/config.default.js: -------------------------------------------------------------------------------- 1 | /* eslint valid-jsdoc: "off" */ 2 | 'use strict'; 3 | const path = require('path'); 4 | /** 5 | * @param {Egg.EggAppInfo} appInfo app info 6 | */ 7 | module.exports = appInfo => { 8 | /** 9 | * built-in config 10 | * @type {Egg.EggAppConfig} 11 | **/ 12 | const config = (exports = {}); 13 | 14 | // use for cookie sign key, should change to your own and keep security 15 | config.keys = appInfo.name + '_1569044743364_2123'; 16 | 17 | // add your middleware config here 18 | config.middleware = []; 19 | 20 | // add your user config here 21 | const userConfig = {}; 22 | config.cors = { 23 | origin: '*', 24 | allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH,OPTIONS', 25 | }; 26 | 27 | config.security = { 28 | csrf: { 29 | enable: false, 30 | }, 31 | domainWhiteList: ['http://localhost:8080'], 32 | }; 33 | exports.mongoose = { 34 | client: { 35 | url: 'mongodb://127.0.0.1/activityData', 36 | options: {}, 37 | }, 38 | }; 39 | config.static = { 40 | prefix: '/static/', 41 | dir: path.join(appInfo.baseDir, 'app/static'), 42 | dynamic: true, 43 | preload: false, 44 | maxAge: 31536000, 45 | buffer: false, 46 | }; 47 | return { 48 | ...config, 49 | ...userConfig, 50 | }; 51 | }; 52 | -------------------------------------------------------------------------------- /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 | // }; 10 | exports.cors = { 11 | enable: true, 12 | package: 'egg-cors', 13 | }; 14 | exports.mongoose = { 15 | enable: true, 16 | package: 'egg-mongoose', 17 | }; 18 | /** @type Egg.EggPlugin */ 19 | exports.nunjucks = { 20 | enable: true, 21 | package: 'egg-view-nunjucks', 22 | }; 23 | 24 | exports.static = true; 25 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "**/*" 4 | ] 5 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "description": "", 5 | "private": true, 6 | "egg": { 7 | "declarations": true 8 | }, 9 | "dependencies": { 10 | "egg": "^2.15.1", 11 | "egg-cors": "^2.2.0", 12 | "egg-mongoose": "^3.2.0", 13 | "egg-scripts": "^2.11.0", 14 | "egg-static": "^2.2.0", 15 | "egg-view-nunjucks": "^2.2.0", 16 | "stream-wormhole": "^1.1.0" 17 | }, 18 | "devDependencies": { 19 | "autod": "^3.0.1", 20 | "autod-egg": "^1.1.0", 21 | "egg-bin": "^4.13.1", 22 | "egg-ci": "^1.11.0", 23 | "egg-mock": "^3.21.0", 24 | "eslint": "^5.13.0", 25 | "eslint-config-egg": "^7.1.0" 26 | }, 27 | "engines": { 28 | "node": ">=10.0.0" 29 | }, 30 | "scripts": { 31 | "start": "egg-scripts start --daemon --title=egg-server-example", 32 | "stop": "egg-scripts stop --title=egg-server-example", 33 | "dev": "egg-bin dev", 34 | "debug": "egg-bin debug", 35 | "test": "npm run lint -- --fix && npm run test-local", 36 | "test-local": "egg-bin test", 37 | "cov": "egg-bin cov", 38 | "lint": "eslint .", 39 | "ci": "npm run lint && npm run cov", 40 | "autod": "autod" 41 | }, 42 | "ci": { 43 | "version": "10" 44 | }, 45 | "repository": { 46 | "type": "git", 47 | "url": "" 48 | }, 49 | "author": "", 50 | "license": "MIT" 51 | } 52 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------