系统维护接口对接

This commit is contained in:
Mrtangl 2022-04-15 11:02:49 +08:00
parent 4cf726c993
commit 5127752ba9
5 changed files with 363 additions and 199 deletions

View File

@ -69,9 +69,9 @@ export function apiSystemLogLists(params: any) {
return request.get('/system/log/operate', { params })
}
// 清除系统缓存
export function apiSystemCacheClear() {
return request.post('/setting.system.cache/clear')
// 系统缓存
export function apiSystemCache(params: any) {
return request.get('/monitor/cache', { params })
}
// 编辑管理员信息

View File

@ -4,7 +4,14 @@ import { App } from '@vue/runtime-core'
// 手动引入 ECharts 各模块来减小打包体积
import { CanvasRenderer } from 'echarts/renderers'
import { BarChart, PieChart, LineChart, PieSeriesOption } from 'echarts/charts'
import {
BarChart,
PieChart,
LineChart,
PieSeriesOption,
GaugeChart,
GaugeSeriesOption
} from 'echarts/charts'
import { LabelLayout } from 'echarts/features'
import {
GridComponent,
@ -25,7 +32,8 @@ use([
TitleComponent,
LegendComponent,
LineChart,
LabelLayout
LabelLayout,
GaugeChart
])
export default (app: App) => {

View File

@ -15,25 +15,40 @@
<!-- <div class="muted">建议尺寸240*200支持jpgpng格式</div> -->
</el-form-item>
<el-form-item label="账号:" prop="account">
<el-input v-model="formData.account" placeholder="" disabled></el-input>
<el-form-item label="账号:" prop="username">
<el-input v-model="formData.username" placeholder="" disabled></el-input>
</el-form-item>
<el-form-item label="名称:" prop="name">
<el-input v-model="formData.name" placeholder="请输入名称"></el-input>
<el-form-item label="名称:" prop="nickname">
<el-input v-model="formData.nickname" placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item label="当前密码:" prop="password_old">
<el-input v-model.trim="formData.password_old" placeholder="修改密码时必填, 不修改密码时留空" type="password" show-password></el-input>
<el-input
v-model.trim="formData.password_old"
placeholder="修改密码时必填, 不修改密码时留空"
type="password"
show-password
></el-input>
</el-form-item>
<el-form-item label="新的密码:" prop="password">
<el-input
v-model.trim="formData.password"
placeholder="修改密码时必填, 不修改密码时留空"
type="password"
show-password
></el-input>
</el-form-item>
<el-form-item label="确定密码:" prop="password_confirm">
<el-input
v-model.trim="formData.password_confirm"
placeholder="修改密码时必填, 不修改密码时留空"
type="password"
show-password
></el-input>
</el-form-item>
<el-form-item label="新的密码:" prop="password">
<el-input v-model.trim="formData.password" placeholder="修改密码时必填, 不修改密码时留空" type="password" show-password></el-input>
</el-form-item>
<el-form-item label="确定密码:" prop="password_confirm">
<el-input v-model.trim="formData.password_confirm" placeholder="修改密码时必填, 不修改密码时留空" type="password" show-password></el-input>
</el-form-item>
</el-form>
</el-card>
@ -44,102 +59,105 @@
</template>
<script setup lang="ts">
import { reactive, ref, onMounted } from 'vue'
import type { ElForm } from 'element-plus'
import MaterialSelect from '@/components/material-select/index.vue'
import FooterBtns from '@/components/footer-btns/index.vue'
import { apiAuthAdminEditSelf, apiAuthAdminMySelf } from '@/api/setting'
import { ElMessage } from 'element-plus'
import { useAdmin } from '@/core/hooks/app'
const { store } = useAdmin()
type FormInstance = InstanceType<typeof ElForm>
const formRefs = ref<FormInstance>()
import { reactive, ref, onMounted } from 'vue'
import type { ElForm } from 'element-plus'
import MaterialSelect from '@/components/material-select/index.vue'
import FooterBtns from '@/components/footer-btns/index.vue'
import { apiAdminEdit, apiAdminDetail } from '@/api/auth'
import { apiUserInfo } from '@/api/user'
import { ElMessage } from 'element-plus'
import { useAdmin } from '@/core/hooks/app'
//
const formData = ref({
avatar: '', //
account: '', //
name: '', //
password_old: '', //
password: '', //
password_confirm: '', //
})
const { store } = useAdmin()
type FormInstance = InstanceType<typeof ElForm>
const formRefs = ref<FormInstance>()
//
const rules = reactive<object>({
avatar: [
{
required: true,
message: '头像不能为空',
trigger: ['change'],
},
],
name: [
{
required: true,
message: '请输入名称',
trigger: ['blur'],
},
],
//
const formData = ref({
avatar: '', //
username: '', //
nickname: '', //
password_old: '', //
password: '', //
password_confirm: '' //
})
//
const rules = reactive<object>({
avatar: [
{
required: true,
message: '头像不能为空',
trigger: ['change']
}
],
nickname: [
{
required: true,
message: '请输入名称',
trigger: ['blur']
}
]
})
//
const getAuthAdminMySelf = async (): Promise<void> => {
formData.value = await apiUserInfo()
}
//
const setAuthAdminEditSelf = async (): Promise<void> => {
if (formData.value.password_old || formData.value.password || formData.value.password_confirm) {
if (!formData.value.password_old) {
return ElMessage({ type: 'error', message: '请输入当前密码' })
}
if (!formData.value.password) {
return ElMessage({ type: 'error', message: '请输入新的密码' })
}
if (!formData.value.password_confirm) {
return ElMessage({ type: 'error', message: '请输入确定密码' })
}
if (formData.value.password_confirm != formData.value.password) {
return ElMessage({ type: 'error', message: '两次输入的密码不一样' })
}
}
if (formData.value.password_old && formData.value.password && formData.value.password_confirm) {
if (formData.value.password_old.length < 6 || formData.value.password_old.length > 32) {
return ElMessage({ type: 'error', message: '密码长度在6到32之间' })
}
if (formData.value.password.length < 6 || formData.value.password.length > 32) {
return ElMessage({ type: 'error', message: '密码长度在6到32之间' })
}
if (
formData.value.password_confirm.length < 6 ||
formData.value.password_confirm.length > 32
) {
return ElMessage({ type: 'error', message: '密码长度在6到32之间' })
}
}
await apiAdminEdit({ ...formData.value })
getAuthAdminMySelf()
store.dispatch('user/getUser')
}
//
const onSubmit = (formEl: FormInstance | undefined): void => {
if (!formEl) return
formEl.validate((valid): Boolean | undefined => {
if (!valid) return false
setAuthAdminEditSelf()
})
//
const getAuthAdminMySelf = async (): Promise<void> => {
formData.value = await apiAuthAdminMySelf()
}
//
const setAuthAdminEditSelf = async ():Promise<void> => {
if(formData.value.password_old || formData.value.password || formData.value.password_confirm) {
if(!formData.value.password_old) {
return ElMessage({ type: 'error', message: '请输入当前密码' })
}
if(!formData.value.password) {
return ElMessage({ type: 'error', message: '请输入新的密码' })
}
if(!formData.value.password_confirm) {
return ElMessage({ type: 'error', message: '请输入确定密码' })
}
if(formData.value.password_confirm != formData.value.password) {
return ElMessage({ type: 'error', message: '两次输入的密码不一样' })
}
}
if(formData.value.password_old && formData.value.password && formData.value.password_confirm) {
if(formData.value.password_old.length < 6 || formData.value.password_old.length > 32) {
return ElMessage({ type: 'error', message: '密码长度在6到32之间' })
}
if(formData.value.password.length < 6 || formData.value.password.length > 32) {
return ElMessage({ type: 'error', message: '密码长度在6到32之间' })
}
if(formData.value.password_confirm.length < 6 || formData.value.password_confirm.length > 32) {
return ElMessage({ type: 'error', message: '密码长度在6到32之间' })
}
}
await apiAuthAdminEditSelf({...formData.value})
getAuthAdminMySelf()
store.dispatch('user/getUser')
}
//
const onSubmit = (formEl: FormInstance | undefined): void => {
if(!formEl) return
formEl.validate((valid): Boolean | undefined => {
if(!valid) return false
setAuthAdminEditSelf()
})
}
onMounted(() => {
getAuthAdminMySelf()
})
}
onMounted(() => {
getAuthAdminMySelf()
})
</script>
<style lang="scss" scoped>
</style>
<style lang="scss" scoped></style>

View File

@ -14,27 +14,56 @@
<el-card class="m-t-15" shadow="never">
<div>
<div>基本信息</div>
<el-table class="m-t-20" :data="cacheDate">
<el-table-column label="Redis版本" prop=""></el-table-column>
<el-table-column label="运行模式" prop=""> </el-table-column>
<el-table-column label="端口" prop=""> </el-table-column>
<el-table-column label="客户端数" prop=""> </el-table-column>
<el-table-column label="运行时间(天)" prop=""> </el-table-column>
<el-table-column label="使用内存" prop=""> </el-table-column>
<el-table-column label="使用CPU" prop=""> </el-table-column>
<el-table-column label="内存配置" prop=""> </el-table-column>
<el-table-column label="AOF是否开启" prop=""> </el-table-column>
<el-table-column label="RDB是否成功" prop=""> </el-table-column>
<el-table-column label="Key数量" prop=""> </el-table-column>
<el-table-column label="网络入口/出口" prop=""> </el-table-column>
</el-table>
<div class="m-b-15">基本信息</div>
<el-form :inline="true" :model="formData" label-width="110px" size="small">
<el-form-item label="Redis版本">
<div>{{ formData.redis_version || '-' }}</div>
</el-form-item>
<el-form-item label="运行模式">
<div>{{ formData.redis_mode || '-' }}</div>
</el-form-item>
<el-form-item label="端口">
<div>{{ formData.tcp_port || '-' }}</div>
</el-form-item>
<el-form-item label="客户端数">
<div>{{ formData.connected_clients || '-' }}</div>
</el-form-item>
<el-form-item label="运行时间(天)">
<div>{{ formData.uptime_in_days || '-' }}</div>
</el-form-item>
<el-form-item label="使用内存">
<div>{{ formData.used_memory_human || '-' }}</div>
</el-form-item>
<el-form-item label="使用CPU">
<div>{{ formData.used_cpu_user_children || '-' }}</div>
</el-form-item>
<el-form-item label="内存配置">
<div>{{ formData.maxmemory_human || '-' }}</div>
</el-form-item>
<el-form-item label="AOF是否开启">
<div>{{ formData.aof_enabled || '-' }}</div>
</el-form-item>
<el-form-item label="RDB是否成功">
<div>{{ formData.rdb_last_bgsave_status || '-' }}</div>
</el-form-item>
<el-form-item label="Key数量">
<div>{{ formData.dbSize || '-' }}</div>
</el-form-item>
<el-form-item label="网络入口/出口">
<div>
{{ formData.instantaneous_input_kbps || '-' }}
<span>/</span>
{{ formData.instantaneous_output_kbps || '-' }}
</div>
</el-form-item>
</el-form>
</div>
</el-card>
<div class="m-t-15 flex">
<!-- 命令统计 -->
<el-card class="m-r-15 flex-1" shadow="never">
<el-card class="m-r-15 flex-1 test" shadow="never">
<div>
<div class="p-b-60">命令统计</div>
<div class="statistical-chart">
@ -46,9 +75,9 @@
<!-- 内存信息 -->
<el-card class="flex-1" shadow="never">
<div>
<div class="p-b-60">内存信息</div>
<div class="p-b-40">内存信息</div>
<div class="statistical-chart">
<div>12222222</div>
<v-chart class="chart" :option="statisticalData.memoryChartOption" />
</div>
</div>
</el-card>
@ -57,8 +86,8 @@
</template>
<script setup lang="ts">
import { apiSystemCacheClear } from '@/api/setting'
import { reactive, ref } from 'vue'
import { apiSystemCache } from '@/api/setting'
import { reactive, ref, onMounted } from 'vue'
import Popup from '@/components/Popup/index.vue'
//
@ -69,6 +98,8 @@ let cacheDate = ref<Array<object>>([
}
])
const formData = ref<any>({})
const statisticalData = reactive({
commandChartOption: {
tooltip: {
@ -79,20 +110,52 @@ const statisticalData = reactive({
series: [
{
label: {
show: false
show: true
},
labelLine: {
show: false
show: true
},
type: 'pie',
radius: '75%',
color: ['#3D87ED', '#CBDAF7', '#246AE7', '#0042de'],
radius: '85%',
color: [
'#0D47A1',
'#1565C0',
'#1976D2',
'#1E88E5',
'#2196F3',
'#42A5F5',
'#64B5F6',
'#90CAF9',
'#BBDEFB',
'#E3F2FD',
'#CAF0F8',
'#ADE8F4',
'#90E0EF',
'#48CAE4',
'#00B4D8',
'#0096C7',
'#0077B6',
'#023E8A',
'#03045E',
'#8ecae6',
'#98c1d9',
'#D9ED92',
'#B5E48C',
'#99D98C',
'#76C893',
'#52B69A',
'#34A0A4',
'#168AAD',
'#1A759F',
'#1E6091',
'#184E77',
'#457b9d'
],
data: [
{ value: 1048, name: 'Search Engine' },
{ value: 735, name: 'Direct' },
{ value: 580, name: 'Email' },
{ value: 484, name: 'Union Ads' },
{ value: 300, name: 'Video Ads' }
{
value: '',
name: ''
}
],
emphasis: {
itemStyle: {
@ -103,18 +166,56 @@ const statisticalData = reactive({
}
}
]
},
memoryChartOption: {
tooltip: {
formatter: '{a} <br/>{b} : {c}%'
},
series: [
{
name: 'Pressure',
type: 'gauge',
radius: '100%',
detail: {
formatter: '{value}'
},
data: [
{
value: '',
name: '内存消耗'
}
]
}
]
}
})
//
const handleClean = async () => {
await apiSystemCacheClear()
const getSystemCache = async () => {
apiSystemCache({})
.then((res: any) => {
console.log(res)
formData.value = res.info
formData.value.dbSize = res.dbSize || ''
statisticalData.commandChartOption.series[0].data = res.commandStats
statisticalData.memoryChartOption.series[0].data = res.info.used_memory_human
console.log(res.info.used_memory_human, '-------------------------')
})
.catch((err: any) => {
console.log('err', err)
})
}
onMounted(() => {
getSystemCache()
})
</script>
<style lang="scss" scoped>
.statistical-chart {
display: flex;
justify-content: center;
height: 240px;
}
</style>

View File

@ -5,24 +5,40 @@
<el-card class="flex-1 m-r-15" shadow="never">
<div>CPU</div>
<div class="m-t-15">
<el-table :data="info.cpu" size="medium">
<el-table-column prop="cpuNum" label="核心数"> </el-table-column>
<el-table-column prop="used" label="用户使用率"> </el-table-column>
<el-table-column prop="sys" label="系统使用率"> </el-table-column>
<el-table-column prop="value" label="当前空闲率"> </el-table-column>
</el-table>
<el-form :inline="true" :model="cpuFormData" label-width="110px" size="small">
<el-form-item label="核心数">
<div>{{ cpuFormData.cpuNum || '-' }}</div>
</el-form-item>
<el-form-item label="用户使用率">
<div>{{ cpuFormData.used || '-' }}%</div>
</el-form-item>
<el-form-item label="系统使用率">
<div>{{ cpuFormData.sys || '-' }}%</div>
</el-form-item>
<el-form-item label="当前空闲率">
<div>{{ cpuFormData.free || '-' }}%</div>
</el-form-item>
</el-form>
</div>
</el-card>
<el-card class="flex-1" shadow="never">
<div>内存</div>
<div class="m-t-15">
<el-table :data="info.mem" size="medium">
<el-table-column prop="total" label="总内存"> </el-table-column>
<el-table-column prop="used" label="已用内存"> </el-table-column>
<el-table-column prop="free" label="剩余内存"> </el-table-column>
<el-table-column prop="usage" label="使用率"> </el-table-column>
</el-table>
<el-form :inline="true" :model="memFormData" label-width="110px" size="small">
<el-form-item label="总内存">
<div>{{ memFormData.total || '-' }}G</div>
</el-form-item>
<el-form-item label="已用内存">
<div>{{ memFormData.used || '-' }}G</div>
</el-form-item>
<el-form-item label="剩余内存">
<div>{{ memFormData.free || '-' }}G</div>
</el-form-item>
<el-form-item label="使用率">
<div>{{ memFormData.usage || '-' }}%</div>
</el-form-item>
</el-form>
</div>
</el-card>
</div>
@ -30,27 +46,49 @@
<el-card shadow="never" class="m-t-15">
<div>服务器信息</div>
<div class="m-t-15">
<el-table :data="info.server" size="medium">
<el-table-column prop="computerName" label="服务器名称"> </el-table-column>
<el-table-column prop="computerIp" label="服务器IP"> </el-table-column>
<el-table-column prop="osName" label="操作系统"> </el-table-column>
<el-table-column prop="osArch" label="系统架构"> </el-table-column>
</el-table>
<el-form :inline="true" :model="serverFormData" label-width="160px" size="small">
<el-form-item label="服务器名称">
<div>{{ serverFormData.computerName || '-' }}</div>
</el-form-item>
<el-form-item label="服务器IP">
<div>{{ serverFormData.computerIp || '-' }}</div>
</el-form-item>
<el-form-item label="操作系统">
<div>{{ serverFormData.osName || '-' }}</div>
</el-form-item>
<el-form-item label="系统架构">
<div>{{ serverFormData.osArch || '-' }}</div>
</el-form-item>
<el-form-item label="项目路径">
<div>{{ serverFormData.userDir || '-' }}</div>
</el-form-item>
</el-form>
</div>
</el-card>
<el-card shadow="never" class="m-t-15">
<div>Java虚拟机信息</div>
<div class="m-t-15">
<el-table :data="info.server" size="medium">
<el-table-column prop="name" label="Java名称"> </el-table-column>
<el-table-column prop="startTime" label="启动时间"> </el-table-column>
<el-table-column prop="home" label="安装路径"> </el-table-column>
<!-- <el-table-column prop="remark" label="项目路径"> </el-table-column> -->
<el-table-column prop="inputArgs" label="运行参数"> </el-table-column>
<el-table-column prop="version" label="Java版本"> </el-table-column>
<el-table-column prop="runTime" label="运行时长"> </el-table-column>
</el-table>
<el-form :inline="true" :model="jvmFormData" label-width="120px" size="small">
<el-form-item label="Java名称">
<div>{{ jvmFormData.name || '-' }}</div>
</el-form-item>
<el-form-item label="启动时间">
<div>{{ jvmFormData.startTime || '-' }}</div>
</el-form-item>
<el-form-item label="安装路径">
<div>{{ jvmFormData.home || '-' }}</div>
</el-form-item>
<el-form-item label="运行参数">
<div>{{ jvmFormData.inputArgs || '-' }}</div>
</el-form-item>
<el-form-item label="Java版本">
<div>{{ jvmFormData.version || '-' }}</div>
</el-form-item>
<el-form-item label="运行时长">
<div>{{ jvmFormData.runTime || '-' }}</div>
</el-form-item>
</el-form>
</div>
</el-card>
@ -71,38 +109,37 @@
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, onMounted } from 'vue'
<script setup lang="ts">
import { defineComponent, reactive, onMounted, ref } from 'vue'
import { apiSystemInfo } from '@/api/setting'
export default defineComponent({
setup() {
const info = reactive({
cpu: [], // cpu
mem: [], //
server: [], //
auth: [], //
disk: [] //
const info = reactive({
disk: [] //
})
const cpuFormData = ref<any>({})
const memFormData = ref<any>({})
const serverFormData = ref<any>({})
const jvmFormData = ref<any>({})
const getSystemInfo = () => {
apiSystemInfo()
.then((res: any) => {
console.log('res', res)
cpuFormData.value = res.cpu
memFormData.value = res.mem
serverFormData.value = res.sys
jvmFormData.value = res.jvm
info.disk = res.disk
})
const getSystemInfo = () => {
apiSystemInfo().then((res: any) => {
console.log('res', res)
info.cpu = res.cpu
info.server = res.server
info.auth = res.auth
info.disk = res.disk
})
}
onMounted(() => {
getSystemInfo()
.catch((err: any) => {
console.log('err', err)
})
}
return {
info,
getSystemInfo
}
}
onMounted(() => {
getSystemInfo()
})
</script>