xiaohuo 9 months ago
commit 58cbb0d94f
  1. 2
      ALOps_sys_backend/alops-system/src/main/java/com/alops/system/domain/dto/MonitorListDto.java
  2. 6
      ALOps_sys_backend/alops-system/src/main/resources/mapper/system/EquBaseMapper.xml
  3. 2
      ALOps_sys_fe/alops-ui/package.json
  4. 13
      ALOps_sys_fe/alops-ui/src/api/QandA/knowledge.js
  5. 1
      ALOps_sys_fe/alops-ui/src/api/device/deviceType.js
  6. 8
      ALOps_sys_fe/alops-ui/src/api/inMonitoring/assessment.js
  7. 13
      ALOps_sys_fe/alops-ui/src/api/inMonitoring/devicesState.js
  8. 43
      ALOps_sys_fe/alops-ui/src/views/QandA/knowledge/index.vue
  9. 485
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/assessment/index.vue
  10. 129
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/devicesState/BarChart2.vue
  11. 34
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/devicesState/cardItem.vue
  12. 676
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/devicesState/detail.vue
  13. 77
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/devicesState/history.vue
  14. 8
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/devicesState/index.vue
  15. 79
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/devicesState/interface.vue
  16. 71
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/devicesState/routing.vue
  17. 70
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/devicesState/vlan.vue
  18. 10
      ALOps_sys_fe/alops-ui/src/views/inMonitoring/inMonitor/rules/index.vue

