更新用户管理,现在能通过班导师,管理员,学生进入对应的页面进行密码修改
This commit is contained in:
BIN
db.sqlite3
BIN
db.sqlite3
Binary file not shown.
@@ -730,7 +730,10 @@ def get_all_users():
|
|||||||
users.append({
|
users.append({
|
||||||
"user_id": hit.user_id,
|
"user_id": hit.user_id,
|
||||||
"username": hit.username,
|
"username": hit.username,
|
||||||
"permission": int(hit.permission)
|
"permission": int(hit.permission),
|
||||||
|
"email": getattr(hit, 'email', None),
|
||||||
|
"key": list(getattr(hit, 'key', []) or []),
|
||||||
|
"manage_key": list(getattr(hit, 'manage_key', []) or []),
|
||||||
})
|
})
|
||||||
|
|
||||||
return users
|
return users
|
||||||
@@ -749,6 +752,9 @@ def get_user_by_id(user_id):
|
|||||||
"user_id": hit.user_id,
|
"user_id": hit.user_id,
|
||||||
"username": hit.username,
|
"username": hit.username,
|
||||||
"permission": int(hit.permission),
|
"permission": int(hit.permission),
|
||||||
|
"email": getattr(hit, 'email', None),
|
||||||
|
"key": list(getattr(hit, 'key', []) or []),
|
||||||
|
"manage_key": list(getattr(hit, 'manage_key', []) or []),
|
||||||
}
|
}
|
||||||
return None
|
return None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
INDEX_NAME = "wordsearch2666661"
|
INDEX_NAME = "wordsearch21"
|
||||||
USER_NAME = "users11111666789"
|
USER_NAME = "users16"
|
||||||
ACHIEVEMENT_INDEX_NAME = INDEX_NAME
|
ACHIEVEMENT_INDEX_NAME = INDEX_NAME
|
||||||
USER_INDEX_NAME = USER_NAME
|
USER_INDEX_NAME = USER_NAME
|
||||||
GLOBAL_INDEX_NAME = "global11111111"
|
GLOBAL_INDEX_NAME = "global11121"
|
||||||
|
|||||||
@@ -216,20 +216,49 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 主内容区域 -->
|
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
|
{% if is_student %}
|
||||||
|
<div class="card">
|
||||||
|
<div class="header"><h2>修改密码</h2></div>
|
||||||
|
<form id="selfPwdForm">
|
||||||
|
<input type="hidden" id="selfUserId" name="user_id" value="{{ user_id }}">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">新密码</label>
|
||||||
|
<input type="password" id="password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="confirmPassword">确认密码</label>
|
||||||
|
<input type="password" id="confirmPassword" name="confirmPassword" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">保存</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
{% if is_tutor %}
|
||||||
|
<div class="card">
|
||||||
|
<div class="header"><h2>修改本人密码</h2></div>
|
||||||
|
<form id="selfPwdForm">
|
||||||
|
<input type="hidden" id="selfUserId" name="user_id" value="{{ user_id }}">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">新密码</label>
|
||||||
|
<input type="password" id="password" name="password" required>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="confirmPassword">确认密码</label>
|
||||||
|
<input type="password" id="confirmPassword" name="confirmPassword" required>
|
||||||
|
</div>
|
||||||
|
<button type="submit" class="btn btn-primary">保存</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<h2>用户管理</h2>
|
<h2>用户管理</h2>
|
||||||
<button id="addUserBtn" class="btn btn-primary">添加用户</button>
|
{% if is_admin %}<button id="addUserBtn" class="btn btn-primary">添加用户</button>{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="notification success" id="successNotification">
|
<div class="notification success" id="successNotification">操作成功!</div>
|
||||||
操作成功!
|
<div class="notification error" id="errorNotification">操作失败!</div>
|
||||||
</div>
|
|
||||||
<div class="notification error" id="errorNotification">
|
|
||||||
操作失败!
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="search-container">
|
<div class="search-container">
|
||||||
<input type="text" id="searchInput" placeholder="搜索用户名...">
|
<input type="text" id="searchInput" placeholder="搜索用户名...">
|
||||||
@@ -247,12 +276,11 @@
|
|||||||
<th>操作</th>
|
<th>操作</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody id="usersTableBody">
|
<tbody id="usersTableBody"></tbody>
|
||||||
<!-- 用户数据将通过JavaScript加载 -->
|
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 添加/编辑用户模态框 -->
|
<!-- 添加/编辑用户模态框 -->
|
||||||
@@ -511,7 +539,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 事件监听器
|
// 事件监听器
|
||||||
document.getElementById('addUserBtn').addEventListener('click', openAddModal);
|
const addBtn = document.getElementById('addUserBtn');
|
||||||
|
if (addBtn) {
|
||||||
|
addBtn.addEventListener('click', openAddModal);
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('userForm').addEventListener('submit', saveUser);
|
document.getElementById('userForm').addEventListener('submit', saveUser);
|
||||||
|
|
||||||
@@ -523,15 +554,21 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('searchBtn').addEventListener('click', function() {
|
const searchBtn = document.getElementById('searchBtn');
|
||||||
|
if (searchBtn) {
|
||||||
|
searchBtn.addEventListener('click', function() {
|
||||||
const searchTerm = document.getElementById('searchInput').value;
|
const searchTerm = document.getElementById('searchInput').value;
|
||||||
loadUsers(searchTerm);
|
loadUsers(searchTerm);
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('resetBtn').addEventListener('click', function() {
|
const resetBtn = document.getElementById('resetBtn');
|
||||||
|
if (resetBtn) {
|
||||||
|
resetBtn.addEventListener('click', function() {
|
||||||
document.getElementById('searchInput').value = '';
|
document.getElementById('searchInput').value = '';
|
||||||
loadUsers();
|
loadUsers();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 点击模态框外部关闭模态框
|
// 点击模态框外部关闭模态框
|
||||||
window.addEventListener('click', function(event) {
|
window.addEventListener('click', function(event) {
|
||||||
@@ -572,7 +609,34 @@
|
|||||||
|
|
||||||
// 页面加载时获取用户列表
|
// 页面加载时获取用户列表
|
||||||
document.addEventListener('DOMContentLoaded', function() {
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const selfForm = document.getElementById('selfPwdForm');
|
||||||
|
if (selfForm) {
|
||||||
|
selfForm.addEventListener('submit', async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const uid = document.getElementById('selfUserId').value;
|
||||||
|
const pwd = document.getElementById('password').value;
|
||||||
|
const cpwd = document.getElementById('confirmPassword').value;
|
||||||
|
if (pwd !== cpwd) { showNotification('密码和确认密码不匹配', false); return; }
|
||||||
|
if ((pwd || '').length < 6) { showNotification('密码长度至少为6位', false); return; }
|
||||||
|
try {
|
||||||
|
const csrftoken = getCookie('csrftoken');
|
||||||
|
const resp = await fetch(`/elastic/users/${uid}/update/`, {
|
||||||
|
method: 'POST', credentials: 'same-origin',
|
||||||
|
headers: { 'Content-Type': 'application/json', 'X-CSRFToken': csrftoken || '' },
|
||||||
|
body: JSON.stringify({ password: pwd })
|
||||||
|
});
|
||||||
|
const result = await resp.json();
|
||||||
|
if (resp.ok && result.status === 'success') { showNotification('修改成功'); }
|
||||||
|
else { showNotification(result.message || '操作失败', false); }
|
||||||
|
} catch (error) {
|
||||||
|
showNotification('保存失败', false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const tbody = document.getElementById('usersTableBody');
|
||||||
|
if (tbody) {
|
||||||
loadUsers();
|
loadUsers();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 为表格中的编辑和删除按钮添加事件监听器
|
// 为表格中的编辑和删除按钮添加事件监听器
|
||||||
|
|||||||
@@ -222,16 +222,27 @@ def add_user(request):
|
|||||||
|
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
def get_users(request):
|
def get_users(request):
|
||||||
if request.session.get("user_id") is None:
|
uid = request.session.get("user_id")
|
||||||
|
if uid is None:
|
||||||
return JsonResponse({"status": "error", "message": "未登录"}, status=401)
|
return JsonResponse({"status": "error", "message": "未登录"}, status=401)
|
||||||
if int(request.session.get("permission", 1)) != 0:
|
|
||||||
return JsonResponse({"status": "error", "message": "无权限"}, status=403)
|
|
||||||
try:
|
try:
|
||||||
|
is_admin = int(request.session.get("permission", 1)) == 0
|
||||||
|
requester = get_user_by_id(uid) or {}
|
||||||
|
mgr_keys = set(requester.get("manage_key") or [])
|
||||||
q = (request.GET.get("search") or "").strip()
|
q = (request.GET.get("search") or "").strip()
|
||||||
users = get_all_users()
|
users = get_all_users()
|
||||||
|
if is_admin:
|
||||||
|
filtered = users
|
||||||
|
elif mgr_keys:
|
||||||
|
def match_manage(user):
|
||||||
|
ukeys = set(user.get("key") or [])
|
||||||
|
return bool(ukeys & mgr_keys)
|
||||||
|
filtered = [u for u in users if match_manage(u)]
|
||||||
|
else:
|
||||||
|
filtered = [u for u in users if str(u.get("user_id")) == str(uid)]
|
||||||
if q:
|
if q:
|
||||||
users = [u for u in users if q in str(u.get("username", ""))]
|
filtered = [u for u in filtered if q in str(u.get("username", ""))]
|
||||||
return JsonResponse({"status": "success", "data": users})
|
return JsonResponse({"status": "success", "data": filtered})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return JsonResponse({"status": "error", "message": str(e)}, status=500)
|
return JsonResponse({"status": "error", "message": str(e)}, status=500)
|
||||||
|
|
||||||
@@ -239,10 +250,9 @@ def get_users(request):
|
|||||||
@require_http_methods(["POST"])
|
@require_http_methods(["POST"])
|
||||||
@csrf_protect
|
@csrf_protect
|
||||||
def update_user_by_id_view(request, user_id):
|
def update_user_by_id_view(request, user_id):
|
||||||
if request.session.get("user_id") is None:
|
uid = request.session.get("user_id")
|
||||||
|
if uid is None:
|
||||||
return JsonResponse({"status": "error", "message": "未登录"}, status=401)
|
return JsonResponse({"status": "error", "message": "未登录"}, status=401)
|
||||||
if int(request.session.get("permission", 1)) != 0:
|
|
||||||
return JsonResponse({"status": "error", "message": "无权限"}, status=403)
|
|
||||||
try:
|
try:
|
||||||
payload = json.loads(request.body.decode("utf-8"))
|
payload = json.loads(request.body.decode("utf-8"))
|
||||||
except Exception:
|
except Exception:
|
||||||
@@ -250,21 +260,41 @@ def update_user_by_id_view(request, user_id):
|
|||||||
new_username = (payload.get("username") or "").strip()
|
new_username = (payload.get("username") or "").strip()
|
||||||
new_permission = payload.get("permission")
|
new_permission = payload.get("permission")
|
||||||
new_password = (payload.get("password") or "").strip()
|
new_password = (payload.get("password") or "").strip()
|
||||||
|
if new_password and len(new_password) < 6:
|
||||||
|
return JsonResponse({"status": "error", "message": "密码长度至少为6位"}, status=400)
|
||||||
|
|
||||||
|
is_admin = int(request.session.get("permission", 1)) == 0
|
||||||
|
requester = get_user_by_id(uid) or {}
|
||||||
|
target = get_user_by_id(user_id) or {}
|
||||||
|
requester_mgr = set(requester.get("manage_key") or [])
|
||||||
|
target_keys = set(target.get("key") or [])
|
||||||
|
|
||||||
|
if is_admin:
|
||||||
if new_username:
|
if new_username:
|
||||||
other = get_user_by_username(new_username)
|
other = get_user_by_username(new_username)
|
||||||
if other and int(other.get("user_id", -1)) != int(user_id):
|
if other and int(other.get("user_id", -1)) != int(user_id):
|
||||||
return JsonResponse({"status": "error", "message": "用户名已存在"}, status=409)
|
return JsonResponse({"status": "error", "message": "用户名已存在"}, status=409)
|
||||||
if new_password and len(new_password) < 6:
|
|
||||||
return JsonResponse({"status": "error", "message": "密码长度至少为6位"}, status=400)
|
|
||||||
ok = es_update_user_by_id(
|
ok = es_update_user_by_id(
|
||||||
user_id,
|
user_id,
|
||||||
username=new_username if new_username else None,
|
username=new_username if new_username else None,
|
||||||
permission=int(new_permission) if new_permission is not None else None,
|
permission=int(new_permission) if new_permission is not None else None,
|
||||||
password=new_password if new_password else None,
|
password=new_password if new_password else None,
|
||||||
)
|
)
|
||||||
if not ok:
|
return JsonResponse({"status": "success"}) if ok else JsonResponse({"status": "error", "message": "用户更新失败"}, status=500)
|
||||||
return JsonResponse({"status": "error", "message": "用户更新失败"}, status=500)
|
|
||||||
return JsonResponse({"status": "success", "message": "用户更新成功"})
|
if str(uid) == str(user_id):
|
||||||
|
if not new_password:
|
||||||
|
return JsonResponse({"status": "error", "message": "仅允许修改密码"}, status=400)
|
||||||
|
ok = es_update_user_by_id(user_id, password=new_password)
|
||||||
|
return JsonResponse({"status": "success"}) if ok else JsonResponse({"status": "error", "message": "用户更新失败"}, status=500)
|
||||||
|
|
||||||
|
if requester_mgr and (target_keys & requester_mgr):
|
||||||
|
if not new_password or new_username or new_permission is not None:
|
||||||
|
return JsonResponse({"status": "error", "message": "导师仅允许修改密码"}, status=403)
|
||||||
|
ok = es_update_user_by_id(user_id, password=new_password)
|
||||||
|
return JsonResponse({"status": "success"}) if ok else JsonResponse({"status": "error", "message": "用户更新失败"}, status=500)
|
||||||
|
|
||||||
|
return JsonResponse({"status": "error", "message": "无权限"}, status=403)
|
||||||
|
|
||||||
@require_http_methods(["POST"])
|
@require_http_methods(["POST"])
|
||||||
@csrf_protect
|
@csrf_protect
|
||||||
@@ -598,11 +628,16 @@ def user_manage(request):
|
|||||||
if session_user_id is None:
|
if session_user_id is None:
|
||||||
from django.shortcuts import redirect
|
from django.shortcuts import redirect
|
||||||
return redirect("/accounts/login/")
|
return redirect("/accounts/login/")
|
||||||
if int(request.session.get("permission", 1)) != 0:
|
is_admin = int(request.session.get("permission", 1)) == 0
|
||||||
from django.shortcuts import redirect
|
me = get_user_by_id(session_user_id) or {}
|
||||||
return redirect("/main/home/")
|
has_manage = bool(me.get("manage_key"))
|
||||||
user_id_qs = request.GET.get("user_id")
|
user_id_qs = request.GET.get("user_id")
|
||||||
context = {"user_id": user_id_qs or session_user_id}
|
context = {
|
||||||
|
"user_id": user_id_qs or session_user_id,
|
||||||
|
"is_admin": is_admin,
|
||||||
|
"is_tutor": (not is_admin) and has_manage,
|
||||||
|
"is_student": (not is_admin) and (not has_manage),
|
||||||
|
}
|
||||||
return render(request, "elastic/users.html", context)
|
return render(request, "elastic/users.html", context)
|
||||||
|
|
||||||
@require_http_methods(["GET"])
|
@require_http_methods(["GET"])
|
||||||
|
|||||||
@@ -42,8 +42,8 @@
|
|||||||
<a href="{% url 'main:home' %}" onclick="return handleNavClick(this, '/');">主页</a>
|
<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:upload_page' %}" onclick="return handleNavClick(this, '/elastic/upload/');">图片上传与识别</a>
|
||||||
<a href="{% url 'elastic:manage_page' %}" onclick="return handleNavClick(this, '/elastic/manage/');">数据管理</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>
|
<a href="{% url 'elastic:user_manage' %}" onclick="return handleNavClick(this, '/elastic/user_manage/');">用户管理</a>
|
||||||
|
{% if is_admin %}
|
||||||
<a href="{% url 'elastic:registration_code_manage_page' %}" onclick="return handleNavClick(this, '/elastic/registration-codes/manage/');">注册码管理</a>
|
<a href="{% url 'elastic:registration_code_manage_page' %}" onclick="return handleNavClick(this, '/elastic/registration-codes/manage/');">注册码管理</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a id="logoutBtn">退出登录</a>
|
<a id="logoutBtn">退出登录</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user