新增:登陆日志,操作日志
This commit is contained in:
parent
f6b4eefaec
commit
6eb0fab315
13
src/api/log.js
Normal file
13
src/api/log.js
Normal file
@ -0,0 +1,13 @@
|
||||
import request from '@/utils/request'
|
||||
const qs = require('qs')
|
||||
|
||||
export default {
|
||||
logList(params) {
|
||||
return request({
|
||||
url: '/log/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
</div>
|
||||
<div v-if="item.formatData">
|
||||
<div v-if="item.tag">
|
||||
<el-tag size="mini" v-for="tagname in item.formatData(scope.row[item.prop])" :key="tagname">{{tagname}}</el-tag>
|
||||
<el-tag size="mini" v-for="tag in item.formatData(scope.row[item.prop])" :type="tag.type" :key="tag.name">{{tag.name}}</el-tag>
|
||||
</div>
|
||||
<div v-else-if="item.icon">
|
||||
<svg-icon :icon-class="item.formatData(scope.row[item.prop])"></svg-icon>
|
||||
|
||||
@ -140,13 +140,13 @@ export default {
|
||||
{prop: 'roles', minWidth: 120, label: '角色', tag: true,
|
||||
formatData: (roles)=> {
|
||||
if(roles){
|
||||
let tagNames = this.roleList.map(role => {
|
||||
let tags = this.roleList.map(role => {
|
||||
if (roles.includes(role.id)) {
|
||||
return role.name
|
||||
return {name : role.name}
|
||||
}
|
||||
})
|
||||
tagNames = tagNames.filter(tagName => tagName !== undefined)
|
||||
return tagNames
|
||||
tags = tags.filter(tag => tag !== undefined)
|
||||
return tags
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
161
src/views/setting/sys/logList.vue
Normal file
161
src/views/setting/sys/logList.vue
Normal file
@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<el-card class="box-card table-search-header">
|
||||
<div slot="header">
|
||||
<div class="box-card-header">
|
||||
<el-form size="medium" class="search-form" ref="queryForm" label-width="77px" :model="queryCondition" @submit.native.prevent>
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="12" :md="8">
|
||||
<el-form-item label="账号:">
|
||||
<el-input clearable placeholder="请输入" v-model="queryCondition.username" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :sm="12" :md="9">
|
||||
<el-form-item label="时间:" prop="logTime">
|
||||
<el-date-picker
|
||||
v-model="pickerValue"
|
||||
size="medium"
|
||||
type="datetimerange"
|
||||
:picker-options="pickerOptions"
|
||||
range-separator="至"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
align="right">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :sm="12" :md="7">
|
||||
<div class="el-form-actions">
|
||||
<el-button class="card-btn-icon" size="medium" icon="el-icon-search" type="primary" @click="getLogList()">查询</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<table-list
|
||||
:less-client-height="280"
|
||||
:tableData="dataList"
|
||||
:loading="loading"
|
||||
:hasSelection="false"
|
||||
:tableHeader="tableHeader"
|
||||
:pagination="pagination"
|
||||
@pageChange="pageChange"
|
||||
@sortChange="sortChange"
|
||||
></table-list>
|
||||
</el-card>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import logApi from '@/api/log'
|
||||
import TableList from "@/components/table/TableList";
|
||||
|
||||
export default {
|
||||
name: 'LogList',
|
||||
components: {
|
||||
TableList
|
||||
},
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
tableHeader: {
|
||||
type: Array,
|
||||
default: []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dataList: [],
|
||||
loading: false,
|
||||
// 分页信息
|
||||
pagination: {
|
||||
pageIndex: 1,
|
||||
pageSize: 12,
|
||||
pageTotal: 0
|
||||
},
|
||||
// 查询条件
|
||||
queryCondition: {
|
||||
username: undefined,
|
||||
type: this.type,
|
||||
startTime: undefined,
|
||||
endTime: undefined
|
||||
},
|
||||
pickerValue: [],
|
||||
pickerOptions: {
|
||||
shortcuts: [{
|
||||
text: '最近一周',
|
||||
onClick(picker) {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
|
||||
picker.$emit('pick', [start, end]);
|
||||
}
|
||||
}, {
|
||||
text: '最近一个月',
|
||||
onClick(picker) {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
|
||||
picker.$emit('pick', [start, end]);
|
||||
}
|
||||
}, {
|
||||
text: '最近三个月',
|
||||
onClick(picker) {
|
||||
const end = new Date();
|
||||
const start = new Date();
|
||||
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90);
|
||||
picker.$emit('pick', [start, end]);
|
||||
}
|
||||
}]
|
||||
},
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getLogList()
|
||||
},
|
||||
methods: {
|
||||
//表格组件返回排序对象
|
||||
sortChange(data) {
|
||||
let column = data.backData;
|
||||
this.queryCondition.sortProp = column.prop
|
||||
this.queryCondition.sortOrder = column.order
|
||||
this.getLogList()
|
||||
},
|
||||
//分页导航
|
||||
pageChange(data) {
|
||||
this.pagination = data.backData;
|
||||
this.getLogList()
|
||||
},
|
||||
getLogList(){
|
||||
if (this.pickerValue.length > 0){
|
||||
this.queryCondition.startTime = this.pickerValue[0].getTime()
|
||||
this.queryCondition.endTime = this.pickerValue[1].getTime()
|
||||
}
|
||||
this.loading = true
|
||||
logApi.logList({
|
||||
page: this.pagination.pageIndex,
|
||||
pageSize: this.pagination.pageSize,
|
||||
...this.queryCondition
|
||||
}).then(res => {
|
||||
this.dataList = res.data
|
||||
this.pagination.pageTotal = res.count
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "src/styles/setting";
|
||||
.box-card {
|
||||
max-width: 1440px;
|
||||
}
|
||||
/deep/.el-range-editor--medium {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
41
src/views/setting/sys/logLogin.vue
Normal file
41
src/views/setting/sys/logLogin.vue
Normal file
@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div>
|
||||
<log-list type="LOGIN" :table-header="tableHeader"></log-list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LogList from "@/views/setting/sys/logList";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LogList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableHeader: [
|
||||
{prop: 'username',label: '账号', sortable: 'custom'},
|
||||
{prop: 'showName',label: '用户名', sortable: 'custom'},
|
||||
{prop: 'ip',label: 'IP地址', sortable: 'custom'},
|
||||
{prop: 'deviceModel',label: '设备型号', sortable: 'custom'},
|
||||
{prop: 'operatingSystem',label: '操作系统', sortable: 'custom'},
|
||||
{prop: 'browser',label: '浏览器', sortable: 'custom'},
|
||||
{prop: 'status', minWidth: 80, label: '状态', tag: true,
|
||||
formatData: (status)=> {
|
||||
if(status === 0) {
|
||||
return [{name: '登陆成功', type: 'success'}]
|
||||
} else {
|
||||
return [{name: '登陆失败', type: 'danger'}]
|
||||
}
|
||||
}
|
||||
},
|
||||
{prop: 'remarks',label: '备注', sortable: 'custom'},
|
||||
{prop: 'createTime',label: '创建时间', minWidth: 110, sortable: 'custom'},
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
122
src/views/setting/sys/logOperation.vue
Normal file
122
src/views/setting/sys/logOperation.vue
Normal file
@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-dialog class="dialog-form" width="600px" title="详情" :visible.sync="dialogVisible">
|
||||
<el-form size="medium" ref="managerForm" label-width="90px" :model="detailsData">
|
||||
<el-row :gutter="10">
|
||||
<el-col :sm="12">
|
||||
<el-form-item label="操作人:">
|
||||
<div>{{detailsData.showName}}({{detailsData.username}})</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作模块:">
|
||||
<div>{{detailsData.operationModule}}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作时间:">
|
||||
<div>{{detailsData.createTime}}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="请求方式:">
|
||||
<div>{{detailsData.method}}</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :sm="12">
|
||||
<el-form-item label="IP地址:">
|
||||
<div>{{detailsData.ip}}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="操作功能:">
|
||||
<div>{{detailsData.operationFun}}</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="请求耗时:">
|
||||
<div>{{detailsData.time}}ms</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="请求状态:">
|
||||
<el-tag size="mini" :type="detailsData.status === 0 ? 'success': 'danger'">{{detailsData.status === 0 ? '正常':'异常'}}</el-tag>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-divider></el-divider>
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form-item label="请求地址:">
|
||||
<div>{{detailsData.url}}</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-form-item label="请求参数:">
|
||||
<div>{{detailsData.params}}</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col>
|
||||
<el-form-item label="备注:">
|
||||
<div>{{detailsData.remarks}}</div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button size="small" @click="dialogVisible = false">关闭</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
<log-list type="OPERATION" :table-header="tableHeader"></log-list>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LogList from "@/views/setting/sys/logList";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LogList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableHeader: [
|
||||
{prop: 'username',label: '账号', minWidth: 105, sortable: 'custom'},
|
||||
{prop: 'showName',label: '用户名', minWidth: 105, sortable: 'custom'},
|
||||
{prop: 'ip',label: 'IP地址', minWidth: 105, sortable: 'custom'},
|
||||
{prop: 'operationModule',label: '操作模块', minWidth: 105, sortable: 'custom'},
|
||||
{prop: 'operationFun',label: '操作功能', minWidth: 105, sortable: 'custom'},
|
||||
{prop: 'url',label: '请求地址', minWidth: 105, sortable: 'custom'},
|
||||
{prop: 'method',label: '方式', minWidth: 75, sortable: 'custom'},
|
||||
{prop: 'status', minWidth: 75, label: '状态', tag: true, sortable: 'custom',
|
||||
formatData: (status)=> {
|
||||
if(status === 0) {
|
||||
return [{name: '正常', type: 'success'}]
|
||||
} else {
|
||||
return [{name: '异常', type: 'danger'}]
|
||||
}
|
||||
}
|
||||
},
|
||||
{prop: 'time', label: '耗时', minWidth: 75, sortable: 'custom',
|
||||
formatData: (time)=> {
|
||||
return time + 'ms'
|
||||
}
|
||||
},
|
||||
{prop: 'createTime',label: '创建时间', minWidth: 110, sortable: 'custom'},
|
||||
{label: '操作', minWidth: 75, active: [
|
||||
{name: '详情', icon: 'el-icon-view', handle: (row) => this.details(row)},
|
||||
],
|
||||
},
|
||||
],
|
||||
dialogVisible: false,
|
||||
detailsData: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
details(row) {
|
||||
this.detailsData = row
|
||||
this.dialogVisible = true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "src/styles/setting";
|
||||
/deep/ .box-card {
|
||||
max-width: 1440px;
|
||||
}
|
||||
/deep/ .el-form-item {
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
/deep/.el-divider--horizontal {
|
||||
margin: 10px 0;
|
||||
}
|
||||
</style>
|
||||
@ -184,15 +184,15 @@ export default {
|
||||
formatData: (menuType)=> {
|
||||
switch (menuType) {
|
||||
case 0:
|
||||
return ['首页菜单']
|
||||
return [{name: '首页菜单'}]
|
||||
case 1:
|
||||
return ['按钮']
|
||||
return [{name: '按钮'}]
|
||||
case 2:
|
||||
return ['设置菜单']
|
||||
return [{name: '设置菜单'}]
|
||||
case 3:
|
||||
return ['顶部菜单']
|
||||
return [{name: '顶部菜单'}]
|
||||
case 4:
|
||||
return ['右上角菜单']
|
||||
return [{name: '右上角菜单'}]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user