分离管理员设备页面、增加分页、增加excel导出。

This commit is contained in:
kingmo888 2024-03-06 21:31:57 +08:00
parent b303d776c4
commit 051ea1e504
7 changed files with 100 additions and 16 deletions

4
.gitignore vendored
View File

@ -23,4 +23,6 @@ dist
dist-
dist_py38
LICENSE.rst
LICENSE.rst
db/test_db.sqlite3

View File

@ -7,7 +7,7 @@
<p align="center">
<i>一个 python 实现的 Rustdesk API 接口,支持 WebUI 管理</i>
<br/>
<img src ="https://img.shields.io/badge/Version-1.4.5-blueviolet.svg"/>
<img src ="https://img.shields.io/badge/Version-1.4.6-blueviolet.svg"/>
<img src ="https://img.shields.io/badge/Python-3.7|3.8|3.9|3.10|3.11-blue.svg" />
<img src ="https://img.shields.io/badge/Django-3.2+|4.x-yelow.svg" />
<br/>
@ -175,9 +175,11 @@ services:
> 通过配置方式,对过期超过指定时间的设备清理或过滤。
- [ ] 首屏拆分为用户列表页与管理员列表页并增加分页。
- [x] 首屏拆分为用户列表页与管理员列表页并增加分页。
- [ ] 支持信息导出到为xlsx文件。
- [x] 支持信息导出到为xlsx文件。
> 支持管理员在【所有设备】页面导出所有设备信息。
## 其他相关工具

View File

@ -28,6 +28,10 @@
<ul class="layui-nav">
<li class="layui-nav-item"><a href="/">首页</a></li>
{% if u.is_admin %}
<li class="layui-nav-item"><a href="/api/work?show_type=admin">所有设备</a>
</li>
{% endif %}
<li class="layui-nav-item"><a href="/api/share">分享</a></li>
<li class="layui-nav-item"><a href="/webui" target="_blank">网页控制</a></li>

View File

@ -4,6 +4,7 @@
{% block content %}
<div style="padding: 20px; background-color: #F2F2F2;">
<div class="layui-row layui-col-space15">
{% if not show_all %}
<div class="layui-col-md15">
<div class="layui-card">
<div class="layui-card-header">设备统计 - 用户名:{{u.username}}</div>
@ -26,7 +27,7 @@
</tr>
</thead>
<tbody>
{% for one in single_info %}
{% for one in page_obj %}
<tr>
<td>{{one.rid}} </td>
<td>{{one.version}}</td>
@ -47,11 +48,32 @@
</div>
</div>
</div>
<div class="layui-col-md4 layui-col-md-offset4">
<span class="step-links">
{% if page_obj.has_previous %}
<button class="layui-btn" ><a href="?page=1">&laquo; 首页</a></button>
<button class="layui-btn" ><a href="?page={{ page_obj.previous_page_number }}">上一页</a></button>
{% endif %}
{% if page_obj.paginator.num_pages > 1 %}
<span class="current">
页码 {{ page_obj.number }} / {{ page_obj.paginator.num_pages }}
</span>
{% endif %}
{% if page_obj.has_next %}
<button class="layui-btn" > <a href="?page={{ page_obj.next_page_number }}">下一页</a></button>
<button class="layui-btn" ><a href="?page={{ page_obj.paginator.num_pages }}">尾页 &raquo;</a></button>
{% endif %}
</span>
</div>
{% endif %}
{% if u.is_admin %}
{% if u.is_admin and show_all %}
<div class="layui-col-md15">
<div class="layui-card">
<div class="layui-card-header">全部用户</div>
<div class="layui-card-header">全部用户 &raquo;
<div class="layui-btn" ><a href="/api/down_peers">导出xlsx</a></div>
</div>
<div class="layui-card-body">
<table class="layui-table">
<thead>
@ -70,7 +92,7 @@
</thead>
<tbody>
{% for one in all_info %}
{% for one in page_obj %}
<tr>
<td>{{one.rid}} </td>
<td>{{one.rust_user}} </td>
@ -89,8 +111,28 @@
</div>
</div>
</div>
<div class="layui-col-md4 layui-col-md-offset4">
<span class="step-links">
{% if page_obj.has_previous %}
<button class="layui-btn" ><a href="?show_type=admin&page=1">&laquo; 首页</a></button>
<button class="layui-btn" ><a href="?show_type=admin&page={{ page_obj.previous_page_number }}">上一页</a></button>
{% endif %}
{% if page_obj.paginator.num_pages > 1 %}
<span class="current">
页码 {{ page_obj.number }} / {{ page_obj.paginator.num_pages }}
</span>
{% endif %}
{% if page_obj.has_next %}
<button class="layui-btn" > <a href="?show_type=admin&page={{ page_obj.next_page_number }}">下一页</a></button>
<button class="layui-btn" ><a href="?show_type=admin&page={{ page_obj.paginator.num_pages }}">尾页 &raquo;</a></button>
{% endif %}
</span>
</div>
{% endif %}
</div>
</div>

