Skip to content

Commit 797b6ea

Browse files
committed
mock 服务器已经开通了
1 parent 5d84c3e commit 797b6ea

14 files changed

+963
-42
lines changed

babel.config.js

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
1+
/*
2+
* @Description:
3+
* @Author: ZY
4+
* @Date: 2020-12-07 10:30:20
5+
* @LastEditors: ZY
6+
* @LastEditTime: 2020-12-09 16:08:21
7+
*/
18
module.exports = {
29
presets: [
310
'@vue/cli-plugin-babel/preset'
4-
]
11+
],
12+
env: {
13+
development: {
14+
// babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
15+
// This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
16+
// https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
17+
plugins: ['dynamic-import-node']
18+
}
19+
}
520
}

mock/constant.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const BASE_PATH_MAP = Symbol('path_map');
2+
export const ROUTER_MAP = Symbol('route_map');

mock/controller/test.ts

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* @Description:
3+
* @Author: ZY
4+
* @Date: 2020-12-10 11:29:27
5+
* @LastEditors: ZY
6+
* @LastEditTime: 2020-12-10 11:35:58
7+
*/
8+
import { get, prefix} from '../requestDecorator';
9+
import { Context } from 'koa';
10+
11+
@prefix('/main')
12+
export default class Test {
13+
14+
/**
15+
* 检查jwt是否有效
16+
* @param ctx Context
17+
*/
18+
@get('/test')
19+
async test() {
20+
return 'ok hahaha2222222'
21+
}
22+
23+
24+
/**
25+
* 检查jwt是否有效
26+
* @param ctx Context
27+
*/
28+
@get('/check')
29+
async checkJwt(ctx: Context) {
30+
ctx.body = {
31+
code: 0,
32+
msg: '登录有效'
33+
};
34+
}
35+
}

mock/middleware/resultHandler.ts

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* @Description:
3+
* @Autor: ZY
4+
* @Date: 2020-11-11 13:59:28
5+
* @LastEditors: ZY
6+
* @LastEditTime: 2020-12-10 14:22:58
7+
*/
8+
import log from '../utils/logger'
9+
import { MiddleWare } from '../type'
10+
11+
export type ResultInfo = {
12+
code:number;
13+
msg?:string;
14+
data?:any;
15+
err?:any
16+
}
17+
18+
/**
19+
* 执行结果 handler 用来给每个响应对象包装响应码等
20+
*/
21+
export const ResultHandler: MiddleWare = () => async (ctx, next) => {
22+
const r :ResultInfo= {code:0};
23+
try {
24+
const data:any = await next();
25+
r.code = 200;
26+
r.data = data;
27+
} catch (err) {
28+
log.error(err);
29+
30+
r.code = -1;
31+
r.msg = "系统错误";
32+
if (ctx.app.env === 'development') {
33+
r.msg = err.message;
34+
r.err = err;
35+
}
36+
}
37+
ctx.body = r;
38+
};

mock/mock.ts

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* @Description:
3+
* @Author: ZY
4+
* @Date: 2020-12-09 17:02:35
5+
* @LastEditors: ZY
6+
* @LastEditTime: 2020-12-10 15:13:35
7+
*/
8+
9+
import Koa, { Context } from "koa";
10+
import koaBody from "koa-body";
11+
import koaRouter from "koa-router";
12+
import addRouter from "./router";
13+
import logger from "koa-logger";
14+
import log4js from "log4js";
15+
import {ResultHandler} from './middleware/resultHandler'
16+
import chalk from "chalk";
17+
18+
const app = new Koa();
19+
const router = new koaRouter();
20+
21+
const port = 3000;
22+
const log4 = log4js.getLogger();
23+
log4.level = "debug";
24+
//日志打印
25+
app.use(logger(info => {
26+
log4.debug(info);
27+
}));
28+
app.use( async (ctx,next)=>{
29+
await next()
30+
// log4.debug(chalk.green('请求路径: ') + ctx.request.url);
31+
log4.debug(chalk.green('请求body: ') + JSON.stringify(ctx.request.body));
32+
log4.debug(chalk.green('返回数据: ')+ JSON.stringify(ctx.body));
33+
})
34+
app.use(koaBody());
35+
36+
app.use(ResultHandler());
37+
38+
//加载路由
39+
addRouter(router);
40+
//启动路由
41+
app.use(router.routes()).use(router.allowedMethods());
42+
43+
app.use(async (ctx: Context) => {
44+
log4.error(`404 ${ctx.message} : ${ctx.href}`);
45+
ctx.status = 404;
46+
ctx.body = "404! api not found !";
47+
});
48+
49+
// koa already had middleware to deal with the error, just register the error event
50+
app.on("error", (err, ctx: Context) => {
51+
log4.error(err); //log all errors
52+
ctx.status = 500;
53+
if (ctx.app.env !== "development") {
54+
//throw the error to frontEnd when in the develop mode
55+
ctx.res.end(err.stack); //finish the response
56+
}
57+
});
58+
59+
app.listen(port, () => {
60+
log4.debug("mock server running at: http://localhost:%d", port);
61+
});

