新增“用户管理”

This commit is contained in:
2025-11-15 20:21:25 +08:00
parent 0f1cfdd803
commit 04b1df2130
6 changed files with 139 additions and 16 deletions

Binary file not shown.

View File

@@ -531,3 +531,37 @@ def update_user_permission(username, new_permission):
except Exception as e:
print(f"更新用户权限失败: {str(e)}")
return False
def delete_user_by_id(user_id):
try:
search = UserDocument.search()
search = search.query("term", user_id=int(user_id))
response = search.execute()
if response.hits:
user = response.hits[0]
user.delete()
return True
return False
except Exception as e:
print(f"删除用户失败: {str(e)}")
return False
def update_user_by_id(user_id, username=None, permission=None, password=None):
try:
search = UserDocument.search()
search = search.query("term", user_id=int(user_id))
response = search.execute()
if response.hits:
user = response.hits[0]
if username is not None:
user.username = username
if permission is not None:
user.permission = int(permission)
if password is not None:
user.password = password
user.save()
return True
return False
except Exception as e:
print(f"更新用户失败: {str(e)}")
return False

View File

@@ -322,8 +322,8 @@
<div class="form-group">
<label for="permission">权限</label>
<select id="permission" name="permission" required>
<option value="0">普通用户</option>
<option value="1">管理员</option>
<option value="0">管理员</option>
<option value="1">普通用户</option>
</select>
</div>
</div>
@@ -408,7 +408,7 @@
const row = document.createElement('tr');
// 根据权限值显示权限名称
const permissionText = user.permission === 1 ? '管理员' : '普通用户';
const permissionText = user.permission === 0 ? '管理员' : '普通用户';
row.innerHTML = `
<td>${user.user_id}</td>

View File

@@ -24,6 +24,8 @@ urlpatterns = [
path('users/add/', views.add_user, name='add_user'),
path('users/<str:username>/delete/', views.delete_user, name='delete_user'),
path('users/<str:username>/update/', views.update_user, name='update_user'),
path('users/<int:user_id>/delete/', views.delete_user_by_id_view, name='delete_user_by_id'),
path('users/<int:user_id>/update/', views.update_user_by_id_view, name='update_user_by_id'),
# 图片上传与确认
path('upload-page/', views.upload_page, name='upload_page'),

View File

@@ -11,7 +11,7 @@ from django.http import JsonResponse
from django.shortcuts import render
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.csrf import csrf_exempt, ensure_csrf_cookie
from django.views.decorators.csrf import csrf_exempt, ensure_csrf_cookie, csrf_protect
from .es_connect import *
from openai import OpenAI
from PIL import Image
@@ -184,25 +184,53 @@ def get_data(request, doc_id):
@require_http_methods(["POST"])
@csrf_exempt
@csrf_protect
def add_user(request):
"""添加用户"""
if request.session.get("user_id") is None:
return JsonResponse({"status": "error", "message": "未登录"}, status=401)
if request.session.get("permission", 1) != 0:
return JsonResponse({"status": "error", "message": "无权限"}, status=403)
try:
data = json.loads(request.body.decode('utf-8'))
success = write_user_data(data)
if success:
return JsonResponse({"status": "success", "message": "用户添加成功"})
else:
payload = json.loads(request.body.decode("utf-8"))
except Exception:
return JsonResponse({"status": "error", "message": "JSON无效"}, status=400)
username = (payload.get("username") or "").strip()
password = (payload.get("password") or "").strip()
try:
permission = int(payload.get("permission", 1))
except Exception:
permission = 1
if not username:
return JsonResponse({"status": "error", "message": "用户名不能为空"}, status=400)
if password and len(password) < 6:
return JsonResponse({"status": "error", "message": "密码长度至少为6位"}, status=400)
existing = get_user_by_username(username)
if existing:
return JsonResponse({"status": "error", "message": "用户名已存在"}, status=409)
users = get_all_users()
next_id = (max([int(u.get("user_id", 0)) for u in users]) + 1) if users else 1
ok = write_user_data({
"user_id": next_id,
"username": username,
"password": password,
"permission": permission,
})
if not ok:
return JsonResponse({"status": "error", "message": "用户添加失败"}, status=500)
except Exception as e:
return JsonResponse({"status": "error", "message": str(e)}, status=500)
return JsonResponse({"status": "success", "message": "用户添加成功"})
@require_http_methods(["GET"])
def get_users(request):
"""获取所有用户"""
if request.session.get("user_id") is None:
return JsonResponse({"status": "error", "message": "未登录"}, status=401)
if request.session.get("permission", 1) != 0:
return JsonResponse({"status": "error", "message": "无权限"}, status=403)
try:
q = (request.GET.get("search") or "").strip()
users = get_all_users()
if q:
users = [u for u in users if q in str(u.get("username", ""))]
return JsonResponse({"status": "success", "data": users})
except Exception as e:
return JsonResponse({"status": "error", "message": str(e)}, status=500)
@@ -228,7 +256,7 @@ def update_user(request, username):
"""更新用户权限"""
try:
data = json.loads(request.body.decode('utf-8'))
new_permission = data.get('permission', 1)
new_permission = int(data.get('permission', 1))
success = update_user_permission(username, new_permission)
if success:
return JsonResponse({"status": "success", "message": "用户权限更新成功"})
@@ -237,6 +265,48 @@ def update_user(request, username):
except Exception as e:
return JsonResponse({"status": "error", "message": str(e)}, status=500)
@require_http_methods(["POST"])
@csrf_protect
def update_user_by_id_view(request, user_id):
if request.session.get("user_id") is None:
return JsonResponse({"status": "error", "message": "未登录"}, status=401)
if request.session.get("permission", 1) != 0:
return JsonResponse({"status": "error", "message": "无权限"}, status=403)
try:
payload = json.loads(request.body.decode("utf-8"))
except Exception:
return JsonResponse({"status": "error", "message": "JSON无效"}, status=400)
new_username = (payload.get("username") or "").strip()
new_permission = payload.get("permission")
new_password = (payload.get("password") or "").strip()
if new_username:
other = get_user_by_username(new_username)
if other and int(other.get("user_id", -1)) != int(user_id):
return JsonResponse({"status": "error", "message": "用户名已存在"}, status=409)
if new_password and len(new_password) < 6:
return JsonResponse({"status": "error", "message": "密码长度至少为6位"}, status=400)
ok = update_user_by_id(
user_id,
username=new_username if new_username else None,
permission=int(new_permission) if new_permission is not None else None,
password=new_password if new_password else None,
)
if not ok:
return JsonResponse({"status": "error", "message": "用户更新失败"}, status=500)
return JsonResponse({"status": "success", "message": "用户更新成功"})
@require_http_methods(["POST"])
@csrf_protect
def delete_user_by_id_view(request, user_id):
if request.session.get("user_id") is None:
return JsonResponse({"status": "error", "message": "未登录"}, status=401)
if request.session.get("permission", 1) != 0:
return JsonResponse({"status": "error", "message": "无权限"}, status=403)
ok = delete_user_by_id(user_id)
if not ok:
return JsonResponse({"status": "error", "message": "用户删除失败"}, status=500)
return JsonResponse({"status": "success", "message": "用户删除成功"})
# 辅助JSON 转换(兼容 a.py 行为)
def json_to_string(obj):
@@ -466,3 +536,17 @@ def manage_page(request):
user_id_qs = request.GET.get("user_id")
context = {"items": results, "user_id": user_id_qs or session_user_id}
return render(request, "elastic/manage.html", context)
@require_http_methods(["GET"])
@ensure_csrf_cookie
def user_manage(request):
session_user_id = request.session.get("user_id")
if session_user_id is None:
from django.shortcuts import redirect
return redirect("/accounts/login/")
if request.session.get("permission", 1) != 0:
from django.shortcuts import redirect
return redirect("/main/home/")
user_id_qs = request.GET.get("user_id")
context = {"user_id": user_id_qs or session_user_id}
return render(request, "elastic/users.html", context)

View File

@@ -141,6 +141,9 @@
<a href="{% url 'main:home' %}" onclick="return handleNavClick(this, '/');">主页</a>
<a href="{% url 'elastic:upload_page' %}" onclick="return handleNavClick(this, '/elastic/upload/');">图片上传与识别</a>
<a href="{% url 'elastic:manage_page' %}" onclick="return handleNavClick(this, '/elastic/manage/');">数据管理</a>
{% if is_admin %}
<a href="{% url 'elastic:user_manage' %}" onclick="return handleNavClick(this, '/elastic/user_manage/');">用户管理</a>
{% endif %}
<button id="logoutBtn">退出登录</button>
<div id="logoutMsg"></div>
{% csrf_token %}