diff --git a/.env.development b/.env.development index 9d2ebe08..1d2d6c9f 100644 --- a/.env.development +++ b/.env.development @@ -1 +1 @@ -VUE_APP_BASE_API = 'https://api-dev' +VUE_APP_BASE_API = '/api' diff --git a/.env.production b/.env.production index e019323f..1d2d6c9f 100644 --- a/.env.production +++ b/.env.production @@ -1 +1 @@ -VUE_APP_BASE_API = 'https://api-prod' +VUE_APP_BASE_API = '/api' diff --git a/src/mock/article.js b/mock/article.js similarity index 81% rename from src/mock/article.js rename to mock/article.js index 45923ddd..72b5f837 100644 --- a/src/mock/article.js +++ b/mock/article.js @@ -1,5 +1,4 @@ import Mock from 'mockjs' -import { param2Obj } from '@/utils' const List = [] const count = 100 @@ -29,8 +28,8 @@ for (let i = 0; i < count; i++) { } export default { - getList: config => { - const { importance, type, title, page = 1, limit = 20, sort } = param2Obj(config.url) + '/article/list': config => { + const { importance, type, title, page = 1, limit = 20, sort } = config.query let mockList = List.filter(item => { if (importance && item.importance !== +importance) return false @@ -50,21 +49,26 @@ export default { items: pageList } }, - getPv: () => ({ - pvData: [{ key: 'PC', pv: 1024 }, { key: 'mobile', pv: 1024 }, { key: 'ios', pv: 1024 }, { key: 'android', pv: 1024 }] - }), - getArticle: (config) => { - const { id } = param2Obj(config.url) + '/article/detail': config => { + const { id } = config.query for (const article of List) { if (article.id === +id) { return article } } }, - createArticle: () => ({ + '/article/pv': { + pvData: [ + { key: 'PC', pv: 1024 }, + { key: 'mobile', pv: 1024 }, + { key: 'ios', pv: 1024 }, + { key: 'android', pv: 1024 } + ] + }, + '/article/create': { data: 'success' - }), - updateArticle: () => ({ + }, + '/article/update': { data: 'success' - }) + } } diff --git a/mock/index.js b/mock/index.js new file mode 100644 index 00000000..f40ac238 --- /dev/null +++ b/mock/index.js @@ -0,0 +1,50 @@ +import Mock from 'mockjs' +import mocks from './mocks' +import { param2Obj } from '../src/utils' + +const MOCK_API_BASE = '/mock' + +export function mockXHR() { + // 修复在使用 MockJS 情况下,设置 withCredentials = true,且未被拦截的跨域请求丢失 Cookies 的问题 + // https://github.com/nuysoft/Mock/issues/300 + Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send + Mock.XHR.prototype.send = function() { + if (this.custom.xhr) { + this.custom.xhr.withCredentials = this.withCredentials || false + } + this.proxy_send(...arguments) + } + + function XHR2ExpressReqWrap(respond) { + return function(options) { + let result = null + if (respond instanceof Function) { + const { body, type, url } = options + // https://expressjs.com/en/4x/api.html#req + result = respond({ + method: type, + body: JSON.parse(body), + query: param2Obj(url) + }) + } else { + result = respond + } + return Mock.mock(result) + } + } + + for (const [route, respond] of Object.entries(mocks)) { + Mock.mock(new RegExp(`${route}`), XHR2ExpressReqWrap(respond)) + } +} + +const responseFake = (route, respond) => ( + { + route: new RegExp(`${MOCK_API_BASE}${route}`), + response(req, res) { + res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond)) + } + } +) + +export default Object.keys(mocks).map(route => responseFake(route, mocks[route])) diff --git a/src/mock/login.js b/mock/login.js similarity index 72% rename from src/mock/login.js rename to mock/login.js index b9694f09..e49f98ce 100644 --- a/src/mock/login.js +++ b/mock/login.js @@ -1,5 +1,3 @@ -import { param2Obj } from '@/utils' - const userMap = { admin: { roles: ['admin'], @@ -18,17 +16,18 @@ const userMap = { } export default { - loginByUsername: config => { - const { username } = JSON.parse(config.body) + '/login/login': config => { + const { username } = config.body return userMap[username] }, - getUserInfo: config => { - const { token } = param2Obj(config.url) + '/login/logout': 'success', + '/user/info': config => { + const { token } = config.query if (userMap[token]) { return userMap[token] } else { return false } - }, - logout: () => 'success' + } } + diff --git a/mock/mocks.js b/mock/mocks.js new file mode 100644 index 00000000..9e551722 --- /dev/null +++ b/mock/mocks.js @@ -0,0 +1,12 @@ +import login from './login' +import article from './article' +import search from './remoteSearch' +import transaction from './transaction' + +export default { + ...login, + ...article, + ...search, + ...transaction +} + diff --git a/src/mock/remoteSearch.js b/mock/remoteSearch.js similarity index 64% rename from src/mock/remoteSearch.js rename to mock/remoteSearch.js index b70f6f7d..bbdc0708 100644 --- a/src/mock/remoteSearch.js +++ b/mock/remoteSearch.js @@ -1,5 +1,4 @@ import Mock from 'mockjs' -import { param2Obj } from '@/utils' const NameList = [] const count = 100 @@ -12,12 +11,11 @@ for (let i = 0; i < count; i++) { NameList.push({ name: 'mockPan' }) export default { - searchUser: config => { - const { name } = param2Obj(config.url) + '/search/user': config => { + const { name } = config.query const mockNameList = NameList.filter(item => { const lowerCaseName = item.name.toLowerCase() - if (name && lowerCaseName.indexOf(name.toLowerCase()) < 0) return false - return true + return !(name && lowerCaseName.indexOf(name.toLowerCase()) < 0) }) return { items: mockNameList } } diff --git a/mock/transaction.js b/mock/transaction.js new file mode 100644 index 00000000..61c84f0d --- /dev/null +++ b/mock/transaction.js @@ -0,0 +1,16 @@ +import Mock from 'mockjs' + +const count = 20 + +export default { + '/transaction/list': { + total: count, + [`items|${count}`]: [{ + order_no: '@guid()', + timestamp: +Mock.Random.date('T'), + username: '@name()', + price: '@float(1000, 15000, 0, 2)', + 'status|1': ['success', 'pending'] + }] + } +} diff --git a/package.json b/package.json index 672636be..66336f1f 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "license": "MIT", "scripts": { "dev": "vue-cli-service serve", - "build:prod": "vue-cli-service build ", + "build:prod": "vue-cli-service build", "build:sit": "vue-cli-service build --mode text", "lint": "eslint --ext .js,.vue src", "test": "npm run lint", diff --git a/src/main.js b/src/main.js index 831b8d6a..6d5c0592 100644 --- a/src/main.js +++ b/src/main.js @@ -17,12 +17,16 @@ import i18n from './lang' // Internationalization import './icons' // icon import './errorLog' // error log import './permission' // permission control -import './mock' // simulation data import * as filters from './filters' // global filters import VueAnalytics from 'vue-analytics' +import { mockXHR } from '../mock' // simulation data + +// mock api in github pages site build +if (process.env.NODE_ENV === 'production') { mockXHR() } + Vue.use(VueAnalytics, { id: 'UA-109340118-1', router diff --git a/src/mock/index.js b/src/mock/index.js deleted file mode 100644 index 3e00e918..00000000 --- a/src/mock/index.js +++ /dev/null @@ -1,39 +0,0 @@ -import Mock from 'mockjs' -import loginAPI from './login' -import articleAPI from './article' -import remoteSearchAPI from './remoteSearch' -import transactionAPI from './transaction' - -// 修复在使用 MockJS 情况下,设置 withCredentials = true,且未被拦截的跨域请求丢失 Cookies 的问题 -// https://github.com/nuysoft/Mock/issues/300 -Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send -Mock.XHR.prototype.send = function() { - if (this.custom.xhr) { - this.custom.xhr.withCredentials = this.withCredentials || false - } - this.proxy_send(...arguments) -} - -// Mock.setup({ -// timeout: '350-600' -// }) - -// 登录相关 -Mock.mock(/\/login\/login/, 'post', loginAPI.loginByUsername) -Mock.mock(/\/login\/logout/, 'post', loginAPI.logout) -Mock.mock(/\/user\/info\.*/, 'get', loginAPI.getUserInfo) - -// 文章相关 -Mock.mock(/\/article\/list/, 'get', articleAPI.getList) -Mock.mock(/\/article\/detail/, 'get', articleAPI.getArticle) -Mock.mock(/\/article\/pv/, 'get', articleAPI.getPv) -Mock.mock(/\/article\/create/, 'post', articleAPI.createArticle) -Mock.mock(/\/article\/update/, 'post', articleAPI.updateArticle) - -// 搜索相关 -Mock.mock(/\/search\/user/, 'get', remoteSearchAPI.searchUser) - -// 账单相关 -Mock.mock(/\/transaction\/list/, 'get', transactionAPI.getList) - -export default Mock diff --git a/src/mock/transaction.js b/src/mock/transaction.js deleted file mode 100644 index a17517e4..00000000 --- a/src/mock/transaction.js +++ /dev/null @@ -1,23 +0,0 @@ -import Mock from 'mockjs' - -const List = [] -const count = 20 - -for (let i = 0; i < count; i++) { - List.push(Mock.mock({ - order_no: '@guid()', - timestamp: +Mock.Random.date('T'), - username: '@name()', - price: '@float(1000, 15000, 0, 2)', - 'status|1': ['success', 'pending'] - })) -} - -export default { - getList: () => { - return { - total: List.length, - items: List - } - } -} diff --git a/src/utils/request.js b/src/utils/request.js index d3997812..47237685 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -6,6 +6,7 @@ import { getToken } from '@/utils/auth' // create an axios instance const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // api 的 base_url + withCredentials: true, // 跨域请求时发送 cookies timeout: 5000 // request timeout }) diff --git a/vue.config.js b/vue.config.js index 4d4fb06d..d4f047fa 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,6 +1,7 @@ 'use strict' require('@babel/register') const path = require('path') +const bodyParser = require('body-parser') function resolve(dir) { return path.join(__dirname, dir) @@ -8,7 +9,28 @@ function resolve(dir) { module.exports = { devServer: { - open: true + open: true, + proxy: { + '/api': { + target: 'http://localhost:8080/mock', + changeOrigin: true, + pathRewrite: { + '^/api': '' + } + } + }, + after(app) { + // parse app.body + // http://expressjs.com/en/4x/api.html#req.body + app.use(bodyParser.json()) + app.use(bodyParser.urlencoded({ extended: true })) + + // import ES2015 module from common.js module + const { default: mocks } = require('./mock') + for (const mock of mocks) { + app.all(mock.route, mock.response) + } + } }, configureWebpack: { resolve: {