refactor: 前后端基础部分

This commit is contained in:
2024-05-27 14:15:48 +08:00
parent f23e4548cd
commit f5e6db390a
928 changed files with 65057 additions and 0 deletions

View File

@@ -0,0 +1,139 @@
<template>
<div class="app-container">
<div class="head-container">
<Search />
<crudOperation>
<el-button
slot="left"
class="filter-item"
type="danger"
icon="el-icon-delete"
size="mini"
:loading="crud.delAllLoading"
@click="confirmDelAll()"
>
{{ $t('ErrorLog.table.clear') }}
</el-button>
</crudOperation>
</div>
<!--表格渲染-->
<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="$t('ErrorLog.table.method')">
<span>{{ props.row.method }}</span>
</el-form-item>
<el-form-item :label="$t('ErrorLog.table.params')">
<span>{{ props.row.params }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column prop="username" :label="$t('ErrorLog.table.username')" />
<el-table-column prop="request_ip" label="IP" />
<el-table-column show-overflow-tooltip prop="address" :label="$t('ErrorLog.table.address')" />
<el-table-column prop="description" :label="$t('ErrorLog.table.description')" show-overflow-tooltip />
<el-table-column prop="browser" :label="$t('ErrorLog.table.browser')" min-width="120" show-overflow-tooltip />
<el-table-column prop="create_time" :label="$t('ErrorLog.table.create_time')" min-width="100" show-overflow-tooltip>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.create_time) }}</span>
</template>
</el-table-column>
<el-table-column :label="$t('ErrorLog.table.err_del')" width="150px">
<template slot-scope="scope">
<el-button size="mini" type="text" @click="info(scope.row.log_id)">{{ $t('ErrorLog.table.see_del') }}</el-button>
</template>
</el-table-column>
</el-table>
<el-dialog :visible.sync="dialog" :title="$t('ErrorLog.table.err_del')" append-to-body top="30px" width="85%">
<pre v-highlightjs="errorInfo"><code class="java" /></pre>
</el-dialog>
<!--分页组件-->
<pagination />
</div>
</template>
<script>
import { getErrDetail, delAllError } from '@/api/monitor/log'
import Search from './search'
import CRUD, { presenter } from '@crud/crud'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
export default {
name: 'ErrorLog',
components: { Search, crudOperation, pagination },
cruds() {
return CRUD({ title: '异常日志', url: 'api/logs/error' })
},
mixins: [presenter()],
data() {
return {
errorInfo: '', dialog: false
}
},
created() {
this.crud.optShow = {
add: false,
edit: false,
del: false,
download: false
}
},
methods: {
// 获取异常详情
info(log_id) {
this.dialog = true
getErrDetail(log_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()
}).catch(err => {
this.crud.delAllLoading = false
console.log(err.response.data.message)
})
}).catch(() => {
})
}
}
}
</script>
<style 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;
}
/deep/ .el-dialog__body {
padding: 0 20px 10px 20px !important;
}
.java.hljs {
color: #444;
background: #ffffff !important;
height: 630px !important;
}
</style>

View File

@@ -0,0 +1,119 @@
<template>
<div class="app-container">
<div class="head-container">
<Search />
<crudOperation>
<el-button
slot="left"
class="filter-item"
type="danger"
icon="el-icon-delete"
size="mini"
:loading="crud.delAllLoading"
@click="confirmDelAll()"
>
{{ $t('ErrorLog.table.clear') }}
</el-button>
</crudOperation>
</div>
<!--表格渲染-->
<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="$t('ErrorLog.table.method')">
<span>{{ props.row.method }}</span>
</el-form-item>
<el-form-item :label="$t('ErrorLog.table.params')">
<span>{{ props.row.params }}</span>
</el-form-item>
</el-form>
</template>
</el-table-column>
<el-table-column prop="username" :label="$t('ErrorLog.table.username')" />
<el-table-column prop="request_ip" label="IP" />
<el-table-column show-overflow-tooltip prop="address" :label="$t('ErrorLog.table.address')" />
<el-table-column prop="description" :label="$t('ErrorLog.table.description')" show-overflow-tooltip />
<el-table-column prop="browser" :label="$t('ErrorLog.table.browser')" min-width="120" show-overflow-tooltip />
<el-table-column prop="time" :label="$t('ErrorLog.table.time')" 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="create_time" :label="$t('ErrorLog.table.create_time')" width="180px">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.create_time) }}</span>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</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 i18n from '@/i18n'
export default {
name: 'Log',
components: { Search, crudOperation, pagination },
cruds() {
return CRUD({ title: '日志', url: 'api/logs' })
},
mixins: [presenter()],
created() {
this.crud.optShow = {
add: false,
edit: false,
del: false,
download: false
}
},
methods: {
confirmDelAll() {
this.$confirm(i18n.t('ErrorLog.msg.m1'), i18n.t('common.Operate'), {
confirmButtonText: i18n.t('common.Confirm'),
cancelButtonText: i18n.t('common.Cancel'),
type: 'warning'
}).then(() => {
this.crud.delAllLoading = true
delAllInfo().then(res => {
this.crud.delAllLoading = false
this.crud.dleChangePage(1)
this.crud.delSuccessNotify()
this.crud.toQuery()
}).catch(err => {
this.crud.delAllLoading = false
console.log(err.response.data.message)
})
}).catch(() => {
})
}
}
}
</script>
<style>
.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;
}
</style>