View File

@ -18,6 +18,7 @@ urlpatterns = [
url(r'^heartbeat',views.heartbeat),
#url(r'^register',views.register),
url(r'^user_action',views.user_action), # 前端
url(r'^work',views.work), # 前端
url(r'^share',views.share), # 前端
url(r'^work',views.work), # 前端
url(r'^down_peers$',views.down_peers), # 前端
url(r'^share',views.share), # 前端
]

View File

@ -8,6 +8,8 @@ from django.contrib.auth.decorators import login_required
from django.contrib import auth
from api.models import RustDeskPeer, RustDesDevice, UserProfile, ShareLink
from django.forms.models import model_to_dict
from django.core.paginator import Paginator
from django.http import HttpResponse
from itertools import chain
from django.db.models.fields import DateTimeField, DateField, CharField, TextField
@ -18,6 +20,9 @@ import time
import hashlib
import sys
from io import BytesIO
import xlwt
salt = 'xiaomo'
EFFECTIVE_SECONDS = 7200
@ -213,17 +218,45 @@ def get_all_info():
@login_required(login_url='/api/user_action?action=login')
def work(request):
username = request.user
u = UserProfile.objects.get(username=username)
single_info = get_single_info(u.id)
show_type = request.GET.get('show_type', '')
show_all = True if show_type == 'admin' and u.is_admin else False
paginator = Paginator(get_all_info(), 15) if show_type == 'admin' and u.is_admin else Paginator(get_single_info(u.id), 15)
page_number = request.GET.get('page')
page_obj = paginator.get_page(page_number)
return render(request, 'show_work.html', {'u':u, 'show_all':show_all, 'page_obj':page_obj})
@login_required(login_url='/api/user_action?action=login')
def down_peers(request):
username = request.user
u = UserProfile.objects.get(username=username)
if not u.is_admin:
print(u.is_admin)
return HttpResponseRedirect('/api/work')
all_info = get_all_info()
print(all_info)
return render(request, 'show_work.html', {'single_info':single_info, 'all_info':all_info, 'u':u})
f = xlwt.Workbook(encoding='utf-8')
sheet1 = f.add_sheet(u'设备信息表', cell_overwrite_ok=True)
all_fields = [x.name for x in RustDesDevice._meta.get_fields()]
all_fields.append('rust_user')
for i, one in enumerate(all_info):
for j, name in enumerate(all_fields):
if i == 0:
# 写入列名
sheet1.write(i, j, name)
sheet1.write(i+1, j, one.get(name, '-'))
sio = BytesIO()
f.save(sio)
sio.seek(0)
response = HttpResponse(sio.getvalue(), content_type='application/vnd.ms-excel')
response['Content-Disposition'] = 'attachment; filename=DeviceInfo.xls'
response.write(sio.getvalue())
return response
def check_sharelink_expired(sharelink):
now = datetime.datetime.now()
if sharelink.create_time > now:

Binary file not shown.