From 406a4a91d217b25fbb7af98c1e41eb7e53714e94 Mon Sep 17 00:00:00 2001 From: xt12321 <1499410095@qq.com> Date: Sat, 27 Mar 2021 20:05:43 +0800 Subject: [PATCH 01/21] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=98=E5=8C=96(?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86)=EF=BC=9A=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E5=85=B3=E8=81=94=E8=A7=92=E8=89=B2=E5=88=97=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/vadmin/permission/user/index.vue | 718 +++++++++--------- 1 file changed, 376 insertions(+), 342 deletions(-) diff --git a/dvadmin-ui/src/views/vadmin/permission/user/index.vue b/dvadmin-ui/src/views/vadmin/permission/user/index.vue index 1991185..5c0797e 100755 --- a/dvadmin-ui/src/views/vadmin/permission/user/index.vue +++ b/dvadmin-ui/src/views/vadmin/permission/user/index.vue @@ -91,7 +91,8 @@ size="mini" @click="handleAdd" v-hasPermi="['permission:user:post']" - >新增 + >新增 + 修改 + >修改 + 删除 + >删除 + 导入 + >导入 + 导出 + >导出 + - - - - - - - + + + + + + + + + + - + @@ -173,7 +200,8 @@ icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['permission:user:{id}:put']" - >修改 + >修改 + 删除 + >删除 + 重置 + >重置 + @@ -209,36 +239,36 @@ - + - + - + - + - + - + @@ -262,7 +292,8 @@ v-for="dict in statusOptions" :key="dict.dictValue" :label="dict.dictValue" - >{{dict.dictLabel}} + >{{dict.dictLabel}} + @@ -329,7 +360,8 @@ 点击上传
- 是否更新已经存在的用户数据 + + 是否更新已经存在的用户数据 下载模板
提示:仅允许导入“xls”或“xlsx”格式文件!
@@ -354,338 +386,340 @@ listUser, resetUserPwd, updateUser - } from "@/api/vadmin/permission/user"; - import {getToken} from "@/utils/auth"; - import {treeselect} from "@/api/vadmin/permission/dept"; - import Treeselect from "@riophae/vue-treeselect"; - import "@riophae/vue-treeselect/dist/vue-treeselect.css"; + } from '@/api/vadmin/permission/user' + import { getToken } from '@/utils/auth' + import { treeselect } from '@/api/vadmin/permission/dept' + import Treeselect from '@riophae/vue-treeselect' + import '@riophae/vue-treeselect/dist/vue-treeselect.css' export default { - name: "User", - components: { Treeselect }, - data() { - return { - // 遮罩层 - loading: true, - // 选中数组 - ids: [], - // 非单个禁用 - single: true, - // 非多个禁用 - multiple: true, - // 显示搜索条件 - showSearch: true, - // 总条数 - total: 0, - // 用户表格数据 - userList: null, - // 弹出层标题 - title: "", - // 部门树选项 - deptOptions: undefined, - // 是否显示弹出层 - open: false, - // 部门名称 - deptName: undefined, - // 默认密码 - initPassword: undefined, - // 日期范围 - dateRange: [], - // 状态数据字典 - statusOptions: [{dictLabel: '正常', dictValue: true,}, {dictLabel: '停用', dictValue: false,}], - // 性别状态字典 - sexOptions: [], - // 岗位选项 - postOptions: [], - // 角色选项 - roleOptions: [], - // 表单参数 - form: {}, - defaultProps: { - children: "children", - label: "label" - }, - // 用户导入参数 - upload: { - // 是否显示弹出层(用户导入) + name: 'User', + components: { Treeselect }, + data() { + return { + // 遮罩层 + loading: true, + // 选中数组 + ids: [], + // 非单个禁用 + single: true, + // 非多个禁用 + multiple: true, + // 显示搜索条件 + showSearch: true, + // 总条数 + total: 0, + // 用户表格数据 + userList: null, + // 弹出层标题 + title: '', + // 部门树选项 + deptOptions: undefined, + // 是否显示弹出层 open: false, - // 弹出层标题(用户导入) - title: "", - // 是否禁用上传 - isUploading: false, - // 是否更新已经存在的用户数据 - updateSupport: 0, - // 设置上传的请求头部 - headers: { Authorization: "Bearer " + getToken() }, - // 上传的地址 - url: process.env.VUE_APP_BASE_API + "/admin/system/savefile/" - }, - // 查询参数 - queryParams: { - pageNum: 1, - pageSize: 10, - username: undefined, - mobile: undefined, - is_active: undefined, - deptId: undefined - }, - // 列信息 - columns: [ - { key: 0, label: `用户编号`, visible: true }, - { key: 1, label: `用户名称`, visible: true }, - { key: 2, label: `用户昵称`, visible: true }, - { key: 3, label: `部门`, visible: true }, - { key: 4, label: `手机号码`, visible: true }, - { key: 5, label: `状态`, visible: true }, - { key: 6, label: `创建时间`, visible: true } - ], - // 表单校验 - rules: { - username: [ - { required: true, message: "用户名称不能为空", trigger: "blur" } + // 部门名称 + deptName: undefined, + // 默认密码 + initPassword: undefined, + // 日期范围 + dateRange: [], + // 状态数据字典 + statusOptions: [{ dictLabel: '正常', dictValue: true }, { dictLabel: '停用', dictValue: false }], + // 性别状态字典 + sexOptions: [], + // 岗位选项 + 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 + '/admin/system/savefile/' + }, + // 查询参数 + queryParams: { + pageNum: 1, + pageSize: 10, + username: undefined, + mobile: undefined, + is_active: undefined, + deptId: undefined + }, + // 列信息 + columns: [ + { key: 0, label: `用户编号`, visible: true }, + { key: 1, label: `用户名称`, visible: true }, + { key: 2, label: `用户昵称`, visible: true }, + { key: 3, label: `部门`, visible: true }, + { key: 4, label: `关联角色`, visible: true }, + { key: 5, label: `手机号码`, visible: true }, + { key: 6, label: `状态`, visible: true }, + { key: 7, label: `创建时间`, visible: true } ], - name: [ - { required: true, message: "用户昵称不能为空", trigger: "blur" } - ], - password: [ - { required: true, message: "用户密码不能为空", trigger: "blur" } - ], - email: [ - { - type: "email", - message: "'请输入正确的邮箱地址", - trigger: ["blur", "change"] - } - ], - mobile: [ - { - pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, - message: "请输入正确的手机号码", - trigger: "blur" - } - ] + // 表单校验 + rules: { + username: [ + { required: true, message: '用户名称不能为空', trigger: 'blur' } + ], + name: [ + { required: true, message: '用户昵称不能为空', trigger: 'blur' } + ], + password: [ + { required: true, message: '用户密码不能为空', trigger: 'blur' } + ], + email: [ + { + type: 'email', + message: '\'请输入正确的邮箱地址', + trigger: ['blur', 'change'] + } + ], + mobile: [ + { + 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(); - this.getTreeselect(); - // this.getDicts("sys_normal_disable").then(response => { - // this.statusOptions = response.data; - // }); - this.getDicts("sys_user_sex").then(response => { - this.sexOptions = response.data; - }); - this.getConfigKey("sys.user.initPassword").then(response => { - this.initPassword = response.msg; - }); - }, - methods: { - /** 查询用户列表 */ - getList() { - this.loading = true; - listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => { - this.userList = response.data.results; - this.total = response.data.count; - this.loading = false; - } - ); }, - /** 查询部门下拉树结构 */ - getTreeselect() { - treeselect().then(response => { - this.deptOptions = this.handleTree(response.data,'id'); - }); + watch: { + // 根据名称筛选部门树 + deptName(val) { + this.$refs.tree.filter(val) + } }, - // 筛选节点 - filterNode(value, data) { - if (!value) return true; - return data.label.indexOf(value) !== -1; + created() { + this.getList() + this.getTreeselect() + // this.getDicts("sys_normal_disable").then(response => { + // this.statusOptions = response.data; + // }); + this.getDicts('sys_user_sex').then(response => { + this.sexOptions = response.data + }) + this.getConfigKey('sys.user.initPassword').then(response => { + this.initPassword = response.msg + }) }, - // 节点单击事件 - handleNodeClick(data) { - this.queryParams.deptId = data.id; - this.getList(); - }, - // 用户状态修改 - handleStatusChange(row) { - let text = row.is_active === true ? "启用" : "停用"; - this.$confirm('确认要"' + text + '""' + row.username + '"用户吗?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" - }).then(function() { - return changeUserStatus(row.id, row.is_active); - }).then(() => { - this.msgSuccess(text + "成功"); - }).catch(function() { - row.is_active = row.is_active === false ? true : false; - }); - }, - // 取消按钮 - cancel() { - this.open = false; - this.reset(); - }, - // 表单重置 - reset() { - this.form = { - id: undefined, - deptId: undefined, - username: undefined, - name: undefined, - password: undefined, - mobile: undefined, - email: undefined, - gender: undefined, - is_active: false, - remark: undefined, - postIds: [], - roleIds: [] - }; - this.resetForm("form"); - }, - /** 搜索按钮操作 */ - handleQuery() { - this.queryParams.page = 1; - this.getList(); - }, - /** 重置按钮操作 */ - resetQuery() { - this.dateRange = []; - this.queryParams.deptId = '' - this.resetForm("queryForm"); - this.handleQuery(); - }, - // 多选框选中数据 - handleSelectionChange(selection) { - this.ids = selection.map(item => item.id); - this.single = selection.length != 1; - this.multiple = !selection.length; - }, - /** 新增按钮操作 */ - handleAdd() { - this.reset(); - this.getTreeselect(); - getUser().then(response => { - this.postOptions = response.data.posts; - this.roleOptions = response.data.roles; - this.open = true; - this.title = "添加用户"; - this.form.password = this.initPassword; - }); - }, - /** 修改按钮操作 */ - handleUpdate(row) { - this.reset(); - this.getTreeselect(); - const id = row.id || this.ids; - getUser(id).then(response => { - let data = response.data.data - data['postIds'] = response.data.postIds - data['roleIds'] = response.data.roleIds - this.form = data; - this.postOptions = response.data.posts; - this.roleOptions = response.data.roles; - this.open = true; - this.title = "修改用户"; - this.form.password = ""; - }); - }, - /** 重置密码按钮操作 */ - handleResetPwd(row) { - this.$prompt('请输入"' + row.username + '"的新密码', "提示", { - confirmButtonText: "确定", - cancelButtonText: "取消" - }).then(({ value }) => { - resetUserPwd(row.id, value).then(response => { - this.msgSuccess("修改成功,新密码是:" + value); - }); - }).catch(() => {}); - }, - /** 提交按钮 */ - submitForm: function() { - this.$refs["form"].validate(valid => { - if (valid) { - if (this.form.id != undefined) { - updateUser(this.form).then(response => { - this.msgSuccess("修改成功"); - this.open = false; - this.getList(); - }); - } else { - addUser(this.form).then(response => { - this.msgSuccess("新增成功"); - this.open = false; - this.getList(); - }); + methods: { + /** 查询用户列表 */ + getList() { + this.loading = true + listUser(this.addDateRange(this.queryParams, this.dateRange)).then(response => { + this.userList = response.data.results + this.total = response.data.count + this.loading = false } - } - }); - }, - /** 删除按钮操作 */ - handleDelete(row) { - const userIds = row.id || this.ids; - this.$confirm('是否确认删除用户编号为"' + userIds + '"的数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" + ) + }, + /** 查询部门下拉树结构 */ + getTreeselect() { + treeselect().then(response => { + this.deptOptions = this.handleTree(response.data, 'id') + }) + }, + // 筛选节点 + filterNode(value, data) { + if (!value) return true + return data.label.indexOf(value) !== -1 + }, + // 节点单击事件 + handleNodeClick(data) { + this.queryParams.deptId = data.id + this.getList() + }, + // 用户状态修改 + handleStatusChange(row) { + let text = row.is_active === true ? '启用' : '停用' + this.$confirm('确认要"' + text + '""' + row.username + '"用户吗?', '警告', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' }).then(function() { - return delUser(userIds); + return changeUserStatus(row.id, row.is_active) }).then(() => { - this.getList(); - this.msgSuccess("删除成功"); + this.msgSuccess(text + '成功') + }).catch(function() { + row.is_active = row.is_active === false ? true : false }) - }, - /** 导出按钮操作 */ - handleExport() { - const queryParams = this.queryParams; - this.$confirm('是否确认导出所有用户数据项?', "警告", { - confirmButtonText: "确定", - cancelButtonText: "取消", - type: "warning" + }, + // 取消按钮 + cancel() { + this.open = false + this.reset() + }, + // 表单重置 + reset() { + this.form = { + id: undefined, + deptId: undefined, + username: undefined, + name: undefined, + password: undefined, + mobile: undefined, + email: undefined, + gender: undefined, + is_active: false, + remark: undefined, + postIds: [], + roleIds: [] + } + this.resetForm('form') + }, + /** 搜索按钮操作 */ + handleQuery() { + this.queryParams.page = 1 + this.getList() + }, + /** 重置按钮操作 */ + resetQuery() { + this.dateRange = [] + this.queryParams.deptId = '' + this.resetForm('queryForm') + this.handleQuery() + }, + // 多选框选中数据 + handleSelectionChange(selection) { + this.ids = selection.map(item => item.id) + this.single = selection.length != 1 + this.multiple = !selection.length + }, + /** 新增按钮操作 */ + handleAdd() { + this.reset() + this.getTreeselect() + getUser().then(response => { + this.postOptions = response.data.posts + this.roleOptions = response.data.roles + this.open = true + this.title = '添加用户' + this.form.password = this.initPassword + }) + }, + /** 修改按钮操作 */ + handleUpdate(row) { + this.reset() + this.getTreeselect() + const id = row.id || this.ids + getUser(id).then(response => { + let data = response.data.data + data['postIds'] = response.data.postIds + data['roleIds'] = response.data.roleIds + this.form = data + this.postOptions = response.data.posts + this.roleOptions = response.data.roles + this.open = true + this.title = '修改用户' + this.form.password = '' + }) + }, + /** 重置密码按钮操作 */ + handleResetPwd(row) { + this.$prompt('请输入"' + row.username + '"的新密码', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消' + }).then(({ value }) => { + resetUserPwd(row.id, value).then(response => { + this.msgSuccess('修改成功,新密码是:' + value) + }) + }).catch(() => { + }) + }, + /** 提交按钮 */ + submitForm: function() { + this.$refs['form'].validate(valid => { + if (valid) { + if (this.form.id != undefined) { + updateUser(this.form).then(response => { + this.msgSuccess('修改成功') + this.open = false + this.getList() + }) + } else { + addUser(this.form).then(response => { + this.msgSuccess('新增成功') + this.open = false + this.getList() + }) + } + } + }) + }, + /** 删除按钮操作 */ + handleDelete(row) { + const userIds = row.id || this.ids + this.$confirm('是否确认删除用户编号为"' + userIds + '"的数据项?', '警告', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' }).then(function() { - return exportUser(queryParams); - }).then(response => { - this.download(response.data.file_url,response.data.name); + return delUser(userIds) + }).then(() => { + this.getList() + this.msgSuccess('删除成功') }) - }, - /** 导入按钮操作 */ - handleImport() { - this.upload.title = "用户导入"; - this.upload.open = true; - }, - /** 下载模板操作 */ - importTemplate() { - importTemplate().then(response => { - this.download(response.data.file_url,response.data.name); - }); - }, - // 文件上传中处理 - handleFileUploadProgress(event, file, fileList) { - this.upload.isUploading = true; - }, - // 文件上传成功处理 - handleFileSuccess(response, file, fileList) { - this.upload.open = false; - this.upload.isUploading = false; - this.$refs.upload.clearFiles(); - // 是否更新已经存在的用户数据 - importsUser({file_url: response.data.file_url,updateSupport:this.upload.updateSupport}).then(response => { - this.$alert('导入成功!', "导入结果", { dangerouslyUseHTMLString: true }); - this.getList(); - }); - }, - // 提交上传文件 - submitFileForm() { - this.$refs.upload.submit(); + }, + /** 导出按钮操作 */ + handleExport() { + const queryParams = this.queryParams + this.$confirm('是否确认导出所有用户数据项?', '警告', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(function() { + return exportUser(queryParams) + }).then(response => { + this.download(response.data.file_url, response.data.name) + }) + }, + /** 导入按钮操作 */ + handleImport() { + this.upload.title = '用户导入' + this.upload.open = true + }, + /** 下载模板操作 */ + importTemplate() { + importTemplate().then(response => { + this.download(response.data.file_url, response.data.name) + }) + }, + // 文件上传中处理 + handleFileUploadProgress(event, file, fileList) { + this.upload.isUploading = true + }, + // 文件上传成功处理 + handleFileSuccess(response, file, fileList) { + this.upload.open = false + this.upload.isUploading = false + this.$refs.upload.clearFiles() + // 是否更新已经存在的用户数据 + importsUser({ file_url: response.data.file_url, updateSupport: this.upload.updateSupport }).then(response => { + this.$alert('导入成功!', '导入结果', { dangerouslyUseHTMLString: true }) + this.getList() + }) + }, + // 提交上传文件 + submitFileForm() { + this.$refs.upload.submit() + } } } -}; From a64225e20f4bacdf6638ceb2ec4f8aca2225addf Mon Sep 17 00:00:00 2001 From: qianzhengkai <18352261659@163.com> Date: Tue, 30 Mar 2021 20:30:06 +0800 Subject: [PATCH 02/21] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E8=8E=B7=E5=8F=96?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8cpu=E3=80=81=E5=86=85=E5=AD=98?= =?UTF-8?q?=E3=80=81=E7=A1=AC=E7=9B=98=E7=9A=84=E4=BD=BF=E7=94=A8=E7=8E=87?= =?UTF-8?q?=E8=A7=86=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvadmin-backend/application/__init__.py | 2 ++ dvadmin-backend/apps/vadmin/system/urls.py | 5 ++-- dvadmin-backend/apps/vadmin/system/views.py | 20 +++++++++++++++ .../vadmin}/utils/system_info_utils.py | 25 ++++++++++++++++--- 4 files changed, 47 insertions(+), 5 deletions(-) rename dvadmin-backend/{ => apps/vadmin}/utils/system_info_utils.py (69%) diff --git a/dvadmin-backend/application/__init__.py b/dvadmin-backend/application/__init__.py index 8b13789..2ea4edd 100644 --- a/dvadmin-backend/application/__init__.py +++ b/dvadmin-backend/application/__init__.py @@ -1 +1,3 @@ +import pymysql +pymysql.install_as_MySQLdb() diff --git a/dvadmin-backend/apps/vadmin/system/urls.py b/dvadmin-backend/apps/vadmin/system/urls.py index 7084014..654bac5 100644 --- a/dvadmin-backend/apps/vadmin/system/urls.py +++ b/dvadmin-backend/apps/vadmin/system/urls.py @@ -3,7 +3,7 @@ from rest_framework.routers import DefaultRouter from ..system.views import DictDataModelViewSet, DictDetailsModelViewSet, \ ConfigSettingsModelViewSet, SaveFileModelViewSet, MessagePushModelViewSet, LoginInforModelViewSet, \ - OperationLogModelViewSet, CeleryLogModelViewSet + OperationLogModelViewSet, CeleryLogModelViewSet, SystemInfoApiView router = DefaultRouter() router.register(r'dict/type', DictDataModelViewSet) @@ -48,6 +48,7 @@ urlpatterns = [ re_path('celery_log/export/', CeleryLogModelViewSet.as_view({'get': 'export', })), # 清除废弃文件 re_path('clearsavefile/', SaveFileModelViewSet.as_view({'post': 'clearsavefile', })), - + # 获取系统信息cpu、内存、硬盘 + re_path('sys/info/', SystemInfoApiView.as_view()) ] urlpatterns += router.urls diff --git a/dvadmin-backend/apps/vadmin/system/views.py b/dvadmin-backend/apps/vadmin/system/views.py index a35338f..05257cc 100644 --- a/dvadmin-backend/apps/vadmin/system/views.py +++ b/dvadmin-backend/apps/vadmin/system/views.py @@ -4,6 +4,7 @@ from django.conf import settings from django.core.cache import cache from django.db.models import Q from rest_framework.request import Request +from rest_framework.views import APIView from .models import LoginInfor, OperationLog, CeleryLog from ..op_drf.filters import DataLevelPermissionsFilter @@ -23,6 +24,7 @@ from ..system.serializers import DictDataSerializer, DictDataCreateUpdateSeriali from ..utils.export_excel import export_excel_save_model from ..utils.file_util import get_all_files, remove_empty_dir, delete_files from ..utils.response import SuccessResponse +from ..utils.system_info_utils import get_memory_used_percent, get_cpu_used_percent, get_disk_used_percent class DictDataModelViewSet(CustomModelViewSet): @@ -328,3 +330,21 @@ class CeleryLogModelViewSet(CustomModelViewSet): """ self.get_queryset().delete() return SuccessResponse(msg="清空成功") + + +class SystemInfoApiView(APIView): + """ + 系统服务监控视图 + """ + + def get(self, request, *args, **kwargs): + # 获取内存使用率 + memory_used_percent = get_memory_used_percent() + # 获取cpu使用率 + cpu_used_percent = get_cpu_used_percent() + # 获取硬盘使用率 + disk_used_percent = get_disk_used_percent() + return SuccessResponse(data={"memory_used_percent": memory_used_percent, + "cpu_used_percent": cpu_used_percent, + "disk_used_percent": disk_used_percent + }) diff --git a/dvadmin-backend/utils/system_info_utils.py b/dvadmin-backend/apps/vadmin/utils/system_info_utils.py similarity index 69% rename from dvadmin-backend/utils/system_info_utils.py rename to dvadmin-backend/apps/vadmin/utils/system_info_utils.py index 69f34c9..88d9895 100644 --- a/dvadmin-backend/utils/system_info_utils.py +++ b/dvadmin-backend/apps/vadmin/utils/system_info_utils.py @@ -4,6 +4,27 @@ import psutil as psutil +def get_cpu_info(): + """ + 获取cpu所有信息 + """ + pass + + +def get_memory_info(): + """ + 获取内存所有信息 + """ + pass + + +def get_disk_info(): + """ + 获取硬盘所有信息 + """ + pass + + def get_cpu_used_percent(): """ 获取CPU运行情况 @@ -31,7 +52,5 @@ def get_disk_used_percent(): pass - - if __name__ == '__main__': - get_cpu_used_percent() + get_disk_used_percent() From b715eff90ddc7602250b62e79c43d11cd0a2cb2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Wed, 31 Mar 2021 13:38:09 +0800 Subject: [PATCH 03/21] update dvadmin-backend/application/__init__.py. --- dvadmin-backend/application/__init__.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/dvadmin-backend/application/__init__.py b/dvadmin-backend/application/__init__.py index 2ea4edd..e69de29 100644 --- a/dvadmin-backend/application/__init__.py +++ b/dvadmin-backend/application/__init__.py @@ -1,3 +0,0 @@ -import pymysql -pymysql.install_as_MySQLdb() - From 9970eed34d1a23f4a85452bc96270a679024cab7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Thu, 1 Apr 2021 00:11:04 +0800 Subject: [PATCH 04/21] =?UTF-8?q?!13=20=E5=8F=91=E5=B8=831.0=E6=AD=A3?= =?UTF-8?q?=E5=BC=8F=E7=89=88=E6=9C=AC=E5=89=8D=E5=90=88=E5=B9=B6=20*=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG(docker=20=E9=83=A8=E7=BD=B2):=20docker-co?= =?UTF-8?q?mpose.yml=20=E6=8F=90=E4=BA=A4=E4=BF=AE=E6=94=B9=20*=20?= =?UTF-8?q?=E6=96=87=E6=A1=A3(=E6=96=87=E6=A1=A3=E6=8F=90=E4=BA=A4):=20REA?= =?UTF-8?q?DME.md=20=E6=96=87=E6=A1=A3=20*=20=E6=96=87=E6=A1=A3(=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E4=BF=AE=E6=94=B9):=20README.md=20=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=20*=20=E4=BF=AE=E5=A4=8DBUG(=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E4=BE=9D=E8=B5=96):=20=E6=B7=BB=E5=8A=A0=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=20psutil=3D=3D5.8.0=20*=20=E4=BF=AE=E5=A4=8DBUG(?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E6=B6=88=E6=81=AF):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E6=B6=88=E6=81=AF=E6=9C=AA=E5=8F=91=E5=B8=83?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E8=BF=87=E6=BB=A4=20*=20Merge=20branch=20'dv?= =?UTF-8?q?admin-liqianglog'=20of=20https://gitee.com/liqianglog/djan?= =?UTF-8?q?=E2=80=A6=20*=20=E4=BF=AE=E5=A4=8DBUG(=E4=B8=AA=E4=BA=BA?= =?UTF-8?q?=E4=BF=A1=E6=81=AF):=20=E4=B8=AA=E4=BA=BA=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E4=B8=AD=E6=9C=AA=E8=AF=BB=E6=B6=88=E6=81=AF=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E6=95=B0=E9=87=8F=E9=94=99=E8=AF=AF=20*=20=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=8F=98=E5=8C=96(=E8=8E=B7=E5=8F=96=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3):=20admin=E7=94=A8=E6=88=B7=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E5=8F=AF=E6=9F=A5=E7=9C=8B=E5=85=A8=E9=83=A8=EF=BC=8C?= =?UTF-8?q?=E4=BE=BF=E4=BA=8E=E5=BC=80=E5=8F=91=20*=20=E4=BF=AE=E5=A4=8DBU?= =?UTF-8?q?G(=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86):=20=E4=B8=AA=E4=BA=BA?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AF=86=E7=A0=81bug=EF=BC=8CUserProfile?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E4=BA=BA=20*=20update=20dvadmin-backend/apps/vadmin/o?= =?UTF-8?q?p=5Fdrf/middleware.py.=20*=20update=20dvadmin-backend/apps/vadm?= =?UTF-8?q?in/op=5Fdrf/middleware.py.=20*=20=E4=BF=AE=E5=A4=8DBUG(?= =?UTF-8?q?=E4=B8=AA=E4=BA=BA=E4=BF=A1=E6=81=AF&=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E5=85=AC=E5=91=8A):=20=E4=B8=AA=E4=BA=BA=E6=9C=AA=E8=AF=BB?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E5=85=AC=E5=91=8A=E6=95=B0=E9=87=8F=E9=94=99?= =?UTF-8?q?=E8=AF=AF=20*=20=E4=BF=AE=E5=A4=8DBUG(=E4=B8=AD=E9=97=B4?= =?UTF-8?q?=E4=BB=B6bug):=20=E6=97=A5=E5=BF=97=E4=B8=AD=E9=97=B4=E4=BB=B6?= =?UTF-8?q?=E5=AD=98=E5=85=A5=E6=A8=A1=E5=9D=97=E4=BF=A1=E6=81=AF=E4=B8=8D?= =?UTF-8?q?=E5=85=A8=20*=20Merge=20remote-tracking=20branch=20'remotes/ori?= =?UTF-8?q?gin/master'=20into=20dvadmin-liqianglog=20*=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8DBUG(=E6=8F=90=E4=BA=A4=E9=94=99=E8=AF=AF):=20DEMO=5FEN?= =?UTF-8?q?V=20*=20Merge=20remote-tracking=20branch=20'remotes/origin/dvad?= =?UTF-8?q?min-liqianglog'=20into=20=E2=80=A6=20*=20=E4=BF=AE=E5=A4=8DBUG(?= =?UTF-8?q?=E4=B8=AD=E9=97=B4=E4=BB=B6bug):=20=E6=97=A5=E5=BF=97=E4=B8=AD?= =?UTF-8?q?=E9=97=B4=E4=BB=B6=E5=AD=98=E5=85=A5=E6=A8=A1=E5=9D=97=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E4=B8=8D=E5=85=A8=20*=20!11=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=A4=9A=E4=B8=AAbug=20*=20=E4=BF=AE=E5=A4=8DBUG(=E4=B8=AD?= =?UTF-8?q?=E9=97=B4=E4=BB=B6bug):=20=E6=97=A5=E5=BF=97=E4=B8=AD=E9=97=B4?= =?UTF-8?q?=E4=BB=B6=E5=AD=98=E5=85=A5=E6=A8=A1=E5=9D=97=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E4=B8=8D=E5=85=A8=20*=20!10=20=E5=90=8E=E7=AB=AF=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=9D=83=E9=99=90=E9=AA=8C=E8=AF=81bug=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=20*=20=E6=B5=8B=E8=AF=95(=E9=83=A8=E7=BD=B2=E6=B5=8B?= =?UTF-8?q?=E8=AF=95):=20*=20=E4=BF=AE=E5=A4=8DBUG(=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0):=20doc=EF=BC=8Cdocx=EF=BC=8Cxlsx=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E9=83=BD=E6=97=A0=E6=B3=95=E4=B8=8A=E4=BC=A0=E6=88=90?= =?UTF-8?q?=E5=8A=9F=20*=20=E4=BF=AE=E5=A4=8DBUG(=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E9=83=A8=E9=97=A8):=20=E9=83=A8=E9=97=A8=E9=87=8C=E9=9D=A2?= =?UTF-8?q?=E5=AD=98=E5=9C=A8=E7=94=A8=E6=88=B7=EF=BC=8C=E4=BE=9D=E7=84=B6?= =?UTF-8?q?=E8=83=BD=E5=A4=9F=E5=88=A0=E9=99=A4=E9=83=A8=E9=97=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 24 +++++++++--- docker-compose.yml | 1 + dvadmin-backend/application/settings.py | 2 +- .../apps/vadmin/op_drf/middleware.py | 37 ++++++++++++------- .../apps/vadmin/permission/models/users.py | 8 ++-- .../apps/vadmin/permission/permissions.py | 20 ++++++++++ .../apps/vadmin/permission/serializers.py | 4 +- .../apps/vadmin/permission/views.py | 11 ++++-- .../permission/permission_userprofile.sql | 4 +- .../apps/vadmin/system/models/save_file.py | 2 +- dvadmin-backend/apps/vadmin/system/views.py | 3 +- .../apps/vadmin/utils/authentication.py | 4 +- .../apps/vadmin/utils/exceptions.py | 2 - dvadmin-backend/requirements.txt | 1 + dvadmin-ui/README.md | 12 +++--- dvadmin-ui/src/layout/components/Navbar.vue | 6 +-- dvadmin-ui/src/store/modules/user.js | 3 +- .../views/vadmin/permission/user/index.vue | 3 +- .../views/vadmin/system/message/Mymessage.vue | 8 ++-- 19 files changed, 103 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index ea9949d..139daa8 100644 --- a/README.md +++ b/README.md @@ -12,26 +12,25 @@ Django-Vue-Admin 是一套全部开源的快速开发平台,毫无保留给个 * 后端采用Python语言Django框架。 * 权限认证使用Jwt,支持多终端认证系统。 * 支持加载动态权限菜单,多方式轻松权限控制。 -* ~~高效率开发,使用代码生成器可以一键生成前后端代码。~~ -* 特别鸣谢:[RuoYi](https://gitee.com/y_project/RuoYi-Vue) ,[Vue-Element-Admin](https://github.com/PanJiaChen/vue-element-admin),[eladmin-web](https://gitee.com/elunez/eladmin-web?_from=gitee_search),[Gin-Vue-Admin](https://www.gin-vue-admin.com/)。 +* 特别鸣谢:[Gin-Vue-Admin](https://www.gin-vue-admin.com/),[RuoYi](https://gitee.com/y_project/RuoYi-Vue) ,[Vue-Element-Admin](https://github.com/PanJiaChen/vue-element-admin),[eladmin-web](https://gitee.com/elunez/eladmin-web?_from=gitee_search)。 ## QQ群 - QQ群号:812482043 -- 由于项目正在启步阶段,第一版预计3月底发,后序会慢慢维护其他版本,有什么不到位的请大家担待~ +- 二维码 ## 源码地址 -gitee地址:[https://gitee.com/liqianglog/django-vue-admin](https://gitee.com/liqianglog/django-vue-admin) +gitee地址(主推):[https://gitee.com/liqianglog/django-vue-admin](https://gitee.com/liqianglog/django-vue-admin) github地址:[https://github.com/liqianglog/django-vue-admin](https://github.com/liqianglog/django-vue-admin) ## 内置功能 -##### 预计3月底发布v1.0正式版本,个别功能开发中 [版本功能说明](https://gitee.com/liqianglog/django-vue-admin/wikis/releaseNote?sort_id=3615540) +##### 后期版本 [版本功能说明](https://gitee.com/liqianglog/django-vue-admin/wikis/releaseNote?sort_id=3615540) 1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 2. 部门管理:配置系统组织机构(公司、部门、小组),树结构展现支持数据权限。 @@ -119,6 +118,21 @@ npm run build:prod 后端接口文档地址:http://127.0.0.1:8000/docs/ ~~~ +### docker-compose 运行 + +~~~shell +# 先安装docker-compose (自行百度安装),执行此命令等待安装 +docker-compose up +# 初始化后端数据(第一次执行即可) +docker exec -ti dvadmin-django bash +python manage.py init -y +exit + +前端地址:http://127.0.0.1:8080 +后端地址:http://127.0.0.1:8000 +账号:admin 密码:123456 +~~~ + ## 演示图 diff --git a/docker-compose.yml b/docker-compose.yml index fb3d0fd..a61dab7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,6 +23,7 @@ services: npm install --registry=https://registry.npm.taobao.org rm -rf /dvadmin-ui/dist npm run build:prod + npm run dev dvadmin-redis: diff --git a/dvadmin-backend/application/settings.py b/dvadmin-backend/application/settings.py index ee3fc5b..4b385f0 100644 --- a/dvadmin-backend/application/settings.py +++ b/dvadmin-backend/application/settings.py @@ -54,7 +54,6 @@ INSTALLED_APPS = [ ] MIDDLEWARE = [ - 'vadmin.op_drf.middleware.PermissionModeMiddleware', # 权限中间件 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', @@ -64,6 +63,7 @@ MIDDLEWARE = [ 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'vadmin.op_drf.middleware.ApiLoggingMiddleware', # 用于记录API访问日志 + 'vadmin.op_drf.middleware.PermissionModeMiddleware', # 权限中间件 ] # 允许跨域源 CORS_ORIGIN_ALLOW_ALL = CORS_ORIGIN_ALLOW_ALL diff --git a/dvadmin-backend/apps/vadmin/op_drf/middleware.py b/dvadmin-backend/apps/vadmin/op_drf/middleware.py index bf28947..0990a07 100644 --- a/dvadmin-backend/apps/vadmin/op_drf/middleware.py +++ b/dvadmin-backend/apps/vadmin/op_drf/middleware.py @@ -1,6 +1,7 @@ """ django中间件 """ +import json import logging import os @@ -11,7 +12,7 @@ from django.utils.deprecation import MiddlewareMixin from apps.vadmin.permission.models import Menu from apps.vadmin.system.models import OperationLog from ..utils.request_util import get_request_ip, get_request_data, get_request_path, get_browser, get_os, \ - get_login_location, get_request_canonical_path, get_request_user + get_login_location, get_request_canonical_path, get_request_user, get_verbose_name from ..utils.response import ErrorJsonResponse logger = logging.getLogger(__name__) @@ -42,9 +43,16 @@ class ApiLoggingMiddleware(MiddlewareMixin): body['password'] = '*' * len(body['password']) if not hasattr(response, 'data') or not isinstance(response.data, dict): response.data = {} + if not response.data and response.content: + try: + content = json.loads(response.content.decode()) + response.data = content if isinstance(content, dict) else {} + except: + pass + user = get_request_user(request) info = { 'request_ip': getattr(request, 'request_ip', 'unknown'), - 'creator': request.user, + 'creator': user if not isinstance(user, AnonymousUser) else None, 'dept_belong_id': getattr(request.user, 'dept_id', None), 'request_method': request.method, 'request_path': request.request_path, @@ -58,11 +66,14 @@ class ApiLoggingMiddleware(MiddlewareMixin): 'json_result': {"code": response.data.get('code'), "msg": response.data.get('msg')}, 'request_modular': request.session.get('model_name'), } - if isinstance(request.user, AnonymousUser): - info['creator'] = None log = OperationLog(**info) log.save() + def process_view(self, request, view_func, view_args, view_kwargs): + if hasattr(view_func, 'cls') and hasattr(view_func.cls, 'queryset'): + request.session['model_name'] = get_verbose_name(view_func.cls.queryset) + return + def process_request(self, request): self.__handle_request(request) @@ -85,14 +96,7 @@ class PermissionModeMiddleware(MiddlewareMixin): """ def process_request(self, request): - """ - 判断环境变量中,是否为演示模式(正常可忽略此判断) - :param request: - :return: - """ - white_list = ['/admin/logout/', '/admin/login/'] - if os.getenv('DEMO_ENV') and not request.method == 'GET' and request.path not in white_list: - return ErrorJsonResponse(data={}, msg=f'演示模式,不允许操作!') + return def has_interface_permission(self, request, method, view_path, user=None): """ @@ -130,18 +134,23 @@ class PermissionModeMiddleware(MiddlewareMixin): if user.is_superuser or (hasattr(user, 'role') and user.role.filter(status='1', admin=True).count()): return 20 # (3)user的角色有该接口权限, 是:通过, 否:不通过 - if view_path in user.get_user_interface_dict: + if view_path in user.get_user_interface_dict.get(method, []): return 30 return -10 def process_view(self, request, view_func, view_args, view_kwargs): + # 判断环境变量中,是否为演示模式(正常可忽略此判断) + white_list = ['/admin/logout/', '/admin/login/'] + if os.getenv('DEMO_ENV') and not request.method in ['GET', 'OPTIONS'] and request.path not in white_list: + return ErrorJsonResponse(data={}, msg=f'演示模式,不允许操作!') + if not settings.INTERFACE_PERMISSION: return user = get_request_user(request) if user and not isinstance(user, AnonymousUser): method = request.method.upper() - if method == 'GET': # GET 不设置接口权限 + if method == 'GET': # GET 不设置接口权限 return view_path = get_request_canonical_path(request, *view_args, **view_kwargs) auth_code = self.has_interface_permission(request, method, view_path, user) diff --git a/dvadmin-backend/apps/vadmin/permission/models/users.py b/dvadmin-backend/apps/vadmin/permission/models/users.py index 2fead2f..e609a2a 100644 --- a/dvadmin-backend/apps/vadmin/permission/models/users.py +++ b/dvadmin-backend/apps/vadmin/permission/models/users.py @@ -4,10 +4,10 @@ from django.contrib.auth.models import UserManager, AbstractUser from django.core.cache import cache from django.db.models import IntegerField, ForeignKey, CharField, TextField, ManyToManyField, CASCADE -from ...op_drf.fields import CreateDateTimeField, UpdateDateTimeField +from ...op_drf.models import CoreModel -class UserProfile(AbstractUser): +class UserProfile(AbstractUser, CoreModel): USER_TYPE_CHOICES = ( (0, "后台用户"), (1, "前台用户"), @@ -25,9 +25,6 @@ class UserProfile(AbstractUser): post = ManyToManyField(to='Post', verbose_name='关联岗位', db_constraint=False) role = ManyToManyField(to='Role', verbose_name='关联角色', db_constraint=False) dept = ForeignKey(to='Dept', verbose_name='归属部门', on_delete=CASCADE, db_constraint=False, null=True, blank=True) - dept_belong_id = CharField(max_length=64, verbose_name="数据归属部门", null=True, blank=True) - create_datetime = CreateDateTimeField() - update_datetime = UpdateDateTimeField() @property def get_user_interface_dict(self): @@ -52,6 +49,7 @@ class UserProfile(AbstractUser): :return: """ return cache.delete(f'permission_interface_dict_{self.username}') + class Meta: verbose_name = '用户管理' verbose_name_plural = verbose_name diff --git a/dvadmin-backend/apps/vadmin/permission/permissions.py b/dvadmin-backend/apps/vadmin/permission/permissions.py index 0186adb..3c09387 100644 --- a/dvadmin-backend/apps/vadmin/permission/permissions.py +++ b/dvadmin-backend/apps/vadmin/permission/permissions.py @@ -93,3 +93,23 @@ class CommonPermission(CustomPermission): self.message = f"没有此数据操作权限!" res = self.check_queryset(request, instance) return res + + +class DeptDestroyPermission(CustomPermission): + """ + 部门删除权限校验:判断部门下是否有用户存在,存在不可删除 + """ + message = '没有有操作权限' + + def has_permission(self, request: Request, view: APIView): + return True + + def check_queryset(self, request, instance): + if instance.values_list('userprofile', flat=True): + self.message = "该部门下有关联用户,无法删除!" + return False + return True + + def has_object_permission(self, request: Request, view: APIView, instance): + res = self.check_queryset(request, instance) + return res diff --git a/dvadmin-backend/apps/vadmin/permission/serializers.py b/dvadmin-backend/apps/vadmin/permission/serializers.py index f9bfaf3..8fc641e 100644 --- a/dvadmin-backend/apps/vadmin/permission/serializers.py +++ b/dvadmin-backend/apps/vadmin/permission/serializers.py @@ -226,8 +226,8 @@ class UserProfileSerializer(CustomModelSerializer): return False def get_unread_msg_count(self, obj: UserProfile): - return MessagePush.objects.filter(status='2').exclude(user=obj, - messagepushuser_message_push__is_read=True).count() + return MessagePush.objects.filter(status='2').exclude(messagepushuser_message_push__is_read=True, + messagepushuser_message_push__user=obj).count() class Meta: model = UserProfile diff --git a/dvadmin-backend/apps/vadmin/permission/views.py b/dvadmin-backend/apps/vadmin/permission/views.py index bec3b8e..8ece4fa 100644 --- a/dvadmin-backend/apps/vadmin/permission/views.py +++ b/dvadmin-backend/apps/vadmin/permission/views.py @@ -2,7 +2,7 @@ from django.contrib.auth import authenticate from rest_framework.request import Request from rest_framework.views import APIView -from .permissions import CommonPermission +from .permissions import CommonPermission, DeptDestroyPermission from ..op_drf.filters import DataLevelPermissionsFilter from ..op_drf.viewsets import CustomModelViewSet from ..permission.filters import MenuFilter, DeptFilter, PostFilter, RoleFilter, UserProfileFilter @@ -48,7 +48,10 @@ class GetRouters(APIView): return dict def get(self, request, format=None): - menus = Menu.objects.filter(role__userprofile=request.user) \ + kwargs = {} + if not request.user.is_superuser: + kwargs['role__userprofile'] = request.user + menus = Menu.objects.filter(**kwargs) \ .exclude(menuType='2').values('id', 'name', 'web_path', 'visible', 'status', 'isFrame', 'component_path', 'icon', 'parentId', 'orderNum', 'isCache').distinct() data = [] @@ -129,7 +132,7 @@ class DeptModelViewSet(CustomModelViewSet): filter_class = DeptFilter extra_filter_backends = [DataLevelPermissionsFilter] update_extra_permission_classes = (CommonPermission,) - destroy_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission, DeptDestroyPermission) create_extra_permission_classes = (CommonPermission,) search_fields = ('deptName',) ordering = 'create_datetime' # 默认排序 @@ -359,7 +362,7 @@ class UserProfileModelViewSet(CustomModelViewSet): :return: """ instance = self.queryset.get(id=request.user.id) - instance.mobile = request.data.get('newPassword', None) + instance.password = request.data.get('newPassword', None) if not authenticate(username=request.user.username, password=request.data.get('oldPassword', None)): return ErrorResponse(msg='旧密码不正确!') instance.set_password(request.data.get('newPassword')) diff --git a/dvadmin-backend/apps/vadmin/scripts/permission/permission_userprofile.sql b/dvadmin-backend/apps/vadmin/scripts/permission/permission_userprofile.sql index e59fc9e..56e3630 100644 --- a/dvadmin-backend/apps/vadmin/scripts/permission/permission_userprofile.sql +++ b/dvadmin-backend/apps/vadmin/scripts/permission/permission_userprofile.sql @@ -33,8 +33,8 @@ -- ---------------------------- -- Records of permission_userprofile -- ---------------------------- -INSERT INTO `permission_userprofile` (id, password, last_login, is_superuser, first_name, last_name, is_staff, is_active, date_joined, username, secret, email, mobile, avatar, name, gender, remark, user_type, create_datetime, update_datetime, dept_id, dept_belong_id) VALUES (1, 'pbkdf2_sha256$150000$OjTMSXJgkzrE$jEQCjWbIbXwpN4k2z0o8Yvou1UQGuoJALyL/kGDZFd4=', '2021-02-27 06:20:28.214775', 1, '', '', 1, 1, '2021-02-27 06:20:09.188689', 'admin', '3704adf3-380f-4c27-a8da-60420e8cb4ab', 'admin@qq.com', NULL, NULL, '管理员', '2', '1', 2, '2021-02-27 06:20:09.263192', '2021-02-27 09:14:30.009998', 8, 1); -INSERT INTO `permission_userprofile` (id, password, last_login, is_superuser, first_name, last_name, is_staff, is_active, date_joined, username, secret, email, mobile, avatar, name, gender, remark, user_type, create_datetime, update_datetime, dept_id, dept_belong_id) VALUES (2, 'pbkdf2_sha256$150000$5Z9LSi7LpNms$xVguE/dOEpI4D95LjSaKm0xzG7vNSopUolANr8f/6/E=', NULL, 0, '', '', 0, 1, '2021-03-03 15:38:27.009893', 'dvadmin', 'b4c5d79a-f01c-4244-92f8-b5288eca1d50', NULL, NULL, NULL, '普通用户', '2', NULL, 0, '2021-03-03 15:38:27.010771', '2021-03-03 15:38:27.086069', 8, 1); +INSERT INTO `permission_userprofile` (id, password, last_login, is_superuser, first_name, last_name, is_staff, is_active, date_joined, username, secret, email, mobile, avatar, name, gender, remark, user_type, create_datetime, update_datetime, dept_id, dept_belong_id, creator_id) VALUES (1, 'pbkdf2_sha256$150000$OjTMSXJgkzrE$jEQCjWbIbXwpN4k2z0o8Yvou1UQGuoJALyL/kGDZFd4=', '2021-02-27 06:20:28.214775', 1, '', '', 1, 1, '2021-02-27 06:20:09.188689', 'admin', '3704adf3-380f-4c27-a8da-60420e8cb4ab', 'admin@qq.com', NULL, NULL, '管理员', '2', '1', 2, '2021-02-27 06:20:09.263192', '2021-02-27 09:14:30.009998', 1, 1, 1); +INSERT INTO `permission_userprofile` (id, password, last_login, is_superuser, first_name, last_name, is_staff, is_active, date_joined, username, secret, email, mobile, avatar, name, gender, remark, user_type, create_datetime, update_datetime, dept_id, dept_belong_id, creator_id) VALUES (2, 'pbkdf2_sha256$150000$5Z9LSi7LpNms$xVguE/dOEpI4D95LjSaKm0xzG7vNSopUolANr8f/6/E=', NULL, 0, '', '', 0, 1, '2021-03-03 15:38:27.009893', 'dvadmin', 'b4c5d79a-f01c-4244-92f8-b5288eca1d50', NULL, NULL, NULL, '普通用户', '2', NULL, 0, '2021-03-03 15:38:27.010771', '2021-03-03 15:38:27.086069', 1, 1, 1); -- ---------------------------- -- Table structure for permission_userprofile_post -- ---------------------------- diff --git a/dvadmin-backend/apps/vadmin/system/models/save_file.py b/dvadmin-backend/apps/vadmin/system/models/save_file.py index b43757d..30407cf 100644 --- a/dvadmin-backend/apps/vadmin/system/models/save_file.py +++ b/dvadmin-backend/apps/vadmin/system/models/save_file.py @@ -13,7 +13,7 @@ def files_path(instance, filename): class SaveFile(CoreModel): name = CharField(max_length=128, verbose_name="文件名称", null=True, blank=True) - type = CharField(max_length=32, verbose_name="文件类型", null=True, blank=True) + type = CharField(max_length=200, verbose_name="文件类型", null=True, blank=True) size = CharField(max_length=64, verbose_name="文件大小", null=True, blank=True) address = CharField(max_length=16, verbose_name="存储位置", null=True, blank=True) # 本地、阿里云、腾讯云.. source = CharField(max_length=16, verbose_name="文件来源", null=True, blank=True) # 导出、用户上传. diff --git a/dvadmin-backend/apps/vadmin/system/views.py b/dvadmin-backend/apps/vadmin/system/views.py index 05257cc..c2d716b 100644 --- a/dvadmin-backend/apps/vadmin/system/views.py +++ b/dvadmin-backend/apps/vadmin/system/views.py @@ -202,7 +202,7 @@ class MessagePushModelViewSet(CustomModelViewSet): serializer_class = MessagePushSerializer create_serializer_class = MessagePushCreateUpdateSerializer update_serializer_class = MessagePushCreateUpdateSerializer - extra_filter_backends = [DataLevelPermissionsFilter] + # extra_filter_backends = [DataLevelPermissionsFilter] update_extra_permission_classes = (CommonPermission,) destroy_extra_permission_classes = (CommonPermission,) create_extra_permission_classes = (CommonPermission,) @@ -217,6 +217,7 @@ class MessagePushModelViewSet(CustomModelViewSet): 获取用户自己消息列表 """ queryset = self.filter_queryset(self.get_queryset()) + queryset = queryset.filter(status=2) is_read = request.query_params.get('is_read', None) if is_read: if is_read == 'False': diff --git a/dvadmin-backend/apps/vadmin/utils/authentication.py b/dvadmin-backend/apps/vadmin/utils/authentication.py index cc3b781..4a51ca5 100644 --- a/dvadmin-backend/apps/vadmin/utils/authentication.py +++ b/dvadmin-backend/apps/vadmin/utils/authentication.py @@ -12,8 +12,8 @@ from django.utils.translation import ugettext as _ from rest_framework import exceptions from rest_framework_jwt.utils import jwt_decode_handler -from .decorators import exceptionHandler from .jwt_util import jwt_get_session_id +from ..permission.models.users import UserProfile logger = logging.getLogger(__name__) User = get_user_model() @@ -38,6 +38,8 @@ class OpAuthJwtAuthentication(object): raise exceptions.AuthenticationFailed(msg) except jwt.InvalidTokenError: raise exceptions.AuthenticationFailed() + except UserProfile.DoesNotExist: + raise exceptions.AuthenticationFailed() username = payload.get('username', None) if not username: diff --git a/dvadmin-backend/apps/vadmin/utils/exceptions.py b/dvadmin-backend/apps/vadmin/utils/exceptions.py index cbd065e..f018592 100644 --- a/dvadmin-backend/apps/vadmin/utils/exceptions.py +++ b/dvadmin-backend/apps/vadmin/utils/exceptions.py @@ -65,8 +65,6 @@ def op_exception_handler(ex, context): """ msg = '' code = '201' - request = context.get('request') - request.session['model_name'] = str(get_verbose_name(view=context.get('view'))) if isinstance(ex, AuthenticationFailed): code = 401 diff --git a/dvadmin-backend/requirements.txt b/dvadmin-backend/requirements.txt index 5e06ebc..2ea4f69 100644 --- a/dvadmin-backend/requirements.txt +++ b/dvadmin-backend/requirements.txt @@ -26,3 +26,4 @@ xlrd==2.0.1 coreapi==2.3.3 user-agents==2.2.0 eventlet==0.30.2 +psutil==5.8.0 diff --git a/dvadmin-ui/README.md b/dvadmin-ui/README.md index a857617..b0823d8 100755 --- a/dvadmin-ui/README.md +++ b/dvadmin-ui/README.md @@ -2,22 +2,22 @@ ```bash # 克隆项目 -git clone https://gitee.com/y_project/RuoYi-Vue +git clone https://gitee.com/liqianglog/django-vue-admin.git # 进入项目目录 -cd ruoyi-ui +cd dvadmin-ui # 安装依赖 -npm install - -# 建议不要直接使用 cnpm 安装依赖,会有各种诡异的 bug。可以通过如下操作解决 npm 下载速度慢的问题 npm install --registry=https://registry.npm.taobao.org # 启动服务 npm run dev + +# 浏览器访问 http://localhost:8080 +# .env.development 文件中可配置启动端口等参数 ``` -浏览器访问 http://localhost:80 +浏览器访问 http://localhost:8080 ## 发布 diff --git a/dvadmin-ui/src/layout/components/Navbar.vue b/dvadmin-ui/src/layout/components/Navbar.vue index c300c63..76e7800 100755 --- a/dvadmin-ui/src/layout/components/Navbar.vue +++ b/dvadmin-ui/src/layout/components/Navbar.vue @@ -14,7 +14,7 @@
- +
@@ -81,11 +81,11 @@ export default { }, data() { return { - count: store.getters.unread_msg_count, + count: store.unread_msg_count, }; }, computed: { - ...mapGetters(["sidebar", "avatar", "device"]), + ...mapGetters(["sidebar", "avatar", "device", "unread_msg_count"]), setting: { get() { return this.$store.state.settings.showSettings; diff --git a/dvadmin-ui/src/store/modules/user.js b/dvadmin-ui/src/store/modules/user.js index 895a689..9e4b5a5 100755 --- a/dvadmin-ui/src/store/modules/user.js +++ b/dvadmin-ui/src/store/modules/user.js @@ -7,7 +7,8 @@ const user = { name: '', avatar: '', roles: [], - permissions: [] + permissions: [], + unread_msg_count: 0 }, mutations: { diff --git a/dvadmin-ui/src/views/vadmin/permission/user/index.vue b/dvadmin-ui/src/views/vadmin/permission/user/index.vue index f11d209..35caf58 100755 --- a/dvadmin-ui/src/views/vadmin/permission/user/index.vue +++ b/dvadmin-ui/src/views/vadmin/permission/user/index.vue @@ -161,7 +161,7 @@ - {{role.roleName}} + {{role.roleName}} @@ -648,6 +648,7 @@ this.$refs['form'].validate(valid => { if (valid) { if (this.form.id != undefined) { + this.form.creator = undefined updateUser(this.form).then(response => { this.msgSuccess('修改成功') this.open = false diff --git a/dvadmin-ui/src/views/vadmin/system/message/Mymessage.vue b/dvadmin-ui/src/views/vadmin/system/message/Mymessage.vue index 1bbcd87..43a2581 100644 --- a/dvadmin-ui/src/views/vadmin/system/message/Mymessage.vue +++ b/dvadmin-ui/src/views/vadmin/system/message/Mymessage.vue @@ -103,9 +103,11 @@ // 修改通知查询状态 if (this.badgeType === "danger") { updateIsRead(this.showingMsgItem).then(response => { - store.getters.unread_msg_count - this.open = false; - this.getList(); + if(response.code === 200){ + store.commit('SET_UNREAD_MSG_COUNT', store.getters.unread_msg_count - 1); + this.open = false; + this.getList(); + } }); } } From 495e2855f455640c5177d5e75673fdb5a5b83e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Thu, 1 Apr 2021 00:19:46 +0800 Subject: [PATCH 05/21] =?UTF-8?q?!14=20=E6=96=87=E6=A1=A3(=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E6=8F=90=E4=BA=A4):=20README.md=20=E6=96=87=E6=A1=A3?= =?UTF-8?q?=20*=20=E6=96=87=E6=A1=A3(=E6=96=87=E6=A1=A3=E6=8F=90=E4=BA=A4)?= =?UTF-8?q?:=20README.md=20=E6=96=87=E6=A1=A3=20*=20=E4=BF=AE=E5=A4=8DBUG(?= =?UTF-8?q?docker=20=E9=83=A8=E7=BD=B2):=20docker-compose.yml=20=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E4=BF=AE=E6=94=B9=20*=20=E6=96=87=E6=A1=A3(=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E6=8F=90=E4=BA=A4):=20README.md=20=E6=96=87=E6=A1=A3?= =?UTF-8?q?=20*=20=E6=96=87=E6=A1=A3(=E6=96=87=E6=A1=A3=E4=BF=AE=E6=94=B9)?= =?UTF-8?q?:=20README.md=20=E6=96=87=E6=A1=A3=E4=BF=AE=E6=94=B9=20*=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG(=E6=B7=BB=E5=8A=A0=E4=BE=9D=E8=B5=96):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BE=9D=E8=B5=96=20psutil=3D=3D5.8.0=20*=20?= =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG(=E9=80=9A=E7=9F=A5=E6=B6=88=E6=81=AF):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=80=9A=E7=9F=A5=E6=B6=88=E6=81=AF=E6=9C=AA?= =?UTF-8?q?=E5=8F=91=E5=B8=83=E7=8A=B6=E6=80=81=E8=BF=87=E6=BB=A4=20*=20Me?= =?UTF-8?q?rge=20branch=20'dvadmin-liqianglog'=20of=20https://gitee.com/li?= =?UTF-8?q?qianglog/djan=E2=80=A6=20*=20=E4=BF=AE=E5=A4=8DBUG(=E4=B8=AA?= =?UTF-8?q?=E4=BA=BA=E4=BF=A1=E6=81=AF):=20=E4=B8=AA=E4=BA=BA=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E4=B8=AD=E6=9C=AA=E8=AF=BB=E6=B6=88=E6=81=AF=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E6=95=B0=E9=87=8F=E9=94=99=E8=AF=AF=20*=20=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=8F=98=E5=8C=96(=E8=8E=B7=E5=8F=96=E8=B7=AF?= =?UTF-8?q?=E7=94=B1=E6=8E=A5=E5=8F=A3):=20admin=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E8=8F=9C=E5=8D=95=E5=8F=AF=E6=9F=A5=E7=9C=8B=E5=85=A8=E9=83=A8?= =?UTF-8?q?=EF=BC=8C=E4=BE=BF=E4=BA=8E=E5=BC=80=E5=8F=91=20*=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8DBUG(=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86):=20=E4=B8=AA?= =?UTF-8?q?=E4=BA=BA=E4=BF=AE=E6=94=B9=E5=AF=86=E7=A0=81bug=EF=BC=8CUserPr?= =?UTF-8?q?ofile=E6=A8=A1=E5=9E=8B=E6=B7=BB=E5=8A=A0=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E4=BA=BA=20*=20update=20dvadmin-backend/apps?= =?UTF-8?q?/vadmin/op=5Fdrf/middleware.py.=20*=20update=20dvadmin-backend/?= =?UTF-8?q?apps/vadmin/op=5Fdrf/middleware.py.=20*=20=E4=BF=AE=E5=A4=8DBUG?= =?UTF-8?q?(=E4=B8=AA=E4=BA=BA=E4=BF=A1=E6=81=AF&=E9=80=9A=E7=9F=A5?= =?UTF-8?q?=E5=85=AC=E5=91=8A):=20=E4=B8=AA=E4=BA=BA=E6=9C=AA=E8=AF=BB?= =?UTF-8?q?=E9=80=9A=E7=9F=A5=E5=85=AC=E5=91=8A=E6=95=B0=E9=87=8F=E9=94=99?= =?UTF-8?q?=E8=AF=AF=20*=20=E4=BF=AE=E5=A4=8DBUG(=E4=B8=AD=E9=97=B4?= =?UTF-8?q?=E4=BB=B6bug):=20=E6=97=A5=E5=BF=97=E4=B8=AD=E9=97=B4=E4=BB=B6?= =?UTF-8?q?=E5=AD=98=E5=85=A5=E6=A8=A1=E5=9D=97=E4=BF=A1=E6=81=AF=E4=B8=8D?= =?UTF-8?q?=E5=85=A8=20*=20Merge=20remote-tracking=20branch=20'remotes/ori?= =?UTF-8?q?gin/master'=20into=20dvadmin-liqianglog=20*=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8DBUG(=E6=8F=90=E4=BA=A4=E9=94=99=E8=AF=AF):=20DEMO=5FEN?= =?UTF-8?q?V=20*=20Merge=20remote-tracking=20branch=20'remotes/origin/dvad?= =?UTF-8?q?min-liqianglog'=20into=20=E2=80=A6=20*=20=E4=BF=AE=E5=A4=8DBUG(?= =?UTF-8?q?=E4=B8=AD=E9=97=B4=E4=BB=B6bug):=20=E6=97=A5=E5=BF=97=E4=B8=AD?= =?UTF-8?q?=E9=97=B4=E4=BB=B6=E5=AD=98=E5=85=A5=E6=A8=A1=E5=9D=97=E4=BF=A1?= =?UTF-8?q?=E6=81=AF=E4=B8=8D=E5=85=A8=20*=20!11=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=A4=9A=E4=B8=AAbug=20*=20=E4=BF=AE=E5=A4=8DBUG(=E4=B8=AD?= =?UTF-8?q?=E9=97=B4=E4=BB=B6bug):=20=E6=97=A5=E5=BF=97=E4=B8=AD=E9=97=B4?= =?UTF-8?q?=E4=BB=B6=E5=AD=98=E5=85=A5=E6=A8=A1=E5=9D=97=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E4=B8=8D=E5=85=A8=20*=20!10=20=E5=90=8E=E7=AB=AF=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=9D=83=E9=99=90=E9=AA=8C=E8=AF=81bug=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=20*=20=E6=B5=8B=E8=AF=95(=E9=83=A8=E7=BD=B2=E6=B5=8B?= =?UTF-8?q?=E8=AF=95):=20*=20=E4=BF=AE=E5=A4=8DBUG(=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E4=B8=8A=E4=BC=A0):=20doc=EF=BC=8Cdocx=EF=BC=8Cxlsx=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E9=83=BD=E6=97=A0=E6=B3=95=E4=B8=8A=E4=BC=A0=E6=88=90?= =?UTF-8?q?=E5=8A=9F=20*=20=E4=BF=AE=E5=A4=8DBUG(=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E9=83=A8=E9=97=A8):=20=E9=83=A8=E9=97=A8=E9=87=8C=E9=9D=A2?= =?UTF-8?q?=E5=AD=98=E5=9C=A8=E7=94=A8=E6=88=B7=EF=BC=8C=E4=BE=9D=E7=84=B6?= =?UTF-8?q?=E8=83=BD=E5=A4=9F=E5=88=A0=E9=99=A4=E9=83=A8=E9=97=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 139daa8..ae3166f 100644 --- a/README.md +++ b/README.md @@ -43,11 +43,10 @@ github地址:[https://github.com/liqianglog/django-vue-admin](https://github.c 9. 通知公告:发布通知公告给所有人,进行消息的通知。 10. 操作日志:系统正常操作日志记录和查询;系统异常信息日志记录和查询。 11. 登录日志:系统登录日志记录查询包含登录异常。 -12. 在线用户:当前系统中活跃用户状态监控、用户强退功能。 -13. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 -14. 用户注册:新用户注册页面。 -15. 服务监控:监视当前系统CPU、内存、磁盘、堆栈、celery 当前状态等相关信息。 -16. 在线构建器:拖动表单元素生成相应的HTML代码。 +12. 定时日志:celery定时任务执行日志记录。 +13. 在线用户:当前系统中活跃用户状态监控、用户强退功能。 +14. 定时任务:在线(添加、修改、删除)任务调度包含执行结果日志。 +15. 在线构建器:拖动表单元素生成相应的HTML代码。 ## 在线体验 From 864d67537097fd7b433507e8878c671830cf0dba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Thu, 8 Apr 2021 23:26:30 +0800 Subject: [PATCH 06/21] =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG(=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=99=A8=E7=9B=91=E6=8E=A7):=20=E6=96=B0=E5=A2=9E=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E7=9B=91=E6=8E=A7=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvadmin-backend/application/settings.py | 1 + .../apps/vadmin/monitor/__init__.py | 0 dvadmin-backend/apps/vadmin/monitor/admin.py | 0 dvadmin-backend/apps/vadmin/monitor/apps.py | 6 ++++ .../apps/vadmin/monitor/filters.py | 23 +++++++++++++ .../vadmin/monitor/migrations/__init__.py | 0 .../apps/vadmin/monitor/models/__init__.py | 3 ++ .../apps/vadmin/monitor/models/monitor.py | 21 ++++++++++++ .../apps/vadmin/monitor/models/server.py | 17 ++++++++++ .../apps/vadmin/monitor/models/sys_files.py | 19 +++++++++++ .../apps/vadmin/monitor/serializers.py | 29 +++++++++++++++++ dvadmin-backend/apps/vadmin/monitor/tasks.py | 0 dvadmin-backend/apps/vadmin/monitor/tests.py | 3 ++ dvadmin-backend/apps/vadmin/monitor/urls.py | 12 +++++++ dvadmin-backend/apps/vadmin/monitor/views.py | 32 +++++++++++++++++++ dvadmin-backend/apps/vadmin/urls.py | 1 + 16 files changed, 167 insertions(+) create mode 100644 dvadmin-backend/apps/vadmin/monitor/__init__.py create mode 100644 dvadmin-backend/apps/vadmin/monitor/admin.py create mode 100644 dvadmin-backend/apps/vadmin/monitor/apps.py create mode 100644 dvadmin-backend/apps/vadmin/monitor/filters.py create mode 100644 dvadmin-backend/apps/vadmin/monitor/migrations/__init__.py create mode 100644 dvadmin-backend/apps/vadmin/monitor/models/__init__.py create mode 100644 dvadmin-backend/apps/vadmin/monitor/models/monitor.py create mode 100644 dvadmin-backend/apps/vadmin/monitor/models/server.py create mode 100644 dvadmin-backend/apps/vadmin/monitor/models/sys_files.py create mode 100644 dvadmin-backend/apps/vadmin/monitor/serializers.py create mode 100644 dvadmin-backend/apps/vadmin/monitor/tasks.py create mode 100644 dvadmin-backend/apps/vadmin/monitor/tests.py create mode 100644 dvadmin-backend/apps/vadmin/monitor/urls.py create mode 100644 dvadmin-backend/apps/vadmin/monitor/views.py diff --git a/dvadmin-backend/application/settings.py b/dvadmin-backend/application/settings.py index 4b385f0..7132864 100644 --- a/dvadmin-backend/application/settings.py +++ b/dvadmin-backend/application/settings.py @@ -51,6 +51,7 @@ INSTALLED_APPS = [ 'apps.vadmin.op_drf', 'apps.vadmin.system', 'apps.vadmin.celery', + 'apps.vadmin.monitor', ] MIDDLEWARE = [ diff --git a/dvadmin-backend/apps/vadmin/monitor/__init__.py b/dvadmin-backend/apps/vadmin/monitor/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dvadmin-backend/apps/vadmin/monitor/admin.py b/dvadmin-backend/apps/vadmin/monitor/admin.py new file mode 100644 index 0000000..e69de29 diff --git a/dvadmin-backend/apps/vadmin/monitor/apps.py b/dvadmin-backend/apps/vadmin/monitor/apps.py new file mode 100644 index 0000000..13ee922 --- /dev/null +++ b/dvadmin-backend/apps/vadmin/monitor/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class MonitorConfig(AppConfig): + name = 'vadmin.monitor' + verbose_name = "系统监控" diff --git a/dvadmin-backend/apps/vadmin/monitor/filters.py b/dvadmin-backend/apps/vadmin/monitor/filters.py new file mode 100644 index 0000000..e80748e --- /dev/null +++ b/dvadmin-backend/apps/vadmin/monitor/filters.py @@ -0,0 +1,23 @@ +import django_filters + +from .models import Server, Monitor + + +class ServerFilter(django_filters.rest_framework.FilterSet): + """ + 服务器信息 简单过滤器 + """ + + class Meta: + model = Server + fields = '__all__' + + +class MonitorFilter(django_filters.rest_framework.FilterSet): + """ + 服务器监控信息 简单过滤器 + """ + + class Meta: + model = Monitor + fields = '__all__' diff --git a/dvadmin-backend/apps/vadmin/monitor/migrations/__init__.py b/dvadmin-backend/apps/vadmin/monitor/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dvadmin-backend/apps/vadmin/monitor/models/__init__.py b/dvadmin-backend/apps/vadmin/monitor/models/__init__.py new file mode 100644 index 0000000..0f0d1f8 --- /dev/null +++ b/dvadmin-backend/apps/vadmin/monitor/models/__init__.py @@ -0,0 +1,3 @@ +from ..models.monitor import Monitor +from ..models.server import Server +from ..models.sys_files import SysFiles diff --git a/dvadmin-backend/apps/vadmin/monitor/models/monitor.py b/dvadmin-backend/apps/vadmin/monitor/models/monitor.py new file mode 100644 index 0000000..5a883d6 --- /dev/null +++ b/dvadmin-backend/apps/vadmin/monitor/models/monitor.py @@ -0,0 +1,21 @@ +from django.db.models import CharField, ForeignKey, CASCADE + +from ...op_drf.models import CoreModel + + +class Monitor(CoreModel): + cpu_num = CharField(max_length=8, verbose_name='CPU核数') + cpu_free = CharField(max_length=8, verbose_name='CPU当前空闲率') + cpu_sys = CharField(max_length=8, verbose_name='CPU已使用率') + mem_num = CharField(max_length=32, verbose_name='内存总数(KB)') + mem_free = CharField(max_length=32, verbose_name='内存剩余大小(KB)') + mem_sys = CharField(max_length=32, verbose_name='内存已使用大小(KB)') + seconds = CharField(max_length=32, verbose_name='运行已时间(秒)') + server = ForeignKey(to='Server', on_delete=CASCADE, verbose_name="关联服务器信息", db_constraint=False) + + class Meta: + verbose_name = '服务器监控信息' + verbose_name_plural = verbose_name + + def __str__(self): + return f"{self.server and self.server.name and self.server.ip}监控信息" diff --git a/dvadmin-backend/apps/vadmin/monitor/models/server.py b/dvadmin-backend/apps/vadmin/monitor/models/server.py new file mode 100644 index 0000000..aebc802 --- /dev/null +++ b/dvadmin-backend/apps/vadmin/monitor/models/server.py @@ -0,0 +1,17 @@ +from django.db.models import CharField + +from ...op_drf.models import CoreModel + + +class Server(CoreModel): + name = CharField(max_length=256, verbose_name='服务器名称', null=True, blank=True) + ip = CharField(max_length=32, verbose_name="ip地址") + os = CharField(max_length=32, verbose_name="操作系统") + remark = CharField(max_length=256, verbose_name="备注", null=True, blank=True) + + class Meta: + verbose_name = '服务器信息' + verbose_name_plural = verbose_name + + def __str__(self): + return f"{self.name and self.ip}" diff --git a/dvadmin-backend/apps/vadmin/monitor/models/sys_files.py b/dvadmin-backend/apps/vadmin/monitor/models/sys_files.py new file mode 100644 index 0000000..6a11ed1 --- /dev/null +++ b/dvadmin-backend/apps/vadmin/monitor/models/sys_files.py @@ -0,0 +1,19 @@ +from django.db.models import CharField, ForeignKey, CASCADE + +from ...op_drf.models import CoreModel + + +class SysFiles(CoreModel): + dir_name = CharField(max_length=32, verbose_name='磁盘路径') + sys_type_name = CharField(max_length=32, verbose_name='系统文件类型') + type_name = CharField(max_length=32, verbose_name='盘符类型') + total = CharField(max_length=32, verbose_name='磁盘总大小(KB)') + mem_free = CharField(max_length=32, verbose_name='已使用大小(KB)') + monitor = ForeignKey(to='Monitor', on_delete=CASCADE, verbose_name="关联服务器监控信息", db_constraint=False) + + class Meta: + verbose_name = '系统磁盘' + verbose_name_plural = verbose_name + + def __str__(self): + return f"{self.creator and self.creator.name}" diff --git a/dvadmin-backend/apps/vadmin/monitor/serializers.py b/dvadmin-backend/apps/vadmin/monitor/serializers.py new file mode 100644 index 0000000..3a7e0bd --- /dev/null +++ b/dvadmin-backend/apps/vadmin/monitor/serializers.py @@ -0,0 +1,29 @@ +from .models import Server, Monitor +from ..op_drf.serializers import CustomModelSerializer + + +# ================================================= # +# ************** 服务器信息 序列化器 ************** # +# ================================================= # + +class ServerSerializer(CustomModelSerializer): + """ + 服务器信息 简单序列化器 + """ + + class Meta: + model = Server + fields = '__all__' + +# ================================================= # +# ************** 服务器监控信息 序列化器 ************** # +# ================================================= # + +class MonitorSerializer(CustomModelSerializer): + """ + 服务器监控信息 简单序列化器 + """ + + class Meta: + model = Monitor + fields = '__all__' diff --git a/dvadmin-backend/apps/vadmin/monitor/tasks.py b/dvadmin-backend/apps/vadmin/monitor/tasks.py new file mode 100644 index 0000000..e69de29 diff --git a/dvadmin-backend/apps/vadmin/monitor/tests.py b/dvadmin-backend/apps/vadmin/monitor/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/dvadmin-backend/apps/vadmin/monitor/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/dvadmin-backend/apps/vadmin/monitor/urls.py b/dvadmin-backend/apps/vadmin/monitor/urls.py new file mode 100644 index 0000000..b1c0b78 --- /dev/null +++ b/dvadmin-backend/apps/vadmin/monitor/urls.py @@ -0,0 +1,12 @@ +from rest_framework.routers import DefaultRouter + +from .views import ServerModelViewSet, MonitorModelViewSet + +router = DefaultRouter() +router.register(r'server', ServerModelViewSet) +router.register(r'monitor', MonitorModelViewSet) + +urlpatterns = [ + +] +urlpatterns += router.urls diff --git a/dvadmin-backend/apps/vadmin/monitor/views.py b/dvadmin-backend/apps/vadmin/monitor/views.py new file mode 100644 index 0000000..e4cec1c --- /dev/null +++ b/dvadmin-backend/apps/vadmin/monitor/views.py @@ -0,0 +1,32 @@ +from .filters import ServerFilter, MonitorFilter +from .models import Server, Monitor +from .serializers import ServerSerializer, MonitorSerializer +from ..op_drf.viewsets import CustomModelViewSet +from ..permission.permissions import CommonPermission + + +class ServerModelViewSet(CustomModelViewSet): + """ + 服务器信息 模型的CRUD视图 + """ + queryset = Server.objects.all() + serializer_class = ServerSerializer + # extra_filter_backends = [DataLevelPermissionsFilter] + filter_class = ServerFilter + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) + ordering = '-create_datetime' # 默认排序 + +class MonitorModelViewSet(CustomModelViewSet): + """ + 服务器监控信息 模型的CRUD视图 + """ + queryset = Monitor.objects.all() + serializer_class = MonitorSerializer + # extra_filter_backends = [DataLevelPermissionsFilter] + filter_class = MonitorFilter + update_extra_permission_classes = (CommonPermission,) + destroy_extra_permission_classes = (CommonPermission,) + create_extra_permission_classes = (CommonPermission,) + ordering = '-create_datetime' # 默认排序 diff --git a/dvadmin-backend/apps/vadmin/urls.py b/dvadmin-backend/apps/vadmin/urls.py index cf4051d..e1354f6 100644 --- a/dvadmin-backend/apps/vadmin/urls.py +++ b/dvadmin-backend/apps/vadmin/urls.py @@ -54,5 +54,6 @@ urlpatterns = [ re_path(r'^permission/', include('apps.vadmin.permission.urls')), re_path(r'^system/', include('apps.vadmin.system.urls')), re_path(r'^celery/', include('apps.vadmin.celery.urls')), + re_path(r'^monitor/', include('apps.vadmin.monitor.urls')), ] From 9d8c74e76814e198e075b879756dfc9338e13b48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Sun, 11 Apr 2021 01:28:06 +0800 Subject: [PATCH 07/21] =?UTF-8?q?=E6=96=B0=E5=8A=9F=E8=83=BD(=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E7=9B=91=E6=8E=A7):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E5=99=A8=E7=9B=91=E6=8E=A7=E5=8A=9F=E8=83=BD?= =?UTF-8?q?API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvadmin-backend/application/settings.py | 1 + dvadmin-backend/application/urls.py | 2 +- .../apps/vadmin/monitor/models/monitor.py | 4 +- .../apps/vadmin/monitor/models/server.py | 7 +- .../apps/vadmin/monitor/models/sys_files.py | 4 +- dvadmin-backend/apps/vadmin/monitor/tasks.py | 89 ++++++++++++++++++ dvadmin-backend/apps/vadmin/monitor/urls.py | 5 +- dvadmin-backend/apps/vadmin/monitor/views.py | 93 +++++++++++++++++++ dvadmin-backend/requirements.txt | 1 + 9 files changed, 197 insertions(+), 9 deletions(-) diff --git a/dvadmin-backend/application/settings.py b/dvadmin-backend/application/settings.py index 7132864..0e9601d 100644 --- a/dvadmin-backend/application/settings.py +++ b/dvadmin-backend/application/settings.py @@ -329,3 +329,4 @@ CELERYBEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler' # Back # ================================================= # # 接口权限 INTERFACE_PERMISSION = {locals().get("INTERFACE_PERMISSION", False)} +DJANGO_CELERY_BEAT_TZ_AWARE = False diff --git a/dvadmin-backend/application/urls.py b/dvadmin-backend/application/urls.py index 1bd1ed6..2a3a0ae 100644 --- a/dvadmin-backend/application/urls.py +++ b/dvadmin-backend/application/urls.py @@ -22,7 +22,7 @@ from django.urls import re_path, include from django.views.static import serve from rest_framework.views import APIView -from vadmin.utils.response import SuccessResponse +from apps.vadmin.utils.response import SuccessResponse class CaptchaRefresh(APIView): diff --git a/dvadmin-backend/apps/vadmin/monitor/models/monitor.py b/dvadmin-backend/apps/vadmin/monitor/models/monitor.py index 5a883d6..121ec8c 100644 --- a/dvadmin-backend/apps/vadmin/monitor/models/monitor.py +++ b/dvadmin-backend/apps/vadmin/monitor/models/monitor.py @@ -5,12 +5,10 @@ from ...op_drf.models import CoreModel class Monitor(CoreModel): cpu_num = CharField(max_length=8, verbose_name='CPU核数') - cpu_free = CharField(max_length=8, verbose_name='CPU当前空闲率') cpu_sys = CharField(max_length=8, verbose_name='CPU已使用率') mem_num = CharField(max_length=32, verbose_name='内存总数(KB)') - mem_free = CharField(max_length=32, verbose_name='内存剩余大小(KB)') mem_sys = CharField(max_length=32, verbose_name='内存已使用大小(KB)') - seconds = CharField(max_length=32, verbose_name='运行已时间(秒)') + seconds = CharField(max_length=32, verbose_name='系统已运行时间') server = ForeignKey(to='Server', on_delete=CASCADE, verbose_name="关联服务器信息", db_constraint=False) class Meta: diff --git a/dvadmin-backend/apps/vadmin/monitor/models/server.py b/dvadmin-backend/apps/vadmin/monitor/models/server.py index aebc802..d05140f 100644 --- a/dvadmin-backend/apps/vadmin/monitor/models/server.py +++ b/dvadmin-backend/apps/vadmin/monitor/models/server.py @@ -1,13 +1,16 @@ +from django.db import models from django.db.models import CharField -from ...op_drf.models import CoreModel +from apps.vadmin.op_drf.fields import UpdateDateTimeField, CreateDateTimeField -class Server(CoreModel): +class Server(models.Model): name = CharField(max_length=256, verbose_name='服务器名称', null=True, blank=True) ip = CharField(max_length=32, verbose_name="ip地址") os = CharField(max_length=32, verbose_name="操作系统") remark = CharField(max_length=256, verbose_name="备注", null=True, blank=True) + update_datetime = UpdateDateTimeField() # 修改时间 + create_datetime = CreateDateTimeField() # 创建时间 class Meta: verbose_name = '服务器信息' diff --git a/dvadmin-backend/apps/vadmin/monitor/models/sys_files.py b/dvadmin-backend/apps/vadmin/monitor/models/sys_files.py index 6a11ed1..a7ce4e1 100644 --- a/dvadmin-backend/apps/vadmin/monitor/models/sys_files.py +++ b/dvadmin-backend/apps/vadmin/monitor/models/sys_files.py @@ -5,10 +5,10 @@ from ...op_drf.models import CoreModel class SysFiles(CoreModel): dir_name = CharField(max_length=32, verbose_name='磁盘路径') - sys_type_name = CharField(max_length=32, verbose_name='系统文件类型') + sys_type_name = CharField(max_length=400, verbose_name='系统文件类型') type_name = CharField(max_length=32, verbose_name='盘符类型') total = CharField(max_length=32, verbose_name='磁盘总大小(KB)') - mem_free = CharField(max_length=32, verbose_name='已使用大小(KB)') + disk_sys = CharField(max_length=32, verbose_name='已使用大小(KB)') monitor = ForeignKey(to='Monitor', on_delete=CASCADE, verbose_name="关联服务器监控信息", db_constraint=False) class Meta: diff --git a/dvadmin-backend/apps/vadmin/monitor/tasks.py b/dvadmin-backend/apps/vadmin/monitor/tasks.py index e69de29..ba734f7 100644 --- a/dvadmin-backend/apps/vadmin/monitor/tasks.py +++ b/dvadmin-backend/apps/vadmin/monitor/tasks.py @@ -0,0 +1,89 @@ +import datetime +import logging +import sys +import time + +import psutil + +from ..monitor.models import Server, Monitor, SysFiles +from ..op_drf.response import SuccessResponse +from ..system.models import ConfigSettings +from ..utils.decorators import BaseCeleryApp + +logger = logging.getLogger(__name__) +from platform import platform + + +def getIP(): + """获取ipv4地址""" + dic = psutil.net_if_addrs() + ipv4_list = [] + for adapter in dic: + snicList = dic[adapter] + for snic in snicList: + if snic.family.name == 'AF_INET': + ipv4 = snic.address + if ipv4 != '127.0.0.1': + ipv4_list.append(ipv4) + if len(ipv4_list) >= 1: + return ipv4_list[0] + else: + return None + + +@BaseCeleryApp(name='apps.vadmin.monitor.tasks.get_monitor_info') +def get_monitor_info(): + """ + 定时获取系统监控信息 + :return: + """ + # 获取服务器 + ip = getIP() + if not ip: + logger.error("无法获取到IP") + return + server_obj, create = Server.objects.get_or_create(ip=ip) + if create: + server_obj.name = ip + terse = ('terse' in sys.argv or '--terse' in sys.argv) + aliased = (not 'nonaliased' in sys.argv and not '--nonaliased' in sys.argv) + server_obj.os = platform(aliased, terse) + server_obj.save() + + # 获取CPU和内存信息 + mem = psutil.virtual_memory() + monitor_obj = Monitor() + monitor_obj.cpu_num = psutil.cpu_count() + monitor_obj.cpu_sys = float(psutil.cpu_percent(0.1)) + monitor_obj.mem_num = int(mem.total / 1024) + monitor_obj.mem_sys = int(mem.used / 1024) + monitor_obj.seconds = time.strftime("%d天 %H 小时 %M 分 %S 秒", time.gmtime(int(time.time()) - int(psutil.boot_time()))) + monitor_obj.server = server_obj + monitor_obj.save() + + # 保存磁盘信息 + for ele in psutil.disk_partitions(): + disk = psutil.disk_usage('/') + + sys_files_obj = SysFiles() + sys_files_obj.dir_name = ele.mountpoint + sys_files_obj.sys_type_name = ele.opts + sys_files_obj.type_name = ele.fstype + sys_files_obj.total = disk.total + sys_files_obj.disk_sys = disk.used + sys_files_obj.monitor = monitor_obj + sys_files_obj.save() + + return SuccessResponse(msg="") + + +@BaseCeleryApp(name='apps.vadmin.monitor.tasks.clean_surplus_monitor_info') +def clean_surplus_monitor_info(): + """ + 定时清理多余 系统监控信息 + :return: + """ + config_settings_obj = ConfigSettings.objects.filter(configKey='sys.monitor.info.save_days').first() + Monitor.objects.filter( + update_datetime__lt=datetime.timedelta(days=int(config_settings_obj.configValue or 30))).delete() + logger.info(f"成功清空{config_settings_obj.configValue}天前数据") diff --git a/dvadmin-backend/apps/vadmin/monitor/urls.py b/dvadmin-backend/apps/vadmin/monitor/urls.py index b1c0b78..c5ef2fa 100644 --- a/dvadmin-backend/apps/vadmin/monitor/urls.py +++ b/dvadmin-backend/apps/vadmin/monitor/urls.py @@ -1,3 +1,4 @@ +from django.urls import re_path from rest_framework.routers import DefaultRouter from .views import ServerModelViewSet, MonitorModelViewSet @@ -7,6 +8,8 @@ router.register(r'server', ServerModelViewSet) router.register(r'monitor', MonitorModelViewSet) urlpatterns = [ - + re_path('monitor/info/', MonitorModelViewSet.as_view({'get': 'get_monitor_info'})), + re_path('monitor/enabled/', MonitorModelViewSet.as_view({'get': 'enabled_monitor_info'})), + re_path('monitor/clean/', MonitorModelViewSet.as_view({'get': 'clean_all'})), ] urlpatterns += router.urls diff --git a/dvadmin-backend/apps/vadmin/monitor/views.py b/dvadmin-backend/apps/vadmin/monitor/views.py index e4cec1c..9325852 100644 --- a/dvadmin-backend/apps/vadmin/monitor/views.py +++ b/dvadmin-backend/apps/vadmin/monitor/views.py @@ -1,8 +1,13 @@ +from django_celery_beat.models import PeriodicTask, IntervalSchedule, CrontabSchedule +from rest_framework.request import Request + from .filters import ServerFilter, MonitorFilter from .models import Server, Monitor from .serializers import ServerSerializer, MonitorSerializer +from ..op_drf.response import SuccessResponse from ..op_drf.viewsets import CustomModelViewSet from ..permission.permissions import CommonPermission +from ..system.models import ConfigSettings class ServerModelViewSet(CustomModelViewSet): @@ -18,6 +23,7 @@ class ServerModelViewSet(CustomModelViewSet): create_extra_permission_classes = (CommonPermission,) ordering = '-create_datetime' # 默认排序 + class MonitorModelViewSet(CustomModelViewSet): """ 服务器监控信息 模型的CRUD视图 @@ -30,3 +36,90 @@ class MonitorModelViewSet(CustomModelViewSet): destroy_extra_permission_classes = (CommonPermission,) create_extra_permission_classes = (CommonPermission,) ordering = '-create_datetime' # 默认排序 + + def get_monitor_info(self, request: Request, *args, **kwargs): + # 定时获取系统监控信息 + periodictask_obj = PeriodicTask.objects.filter(task='apps.vadmin.monitor.tasks.get_monitor_info').first() + if not periodictask_obj: + intervalschedule_obj, _ = IntervalSchedule.objects.get_or_create(every=5, period="seconds") + periodictask_obj = PeriodicTask() + periodictask_obj.task = "apps.vadmin.monitor.tasks.get_monitor_info" + periodictask_obj.name = "定时获取系统监控信息" + periodictask_obj.interval = intervalschedule_obj + periodictask_obj.enabled = False + periodictask_obj.save() + + # 定时清理多余 系统监控信息 + clean_task_obj = PeriodicTask.objects.filter( + task='apps.vadmin.monitor.tasks.clean_surplus_monitor_info').first() + if not clean_task_obj: + crontab_obj, _ = CrontabSchedule.objects.get_or_create(day_of_month="*", day_of_week="*", hour="1", + minute="0", month_of_year="*") + clean_task_obj = PeriodicTask() + clean_task_obj.task = "apps.vadmin.monitor.tasks.clean_surplus_monitor_info" + clean_task_obj.name = "定时清理多余-系统监控信息" + clean_task_obj.crontab = crontab_obj + clean_task_obj.enabled = True + clean_task_obj.save() + # 配置添加 + config_obj = ConfigSettings.objects.filter(configKey='sys.monitor.info.save_days').first() + if not config_obj: + config_obj = ConfigSettings() + config_obj.configKey = "sys.monitor.info.save_days" + config_obj.configName = "定时清理多余系统监控信息" + config_obj.configValue = "30" + config_obj.configType = "Y" + config_obj.status = "1" + config_obj.remark = "定时清理多余-系统监控信息,默认30天" + config_obj.save() + + # 获取保留天数 + return SuccessResponse(data={ + "enabled": periodictask_obj.enabled, + "interval": periodictask_obj.interval.every, + "save_days": config_obj.configValue if config_obj else "30", + }) + + def enabled_monitor_info(self, request: Request, *args, **kwargs): + enabled = request.query_params.get('enabled', None) + save_days = request.query_params.get('save_days', None) + interval = request.query_params.get('interval', None) + + periodictask_obj = PeriodicTask.objects.filter(task='apps.vadmin.monitor.tasks.get_monitor_info').first() + if enabled: + # 更新监控状态 + periodictask_obj.enabled = True if enabled == "1" else False + periodictask_obj.save() + + # 更新 定时清理多余 系统监控信息 状态 + clean_task_obj = PeriodicTask.objects.filter( + task='apps.vadmin.monitor.tasks.clean_surplus_monitor_info').first() + clean_task_obj.enabled = True if enabled == "1" else False + clean_task_obj.save() + # 更新保留天数 + config_obj = ConfigSettings.objects.filter(configKey='sys.monitor.info.save_days').first() + print(33, save_days) + print(22, config_obj) + if save_days and config_obj: + config_obj.configValue = save_days + config_obj.save() + # 更新监控获取频率 + if interval: + periodictask_obj.interval.every = interval + periodictask_obj.interval.save() + return SuccessResponse(data={ + "enabled": periodictask_obj.enabled, + "interval": periodictask_obj.interval.every, + "save_days": config_obj.configValue if config_obj else "30", + }) + + def clean_all(self, request: Request, *args, **kwargs): + """ + 清空监控信息 + :param request: + :param args: + :param kwargs: + :return: + """ + self.get_queryset().delete() + return SuccessResponse(msg="清空成功") diff --git a/dvadmin-backend/requirements.txt b/dvadmin-backend/requirements.txt index 5e06ebc..2ea4f69 100644 --- a/dvadmin-backend/requirements.txt +++ b/dvadmin-backend/requirements.txt @@ -26,3 +26,4 @@ xlrd==2.0.1 coreapi==2.3.3 user-agents==2.2.0 eventlet==0.30.2 +psutil==5.8.0 From 4a8024d8100ac67fa6a8ffbed824b180dd7a1d12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Sat, 17 Apr 2021 10:11:33 +0800 Subject: [PATCH 08/21] =?UTF-8?q?=E9=87=8D=E6=9E=84(=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=AE=A1=E7=90=86):=20=E8=8E=B7=E5=8F=96=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=EF=BC=9AUserProfile=20=3D=20get=5Fuser=5Fmod?= =?UTF-8?q?el()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvadmin-backend/apps/vadmin/op_drf/models.py | 3 ++- dvadmin-backend/apps/vadmin/permission/filters.py | 5 ++++- dvadmin-backend/apps/vadmin/permission/models/users.py | 2 ++ dvadmin-backend/apps/vadmin/permission/serializers.py | 5 ++++- dvadmin-backend/apps/vadmin/permission/views.py | 6 ++++-- dvadmin-backend/apps/vadmin/system/models/message_push.py | 3 ++- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/dvadmin-backend/apps/vadmin/op_drf/models.py b/dvadmin-backend/apps/vadmin/op_drf/models.py index 1eead22..2bffdeb 100644 --- a/dvadmin-backend/apps/vadmin/op_drf/models.py +++ b/dvadmin-backend/apps/vadmin/op_drf/models.py @@ -1,3 +1,4 @@ +from django.conf import settings from django.db import models from django.db.models import SET_NULL @@ -24,7 +25,7 @@ class CoreModel(models.Model): 增加审计字段, 覆盖字段时, 字段名称请勿修改, 必须统一审计字段名称 """ description = DescriptionField() # 描述 - creator = models.ForeignKey(to='permission.UserProfile', related_query_name='creator_query', null=True, + creator = models.ForeignKey(to=settings.AUTH_USER_MODEL, related_query_name='creator_query', null=True, verbose_name='创建者', on_delete=SET_NULL, db_constraint=False) # 创建者 modifier = ModifierCharField() # 修改者 dept_belong_id = models.CharField(max_length=64, verbose_name="数据归属部门", null=True, blank=True) diff --git a/dvadmin-backend/apps/vadmin/permission/filters.py b/dvadmin-backend/apps/vadmin/permission/filters.py index bf302b1..8f8d8da 100644 --- a/dvadmin-backend/apps/vadmin/permission/filters.py +++ b/dvadmin-backend/apps/vadmin/permission/filters.py @@ -1,8 +1,11 @@ import django_filters +from django.contrib.auth import get_user_model -from ..permission.models import Menu, Dept, Post, Role, UserProfile +from ..permission.models import Menu, Dept, Post, Role from ..utils.model_util import get_dept +UserProfile = get_user_model() + class MenuFilter(django_filters.rest_framework.FilterSet): """ diff --git a/dvadmin-backend/apps/vadmin/permission/models/users.py b/dvadmin-backend/apps/vadmin/permission/models/users.py index e609a2a..fb1818e 100644 --- a/dvadmin-backend/apps/vadmin/permission/models/users.py +++ b/dvadmin-backend/apps/vadmin/permission/models/users.py @@ -1,5 +1,6 @@ from uuid import uuid4 +from django.conf import settings from django.contrib.auth.models import UserManager, AbstractUser from django.core.cache import cache from django.db.models import IntegerField, ForeignKey, CharField, TextField, ManyToManyField, CASCADE @@ -51,6 +52,7 @@ class UserProfile(AbstractUser, CoreModel): return cache.delete(f'permission_interface_dict_{self.username}') class Meta: + abstract = settings.AUTH_USER_MODEL != 'permission.UserProfile' verbose_name = '用户管理' verbose_name_plural = verbose_name diff --git a/dvadmin-backend/apps/vadmin/permission/serializers.py b/dvadmin-backend/apps/vadmin/permission/serializers.py index 8fc641e..ac82342 100644 --- a/dvadmin-backend/apps/vadmin/permission/serializers.py +++ b/dvadmin-backend/apps/vadmin/permission/serializers.py @@ -1,10 +1,13 @@ +from django.contrib.auth import get_user_model from rest_framework import serializers from rest_framework.validators import UniqueValidator from ..op_drf.serializers import CustomModelSerializer -from ..permission.models import Menu, Dept, Post, Role, UserProfile +from ..permission.models import Menu, Dept, Post, Role from ..system.models import MessagePush +UserProfile = get_user_model() + # ================================================= # # ************** 菜单管理 序列化器 ************** # diff --git a/dvadmin-backend/apps/vadmin/permission/views.py b/dvadmin-backend/apps/vadmin/permission/views.py index 8ece4fa..f11def9 100644 --- a/dvadmin-backend/apps/vadmin/permission/views.py +++ b/dvadmin-backend/apps/vadmin/permission/views.py @@ -1,4 +1,4 @@ -from django.contrib.auth import authenticate +from django.contrib.auth import authenticate, get_user_model from rest_framework.request import Request from rest_framework.views import APIView @@ -6,7 +6,7 @@ from .permissions import CommonPermission, DeptDestroyPermission from ..op_drf.filters import DataLevelPermissionsFilter from ..op_drf.viewsets import CustomModelViewSet from ..permission.filters import MenuFilter, DeptFilter, PostFilter, RoleFilter, UserProfileFilter -from ..permission.models import Role, Menu, Dept, Post, UserProfile +from ..permission.models import Role, Menu, Dept, Post from ..permission.serializers import UserProfileSerializer, MenuSerializer, RoleSerializer, \ MenuCreateUpdateSerializer, DeptSerializer, DeptCreateUpdateSerializer, PostSerializer, PostCreateUpdateSerializer, \ RoleCreateUpdateSerializer, DeptTreeSerializer, MenuTreeSerializer, UserProfileCreateUpdateSerializer, \ @@ -15,6 +15,8 @@ from ..permission.serializers import UserProfileSerializer, MenuSerializer, Role from ..system.models import DictDetails from ..utils.response import SuccessResponse, ErrorResponse +UserProfile = get_user_model() + class GetUserProfileView(APIView): """ diff --git a/dvadmin-backend/apps/vadmin/system/models/message_push.py b/dvadmin-backend/apps/vadmin/system/models/message_push.py index efbde44..04ad68e 100644 --- a/dvadmin-backend/apps/vadmin/system/models/message_push.py +++ b/dvadmin-backend/apps/vadmin/system/models/message_push.py @@ -1,10 +1,11 @@ +from django.contrib.auth import get_user_model from django.db import models from django.db.models import * from ...op_drf.fields import UpdateDateTimeField, CreateDateTimeField from ...op_drf.models import CoreModel -from ...permission.models import UserProfile +UserProfile = get_user_model() """ 消息通知模型 """ From 6f1c26061a8cf73dd760dd46e4551a36b887d25b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Sat, 17 Apr 2021 10:17:41 +0800 Subject: [PATCH 09/21] =?UTF-8?q?=E9=87=8D=E6=9E=84(=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E7=AE=A1=E7=90=86):=20=E8=8E=B7=E5=8F=96=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B=EF=BC=9AUserProfile=20=3D=20get=5Fuser=5Fmod?= =?UTF-8?q?el()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvadmin-backend/apps/vadmin/system/models/message_push.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/dvadmin-backend/apps/vadmin/system/models/message_push.py b/dvadmin-backend/apps/vadmin/system/models/message_push.py index 04ad68e..37bc089 100644 --- a/dvadmin-backend/apps/vadmin/system/models/message_push.py +++ b/dvadmin-backend/apps/vadmin/system/models/message_push.py @@ -1,11 +1,10 @@ -from django.contrib.auth import get_user_model +from django.conf import settings from django.db import models from django.db.models import * from ...op_drf.fields import UpdateDateTimeField, CreateDateTimeField from ...op_drf.models import CoreModel -UserProfile = get_user_model() """ 消息通知模型 """ @@ -18,7 +17,7 @@ class MessagePush(CoreModel): is_reviewed = BooleanField(default=True, verbose_name="是否审核") status = CharField(max_length=8, verbose_name="通知状态") to_path = CharField(max_length=256, verbose_name="跳转路径", null=True, blank=True, ) - user = ManyToManyField(to="permission.UserProfile", + user = ManyToManyField(to=settings.AUTH_USER_MODEL, related_name="user", related_query_name="user_query", through='MessagePushUser', through_fields=('message_push', 'user')) @@ -35,7 +34,7 @@ class MessagePushUser(models.Model): related_name="messagepushuser_message_push", verbose_name='消息通知', help_text='消息通知') - user = ForeignKey(UserProfile, on_delete=CASCADE, db_constraint=False, + user = ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=CASCADE, db_constraint=False, related_name="messagepushuser_user", verbose_name='用户', help_text='用户') is_read = BooleanField(default=False, verbose_name="是否已读") From fcd6e85ea6fceaff8c95d80904cc0b14af6fda8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Sat, 17 Apr 2021 11:30:14 +0800 Subject: [PATCH 10/21] =?UTF-8?q?=E6=80=A7=E8=83=BD=E6=8F=90=E5=8D=87(?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=AE=A1=E7=90=86):=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E9=87=8D=E5=86=99=E7=94=A8=E6=88=B7=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 在settings.py 中 AUTH_USER_MODEL 为重写的 user位置 2. 继承 from apps.vadmin.permission.models import UserProfile 写自己的用户模型 3. 需要注意,自己重写的用户模型不能有必填字段 --- dvadmin-backend/apps/vadmin/monitor/models/monitor.py | 2 +- dvadmin-backend/apps/vadmin/monitor/models/sys_files.py | 2 +- .../apps/vadmin/permission/management/commands/init.py | 5 +++-- dvadmin-backend/apps/vadmin/permission/models/dept.py | 2 +- dvadmin-backend/apps/vadmin/permission/models/role.py | 4 ++-- dvadmin-backend/apps/vadmin/permission/models/users.py | 6 +++--- dvadmin-backend/apps/vadmin/scripts/__init__.py | 8 +++++++- dvadmin-backend/apps/vadmin/system/models/dict_details.py | 2 +- 8 files changed, 19 insertions(+), 12 deletions(-) diff --git a/dvadmin-backend/apps/vadmin/monitor/models/monitor.py b/dvadmin-backend/apps/vadmin/monitor/models/monitor.py index 121ec8c..7cf2bb5 100644 --- a/dvadmin-backend/apps/vadmin/monitor/models/monitor.py +++ b/dvadmin-backend/apps/vadmin/monitor/models/monitor.py @@ -9,7 +9,7 @@ class Monitor(CoreModel): mem_num = CharField(max_length=32, verbose_name='内存总数(KB)') mem_sys = CharField(max_length=32, verbose_name='内存已使用大小(KB)') seconds = CharField(max_length=32, verbose_name='系统已运行时间') - server = ForeignKey(to='Server', on_delete=CASCADE, verbose_name="关联服务器信息", db_constraint=False) + server = ForeignKey(to='monitor.Server', on_delete=CASCADE, verbose_name="关联服务器信息", db_constraint=False) class Meta: verbose_name = '服务器监控信息' diff --git a/dvadmin-backend/apps/vadmin/monitor/models/sys_files.py b/dvadmin-backend/apps/vadmin/monitor/models/sys_files.py index a7ce4e1..41557cf 100644 --- a/dvadmin-backend/apps/vadmin/monitor/models/sys_files.py +++ b/dvadmin-backend/apps/vadmin/monitor/models/sys_files.py @@ -9,7 +9,7 @@ class SysFiles(CoreModel): type_name = CharField(max_length=32, verbose_name='盘符类型') total = CharField(max_length=32, verbose_name='磁盘总大小(KB)') disk_sys = CharField(max_length=32, verbose_name='已使用大小(KB)') - monitor = ForeignKey(to='Monitor', on_delete=CASCADE, verbose_name="关联服务器监控信息", db_constraint=False) + monitor = ForeignKey(to='monitor.Monitor', on_delete=CASCADE, verbose_name="关联服务器监控信息", db_constraint=False) class Meta: verbose_name = '系统磁盘' diff --git a/dvadmin-backend/apps/vadmin/permission/management/commands/init.py b/dvadmin-backend/apps/vadmin/permission/management/commands/init.py index f749f31..3db4d21 100644 --- a/dvadmin-backend/apps/vadmin/permission/management/commands/init.py +++ b/dvadmin-backend/apps/vadmin/permission/management/commands/init.py @@ -1,6 +1,7 @@ import logging import os +from django.conf import settings from django.core.management.base import BaseCommand from django.db import connection @@ -75,6 +76,7 @@ class Command(BaseCommand): parser.add_argument('-N', nargs='*') def handle(self, *args, **options): + user_name = "_".join(settings.AUTH_USER_MODEL.lower().split(".")) init_dict = { 'system_dictdata': [os.path.join('system', 'system_dictdata.sql'), '字典管理', 'system_dictdata'], 'system_dictdetails': [os.path.join('system', 'system_dictdetails.sql'), '字典详情', 'system_dictdetails'], @@ -86,8 +88,7 @@ class Command(BaseCommand): 'permission_role': [os.path.join('permission', 'permission_role.sql'), '角色管理', ','.join(['permission_role', 'permission_role_dept', 'permission_role_menu'])], 'permission_userprofile': [os.path.join('permission', 'permission_userprofile.sql'), '用户管理', ','.join( - ['permission_userprofile_groups', 'permission_userprofile', 'permission_userprofile_role', - 'permission_userprofile_post'])] + [f'{user_name}_groups', f'{user_name}', f'{user_name}_role', f'{user_name}_post'])] } init_name = options.get('init_name') is_yes = None diff --git a/dvadmin-backend/apps/vadmin/permission/models/dept.py b/dvadmin-backend/apps/vadmin/permission/models/dept.py index f8b6631..a339650 100644 --- a/dvadmin-backend/apps/vadmin/permission/models/dept.py +++ b/dvadmin-backend/apps/vadmin/permission/models/dept.py @@ -11,7 +11,7 @@ class Dept(CoreModel): phone = CharField(max_length=32, verbose_name="联系电话", null=True, blank=True) email = CharField(max_length=32, verbose_name="邮箱", null=True, blank=True) status = CharField(max_length=8, verbose_name="部门状态", null=True, blank=True) - parentId = ForeignKey(to='Dept', on_delete=CASCADE, default=False, verbose_name="上级部门", + parentId = ForeignKey(to='permission.Dept', on_delete=CASCADE, default=False, verbose_name="上级部门", db_constraint=False, null=True, blank=True) class Meta: diff --git a/dvadmin-backend/apps/vadmin/permission/models/role.py b/dvadmin-backend/apps/vadmin/permission/models/role.py index dffa586..d34b91e 100644 --- a/dvadmin-backend/apps/vadmin/permission/models/role.py +++ b/dvadmin-backend/apps/vadmin/permission/models/role.py @@ -18,8 +18,8 @@ class Role(CoreModel): admin = BooleanField(default=False, verbose_name="是否为admin") dataScope = CharField(max_length=8,default='1', choices=DATASCOPE_CHOICES, verbose_name="权限范围",) remark = TextField(verbose_name="备注", help_text="备注", null=True, blank=True) - dept = ManyToManyField(to='Dept', verbose_name='数据权限-关联部门', db_constraint=False) - menu = ManyToManyField(to='Menu', verbose_name='关联菜单权限', db_constraint=False) + dept = ManyToManyField(to='permission.Dept', verbose_name='数据权限-关联部门', db_constraint=False) + menu = ManyToManyField(to='permission.Menu', verbose_name='关联菜单权限', db_constraint=False) class Meta: verbose_name = '角色管理' diff --git a/dvadmin-backend/apps/vadmin/permission/models/users.py b/dvadmin-backend/apps/vadmin/permission/models/users.py index fb1818e..59ef52e 100644 --- a/dvadmin-backend/apps/vadmin/permission/models/users.py +++ b/dvadmin-backend/apps/vadmin/permission/models/users.py @@ -23,9 +23,9 @@ class UserProfile(AbstractUser, CoreModel): gender = CharField(max_length=8, verbose_name="性别", null=True, blank=True) remark = TextField(verbose_name="备注", null=True) user_type = IntegerField(default=0, verbose_name="用户类型") - post = ManyToManyField(to='Post', verbose_name='关联岗位', db_constraint=False) - role = ManyToManyField(to='Role', verbose_name='关联角色', db_constraint=False) - dept = ForeignKey(to='Dept', verbose_name='归属部门', on_delete=CASCADE, db_constraint=False, null=True, blank=True) + post = ManyToManyField(to='permission.Post', verbose_name='关联岗位', db_constraint=False) + role = ManyToManyField(to='permission.Role', verbose_name='关联角色', db_constraint=False) + dept = ForeignKey(to='permission.Dept', verbose_name='归属部门', on_delete=CASCADE, db_constraint=False, null=True, blank=True) @property def get_user_interface_dict(self): diff --git a/dvadmin-backend/apps/vadmin/scripts/__init__.py b/dvadmin-backend/apps/vadmin/scripts/__init__.py index fd9177f..e0d0cfa 100644 --- a/dvadmin-backend/apps/vadmin/scripts/__init__.py +++ b/dvadmin-backend/apps/vadmin/scripts/__init__.py @@ -1,5 +1,7 @@ import os +from django.conf import settings + def getSql(filename): """ @@ -9,6 +11,10 @@ def getSql(filename): """ abspath = os.path.abspath(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..")) pwd = os.path.join(abspath, 'scripts', filename) - with open(pwd,'rb') as fp: + with open(pwd, 'rb') as fp: content = fp.read().decode('utf8') + if filename == "permission/permission_userprofile.sql": + user_name = "_".join(settings.AUTH_USER_MODEL.lower().split(".")) + content = content.replace("permission_userprofile", user_name). \ + replace("userprofile", settings.AUTH_USER_MODEL.lower().split(".")[-1]) return [ele for ele in content.split('\n') if not ele.startswith('--') and ele.strip(' ')] diff --git a/dvadmin-backend/apps/vadmin/system/models/dict_details.py b/dvadmin-backend/apps/vadmin/system/models/dict_details.py index 1db9b5c..8cf18ac 100644 --- a/dvadmin-backend/apps/vadmin/system/models/dict_details.py +++ b/dvadmin-backend/apps/vadmin/system/models/dict_details.py @@ -9,7 +9,7 @@ class DictDetails(CoreModel): is_default = BooleanField(verbose_name="是否默认", default=False) status = CharField(max_length=2, verbose_name="字典状态") sort = CharField(max_length=256, verbose_name="字典排序") - dict_data = ForeignKey(to='DictData', on_delete=CASCADE, verbose_name="关联字典", db_constraint=False) + dict_data = ForeignKey(to='system.DictData', on_delete=CASCADE, verbose_name="关联字典", db_constraint=False) remark = CharField(max_length=256, verbose_name="备注", null=True, blank=True) @classmethod From 9bfac232fe3e591d4aab162d3d384fe537d9de65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Sun, 18 Apr 2021 17:53:24 +0800 Subject: [PATCH 11/21] =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG(docker=20=E9=83=A8?= =?UTF-8?q?=E7=BD=B2):=20=E5=89=8D=E7=AB=AF=E6=B2=A1=E6=9C=89=E5=BC=80?= =?UTF-8?q?=E6=94=BE=E7=AB=AF=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index fb3d0fd..ce8ee27 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -8,6 +8,8 @@ version: "3" services: dvadmin-ui: container_name: dvadmin-ui + ports: + - "8080:8080" build: context: ./ dockerfile: ./docker_env/vue-ui/Dockerfile From f804d45bed821685bb9ecf86656163fd0516ae82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Wed, 21 Apr 2021 00:24:25 +0800 Subject: [PATCH 12/21] =?UTF-8?q?=E6=96=B0=E5=8A=9F=E8=83=BD(=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E7=9B=91=E6=8E=A7API):=20=E6=9C=8D=E5=8A=A1=E7=9B=91?= =?UTF-8?q?=E6=8E=A7API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apps/vadmin/monitor/serializers.py | 13 ++- dvadmin-backend/apps/vadmin/monitor/urls.py | 3 +- dvadmin-backend/apps/vadmin/monitor/views.py | 98 +++++++++++++++---- 3 files changed, 91 insertions(+), 23 deletions(-) diff --git a/dvadmin-backend/apps/vadmin/monitor/serializers.py b/dvadmin-backend/apps/vadmin/monitor/serializers.py index 3a7e0bd..69d789e 100644 --- a/dvadmin-backend/apps/vadmin/monitor/serializers.py +++ b/dvadmin-backend/apps/vadmin/monitor/serializers.py @@ -13,7 +13,18 @@ class ServerSerializer(CustomModelSerializer): class Meta: model = Server - fields = '__all__' + fields = ("id", "ip", "name", "os", "remark") + + +class UpdateServerSerializer(CustomModelSerializer): + """ + 服务器信息 简单序列化器 + """ + + class Meta: + model = Server + fields = ("name", "remark") + # ================================================= # # ************** 服务器监控信息 序列化器 ************** # diff --git a/dvadmin-backend/apps/vadmin/monitor/urls.py b/dvadmin-backend/apps/vadmin/monitor/urls.py index c5ef2fa..49feeef 100644 --- a/dvadmin-backend/apps/vadmin/monitor/urls.py +++ b/dvadmin-backend/apps/vadmin/monitor/urls.py @@ -8,7 +8,8 @@ router.register(r'server', ServerModelViewSet) router.register(r'monitor', MonitorModelViewSet) urlpatterns = [ - re_path('monitor/info/', MonitorModelViewSet.as_view({'get': 'get_monitor_info'})), + re_path('monitor/info/(?P.*)/', MonitorModelViewSet.as_view({'get': 'get_monitor_info'})), + re_path('monitor/rate/(?P.*)/', MonitorModelViewSet.as_view({'get': 'get_rate_info'})), re_path('monitor/enabled/', MonitorModelViewSet.as_view({'get': 'enabled_monitor_info'})), re_path('monitor/clean/', MonitorModelViewSet.as_view({'get': 'clean_all'})), ] diff --git a/dvadmin-backend/apps/vadmin/monitor/views.py b/dvadmin-backend/apps/vadmin/monitor/views.py index 9325852..67e2861 100644 --- a/dvadmin-backend/apps/vadmin/monitor/views.py +++ b/dvadmin-backend/apps/vadmin/monitor/views.py @@ -2,9 +2,9 @@ from django_celery_beat.models import PeriodicTask, IntervalSchedule, CrontabSch from rest_framework.request import Request from .filters import ServerFilter, MonitorFilter -from .models import Server, Monitor -from .serializers import ServerSerializer, MonitorSerializer -from ..op_drf.response import SuccessResponse +from .models import Server, Monitor, SysFiles +from .serializers import ServerSerializer, MonitorSerializer, UpdateServerSerializer +from ..op_drf.response import SuccessResponse, ErrorResponse from ..op_drf.viewsets import CustomModelViewSet from ..permission.permissions import CommonPermission from ..system.models import ConfigSettings @@ -16,6 +16,7 @@ class ServerModelViewSet(CustomModelViewSet): """ queryset = Server.objects.all() serializer_class = ServerSerializer + update_serializer_class = UpdateServerSerializer # extra_filter_backends = [DataLevelPermissionsFilter] filter_class = ServerFilter update_extra_permission_classes = (CommonPermission,) @@ -37,7 +38,80 @@ class MonitorModelViewSet(CustomModelViewSet): create_extra_permission_classes = (CommonPermission,) ordering = '-create_datetime' # 默认排序 + def get_rate_info(self, request: Request, *args, **kwargs): + """ + 获取使用率 监控信息 + :param request: + :param args: + :param kwargs: + :return: + """ + pk = kwargs.get("pk") + queryset = self.filter_queryset(self.get_queryset()) + queryset = queryset.filter(server__id=pk).order_by("-create_datetime") + # 间隔取值 + queryset_count = queryset.count() + Interval_num = 1 if queryset_count < 200 else int(queryset_count / 100) + queryset = queryset.values('cpu_sys', 'mem_num', 'mem_sys')[::Interval_num][:100] + data = { + "cpu": [], + "memory": [], + } + for ele in queryset: + data["cpu"].append(float(ele.get('cpu_sys', 0))) + data["memory"].append(float(ele.get('mem_num', 0)) and round(float(ele.get('mem_sys', 0)) / + float(ele.get('mem_num', 0)), 4)) + return SuccessResponse(data=data) + def get_monitor_info(self, request: Request, *args, **kwargs): + """ + 最新的服务器状态信息 + :param request: + :param args: + :param kwargs: + :return: + """ + pk = kwargs.get("pk") + instance = Monitor.objects.filter(server__id=pk).order_by("-create_datetime").first() + if not instance: + return ErrorResponse(msg="未找到服务器信息id") + serializer = self.get_serializer(instance) + data = serializer.data + return SuccessResponse(data={ + "cpu": { + "total": int(data.get('cpu_num'), 0), + "used": "", # cpu核心 可不传,如指cpu当前主频,该值可以传 + "rate": float(data.get('cpu_sys', 0)), + "unit": "核心", # 默认单位 核心 + }, + "memory": { + "total": int(int(data.get('mem_num', 0)) / 1024), + "used": int(int(data.get('mem_sys', 0)) / 1024), + "rate": int(data.get('mem_num', 0)) and round(int(data.get('mem_sys', 0)) / + int(data.get('mem_num', 0)), 4), + "unit": "MB", # 默认单位 MB + }, + "disk": [{ + "dir_name": ele.get('dir_name'), + "total": int(int(ele.get('total', 0)) / 1024 / 1024 / 1024), + "used": int(int(ele.get('disk_sys', 0)) / 1024 / 1024 / 1024), + "rate": int(ele.get('total', 0)) and round(int(ele.get('disk_sys', 0)) / int(ele.get('total', 0)), + 4), + "unit": "GB", # 默认单位 GB + } for ele in SysFiles.objects.filter(monitor=instance).values('dir_name', 'total', 'disk_sys')] + }) + + def enabled_monitor_info(self, request: Request, *args, **kwargs): + """ + 更新和获取监控信息 + :param request: + :param args: + :param kwargs: + :return: + """ + enabled = request.query_params.get('enabled', None) + save_days = request.query_params.get('save_days', None) + interval = request.query_params.get('interval', None) # 定时获取系统监控信息 periodictask_obj = PeriodicTask.objects.filter(task='apps.vadmin.monitor.tasks.get_monitor_info').first() if not periodictask_obj: @@ -73,33 +147,15 @@ class MonitorModelViewSet(CustomModelViewSet): config_obj.remark = "定时清理多余-系统监控信息,默认30天" config_obj.save() - # 获取保留天数 - return SuccessResponse(data={ - "enabled": periodictask_obj.enabled, - "interval": periodictask_obj.interval.every, - "save_days": config_obj.configValue if config_obj else "30", - }) - - def enabled_monitor_info(self, request: Request, *args, **kwargs): - enabled = request.query_params.get('enabled', None) - save_days = request.query_params.get('save_days', None) - interval = request.query_params.get('interval', None) - - periodictask_obj = PeriodicTask.objects.filter(task='apps.vadmin.monitor.tasks.get_monitor_info').first() if enabled: # 更新监控状态 periodictask_obj.enabled = True if enabled == "1" else False periodictask_obj.save() # 更新 定时清理多余 系统监控信息 状态 - clean_task_obj = PeriodicTask.objects.filter( - task='apps.vadmin.monitor.tasks.clean_surplus_monitor_info').first() clean_task_obj.enabled = True if enabled == "1" else False clean_task_obj.save() # 更新保留天数 - config_obj = ConfigSettings.objects.filter(configKey='sys.monitor.info.save_days').first() - print(33, save_days) - print(22, config_obj) if save_days and config_obj: config_obj.configValue = save_days config_obj.save() From d7a7e09099627afc9f7e04ba62856135890f8bce Mon Sep 17 00:00:00 2001 From: xt12321 <1499410095@qq.com> Date: Sat, 24 Apr 2021 11:02:12 +0800 Subject: [PATCH 13/21] =?UTF-8?q?=E6=96=B0=E5=8A=9F=E8=83=BD(=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E7=9B=91=E6=8E=A7):=20=E6=96=B0=E5=A2=9E=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E7=9B=91=E6=8E=A7=E5=8A=9F=E8=83=BD=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvadmin-ui/package.json | 6 +- dvadmin-ui/src/api/vadmin/menu.js | 2 +- dvadmin-ui/src/api/vadmin/monitor/server.js | 64 +- dvadmin-ui/src/store/modules/permission.js | 19 +- .../server/components/InstrumentBoard.vue | 150 ++++ .../monitor/server/components/LineChart.vue | 183 +++++ .../src/views/vadmin/monitor/server/index.vue | 675 +++++++++++++----- 7 files changed, 910 insertions(+), 189 deletions(-) create mode 100644 dvadmin-ui/src/views/vadmin/monitor/server/components/InstrumentBoard.vue create mode 100644 dvadmin-ui/src/views/vadmin/monitor/server/components/LineChart.vue diff --git a/dvadmin-ui/package.json b/dvadmin-ui/package.json index beaf7ec..f27a1ff 100755 --- a/dvadmin-ui/package.json +++ b/dvadmin-ui/package.json @@ -41,14 +41,16 @@ "axios": "0.21.0", "clipboard": "2.0.6", "core-js": "3.8.1", - "echarts": "4.9.0", + "echarts": "^4.9.0", "element-ui": "2.15.0", + "eslint-loader": "^4.0.2", "file-saver": "2.0.4", "fuse.js": "6.4.3", "highlight.js": "9.18.5", "js-beautify": "1.13.0", "js-cookie": "2.2.1", "jsencrypt": "3.0.0-rc.1", + "lodash": "^4.17.21", "moment": "^2.29.1", "nprogress": "0.2.0", "quill": "1.3.7", @@ -58,6 +60,7 @@ "vue-count-to": "1.0.13", "vue-cropper": "0.5.5", "vue-router": "3.4.9", + "vue-types": "^2.0.3", "vuedraggable": "2.24.3", "vuex": "3.6.0" }, @@ -65,6 +68,7 @@ "@vue/cli-plugin-babel": "4.4.6", "@vue/cli-plugin-eslint": "4.4.6", "@vue/cli-service": "4.4.6", + "@vue/composition-api": "^1.0.0-rc.6", "babel-eslint": "10.1.0", "chalk": "4.1.0", "connect": "3.6.6", diff --git a/dvadmin-ui/src/api/vadmin/menu.js b/dvadmin-ui/src/api/vadmin/menu.js index 9fc5b52..205e8dd 100755 --- a/dvadmin-ui/src/api/vadmin/menu.js +++ b/dvadmin-ui/src/api/vadmin/menu.js @@ -3,7 +3,7 @@ import request from '@/utils/request' // 获取路由 export const getRouters = () => { return request({ - url: '/admin/getRouters', + url: '/admin/getRouters/', method: 'get' }) } diff --git a/dvadmin-ui/src/api/vadmin/monitor/server.js b/dvadmin-ui/src/api/vadmin/monitor/server.js index feed783..2b959d9 100755 --- a/dvadmin-ui/src/api/vadmin/monitor/server.js +++ b/dvadmin-ui/src/api/vadmin/monitor/server.js @@ -1,9 +1,65 @@ import request from '@/utils/request' -// 查询服务器详细 -export function getServer() { +// 查询服务器信息详细 +export function getServerList(params) { return request({ - url: '/monitor/server', + url: 'admin/monitor/server/', + params, method: 'get' }) -} \ No newline at end of file +} + +// 修改服务器信息 +export function updateServerInfo(id, data) { + let {name, remark} = data; + return request({ + url: `admin/monitor/server/${id}/`, + data: { + name, + remark + }, + method: 'PUT' + }) +} + +// 获取监控配置信息 +export function getMonitorStatusInfo() { + return request({ + url: 'admin/monitor/monitor/enabled/', + method: 'get' + }) +} + +// 更新监控配置信息 +export function updateMonitorStatusInfo(params) { + return request({ + url: 'admin/monitor/monitor/enabled/', + params, + method: 'get' + }) +} + +// 清空记录 +export function cleanMonitorLog() { + return request({ + url: 'admin/monitor/monitor/clean/', + method: 'delete' + }) +} + +// 获取监控记录 +export function getMonitorLogs(id, params) { + return request({ + url: `admin/monitor/monitor/${id}/`, + params, + method: 'get' + }) +} + +// 获取服务器最新监控日志信息 +export function getServerLatestLog(id) { + return request({ + url: `admin/monitor/monitor/info/${id}/`, + method: 'get' + }) +} diff --git a/dvadmin-ui/src/store/modules/permission.js b/dvadmin-ui/src/store/modules/permission.js index 00d4194..3be95be 100755 --- a/dvadmin-ui/src/store/modules/permission.js +++ b/dvadmin-ui/src/store/modules/permission.js @@ -24,11 +24,28 @@ const permission = { return new Promise(resolve => { // 向后端请求路由数据 getRouters().then(res => { - const data = handleTree(res.data, "id"); + let tempData = handleTree(res.data, "id"); + tempData[2].children.push({ + component: "vadmin/monitor/server/index", + hidden: false, + id: 97, + meta: {title: "服务监控", icon: "server", noCache: false}, + name: "server", + orderNum: 3, + parentId: 66, + path: "server", + redirect: "server" + }) + const data = tempData + + + // console.log("handleTree:", data) const sdata = JSON.parse(JSON.stringify(data)) const rdata = JSON.parse(JSON.stringify(data)) const sidebarRoutes = filterAsyncRouter(sdata) + // console.log(sidebarRoutes) const rewriteRoutes = filterAsyncRouter(rdata, false, true) + // console.log(rewriteRoutes) rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) commit('SET_ROUTES', rewriteRoutes) commit('SET_SIDEBAR_ROUTERS', sidebarRoutes) diff --git a/dvadmin-ui/src/views/vadmin/monitor/server/components/InstrumentBoard.vue b/dvadmin-ui/src/views/vadmin/monitor/server/components/InstrumentBoard.vue new file mode 100644 index 0000000..5bbe83e --- /dev/null +++ b/dvadmin-ui/src/views/vadmin/monitor/server/components/InstrumentBoard.vue @@ -0,0 +1,150 @@ + + + + + diff --git a/dvadmin-ui/src/views/vadmin/monitor/server/components/LineChart.vue b/dvadmin-ui/src/views/vadmin/monitor/server/components/LineChart.vue new file mode 100644 index 0000000..0dedd16 --- /dev/null +++ b/dvadmin-ui/src/views/vadmin/monitor/server/components/LineChart.vue @@ -0,0 +1,183 @@ + + + + + diff --git a/dvadmin-ui/src/views/vadmin/monitor/server/index.vue b/dvadmin-ui/src/views/vadmin/monitor/server/index.vue index 5a35767..684e4db 100755 --- a/dvadmin-ui/src/views/vadmin/monitor/server/index.vue +++ b/dvadmin-ui/src/views/vadmin/monitor/server/index.vue @@ -1,210 +1,521 @@ + From 2efe41347b9c3847d3fb66abdd85ecc015af82a0 Mon Sep 17 00:00:00 2001 From: xt12321 <1499410095@qq.com> Date: Sat, 24 Apr 2021 11:58:41 +0800 Subject: [PATCH 14/21] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=98=E5=8C=96(?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=9B=91=E6=8E=A7):=20=E7=9B=91=E6=8E=A7?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E6=8E=A5=E5=8F=A3=E8=B0=83=E6=95=B4=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvadmin-ui/src/api/vadmin/monitor/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dvadmin-ui/src/api/vadmin/monitor/server.js b/dvadmin-ui/src/api/vadmin/monitor/server.js index 2b959d9..e25be29 100755 --- a/dvadmin-ui/src/api/vadmin/monitor/server.js +++ b/dvadmin-ui/src/api/vadmin/monitor/server.js @@ -50,7 +50,7 @@ export function cleanMonitorLog() { // 获取监控记录 export function getMonitorLogs(id, params) { return request({ - url: `admin/monitor/monitor/${id}/`, + url: `admin/monitor/monitor/rate/${id}/`, params, method: 'get' }) From b3b2d93badbc2a616aa4c5c503fffb477c4663b9 Mon Sep 17 00:00:00 2001 From: xt12321 <1499410095@qq.com> Date: Sat, 24 Apr 2021 11:59:21 +0800 Subject: [PATCH 15/21] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=98=E5=8C=96(?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=9B=91=E6=8E=A7):=20=E6=8A=98=E7=BA=BF?= =?UTF-8?q?=E5=9B=BE=E4=B8=AD=E6=97=B6=E9=97=B4=E4=BF=AE=E5=A4=8D=EF=BC=8C?= =?UTF-8?q?y=E8=BD=B4=E6=98=BE=E7=A4=BA=E5=86=85=E5=AE=B9=E8=B0=83?= =?UTF-8?q?=E6=95=B4=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/vadmin/monitor/server/components/LineChart.vue | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/dvadmin-ui/src/views/vadmin/monitor/server/components/LineChart.vue b/dvadmin-ui/src/views/vadmin/monitor/server/components/LineChart.vue index 0dedd16..e35aee1 100644 --- a/dvadmin-ui/src/views/vadmin/monitor/server/components/LineChart.vue +++ b/dvadmin-ui/src/views/vadmin/monitor/server/components/LineChart.vue @@ -26,7 +26,7 @@ import { getMonitorLogs } from '@/api/vadmin/monitor/server' const MONTH = moment().month() const YEAR = moment().year() const TODAY = moment().format('YYYY-MM-DD') -const YESTERDAY = moment().subtract(7, 'days').format('YYYY-MM-DD') +const YESTERDAY = moment().subtract(1, 'days').format('YYYY-MM-DD') const LAST_SEVEN_DAYS = moment().subtract(7, 'days').format('YYYY-MM-DD') const LAST_THIRTY_DAYS = moment().subtract(30, 'days').format('YYYY-MM-DD') @@ -129,10 +129,8 @@ export default { containLabel: true }, yAxis: { - type: 'category', - name: '百分比', - splitLine: { show: true }, - data: ['10%', '20%', '30%', '40%', '50%', '60%', '70%', '80%', '90%', '100%'] + type: 'value', + name: '使用率', }, series: [ { From 9bd51d030e865cebc58847882a5141ed755b2c2b Mon Sep 17 00:00:00 2001 From: xt12321 <1499410095@qq.com> Date: Sat, 24 Apr 2021 12:00:23 +0800 Subject: [PATCH 16/21] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=98=E5=8C=96(?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=9B=91=E6=8E=A7):=20=E6=8C=89=E9=92=AE?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0title=EF=BC=9B=E5=88=A0=E9=99=A4=E6=A8=A1?= =?UTF-8?q?=E6=8B=9F=E6=95=B0=E6=8D=AE=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/vadmin/monitor/server/index.vue | 64 ++++++++----------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/dvadmin-ui/src/views/vadmin/monitor/server/index.vue b/dvadmin-ui/src/views/vadmin/monitor/server/index.vue index 684e4db..b20b946 100755 --- a/dvadmin-ui/src/views/vadmin/monitor/server/index.vue +++ b/dvadmin-ui/src/views/vadmin/monitor/server/index.vue @@ -9,13 +9,14 @@ v-model="isOpeningMonitor" active-color="#13ce66" inactive-color="#ff4949" + title="控制所有监控项" @change="changeMonitorStatus" >
- 更新频率: + 监控频率: 更改
- 清空记录 + 清空记录 +
@@ -71,7 +78,12 @@ > - 更改 + 更改 +
@@ -176,9 +188,9 @@ const CHART_KEY_NAME_MAPPING = { // 仪表盘字段映射 const INSTRUMENT_BOARD_KEY_TO_NAME_MAPPING = { - cpu: "CPU使用率", - memory: "内存使用率", - disk: "磁盘使用率" + cpu: 'CPU使用率', + memory: '内存使用率', + disk: '磁盘使用率' } // 仪表盘颜色范围 @@ -297,8 +309,8 @@ export default { }, /**修改服务器信息*/ updateServerInfo() { - updateServerInfo(this.currentServer.id, this.currentServer).then(results => { - this.msgSuccess(results.msg || '修改服务器信息成功!') + updateServerInfo(this.currentServer.id, this.currentServer).then(() => { + this.msgSuccess('修改服务器信息成功!') }).catch(error => { this.$message.error(error.msg || '提交修改服务器信息出错!') }) @@ -306,27 +318,7 @@ export default { /** 获取服务器最新监控信息 */ getServerLatestLogInfo(serverId) { getServerLatestLog(serverId).then(results => { - // this.instrumentBoardData = results.data - this.instrumentBoardData = { - cpu: { - total: 2, - used: '', // cpu核心 可不传,如指cpu当前主频,该值可以传 - rate: 12, - unit: '核心' // 默认单位 核心 - }, - memory: { - total: 1024, - used: 512, - rate: 70, - unit: 'MB' // 默认单位 MB - }, - disk: { - total: 50, - used: 30, - rate: 90, - unit: 'GB' // 默认单位 GB - } - } + this.instrumentBoardData = results.data }).catch(error => { this.msgError(error.msg || '获取服务器最新监控信息错误!') }) @@ -334,11 +326,7 @@ export default { /** 获取监控日志信息 */ getCurrentServerMonitorLogs() { getMonitorLogs(this.currentServer.id, { as: { 'create_datetime__range': this.timeRange } }).then(results => { - // this.lineChartData = results.data - this.lineChartData = { - cpu: [0.5, 0.43, 0.56, 0.89, 0.5, 0.43, 0.56, 0.89, 0.5, 0.43, 0.56, 0.89, 0.5, 0.43, 0.56, 0.89], - memory: [0.6, 0.43, 0.56, 0.56, 0.89, 0.5, 0.43, 0.43, 0.56, 0.56, 0.5, 0.43, 0.56, 0.89, 0.5] - } + this.lineChartData = results.data }).catch(error => { this.msgError(error.msg || '获取监控日志信息出错误!') }) @@ -356,9 +344,9 @@ export default { /** 获取监控配置信息 */ getMonitorStatusSettingsInfo() { getMonitorStatusInfo().then(results => { - let { enabled, interval, save_days } = results + let { enabled, interval, save_days } = results.data this.isOpeningMonitor = enabled - this.monitorLogSavingDays = parseInt(save_days || 30) + this.monitorLogSavingDays = parseInt(save_days) this.formatInterval(parseInt(interval)) }).catch(error => { this.msgError(error.msg || '获取服务器监控配置信息出错误!') @@ -366,8 +354,8 @@ export default { }, /** 更新监控配置信息 */ updateMonitorStatusSettingsInfo() { - updateMonitorStatusInfo(this.monitorStatusInfo).then(result => { - this.msgSuccess(result.msg || '更新配置成功!') + updateMonitorStatusInfo(this.monitorStatusInfo).then(() => { + this.msgSuccess('更新配置成功!') }).catch((error) => { this.msgError(error.msg || '更新服务器监控配置信息出错误!') }) From ff5706af5301a5900d5d4030135a0fc279b8a0f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com> Date: Sat, 24 Apr 2021 12:47:28 +0800 Subject: [PATCH 17/21] =?UTF-8?q?=E6=96=B0=E5=8A=9F=E8=83=BD(=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E7=9B=91=E6=8E=A7API):=20=E6=9C=8D=E5=8A=A1=E7=9B=91?= =?UTF-8?q?=E6=8E=A7API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvadmin-backend/apps/vadmin/monitor/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dvadmin-backend/apps/vadmin/monitor/views.py b/dvadmin-backend/apps/vadmin/monitor/views.py index 67e2861..417ffc4 100644 --- a/dvadmin-backend/apps/vadmin/monitor/views.py +++ b/dvadmin-backend/apps/vadmin/monitor/views.py @@ -81,7 +81,7 @@ class MonitorModelViewSet(CustomModelViewSet): "cpu": { "total": int(data.get('cpu_num'), 0), "used": "", # cpu核心 可不传,如指cpu当前主频,该值可以传 - "rate": float(data.get('cpu_sys', 0)), + "rate": float(data.get('cpu_sys', 0)) / 100, "unit": "核心", # 默认单位 核心 }, "memory": { From 51581abe1319681220a1172298bd85968e325ce4 Mon Sep 17 00:00:00 2001 From: xt12321 <1499410095@qq.com> Date: Sat, 24 Apr 2021 15:40:33 +0800 Subject: [PATCH 18/21] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=98=E5=8C=96(inst?= =?UTF-8?q?rumentBoard):=20=E6=94=AF=E6=8C=81=E5=A4=9A=E6=9D=A1=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E9=80=89=E6=8B=A9=E6=98=BE=E7=A4=BA=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/components/InstrumentBoard.vue | 139 +++++++++++++----- .../src/views/vadmin/monitor/server/index.vue | 38 +---- 2 files changed, 109 insertions(+), 68 deletions(-) diff --git a/dvadmin-ui/src/views/vadmin/monitor/server/components/InstrumentBoard.vue b/dvadmin-ui/src/views/vadmin/monitor/server/components/InstrumentBoard.vue index 5bbe83e..9b8d182 100644 --- a/dvadmin-ui/src/views/vadmin/monitor/server/components/InstrumentBoard.vue +++ b/dvadmin-ui/src/views/vadmin/monitor/server/components/InstrumentBoard.vue @@ -1,10 +1,29 @@ @@ -14,58 +33,88 @@ import VueTypes from 'vue-types' const echarts = require('echarts/lib/echarts') require('echarts/lib/chart/gauge') +// 仪表盘颜色范围 +const NORMAL_COLOR = { + color: '#28BCFE', + itemColor: ['#25bfff', '#5284de', '#2a95f9'] +} +const WARNING_COLOR = { + color: '#e6a23c', + itemColor: ['#e6a23c', '#cc8b1d', '#ffaf18'] +} +const DANGER_COLOR = { + color: '#F56C6C', + itemColor: ['#fd666d', '#cf1717', '#b31212'] +} + export default { name: 'InstrumentBoard', props: { - // 组件唯一id - ringGraphId: VueTypes.string.isRequired, + // 组件key + ringGraphKey: VueTypes.string.isRequired, // 上标题 - topTitle: VueTypes.shape({ - show: VueTypes.bool, - text: VueTypes.string - }).def({ - show: false - }), + showTopTitle: VueTypes.bool.def(false), // 下标题 - subTitle: VueTypes.shape({ - show: VueTypes.bool, - total: VueTypes.any, - used: VueTypes.any, - unit: VueTypes.string - }).def({ - show: false - }), - // 使用率-数值 - usingRate: VueTypes.number.isRequired, - // 使用率样式配置 - usingRateStyle: VueTypes.object.def({ - color: '#28BCFE', - fontSize: 18, - itemColor: ['#25BFFF', '#5284DE', '#2A95F9'] - }), + showSubTitle: VueTypes.bool.def(false), + // top title 配置映射 topTitleKeyToNameMapping: VueTypes.object.def({ cpu: 'CPU使用率', - memory: '内存使用率', - disk: '磁盘使用率' - }) + memory: '内存使用率' + }), + instrumentBoardData: VueTypes.any.isRequired }, data() { - return {} + return { + // 当前显示的数据 + currentInstrumentBoardData: {} + } }, computed: { - subTitleContent() { - let used = this.subTitle.used ? this.subTitle.used + '/' : '' - let total = this.subTitle.total ? this.subTitle.total : '' - let unit = this.subTitle.unit ? ` (${this.subTitle.unit})` : '' - return `${used}${total}${unit} ` + // 仪表盘是否存在多个数据 + haveMultipleData() { + return this.instrumentBoardData instanceof Array && this.instrumentBoardData.length > 0 + }, + // 使用率 + ringRate() { + let ringRate = this.currentInstrumentBoardData.rate + return ringRate < 1 ? ringRate * 100 : ringRate + }, + // 仪表盘id + ringGraphId() { + return `${this.ringGraphKey}UsingRate` + }, + // 上方标题 + topTitle() { + return this.currentInstrumentBoardData['dir_name'] || this.topTitleKeyToNameMapping[this.ringGraphKey] || this.ringGraphKey + }, + // 下方标题 + subTitle() { + let used = this.currentInstrumentBoardData['used'] ? this.currentInstrumentBoardData['used'] + '/' : '' + let total = this.currentInstrumentBoardData['total'] ? this.currentInstrumentBoardData['total'] : '' + let unit = this.currentInstrumentBoardData['unit'] ? ` (${this.currentInstrumentBoardData['unit']})` : '' + let content = `${used}${total}${unit} ` + let title = (this.currentInstrumentBoardData['used'] ? '已用/' : '') + '总量(单位)' + return { content, title } + }, + // 使用率样式配置 + usingRateStyle() { + return { + fontSize: 18, + ...this.getCircleColor(this.ringRate) + } } }, mounted() { + if (this.haveMultipleData) { + this.currentInstrumentBoardData = this.instrumentBoardData[0] + } else { + this.currentInstrumentBoardData = this.instrumentBoardData + } this.drawBar() }, methods: { drawBar() { - let currentRate = [this.usingRate] + let currentRate = [this.ringRate] // 基于dom,初始化echarts实例 let RingGraph = echarts.init(document.getElementById(this.ringGraphId)) @@ -128,8 +177,24 @@ export default { } // 绘制图表 RingGraph.setOption(option) + }, + // 仪表盘样式-颜色 + getCircleColor(usingRate) { + if (usingRate < 60) { + return NORMAL_COLOR + } else if (usingRate > 60 && usingRate < 80) { + return WARNING_COLOR + } else if (usingRate > 80) { + return DANGER_COLOR + } + return NORMAL_COLOR + }, + chooseDisplayInstrumentBoardData(index) { + this.currentInstrumentBoardData = this.instrumentBoardData[index] + this.drawBar() } } + } diff --git a/dvadmin-ui/src/views/vadmin/monitor/server/index.vue b/dvadmin-ui/src/views/vadmin/monitor/server/index.vue index b20b946..35ecb3d 100755 --- a/dvadmin-ui/src/views/vadmin/monitor/server/index.vue +++ b/dvadmin-ui/src/views/vadmin/monitor/server/index.vue @@ -59,6 +59,7 @@
+
@@ -99,15 +100,15 @@ -
@@ -190,21 +191,6 @@ const CHART_KEY_NAME_MAPPING = { const INSTRUMENT_BOARD_KEY_TO_NAME_MAPPING = { cpu: 'CPU使用率', memory: '内存使用率', - disk: '磁盘使用率' -} - -// 仪表盘颜色范围 -const NORMAL_COLOR = { - color: '#28BCFE', - itemColor: ['#25bfff', '#5284de', '#2a95f9'] -} -const WARNING_COLOR = { - color: '#e6a23c', - itemColor: ['#e6a23c', '#cc8b1d', '#ffaf18'] -} -const DANGER_COLOR = { - color: '#F56C6C', - itemColor: ['#fd666d', '#cf1717', '#b31212'] } // 服务器信息可修改字段 @@ -401,16 +387,6 @@ export default { } } }, - // 仪表盘样式-颜色 - getCircleColor(usingRate) { - if (usingRate < 60) { - return NORMAL_COLOR - } else if (usingRate > 60 && usingRate < 80) { - return WARNING_COLOR - } else if (usingRate > 80) { - return DANGER_COLOR - } - } } } From 88fa332916456636413c0815e375ca9c06c793a6 Mon Sep 17 00:00:00 2001 From: xt12321 <1499410095@qq.com> Date: Sat, 24 Apr 2021 15:44:55 +0800 Subject: [PATCH 19/21] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=98=E5=8C=96(?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=9B=91=E6=8E=A7):=20=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E5=99=A8=E4=BF=A1=E6=81=AF=E5=8F=98=E6=9B=B4=E6=8F=90=E4=BA=A4?= =?UTF-8?q?=E5=90=8E=EF=BC=8C=E6=9B=B4=E6=96=B0=E6=9C=8D=E5=8A=A1=E5=99=A8?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E4=BF=A1=E6=81=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvadmin-ui/src/views/vadmin/monitor/server/index.vue | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dvadmin-ui/src/views/vadmin/monitor/server/index.vue b/dvadmin-ui/src/views/vadmin/monitor/server/index.vue index 35ecb3d..dd6c472 100755 --- a/dvadmin-ui/src/views/vadmin/monitor/server/index.vue +++ b/dvadmin-ui/src/views/vadmin/monitor/server/index.vue @@ -66,7 +66,7 @@
服务器
{ this.$message.error(error.msg || '提交修改服务器信息出错!') + }).finally(() => { + this.getServerList() }) }, /** 获取服务器最新监控信息 */ @@ -386,7 +388,7 @@ export default { this.intervalTypeUnits = interval.second } } - }, + } } } From 006d4d7a203c525da5d2b952bf682f13be74efe5 Mon Sep 17 00:00:00 2001 From: xt12321 <1499410095@qq.com> Date: Sat, 24 Apr 2021 15:58:16 +0800 Subject: [PATCH 20/21] =?UTF-8?q?=E9=87=8D=E6=9E=84(=E6=9C=8D=E5=8A=A1?= =?UTF-8?q?=E7=9B=91=E6=8E=A7):=20=E6=B8=85=E7=A9=BA=E8=AE=B0=E5=BD=95?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BA=8C=E6=AC=A1=E7=A1=AE=E8=AE=A4=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/vadmin/monitor/server/index.vue | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/dvadmin-ui/src/views/vadmin/monitor/server/index.vue b/dvadmin-ui/src/views/vadmin/monitor/server/index.vue index dd6c472..1ac0759 100755 --- a/dvadmin-ui/src/views/vadmin/monitor/server/index.vue +++ b/dvadmin-ui/src/views/vadmin/monitor/server/index.vue @@ -322,10 +322,16 @@ export default { /** 清除监控日志 */ cleanMonitorLogsInfo() { - cleanMonitorLog().then(results => { - this.msgSuccess(results.msg || '清除记录成功!') - }).catch(error => { - this.$message.warning(error.msg || '清除记录失败,请重试!') + this.$confirm('此操作将删除所有的监控记录,是否继续?', '提示', { + confirmButtonText: '确定删除', + cancelButtonText: '放弃' + }).then(() => { + cleanMonitorLog().then(results => { + this.msgSuccess(results.msg || '清除记录成功!') + }).catch(error => { + this.$message.warning(error.msg || '清除记录失败,请重试!') + }) + }).catch(() => { }) }, From cd59054432a7e2574e4ac0b215f1cbc6d723e4da Mon Sep 17 00:00:00 2001 From: xt12321 <1499410095@qq.com> Date: Sat, 24 Apr 2021 15:59:22 +0800 Subject: [PATCH 21/21] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=98=E5=8C=96(?= =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=9B=91=E6=8E=A7):=20=E6=B8=85=E7=A9=BA?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E6=88=90=E5=8A=9F=E6=97=B6=EF=BC=8C=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E4=BD=BF=E7=94=A8=E8=87=AA=E5=AE=9A=E4=B9=89=E7=9A=84?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E4=BF=A1=E6=81=AF=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dvadmin-ui/src/views/vadmin/monitor/server/index.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dvadmin-ui/src/views/vadmin/monitor/server/index.vue b/dvadmin-ui/src/views/vadmin/monitor/server/index.vue index 1ac0759..e103444 100755 --- a/dvadmin-ui/src/views/vadmin/monitor/server/index.vue +++ b/dvadmin-ui/src/views/vadmin/monitor/server/index.vue @@ -327,7 +327,7 @@ export default { cancelButtonText: '放弃' }).then(() => { cleanMonitorLog().then(results => { - this.msgSuccess(results.msg || '清除记录成功!') + this.msgSuccess( '清除记录成功!') }).catch(error => { this.$message.warning(error.msg || '清除记录失败,请重试!') })