Commit e4c36db6 authored by neogcg's avatar neogcg

2.22

parents d39501ef 97209ebb
# just a flag
ENV = 'development'
# base api
VUE_APP_BASE_API = '/dev-api'
# just a flag
ENV = 'production'
# base api
VUE_APP_BASE_API = '/prod-api'
NODE_ENV = production
# just a flag
ENV = 'staging'
# base api
VUE_APP_BASE_API = '/stage-api'
File added
const Mock = require('mockjs')
const { param2Obj } = require('./utils')
const user = require('./user')
const table = require('./table')
const mocks = [
...user,
...table
]
// for front mock
// please use it cautiously, it will redefine XMLHttpRequest,
// which will cause many of your third-party libraries to be invalidated(like progress event).
function mockXHR() {
// mock patch
// 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
if (this.responseType) {
this.custom.xhr.responseType = this.responseType
}
}
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 i of mocks) {
Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
}
}
module.exports = {
mocks,
mockXHR
}
const chokidar = require('chokidar')
const bodyParser = require('body-parser')
const chalk = require('chalk')
const path = require('path')
const Mock = require('mockjs')
const mockDir = path.join(process.cwd(), 'mock')
function registerRoutes(app) {
let mockLastIndex
const { mocks } = require('./index.js')
const mocksForServer = mocks.map(route => {
return responseFake(route.url, route.type, route.response)
})
for (const mock of mocksForServer) {
app[mock.type](mock.url, mock.response)
mockLastIndex = app._router.stack.length
}
const mockRoutesLength = Object.keys(mocksForServer).length
return {
mockRoutesLength: mockRoutesLength,
mockStartIndex: mockLastIndex - mockRoutesLength
}
}
function unregisterRoutes() {
Object.keys(require.cache).forEach(i => {
if (i.includes(mockDir)) {
delete require.cache[require.resolve(i)]
}
})
}
// for mock server
const responseFake = (url, type, respond) => {
return {
url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),
type: type || 'get',
response(req, res) {
console.log('request invoke:' + req.path)
res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
}
}
}
module.exports = app => {
// parse app.body
// https://expressjs.com/en/4x/api.html#req.body
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
extended: true
}))
const mockRoutes = registerRoutes(app)
var mockRoutesLength = mockRoutes.mockRoutesLength
var mockStartIndex = mockRoutes.mockStartIndex
// watch files, hot reload mock server
chokidar.watch(mockDir, {
ignored: /mock-server/,
ignoreInitial: true
}).on('all', (event, path) => {
if (event === 'change' || event === 'add') {
try {
// remove mock routes stack
app._router.stack.splice(mockStartIndex, mockRoutesLength)
// clear routes cache
unregisterRoutes()
const mockRoutes = registerRoutes(app)
mockRoutesLength = mockRoutes.mockRoutesLength
mockStartIndex = mockRoutes.mockStartIndex
console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))
} catch (error) {
console.log(chalk.redBright(error))
}
}
})
}
const Mock = require('mockjs')
const data = Mock.mock({
'items|30': [{
id: '@id',
title: '@sentence(10, 20)',
'status|1': ['published', 'draft', 'deleted'],
author: 'name',
display_time: '@datetime',
pageviews: '@integer(300, 5000)'
}]
})
module.exports = [
{
url: '/vue-admin-template/table/list',
type: 'get',
response: config => {
const items = data.items
return {
code: 20000,
data: {
total: items.length,
items: items
}
}
}
}
]
const tokens = {
admin: {
token: 'admin-token'
},
editor: {
token: 'editor-token'
}
}
const users = {
'admin-token': {
roles: ['admin'],
introduction: 'I am a super administrator',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Super Admin'
},
'editor-token': {
roles: ['editor'],
introduction: 'I am an editor',
avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
name: 'Normal Editor'
}
}
module.exports = [
// user login
{
url: '/vue-admin-template/user/login',
type: 'post',
response: config => {
const { username } = config.body
const token = tokens[username]
// mock error
if (!token) {
return {
code: 60204,
message: 'Account and password are incorrect.'
}
}
return {
code: 20000,
data: token
}
}
},
// get user info
{
url: '/vue-admin-template/user/info\.*',
type: 'get',
response: config => {
const { token } = config.query
const info = users[token]
// mock error
if (!info) {
return {
code: 50008,
message: 'Login failed, unable to get user details.'
}
}
return {
code: 20000,
data: info
}
}
},
// user logout
{
url: '/vue-admin-template/user/logout',
type: 'post',
response: _ => {
return {
code: 20000,
data: 'success'
}
}
}
]
/**
* @param {string} url
* @returns {Object}
*/
function param2Obj(url) {
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
if (!search) {
return {}
}
const obj = {}
const searchArr = search.split('&')
searchArr.forEach(v => {
const index = v.indexOf('=')
if (index !== -1) {
const name = v.substring(0, index)
const val = v.substring(index + 1, v.length)
obj[name] = val
}
})
return obj
}
module.exports = {
param2Obj
}
......@@ -2,7 +2,7 @@ import request from '@/utils/request'
export function login(data) {
return request({
url: '/vue-admin-template/user/login',
url: '/user/login',
method: 'post',
data
})
......@@ -10,7 +10,7 @@ export function login(data) {
export function getInfo(token) {
return request({
url: '/vue-admin-template/user/info',
url: '/user/info',
method: 'get',
params: { token }
})
......@@ -18,7 +18,7 @@ export function getInfo(token) {
export function logout() {
return request({
url: '/vue-admin-template/user/logout',
url: '/user/logout',
method: 'post'
})
}
......@@ -26,6 +26,8 @@ import { mapGetters } from 'vuex'
import Breadcrumb from '@/components/Breadcrumb'
import Hamburger from '@/components/Hamburger'
import Sidebar from './Sidebar/index.vue'
import { logout } from '@/api/user'
export default {
data() {
let timer
......@@ -51,9 +53,11 @@ export default {
toggleSideBar() {
this.$store.dispatch('app/toggleSideBar')
},
async logout() {
await this.$store.dispatch('user/logout')
this.$router.push(`/login?redirect=${this.$route.fullPath}`)
logout() {
logout().then(() => {
this.$store.dispatch('user/logout')
this.$router.push(`/login`)
})
},
// 获取当前时间函数
timeFormate (timeStamp) {
......
......@@ -3,8 +3,8 @@
<template
v-if="
hasOneShowingChild(item.children, item) &&
(!onlyOneChild.children || onlyOneChild.noShowingChildren) &&
!item.alwaysShow
(!onlyOneChild.children || onlyOneChild.noShowingChildren) &&
!item.alwaysShow
"
>
<app-link
......@@ -80,14 +80,10 @@ export default {
this.onlyOneChild = null;
return {};
},
mounted() {
// console.log(this.$refs['subMenu']);
// console.log(document.getElementById('subid'));
},
mounted() {},
methods: {
hasOneShowingChild(children = [], parent) {
const showingChildren = children.filter(item => {
const showingChildren = children.filter((item) => {
if (item.hidden) {
return false;
} else {
......@@ -135,12 +131,11 @@ export default {
width: 100%;
}
}
.el-menu--collapse .el-menu .el-submenu, .el-menu--popup{
min-width: 120px!important;
.el-menu--collapse .el-menu .el-submenu,
.el-menu--popup {
min-width: 120px !important;
}
.el-menu .el-menu--popup .el-menu--popup-bottom-start ::v-deep{
.el-menu .el-menu--popup .el-menu--popup-bottom-start ::v-deep {
width: 1020px;
}
</style>
......@@ -32,7 +32,7 @@ router.beforeEach(async(to, from, next) => {
} else {
try {
// get user info
await store.dispatch('user/getInfo')
// await store.dispatch('user/getInfo')
next()
} catch (error) {
......
import { login, logout, getInfo } from '@/api/user'
import { login, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter } from '@/router'
......@@ -67,14 +67,11 @@ const actions = {
// user logout
logout({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
removeToken() // must remove token first
resetRouter()
commit('RESET_STATE')
resolve()
}).catch(error => {
reject(error)
})
removeToken() // must remove token first
resetRouter()
commit("SET_TOKEN", "")
commit('RESET_STATE')
resolve()
})
},
......
......@@ -2,82 +2,118 @@ import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'
import Vue from 'vue'
// create an axios instance
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
baseURL: '/api/', // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout
})
let loading = {}
function startLoading(el) {
if (!el) return
let target = document.querySelector(el)
if (!target || loading[el]) return
loading[el] = Vue.prototype.$loading({
lock: true,
target
})
}
function endLoading(el) {
if (el && loading[el]) {
loading[el].close()
delete loading[el]
}
}
// request interceptor
service.interceptors.request.use(
config => {
// do something before request is sent
startLoading(config.el)
if (store.getters.token) {
// let each request carry token
// ['X-Token'] is a custom headers key
// please modify it according to the actual situation
config.headers['X-Token'] = getToken()
config.headers['Authorization'] = getToken()
} else {
config.headers['Authorization'] = '121212'
}
return config
},
error => {
// do something with request error
console.log(error) // for debug
startLoading(error.request.config.el)
return Promise.reject(error)
}
)
// response interceptor
let errorShowing = false
service.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
response => {
const res = response.data
// if the custom code is not 20000, it is judged as an error.
if (res.code !== 20000) {
Message({
message: res.message || 'Error',
type: 'error',
duration: 5 * 1000
})
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
// to re-login
MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
confirmButtonText: 'Re-Login',
cancelButtonText: 'Cancel',
type: 'warning'
}).then(() => {
store.dispatch('user/resetToken').then(() => {
location.reload()
})
})
const res = response.data.data ? response.data.data : response.data
let config = response.config
endLoading(config.el)
let resFinal = res.rsp || res || {}
let code = resFinal.errorCode || resFinal.code
let message = resFinal.message || resFinal.errorMsg || resFinal.error || '接口错误'
if(code) {
if (code == 40101) {
location.href = location.href.replace(/#.+/, '') + '#/login'
return
}
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
if (code == '401') {
!config.silence && !errorShowing && Message.error(message)
errorShowing = true
setTimeout(() => { errorShowing = false }, 3000)
store.dispatch('user/resetToken')
return
}
// if (code) {
// !config.silence && Message.error(message)
// return Promise.reject(new Error(message))
// }
}
// if (res.code !== 20000) {
// Message({
// message: res.message || 'Error',
// type: 'error',
// duration: 5 * 1000
// })
// // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
// if (res.code === 501 || res.code === 201 || res.code === 50014) {
// // to re-login
// MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
// confirmButtonText: '重新登陆',
// cancelButtonText: '取消',
// type: 'warning'
// }).then(() => {
// store.dispatch('user/resetToken').then(() => {
// location.reload()
// })
// })
// }
// return Promise.reject(new Error(res.message || 'Error'))
// } else {
return res
// }
},
error => {
console.log('err' + error) // for debug
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
if (error.response) {
endLoading(error.response.config.el)
if (!error.response.config.silence) {
Message.error(error.message)
}
}
// Message({
// message: error.message,
// type: 'error',
// duration: 5 * 1000
// })
return Promise.reject(error)
}
)
......
......@@ -34,7 +34,6 @@
ref="username"
v-model="loginForm.username"
placeholder="用户名"
name="username"
type="text"
tabindex="1"
auto-complete="on"
......@@ -72,29 +71,18 @@
@click.native.prevent="handleLogin"
>登录</el-button
>
<!-- <div class="tips">
<span style="margin-right:20px;">username: admin</span>
<span> password:任意6位</span>
</div> -->
</el-form>
</div>
</div>
</template>
<script>
import { validUsername } from "@/utils/validate";
import { login } from "@/api/user"
import { setToken } from "@/utils/auth"
export default {
name: "Login",
data() {
const validateUsername = (rule, value, callback) => {
if (!validUsername(value)) {
callback(new Error("请输入正确的用户名"));
} else {
callback();
}
};
const validatePassword = (rule, value, callback) => {
if (value.length < 6) {
callback(new Error("密码不能少于6位"));
......@@ -109,7 +97,7 @@ export default {
},
loginRules: {
username: [
{ required: true, trigger: "blur", validator: validateUsername },
{ required: true, trigger: "blur", message: '请输入用户名' },
],
password: [
{ required: true, trigger: "blur", validator: validatePassword },
......@@ -149,31 +137,52 @@ export default {
this.$refs.password.focus();
});
},
async toLogin() {
const {
username,
password
} = this.loginForm
let { token } = await login({
userName: username,
password: password,
}, {
el: '.el-button'
})
if (!token) return
this.$store.commit("user/SET_TOKEN", token)
setToken(token)
// this.$store.commit("user/SET_NAVIGATION_SHOW", false)
this.$router.push({ path: "/" })
setTimeout(() => {
location.reload()
}, 10)
},
handleLogin() {
this.$refs.loginForm.validate((valid) => {
if (valid) {
this.loading = true;
this.$store
.dispatch("user/login", this.loginForm)
.then(() => {
if (this.loginForm.password == "123456") {
this.$router.push({ path: this.redirect || "/" });
this.loading = false;
} else {
alert("密码错误");
this.loading = false;
return false;
}
})
.catch(() => {
this.loading = false;
});
this.toLogin()
// this.loading = true;
// this.$store
// .dispatch("user/login", this.loginForm)
// .then(() => {
// if (this.loginForm.password == "123456") {
// this.$router.push({ path: this.redirect || "/" });
// this.loading = false;
// } else {
// alert("密码错误");
// this.loading = false;
// return false;
// }
// })
// .catch(() => {
// this.loading = false;
// });
} else {
console.log("error submit!!");
return false;
}
});
},
},
},
};
</script>
......
......@@ -6,37 +6,44 @@ function resolve(dir) {
return path.join(__dirname, dir)
}
const name = defaultSettings.title || 'vue Admin Template' // page title
const name = defaultSettings.title || '漏缆故障定位监测系统' // page title
const port = process.env.port || process.env.npm_config_port || 8886 // dev port
// If your port is set to 80,
// use administrator privileges to execute the command line.
// For example, Mac: sudo npm run
// You can change the port by the following methods:
// port = 9528 npm run dev OR npm run dev --port = 9528
const port = process.env.port || process.env.npm_config_port || 9528 // dev port
const rewriteDefaultConfig = {
changeOrigin: true,
target: 'http://8.142.143.40:8886',
// ws: true,
headers: {
referer: 'laddercloud.cn'
},
// onProxyRes: proxyResponse => {
// if (proxyResponse.headers['set-cookie']) {
// const cookies = proxyResponse.headers['set-cookie'].map(cookie =>
// cookie.replace(/; secure/gi, '')
// )
// proxyResponse.headers['set-cookie'] = cookies
// }
// }
}
// All configuration item explanations can be find in https://cli.vuejs.org/config/
module.exports = {
/**
* You will need to set publicPath if you plan to deploy your site under a sub path,
* for example GitHub Pages. If you plan to deploy your site to https://foo.github.io/bar/,
* then publicPath should be set to "/bar/".
* In most cases please use '/' !!!
* Detail: https://cli.vuejs.org/config/#publicpath
*/
publicPath: '/',
outputDir: 'dist',
assetsDir: 'static',
lintOnSave: process.env.NODE_ENV === 'development',
productionSourceMap: false,
devServer: {
index: 'index.html',
port: port,
open: true,
overlay: {
warnings: false,
errors: true
},
before: require('./mock/mock-server.js')
proxy: {
'/api': rewriteDefaultConfig
},
// before: require('./mock/mock-server.js')
},
configureWebpack: {
// provide the app's title in webpack's name field, so that
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment