Merge branch 'dvadmin-liqianglog' of https://gitee.com/liqianglog/django-vue-admin into dvadmin-dev
# Conflicts: # dvadmin-ui/src/store/modules/permission.jspull/26/MERGE
commit
dc57574e55
|
@ -50,9 +50,9 @@ github地址:[https://github.com/liqianglog/django-vue-admin](https://github.c
|
|||
|
||||
## 在线体验
|
||||
|
||||
演示地址:[https://demo.django-vue-admin.com/](https://demo.django-vue-admin.com/) 账号:admin 密码:123456
|
||||
演示地址:[http://demo.django-vue-admin.com/](http://demo.django-vue-admin.com/) 账号:admin 密码:123456
|
||||
|
||||
文档地址:[https://django-vue-admin.com/](https://django-vue-admin.com/)
|
||||
文档地址:[http://django-vue-admin.com/](http://django-vue-admin.com/)
|
||||
|
||||
## 前端
|
||||
|
||||
|
|
|
@ -48,19 +48,22 @@ class MonitorModelViewSet(CustomModelViewSet):
|
|||
"""
|
||||
pk = kwargs.get("pk")
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
queryset = queryset.filter(server__id=pk).order_by("-create_datetime")
|
||||
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]
|
||||
queryset = queryset.values('cpu_sys', 'mem_num', 'mem_sys', 'create_datetime')[::Interval_num][:100]
|
||||
data = {
|
||||
"cpu": [],
|
||||
"memory": [],
|
||||
"datetime": [],
|
||||
}
|
||||
for ele in queryset:
|
||||
data["cpu"].append(float(ele.get('cpu_sys', 0)) / 100)
|
||||
data["memory"].append(float(ele.get('mem_num', 0)) and round(float(ele.get('mem_sys', 0)) /
|
||||
float(ele.get('mem_num', 0)), 4))
|
||||
data["cpu"].append(round(float(ele.get('cpu_sys', 0)), 2))
|
||||
data["datetime"].append(ele.get('create_datetime').strftime('%Y-%m-%d %H:%M:%S'))
|
||||
data["memory"].append(round(float(ele.get('mem_num', 0)), 4) and round(float(ele.get('mem_sys', 0)) /
|
||||
float(ele.get('mem_num', 0)) * 100,
|
||||
2))
|
||||
return SuccessResponse(data=data)
|
||||
|
||||
def get_monitor_info(self, request: Request, *args, **kwargs):
|
||||
|
|
|
@ -315,8 +315,9 @@ class ImportSerializerMixin:
|
|||
# 导出模板
|
||||
if request.method == 'GET':
|
||||
# 示例数据
|
||||
queryset = self.filter_queryset(self.get_queryset())
|
||||
return SuccessResponse(
|
||||
export_excel_save_model(request, self.import_field_data.values(), [], '导入用户数据模板.xls'))
|
||||
export_excel_save_model(request, self.import_field_data.values(), [], f'导入{get_verbose_name(queryset)}模板.xls'))
|
||||
updateSupport = request.data.get('updateSupport')
|
||||
# 从excel中组织对应的数据结构,然后使用序列化器保存
|
||||
data = excel_to_data(request.data.get('file_url'), self.import_field_data)
|
||||
|
|
|
@ -33,6 +33,8 @@ class CustomModelSerializer(ModelSerializer):
|
|||
return super().save(**kwargs)
|
||||
|
||||
def create(self, validated_data):
|
||||
if self.context.get('request'):
|
||||
self.request = self.context.get('request')
|
||||
if self.request:
|
||||
username = self.get_request_username()
|
||||
if self.modifier_field_name in self.fields.fields:
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
"""
|
||||
重写校验器返回字段
|
||||
"""
|
||||
from rest_framework.validators import UniqueValidator, qs_exists
|
||||
|
||||
from vadmin.utils.exceptions import APIException
|
||||
|
||||
|
||||
class CustomUniqueValidator(UniqueValidator):
|
||||
"""
|
||||
继承,重写必填字段的验证器结果,防止字段暴露
|
||||
"""
|
||||
|
||||
def __call__(self, value, serializer_field):
|
||||
# Determine the underlying model field name. This may not be the
|
||||
# same as the serializer field name if `source=<>` is set.
|
||||
field_name = serializer_field.source_attrs[-1]
|
||||
# Determine the existing instance, if this is an update operation.
|
||||
instance = getattr(serializer_field.parent, 'instance', None)
|
||||
|
||||
queryset = self.queryset
|
||||
queryset = self.filter_queryset(value, queryset, field_name)
|
||||
queryset = self.exclude_current_instance(queryset, instance)
|
||||
if qs_exists(queryset):
|
||||
raise APIException(message=self.message)
|
||||
|
||||
def __repr__(self):
|
||||
return super().__repr__()
|
|
@ -1,8 +1,8 @@
|
|||
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 ..op_drf.validator import CustomUniqueValidator
|
||||
from ..permission.models import Menu, Dept, Post, Role
|
||||
from ..system.models import MessagePush
|
||||
|
||||
|
@ -260,7 +260,8 @@ class UserProfileCreateUpdateSerializer(CustomModelSerializer):
|
|||
post = PostSerializer(many=True, read_only=True)
|
||||
role = RoleSerializer(many=True, read_only=True)
|
||||
username = serializers.CharField(required=True, max_length=150,
|
||||
validators=[UniqueValidator(queryset=UserProfile.objects.all(), message="用戶已存在")],
|
||||
validators=[
|
||||
CustomUniqueValidator(queryset=UserProfile.objects.all(), message="用戶已存在")],
|
||||
error_messages={
|
||||
"blank": "请输入用户名称",
|
||||
"required": "用户名称不能为空",
|
||||
|
|
|
@ -121,3 +121,10 @@ INSERT INTO `permission_menu` (id, description, modifier, update_datetime, creat
|
|||
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (88, '', 'admin', '2021-03-21 23:33:30.888568', '2021-03-21 23:33:30.888593', '2', NULL, '登录日志清空', 4, '1', NULL, NULL, '/admin/system/logininfor/clean/', 'DELETE', 'admin:system:logininfor:clean:delete', '1', '1', '1', 1, 62, '1');
|
||||
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (90, '', 'admin', '2021-03-26 00:44:00.756139', '2021-03-26 00:43:14.390228', '2', NULL, '定时日志批量删除', 3, '1', NULL, NULL, '/admin/system/celery_log/{id}/', 'DELETE', 'admin:system:celery_log:{id}:delete', '1', '1', '1', 1, 79, '8');
|
||||
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (91, '', 'admin', '2021-03-26 00:44:36.135658', '2021-03-26 00:44:36.135679', '2', NULL, '定时日志清空', 4, '1', NULL, NULL, '/admin/system/celery_log/clean/', 'DELETE', 'admin:system:celery_log:clean:delete', '1', '1', '1', 1, 79, '8');
|
||||
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (92, '', 'admin', '2021-04-27 23:49:59.036636', '2021-04-27 23:44:54.512207', '1', 'server', '服务监控', 3, '1', '/monitor/server', 'vadmin/monitor/server/index', NULL, 'GET', NULL, '1', '1', '1', 1, 66, '1');
|
||||
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (93, '', 'admin', '2021-04-27 23:57:46.633022', '2021-04-27 23:49:28.569029', '2', NULL, '服务监控查询', 1, '1', NULL, NULL, '/admin/monitor/server/', 'GET', 'admin:monitor:server:get', '1', '1', '1', 1, 92, '1');
|
||||
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (94, '', 'admin', '2021-04-27 23:58:44.705142', '2021-04-27 23:58:13.384483', '2', NULL, '修改服务器信息', 2, '1', NULL, NULL, '/admin/monitor/server/{id}/', 'PUT', 'admin:monitor:server:{id}:put', '1', '1', '1', 1, 92, '1');
|
||||
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (95, '', 'admin', '2021-04-27 23:59:29.530633', '2021-04-27 23:59:07.744938', '2', NULL, '修改监控信息', 3, '1', NULL, NULL, '/admin/monitor/monitor/enabled/', 'GET', 'admin:monitor:monitor:enabled:get', '1', '1', '1', 1, 92, '1');
|
||||
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (96, '', 'admin', '2021-04-28 00:01:15.071889', '2021-04-27 23:59:48.612905', '2', NULL, '清空监控记录', 4, '1', NULL, NULL, '/admin/monitor/monitor/clean/', 'GET', 'admin:monitor:monitor:clean:get', '1', '1', '1', 1, 92, '1');
|
||||
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (97, '', 'admin', '2021-05-02 19:12:06.813143', '2021-05-02 18:58:06.260280', '0', 'dashboard', '首页', 0, '1', '/home', NULL, NULL, 'GET', NULL, '1', '1', '1', 1, NULL, '1');
|
||||
INSERT INTO `permission_menu` (id, description, modifier, update_datetime, create_datetime, menuType, icon, name, orderNum, isFrame, web_path, component_path, interface_path, interface_method, perms, status, visible, isCache, creator_id, parentId_id, dept_belong_id) VALUES (98, '', 'admin', '2021-05-02 19:10:34.233070', '2021-05-02 19:10:34.233125', '0', 'dashboard', '首页', 1, '1', 'index', 'index', NULL, 'GET', NULL, '1', '1', '1', 1, 97, '1');
|
||||
|
|
|
@ -56,14 +56,14 @@ export const constantRoutes = [
|
|||
{
|
||||
path: '',
|
||||
component: Layout,
|
||||
redirect: 'index',
|
||||
redirect: '/home/index',
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: (resolve) => require(['@/views/index'], resolve),
|
||||
name: '首页',
|
||||
meta: { title: '首页', icon: 'dashboard', noCache: true, affix: true }
|
||||
}
|
||||
// {
|
||||
// path: 'index',
|
||||
// component: (resolve) => require(['@/views/index'], resolve),
|
||||
// name: '首页',
|
||||
// meta: { title: '首页', icon: 'dashboard', noCache: true, affix: true }
|
||||
// }
|
||||
]
|
||||
},
|
||||
{
|
||||
|
|
|
@ -58,7 +58,11 @@ function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
|
|||
}
|
||||
if (route.children != null && route.children && route.children.length) {
|
||||
route.children = filterAsyncRouter(route.children, route, type)
|
||||
if (route.children.length === 1 && route.children[0].path === 'index') {
|
||||
route.alwaysShow = false
|
||||
} else {
|
||||
route.alwaysShow = true
|
||||
}
|
||||
} else {
|
||||
delete route['children']
|
||||
delete route['redirect']
|
||||
|
|
|
@ -74,14 +74,15 @@ export default {
|
|||
serverInfo: VueTypes.object.isRequired,
|
||||
lineChartKey: VueTypes.string.isRequired,
|
||||
chartTitle: VueTypes.string.isRequired,
|
||||
chartData: VueTypes.array.isRequired
|
||||
chartData: VueTypes.array.isRequired,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
TIME_LIMIT_SETTING,
|
||||
timeLimit: DEFAULT_TIME,
|
||||
lineChartId: this.lineChartKey + 'Chart',
|
||||
lineChartData: this.chartData
|
||||
lineChartData: this.chartData,
|
||||
lineChartTime: this.chartData
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -107,9 +108,14 @@ export default {
|
|||
let barGraph = echarts.init(document.getElementById(this.lineChartId))
|
||||
// 绘制图表
|
||||
barGraph.setOption({
|
||||
tooltip: {
|
||||
trigger: 'item',
|
||||
formatter: '{a} <br/>{b} : {c}'
|
||||
tooltip : {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
label: {
|
||||
backgroundColor: '#6a7985',
|
||||
}
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
left: 'center',
|
||||
|
@ -120,7 +126,8 @@ export default {
|
|||
type: 'category',
|
||||
name: 'x',
|
||||
splitLine: { show: false },
|
||||
data: []
|
||||
data:this.lineChartTime,
|
||||
offset:20
|
||||
},
|
||||
grid: {
|
||||
left: '1%',
|
||||
|
@ -131,14 +138,19 @@ export default {
|
|||
yAxis: {
|
||||
type: 'value',
|
||||
name: '使用率',
|
||||
axisLabel: {
|
||||
show: true,
|
||||
interval: 'auto',
|
||||
formatter: '{value}%'
|
||||
},
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '使用率',
|
||||
type: 'line',
|
||||
data: this.lineChartData
|
||||
data: this.lineChartData,
|
||||
}
|
||||
]
|
||||
],
|
||||
})
|
||||
},
|
||||
changeTimeLimit(value) {
|
||||
|
@ -146,8 +158,9 @@ export default {
|
|||
this.getCurrentServerMonitorLogs()
|
||||
},
|
||||
getCurrentServerMonitorLogs() {
|
||||
getMonitorLogs(this.serverInfo.id,{ as: { 'create_datetime__range': this.currentTimeLimitSetting.timeRange } }).then(results => {
|
||||
getMonitorLogs(this.serverInfo.id, {as: JSON.stringify({create_datetime__range: this.currentTimeLimitSetting.timeRange})}).then(results => {
|
||||
this.lineChartData = results.data[this.lineChartKey]
|
||||
this.lineChartTime = results.data["datetime"]
|
||||
this.drawBar()
|
||||
}).catch(error => {
|
||||
this.$message.warning(error.msg || `获取${this.chartTitle}数据失败!`)
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
<!-- 下方折线图 -->
|
||||
<div class="server-monitor-bottom">
|
||||
<!-- 折线图 -->
|
||||
<el-card class="box-card server-monitor-line-chart" v-for="(key, index) in Object.keys(lineChartData)"
|
||||
<el-card class="box-card server-monitor-line-chart" v-for="(key, index) in Object.keys(lineChartData).slice(0,2)"
|
||||
:key="`${index}-${key}`">
|
||||
<line-chart :line-chart-key="key"
|
||||
:server-info="currentServer"
|
||||
|
@ -313,7 +313,7 @@ export default {
|
|||
},
|
||||
/** 获取监控日志信息 */
|
||||
getCurrentServerMonitorLogs() {
|
||||
getMonitorLogs(this.currentServer.id, { as: { 'create_datetime__range': this.timeRange } }).then(results => {
|
||||
getMonitorLogs(this.currentServer.id, { as: JSON.stringify( { 'create_datetime__range': this.timeRange })}).then(results => {
|
||||
this.lineChartData = results.data
|
||||
}).catch(error => {
|
||||
this.msgError(error.msg || '获取监控日志信息出错误!')
|
||||
|
|
|
@ -117,7 +117,7 @@
|
|||
<el-table-column label="字典名称" align="center" prop="dictName" :show-overflow-tooltip="true" />
|
||||
<el-table-column label="字典类型" align="center" :show-overflow-tooltip="true">
|
||||
<template slot-scope="scope">
|
||||
<router-link :to="'/dict/type/data/' + scope.row.id" class="link-type">
|
||||
<router-link :to="hasPermi(['system:dict:type:get']) ?'/dict/type/data/' + scope.row.id :'#'" class="link-type">
|
||||
<span>{{ scope.row.dictType }}</span>
|
||||
</router-link>
|
||||
</template>
|
||||
|
|
Loading…
Reference in New Issue