feat: access log mangement
This commit is contained in:
@@ -1 +1,2 @@
|
||||
VUE_APP_API_BASE_URL=https://apis.lihailezzc.com
|
||||
VUE_APP_API_BASE_URL=http://127.0.0.1:3999
|
||||
# VUE_APP_API_BASE_URL=https://apis.lihailezzc.com
|
||||
15180
pnpm-lock.yaml
generated
15180
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -23,19 +23,7 @@
|
||||
<h1><%= VUE_APP_TITLE %></h1>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
;/^http(s*):\/\//.test(location.href) || alert('基于vue-admin-beautiful-pro开源版开发的项目需要部署到服务器下访问')
|
||||
</script>
|
||||
<script>
|
||||
if (window.location.hostname !== 'localhost') {
|
||||
var _hmt = _hmt || []
|
||||
;(function () {
|
||||
var hm = document.createElement('script')
|
||||
hm.src = 'https://hm.baidu.com/hm.js?7174bade1219f9cc272e7978f9523fc8'
|
||||
var s = document.getElementsByTagName('script')[0]
|
||||
s.parentNode.insertBefore(hm, s)
|
||||
})()
|
||||
}
|
||||
</script>
|
||||
<script></script>
|
||||
<script></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
33
src/api/accessLogManagement.js
Normal file
33
src/api/accessLogManagement.js
Normal file
@@ -0,0 +1,33 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getList(data) {
|
||||
return request({
|
||||
url: '/management/api/access_log/list',
|
||||
method: 'get',
|
||||
params: data,
|
||||
})
|
||||
}
|
||||
|
||||
export function doAdd(data) {
|
||||
return request({
|
||||
url: '/management/access_log/role',
|
||||
method: 'post',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
export function doEdit(id, data) {
|
||||
return request({
|
||||
url: `/management/api/access_log/${id}`,
|
||||
method: 'put',
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
export function doDelete(data) {
|
||||
return request({
|
||||
url: '/management/api/access_log/delete',
|
||||
method: 'put',
|
||||
data,
|
||||
})
|
||||
}
|
||||
@@ -5,10 +5,10 @@ import router from './router'
|
||||
import './plugins'
|
||||
import '@/layouts/export'
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
const { mockXHR } = require('@/utils/static')
|
||||
mockXHR()
|
||||
}
|
||||
// if (process.env.NODE_ENV === 'production') {
|
||||
// const { mockXHR } = require('@/utils/static')
|
||||
// mockXHR()
|
||||
// }
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
|
||||
@@ -324,6 +324,12 @@ export const asyncRoutes = [
|
||||
component: () => import('@/views/personnelManagement/roleManagement/index'),
|
||||
meta: { title: '角色管理' },
|
||||
},
|
||||
{
|
||||
path: 'accessLogManagement',
|
||||
name: 'AccessLogManagement',
|
||||
component: () => import('@/views/personnelManagement/accessLogManagement/index'),
|
||||
meta: { title: '访问日志' },
|
||||
},
|
||||
// {
|
||||
// path: 'menuManagement',
|
||||
// name: 'MenuManagement',
|
||||
|
||||
@@ -1,8 +1,3 @@
|
||||
/**
|
||||
* @author https://github.com/zxwk1998/vue-admin-better (不想保留author可删除)
|
||||
* @description 登录、获取用户信息、退出登录、清除accessToken逻辑,不建议修改
|
||||
*/
|
||||
|
||||
import Vue from 'vue'
|
||||
import { getUserInfo, login, logout } from '@/api/user'
|
||||
import { getAccessToken, removeAccessToken, setAccessToken } from '@/utils/accessToken'
|
||||
@@ -13,6 +8,8 @@ const state = () => ({
|
||||
accessToken: getAccessToken(),
|
||||
username: '',
|
||||
avatar: '',
|
||||
appId: '',
|
||||
userId: '',
|
||||
permissions: [],
|
||||
})
|
||||
const getters = {
|
||||
@@ -20,6 +17,8 @@ const getters = {
|
||||
username: (state) => state.username,
|
||||
avatar: (state) => state.avatar,
|
||||
permissions: (state) => state.permissions,
|
||||
appId: (state) => state.appId,
|
||||
userId: (state) => state.userId,
|
||||
}
|
||||
const mutations = {
|
||||
setAccessToken(state, accessToken) {
|
||||
@@ -29,6 +28,12 @@ const mutations = {
|
||||
setUsername(state, username) {
|
||||
state.username = username
|
||||
},
|
||||
setUserId(state, userId) {
|
||||
state.userId = userId
|
||||
},
|
||||
setAppId(state, appId) {
|
||||
state.appId = appId
|
||||
},
|
||||
setAvatar(state, avatar) {
|
||||
state.avatar = avatar
|
||||
},
|
||||
@@ -63,11 +68,13 @@ const actions = {
|
||||
Vue.prototype.$baseMessage('验证失败,请重新登录...', 'error')
|
||||
return false
|
||||
}
|
||||
let { permissions, username, avatar, appIcon, appName } = data
|
||||
let { permissions, username, avatar, appIcon, appName, userId, appId } = data
|
||||
if (permissions && username && Array.isArray(permissions)) {
|
||||
commit('setPermissions', permissions)
|
||||
commit('setUsername', username)
|
||||
commit('setAvatar', avatar)
|
||||
commit('setAppId', appId)
|
||||
commit('setUserId', userId)
|
||||
dispatch('settings/changeLogo', appIcon, { root: true })
|
||||
dispatch('settings/changeTitle', appName, { root: true })
|
||||
return permissions
|
||||
|
||||
@@ -18,12 +18,6 @@ import { isArray } from '@/utils/validate'
|
||||
|
||||
let loadingInstance
|
||||
|
||||
/**
|
||||
* @author https://github.com/zxwk1998/vue-admin-better (不想保留author可删除)
|
||||
* @description 处理code异常
|
||||
* @param {*} code
|
||||
* @param {*} msg
|
||||
*/
|
||||
const handleCode = (code, msg) => {
|
||||
switch (code) {
|
||||
case invalidCode:
|
||||
@@ -55,9 +49,13 @@ instance.interceptors.request.use(
|
||||
if (store.getters['user/accessToken']) {
|
||||
config.headers['authorization'] = store.getters['user/accessToken']
|
||||
}
|
||||
// 处理 GET 请求参数
|
||||
if (store.getters['user/userId']) {
|
||||
config.headers['x-user-id'] = store.getters['user/userId']
|
||||
}
|
||||
if (store.getters['user/appId']) {
|
||||
config.headers['x-app-id'] = store.getters['user/appId']
|
||||
}
|
||||
if (config.method === 'get' && config.params) {
|
||||
// 过滤掉空值参数
|
||||
config.params = Vue.prototype.$baseLodash.pickBy(config.params, Vue.prototype.$baseLodash.identity)
|
||||
}
|
||||
//这里会过滤所有为空、0、false的key,如果不需要请自行注释
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
/**
|
||||
* @author https://vuejs-core.cn
|
||||
* @description 导入所有 controller 模块,浏览器环境中自动输出controller文件夹下Mock接口,请勿修改。
|
||||
*/
|
||||
import Mock from 'mockjs'
|
||||
import { paramObj } from '@/utils'
|
||||
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
<el-row :gutter="20">
|
||||
<el-col :lg="12" :md="12" :sm="24" :xl="12" :xs="24">
|
||||
<div class="pic-error">
|
||||
<img alt="401" class="pic-error-parent" src="@/assets/error_images/401.png" />
|
||||
<img alt="401" class="pic-error-child left" src="@/assets/error_images/cloud.png" />
|
||||
<img alt="401" class="pic-error-child" src="@/assets/error_images/cloud.png" />
|
||||
<img alt="401" class="pic-error-child" src="@/assets/error_images/cloud.png" />
|
||||
<img alt="401" class="pic-error-parent" :src="require('@/assets/error_images/401.png')" />
|
||||
<img alt="401" class="pic-error-child left" :src="require('@/assets/error_images/cloud.png')" />
|
||||
<img alt="401" class="pic-error-child" :src="require('@/assets/error_images/cloud.png')" />
|
||||
<img alt="401" class="pic-error-child" :src="require('@/assets/error_images/cloud.png')" />
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
|
||||
@@ -35,9 +35,9 @@
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-button class="login-btn" :loading="loading" type="primary" @click="handleLogin">登录</el-button>
|
||||
<router-link to="/register">
|
||||
<!-- <router-link to="/register">
|
||||
<div style="margin-top: 20px">注册</div>
|
||||
</router-link>
|
||||
</router-link> -->
|
||||
</el-form>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
102
src/views/personnelManagement/accessLogManagement/index.vue
Normal file
102
src/views/personnelManagement/accessLogManagement/index.vue
Normal file
@@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<div class="accessLogManagement-container">
|
||||
<vab-query-form>
|
||||
<vab-query-form-right-panel :span="12">
|
||||
<el-form :inline="true" :model="queryForm" @submit.native.prevent>
|
||||
<el-form-item>
|
||||
<el-input v-model.trim="queryForm.permission" clearable placeholder="请输入查询条件" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="el-icon-search" type="primary" @click="queryData">查询</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</vab-query-form-right-panel>
|
||||
</vab-query-form>
|
||||
|
||||
<el-table v-loading="listLoading" :data="list" :element-loading-text="elementLoadingText" @selection-change="setSelectRows">
|
||||
<el-table-column show-overflow-tooltip type="selection" />
|
||||
<el-table-column align="center" label="IP" prop="ip" show-overflow-tooltip />
|
||||
<el-table-column align="center" label="地址" prop="address" show-overflow-tooltip />
|
||||
<el-table-column align="center" label="url" prop="url" show-overflow-tooltip />
|
||||
<el-table-column align="center" label="应用" show-overflow-tooltip>
|
||||
<template slot-scope="{ row }">
|
||||
{{ row.appName || row.addId }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="用户" show-overflow-tooltip>
|
||||
<template slot-scope="{ row }">
|
||||
{{ row.userName || row.userId }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="userAgent" prop="userAgent" show-overflow-tooltip />
|
||||
<el-table-column align="center" label="referrer" prop="referrer" show-overflow-tooltip />
|
||||
</el-table>
|
||||
<el-pagination
|
||||
background
|
||||
:current-page="queryForm.pageNo"
|
||||
:layout="layout"
|
||||
:page-size="queryForm.pageSize"
|
||||
:total="total"
|
||||
@current-change="handleCurrentChange"
|
||||
@size-change="handleSizeChange"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getList } from '@/api/accessLogManagement'
|
||||
import { formatTime } from '@/utils'
|
||||
|
||||
export default {
|
||||
name: 'AccessLogManagement',
|
||||
data() {
|
||||
return {
|
||||
list: null,
|
||||
listLoading: true,
|
||||
layout: 'total, sizes, prev, pager, next, jumper',
|
||||
total: 0,
|
||||
selectRows: '',
|
||||
elementLoadingText: '正在加载...',
|
||||
queryForm: {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
permission: '',
|
||||
},
|
||||
timeOutID: null,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchData()
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
clearTimeout(this.timeOutID)
|
||||
},
|
||||
methods: {
|
||||
setSelectRows(val) {
|
||||
this.selectRows = val
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.queryForm.pageSize = val
|
||||
this.fetchData()
|
||||
},
|
||||
handleCurrentChange(val) {
|
||||
this.queryForm.pageNo = val
|
||||
this.fetchData()
|
||||
},
|
||||
queryData() {
|
||||
this.queryForm.pageNo = 1
|
||||
this.fetchData()
|
||||
},
|
||||
async fetchData() {
|
||||
this.listLoading = true
|
||||
const { data } = await getList(this.queryForm)
|
||||
this.list = data.list
|
||||
this.total = data.totalCount
|
||||
this.timeOutID = setTimeout(() => {
|
||||
this.listLoading = false
|
||||
}, 300)
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div class="appManagement-container">
|
||||
<el-divider content-position="left">
|
||||
演示环境仅做基础功能展示,若想实现不同角色的真实菜单配置,需将settings.js路由加载模式改为all模式,由后端全面接管路由渲染与权限控制
|
||||
</el-divider>
|
||||
<vab-query-form>
|
||||
<vab-query-form-left-panel :span="12">
|
||||
<el-button icon="el-icon-plus" type="primary" @click="handleEdit">添加</el-button>
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div class="menuManagement-container">
|
||||
<el-divider content-position="left">
|
||||
演示环境仅做基础功能展示,若想实现不同角色的真实菜单配置,需将settings.js路由加载模式改为all模式,由后端全面接管路由渲染与权限控制
|
||||
</el-divider>
|
||||
<el-row>
|
||||
<el-col :lg="4" :md="8" :sm="24" :xl="4" :xs="24">
|
||||
<el-tree :data="data" :default-expanded-keys="['root']" node-key="id" :props="defaultProps" @node-click="handleNodeClick" />
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div class="roleManagement-container">
|
||||
<el-divider content-position="left">
|
||||
演示环境仅做基础功能展示,若想实现不同角色的真实菜单配置,需将settings.js路由加载模式改为all模式,由后端全面接管路由渲染与权限控制
|
||||
</el-divider>
|
||||
<vab-query-form>
|
||||
<vab-query-form-left-panel :span="12">
|
||||
<el-button icon="el-icon-plus" type="primary" @click="handleEdit">添加</el-button>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button class="register-btn" type="primary" @click.native.prevent="handleReister">注册</el-button>
|
||||
<!-- <el-button class="register-btn" type="primary" @click.native.prevent="handleReister">注册</el-button> -->
|
||||
<router-link to="/login">
|
||||
<div style="margin-top: 20px">登录</div>
|
||||
</router-link>
|
||||
@@ -111,47 +111,47 @@
|
||||
}
|
||||
},
|
||||
created() {
|
||||
document.body.style.overflow = 'hidden'
|
||||
// document.body.style.overflow = 'hidden'
|
||||
},
|
||||
beforeDestroy() {
|
||||
document.body.style.overflow = 'auto'
|
||||
clearInterval(this.getPhoneIntval)
|
||||
this.getPhoneIntval = null
|
||||
// document.body.style.overflow = 'auto'
|
||||
// clearInterval(this.getPhoneIntval)
|
||||
// this.getPhoneIntval = null
|
||||
},
|
||||
methods: {
|
||||
getPhoneCode() {
|
||||
if (!isPhone(this.form.phone)) {
|
||||
//this.$baseMessage('请输入手机号', 'error')
|
||||
this.$refs['registerForm'].validateField('phone')
|
||||
return
|
||||
}
|
||||
this.isGetphone = true
|
||||
let n = 60
|
||||
this.getPhoneIntval = setInterval(() => {
|
||||
if (n > 0) {
|
||||
n--
|
||||
this.phoneCode = `重新获取(${n}s)`
|
||||
} else {
|
||||
clearInterval(this.getPhoneIntval)
|
||||
this.getPhoneIntval = null
|
||||
this.phoneCode = '获取验证码'
|
||||
this.isGetphone = false
|
||||
}
|
||||
}, 1000)
|
||||
// if (!isPhone(this.form.phone)) {
|
||||
// //this.$baseMessage('请输入手机号', 'error')
|
||||
// this.$refs['registerForm'].validateField('phone')
|
||||
// return
|
||||
// }
|
||||
// this.isGetphone = true
|
||||
// let n = 60
|
||||
// this.getPhoneIntval = setInterval(() => {
|
||||
// if (n > 0) {
|
||||
// n--
|
||||
// this.phoneCode = `重新获取(${n}s)`
|
||||
// } else {
|
||||
// clearInterval(this.getPhoneIntval)
|
||||
// this.getPhoneIntval = null
|
||||
// this.phoneCode = '获取验证码'
|
||||
// this.isGetphone = false
|
||||
// }
|
||||
// }, 1000)
|
||||
},
|
||||
handleReister() {
|
||||
this.$refs['registerForm'].validate(async (valid) => {
|
||||
if (valid) {
|
||||
const param = {
|
||||
username: this.form.username,
|
||||
phone: this.form.phone,
|
||||
password: this.form.password,
|
||||
phoneCode: this.form.phoneCode,
|
||||
}
|
||||
const { msg } = await register(param)
|
||||
this.$baseMessage(msg, 'success')
|
||||
}
|
||||
})
|
||||
// this.$refs['registerForm'].validate(async (valid) => {
|
||||
// if (valid) {
|
||||
// const param = {
|
||||
// username: this.form.username,
|
||||
// phone: this.form.phone,
|
||||
// password: this.form.password,
|
||||
// phoneCode: this.form.phoneCode,
|
||||
// }
|
||||
// const { msg } = await register(param)
|
||||
// this.$baseMessage(msg, 'success')
|
||||
// }
|
||||
// })
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ const WebpackBar = require('webpackbar')
|
||||
const dayjs = require('dayjs')
|
||||
const date = dayjs().format('YYYY_M_D')
|
||||
const time = dayjs().format('YYYY-M-D HH:mm:ss')
|
||||
process.env.VUE_APP_TITLE = title || 'vue-admin-better'
|
||||
process.env.VUE_APP_AUTHOR = author || 'https://vuejs-core.cn'
|
||||
process.env.VUE_APP_TITLE = title || 'admin'
|
||||
process.env.VUE_APP_AUTHOR = author || 'zzc'
|
||||
process.env.VUE_APP_UPDATE_TIME = time
|
||||
process.env.VUE_APP_VERSION = version
|
||||
|
||||
@@ -136,15 +136,15 @@ module.exports = {
|
||||
.plugin('banner')
|
||||
.use(Webpack.BannerPlugin, [`${webpackBanner}${time}`])
|
||||
.end()
|
||||
if (imageCompression)
|
||||
config.module
|
||||
.rule('images')
|
||||
.use('image-webpack-loader')
|
||||
.loader('image-webpack-loader')
|
||||
.options({
|
||||
bypassOnDebug: true,
|
||||
})
|
||||
.end()
|
||||
// if (imageCompression)
|
||||
// config.module
|
||||
// .rule('images')
|
||||
// // .use('image-webpack-loader')
|
||||
// // .loader('image-webpack-loader')
|
||||
// .options({
|
||||
// bypassOnDebug: true,
|
||||
// })
|
||||
// .end()
|
||||
})
|
||||
},
|
||||
runtimeCompiler: true,
|
||||
|
||||
Reference in New Issue
Block a user