From 73e3bc918bad1b42e5175e4409d01228279ffe2c Mon Sep 17 00:00:00 2001 From: yoga Date: Sat, 30 Jul 2022 19:04:25 +0800 Subject: [PATCH] =?UTF-8?q?init:=20=E7=A1=AE=E8=AE=A4=E7=9B=AE=E5=BD=95?= =?UTF-8?q?=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 8 +++ .nvmrc | 1 + .vscode/settings.json | 13 +++++ nodemon.json | 3 + package.json | 27 +++++++++ public/css/reset.css | 53 ++++++++++++++++++ readme.md | 24 ++++++++ src/app/errorHandler.js | 10 ++++ src/app/index.js | 35 ++++++++++++ src/config/.env | 1 + src/config/.env.template | 31 ++++++++++ src/config/env.config.js | 3 + src/constant/errorType.js | 87 +++++++++++++++++++++++++++++ src/index.js | 7 +++ src/middlewares/captureRouteOmit.js | 17 ++++++ src/routers/index.js | 14 +++++ test/.http | 8 +++ test/.rest | 0 18 files changed, 342 insertions(+) create mode 100644 .gitignore create mode 100644 .nvmrc create mode 100644 .vscode/settings.json create mode 100644 nodemon.json create mode 100644 package.json create mode 100644 public/css/reset.css create mode 100644 readme.md create mode 100644 src/app/errorHandler.js create mode 100644 src/app/index.js create mode 100644 src/config/.env create mode 100644 src/config/.env.template create mode 100644 src/config/env.config.js create mode 100644 src/constant/errorType.js create mode 100644 src/index.js create mode 100644 src/middlewares/captureRouteOmit.js create mode 100644 src/routers/index.js create mode 100644 test/.http create mode 100644 test/.rest diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..55ab115 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +node_modules +/target/ + +# .env* +!.env.template + +upload/* +log/* \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..f274881 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +v16.16.0 diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c55f99e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,13 @@ +{ + "files.exclude": { + ".{git}/": false + }, + "search.exclude": { + "**/node_modules": true, + "**/bower_components": true, + "**/*.code-search": true, + ".*/": true + }, + "files.associations": {}, + "explorer.excludeGitIgnore": false +} diff --git a/nodemon.json b/nodemon.json new file mode 100644 index 0000000..077404a --- /dev/null +++ b/nodemon.json @@ -0,0 +1,3 @@ +{ + +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..8907ad2 --- /dev/null +++ b/package.json @@ -0,0 +1,27 @@ +{ + "name": "koa2-template", + "version": "1.0.0", + "description": "init a project with me", + "main": "index.js", + "scripts": { + "start": "pm2 start ./src/index.js", + "dev": "nodemon ./src/index.js", + "test": "node ./test/redis.test.js" + }, + "author": "Hawkin", + "license": "MIT", + "dependencies": { + "bcryptjs": "^2.4.3", + "dotenv": "^16.0.0", + "jsonwebtoken": "^8.5.1", + "koa": "^2.13.4", + "koa-body": "^5.0.0", + "koa-parameter": "^3.0.1", + "koa-router": "^10.1.1", + "koa-static": "^5.0.0", + "pm2": "^5.2.0" + }, + "devDependencies": { + "nodemon": "^2.0.16" + } +} diff --git a/public/css/reset.css b/public/css/reset.css new file mode 100644 index 0000000..fe1dfdf --- /dev/null +++ b/public/css/reset.css @@ -0,0 +1,53 @@ +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; + text-decoration: none; +} + +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; + font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", + "Microsoft YaHei", "微软雅黑", Arial, sans-serif; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ""; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} + +/*清除浮动*/ +.clearfix:before, +.clearfix:after { + content: ""; + display: block; + visibility: hidden; + clear: both; +} + +/*容器*/ +.container { + margin: 10px auto 0px; + width: 95%; +} diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..ac6be95 --- /dev/null +++ b/readme.md @@ -0,0 +1,24 @@ +```bash +. +├── node_modules +├── public 静态资源 +├── src +│ ├── index.js 项目入口文件 +│ ├── app 业务应用 +│ ├── config 业务配置 +│ ├── routers 路由 +│ ├── middlewares 中间件() +│ ├── controller 控制器(业务方法) +│ ├── services 数据库交互 +│ ├── models (数据库)模型对象 +│ ├── db 数据库连接对象 +│ ├── constant 常数定义 +│ ├── util 工具函数 +│ └── views 渲染模板 +├── test +│ ├── .example.http +│ └── redis.test.js +├── package.json +├── readme.md +└── readme.en.md +``` \ No newline at end of file diff --git a/src/app/errorHandler.js b/src/app/errorHandler.js new file mode 100644 index 0000000..be94c0f --- /dev/null +++ b/src/app/errorHandler.js @@ -0,0 +1,10 @@ +module.exports = (err, ctx) => { + let status; + switch (err.code) { + default: + status = 500; + } + ctx.status = status; + ctx.body = err; + // console.log(err) +}; diff --git a/src/app/index.js b/src/app/index.js new file mode 100644 index 0000000..7edd715 --- /dev/null +++ b/src/app/index.js @@ -0,0 +1,35 @@ +const path = require("path"); + +const Koa = require("koa"); +const KoaBody = require("koa-body"); +const KoaStatic = require("koa-static"); +const parameter = require("koa-parameter"); + +require("../config/env.config"); // 加载配置 + +const router = require("../routers"); // 加载路由 +const { captureRouteOmit } = require("../middlewares/captureRouteOmit"); +const errHandler = require("./errorHandler"); // 加载自定义异常 + +const app = new Koa(); + +app.use( + KoaBody({ + multipart: true, + formidable: { + uploadDir: path.join(__dirname, "../../data/upload"), + keepExtensions: true, + }, + parsedMethods: ["POST", "PUT", "PATCH", "DELETE"], + }) +); +app.use(KoaStatic(path.join(__dirname, "../../public"))); +app.use(parameter(app)); + +app.use(captureRouteOmit); // 兜底处理路由错误,是否要考虑koa-parameter错误 +app.use(router.routes()).use(router.allowedMethods()); + +// 统一的错误处理 +app.on("error", errHandler); // 监听全局异常事件 + +module.exports = app; diff --git a/src/config/.env b/src/config/.env new file mode 100644 index 0000000..83c74f9 --- /dev/null +++ b/src/config/.env @@ -0,0 +1 @@ +APP_PORT = 3000 diff --git a/src/config/.env.template b/src/config/.env.template new file mode 100644 index 0000000..149c8db --- /dev/null +++ b/src/config/.env.template @@ -0,0 +1,31 @@ +APP_PORT = 3000 + +MYSQL_DIALECT = mysql +MYSQL_HOST = +MYSQL_PORT = 3306 +MYSQL_DBNAME = +MYSQL_USER = +MYSQL_PASSWD = + +MARIA_DIALECT = mariadb +MARIA_HOST = +MARIA_PORT = 3306 +MARIA_DBNAME = +MARIA_USER = +MARIA_PASSWD = + +MONGO_DIALECT = mongodb +MONGO_HOST = +MONGO_PORT = 21017 +MONGO_DBNAME = +MONGO_USER = +MONGO_PASSWD = + +REDIS_DIALECT = redis +REDIS_HOST = +REDIS_PORT = 6379 +REDIS_DBNAME = +REDIS_USER = +REDIS_PASSWD = + +JWT_SECRET = \ No newline at end of file diff --git a/src/config/env.config.js b/src/config/env.config.js new file mode 100644 index 0000000..59cf21c --- /dev/null +++ b/src/config/env.config.js @@ -0,0 +1,3 @@ +const { config } = require("dotenv"); + +config({ path: "./src/config/.env" }); diff --git a/src/constant/errorType.js b/src/constant/errorType.js new file mode 100644 index 0000000..a0b21da --- /dev/null +++ b/src/constant/errorType.js @@ -0,0 +1,87 @@ +module.exports = { + userFormateError: { + code: '10001', + message: '用户名或密码为空', + result: '', + }, + userAlreadyExited: { + code: '10002', + message: '用户已经存在', + result: '', + }, + userRegisterError: { + code: '10003', + message: '用户注册错误', + result: '', + }, + userDoesNotExist: { + code: '10004', + message: '用户不存在', + result: '', + }, + userLoginError: { + code: '10005', + message: '用户登录失败', + result: '', + }, + invalidPassword: { + code: '10006', + message: '密码不匹配', + result: '', + }, + tokenExpiredError: { + code: '10101', + message: 'token已过期', + result: '', + }, + invalidToken: { + code: '10102', + message: '无效的token', + result: '', + }, + hasNotAdminPermission: { + code: '10103', + message: '没有管理员权限', + result: '', + }, + fileUploadError: { + code: '10201', + message: '商品图片上传失败', + result: '', + }, + unSupportedFileType: { + code: '10202', + message: '不支持的文件格式', + result: '', + }, + goodsFormatError: { + code: '10203', + message: '商品参数格式错误', + result: '', + }, + publishGoodsError: { + code: '10204', + message: '发布商品失败', + result: '', + }, + invalidGoodsID: { + code: '10205', + message: '无效的商品id', + result: '', + }, + cartFormatError: { + code: '10301', + message: '购物车数据格式错误', + result: '', + }, + addrFormatError: { + code: '10401', + message: '地址数据格式错误', + result: '', + }, + orderFormatError: { + code: '10501', + message: '订单数据格式错误', + result: '', + }, +} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..669ca40 --- /dev/null +++ b/src/index.js @@ -0,0 +1,7 @@ +const app = require("./app"); + +const { APP_PORT } = process.env; + +app.listen(APP_PORT ?? 3000, () => { + console.log(`server is running on http://localhost:${APP_PORT ?? 3000}`); +}); diff --git a/src/middlewares/captureRouteOmit.js b/src/middlewares/captureRouteOmit.js new file mode 100644 index 0000000..2996dda --- /dev/null +++ b/src/middlewares/captureRouteOmit.js @@ -0,0 +1,17 @@ +async function captureRouteOmit(ctx, next) { + try { + await next(); + if (!ctx.body) { + // 没有资源 + ctx.status = 404; + ctx.body = { message: "Not Found." }; + } + } catch (e) { + // 如果后面的代码报错 返回500(泛服务器错误) + ctx.status = 500; + ctx.body = { message: "Server Error." }; + // 记录错误日志 + } +} + +module.exports = { captureRouteOmit }; diff --git a/src/routers/index.js b/src/routers/index.js new file mode 100644 index 0000000..5d81cc1 --- /dev/null +++ b/src/routers/index.js @@ -0,0 +1,14 @@ +const fs = require("fs"); + +const Router = require("koa-router"); +const router = new Router(); + +// 自动载入同级目录中所有文件里的router +fs.readdirSync(__dirname).forEach((file) => { + if (file !== "index.js") { + let r = require("./" + file); + router.use(r.routes()); + } +}); + +module.exports = router; diff --git a/test/.http b/test/.http new file mode 100644 index 0000000..32258bb --- /dev/null +++ b/test/.http @@ -0,0 +1,8 @@ +GET http://localhost:3000/ HTTP/1.1 + + +### +POST http://localhost:3000/ HTTP/1.1 +Content-Type: application/json; charset=utf-8 + +{} \ No newline at end of file diff --git a/test/.rest b/test/.rest new file mode 100644 index 0000000..e69de29