Browse Source

通知管理/系统日志

master
xuhuajiao 2 years ago
parent
commit
38f92a51c4
  1. 70
      src/assets/iconfonts/light/iconfont.css
  2. 2
      src/assets/iconfonts/light/iconfont.js
  3. 112
      src/assets/iconfonts/light/iconfont.json
  4. BIN
      src/assets/iconfonts/light/iconfont.ttf
  5. BIN
      src/assets/iconfonts/light/iconfont.woff
  6. BIN
      src/assets/iconfonts/light/iconfont.woff2
  7. 1
      src/assets/styles/mixin.scss
  8. 161
      src/views/system/log/errorLog/index.vue
  9. 148
      src/views/system/log/index.vue
  10. 92
      src/views/system/log/index2.vue
  11. 104
      src/views/system/log/loginLog/index.vue
  12. 143
      src/views/system/log/operateLog/index.vue
  13. 90
      src/views/system/log/search.vue
  14. 26
      src/views/system/notifyManage/data.json
  15. 41
      src/views/system/notifyManage/index.vue
  16. 177
      src/views/system/notifyManage/module/selectObj.vue

70
src/assets/iconfonts/light/iconfont.css

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 3966148 */
src: url('iconfont.woff2?t=1679470396117') format('woff2'),
url('iconfont.woff?t=1679470396117') format('woff'),
url('iconfont.ttf?t=1679470396117') format('truetype');
src: url('iconfont.woff2?t=1681870503932') format('woff2'),
url('iconfont.woff?t=1681870503932') format('woff'),
url('iconfont.ttf?t=1681870503932') format('truetype');
}
.iconfont {
@ -13,6 +13,70 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-fabu:before {
content: "\e643";
}
.icon-guaqi:before {
content: "\e63b";
}
.icon-jihuo:before {
content: "\e63d";
}
.icon-xiala-shouqi:before {
content: "\e63e";
}
.icon-xiala-chakanxinxi:before {
content: "\e63f";
}
.icon-chakan:before {
content: "\e640";
}
.icon-jiazaigengduo:before {
content: "\e641";
}
.icon-quanbuyidu:before {
content: "\e642";
}
.icon-shangchuan:before {
content: "\e62b";
}
.icon-yonghuyouxiang:before {
content: "\e635";
}
.icon-yonghuming:before {
content: "\e636";
}
.icon-suoshubumen:before {
content: "\e637";
}
.icon-suoshuquanzong:before {
content: "\e638";
}
.icon-shoujihaoma:before {
content: "\e639";
}
.icon-yonghujiaose:before {
content: "\e63a";
}
.icon-xingbie:before {
content: "\e63c";
}
.icon-dianzibiao:before {
content: "\e623";
}

2
src/assets/iconfonts/light/iconfont.js
File diff suppressed because it is too large
View File

112
src/assets/iconfonts/light/iconfont.json

@ -5,6 +5,118 @@
"css_prefix_text": "icon-",
"description": "",
"glyphs": [
{
"icon_id": "35119672",
"name": "发布",
"font_class": "fabu",
"unicode": "e643",
"unicode_decimal": 58947
},
{
"icon_id": "35004711",
"name": "挂起",
"font_class": "guaqi",
"unicode": "e63b",
"unicode_decimal": 58939
},
{
"icon_id": "35004712",
"name": "激活",
"font_class": "jihuo",
"unicode": "e63d",
"unicode_decimal": 58941
},
{
"icon_id": "35004753",
"name": "下拉-收起",
"font_class": "xiala-shouqi",
"unicode": "e63e",
"unicode_decimal": 58942
},
{
"icon_id": "35004754",
"name": "下拉-查看信息",
"font_class": "xiala-chakanxinxi",
"unicode": "e63f",
"unicode_decimal": 58943
},
{
"icon_id": "35004755",
"name": "查看",
"font_class": "chakan",
"unicode": "e640",
"unicode_decimal": 58944
},
{
"icon_id": "35004756",
"name": "加载更多",
"font_class": "jiazaigengduo",
"unicode": "e641",
"unicode_decimal": 58945
},
{
"icon_id": "35004757",
"name": "全部已读",
"font_class": "quanbuyidu",
"unicode": "e642",
"unicode_decimal": 58946
},
{
"icon_id": "35004555",
"name": "上传",
"font_class": "shangchuan",
"unicode": "e62b",
"unicode_decimal": 58923
},
{
"icon_id": "35004562",
"name": "用户邮箱",
"font_class": "yonghuyouxiang",
"unicode": "e635",
"unicode_decimal": 58933
},
{
"icon_id": "35004563",
"name": "用户名",
"font_class": "yonghuming",
"unicode": "e636",
"unicode_decimal": 58934
},
{
"icon_id": "35004564",
"name": "所属部门",
"font_class": "suoshubumen",
"unicode": "e637",
"unicode_decimal": 58935
},
{
"icon_id": "35004565",
"name": "所属全宗",
"font_class": "suoshuquanzong",
"unicode": "e638",
"unicode_decimal": 58936
},
{
"icon_id": "35004566",
"name": "手机号码",
"font_class": "shoujihaoma",
"unicode": "e639",
"unicode_decimal": 58937
},
{
"icon_id": "35004567",
"name": "用户角色",
"font_class": "yonghujiaose",
"unicode": "e63a",
"unicode_decimal": 58938
},
{
"icon_id": "35004569",
"name": "性别",
"font_class": "xingbie",
"unicode": "e63c",
"unicode_decimal": 58940
},
{
"icon_id": "34690983",
"name": "电子表",

BIN
src/assets/iconfonts/light/iconfont.ttf

BIN
src/assets/iconfonts/light/iconfont.woff

BIN
src/assets/iconfonts/light/iconfont.woff2

1
src/assets/styles/mixin.scss

@ -860,3 +860,4 @@
}
}
}

