From 80bc18c5fafe1a30a4aaa403c3b99af20beadaf7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com>
Date: Fri, 21 Apr 2023 18:51:09 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20=E9=A6=96=E9=A1=B5=E6=8E=A7?=
=?UTF-8?q?=E5=88=B6=E5=8F=B0=E6=96=B0=E5=A2=9E=E7=99=BB=E5=BD=95=E5=8C=BA?=
=?UTF-8?q?=E5=9F=9F=E5=88=86=E5=B8=83?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
backend/dvadmin/system/views/datav.py | 60 +++++
.../workbench/components/loginRegion.vue | 205 ++++++++++++++++++
web/src/views/dashboard/workbench/index.vue | 1 -
web/src/views/dashboard/workbench/init.js | 11 +
4 files changed, 276 insertions(+), 1 deletion(-)
create mode 100644 web/src/views/dashboard/workbench/components/loginRegion.vue
diff --git a/backend/dvadmin/system/views/datav.py b/backend/dvadmin/system/views/datav.py
index f5f0fe8..f30acd5 100644
--- a/backend/dvadmin/system/views/datav.py
+++ b/backend/dvadmin/system/views/datav.py
@@ -198,3 +198,63 @@ class DataVViewSet(GenericViewSet):
'monthly_active': monthly_active
}
return DetailResponse(data=data, msg="获取成功")
+
+ @action(methods=["GET"], detail=False, permission_classes=[IsAuthenticated])
+ def login_region(self, request):
+ """
+ 登录用户区域分布
+ :param request:
+ :return:
+ """
+ CHINA_PROVINCES = [
+ {'name': '北京', 'code': '110000'},
+ {'name': '天津', 'code': '120000'},
+ {'name': '河北', 'code': '130000'},
+ {'name': '山西', 'code': '140000'},
+ {'name': '内蒙古', 'code': '150000'},
+ {'name': '辽宁', 'code': '210000'},
+ {'name': '吉林', 'code': '220000'},
+ {'name': '黑龙江', 'code': '230000'},
+ {'name': '上海', 'code': '310000'},
+ {'name': '江苏', 'code': '320000'},
+ {'name': '浙江', 'code': '330000'},
+ {'name': '安徽', 'code': '340000'},
+ {'name': '福建', 'code': '350000'},
+ {'name': '江西', 'code': '360000'},
+ {'name': '山东', 'code': '370000'},
+ {'name': '河南', 'code': '410000'},
+ {'name': '湖北', 'code': '420000'},
+ {'name': '湖南', 'code': '430000'},
+ {'name': '广东', 'code': '440000'},
+ {'name': '广西', 'code': '450000'},
+ {'name': '海南', 'code': '460000'},
+ {'name': '重庆', 'code': '500000'},
+ {'name': '四川', 'code': '510000'},
+ {'name': '贵州', 'code': '520000'},
+ {'name': '云南', 'code': '530000'},
+ {'name': '西藏', 'code': '540000'},
+ {'name': '陕西', 'code': '610000'},
+ {'name': '甘肃', 'code': '620000'},
+ {'name': '青海', 'code': '630000'},
+ {'name': '宁夏', 'code': '640000'},
+ {'name': '新疆', 'code': '650000'},
+ {'name': '台湾', 'code': '710000'},
+ {'name': '香港', 'code': '810000'},
+ {'name': '澳门', 'code': '820000'},
+ {'name': '未知区域', 'code': '000000'},
+ ]
+ provinces = [x['name'] for x in CHINA_PROVINCES]
+ day = 30
+ today = datetime.datetime.today()
+ seven_days_ago = today - datetime.timedelta(days=day)
+ province_data = LoginLog.objects.filter(create_datetime__gte=seven_days_ago).values('province').annotate(
+ count=Count('id')).order_by('-count')
+ province_dict = {p: 0 for p in provinces}
+ for ele in province_data:
+ if ele.get('province') in province_dict:
+ province_dict[ele.get('province')] += 1
+ else:
+ province_dict['未知区域'] += ele.get('count')
+ data = [{'region': key, 'count': val} for key, val in province_dict.items()]
+ data = sorted(data, key=lambda x: x['count'], reverse=True)
+ return DetailResponse(data=data, msg="获取成功")
diff --git a/web/src/views/dashboard/workbench/components/loginRegion.vue b/web/src/views/dashboard/workbench/components/loginRegion.vue
new file mode 100644
index 0000000..f867ee0
--- /dev/null
+++ b/web/src/views/dashboard/workbench/components/loginRegion.vue
@@ -0,0 +1,205 @@
+
+
+
+
+
+
+
+
+
diff --git a/web/src/views/dashboard/workbench/index.vue b/web/src/views/dashboard/workbench/index.vue
index 994674e..d26dfdc 100644
--- a/web/src/views/dashboard/workbench/index.vue
+++ b/web/src/views/dashboard/workbench/index.vue
@@ -262,7 +262,6 @@ export default {
},
// 设置实际的宽度和高度
containerResizedEvent: function (i, newH, newW, newHPx, newWPx) {
- console.log(this.layout, 'CONTAINER RESIZED i=' + i + ', H=' + newH + ', W=' + newW + ', H(px)=' + newHPx + ', W(px)=' + newWPx)
this.layout.map(val => {
if (val.i === i) {
this.$set(this.pxData, val.i, {
diff --git a/web/src/views/dashboard/workbench/init.js b/web/src/views/dashboard/workbench/init.js
index 4af261b..ca610d1 100644
--- a/web/src/views/dashboard/workbench/init.js
+++ b/web/src/views/dashboard/workbench/init.js
@@ -302,6 +302,17 @@ const log = [
isResizable: true,
element: 'ver',
moved: false
+ },
+ {
+ i: 'loginRegion12',
+ x: 0,
+ y: 75,
+ w: 48,
+ h: 30,
+ config: {},
+ isResizable: true,
+ element: 'loginRegion',
+ moved: false
}
]
export default log