mock/requestDecorator.ts

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import 'reflect-metadata'
2+
import { ROUTER_MAP ,BASE_PATH_MAP} from './constant'
3+
4+
/**
5+
* @desc 生成 http method 装饰器
6+
* @param {string} method - http method,如 get、post、head
7+
* @return Decorator - 装饰器
8+
*/
9+
function createMethodDecorator(method: string) {
10+
// 装饰器接收路由 path 作为参数
11+
return function httpMethodDecorator(path: string) {
12+
return (proto: any, name: string) => {
13+
const target = proto.constructor;
14+
const routeMap = Reflect.getMetadata(ROUTER_MAP, target, 'method') || [];
15+
routeMap.push({ name, method, path });
16+
Reflect.defineMetadata(ROUTER_MAP, routeMap, target, 'method');
17+
};
18+
};
19+
}
20+
21+
/**
22+
* 创建类路径装饰器
23+
* @param className
24+
*/
25+
function createClassDecorator() {
26+
// 装饰器接收路由 path 作为参数
27+
return function httpMethodDecorator(basePath: string):ClassDecorator {
28+
return (proto: any) => {
29+
const target = proto;
30+
const pathMap = Reflect.getMetadata(BASE_PATH_MAP, target) || [];
31+
pathMap.push({path:basePath});
32+
Reflect.defineMetadata(BASE_PATH_MAP, pathMap, target);
33+
};
34+
};
35+
}
36+
37+
// 路径前缀
38+
export const prefix = createClassDecorator()
39+
40+
// 导出 http method 装饰器
41+
export const post = createMethodDecorator('post');
42+
43+
export const get = createMethodDecorator('get');
44+
45+
export const del = createMethodDecorator('del');
46+
47+
export const put = createMethodDecorator('put');
48+
49+
export const patch = createMethodDecorator('patch');
50+
51+
export const options = createMethodDecorator('options');
52+
53+
export const head = createMethodDecorator('head');
54+
55+
export const all = createMethodDecorator('all');

mock/router.ts

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* @Description:
3+
* @Author: ZY
4+
* @Date: 2020-12-10 10:09:06
5+
* @LastEditors: ZY
6+
* @LastEditTime: 2020-12-10 14:41:18
7+
*/
8+
import 'reflect-metadata'
9+
import fs from 'fs'
10+
import path from 'path'
11+
import {ROUTER_MAP, BASE_PATH_MAP} from './constant'
12+
import {RouteMeta, PathMeta} from './type'
13+
import Router from 'koa-router'
14+
15+
const addRouter = (router: Router) => {
16+
const ctrPath = path.join(__dirname, 'controller');
17+
const modules: ObjectConstructor[] = [];
18+
// 扫描controller文件夹,收集所有controller
19+
fs.readdirSync(ctrPath).forEach(name => {
20+
if (/^[^.]+\.(t|j)s$/.test(name)) {
21+
modules.push(require(path.join(ctrPath, name)).default)
22+
}
23+
});
24+
25+
// 结合meta数据添加路由 和 验证
26+
modules.forEach(m => {
27+
const routerMap: RouteMeta[] = Reflect.getMetadata(ROUTER_MAP, m, 'method') || [];
28+
const basePathMap: PathMeta[] = Reflect.getMetadata(BASE_PATH_MAP, m) || [];
29+
const basePath:PathMeta = basePathMap.pop();
30+
if (routerMap.length) {
31+
const ctr = new m();
32+
routerMap.forEach(route => {
33+
// const {name, method, path, isVerify} = route;
34+
const {name, method, path} = route;
35+
const newPath:String = basePath ? (basePath.path + path) : path;
36+
// router[method](newPath, jwt(newPath, isVerify), ctr[name]);
37+
router[method](newPath, ctr[name]);
38+
})
39+
}
40+
})
41+
}
42+
43+
export default addRouter

