diff --git a/app.js b/app.js index 4ad5263..349d8f1 100644 --- a/app.js +++ b/app.js @@ -1,4 +1,4 @@ -const app = new require('koa')() +const app = new (require('koa'))() app.use(require('koa-body')({multipart: true})) app.use(require('koa2-cors')()) @@ -10,7 +10,7 @@ app.use(require('./src/middleware/paramHandler')) app.use(require('./src/middleware/useridHandler')) app.use(require('./src/router').routes()).use(require('./src/router').allowedMethods()) -const config = require('./src/config/env') +const config = require('./config/env') const server = app.listen(config.server.port) require('./src/log/realtime').init(app.listen(config.server.log.port)) diff --git a/src/config/dev.toml b/config/dev.toml similarity index 77% rename from src/config/dev.toml rename to config/dev.toml index 2289935..f866289 100644 --- a/src/config/dev.toml +++ b/config/dev.toml @@ -4,7 +4,7 @@ port = 3000 port = 4000 # 实时日志的端口 [db] -host = 'mongodb://localhost/projectname' +host = 'mongodb://localhost/bloodbrone-koa2' [site.auth] host = '' # todo 自行加入其它配置,如外接其它服务器 diff --git a/config/env.js b/config/env.js new file mode 100644 index 0000000..106ea9c --- /dev/null +++ b/config/env.js @@ -0,0 +1,3 @@ +process.env.NODE_ENV = 'dev' + +module.exports = require('../src/util/readToml')(`/config/${process.env.NODE_ENV}.toml`) \ No newline at end of file diff --git a/src/config/prod.toml b/config/prod.toml similarity index 100% rename from src/config/prod.toml rename to config/prod.toml diff --git a/src/config/env.js b/src/config/env.js deleted file mode 100644 index dc563ca..0000000 --- a/src/config/env.js +++ /dev/null @@ -1,8 +0,0 @@ -process.env.NODE_ENV = 'dev' - -module.exports = require('toml').parse( - require('fs').readFileSync( - require('path').join(__dirname, `./${process.env.NODE_ENV}.toml`), - 'utf-8' - ) -) \ No newline at end of file diff --git a/src/controller/bb/weaponController.js b/src/controller/bb/weaponController.js new file mode 100644 index 0000000..3cb570e --- /dev/null +++ b/src/controller/bb/weaponController.js @@ -0,0 +1,41 @@ +const Router = require('koa-router') +const router = new Router() + +const service = require('../../service/weaponService') +const valid = require('../../valid') + +router.post('/bb/weapon', async(ctx, next) => { + let e = { + name: ctx.params.name, + phy: ctx.params.phy || 0, + bld: ctx.params.bld || 0, + } + valid.string('weapon.name', e.name).is().lengthIn(1, 20) + valid.number('weapon.phy', e.phy).is().in(500) + valid.number('weapon.bld', e.bld).is().in(500) + e = await service.save(e) + ctx.ok(e._id) +}) + +router.delete('/bb/weapon/:_id', async(ctx, next) => { + let e = { + _id: ctx.params._id, + } + await service.delete(e) + ctx.ok() +}) + +router.put('/bb/weapon/:_id', async(ctx, next) => { + let e = { + _id: ctx.params._id, + name: ctx.params.name, + phy: ctx.params.phy, + bld: ctx.params.bld, + } + if (e.name) valid.string('weapon.name', e.name).is().lengthIn(1, 20) + if (e.phy) valid.number('weapon.phy', e.phy).is().in(500) + if (e.bld) valid.number('weapon.bld', e.bld).is().in(500) + await service.update(e) + ctx.ok() +}) +module.exports = router \ No newline at end of file diff --git a/src/controller/everyone/weaponController.js b/src/controller/everyone/weaponController.js new file mode 100644 index 0000000..81da2db --- /dev/null +++ b/src/controller/everyone/weaponController.js @@ -0,0 +1,30 @@ +const Router = require('koa-router') +const router = new Router() + +const service = require('../../service/weaponService') + +router.get('/weapon/:_id', async(ctx, next) => { + let e = { + _id: ctx.params._id + } + let weapon = await service.findById(e) + ctx.ok(weapon) +}) +router.get('/weapon/count', async(ctx, next) => { + let filter = { + name: ctx.params.name || '', + } + let count = await service.count(filter) + ctx.ok(count) +}) +router.get('/weapon', async(ctx, next) => { + let filter = { + name: ctx.params.name || '', + start: parseInt(ctx.params.start) || 0, + limit: parseInt(ctx.params.limit) || 10 + } + let list = await service.find(filter) + ctx.ok(list) +}) + +module.exports = router \ No newline at end of file diff --git a/src/controller/xController.js b/src/controller/xController.js deleted file mode 100644 index 362888b..0000000 --- a/src/controller/xController.js +++ /dev/null @@ -1,36 +0,0 @@ -const Router = require('koa-router') -const router = new Router() - -const service = require('../service/xService') -const valid = require('../valid') - -const fetch = require('../fetch') -const config = require('../config/env') - -router.post('/xxx', async(ctx, next) => { - let e = { - userid: ctx.params.userid, - name: ctx.params.name, - age: ctx.params.age, - } - valid.string('xxx.userid', e.userid).is().mongoId() - valid.number('xxx.age', e.age).is().in(100) - valid.string('xxx.name', e.name).is().lengthIn(1, 20) - e = await service.save(e) - ctx.ok(e._id) -}) - -router.put('/xxx', async(ctx, next) => { - let e = { - _id: ctx.params._id, - name: ctx.params.name, - } - if (!e.name) { - let rest = await fetch(`${config.site.other1}/api/user/${e._id}`, {headers: {apikey: config.site.other1.apikey}}) - e.name = rest.data.name - } - let success = await service.update(e) - ctx.ok(success) -}) - -module.exports = router \ No newline at end of file diff --git a/src/db/index.js b/src/db/index.js new file mode 100644 index 0000000..b0af666 --- /dev/null +++ b/src/db/index.js @@ -0,0 +1,9 @@ +const config = require('../../config/env') +const mongoose = require('mongoose') + +module.exports = { + drop: async () => { + await mongoose.connect(config.db.host, {useNewUrlParser: true}) + mongoose.connection.db.dropDatabase() + } +} diff --git a/src/error/createRestAndLog.js b/src/error/createRestAndLog.js index cb33c61..a23af30 100644 --- a/src/error/createRestAndLog.js +++ b/src/error/createRestAndLog.js @@ -1,5 +1,5 @@ const log = require('../log') -module.exports = async (err) => { +module.exports = (err) => { let result = {} switch (err.name) { case 'PARAM': diff --git a/src/log/index.js b/src/log/index.js index a71d8aa..8c34051 100644 --- a/src/log/index.js +++ b/src/log/index.js @@ -29,23 +29,23 @@ log4js.configure({ module.exports = { c: (name, v) => { - log4js.getLogger(name).debug(format(v)) + log4js.getLogger(JSON.stringify(name)).debug(format(v)) realtime.send(name, v) }, d: (name, v) => { - log4js.getLogger(name).debug(format(v)) + log4js.getLogger(JSON.stringify(name)).debug(format(v)) realtime.send(name, v) }, i: (name, v) => { - log4js.getLogger(name).info(format(v)) + log4js.getLogger(JSON.stringify(name)).info(format(v)) realtime.send(name, v) }, w: (name, v) => { - log4js.getLogger(name).warn(format(v)) + log4js.getLogger(JSON.stringify(name)).warn(format(v)) realtime.send(name, v) }, e: (name, v) => { - log4js.getLogger(name).error(format(v)) + log4js.getLogger(JSON.stringify(name)).error(format(v)) realtime.send(name, v) }, } diff --git a/src/middleware/errorHandler.js b/src/middleware/errorHandler.js index f0f3c42..6b98b81 100644 --- a/src/middleware/errorHandler.js +++ b/src/middleware/errorHandler.js @@ -2,8 +2,8 @@ const createRestAndLog = require('../error/createRestAndLog') module.exports = async (ctx, next) => { try { await next() - } catch(err) { - let rest = createRestAndLog(err) + } catch(err) { + let rest = createRestAndLog(err) ctx.body = rest } } \ No newline at end of file diff --git a/src/model/weapon.js b/src/model/weapon.js new file mode 100644 index 0000000..89243e3 --- /dev/null +++ b/src/model/weapon.js @@ -0,0 +1,4 @@ +const mongoose = require('mongoose') +const model = mongoose.model('weapon', {name: String, phy: Number, bld: Number}) +model.null = {isNull: true} +module.exports = model \ No newline at end of file diff --git a/src/model/xxx.js b/src/model/xxx.js deleted file mode 100644 index d0408ca..0000000 --- a/src/model/xxx.js +++ /dev/null @@ -1,4 +0,0 @@ -const mongoose = require('mongoose') -const model = mongoose.model('xxx', {name: String, age: Number}) - -module.exports = model \ No newline at end of file diff --git a/src/router/index.js b/src/router/index.js index d23e94c..fbbdead 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -1,7 +1,10 @@ const Router = require('koa-router') const router = new Router() -const xController = require('./controller/xController') -router.use('', xController.routes(), xController.allowedMethods()) +const bbWeaponController = require('../controller/bb/weaponController') +router.use('', bbWeaponController.routes(), bbWeaponController.allowedMethods()) + +const weaponController = require('../controller/everyone/weaponController') +router.use('', weaponController.routes(), weaponController.allowedMethods()) module.exports = router \ No newline at end of file diff --git a/src/service/weaponService.js b/src/service/weaponService.js new file mode 100644 index 0000000..e08d71e --- /dev/null +++ b/src/service/weaponService.js @@ -0,0 +1,32 @@ +const model = require('../model/weapon') +const failError = require('../error/failError') + +module.exports = { + save: async(e) => { + let exists = await model.findOne({name: e.name}, '-__v') + if (exists) { + throw new failError('data exists') + } + e = new model(e) + await e.save() + return e + }, + delete: async(e) => { + await model.deleteOne({_id: new model(e).id}) + }, + update: async(e) => { + let exists = await model.findOne({_id: e._id}, '-__v') + let next = new model({...exists, ...e}) + await next.updateOne(next) + }, + findById: async(e) => { + return await model.findOne({_id: e._id}, '-__v') || model.null + }, + count: async(filter) => { + return await model.countDocuments({name: {$regex: `${filter.name}.*`}}) + }, + find: async(filter) => { + let result = await model.find({name: {$regex: `${filter.name}.*`}}, '-__v').skip(filter.start).limit(filter.limit).sort('name') + return result + } +} \ No newline at end of file diff --git a/src/service/xService.js b/src/service/xService.js deleted file mode 100644 index 0837d47..0000000 --- a/src/service/xService.js +++ /dev/null @@ -1,23 +0,0 @@ -const model = require('../model/xxx') -const failError = require('../error/failError') - -module.exports = { - save: async(e) => { - let exists = await model.findOne({name: e.name}, '-__v') - if (exists) { - throw new failError('data exists') - } - e = new model(e) - await e.save() - return e - }, - update: async(e) => { - let exists = await model.findOne({_id: e._id}, '-__v') - if (!exists) { - throw new failError('data not exists') - } - exists.name = e.name || exists.name - await exists.updateOne(exists) - return true - } -} \ No newline at end of file diff --git a/src/util/readToml.js b/src/util/readToml.js new file mode 100644 index 0000000..8dbc5f0 --- /dev/null +++ b/src/util/readToml.js @@ -0,0 +1,10 @@ + +module.exports = (pathFromProjectRoot) => { + let result = require('toml').parse( + require('fs').readFileSync( + require('path').join(__dirname, '../../', pathFromProjectRoot), + 'utf-8' + ) + ) + return result +} \ No newline at end of file diff --git a/src/valid/validString.js b/src/valid/validString.js index f65b7bd..106f4fd 100644 --- a/src/valid/validString.js +++ b/src/valid/validString.js @@ -26,7 +26,7 @@ class validString { return this } mongoId() { - if (this.v.length < 15 || this.v.length > 30) throw new paramError(`${this.name}: ${this.v}, must be mongodb id`) + if ((this.v.length === 24 || this.v.length === 12) && isNaN(parseInt(this.v,16))!== true) throw new paramError(`${this.name}: ${this.v}, must be mongodb id`) return this } of(list) { diff --git a/tests/data/operator.js b/tests/data/operator.js new file mode 100644 index 0000000..c2d8db0 --- /dev/null +++ b/tests/data/operator.js @@ -0,0 +1,7 @@ +const weaponOperator = require('./weapon/operator') + +module.exports = { + saveWeapon: () => { + weaponOperator.save() + } +} \ No newline at end of file diff --git a/tests/data/weapon/data.toml b/tests/data/weapon/data.toml new file mode 100644 index 0000000..a799a7e --- /dev/null +++ b/tests/data/weapon/data.toml @@ -0,0 +1,8 @@ +[[list]] + name = 'Chikage' + phy = 92 + bld = 92 +[[list]] + name = 'Rakuyo' + phy = 82 + bld = 0 diff --git a/tests/data/weapon/operator.js b/tests/data/weapon/operator.js new file mode 100644 index 0000000..6db0de0 --- /dev/null +++ b/tests/data/weapon/operator.js @@ -0,0 +1,15 @@ +const model = require('../../../src/model/weapon') + +module.exports = { + save: () => { + let data = require('toml').parse( + require('fs').readFileSync( + require('path').join(__dirname, './data.toml'), + 'utf-8' + ) + ) + data.list.forEach(async e => { + await new model(e).save() + }) + } +} \ No newline at end of file diff --git a/tests/rest/weapon.spec.js b/tests/rest/weapon.spec.js new file mode 100644 index 0000000..a6f1b46 --- /dev/null +++ b/tests/rest/weapon.spec.js @@ -0,0 +1,74 @@ +const {expect} = require('chai') +const fetch = require('../../src/fetch') +const config = require('../../config/env') +const host = `http://localhost:${config.server.port}` +const db = require('../../src/db') +const operator = require('../data/operator') + +describe('weapon controller', () => { + it('save, delete', async() => { + let rest = await fetch(`${host}/bb/weapon`, {method: 'post', body: 'name=chikage2&phy=92'}) + expect(rest.code).to.be.deep.equal('SUCCESS') + let _id = rest.data + rest = await fetch(`${host}/bb/weapon/${_id}`, {method: 'delete', }) + expect(rest.code).to.be.deep.equal('SUCCESS') + }) + + it('list', async() => { + let rest = await fetch(`${host}/weapon`) + expect(rest.code).to.be.deep.equal('SUCCESS') + expect(rest.data.length).to.be.deep.equal(2) + }) + + it('findById, update', async() => { + let rest = await fetch(`${host}/weapon`) + let _id = rest.data[0]._id + let name = rest.data[0].name + + rest = await fetch(`${host}/weapon/${_id}`) + expect(rest.code).to.be.deep.equal('SUCCESS') + expect(rest.data.name).to.be.deep.equal(name) + rest = await fetch(`${host}/bb/weapon/${_id}`, {method: 'put', body: 'name=Chikage2'}) + expect(rest.code).to.be.deep.equal('SUCCESS') + + rest = await fetch(`${host}/weapon/${_id}`) + expect(rest.data.name).to.be.deep.equal('Chikage2') + expect(rest.data.phy).to.be.deep.equal(92) + + await fetch(`${host}/bb/weapon/${_id}`, {method: 'put', body: `name=${name}`}) + }) + + it('findById: not exists', async() => { + let rest = await fetch(`${host}/weapon/537eed02ed345b2e039652d5`) + expect(rest.code).to.be.deep.equal('SUCCESS') + expect(rest.data.name).to.be.not.ok + }) + it('save FAIL: name exists', async() => { + let rest = await fetch(`${host}/bb/weapon`, {method: 'post', body: 'name=Chikage&phy=92'}) + expect(rest.code).to.be.deep.equal('FAIL') + }) + it('save FAIL: name too long', async() => { + let rest = await fetch(`${host}/bb/weapon`, {method: 'post', body: 'name=chikagea23s1df23a1s32df1sad5fv1sa856v1sa38e13f51a5seg13ad5s1g352sad153&phy=92'}) + expect(rest.code).to.be.deep.equal('PARAM') + }) + it('update FAIL: name too long', async() => { + let rest = await fetch(`${host}/weapon`) + let _id = rest.data[0]._id + rest = await fetch(`${host}/bb/weapon/${_id}`, {method: 'put', body: 'name=chikagea23s1df23a1s32df1sad5fv1sa856v1sa38e13f51a5seg13ad5s1g352sad153'}) + expect(rest.code).to.be.deep.equal('PARAM') + }) + it('update FAIL: phy too large', async() => { + let rest = await fetch(`${host}/weapon`) + let _id = rest.data[0]._id + rest = await fetch(`${host}/bb/weapon/${_id}`, {method: 'put', body: 'phy=6000'}) + expect(rest.code).to.be.deep.equal('PARAM') + }) + + before(async() => { + await db.drop() + operator.saveWeapon() + }) + after(async() => { + await db.drop() + }) +}) \ No newline at end of file