View File

@@ -0,0 +1,24 @@
<template>
<div v-if="crud.props.searchToggle">
<el-input
v-model="query.blurry"
clearable
size="mini"
:placeholder="$t('common.Tip17')"
style="width: 200px;"
class="filter-item"
/>
<date-range-picker v-model="query.createTime" class="date-item" />
<rrOperation />
</div>
</template>
<script>
import { header } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import DateRangePicker from '@/components/DateRangePicker'
export default {
components: { rrOperation, DateRangePicker },
mixins: [header()]
}
</script>

View File

@@ -0,0 +1,126 @@
<template>
<div class="app-container">
<div class="head-container">
<div v-if="crud.props.searchToggle">
<el-input v-model="query.filter" clearable size="mini" :placeholder="$t('Online.msg.m4')" style="width: 200px;" class="filter-item" @keyup.enter.native="crud.toQuery" />
<rrOperation />
</div>
<crudOperation>
<el-button
slot="left"
class="filter-item"
type="danger"
icon="el-icon-delete"
size="mini"
:loading="delLoading"
:disabled="crud.selections.length === 0"
@click="doDelete(crud.selections)"
>
{{ $t('Online.table.forced') }}
</el-button>
</crudOperation>
</div>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table-column type="selection" width="55" />
<el-table-column prop="userName" :label="$t('Online.table.userName')" />
<el-table-column prop="nickName" :label="$t('Online.table.nickName')" />
<el-table-column prop="dept" :label="$t('Online.table.dept')" />
<el-table-column prop="ip" :label="$t('Online.table.ip')" />
<el-table-column show-overflow-tooltip prop="address" :label="$t('Online.table.address')" />
<el-table-column prop="browser" :label="$t('Online.table.browser')" width="145px" />
<el-table-column prop="loginTime" :label="$t('Online.table.loginTime')" min-width="110" show-overflow-tooltip>
<template slot-scope="scope">
<span>{{ parseTime(scope.row.loginTime) }}</span>
</template>
</el-table-column>
<el-table-column :label="$t('common.Operate')" width="100px" fixed="right">
<template slot-scope="scope">
<el-popover
:ref="scope.$index"
v-permission="['admin']"
placement="top"
width="180px"
>
<p>{{ $t('Online.msg.m1') }}</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="$refs[scope.$index].doClose()">{{ $t('common.Cancel') }}</el-button>
<el-button :loading="delLoading" type="primary" size="mini" @click="delMethod(scope.row, scope.$index)">{{ $t('common.Confirm') }}</el-button>
</div>
<el-button slot="reference" size="mini" type="text">{{ $t('Online.table.forced') }}</el-button>
</el-popover>
</template>
</el-table-column>
</el-table>
<!--分页组件-->
<pagination />
</div>
</template>
<script>
import { del } from '@/api/monitor/online'
import CRUD, { presenter, header, crud } from '@crud/crud'
import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import pagination from '@crud/Pagination'
import i18n from '@/i18n'
export default {
name: 'OnlineUser',
components: { pagination, crudOperation, rrOperation },
cruds() {
return CRUD({ url: 'auth/online', title: i18n.t('Online.title') })
},
mixins: [presenter(), header(), crud()],
data() {
return {
delLoading: false,
permission: {}
}
},
created() {
this.crud.msg.del = i18n.t('Online.msg.m2')
this.crud.optShow = {
add: false,
edit: false,
del: false,
download: false
}
},
methods: {
doDelete(datas) {
this.$confirm(i18n.t('Online.msg.m3', { count: datas.length }), i18n.t('common.Tips'), {
confirmButtonText: i18n.t('common.Confirm'),
cancelButtonText: i18n.t('common.Cancel'),
type: 'warning'
}).then(() => {
this.delMethod(datas)
}).catch(() => {})
},
// 踢出用户
delMethod(key, index) {
const ids = []
if (key instanceof Array) {
key.forEach(val => {
ids.push(val)
})
} else ids.push(key)
this.delLoading = true
del(ids).then(() => {
this.delLoading = false
if (this.$refs[index]) {
this.$refs[index].doClose()
}
this.crud.dleChangePage(1)
this.crud.delSuccessNotify()
this.crud.toQuery()
}).catch(() => {
this.delLoading = false
if (this.$refs[index]) {
this.$refs[index].doClose()
}
})
}
}
}
</script>

