在上一篇文章说到,我们通过getuser的方法向服务器请求到svn配置文件有写权限的用户,下面我们需要把用户显示在前端文件中,简单列一下前端的核心显示代码,具体的css样式就不列出来了
<div class="user-container" id="userList" {% if commitSwitch=='true' %}style="display: flex;" {% else%}style="display: none;" {% endif %}><div class="user-list" id="noPermission"><div class="header-container"><h4>无权限用户:</h4><input type="text" id="searchBox" class="form-control search-box" placeholder="搜索用户..."></div><div class="user-items"><!-- 用户项将动态添加到这里 --></div><div class="text-center"><nav aria-label="分页导航"><ul class="pagination" id="pagination"><!-- 分页按钮将动态添加到这里 --></ul></nav></div></div><div class="button-container"><button class="move-button right" id="moveToPermission"></button><button class="move-button left" id="moveToNoPermission"></button></div><div class="user-list" id="hasPermission"><div class="header-container"><h4>有权限用户:</h4></div><div class="user-items"style="max-height: 250px; flex-direction: column;overflow-y: auto; display: flex; margin: 5px 0;"><!-- 初始为空,移动用户后动态添加 --></div></div></div>
这里就是页面的分页处理,还是数据初始化,以及移动用户后向服务器请求更改状态
$(document).ready(function () {const usersPerPage = 10; // 每页显示的用户数量let currentPage = 1;let users = {};let filteredUsers = {hasPermission: [],noPermission: []};// 定义一个函数来获取用户列表function fetchUsers(callback) {$.get('/api/users2', function (data) {users = data; // 假设返回的是用户对象filteredUsers.hasPermission = [];filteredUsers.noPermission = [];// 根据权限分配用户到不同的列表for (const [user, hasPermission] of Object.entries(users)) {if (hasPermission) {filteredUsers.hasPermission.push(user);} else {filteredUsers.noPermission.push(user);}}callback();});}// 初始获取用户列表fetchUsers(function () {displayUsers();setupPagination();});function displayUsers() {const start = (currentPage - 1) * usersPerPage;const end = start + usersPerPage;// 显示无权限用户$('#noPermission .user-items').empty();filteredUsers.noPermission.slice(start, end).forEach(function (user) {$('#noPermission .user-items').append(`<div><label><input type="checkbox" value="${user}"> ${user}</label></div>`);});// 显示有权限用户$('#hasPermission .user-items').empty();filteredUsers.hasPermission.forEach(function (user) {$('#hasPermission .user-items').append(`<div><label><input type="checkbox" value="${user}"> ${user}</label></div>`);});}function setupPagination() {const totalPages = Math.ceil(filteredUsers.noPermission.length / usersPerPage);$('#pagination').empty(); // 清空现有的分页按钮for (let i = 1; i <= totalPages; i++) {$('#pagination').append(`<li class="page-item ${i === currentPage ? 'active' : ''}"><a class="page-link" href="#" data-page="${i}">${i}</a></li>`);}// 添加点击事件$('.page-link').click(function (e) {e.preventDefault();currentPage = parseInt($(this).data('page'));displayUsers();setupPagination();});}$('#commitSwitch').change(function () {const isChecked = $('#commitSwitch').is(':checked');getCommitSwitchStatus(function (commitSwitch11) {if (commitSwitch11 === 'true') {$('#userList').css('display', 'flex'); // 切换用户列表的显示状态} else {$('#userList').toggle(false); // 切换用户列表的显示状态}});// 发送POST请求更新开关状态$.ajax({url: '/set_switch',type: 'POST',contentType: 'application/json', // 设置请求头为JSONdata: JSON.stringify({commit_switch: isChecked.toString()}), // 转换为字符串success: function (response) {console.log('成功更新:', response); // 处理成功响应},error: function (jqXHR, textStatus, errorThrown) {console.error('更新失败:', textStatus, errorThrown); // 处理错误}});});// 定义一个函数来通过 AJAX 请求获取实时的 commit_switch 状态function getCommitSwitchStatus(callback) {$.ajax({url: '/get_switch', // 替换为实际的 API 地址method: 'GET', // 使用 GET 方法请求数据success: function (data) {const commitSwitch11 = data.commit_switch;callback(commitSwitch11);},error: function () {alert('Failed to fetch commit switch status.');}});}// 定义一个函数来移动用户项function moveUsers(fromSelector, toSelector) {console.log('moveUsers 被调用');console.log('fromSelector:', fromSelector);console.log('toSelector:', toSelector);console.log('初始有权限用户列表:', filteredUsers.hasPermission);console.log('初始无权限用户列表:', filteredUsers.noPermission);$(fromSelector + ' .user-items input:checked').each(function () {const user = $(this).val();console.log('当前处理的用户:', user);console.log('检查用户是否在目标区域:', user, '目标区域:', toSelector);// 检查用户是否已经在目标区域if (toSelector === '#hasPermission' && filteredUsers.hasPermission.includes(user)) {console.log(user + ' 已经在有权限列表中!');alert(user + ' 已经在有权限列表中!');location.reload(); // 刷新页面以更新状态return; // 不执行移动操作} else if (toSelector === '#noPermission' && filteredUsers.noPermission.includes(user)) {console.log(user + ' 已经在无权限列表中!');alert(user + ' 已经在无权限列表中!');location.reload(); // 刷新页面以更新状态return; // 不执行移动操作}const userLabel = $(this).parent().detach();$(toSelector + ' .user-items').append(userLabel);$(this).prop('checked', false);// 更新用户权限值if (toSelector === '#hasPermission') {filteredUsers.hasPermission.push(user);filteredUsers.noPermission = filteredUsers.noPermission.filter(u => u !== user);users[user] = true; // 更新权限} else {filteredUsers.noPermission.push(user);filteredUsers.hasPermission = filteredUsers.hasPermission.filter(u => u !== user);users[user] = false; // 更新权限}// 打印更新后的状态console.log('移动用户后有权限用户列表:', filteredUsers.hasPermission);console.log('移动用户后无权限用户列表:', filteredUsers.noPermission);console.log('用户权限更新:', user, '新权限:', users[user]);// 发送 AJAX 请求到服务端$.ajax({url: '/api/updateUserPermissions',method: 'POST',contentType: 'application/json',data: JSON.stringify({user: user, permission: users[user]}),success: function (response) {console.log('权限更新成功:', response);},error: function (error) {console.error('权限更新失败:', error);}});});}// 为 “Move to Permission” 按钮绑定点击事件$('#moveToPermission').click(function () {getCommitSwitchStatus(function (commitSwitch11) {if (commitSwitch11 === 'true') {fetchUsers(function () {moveUsers('#noPermission', '#hasPermission');});} else {alert('SVN锁定已经被关闭,无需再授权');location.reload(); // 刷新页面以更新状态}});});// 为 “Move to No Permission” 按钮绑定点击事件$('#moveToNoPermission').click(function () {getCommitSwitchStatus(function (commitSwitch11) {if (commitSwitch11 === 'true') {fetchUsers(function () {moveUsers('#hasPermission', '#noPermission');});} else {alert('SVN锁定已经被关闭,无需再授权');location.reload(); // 刷新页面以更新状态}});});});
服务端一开始请求到的用户时一个list,我们需要把它改成一个字典,key是用户名,value是提交权限,一开始全部默认是false,如果svnhoos打开,所有用户都无法提交
# 向 svn 仓库的配置文件获取有写权限的用户 users1 = get_users_with_write_access(hostname, username, password, authz_path) users2 = {user: False for user in users1}
这里是定义一个GET方法,客户端需要请求用户数据显示
#提供用户列表 @app.route('/api/users2', methods=['GET']) def get_users2():users_permissions = users2return jsonify(users_permissions)
这个方法是接收客户端做了授予权限以后,服务端数据的改变
更新用户提交权限,用户在网页的操作 @app.route('/api/updateUserPermissions', methods=['POST']) def update_user_permissions():try:data = request.get_json()user = data.get('user')permission = data.get('permission')if user in users2:users2[user] = permissionresponse = {'status': 'success','message': f'{user} 权限已更新为 {permission}'}else:response = {'status': 'error','message': f'用户 {user} 不存在'}# 通知所有连接的客户端刷新页面socketio.emit('refresh_page')return jsonify(response), 200except Exception as e:return jsonify({'status': 'error','message': str(e)}), 500
在每次修改了用户权限后,我会调用socker,刷新一次页面,避免有多个用户操作页面,数据更新不及时,导致权限变更后,其他用户显示的数据是滞后的
如果用使用socket,需要在html前端加一个socker的引用
<script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script><script>var socket = io();socket.on('refresh_page', function() {location.reload(); // 刷新页面 });</script>
大概的效果就是如下