操做系統:windows10 64bitvue
node:v10.15.3node
npm:6.4.1mysql
koa:2.7.0web
mariadb:10.2.14sql
npm init複製代碼
npm install koa複製代碼
/*項目依賴*/
const Koa = require('koa');
const http = require('http');
/*應用實例*/
const app = new Koa();
/*web服務*/
http.createServer(app.callback())
.listen(3000)
.on('listening', function () {
console.log(`服務已開啓,端口:3000`)
});複製代碼
::指定建立服務的程序
@set mysql_service="D:\db\mariadb\10.2.14\bin\mysqld.exe"
::設置服務名
@set service_name="MariaDB.10"
::開始安裝Mariadb服務
%mysql_service% --install %service_name% --defaults-file="D:\db\mariadb\10.2.14\my-medium.ini"
pause複製代碼
@set mysql_service="D:\db\mariadb\10.2.14\bin\mysqld"
@set service_name="MariaDB.10"
:: 卸載服務
%mysql_service% --remove %service_name%
pause複製代碼
net start MariaDB.10複製代碼
net stop MariaDB.10複製代碼
// koa-json -- get提交數據的中間件
// koa-bodyparser -- post提交數據的中間件
// koa-body -- 文件上傳的中間件
// koa-router -- 路由中間件(接口地址)
// mysql -- mysql數據庫鏈接中間件
npm install koa-json koa-bodyparser koa-body koa-router mysql複製代碼
module.exports = {
// 服務器配置
SERVICE:{
HOST:"",
PORT:"3000"
},
// 數據庫鏈接配置
DATABASE:{
HOST: 'localhost',
USER: 'root',
PASSWORD: '123456',
DATABASE: 'test',
CONNECTION_LIMIT: 10
},
// 接口地址配置
API:{
// 項目接口前綴
PROJECT_INTERFACE_PREFIX:'/testApi',
// 後臺接口前綴
ADMIN_INTERFACE_PREFIX: '/adminApi',
// 移動端接口前綴
MOBILE_INTERFACE_PREFIX:'/mobileApi'
},
// 路徑配置
PATH:{
UPLOAD_PATH:"public/upload"
},
// 限制條件配置
LIMIT:{
UPLOAD_IMG_SIZE:200*1024*1024
}
};複製代碼
const mysql = require('mysql');
const fs = require("fs");
const path = require("path");
const config = require("./config");
const db = config.DATABASE;
const pool = mysql.createPool({
host: db.HOST,
user: db.USER,
password: db.PASSWORD,
database: db.DATABASE,
connectionLimit: db.CONNECTION_LIMIT
});
const utils = {
// 數據庫查詢方法
query: (sql, values) => {
return new Promise((resolve, reject) => {
pool.getConnection((err, connection) => {
if (err) {
return reject(err);
} else {
connection.query(sql, values, (err, rows) => {
connection.release();
if (err) {
return reject(err)
} else {
return resolve(rows);
}
})
}
})
});
},
// 錯誤JSON
resultErrorJson:(code=-1,message="失敗",data={})=>{
return {
code:code,
data:data,
message:message
}
},
// 成功JSON
resultSuccessJson:(code=0,message="成功",data={})=>{
return {
code:code,
data:data,
message:message
}
},
// 切割文件後綴名
splitFileName:(text) =>{
let index = text.lastIndexOf(".");
return {
name:text.substring(0,index),
suffix:text.substring(index+1)
};
},
// 遞歸建立目錄
mkdirsSync: (dirname)=>{
if (fs.existsSync(dirname)) {
return true;
} else {
if (utils.mkdirsSync(path.dirname(dirname))) {
fs.mkdirSync(dirname);
return true;
}
}
}
};
module.exports = utils;複製代碼
/*依賴包*/
const path = require("path");
const fs = require("fs");
const router = require('koa-router')();
/*配置文件*/
const config = require('./config.js');
const projectApiPrefix = config.API.PROJECT_INTERFACE_PREFIX;
// 讀取controller文件夾中的文件
fs.readdirSync(path.join(__dirname, 'controller')).forEach((file) => {
if (~file.indexOf('.js')) {
let controller = require(path.join(__dirname, 'controller', file));
// 爲接口設置通用前綴
router.use(`${projectApiPrefix}`, controller.routes(), controller.allowedMethods());
}
});
module.exports = router;複製代碼
module.exports = {}複製代碼
// china.js
const tableName = "china";
module.exports = {
getAllData:(ctx)=>{
return ctx.execSql(`select * from ${tableName}`);
}
};複製代碼
// login.js
const tableName = "account";
module.exports = {
adminLogin:(ctx,postData)=>{
return ctx.execSql(`select * from ${tableName} where phone = ? and password = ?`, [postData.phone, postData.psd]);
}
};複製代碼
// uploadfile.js
const tableName = "upload_file";
module.exports = {
uploadFile:(ctx,postData)=>{
return ctx.execSql(`insert into ${tableName} values (?,?,?)`, [null,postData.url, postData.fileName]);
},
getAllFiles:(ctx)=>{
return ctx.execSql(`select * from ${tableName}`);
}
};
複製代碼
// china.js
const chinaDao = require("../dao/china");
const util = require("../utilitys");
/**
* 後臺獲取全部城市接口邏輯
* @param ctx
* @returns {Promise<boolean>}
* @constructor
*/
exports.getAllCity = async(ctx) => {
try {
let result = await chinaDao.getAllData(ctx);
ctx.body = util.resultSuccessJson(undefined,undefined,result); } catch (err) {
ctx.body = util.resultErrorJson(undefined,err,{}); }
};
複製代碼
// login.js
const loginDao = require("../dao/login");
const util = require("../utilitys");
/**
* 後臺登陸接口業務邏輯
* @param ctx
* @returns {Promise<boolean>}
* @constructor
*/
exports.adminLogin = async(ctx) => {
let phone = ctx.request.body.phone || '';
let psd = ctx.request.body.password || '';
if (!phone || !psd) {
ctx.body = util.resultErrorJson(undefined,'手機號碼或密碼不能爲空',{}); return false;
}
try {
let result = await loginDao.adminLogin(ctx,{phone,psd});
if (result.length > 0) {
ctx.body = util.resultSuccessJson(undefined,undefined,result); } else {
ctx.body = util.resultSuccessJson(undefined,'帳號或密碼錯誤',{}) }
} catch (err) {
ctx.body = util.resultErrorJson(undefined,err,{}); }
};
/**
* 後臺登出接口業務邏輯
* @param ctx
* @returns {Promise<boolean>}
* @constructor
*/
exports.adminLoginOut = async(ctx) => {
let phone = ctx.request.body.phone || '';
let psd = ctx.request.body.password || '';
if (!phone || !psd) {
ctx.body = {
success: false,
message: '手機號碼或密碼不能爲空'
};
return false;
}
try {
let result = await ctx.execSql(`select * from account where phone = ? and password = ?`, [phone, psd]);
if (result.length > 0) {
ctx.body = {
success: true,
userID: result[0].id,
message: ''
};
} else {
ctx.body = {
success: false,
userID: 0,
message: '帳號或密碼錯誤'
};
}
} catch (err) {
ctx.body = {
success: false,
userID: 0,
message: err
};
}
}
/**
* 移動端登陸接口業務邏輯
* @param ctx
* @returns {Promise<boolean>}
* @constructor
*/
exports.mobileLogin = async(ctx) => {
let phone = ctx.request.body.phone || '';
let psd = ctx.request.body.password || '';
if (!phone || !psd) {
ctx.body = {
success: false,
message: '手機號碼或密碼不能爲空'
};
return false;
}
try {
let result = await ctx.execSql(`select * from account where phone = ? and password = ?`, [phone, psd]);
if (result.length > 0) {
ctx.body = {
success: true,
userID: result[0].id,
message: ''
};
} else {
ctx.body = {
success: false,
userID: 0,
message: '帳號或密碼錯誤'
};
}
} catch (err) {
ctx.body = {
success: false,
userID: 0,
message: err
};
}
}
/**
* 移動端登出接口業務邏輯
* @param ctx
* @returns {Promise<boolean>}
* @constructor
*/
exports.mobileLoginOut = async(ctx) => {
let phone = ctx.request.body.phone || '';
let psd = ctx.request.body.password || '';
if (!phone || !psd) {
ctx.body = {
success: false,
message: '手機號碼或密碼不能爲空'
};
return false;
}
try {
let result = await ctx.execSql(`select * from account where phone = ? and password = ?`, [phone, psd]);
if (result.length > 0) {
ctx.body = {
success: true,
userID: result[0].id,
message: ''
};
} else {
ctx.body = {
success: false,
userID: 0,
message: '帳號或密碼錯誤'
};
}
} catch (err) {
ctx.body = {
success: false,
userID: 0,
message: err
};
}
}
複製代碼
// uploadfile.js
const path = require("path");
const fs = require("fs");
const uploadFileDao = require("../dao/uploadfile");
const util = require("../utilitys");
const config = require("../config");
const uploadPath = config.PATH.UPLOAD_PATH;
/**
* 單個上傳文件接口
* @param ctx
* @returns {Promise<boolean>}
* @constructor
*/
exports.uploadFile = async(ctx) => {
// 文件
const file = ctx.request.files.file; // 獲取上傳文件
// 獲取文件後綴名
const fileName = util.splitFileName(file.name).name;
// 獲取文件後綴名
const suffix = util.splitFileName(file.name).suffix;
// 新生成的文件名稱
const newFileName =`${new Date().getTime()}.${suffix}`;
// 文件上傳分類
const category = ctx.request.body.category || '';
// 建立可讀流
const reader = fs.createReadStream(file.path);
// 設置上傳文件路徑及名稱
const filePath = path.join(__dirname, '..',uploadPath,category,`/${newFileName}`);
// 服務器相對路徑
const serviceUrl = `${uploadPath}/${category}/${newFileName}`;
// 遞歸建立目錄 同步方法
util.mkdirsSync(path.join(__dirname, '..',uploadPath,category));
// 若是文件夾存在,則建立可寫流
const upStream = fs.createWriteStream(filePath);
try {
// 可讀流經過管道寫入可寫流
reader.pipe(upStream);
let result = await uploadFileDao.uploadFile(ctx,{url:serviceUrl,fileName});
ctx.body = util.resultSuccessJson(undefined,"上傳成功",{}); } catch (err) {
ctx.body = util.resultErrorJson(undefined,err.message||"error",{}); }
};
/**
* 獲取全部文件信息
* @param ctx
* @returns {Promise<void>}
*/
exports.getAllFiles = async(ctx)=>{
try {
let result = await uploadFileDao.getAllFiles(ctx);
ctx.body = util.resultSuccessJson(undefined,undefined,result); } catch (err) {
ctx.body = util.resultErrorJson(undefined,err,{}); }
}
複製代碼
// china.js
/*路由*/
const router = require('koa-router')();
/*接口服務*/
const chinaService = require('../service/china.js');
// 通用獲取全部省市區接口
router.get(`/getAllCity`, chinaService.getAllCity);
module.exports = router;
複製代碼
// login.js
/*路由*/
const router = require('koa-router')();
/*接口服務*/
const loginService = require('../service/login.js');
/*配置屬性*/
const config = require('../config.js');
const adminPrefix = config.API.ADMIN_INTERFACE_PREFIX;
const mobilePrefix = config.API.MOBILE_INTERFACE_PREFIX;
// 後臺-使用登陸控制器實現登陸接口
router.post(`${adminPrefix}/login`, loginService.adminLogin);
// 後臺-使用登陸控制器實現登出接口
router.post(`${adminPrefix}/login/out`, loginService.adminLoginOut);
// 移動端-使用登陸控制器實現登陸接口
router.post(`${mobilePrefix}/login`, loginService.mobileLogin);
// 移動端-使用登陸控制器實現登出接口
router.post(`${mobilePrefix}/login/out`, loginService.mobileLoginOut);
module.exports = router;
複製代碼
// uploadfile.js
/*路由*/
const router = require('koa-router')();
/*接口服務*/
const chinaService = require('../service/uploadfile.js');
// 通用上傳文件接口
router.post(`/uploadfile`, chinaService.uploadFile);
// 獲取全部文件信息接口
router.get(`/getAllFiles`, chinaService.getAllFiles);
module.exports = router;複製代碼
app.js代碼以下數據庫
/*項目依賴*/
const Koa = require('koa');
const koaJson = require('koa-json'); // get提交數據的中間件
const bodyParser = require('koa-bodyparser'); // post提交數據中間件
const koaBody = require('koa-body'); // 文件上傳
const http = require('http');
const routes = require('./routes')
/*工具方法*/
const util = require('./utilitys.js');
/*配置文件*/
const config = require("./config.js");
/*應用實例*/
const app = new Koa();
app.use(bodyParser());
app.use(koaJson());
app.use(koaBody({
multipart: true,
formidable: {
maxFileSize: config.LIMIT.UPLOAD_IMG_SIZE // 設置上傳文件大小最大限制,默認2M
}
}));
app.use(async (ctx, next) => {
ctx.execSql = util.query;
await next();
});
/*配置屬性*/
const {SERVICE} = config;
/*路由配置*/
app.use(routes.routes());
/*web服務*/
http.createServer(app.callback())
.listen(SERVICE.PORT)
.on('listening', function () {
console.log(`服務已開啓,端口:${SERVICE.PORT}`)
});複製代碼
修改package.json文件添加命令,代碼以下:npm
"scripts": {
"start": "node app.js",
"debugger-start": "node --inspect-brk app.js"
},複製代碼
執行命令json
npm start複製代碼
結果以下:windows
const proxy = require('koa-server-http-proxy');
// 開啓代理
const proxyTable = {
'/shsApi': {
target: 'http://www.91vue.com:8081',
pathRewrite: { '^/shsApi': 'shsApi/' },
changeOrigin: true
},
// '/api': {
// target: 'https://news-at.zhihu.com',
// pathRewrite: { '^/api': 'api/4/' },
// changeOrigin: true
// }
};
Object.keys(proxyTable).forEach((context) => {
var options = proxyTable[context];
app.use(proxy(context, options))
});複製代碼