diff --git a/README.md b/README.md index 77de48a5..39d6dbcc 100644 --- a/README.md +++ b/README.md @@ -81,11 +81,12 @@ git clone http://github.com/didi/xiaoju-survey ### 安装依赖 ```shell cd server -sh init.sh ``` ### 启动 ```shell +npm run local // 无需安装mongo +或 npm run dev ``` diff --git a/server/package.json b/server/package.json index 674025b1..ce7dc001 100644 --- a/server/package.json +++ b/server/package.json @@ -4,15 +4,16 @@ "description": "survey server template", "main": "index.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", "copy": "cp -rf ./src/ ./build/", "build": "tsc", - "launch": "npm run build && SERVER_ENV=local node ./build/index.js", - "start:stable": "SERVER_ENV=stable node ./build/index.js", - "start:preonline": "SERVER_ENV=preonline node ./build/index.js", - "start:online": "SERVER_ENV=online node ./build/index.js", - "start": "npm run copy && npm run launch", - "dev": "npm run copy && nodemon -e js,mjs,json,ts --exec 'npm run launch' --watch ./src" + "launch:local": "npm run build && SERVER_ENV=local node ./build/index.js", + "launch:dev": "npm run build && SERVER_ENV=dev node ./build/index.js", + "start:stable": "npm run copy && npm run build && SERVER_ENV=stable node ./build/index.js", + "start:preonline": "npm run copy && npm run build && SERVER_ENV=preonline node ./build/index.js", + "start:online": "npm run copy && npm run build && SERVER_ENV=online node ./build/index.js", + "start": "npm run start:online", + "local": "npm run copy && nodemon -e js,mjs,json,ts --exec 'npm run launch:local' --watch ./src", + "dev": "npm run copy && nodemon -e js,mjs,json,ts --exec 'npm run launch:dev' --watch ./src" }, "devDependencies": { "nodemon": "^2.0.20", @@ -22,13 +23,19 @@ "@types/koa": "^2.13.8", "@types/koa-bodyparser": "^4.3.10", "@types/koa-router": "^7.4.4", + "joi": "^17.9.2", + "jsonwebtoken": "^9.0.1", "koa": "^2.14.2", "koa-bodyparser": "^4.4.1", "koa-pino-logger": "^4.0.0", - "koa-router": "^12.0.0" + "koa-router": "^12.0.0", + "lodash": "^4.17.21", + "moment": "^2.29.4", + "mongodb": "^5.7.0", + "mongodb-memory-server": "^9.0.1" }, "engines": { - "node": ">=14.15.4", - "npm": ">=6.14.10" + "node": ">=14.21.0", + "npm": ">=6.14.17" } } diff --git a/server/src/apps/security/db/mongo.ts b/server/src/apps/security/db/mongo.ts index 6aab7c5f..b2c1232a 100644 --- a/server/src/apps/security/db/mongo.ts +++ b/server/src/apps/security/db/mongo.ts @@ -1,5 +1,6 @@ import { Collection, MongoClient, ObjectId } from 'mongodb' import { getConfig } from '../config/index' +import { getMongoMemoryUri } from '../../../getMongoMemoryUri' const config = getConfig() @@ -9,7 +10,12 @@ class mongoService { constructor() { this.client = new MongoClient(config.mongo.url); } + async getCollection({ collectionName }): Promise { + if (process.env.SERVER_ENV === 'local') { + const uri = await getMongoMemoryUri() + this.client = new MongoClient(uri); + } await this.client.connect() return this.client.db(config.mongo.dbName).collection(collectionName) } diff --git a/server/src/apps/security/package.json b/server/src/apps/security/package.json deleted file mode 100644 index 5c559fee..00000000 --- a/server/src/apps/security/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "sceurity", - "version": "1.0.0", - "description": "", - "main": "index.js", - "dependencies": { - "mongodb": "^5.7.0" - }, - "devDependencies": {} -} diff --git a/server/src/apps/surveyManage/db/mongo.ts b/server/src/apps/surveyManage/db/mongo.ts index 6aab7c5f..b2c1232a 100644 --- a/server/src/apps/surveyManage/db/mongo.ts +++ b/server/src/apps/surveyManage/db/mongo.ts @@ -1,5 +1,6 @@ import { Collection, MongoClient, ObjectId } from 'mongodb' import { getConfig } from '../config/index' +import { getMongoMemoryUri } from '../../../getMongoMemoryUri' const config = getConfig() @@ -9,7 +10,12 @@ class mongoService { constructor() { this.client = new MongoClient(config.mongo.url); } + async getCollection({ collectionName }): Promise { + if (process.env.SERVER_ENV === 'local') { + const uri = await getMongoMemoryUri() + this.client = new MongoClient(uri); + } await this.client.connect() return this.client.db(config.mongo.dbName).collection(collectionName) } diff --git a/server/src/apps/surveyManage/package.json b/server/src/apps/surveyManage/package.json deleted file mode 100644 index 0b482bbb..00000000 --- a/server/src/apps/surveyManage/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "survey_manage", - "version": "1.0.0", - "description": "", - "main": "index.js", - "dependencies": { - "joi": "^17.9.2", - "lodash": "^4.17.21", - "moment": "^2.29.4", - "mongodb": "^5.7.0" - }, - "devDependencies": {} -} diff --git a/server/src/apps/surveyPublish/db/mongo.ts b/server/src/apps/surveyPublish/db/mongo.ts index f07d8989..e0cd3d7b 100644 --- a/server/src/apps/surveyPublish/db/mongo.ts +++ b/server/src/apps/surveyPublish/db/mongo.ts @@ -1,5 +1,6 @@ import { Collection, MongoClient, ObjectId } from 'mongodb' import { getConfig } from '../config/index' +import { getMongoMemoryUri } from '../../../getMongoMemoryUri' const config = getConfig() @@ -9,7 +10,12 @@ class mongoService { constructor() { this.client = new MongoClient(config.mongo.url); } - async getCollection({collectionName}):Promise { + + async getCollection({ collectionName }): Promise { + if (process.env.SERVER_ENV === 'local') { + const uri = await getMongoMemoryUri() + this.client = new MongoClient(uri); + } await this.client.connect() return this.client.db(config.mongo.dbName).collection(collectionName) } diff --git a/server/src/apps/surveyPublish/package.json b/server/src/apps/surveyPublish/package.json deleted file mode 100644 index bcbd1e33..00000000 --- a/server/src/apps/surveyPublish/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "survey_publish", - "version": "1.0.0", - "description": "", - "main": "index.js", - "dependencies": { - "joi": "^17.9.2", - "lodash": "^4.17.21", - "moment": "^2.29.4", - "mongodb": "^5.7.0" - }, - "devDependencies": {} -} diff --git a/server/src/apps/ui/package.json b/server/src/apps/ui/package.json deleted file mode 100644 index a54c245f..00000000 --- a/server/src/apps/ui/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "ui", - "version": "1.0.0", - "main": "index.js", - "license": "MIT", - "dependencies": {} -} diff --git a/server/src/apps/user/db/mongo.ts b/server/src/apps/user/db/mongo.ts index f07d8989..7e6b6750 100644 --- a/server/src/apps/user/db/mongo.ts +++ b/server/src/apps/user/db/mongo.ts @@ -1,31 +1,37 @@ import { Collection, MongoClient, ObjectId } from 'mongodb' import { getConfig } from '../config/index' +import { getMongoMemoryUri } from '../../../getMongoMemoryUri' const config = getConfig() class mongoService { - isInit:boolean - client:MongoClient + isInit: boolean + client: MongoClient constructor() { this.client = new MongoClient(config.mongo.url); } - async getCollection({collectionName}):Promise { + + async getCollection({ collectionName }): Promise { + if (process.env.SERVER_ENV === 'local') { + const uri = await getMongoMemoryUri() + this.client = new MongoClient(uri); + } await this.client.connect() return this.client.db(config.mongo.dbName).collection(collectionName) } - convertId2StringByDoc(doc:any):any { + convertId2StringByDoc(doc: any): any { doc._id = doc._id.toString() return doc; } - convertId2StringByList(list:Array):Array { - return list.map(e=>{ + convertId2StringByList(list: Array): Array { + return list.map(e => { return this.convertId2StringByDoc(e); }) } - getObjectIdByStr(str:string) { + getObjectIdByStr(str: string) { return new ObjectId(str) } } diff --git a/server/src/apps/user/package.json b/server/src/apps/user/package.json deleted file mode 100644 index 613c7e74..00000000 --- a/server/src/apps/user/package.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "user", - "version": "1.0.0", - "description": "", - "main": "index.js", - "dependencies": { - "joi": "^17.9.2", - "jsonwebtoken": "^9.0.1", - "lodash": "^4.17.21", - "mongodb": "^5.7.0" - }, - "devDependencies": {} -} diff --git a/server/src/apps/user/service/userService.ts b/server/src/apps/user/service/userService.ts index a2806f1d..fd2c59e5 100644 --- a/server/src/apps/user/service/userService.ts +++ b/server/src/apps/user/service/userService.ts @@ -1,9 +1,9 @@ -import { - verify as jwtVerify, - sign as jwtSign +import { + verify as jwtVerify, + sign as jwtSign } from 'jsonwebtoken'; -import { - createHash +import { + createHash } from 'crypto'; import { mongo } from '../db/mongo' import { getStatusObject } from '../utils/index' @@ -23,55 +23,55 @@ class UserService { return jwtSign(userInfo, config.jwt.secret, { expiresIn: config.jwt.expiresIn }); } - async register(userInfo:{username:string, password:string}) { - const user = await mongo.getCollection({collectionName:'user'}); + async register(userInfo: { username: string, password: string }) { + const user = await mongo.getCollection({ collectionName: 'user' }); const userRes = await user.findOne({ - username:userInfo.username, + username: userInfo.username, }) - if(userRes) { + if (userRes) { throw new CommonError('该用户已存在') } const userInsertRes = await user.insertOne({ - username:userInfo.username, - password:this.hash256(userInfo.password), - curStatus:getStatusObject({status:SURVEY_STATUS.new}), - createDate:Date.now() + username: userInfo.username, + password: this.hash256(userInfo.password), + curStatus: getStatusObject({ status: SURVEY_STATUS.new }), + createDate: Date.now() }) - const token = this.getToken({ + const token = this.getToken({ _id: userInsertRes.insertedId.toString(), - username:userInfo.username - }); - return {userInsertRes, token, username:userInfo.username} + username: userInfo.username + }); + return { userInsertRes, token, username: userInfo.username } } - async login(userInfo:{username:string, password:string}) { - const user = await mongo.getCollection({collectionName:'user'}); + async login(userInfo: { username: string, password: string }) { + const user = await mongo.getCollection({ collectionName: 'user' }); const userRes = await user.findOne({ - username:userInfo.username, - password:this.hash256(userInfo.password), + username: userInfo.username, + password: this.hash256(userInfo.password), }) - if(!userRes) { + if (!userRes) { throw new CommonError('用户名或密码错误') } - const token = this.getToken({ + const token = this.getToken({ _id: userRes._id.toString(), - username:userInfo.username - }); - return {token, username:userInfo.username} + username: userInfo.username + }); + return { token, username: userInfo.username } } - async getUserByToken(tokenInfo:{token:string}) { + async getUserByToken(tokenInfo: { token: string }) { let userInfo; try { userInfo = jwtVerify(tokenInfo.token, config.jwt.secret) - } catch(err) { - throw new CommonError('用户凭证无效或已过期',403) + } catch (err) { + throw new CommonError('用户凭证无效或已过期', 403) } - const user = await mongo.getCollection({collectionName:'user'}); + const user = await mongo.getCollection({ collectionName: 'user' }); const userRes = await user.findOne({ - _id:mongo.getObjectIdByStr(userInfo._id), + _id: mongo.getObjectIdByStr(userInfo._id), }) - if(!userRes) { + if (!userRes) { throw new CommonError('用户已不存在') } return mongo.convertId2StringByDoc(userRes); diff --git a/server/src/getMongoMemoryUri.ts b/server/src/getMongoMemoryUri.ts new file mode 100644 index 00000000..bb615006 --- /dev/null +++ b/server/src/getMongoMemoryUri.ts @@ -0,0 +1,10 @@ +import { MongoMemoryServer } from 'mongodb-memory-server' + +let mongoMemeryInstance +export async function getMongoMemoryUri () { + if (!mongoMemeryInstance) { + mongoMemeryInstance = await MongoMemoryServer.create() + } + + return mongoMemeryInstance.getUri() +} \ No newline at end of file diff --git a/server/src/index.ts b/server/src/index.ts index 1ea341b1..e659de04 100644 --- a/server/src/index.ts +++ b/server/src/index.ts @@ -16,6 +16,6 @@ app.use(KoaBodyparser({ })) app.use(getRouter().routes()) -const port = 8080 +const port = process.env.PORT || 3000 app.listen(port) process.stdout.write(`${os.EOL}server run: http://127.0.0.1:${port} ${os.EOL}`) \ No newline at end of file diff --git a/server/src/middleware/outputCatch.ts b/server/src/middleware/outputCatch.ts index a73ca131..06b804ff 100644 --- a/server/src/middleware/outputCatch.ts +++ b/server/src/middleware/outputCatch.ts @@ -1,10 +1,10 @@ -export function outputCatch({showErrorStack}:{showErrorStack:boolean}) { - return async function (ctx, next) { - try{ +export function outputCatch({ showErrorStack }: { showErrorStack: boolean }) { + return async function (ctx, next) { + try { await next() - } catch(err) { - const outputData = {...err} - if(showErrorStack) { + } catch (err) { + const outputData = { ...err } + if (showErrorStack) { outputData.stack = err.stack; } return ctx.body = outputData diff --git a/web/package.json b/web/package.json index ba2a1c1c..0bacbc62 100644 --- a/web/package.json +++ b/web/package.json @@ -21,7 +21,6 @@ "moment": "^2.29.4", "qrcode": "^1.5.3", "vue": "^2.7.14", - "vue-demi": "^0.14.5", "vue-router": "^3.5.1", "vuedraggable": "^2.24.3", "vuex": "^3.6.2", @@ -50,7 +49,7 @@ "vue-template-compiler": "^2.7.14" }, "engines": { - "node": ">=16.11.1", - "npm": ">=8.0.0" + "node": ">=14.21.0", + "npm": ">=6.14.17" } } diff --git a/web/src/management/api/base.js b/web/src/management/api/base.js index cd0e2a73..63347fc1 100644 --- a/web/src/management/api/base.js +++ b/web/src/management/api/base.js @@ -2,26 +2,33 @@ import axios from 'axios'; import store from '@/management/store/index'; import router from '@/management/router/index'; import _get from 'lodash/get'; +import { Message } from 'element-ui'; const instance = axios.create({ baseURL: '/api', timeout: 3000, }); -instance.interceptors.response.use((response) => { - if (response.status !== 200) { - throw new Error('http请求出错'); +instance.interceptors.response.use( + (response) => { + if (response.status !== 200) { + throw new Error('http请求出错'); + } + const res = response.data; + if (res.code === 403) { + router.replace({ + name: 'login', + }); + return res; + } else { + return res; + } + }, + (err) => { + Message.error(err || 'http请求出错'); + throw new Error(err); } - const res = response.data; - if (res.code === 403) { - router.replace({ - name: 'login', - }); - return res; - } else { - return res; - } -}); +); instance.interceptors.request.use((config) => { const hasLogined = _get(store, 'state.user.hasLogined'); diff --git a/web/src/management/pages/login/index.vue b/web/src/management/pages/login/index.vue index 3c75ac38..110b012e 100644 --- a/web/src/management/pages/login/index.vue +++ b/web/src/management/pages/login/index.vue @@ -3,7 +3,7 @@ class="login-page" :style="{ background: `url('/imgs/create/background.jpg') no-repeat bottom right`, - 'background-size': 'cover' + 'background-size': 'cover', }" >