View File

@@ -0,0 +1,291 @@
<template>
<div v-loading="!show" :element-loading-text="$t('common.loading')" :style="!show ? 'height: 500px' : 'height: 100%'" class="app-container">
<div v-if="show">
<el-card class="box-card">
<div style="color: #666;font-size: 13px;">
<svg-icon icon-class="system" style="margin-right: 5px" />
<span>
{{ $t('monitor.sys') }}{{ data.sys.os }}
</span>
<span>
IP{{ data.sys.ip }}
</span>
<span>
{{ $t('monitor.day') }}{{ data.sys.day }}
</span>
<i class="el-icon-refresh" style="margin-left: 40px" @click="init" />
</div>
</el-card>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span style="font-weight: bold;color: #666;font-size: 15px">{{ $t('monitor.status') }}</span>
</div>
<div>
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="6" style="margin-bottom: 10px">
<div class="title">{{ $t('monitor.cpu') }}</div>
<el-tooltip placement="top-end">
<div slot="content" style="font-size: 12px;">
<div style="padding: 3px;">
{{ data.cpu.name }}
</div>
<div style="padding: 3px">
{{ data.cpu.package }}
</div>
<div style="padding: 3px">
{{ data.cpu.core }}
</div>
<div style="padding: 3px">
{{ data.cpu.logic }}
</div>
</div>
<div class="content">
<el-progress type="dashboard" :percentage="parseFloat(data.cpu.used)" />
</div>
</el-tooltip>
<div class="footer">{{ data.cpu.coreNumber }} {{ $t('monitor.core') }}</div>
</el-col>
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="6" style="margin-bottom: 10px">
<div class="title">{{ $t('monitor.memory') }}</div>
<el-tooltip placement="top-end">
<div slot="content" style="font-size: 12px;">
<div style="padding: 3px;">
{{ $t('monitor.tality') }}{{ data.memory.total }}
</div>
<div style="padding: 3px">
{{ $t('monitor.used') }}{{ data.memory.used }}
</div>
<div style="padding: 3px">
{{ $t('monitor.leisure') }}{{ data.memory.available }}
</div>
</div>
<div class="content">
<el-progress type="dashboard" :percentage="parseFloat(data.memory.usageRate)" />
</div>
</el-tooltip>
<div class="footer">{{ data.memory.used }} / {{ data.memory.total }}</div>
</el-col>
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="6" style="margin-bottom: 10px">
<div class="title">{{ $t('monitor.exchange') }}</div>
<el-tooltip placement="top-end">
<div slot="content" style="font-size: 12px;">
<div style="padding: 3px;">
{{ $t('monitor.tality') }}{{ data.swap.total }}
</div>
<div style="padding: 3px">
{{ $t('monitor.used') }}{{ data.swap.used }}
</div>
<div style="padding: 3px">
{{ $t('monitor.leisure') }}{{ data.swap.available }}
</div>
</div>
<div class="content">
<el-progress type="dashboard" :percentage="parseFloat(data.swap.usageRate)" />
</div>
</el-tooltip>
<div class="footer">{{ data.swap.used }} / {{ data.swap.total }}</div>
</el-col>
<el-col :xs="24" :sm="24" :md="6" :lg="6" :xl="6" style="margin-bottom: 10px">
<div class="title">{{ $t('monitor.disk') }}</div>
<div class="content">
<el-tooltip placement="top-end">
<div slot="content" style="font-size: 12px;">
<div style="padding: 3px">
{{ $t('monitor.tality') }}{{ data.disk.total }}
</div>
<div style="padding: 3px">
{{ $t('monitor.leisure') }}{{ data.disk.available }}
</div>
</div>
<div class="content">
<el-progress type="dashboard" :percentage="parseFloat(data.disk.usageRate)" />
</div>
</el-tooltip>
</div>
<div class="footer">{{ data.disk.used }} / {{ data.disk.total }}</div>
</el-col>
</div>
</el-card>
<div>
<el-row :gutter="6">
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" style="margin-bottom: 10px">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span style="font-weight: bold;color: #666;font-size: 15px">{{ $t('monitor.cpu_monitoring') }}</span>
</div>
<div>
<v-chart :options="cpuInfo" />
</div>
</el-card>
</el-col>
<el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" style="margin-bottom: 10px">
<el-card class="box-card">
<div slot="header" class="clearfix">
<span style="font-weight: bold;color: #666;font-size: 15px">{{ $t('monitor.memory_monitoring') }}</span>
</div>
<div>
<v-chart :options="memoryInfo" />
</div>
</el-card>
</el-col>
</el-row>
</div>
</div>
</div>
</template>
<script>
import ECharts from 'vue-echarts'
import 'echarts/lib/chart/line'
import 'echarts/lib/component/polar'
import { initData } from '@/api/data'
export default {
name: 'ServerMonitor',
components: {
'v-chart': ECharts
},
data() {
return {
show: false,
monitor: null,
url: 'api/monitor',
data: {},
cpuInfo: {
tooltip: {
trigger: 'axis'
},
xAxis: {
type: 'category',
boundaryGap: false,
data: []
},
yAxis: {
type: 'value',
min: 0,
max: 100,
interval: 20
},
series: [{
data: [],
type: 'line',
areaStyle: {
normal: {
color: 'rgb(32, 160, 255)' // 改变区域颜色
}
},
itemStyle: {
normal: {
color: '#6fbae1',
lineStyle: {
color: '#6fbae1' // 改变折线颜色
}
}
}
}]
},
memoryInfo: {
tooltip: {
trigger: 'axis'
},
xAxis: {
type: 'category',
boundaryGap: false,
data: []
},
yAxis: {
type: 'value',
min: 0,
max: 100,
interval: 20
},
series: [{
data: [],
type: 'line',
areaStyle: {
normal: {
color: 'rgb(32, 160, 255)' // 改变区域颜色
}
},
itemStyle: {
normal: {
color: '#6fbae1',
lineStyle: {
color: '#6fbae1' // 改变折线颜色
}
}
}
}]
}
}
},
created() {
this.init()
this.monitor = window.setInterval(() => {
setTimeout(() => {
this.init()
}, 2)
}, 3500)
},
destroyed() {
clearInterval(this.monitor)
},
methods: {
init() {
initData(this.url, {}).then(data => {
this.data = data
this.show = true
if (this.cpuInfo.xAxis.data.length >= 8) {
this.cpuInfo.xAxis.data.shift()
this.memoryInfo.xAxis.data.shift()
this.cpuInfo.series[0].data.shift()
this.memoryInfo.series[0].data.shift()
}
this.cpuInfo.xAxis.data.push(data.time)
this.memoryInfo.xAxis.data.push(data.time)
this.cpuInfo.series[0].data.push(parseFloat(data.cpu.used))
this.memoryInfo.series[0].data.push(parseFloat(data.memory.usageRate))
})
}
}
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
::v-deep .box-card {
margin-bottom: 5px;
span {
margin-right: 28px;
}
.el-icon-refresh {
margin-right: 10px;
float: right;
cursor:pointer;
}
}
.cpu, .memory, .swap, .disk {
width: 20%;
float: left;
padding-bottom: 20px;
margin-right: 5%;
}
.title {
text-align: center;
font-size: 15px;
font-weight: 500;
color: #999;
margin-bottom: 16px;
}
.footer {
text-align: center;
font-size: 15px;
font-weight: 500;
color: #999;
margin-top: -5px;
margin-bottom: 10px;
}
.content {
text-align: center;
margin-top: 5px;
margin-bottom: 5px;
}
</style>

View File

@@ -0,0 +1,16 @@
<template>
<elFrame :src="sqlApi" />
</template>
<script>
import { mapGetters } from 'vuex'
import elFrame from '@/components/Iframe/index'
export default {
name: 'Sql',
components: { elFrame },
computed: {
...mapGetters([
'sqlApi'
])
}
}
</script>