161
src/views/system/log/errorLog/index.vue

@ -0,0 +1,161 @@
<template>
<div>
<Search />
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler" @cell-dblclick="tableDoubleClick">
<el-table-column type="selection" width="55" align="center" />
<el-table-column align="center" type="expand">
<template slot-scope="props">
<el-form label-position="left" inline class="demo-table-expand">
<el-form-item label="请求方法">
<span>{{ props.row.method }}</span>
</el-form-item>
<el-form-item label="请求参数">
<span style="word-break:break-all;">{{ props.row.params }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column align="center" prop="account" label="账号" />
<el-table-column align="center" prop="username" label="用户名" />
<el-table-column prop="username" label="所属全宗" align="center" />
<el-table-column prop="det" label="所属部门" align="center" />
<el-table-column align="center" prop="requestIp" label="IP" />
<el-table-column align="center" :show-overflow-tooltip="true" prop="address" label="IP来源" />
<el-table-column align="center" prop="description" label="内容描述" />
<el-table-column align="center" prop="browser" label="浏览器" />
<el-table-column align="center" prop="createTime" label="创建时间">
<template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
</template>
</el-table-column>
<!-- <el-table-column align="center" label="异常详情" width="100px">
<template slot-scope="scope">
<el-button size="mini" type="text" @click="info(scope.row.id)">查看详情</el-button>
</template>
</el-table-column> -->
</el-table>
<el-dialog :visible.sync="dialog" title="异常详情" append-to-body top="30px">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<pre v-highlightjs="errorInfo"><code class="java" /></pre>
</div>
</el-dialog>
<!--分页组件-->
<pagination />
<!-- 清空 -->
<el-dialog :visible.sync="delVisible" title="确认清空">
<div class="setting-dialog">
<p class="delMsg" style="padding-top:20px">确认清空所有操作日志吗?</p>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="confirmDelAll">确定</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import { getErrDetail, delAllError } from '@/api/monitor/log'
import Search from '@/views/system/log/search.vue'
import CRUD, { presenter } from '@crud/crud'
import pagination from '@crud/Pagination'
export default {
name: 'ErrorLog',
components: { Search, pagination },
cruds() {
return CRUD({ title: '异常日志', url: 'api/logs/error' })
},
mixins: [presenter()],
data() {
return {
errorInfo: '', dialog: false, delVisible: false
}
},
created() {
this.crud.optShow = {
add: false,
edit: false,
del: false,
download: true,
reset: true,
group: false
}
},
methods: {
//
info(id) {
this.dialog = true
getErrDetail(id).then(res => {
this.errorInfo = res.exception
})
},
// table -
tableDoubleClick(row) {
this.dialog = true
getErrDetail(row.id).then(res => {
this.errorInfo = res.exception
})
},
confirmDelAll() {
// this.$confirm(`?`, '', {
// confirmButtonText: '',
// cancelButtonText: '',
// type: 'warning'
// }).then(() => {
this.crud.delAllLoading = true
delAllError().then(res => {
this.crud.delAllLoading = false
this.crud.dleChangePage(1)
this.crud.delSuccessNotify()
this.crud.toQuery()
this.delVisible = false
}).catch(err => {
this.crud.delAllLoading = false
console.log(err.response.data.message)
})
// }).catch(() => {
// })
}
}
}
</script>
<style lang="scss" scoped>
::v-deep .el-table__expanded-cell{
padding: 0 !important;
}
.demo-table-expand {
padding: 10px 30px;
background-color: #F5F9FC;
}
.demo-table-expand {
.el-form-item {
display: flex;
justify-content: flex-start;
margin-right: 0;
margin-bottom: 0;
width: 100%;
::v-deep .el-form-item__label{
width: 80px !important;
font-size: 12px;
color: #0C0E1E;
}
::v-deep .el-form-item__content {
font-size: 12px;
color: #545B65;
}
}
}
::v-deep .el-dialog .el-dialog__body{
padding: 10px 0 30px 0;
}
.java.hljs {
color: #545B65 !important;
background: transparent !important;
width: 100%;
height: 630px !important;
}
</style>

148
src/views/system/log/index.vue

@ -1,141 +1,57 @@
<template>
<div>
<div class="head-container">
<Search />
<crudOperation>
<el-button
slot="left"
type="danger"
icon="el-icon-delete"
size="mini"
:loading="crud.delAllLoading"
@click="delVisible = true"
>
清空
</el-button>
</crudOperation>
</div>
<!--表格渲染-->
<div class="app-container container-wrap" style="min-height: calc(100vh - 242px)">
<div class="app-container tab-container">
<div class="tab-content">
<span class="right-top-line" />
<span class="left-bottom-line" />
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" inline class="demo-table-expand">
<el-form-item label="请求方法">
<span>{{ props.row.method }}</span>
</el-form-item>
<el-form-item label="请求参数">
<span>{{ props.row.params }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column prop="username" label="用户名" />
<el-table-column prop="requestIp" label="IP" />
<el-table-column :show-overflow-tooltip="true" prop="address" label="IP来源" />
<el-table-column prop="description" label="描述" />
<el-table-column prop="browser" label="浏览器" />
<el-table-column prop="time" label="请求耗时" align="center">
<template slot-scope="scope">
<el-tag v-if="scope.row.time <= 300">{{ scope.row.time }}ms</el-tag>
<el-tag v-else-if="scope.row.time <= 1000" type="warning">{{ scope.row.time }}ms</el-tag>
<el-tag v-else type="danger">{{ scope.row.time }}ms</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建日期" width="180px" />
</el-table>
<!--分页组件-->
<pagination />
<!-- 清空 -->
<el-dialog :visible.sync="delVisible" title="确认清空">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<p class="delMsg">确认清空所有操作日志吗?</p>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="confirmDelAll">确定</el-button>
</div>
</div>
</el-dialog>
<span class="right-bottom-line" />
<ul class="tab-nav">
<li :class="{ 'active-tab-nav': activeIndex == 0 }" @click="changeActiveTab(0)">登录日志<i /></li>
<li :class="{ 'active-tab-nav': activeIndex == 1 }" @click="changeActiveTab(1)">操作日志<i /></li>
<li :class="{ 'active-tab-nav': activeIndex == 2 }" @click="changeActiveTab(2)">异常日志<i /></li>
<!-- 最右侧装饰img -->
<span class="tab-right-img" />
</ul>
<component :is="comName" />
</div>
</div>
</template>
<script>
import Search from './search'
import { delAllInfo } from '@/api/monitor/log'
import CRUD, { presenter } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
import loginLog from './loginLog/index.vue'
import operateLog from './operateLog/index.vue'
import errorLog from './errorLog/index.vue'
export default {
name: 'Log',
components: { Search, crudOperation, pagination },
cruds() {
return CRUD({ title: '日志', url: 'api/logs' })
name: 'LogManage',
components: {
loginLog,
operateLog,
errorLog
},
mixins: [presenter()],
data() {
return {
delVisible: false
activeIndex: 0
}
},
created() {
this.crud.optShow = {
add: false,
edit: false,
del: false,
download: true
computed: {
comName: function() {
if (this.activeIndex === 0) {
return 'loginLog'
} else if (this.activeIndex === 1) {
return 'operateLog'
} else if (this.activeIndex === 2) {
return 'errorLog'
}
return 'loginLog'
}
},
methods: {
confirmDelAll() {
// this.$confirm(`?`, '', {
// confirmButtonText: '',
// cancelButtonText: '',
// type: 'warning'
// }).then(() => {
this.crud.delAllLoading = true
delAllInfo().then(res => {
this.crud.delAllLoading = false
this.crud.dleChangePage(1)
this.crud.delSuccessNotify()
this.crud.toQuery()
this.delVisible = false
}).catch(err => {
this.crud.delAllLoading = false
console.log(err.response.data.message)
})
// })
changeActiveTab(data) {
this.activeIndex = data
}
}
}
</script>
<style lang="scss" scoped>
.demo-table-expand {
font-size: 0;
}
.demo-table-expand label {
width: 70px;
color: #99a9bf;
}
.demo-table-expand .el-form-item {
margin-right: 0;
margin-bottom: 0;
width: 100%;
}
.demo-table-expand .el-form-item__content {
font-size: 12px;
}
::v-deep .head-container{
display: flex;
padding-bottom: 0;
}
.head-search{
margin-bottom:0 ;
}
</style>

92
src/views/system/log/errorLog.vue → src/views/system/log/index2.vue

@ -1,7 +1,7 @@
<template>
<div>
<div class="head-container">
<Search />
<crudOperation>
<el-button
slot="left"
@ -9,53 +9,43 @@
icon="el-icon-delete"
size="mini"
:loading="crud.delAllLoading"
@click="delVisible=true"
@click="delVisible = true"
>
清空
</el-button>
</crudOperation>
<Search />
</div>
<!--表格渲染-->
<div class="app-container container-wrap" style="min-height: calc(100vh - 242px)">
<span class="right-top-line" />
<span class="left-bottom-line" />
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table-column align="center" type="expand">
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" inline class="demo-table-expand">
<el-form-item label="请求方法">
<span>{{ props.row.method }}</span>
</el-form-item>
<el-form-item label="请求参数">
<span style="word-break:break-all;">{{ props.row.params }}</span>
<span>{{ props.row.params }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column align="center" prop="username" label="用户名" />
<el-table-column align="center" prop="requestIp" label="IP" />
<el-table-column align="center" :show-overflow-tooltip="true" prop="address" label="IP来源" />
<el-table-column align="center" prop="description" label="描述" />
<el-table-column align="center" prop="browser" label="浏览器" />
<el-table-column align="center" prop="createTime" label="创建时间">
<el-table-column prop="username" label="用户名" />
<el-table-column prop="requestIp" label="IP" />
<el-table-column :show-overflow-tooltip="true" prop="address" label="IP来源" />
<el-table-column prop="description" label="描述" />
<el-table-column prop="browser" label="浏览器" />
<el-table-column prop="time" label="请求耗时" align="center">
<template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
</template>
</el-table-column>
<el-table-column align="center" label="异常详情" width="100px">
<template slot-scope="scope">
<el-button size="mini" type="text" @click="info(scope.row.id)">查看详情</el-button>
<el-tag v-if="scope.row.time <= 300">{{ scope.row.time }}ms</el-tag>
<el-tag v-else-if="scope.row.time <= 1000" type="warning">{{ scope.row.time }}ms</el-tag>
<el-tag v-else type="danger">{{ scope.row.time }}ms</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建日期" width="180px" />
</el-table>
<el-dialog :visible.sync="dialog" title="异常详情" append-to-body top="30px">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<pre v-highlightjs="errorInfo"><code class="java" /></pre>
</div>
</el-dialog>
<!--分页组件-->
<pagination />
<!-- 清空 -->
@ -63,33 +53,34 @@
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<p class="delMsg" style="padding-top:20px">确认清空所有操作日志吗?</p>
<p class="delMsg">确认清空所有操作日志吗?</p>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="confirmDelAll">确定</el-button>
</div>
</div>
</el-dialog>
</div>
</div>
</template>
<script>
import { getErrDetail, delAllError } from '@/api/monitor/log'
import Search from './search'
import { delAllInfo } from '@/api/monitor/log'
import CRUD, { presenter } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
export default {
name: 'ErrorLog',
name: 'Log',
components: { Search, crudOperation, pagination },
cruds() {
return CRUD({ title: '异常日志', url: 'api/logs/error' })
return CRUD({ title: '日志', url: 'api/logs' })
},
mixins: [presenter()],
data() {
return {
errorInfo: '', dialog: false, delVisible: false
delVisible: false
}
},
created() {
@ -101,21 +92,14 @@ export default {
}
},
methods: {
//
info(id) {
this.dialog = true
getErrDetail(id).then(res => {
this.errorInfo = res.exception
})
},
confirmDelAll() {
// this.$confirm(`?`, '', {
// this.$confirm(`?`, '', {
// confirmButtonText: '',
// cancelButtonText: '',
// type: 'warning'
// }).then(() => {
this.crud.delAllLoading = true
delAllError().then(res => {
delAllInfo().then(res => {
this.crud.delAllLoading = false
this.crud.dleChangePage(1)
this.crud.delSuccessNotify()
@ -125,7 +109,6 @@ export default {
this.crud.delAllLoading = false
console.log(err.response.data.message)
})
// }).catch(() => {
// })
}
}
@ -148,18 +131,6 @@ export default {
.demo-table-expand .el-form-item__content {
font-size: 12px;
}
::v-deep .el-dialog{
width: 1200px !important;
}
::v-deep .el-dialog__body {
padding: 0 20px 10px 20px !important;
}
.java.hljs {
color: #999;
background: transparent !important;
width: 100%;
height: 630px !important;
}
::v-deep .head-container{
display: flex;
padding-bottom: 0;
@ -167,21 +138,4 @@ export default {
.head-search{
margin-bottom:0 ;
}
.el-table td.el-table__cell div{
display: flex;
justify-content: flex-start;
margin-bottom: 10px;
}
.el-table .el-form {
padding: 0 10px;
}
::v-deep .el-form-item--small .el-form-item__label{
width: 80px;
line-height: 28px;
}
::v-deep .el-form-item__content{
flex: 1;
font-size: 12px;
line-height: 28px;
}
</style>

104
src/views/system/log/loginLog/index.vue

@ -0,0 +1,104 @@
<template>
<div>
<Search />
<el-table
ref="table"
:data="crud.data"
style="width: 100%;"
@row-click="clickRowHandler"
@selection-change="selectionChangeHandler"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column prop="account" label="账号" min-width="150" align="center" />
<el-table-column prop="username" label="用户名" align="center" min-width="150" />
<el-table-column prop="username" label="所属全宗" align="center" min-width="150" />
<el-table-column prop="det" label="所属部门" align="center" min-width="180" />
<el-table-column prop="role" label="用户角色" align="center" min-width="150">
<template slot-scope="scope">
<div>{{ scope.row.role | parseRole }}</div>
</template>
</el-table-column>
<el-table-column prop="requestIp" label="IP" align="center" min-width="180" />
<el-table-column prop="create_time" label="操作时间" align="center" min-width="180">
<template slot-scope="scope">
<div>{{ scope.row.create_time | parseTime }}</div>
</template>
</el-table-column>
</el-table>
<pagination />
</div>
</template>
<script>
import CRUD, { presenter, crud, header } from '@crud/crud'
import pagination from '@crud/Pagination'
import Search from '@/views/system/log/search.vue'
import { mapGetters } from 'vuex'
import { parseTime, saveAs, getBlob } from '@/utils/index'
import qs from 'qs'
export default {
name: 'LoginLog',
components: { pagination, Search },
filters: {
parseRole(val) {
const arr = val.split(',')
const arr1 = arr.filter(item => item.includes('name'))
const role = arr1[0].split('=')[1]
return role
}
},
mixins: [presenter(), crud(), header()],
cruds() {
return CRUD({
url: 'api/loginlogs/list',
// sort: ['update_time,desc'],
// crudMethod: caseCrudMethod,
optShow: {
add: false,
edit: false,
del: false,
download: true,
reset: true,
group: false
}
})
},
data() {
return {
selections: [],
keyWord: '',
queryTime: null
}
},
computed: {
...mapGetters([
'baseApi'
])
},
methods: {
//
handleDownload() {
this.crud.downloadLoading = true
const fileName = parseTime(new Date()) + '-登录日志'
getBlob(this.baseApi + '/api/loginlogs/download' + '?' + qs.stringify(this.crud.query, { indices: false }), function(blob) {
saveAs(blob, fileName)
})
this.crud.downloadLoading = false
},
test() {
console.log(this.crud, 'crud')
},
clickRowHandler(row) {
this.$refs.table.toggleRowSelection(row) //
},
selectionChangeHandler(val) {
this.selections = val
}
}
}
</script>
<style lang="scss" scoped>
</style>

143
src/views/system/log/operateLog/index.vue

@ -0,0 +1,143 @@
<template>
<div>
<Search />
<!-- height="calc(100vh - 356px)" -->
<el-table
ref="table"
:data="crud.data"
style="width: 100%;"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column type="expand">
<template slot-scope="props">
<el-form label-position="left" inline class="demo-table-expand">
<el-form-item label="请求方法">
<span>{{ props.row.method }}</span>
</el-form-item>
<el-form-item label="请求参数">
<span style="word-break:break-all;">{{ props.row.params }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<!-- <el-table-column type="index" label="序号" width="100" align="center" /> -->
<el-table-column prop="account" label="账号" align="center" />
<el-table-column prop="username" label="用户名" align="center" />
<el-table-column prop="username" label="所属全宗" align="center" />
<el-table-column prop="det" label="所属部门" align="center" />
<el-table-column prop="requestIp" label="IP" align="center" />
<el-table-column prop="address" label="IP来源" align="center" />
<el-table-column prop="description" label="内容描述" align="center" />
<el-table-column prop="browser" label="浏览器" align="center" />
<el-table-column prop="time" label="请求耗时" align="center">
<template slot-scope="scope">
<el-tag v-if="scope.row.time <= 300">{{ scope.row.time }}ms</el-tag>
<el-tag v-else-if="scope.row.time <= 1000" type="warning">{{ scope.row.time }}ms</el-tag>
<el-tag v-else type="danger">{{ scope.row.time }}ms</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="操作时间" align="center" min-width="150">
<template slot-scope="scope">
<div>{{ scope.row.createTime | parseTime }}</div>
</template>
</el-table-column>
<!-- <el-table-column prop="" label="操作时间" align="center" min-width="180" /> -->
<!-- <el-table-column prop="" label="操作" align="center" min-width="100">
<el-button size="mini" style="background:#3A99FD" @click="handleListen">查看监控</el-button>
</el-table-column> -->
</el-table>
<pagination />
<!-- 查看监控 -->
<!-- <Listen ref="listenDom" /> -->
</div>
</template>
<script>
import CRUD, { presenter, crud } from '@crud/crud'
import pagination from '@crud/Pagination'
import Search from '@/views/system/log/search.vue'
import { delAllInfo } from '@/api/monitor/log'
export default {
name: 'LoginLog',
components: { pagination, Search },
mixins: [presenter(), crud()],
cruds() {
return CRUD({
url: 'api/logs',
title: '操作日志',
optShow: {
add: false,
edit: false,
del: false,
download: true,
reset: true,
group: false
}
})
},
data() {
return {
selections: [],
keyWord: '',
oprType: 0,
oprTypeOptions: [
{ value: 0, label: '全部' },
{ value: 1, label: '成功' },
{ value: 2, label: '失败' }
],
optionVal: 1,
options: [
{ value: 1, label: '操作人' },
{ value: 2, label: '所属部门' }
],
queryTime: null
}
},
methods: {
// clickRowHandler(row) {
// this.$refs.table.toggleRowSelection(row) //
// },
// selectionChangeHandler(val) {
// this.selections = val
// },
//
handleListen() {
this.$refs.listenDom.dialogVisible = true
},
confirmDelAll() {
this.crud.delAllLoading = true
delAllInfo().then(res => {
this.crud.delAllLoading = false
this.crud.dleChangePage(1)
this.crud.delSuccessNotify()
this.crud.toQuery()
this.delVisible = false
}).catch(err => {
this.crud.delAllLoading = false
console.log(err.response.data.message)
})
}
}
}
</script>
<style lang="scss" scoped>
// .el-table td.el-table__cell div{
// display: flex;
// justify-content: flex-start;
// margin-bottom: 10px;
// }
// .el-table .el-form {
// padding: 0 10px;
// }
// ::v-deep .el-form-item--small .el-form-item__label{
// width: 80px;
// line-height: 28px;
// }
// ::v-deep .el-form-item__content{
// flex: 1;
// font-size: 12px;
// line-height: 28px;
// }
</style>

90
src/views/system/log/search.vue

@ -1,40 +1,94 @@
<template>
<div v-if="crud.props.searchToggle" class="head-search">
<div class="head-container">
<!-- <crudOperation /> -->
<!-- <el-button v-permission="permission.download" :loading="crud.downloadLoading" :disabled="!selections.length" size="mini" icon="el-icon-download" @click="handleDownload">导出</el-button> -->
<div class="head-search">
<el-input
v-model="query.blurry"
clearable
size="small"
prefix-icon="el-icon-search"
placeholder="请输入你要搜索的内容"
style="width: 200px;"
class="filter-item"
clearable
placeholder="请输入关键词"
style="width: 300px;"
class="input-prepend filter-item"
@keyup.enter.native="crud.toQuery"
>
<!-- <el-select slot="prepend" v-model="optionVal" style="width: 100px" @keyup.enter.native="crud.toQuery"> -->
<el-select slot="prepend" v-model="optionVal" style="width: 100px">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-input>
<date-range-picker v-model="query.createTime" class="date-item" />
<rrOperation />
</div>
<crudOperation :permission="permission">
<template v-slot:left>
<el-button :loading="crud.downloadLoading" size="mini" @click="delVisible=true"><i class="iconfont icon-shanchu" />清空</el-button>
</template>
</crudOperation>
<!-- <el-button :loading="crud.downloadLoading" size="mini" icon="el-icon-download" @click="handleDownload">导出</el-button> -->
<!-- 清空 -->
<el-dialog class="tip-dialog" :visible.sync="delVisible" title="提示">
<div class="setting-dialog">
<div class="tip-content">
<p class="tipMsg">此操作将清空所选数据</p>
<span>你是否还要继续?</span>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="delVisible = false">取消</el-button>
<el-button type="primary" @click="confirmDelAll">继续</el-button>
</div>
</div>
</el-dialog>
</div>
</template>
<script>
import { header } from '@crud/crud'
import { header, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import DateRangePicker from '@/components/DateRangePicker'
export default {
components: { rrOperation, DateRangePicker },
mixins: [header()]
components: { rrOperation, DateRangePicker, crudOperation },
mixins: [header(), crud()],
data() {
return {
delVisible: false,
optionVal: 1,
options: [
{ value: 1, label: '用户名' },
{ value: 2, label: '所属部门' },
{ value: 3, label: '登录账号' },
{ value: 4, label: '请求方法' },
{ value: 5, label: '请求参数' }
],
permission: {}
}
}
}
</script>
<style lang="scss" scoped>
.head-search{
margin-left: 10px;
::v-deep .input-prepend .el-input-group__prepend .el-input__inner{
height: 29px;
padding: 0 10px !important;
color: #545B65 !important;
border: 0;
border-right: 1px solid #E3E7EE !important;
border-radius: 0;
}
.head-container{
.filter-item{
margin-right: 8px;
}
.date-item{
margin-right: 8px;
}
::v-deep .el-input-group__prepend div.el-select:hover .el-input__inner{
border-right: 1px solid #E3E7EE !important;
}
::v-deep .input-prepend .el-input-group__prepend .el-select__caret {
color: #545B65 !important;
}
::v-deep .input-prepend .el-input__inner{
padding-left: 110px;
}
</style>

26
src/views/system/notifyManage/data.json

@ -0,0 +1,26 @@
[
{
"id": 1,
"label": "全宗部门选择",
"children": [
{
"id": 2,
"label": "全宗A",
"children": [
{
"id": 4,
"label": "部门A1"
},
{
"id": 5,
"label": "部门A2"
}
]
},
{
"id": 3,
"label": "全宗B"
}
]
}
]

41
src/views/system/notifyManage/index.vue

@ -7,7 +7,7 @@
<date-range-picker v-model="query.createTime" class="date-item" />
<rrOperation />
</div>
<el-button class="iconfont icon-fabu-fanbai" size="mini" @click="handleSend">发布</el-button>
<el-button size="mini" @click="handleSend"><i class="iconfont icon-fabu" />发布</el-button>
<!-- <el-button icon="el-icon-edit" size="mini" :disabled="!(selections.length === 1)" @click="handleEdit">修改</el-button>
<el-button icon="el-icon-delete" size="mini" :disabled="!selections.length" @click="handleDel">删除</el-button> -->
</div>
@ -86,7 +86,7 @@
<el-form-item label="发送对象" prop="pushObj">
<el-input v-model="sendForm.pushObj" placeholder="点击下方按钮选择对象" type="textarea" rows="6" style="width: 580px;" />
</el-form-item>
<span class="select-btn iconfont icon-shezhi" @click="sendObjVisible = true" />
<span class="select-btn iconfont icon-shezhi" @click="openSelectObj" />
<!-- <el-form-item label="发送对象" prop="">
<el-radio-group v-model="pushObj" @change="pushObjChange">
<el-radio label="用户">用户</el-radio>
@ -105,25 +105,7 @@
</div>
</div>
</el-dialog>
<!-- 选择发送对象 -->
<el-dialog append-to-body :close-on-click-modal="false" :visible.sync="sendObjVisible" title="发布通知" @close="handleClose">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<el-form ref="selectObjForm" :rules="rulesObj" :model="selectObjForm" size="small" label-width="100px">
<el-form-item label="发送对象" prop="sendObj" class="down-select">
<el-radio-group v-model="selectObjForm.sendObj" size="mini" style="width: 178px">
<el-radio-button label="0">用户</el-radio-button>
<el-radio-button label="1">设备</el-radio-button>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button type="text" @click="sendObjVisible = false">取消</el-button>
<el-button type="primary">保存</el-button>
</div>
</div>
</el-dialog>
<SelectObj ref="selectObj" />
</div>
</template>
@ -131,12 +113,14 @@
import CRUD, { presenter, header, form, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import DateRangePicker from '@/components/DateRangePicker'
import SelectObj from './module/selectObj'
// noticeDel
import { noticeCreate, getAllDev, getAllUser, getNoticeList } from '@/api/system/logs'
const defaultForm = {}
export default {
name: 'NotifyManage',
components: { rrOperation, DateRangePicker },
components: { rrOperation, DateRangePicker, SelectObj },
cruds() {
return CRUD({ title: '通知', url: 'api/system/logs', crudMethod: { }})
},
@ -148,15 +132,11 @@ export default {
tableData: [],
selections: [],
sendVisible: false,
sendObjVisible: false,
sendForm: {
msgType: '系统消息',
title: null,
notification: ''
},
selectObjForm: {
sendObj: 0
},
pushObj: '用户',
checked: '',
noticeType: 1,
@ -182,11 +162,6 @@ export default {
{ required: true, message: '发送对象不可为空', trigger: 'blur' }
]
},
rulesObj: {
sendObj: [
{ required: true, message: '请选择发送对象', trigger: 'change' }
]
},
allUser: null,
allDev: null,
page: {
@ -213,6 +188,9 @@ export default {
this.getTableData()
},
methods: {
openSelectObj() {
this.$refs.selectObj.sendObjVisible = true
},
getParams() {
const params = {
page: null,
@ -485,4 +463,5 @@ export default {
text-align: center;
cursor: pointer;
}
</style>

177
src/views/system/notifyManage/module/selectObj.vue

@ -0,0 +1,177 @@
<template>
<!-- 选择发送对象 -->
<el-dialog append-to-body :close-on-click-modal="false" :visible.sync="sendObjVisible" title="发布通知" @close="handleClose">
<span class="dialog-right-top" />
<span class="dialog-left-bottom" />
<div class="setting-dialog">
<el-form ref="selectObjForm" :rules="rulesObj" :model="selectObjForm" size="small" label-width="100px">
<el-form-item label="发送对象" prop="sendObj" class="down-select">
<el-radio-group v-model="selectObjForm.sendObj" size="mini" style="width: 178px">
<el-radio-button label="0">用户</el-radio-button>
<el-radio-button label="1">设备</el-radio-button>
</el-radio-group>
</el-form-item>
</el-form>
<div class="obj-tree-select">
<div class="obj-tree">
<el-tree :data="treeList" :props="defaultProps" @node-click="handleNodeClick" />
</div>
<div class="obj-list">
<p class="obj-title">用户列表<i class="el-icon-circle-plus-outline" /></p>
<el-checkbox-group v-model="checkList">
<el-checkbox label="用户列表" />
<el-checkbox label="张三" />
<el-checkbox label="李思思" />
</el-checkbox-group>
</div>
<div class="obj-selected">
<p class="obj-title">已选中<i class="iconfont icon-shanchu" /></p>
<div class="selected-list">
<el-tag
v-for="tag in dynamicTags"
:key="tag"
closable
:disable-transitions="false"
@close="handleDelt(tag)"
>
{{ tag }}
</el-tag>
</div>
</div>
</div>
<div slot="footer" class="dialog-footer">
<el-button type="primary">保存</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
import dataJson from '../data.json'
export default {
props: {
selectedCategory: {
type: Object,
default: function() {
return {}
}
}
},
data() {
return {
sendObjVisible: false,
selectObjForm: {
sendObj: 0
},
treeList: [],
checkList: ['用户列表'],
dynamicTags: ['张三', '李思思'],
defaultProps: {
children: 'children',
label: 'label'
},
rulesObj: {
sendObj: [
{ required: true, message: '请选择发送对象', trigger: 'change' }
]
}
}
},
watch: {
},
created() {
this.treeList = dataJson
},
methods: {
handleNodeClick(data) {
console.log(data)
},
handleClose() {
this.sendObjVisible = false
},
handleDelt(tag) {
this.dynamicTags.splice(this.dynamicTags.indexOf(tag), 1)
}
}
}
</script>
<style lang='scss' scoped>
.obj-tree-select{
display: flex;
justify-content: space-between;
height: 367px;
border: 1px solid #E6E8ED;
.obj-tree{
width: 194px;
overflow: hidden;
overflow-y: scroll;
border-right: 1px solid #E6E8ED;
}
.obj-list{
width: 184px;
overflow: hidden;
overflow-y: scroll;
border-right: 1px solid #E6E8ED;
.obj-title{
padding: 0 12px;
i{
font-weight: bold;
font-size: 18px;
right: 12px;
}
}
::v-deep .el-checkbox{
width: 100%;
height: 40px;
line-height: 40px;
padding-left: 16px;
&:hover{
background-color: #F5F9FC;
}
}
}
.obj-selected{
flex: 1;
.obj-title{
padding: 0 15px;
border-bottom: 1px solid #E6E8ED;
i{
right: 15px;
}
}
::v-deep .el-tag{
margin: 14px 0 0 10px;
height: 24px;
line-height: 24px;
padding: 0 8px;
font-size: 12px;
color: #0348F3;
background: #E8F2FF;
border: none;
border-radius: 3px;
.el-icon-close{
color: #0348F3;
&:hover{
color: #fff;
background-color: #0348F3;
}
}
}
}
.obj-title{
position: relative;
font-size: 16px;
color: #0C0E1E;
height: 48px;
line-height: 48px;
i{
position: absolute;
top: 50%;
transform: translateY(-50%);
color: #0348F3;
cursor: pointer;
}
}
}
</style>
Loading…
Cancel
Save