mock/tsconfig.json

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
{
2+
"compilerOptions": {
3+
"baseUrl": ".",
4+
"outDir": "./dist",
5+
"module": "commonjs",
6+
"target": "esnext",
7+
"allowSyntheticDefaultImports": true,
8+
"importHelpers": true,
9+
"strict": false,
10+
"moduleResolution": "node",
11+
"esModuleInterop": true,
12+
"forceConsistentCasingInFileNames": true,
13+
"noImplicitAny": true,
14+
"suppressImplicitAnyIndexErrors": true,
15+
"noUnusedParameters": true,
16+
"noUnusedLocals": true,
17+
"noImplicitReturns": true,
18+
"experimentalDecorators": true,
19+
"emitDecoratorMetadata": true,
20+
"allowJs": true,
21+
"sourceMap": true,
22+
},
23+
"include": [
24+
"**/*.ts",
25+
"**/*.tsx"
26+
],
27+
"exclude": [
28+
"node_modules",
29+
"dist"
30+
]
31+
}

mock/type.d.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import {Context, Next} from "koa"
2+
3+
// type PlainObject = { [P: string]: any };
4+
type PlainObject = Record<string, any>;
5+
type ParamObject = Record<string, any>;
6+
type MysqlResult = {
7+
affectedRows?: number;
8+
insertId?: string;
9+
}
10+
11+
type PathMeta = {
12+
name: string;
13+
path: string;
14+
}
15+
16+
type RouteMeta = {
17+
name: string;
18+
method: string;
19+
path: string;
20+
isVerify: boolean;
21+
}
22+
23+
type MiddleWare = (...arg: any[]) => (ctx: Context, next?: Next) => Promise<void>;
24+
25+
export {
26+
MysqlResult,
27+
PlainObject,
28+
RouteMeta,
29+
MiddleWare,
30+
PathMeta,
31+
ParamObject
32+
}

mock/utils/logger.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import log4js from 'log4js'
2+
3+
const log = log4js.getLogger('default');
4+
export const errlog = log4js.getLogger('err');
5+
export default log

package.json

+17-1
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,20 @@
1111
"build:prod": "cross-env NODE_ENV=production dotenv -e .env.prod.build vue-cli-service build",
1212
"test:unit": "vue-cli-service test:unit",
1313
"test:e2e": "vue-cli-service test:e2e",
14-
"lint": "vue-cli-service lint"
14+
"lint": "vue-cli-service lint",
15+
"mock": "cd mock && ts-node-dev mock.ts"
1516
},
1617
"dependencies": {
18+
"@types/koa-logger": "^3.1.1",
19+
"chalk": "^4.1.0",
1720
"core-js": "^3.6.5",
21+
"koa": "^2.13.0",
22+
"koa-body": "^4.2.0",
23+
"koa-logger": "^3.2.1",
24+
"koa-router": "^10.0.0",
25+
"log4js": "^6.3.0",
26+
"moment": "^2.29.1",
27+
"reflect-metadata": "^0.1.13",
1828
"register-service-worker": "^1.7.1",
1929
"vue": "^3.0.0",
2030
"vue-class-component": "^8.0.0-0",
@@ -23,6 +33,9 @@
2333
},
2434
"devDependencies": {
2535
"@types/jest": "^24.0.19",
36+
"@types/koa": "^2.11.6",
37+
"@types/koa-router": "^7.4.1",
38+
"@types/node": "^14.14.11",
2639
"@typescript-eslint/eslint-plugin": "^2.33.0",
2740
"@typescript-eslint/parser": "^2.33.0",
2841
"@vue/cli-plugin-babel": "~4.5.0",
@@ -38,6 +51,8 @@
3851
"@vue/eslint-config-standard": "^5.1.2",
3952
"@vue/eslint-config-typescript": "^5.0.2",
4053
"@vue/test-utils": "^2.0.0-0",
54+
"babel-loader": "^8.2.2",
55+
"concurrently": "^5.3.0",
4156
"cross-env": "^7.0.3",
4257
"dotenv-cli": "^4.0.0",
4358
"eslint": "^6.7.2",
@@ -49,6 +64,7 @@
4964
"lint-staged": "^9.5.0",
5065
"sass": "^1.26.5",
5166
"sass-loader": "^8.0.2",
67+
"ts-node-dev": "^1.0.0",
5268
"typescript": "~3.9.3",
5369
"vue-jest": "^5.0.0-0",
5470
"webpackbar": "^5.0.0-3"

tsconfig.json

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"sourceMap": true,
1414
"baseUrl": ".",
1515
"types": [
16+
"node",
1617
"webpack-env",
1718
"jest"
1819
],

0 commit comments

Comments
 (0)