@ -20,7 +20,7 @@ public class MonitorListDto {
private String deviceLevel;
private String location;
private String status;
private String equImage;
// 监控指标
private Float cpuUtilization;
private String health;

@ -200,6 +200,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
c.equTypeName,
c.equManuId,
c.equManuName,
c.equImage,
c.version,
c.deviceLevel,
c.location,
@ -219,6 +220,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
t.name AS equTypeName,
b.manufacture AS equManuId,
m.name AS equManuName,
b.equ_image AS equImage,
b.version,
b.device_level AS deviceLevel,
b.location,
@ -324,9 +326,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
LEFT JOIN equ_supplier s ON b.supplier_id = s.id
LEFT JOIN equ_gather g ON b.id = g.equ_id
where g.cpu_utilization is not null
and b.id = #{id}
where b.id = #{id}
ORDER BY g.gather_time desc limit 1
</select>

@ -29,6 +29,7 @@
"axios": "0.28.1",
"clipboard": "2.0.8",
"core-js": "3.37.1",
"dayjs": "^1.11.18",
"echarts": "5.4.0",
"element-ui": "2.15.14",
"file-saver": "2.0.5",
@ -37,6 +38,7 @@
"js-beautify": "1.13.0",
"js-cookie": "3.0.1",
"jsencrypt": "3.0.0-rc.1",
"lodash": "^4.17.21",
"nprogress": "0.2.0",
"quill": "2.0.2",
"screenfull": "5.0.2",

@ -1,5 +1,5 @@
import request from '@/utils/request'
const api = '/QandA/knowledge/'
const api = '/QandA/knowledge'
// 查询详细
export function getDict() {
@ -21,7 +21,7 @@ export function permanentKnowledgeList(query) {
// 获取所有上传文件信息
export function uploadedFilesList(query) {
return request({
url: api + '/knowBase/uploaded-files',
url: '/QandA/knowledge/uploaded-files',
method: 'get',
params: query
})
@ -30,16 +30,19 @@ export function uploadedFilesList(query) {
// 新增
export function add(data) {
return request({
url: api + 'upload',
url: api + '/upload',
method: 'post',
data: data
data: data,
headers: {
'Content-Type': 'multipart/form-data'
}
})
}
// 修改
export function update(data) {
return request({
url: api + 'upload',
url: api + '/update-knowledge',
method: 'put',
data: data
})

@ -1,4 +1,5 @@
import request from '@/utils/request'
import { parseStrEmpty } from "@/utils/ruoyi";
const api = '/device/deviceType/'
// 查询详细

@ -1,11 +1,11 @@
import request from '@/utils/request'
// 新增用户
export function knowledgeAsk(data) {
export function list(query) {
return request({
url: '/QandA/knowledge/ask',
method: 'post',
data: data
url: '/inMonitoring/equAssessment/list',
method: 'get',
params: query
})
}

@ -2,7 +2,7 @@ import request from '@/utils/request'
import { parseStrEmpty } from "@/utils/ruoyi";
const api = '/device/files/'
// 查询多台设备列表
// 查询多台设备列表-s首页
export function list(query) {
return request({
url: api + 'monitorById',
@ -11,6 +11,15 @@ export function list(query) {
})
}
// 查询多台设备列表-s首页
export function monitorpageList(query) {
return request({
url: api + 'monitorpage',
method: 'get',
params: query
})
}
// 查询单台设备
export function getInfo(id) {
return request({
@ -31,7 +40,7 @@ export function historyQuery(query) {
// 设备历史预警
export function alertmessage(equId) {
return request({
url: '/inMonitoring/alertmessage/' + parseStrEmpty(equId),
url: '/inMonitoring/alertMessage/' + parseStrEmpty(equId),
method: 'get'
})
}

@ -14,13 +14,15 @@
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="序号" align="center" key="id" prop="id"/>
<el-table-column label="文件名称" align="center" key="title" prop="title" :show-overflow-tooltip="true" />
<el-table-column label="描述" align="center" key="description" prop="description" :show-overflow-tooltip="true" />
<el-table-column label="创建人" align="center" key="createBy" prop="createBy" :show-overflow-tooltip="true" />
<el-table-column label="创建时间" align="center" prop="createDate" width="160">
<el-table-column
label="序号"
width="60"
type="index"
></el-table-column>
<el-table-column label="文件名称" align="center" key="source" prop="source" :show-overflow-tooltip="true" />
<el-table-column label="更新时间" align="center" prop="uploadTime" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createDate) }}</span>
<span>{{ parseTime(scope.row.uploadTime) }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
@ -41,19 +43,13 @@
<el-form ref="form" :model="form" :rules="rules" label-width="90px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="文档标题" prop="title">
<el-input v-model="form.title" placeholder="请输入文档标题" maxlength="30" />
<el-form-item label="文档标题" prop="source">
<el-input v-model="form.source" placeholder="请输入文档标题" maxlength="30" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="文档简介" prop="description">
<el-input v-model="form.description" type="textarea" :rows="3" placeholder="请输入文档简介" />
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="上传文件" prop="fileUrl">
<ImageUpload @input="upImage" :value="form.fileUrl" :fileType="['docx','txt']" listType="txt"/>
<el-form-item label="上传文件" prop="file">
<ImageUpload @input="upImage" :value="form.filePath" :fileType="['docx','txt']" listType="txt"/>
</el-form-item>
</el-col>
</el-row>
@ -178,7 +174,7 @@ export default {
},
upImage(fileList){
console.log(fileList)
this.form.fileUrl = fileList
this.form.file = fileList
},
@ -235,18 +231,25 @@ export default {
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
const formData = new FormData();
formData.append("source", this.form.source)
formData.append("description", this.form.description)
formData.append("file", this.form.file)
if (this.form.id != undefined) {
update(this.form).then(response => {
update(formData).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
add(this.form).then(response => {
add(formData).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}).catch(error => console.error('上传失败', error));
}
}
})

@ -7,76 +7,44 @@
<!--用户数据-->
<pane size="84">
<el-col>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="用户名称" prop="userName">
<el-input v-model="queryParams.userName" placeholder="请输入用户名称" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="queryParams.phonenumber" placeholder="请输入手机号码" clearable style="width: 240px" @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="状态" prop="status">
<el-select v-model="queryParams.status" placeholder="用户状态" clearable style="width: 240px">
<el-option v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="创建时间">
<el-date-picker v-model="dateRange" style="width: 240px" value-format="yyyy-MM-dd" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"></el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd" v-hasPermi="['inMonitoring:assessment:add']">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" v-hasPermi="['inMonitoring:assessment:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['inMonitoring:assessment:remove']">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="el-icon-upload2" size="mini" @click="handleImport" v-hasPermi="['inMonitoring:assessment:import']">导入</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['inMonitoring:assessment:export']">导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" />
<el-table-column label="用户编号" align="center" key="userId" prop="userId" v-if="columns[0].visible" />
<el-table-column label="用户名称" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
<el-table-column label="用户昵称" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
<el-table-column label="手机号码" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" />
<el-table-column label="状态" align="center" key="status" v-if="columns[5].visible">
<el-table-column
label="序号"
width="60"
type="index"
></el-table-column>
<el-table-column label="设备ID" align="center" key="equNumber" prop="equNumber" />
<el-table-column label="设备名称" align="center" key="name" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="设备类型" align="center" key="equType" prop="equType" :show-overflow-tooltip="true" />
<el-table-column label="设备级别" align="center" key="deviceLevel" prop="deviceLevel" width="120" />
<el-table-column label="位置" align="center" key="location" prop="location" width="120" />
<el-table-column label="CPU使用率" align="center" key="cpuStatus" prop="cpuStatus" width="120" >
<template slot-scope="scope">
<el-tag :hit="false" :type="scope.row.cpuStatus == '健康'?'success':scope.row.cpuStatus == '良好'?'':scope.row.cpuStatus == '一般'?'danger':scope.row.cpuStatus == '需维护'?'warning':'info'"> {{ scope.row.cpuStatus }} </el-tag>
</template>
</el-table-column>
<el-table-column label="内存使用率" align="center" key="memoryStatus" prop="memoryStatus" width="120" >
<template slot-scope="scope">
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
<el-tag :hit="false" :type="scope.row.memoryStatus == '健康'?'success':scope.row.memoryStatus == '良好'?'':scope.row.memoryStatus == '一般'?'danger':scope.row.memoryStatus == '需维护'?'warning':'info'"> {{ scope.row.memoryStatus }} </el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" v-if="columns[6].visible" width="160">
<el-table-column label="设备温度" align="center" key="temperatureStatus" prop="temperatureStatus" width="120" >
<template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span>
<el-tag :hit="false" :type="scope.row.temperatureStatus == '健康'?'success':scope.row.temperatureStatus == '良好'?'':scope.row.temperatureStatus == '一般'?'danger':scope.row.temperatureStatus == '需维护'?'warning':'info'"> {{ scope.row.temperatureStatus }} </el-tag>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="160" class-name="small-padding fixed-width">
<template slot-scope="scope" v-if="scope.row.userId !== 1">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['inMonitoring:assessment:edit']">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['inMonitoring:assessment:remove']">删除</el-button>
<el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['inMonitoring:assessment:resetPwd', 'inMonitoring:assessment:edit']">
<el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="handleResetPwd" icon="el-icon-key" v-hasPermi="['inMonitoring:assessment:resetPwd']">重置密码</el-dropdown-item>
<el-dropdown-item command="handleAuthRole" icon="el-icon-circle-check" v-hasPermi="['inMonitoring:assessment:edit']">分配角色</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-table-column label="健康度" align="center" key="healthStatus" prop="healthStatus" width="120" >
<template slot-scope="scope">
<el-tag :hit="false" :type="scope.row.healthStatus == '健康'?'success':scope.row.healthStatus == '良好'?'':scope.row.healthStatus == '一般'?'danger':scope.row.healthStatus == '需维护'?'warning':'info'"> {{ scope.row.healthStatus }} </el-tag>
</template>
</el-table-column>
<el-table-column label="风险等级" align="center" key="riskGrade" prop="riskGrade" width="120" >
<template slot-scope="scope">
<el-tag :hit="false" :type="scope.row.riskGrade == '无风险'?'success':scope.row.riskGrade == '低'?'':scope.row.riskGrade == '中'?'danger':scope.row.riskGrade == '高'?'warning':'info'"> {{ scope.row.riskGrade }} </el-tag>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
@ -84,104 +52,11 @@
</pane>
</splitpanes>
</el-row>
<el-dialog :title="title" :visible.sync="open" width="760px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="90px">
<el-row :gutter="20">
<!-- 用户昵称 + 手机号码 -->
<el-col :span="12">
<el-form-item label="用户昵称" prop="nickName">
<el-input v-model="form.nickName" placeholder="请输入用户昵称" maxlength="30" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手机号码" prop="phonenumber">
<el-input v-model="form.phonenumber" placeholder="请输入手机号码" maxlength="11" />
</el-form-item>
</el-col>
<!-- 邮箱 + 用户名称 -->
<el-col :span="12">
<el-form-item label="邮箱" prop="email">
<el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item v-if="form.userId == undefined" label="用户名称" prop="userName">
<el-input v-model="form.userName" placeholder="请输入用户名称" maxlength="30" />
</el-form-item>
</el-col>
<!-- 用户密码仅新增+ 用户性别 -->
<el-col :span="12">
<el-form-item v-if="form.userId == undefined" label="用户密码" prop="password">
<el-input v-model="form.password" placeholder="请输入用户密码" type="password" maxlength="20" show-password />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="用户性别">
<el-select v-model="form.sex" placeholder="请选择性别" style="width: 100%">
<el-option v-for="dict in dict.type.sys_user_sex" :key="dict.value" :label="dict.label" :value="dict.value"></el-option>
</el-select>
</el-form-item>
</el-col>
<!-- 状态 + 角色 -->
<el-col :span="12">
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio v-for="dict in dict.type.sys_normal_disable" :key="dict.value" :label="dict.value">{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="角色">
<el-select v-model="form.roleIds" multiple placeholder="请选择角色" style="width: 100%">
<el-option v-for="item in roleOptions" :key="item.roleId" :label="item.roleName" :value="item.roleId" :disabled="item.status == 1"></el-option>
</el-select>
</el-form-item>
</el-col>
<!-- 备注单独一行 -->
<el-col :span="24">
<el-form-item label="备注">
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入内容" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</span>
</el-dialog>
<!-- 用户导入对话框 -->
<el-dialog :title="upload.title" :visible.sync="upload.open" width="400px" append-to-body>
<el-upload ref="upload" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip text-center" slot="tip">
<div class="el-upload__tip" slot="tip">
<el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据
</div>
<span>仅允许导入xlsxlsx格式文件</span>
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline" @click="importTemplate">下载模板</el-link>
</div>
</el-upload>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="submitFileForm"> </el-button>
<el-button @click="upload.open = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus, deptTreeSelect } from "@/api/inMonitoring/assessment"
import { list } from "@/api/inMonitoring/assessment"
import { getToken } from "@/utils/auth"
import Treeselect from "@riophae/vue-treeselect"
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
@ -196,57 +71,8 @@ export default {
return {
//
loading: true,
//
ids: [],
//
single: true,
//
multiple: true,
//
showSearch: true,
//
total: 0,
//
userList: null,
//
title: "",
//
deptOptions: undefined,
//
enabledDeptOptions: undefined,
//
open: false,
//
deptName: undefined,
//
initPassword: undefined,
//
dateRange: [],
//
postOptions: [],
//
roleOptions: [],
//
form: {},
defaultProps: {
children: "children",
label: "label"
},
//
upload: {
//
open: false,
//
title: "",
//
isUploading: false,
//
updateSupport: 0,
//
headers: { Authorization: "Bearer " + getToken() },
//
url: process.env.VUE_APP_BASE_API + "/system/user/importData"
},
//
queryParams: {
pageNum: 1,
@ -256,53 +82,9 @@ export default {
status: undefined,
deptId: undefined
},
//
columns: [
{ key: 0, label: '用户编号', visible: true, showInSelector: true },
{ key: 1, label: '用户名称', visible: true, showInSelector: true },
{ key: 2, label: '用户昵称', visible: true, showInSelector: true },
{ key: 3, label: '部门', visible: false, showInSelector: false }, // 👈
{ key: 4, label: '手机号码', visible: true, showInSelector: true },
{ key: 5, label: '状态', visible: true, showInSelector: true },
{ key: 6, label: '创建时间', visible: true, showInSelector: true }
],
//
rules: {
userName: [
{ required: true, message: "用户名称不能为空", trigger: "blur" },
{ min: 2, max: 20, message: '用户名称长度必须介于 2 和 20 之间', trigger: 'blur' }
],
nickName: [
{ required: true, message: "用户昵称不能为空", trigger: "blur" }
],
password: [
{ required: true, message: "用户密码不能为空", trigger: "blur" },
{ min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' },
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
],
email: [
{
type: "email",
message: "请输入正确的邮箱地址",
trigger: ["blur", "change"]
}
],
phonenumber: [
{
pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/,
message: "请输入正确的手机号码",
trigger: "blur"
}
]
}
}
},
watch: {
//
deptName(val) {
this.$refs.tree.filter(val)
}
},
created() {
this.getList()
@ -311,219 +93,12 @@ export default {
/** 查询用户列表 */
getList() {
this.loading = true
listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
list(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.userList = response.rows
this.total = response.total
this.loading = false
}
)
},
// /** */
// getDeptTree() {
// deptTreeSelect().then(response => {
// this.deptOptions = response.data
// this.enabledDeptOptions = this.filterDisabledDept(JSON.parse(JSON.stringify(response.data)))
// })
// },
//
filterDisabledDept(deptList) {
return deptList.filter(dept => {
if (dept.disabled) {
return false
}
if (dept.children && dept.children.length) {
dept.children = this.filterDisabledDept(dept.children)
}
return true
})
},
//
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
//
handleNodeClick(data) {
this.queryParams.deptId = data.id
this.handleQuery()
},
//
handleStatusChange(row) {
let text = row.status === "0" ? "启用" : "停用"
this.$modal.confirm('确认要"' + text + '""' + row.userName + '"用户吗?').then(function() {
return changeUserStatus(row.userId, row.status)
}).then(() => {
this.$modal.msgSuccess(text + "成功")
}).catch(function() {
row.status = row.status === "0" ? "1" : "0"
})
},
//
cancel() {
this.open = false
this.reset()
},
//
reset() {
this.form = {
userId: undefined,
deptId: undefined,
userName: undefined,
nickName: undefined,
password: undefined,
phonenumber: undefined,
email: undefined,
sex: undefined,
status: "0",
remark: undefined,
postIds: [],
roleIds: []
}
this.resetForm("form")
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1
this.getList()
},
/** 重置按钮操作 */
resetQuery() {
this.dateRange = []
this.resetForm("queryForm")
this.queryParams.deptId = undefined
this.$refs.tree.setCurrentKey(null)
this.handleQuery()
},
//
handleSelectionChange(selection) {
this.ids = selection.map(item => item.userId)
this.single = selection.length != 1
this.multiple = !selection.length
},
//
handleCommand(command, row) {
switch (command) {
case "handleResetPwd":
this.handleResetPwd(row)
break
case "handleAuthRole":
this.handleAuthRole(row)
break
default:
break
}
},
/** 新增按钮操作 */
handleAdd() {
this.reset()
getUser().then(response => {
this.postOptions = response.posts
this.roleOptions = response.roles
this.open = true
this.title = "添加用户"
this.form.password = this.initPassword
})
},
/** 修改按钮操作 */
handleUpdate(row) {
this.reset()
const userId = row.userId || this.ids
getUser(userId).then(response => {
this.form = response.data
this.postOptions = response.posts
this.roleOptions = response.roles
this.$set(this.form, "postIds", response.postIds)
this.$set(this.form, "roleIds", response.roleIds)
this.open = true
this.title = "修改用户"
this.form.password = ""
})
},
/** 重置密码按钮操作 */
handleResetPwd(row) {
this.$prompt('请输入"' + row.userName + '"的新密码', "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
closeOnClickModal: false,
inputPattern: /^.{5,20}$/,
inputErrorMessage: "用户密码长度必须介于 5 和 20 之间",
inputValidator: (value) => {
if (/<|>|"|'|\||\\/.test(value)) {
return "不能包含非法字符:< > \" ' \\\ |"
}
},
}).then(({ value }) => {
resetUserPwd(row.userId, value).then(response => {
this.$modal.msgSuccess("修改成功,新密码是:" + value)
})
}).catch(() => {})
},
/** 分配角色操作 */
handleAuthRole: function(row) {
const userId = row.userId
this.$router.push("/system/user-auth/role/" + userId)
},
/** 提交按钮 */
submitForm: function() {
this.$refs["form"].validate(valid => {
if (valid) {
if (this.form.userId != undefined) {
updateUser(this.form).then(response => {
this.$modal.msgSuccess("修改成功")
this.open = false
this.getList()
})
} else {
addUser(this.form).then(response => {
this.$modal.msgSuccess("新增成功")
this.open = false
this.getList()
})
}
}
})
},
/** 删除按钮操作 */
handleDelete(row) {
const userIds = row.userId || this.ids
this.$modal.confirm('是否确认删除用户编号为"' + userIds + '"的数据项?').then(function() {
return delUser(userIds)
}).then(() => {
this.getList()
this.$modal.msgSuccess("删除成功")
}).catch(() => {})
},
/** 导出按钮操作 */
handleExport() {
this.download('system/user/export', {
...this.queryParams
}, `user_${new Date().getTime()}.xlsx`)
},
/** 导入按钮操作 */
handleImport() {
this.upload.title = "用户导入"
this.upload.open = true
},
/** 下载模板操作 */
importTemplate() {
this.download('system/user/importTemplate', {
}, `user_template_${new Date().getTime()}.xlsx`)
},
//
handleFileUploadProgress(event, file, fileList) {
this.upload.isUploading = true
},
//
handleFileSuccess(response, file, fileList) {
this.upload.open = false
this.upload.isUploading = false
this.$refs.upload.clearFiles()
this.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "导入结果", { dangerouslyUseHTMLString: true })
this.getList()
},
//
submitFileForm() {
this.$refs.upload.submit()
}
}
}

@ -1,129 +0,0 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import * as echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
const animationDuration = 6000
export default {
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
var handred = 100
var point = 66
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
title: [{
text: 'CPU占用',
x: 'center',
y: '40%',
textStyle: {
fontSize: 10,
color: '#000',
}
},{
text: '{a|'+ point +'}{c|%}',
x: 'center',
y: '53%',
textStyle: {
rich:{
a: {
fontSize: 10,
color: '#000'
},
c: {
fontSize: 10,
color: '#000',
// padding: [5,0]
}
}
}
}],
series: [{
name: 'circle',
type: 'pie',
clockWise: true,
radius: ['50%', '66%'],
itemStyle: {
normal: {
label: {
show: false
},
labelLine: {
show: false
}
}
},
hoverAnimation: false,
data: [{
value: point,
name: '占比',
itemStyle: {
normal: {
color: { //
colorStops: [{
offset: 0,
color: '#0095e3' // 0%
}, {
offset: 1,
color: '#28E8FA' // 100%
}]
},
label: {
show: false
},
labelLine: {
show: false
}
}
}
}, {
name: '剩余',
value: handred - point,
itemStyle: {
normal: {
color: '#cceaf9'
}
}
}]
}]
})
}
}
}
</script>

@ -18,7 +18,7 @@
<div class="device-box">
<div class="device-image">
<img v-if="cardData.image" :src="cardData.image" alt="" class="device-icon">
<img v-if="cardData.equImage" :src="baseUrl+cardData.equImage" alt="" class="device-icon">
<i v-else class="fas fa-server"></i>
</div>
<div class="device-info">
@ -43,6 +43,7 @@
<div class="info-item">
<span class="info-label">
<i class="fas fa-heartbeat"></i> 带外IP
<i class="fas fa-heartbeat"></i> 带内IP
</span>
<span class="info-value">{{cardData.ip || '暂无'}}</span>
</div>
@ -55,29 +56,27 @@
<div class="metric-value cpu-usage">{{cardData.cpuUtilization||0}}%</div>
<div class="metric-label">CPU占用</div>
<div class="progress-bar">
<div class="progress-fill" :style="{width: cardData.cpuUtilization||0+'%'}"></div>
<div class="progress-fill" :style="{ width: `${cardData.cpuUtilization || 0}%` }"></div>
</div>
</div>
<div class="metric-card">
<div class="metric-value cpu-usage">{{cardData.contWorkPeriod||0}}%</div>
<div class="metric-label">内存占用</div>
<div class="metric-value cpu-usage">{{getPercentage(cardData.health)||0}}%</div>
<div class="metric-label">健康度</div>
<div class="progress-bar">
<div class="progress-fill" :style="{width: cardData.contWorkPeriod||0+'%'}"></div>
<div class="progress-fill" :style="{width: getPercentage(cardData.health)||0+'%'}"></div>
</div>
</div>
<div class="metric-card">
<div class="metric-value alert-pending">{{cardData.unhandledAlertCount||0}}</div>
<div class="metric-label">待处理预警数</div>
</div>
<div class="metric-card">
<div class="metric-value alert-total">{{cardData.handledAlertCount||0}}</div>
<div class="metric-label">预警总数</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@ -87,11 +86,8 @@
import * as echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import BarChart from './BarChart1.vue'
import BarChart2 from './BarChart2.vue'
export default {
name: "cardItem",
components: { BarChart, BarChart2 },
props: {
cardData: {
type: Object,
@ -101,6 +97,7 @@ export default {
},
data() {
return {
baseUrl: process.env.VUE_APP_BASE_API
}
},
mounted() {
@ -223,6 +220,19 @@ export default {
const userId = row.id
this.$router.push("/inMonitoring/devicesState-detail/detail/" + userId)
},
getPercentage(value) {
const percentageMap = {
1: 100,
2: 75,
3: 50,
4: 25,
0: 0,
};
return percentageMap[value] || 0; // value 0
},
}
@ -232,7 +242,7 @@ export default {
.body {
color: #2d3748;
line-height: 1.6;
min-height: 100vh;
min-height: 60vh;
}
.dashboard {

@ -16,7 +16,7 @@
</div>
<div class="top-section-con">
<div class="device-image">
<img v-if="details.image" :src="details.image" alt="" class="device-icon">
<img v-if="details.equImage" :src="baseUrl+details.equImage" alt="" class="device-icon">
<i v-else class="fas fa-server"></i>
</div>
<!-- 设备基本信息 -->
@ -157,17 +157,51 @@
<i class="fas fa-chart-bar"></i>
设备运行数据
</h2>
<el-date-picker
v-model="daterange"
type="daterange"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
v-model="DateValue"
type="datetimerange"
value-format="yyyy-MM-dd hh:mm:ss"
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
@change="handleDateChange">
</el-date-picker>
</div>
<div class="chart-container" id="performanceChart"></div>
<div class="chart-container" id="trafficChart"></div>
<el-row :gutter="20" class="chart-row">
<el-col :span="12">
<el-col :span="12">
<div class="chart-container" id="performanceChart4"></div>
</el-col>
<el-col :span="12">
<div class="chart-container" id="performanceChart3"></div>
</el-col>
<el-col :span="12">
<div class="chart-container" id="performanceChart2"></div>
</el-col>
<el-col :span="12">
<div class="chart-container" id="performanceChart"></div>
</el-col>
</el-col>
<el-col :span="12">
<el-col :span="12">
<div ref="usedmemory" style="height: 200px" />
</el-col>
<el-col :span="12">
<div ref="usedmemory2" style="height: 200px" />
</el-col>
<el-col :span="8">
<div ref="usedmemory3" style="height: 200px" />
</el-col>
<el-col :span="8">
<div ref="usedmemory4" style="height: 200px" />
</el-col>
<el-col :span="8">
<div ref="usedmemory5" style="height: 200px" />
</el-col>
</el-col>
</el-row>
</div>
<!-- 右侧参数 -->
@ -182,7 +216,16 @@
<div class="metrics-grid">
<div class="bottom-item" v-if="tabIndex == 0">
<History/>
<History :dsId="dsId"/>
</div>
<div class="bottom-item" v-if="tabIndex == 1">
<Interface :dsId="dsId"/>
</div>
<div class="bottom-item" v-if="tabIndex == 2">
<Vlan :dsId="dsId"/>
</div>
<div class="bottom-item" v-if="tabIndex == 3">
<Routing :dsId="dsId"/>
</div>
</div>
</div>
@ -195,14 +238,20 @@
import { getInfo, historyQuery } from "@/api/inMonitoring/devicesState"
import * as echarts from 'echarts'
import dayjs from 'dayjs';
require('echarts/theme/macarons') // echarts theme
import History from './history.vue'
import Interface from './interface.vue'
import Vlan from './vlan.vue'
import Routing from './routing.vue'
import LineChart from './LineChart.vue'
export default {
name: "cardItem",
components: { History },
components: { History, Interface, Vlan, Routing, LineChart },
data() {
return {
dateRange: [],
DateValue: [dayjs().subtract(1, 'month').format('YYYY-MM-DD HH:mm:ss'),dayjs().format('YYYY-MM-DD HH:mm:ss')],
selectedTab: 1,
tabs: [
{ name: '历史预警' },
@ -211,35 +260,342 @@ export default {
{ name: '路由表信息' },
],
tabIndex: 0,
details: {},
historyQueryList: {
minTime: '',
maxTime: '',
pageNum: 1,
pageSize: 1000,
},
dsId:null,
details: {},
historyQueryList: {
maxTime:dayjs().format('YYYY-MM-DD HH:mm:ss'),
minTime:dayjs().subtract(1, 'month').format('YYYY-MM-DD HH:mm:ss'),
pageNum: 1,
pageSize: 1000,
},
historyQueryData: {
},
baseUrl: process.env.VUE_APP_BASE_API
}
},
mounted() {
let routeList = this.$route.params;
this.initCharts();
this.getInfoFun(routeList.id)
this.gethistoryQuery(routeList.id)
this.dsId = routeList.id;
this.getInfoFun(this.dsId)
setTimeout(() => {
this.gethistoryQuery(this.dsId)
}, 1000)
},
methods: {
initCharts() {
//
let details = this.historyQueryData;
const performanceChart = echarts.init(document.getElementById('performanceChart'));
const performanceChart2 = echarts.init(document.getElementById('performanceChart2'));
const performanceChart3 = echarts.init(document.getElementById('performanceChart3'));
const performanceChart4 = echarts.init(document.getElementById('performanceChart4'));
const usedmemory = echarts.init(this.$refs.usedmemory, "macarons")
const usedmemory2 = echarts.init(this.$refs.usedmemory2, "macarons")
const usedmemory3 = echarts.init(this.$refs.usedmemory3, "macarons")
const usedmemory4 = echarts.init(this.$refs.usedmemory4, "macarons")
const usedmemory5 = echarts.init(this.$refs.usedmemory5, "macarons")
const chartData = { min: 0, max: 100, value: 70 };
usedmemory.setOption({
series: [
{
type: 'gauge',
center: ['50%', '60%'],
radius: '90%',
min: chartData.min,
max: chartData.max,
startAngle: 220,
endAngle: -40,
splitNumber: 8,
axisLine: {
lineStyle: {
color: [
[0.25, '#7afeaf'],
[0.5, '#58d9f9'],
[0.75, '#fbdd5e'],
[1, '#f03b44'],
],
width: 10,
},
},
splitLine: {
// 线
show: true,
length: 15,
distance: 10,
lineStyle: {
width: 2,
color: 'auto',
},
},
axisTick: {
// 线线
show: true,
lineStyle: {
width: 2,
color: 'auto',
},
length: 10,
distance: 10,
},
axisLabel: false,
detail: {
fontSize: '16',
formatter: '{value}℃',
color: 'auto',
offsetCenter: ['0', '0%'],
},
pointer: {
icon: 'triangle',
show: true,
offsetCenter: [0, '-70%'],
itemStyle: {
color: 'auto',
},
length: '10%',
width: '3%',
},
data: [
{
value: this.details.temperature,
name: '温度',
title: {
show: true,
color: '#606266',
offsetCenter: [0, '70%'],
fontSize: 18,
}
},
],
}
]
})
usedmemory2.setOption({
series: [
{
type: 'gauge',
center: ['50%', '60%'],
radius: '90%',
min: chartData.min,
max: chartData.max,
startAngle: 220,
endAngle: -40,
splitNumber: 8,
axisLine: {
lineStyle: {
color: [
[0.25, '#f03b44'],
[0.5, '#fbdd5e'],
[0.75, '#58d9f9'],
[1, '#7afeaf'],
],
width: 10,
},
},
splitLine: {
// 线
show: true,
length: 15,
distance: 10,
lineStyle: {
width: 2,
color: 'auto',
},
},
axisTick: {
// 线线
show: true,
lineStyle: {
width: 2,
color: 'auto',
},
length: 10,
distance: 10,
},
axisLabel: false,
detail: {
fontSize: '16',
formatter: '{value}',
color: 'auto',
offsetCenter: ['0', '0%'],
},
pointer: {
icon: 'triangle',
show: true,
offsetCenter: [0, '-70%'],
itemStyle: {
color: 'auto',
},
length: '10%',
width: '3%',
},
data: [
{
value: this.details.health == 1 ? '100' : this.details.health == 2 ? '75': this.details.health == 3 ? '50': this.details.health == 4 ? '25' : '0',
name: '健康度',
title: {
show: true,
color: '#606266',
offsetCenter: [0, '70%'],
fontSize: 18,
}
},
],
}
]
})
usedmemory3.setOption({
title: [
{
text: 'CPU占用',
left: '45%',
top: '55%',
textAlign: 'center',
textStyle: {
fontSize: '14',
fontWeight: '400',
color: '#6AA0E4',
textAlign: 'center',
textShadowColor: '#000',
},
},
],
series: {
type: 'pie',
radius: ['90%', "100%"],
hoverAnimation: false,
data: [
{
value: this.details.cpuUtilization,
label: {
normal: {
color: '#6AA0E4',
fontSize: 22,
fontWeight: 'bold',
formatter: function(params) {
return params.value + '%';
},
position: 'center',
show: true,
}
},
itemStyle: {
normal: {
color: '#6AA0E4'
}
}
},{
value: 100-this.details.cpuUtilization,
name: '',
labelLine: {
show: false
},
itemStyle: {
normal: {
color: '#D8D8D8'
},
emphasis:{
color:'#D8D8D8'
}
}
}]
}
})
usedmemory4.setOption({
title: [
{
text: '内存使用率',
left: '45%',
top: '55%',
textAlign: 'center',
textStyle: {
fontSize: '14',
fontWeight: '400',
color: '#6AA0E4',
textAlign: 'center',
textShadowColor: '#000',
},
},
],
series: {
type: 'pie',
radius: ['90%', "100%"],
hoverAnimation: false,
data: [
{
value: this.details.memoryUtilization,
label: {
normal: {
color: '#6AA0E4',
fontSize: 22,
fontWeight: 'bold',
formatter: function(params) {
return params.value + '%';
},
position: 'center',
show: true,
}
},
itemStyle: {
normal: {
color: '#6AA0E4'
}
}
},{
value: 100-this.details.memoryUtilization,
name: '',
labelLine: {
show: false
},
itemStyle: {
normal: {
color: '#D8D8D8'
},
emphasis:{
color:'#D8D8D8'
}
}
}]
}
})
usedmemory5.setOption({
series: [
{
type: 'pie',
radius: [0, '100%'],
center: ['50%', '50%'],
label: {
position: 'inside',
formatter: '{b}\n{c}',
color: '#30465D'
},
labelLine: {
length: 5,
length2: 5
},
data: [{
name: '输入',
value: this.details.volIn
},
{
name: '输出',
value: this.details.volOut
}
]
}
]
})
performanceChart.setOption({
tooltip: {
trigger: 'axis'
},
legend: {
data: ['CPU使用率', '内存使用率'],
data: ['设备温度'],
textStyle: {
color: '#718096'
}
@ -253,7 +609,7 @@ mounted() {
xAxis: {
type: 'category',
boundaryGap: false,
data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00', '24:00'],
data: [...details.temperatureList],
axisLine: {
lineStyle: {
color: '#cbd5e0'
@ -280,17 +636,25 @@ mounted() {
}
}
},
dataZoom: [
{
type: 'inside', //
xAxisIndex: 0,
start: 0,
end: 50
}
],
series: [
{
name: 'CPU使用率',
name: '设备温度',
type: 'line',
smooth: true,
data: [45, 52, 38, 66, 58, 62, 48],
data: [...details.temperatureList],
lineStyle: {
color: '#ed8936'
color: '#4299e1'
},
itemStyle: {
color: '#ed8936'
color: '#4299e1'
},
areaStyle: {
color: {
@ -300,18 +664,75 @@ mounted() {
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(237, 137, 54, 0.3)'
offset: 0, color: 'rgba(66, 153, 225, 0.3)'
}, {
offset: 1, color: 'rgba(237, 137, 54, 0.1)'
offset: 1, color: 'rgba(66, 153, 225, 0.1)'
}]
}
}
}
]
});
performanceChart4.setOption({
tooltip: {
trigger: 'axis'
},
legend: {
data: ['健康度'],
textStyle: {
color: '#718096'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: [...details.timeList],
axisLine: {
lineStyle: {
color: '#cbd5e0'
}
},
axisLabel: {
color: '#718096'
}
},
yAxis: {
type: 'value',
axisLine: {
lineStyle: {
color: '#cbd5e0'
}
},
axisLabel: {
color: '#718096',
formatter: '{value}%'
},
splitLine: {
lineStyle: {
color: 'rgba(203, 213, 224, 0.6)'
}
}
},
dataZoom: [
{
name: '内存使用率',
type: 'inside', //
xAxisIndex: 0,
start: 0,
end: 50
}
],
series: [
{
name: '健康度',
type: 'line',
smooth: true,
data: [30, 45, 35, 50, 42, 38, 32],
data: [...details.healthList],
lineStyle: {
color: '#4299e1'
},
@ -335,19 +756,12 @@ mounted() {
}
]
});
//
const trafficChart = echarts.init(document.getElementById('trafficChart'));
trafficChart.setOption({
performanceChart3.setOption({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
trigger: 'axis'
},
legend: {
data: ['入站流量', '出站流量'],
data: ['CPU使用率'],
textStyle: {
color: '#718096'
}
@ -360,7 +774,8 @@ mounted() {
},
xAxis: {
type: 'category',
data: ['周一', '周二', '周三', '周四', '周五', '周六', '周日'],
boundaryGap: false,
data: [...details.timeList],
axisLine: {
lineStyle: {
color: '#cbd5e0'
@ -372,14 +787,14 @@ mounted() {
},
yAxis: {
type: 'value',
name: 'MB/s',
axisLine: {
lineStyle: {
color: '#cbd5e0'
}
},
axisLabel: {
color: '#718096'
color: '#718096',
formatter: '{value}%'
},
splitLine: {
lineStyle: {
@ -387,30 +802,135 @@ mounted() {
}
}
},
dataZoom: [
{
type: 'inside', //
xAxisIndex: 0,
start: 0,
end: 50
}
],
series: [
{
name: '入站流量',
type: 'bar',
data: [320, 332, 301, 334, 390, 330, 320],
name: 'CPU使用率',
type: 'line',
smooth: true,
data: [...details.cpuList],
lineStyle: {
color: '#4299e1'
},
itemStyle: {
color: '#4299e1'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(66, 153, 225, 0.3)'
}, {
offset: 1, color: 'rgba(66, 153, 225, 0.1)'
}]
}
}
}
]
});
performanceChart2.setOption({
tooltip: {
trigger: 'axis'
},
legend: {
data: ['内存使用率'],
textStyle: {
color: '#718096'
}
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: {
type: 'category',
boundaryGap: false,
data: [...details.timeList],
axisLine: {
lineStyle: {
color: '#cbd5e0'
}
},
axisLabel: {
color: '#718096'
}
},
yAxis: {
type: 'value',
axisLine: {
lineStyle: {
color: '#cbd5e0'
}
},
axisLabel: {
color: '#718096',
formatter: '{value}%'
},
splitLine: {
lineStyle: {
color: 'rgba(203, 213, 224, 0.6)'
}
}
},
dataZoom: [
{
name: '出站流量',
type: 'bar',
data: [220, 182, 191, 234, 290, 330, 310],
type: 'inside', //
xAxisIndex: 0,
start: 0,
end: 50
}
],
series: [
{
name: '内存使用率',
type: 'line',
smooth: true,
data: [...details.memoryList],
lineStyle: {
color: '#4299e1'
},
itemStyle: {
color: '#ed8936'
color: '#4299e1'
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 0, color: 'rgba(66, 153, 225, 0.3)'
}, {
offset: 1, color: 'rgba(66, 153, 225, 0.1)'
}]
}
}
}
]
});
//
window.addEventListener('resize', function() {
performanceChart.resize();
trafficChart.resize();
performanceChart2.resize();
performanceChart3.resize();
performanceChart4.resize();
usedmemory.resize();
usedmemory2.resize();
// trafficChart.resize();
});
},
/** 查询设备列表 */
@ -430,12 +950,18 @@ mounted() {
...this.historyQueryList
}
historyQuery(queryForm).then(response => {
this.details = response.data
this.loading = false
this.historyQueryData = response.data
console.log("%c 🇸🇸: gethistoryQuery -> this.historyQueryData ", "font-size:16px;background-color:#bc384b;color:white;", this.historyQueryData)
this.loading = false
this.initCharts();
}
)
},
handleDateChange(date) {
this.historyQueryList.minTime = date[0]
this.historyQueryList.maxTime = date[1]
this.gethistoryQuery(this.$route.params.id)
}
}
}
</script>
@ -446,7 +972,7 @@ mounted() {
color: #2d3748;
line-height: 1.6;
padding: 20px;
min-height: 100vh;
min-height: 60vh;
}
.dashboard {
@ -585,11 +1111,23 @@ mounted() {
color: #4299e1;
opacity: 0.8;
}
.device-icon{
width: 100%;
}
.device-info {
display: flex;
flex-direction:column;
gap: 15px;
background: linear-gradient(135deg, #edf2f7, #e2e8f0);
border-radius: 12px;
border: 1px solid rgba(226, 232, 240, 0.8);
transition: all 0.3s ease;
}
.device-info:hover {
background: rgba(255, 255, 255, 0.9);
border-color: rgba(66, 153, 225, 0.3);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
.info-title {
@ -597,24 +1135,16 @@ mounted() {
font-size: 16px;
font-weight: 600;
text-align: center;
padding-top: 10px;
}
.info-item {
display: flex;
flex-direction: column;
padding: 8px 12px;
background: rgba(255, 255, 255, 0.7);
border-radius: 12px;
border: 1px solid rgba(226, 232, 240, 0.8);
transition: all 0.3s ease;
}
.info-item:hover {
background: rgba(255, 255, 255, 0.9);
border-color: rgba(66, 153, 225, 0.3);
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
}
.info-label {
font-size: 13px;
@ -638,7 +1168,7 @@ mounted() {
.chart-container {
width: 100%;
height: 300px;
height: 200px;
margin-top: 10px;
}

@ -1,39 +1,48 @@
<template>
<div class="">
<el-row :gutter="20">
<el-col>
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
<el-table-column
label="序号"
width="60"
type="index"
></el-table-column>
<el-table-column label="预警时间" align="center" key="id" prop="id"/>
<el-table-column label="预警等级" align="center" key="name" prop="name" :show-overflow-tooltip="true" />
<el-table-column label="预警信息" align="center" key="description" prop="description" :show-overflow-tooltip="true" />
<el-table-column label="预警状态" align="center" key="createBy" prop="createBy" :show-overflow-tooltip="true" />
<el-table-column label="处理人" align="center" key="createBy" prop="createBy" :show-overflow-tooltip="true" />
</el-table>
<el-col>
<el-table v-loading="loading" :data="userList">
<el-table-column
label="序号"
width="60"
type="index"
></el-table-column>
<el-table-column label="预警时间" align="center" key="occurTime" prop="occurTime"/>
<el-table-column label="预警等级" align="center" key="level" prop="level" :show-overflow-tooltip="true" />
<el-table-column label="预警信息" align="center" key="message" prop="message" :show-overflow-tooltip="true" />
<el-table-column label="预警状态" align="center" key="status" prop="status" :show-overflow-tooltip="true">
<template slot-scope="scope">
<el-tag v-if="scope.row.status === 'HANDLED'" type="success">已处理</el-tag>
<el-tag v-else type="danger">未处理</el-tag>
</template>
</el-table-column>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
</el-col>
<el-table-column label="处理人" align="center" key="handler" prop="handler" :show-overflow-tooltip="true" >
<template slot-scope="scope">
<span >{{ scope.row.handler || '--' }}</span>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
import { list, del, add, update } from "@/api/device/deviceType"
import { getToken } from "@/utils/auth"
import Treeselect from "@riophae/vue-treeselect"
import { alertmessage } from "@/api/inMonitoring/devicesState"
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
import { Splitpanes, Pane } from "splitpanes"
import { template } from "lodash";
import "splitpanes/dist/splitpanes.css"
export default {
name: "User",
dicts: ['sys_normal_disable', 'sys_user_sex'],
components: { Treeselect, Splitpanes, Pane },
props: {
dsId: {
type: String,
default: 'chart'
}
},
data() {
return {
//
@ -51,18 +60,28 @@ export default {
}
},
created() {
this.getList()
},
watch: {
dsId: {
handler(val) {
this.getList(val)
},
deep: true,
immediate: true
}
},
methods: {
/** 查询类型列表 */
getList() {
getList(id) {
this.loading = true
list(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
try {
alertmessage(id).then(response => {
this.userList = response.rows
this.total = response.total
this.loading = false
}
)
})
} catch (error) {
this.loading = false
}
}
}
}

@ -44,7 +44,7 @@
</el-row>
</div>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize" @pagination="getList" />
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :page-size="queryParams.pageSize" :limit.sync="queryParams.pageSize" @pagination="getList" />
</el-col>
</pane>
</splitpanes>
@ -146,7 +146,7 @@
</template>
<script>
import { list, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus } from "@/api/inMonitoring/devicesState"
import { monitorpageList, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus } from "@/api/inMonitoring/devicesState"
import { getToken } from "@/utils/auth"
import Treeselect from "@riophae/vue-treeselect"
import cardItem from "./cardItem.vue"
@ -216,7 +216,7 @@ export default {
//
queryParams: {
pageNum: 1,
pageSize: 10,
pageSize: 9,
userName: undefined,
phonenumber: undefined,
status: undefined,
@ -277,7 +277,7 @@ export default {
/** 查询设备列表 */
getList() {
this.loading = true
list(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
monitorpageList(this.addDateRange(this.queryParams, this.dateRange)).then(response => {
this.userList = response.rows
this.total = response.total
this.loading = false

@ -0,0 +1,79 @@
<template>
<div class="">
<el-row :gutter="20">
<el-col>
<el-table v-loading="loading" :data="userList">
<el-table-column
label="序号"
width="60"
type="index"
></el-table-column>
<el-table-column label="采集时间" align="center" prop="gatherTime" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.gatherTime) }}</span>
</template>
</el-table-column>
<el-table-column label="接口ID" align="center" key="id" prop="id" :show-overflow-tooltip="true" />
<el-table-column label="双工模式" align="center" key="commuicateMode" prop="commuicateMode" :show-overflow-tooltip="true" />
<el-table-column label="入方向流量" align="center" key="inFlow" prop="inFlow" :show-overflow-tooltip="true" />
<el-table-column label="出方向流量" align="center" key="outFlow" prop="outFlow" :show-overflow-tooltip="true" />
<el-table-column label="宽带占用率" align="center" key="outBandwidth" prop="outBandwidth" :show-overflow-tooltip="true" />
<el-table-column label="丢包率" align="center" key="lossRate" prop="lossRate" :show-overflow-tooltip="true" />
<el-table-column label="错包率" align="center" key="errorRate" prop="errorRate" :show-overflow-tooltip="true" />
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
import { systemInterface } from "@/api/inMonitoring/devicesState"
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
import "splitpanes/dist/splitpanes.css"
export default {
props: {
dsId: {
type: String,
default: 'chart'
}
},
data() {
return {
//
loading: true,
//
total: 0,
//
userList: null,
//
queryParams: {
pageNum: 1,
pageSize: 10,
name: undefined
},
}
},
created() {
},
watch: {
dsId: {
handler(val) {
this.getList(val)
},
deep: true,
immediate: true
}
},
methods: {
/** 查询类型列表 */
getList(id) {
this.loading = true
systemInterface(id).then(response => {
this.userList = response.rows
this.loading = false
})
}
}
}
</script>

@ -0,0 +1,71 @@
<template>
<div class="">
<el-row :gutter="20">
<el-col>
<el-table v-loading="loading" :data="userList">
<el-table-column
label="序号"
width="60"
type="index"
></el-table-column>
<el-table-column label="目的地址" align="center" key="desAddress" prop="desAddress" :show-overflow-tooltip="true" />
<el-table-column label="子网掩码" align="center" key="subnetMask" prop="subnetMask" :show-overflow-tooltip="true" />
<el-table-column label="下一跳地址" align="center" key="nextHop" prop="nextHop" :show-overflow-tooltip="true" />
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
import { systemRouting } from "@/api/inMonitoring/devicesState"
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
import "splitpanes/dist/splitpanes.css"
export default {
props: {
dsId: {
type: String,
default: 'chart'
}
},
data() {
return {
//
loading: true,
//
total: 0,
//
userList: null,
//
queryParams: {
pageNum: 1,
pageSize: 10,
name: undefined
},
}
},
created() {
},
watch: {
dsId: {
handler(val) {
this.getList(val)
},
deep: true,
immediate: true
}
},
methods: {
/** 查询类型列表 */
getList(id) {
this.loading = true
systemRouting(id).then(response => {
this.userList = response.rows
this.loading = false
}
)
},
}
}
</script>

@ -0,0 +1,70 @@
<template>
<div class="">
<el-row :gutter="20">
<el-col>
<el-table v-loading="loading" :data="userList">
<el-table-column
label="序号"
width="60"
type="index"
></el-table-column>
<el-table-column label="ManID" align="center" key="mainId" prop="mainId" :show-overflow-tooltip="true" />
<el-table-column label="IP地址" align="center" key="ipAddress" prop="ipAddress" :show-overflow-tooltip="true" />
<el-table-column label="子网掩码" align="center" key="subnetMask" prop="subnetMask" :show-overflow-tooltip="true" />
</el-table>
</el-col>
</el-row>
</div>
</template>
<script>
import { deviceVlan } from "@/api/inMonitoring/devicesState"
import "@riophae/vue-treeselect/dist/vue-treeselect.css"
import "splitpanes/dist/splitpanes.css"
export default {
props: {
dsId: {
type: String,
default: 'chart'
}
},
data() {
return {
//
loading: true,
//
total: 0,
//
userList: null,
//
queryParams: {
pageNum: 1,
pageSize: 10,
name: undefined
},
}
},
created() {
},
watch: {
dsId: {
handler(val) {
this.getList(val)
},
deep: true,
immediate: true
}
},
methods: {
/** 查询类型列表 */
getList(id) {
this.loading = true
deviceVlan(id).then(response => {
this.userList = response.rows
this.loading = false
})
}
}
}
</script>

@ -35,7 +35,12 @@
></el-table-column>
<el-table-column label="名称" align="center" key="ruleName" prop="ruleName" width="120"/>
<el-table-column label="描述" align="center" key="description" prop="description" width="240" :show-overflow-tooltip="true" />
<el-table-column label="触发条件" align="center" key="alertTemplate" prop="alertTemplate" width="240" :show-overflow-tooltip="true" />
<el-table-column label="触发条件" align="center" key="alertTemplate" prop="alertTemplate" width="240" :show-overflow-tooltip="true" >
<template slot-scope="scope">
<span v-if="scope.row.paramName">{{ findParamName(scope.row.tableName) }} {{ scope.row.operator }} {{ scope.row.compareValue }}</span>
<span v-else></span>
</template>
</el-table-column>
<el-table-column label="预警级别" align="center" key="severity" prop="severity" width="120" />
<el-table-column label="预警方式" align="center" key="alertWay" prop="alertWay" width="120" :show-overflow-tooltip="true" />
<el-table-column label="预警邮箱" align="center" key="alertStation" prop="alertStation" width="200" :show-overflow-tooltip="true" />
@ -288,6 +293,9 @@ export default {
},
methods: {
findParamName(tableName) {
return this.byTableData.find(item => item.tableName == tableName).paramName
},
/** 查询设备列表 */
getList() {
this.loading = true

Loading…
Cancel
Save