diff --git a/Login/login.cpp b/Login/login.cpp index 49c4d87..2d18852 100644 --- a/Login/login.cpp +++ b/Login/login.cpp @@ -191,7 +191,7 @@ extern "C" LOGIN_EXPORT int validateUser(const char *username_buffer, size_t use return -1; } - fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db"; + fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db"; sqlite3 *db; if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) { @@ -230,7 +230,7 @@ extern "C" LOGIN_EXPORT int getUserInfo(int user_id, char *result, int result_le return -1; } - fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db"; + fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db"; sqlite3 *db; if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) { @@ -290,14 +290,21 @@ extern "C" LOGIN_EXPORT int getUserInfo(int user_id, char *result, int result_le std::string jsonData = userInfo.dump(); if (result_length >= jsonData.size() + 1) { std::strcpy(result, jsonData.c_str()); + sqlite3_finalize(stmt); + sqlite3_close(db); return 0; } else { std::cout << "result_length: " << result_length << std::endl; + sqlite3_finalize(stmt); + sqlite3_close(db); return -1; } + } else { + // 用户不存在 + sqlite3_finalize(stmt); + sqlite3_close(db); + return -2; // 用户不存在 } - - sqlite3_finalize(stmt); } sqlite3_close(db); @@ -336,7 +343,7 @@ int checkUsernameExists(const void *username_buffer, size_t username_length) return -1; } - fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db"; + fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db"; std::string connectionName = "usercheck_" + std::to_string(std::chrono::duration_cast( @@ -428,12 +435,7 @@ extern "C" LOGIN_EXPORT int registerUser(const char *username_buffer, int userna return -1; } - fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db"; - std::string connectionName = - "userreg_" - + std::to_string(std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count()); + fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db"; int newUserId = -1; { @@ -497,12 +499,7 @@ extern "C" LOGIN_EXPORT int changePassword(int user_id, const char *old_password return -1; } - fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db"; - std::string connectionName = - "changepwd_" - + std::to_string(std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count()); + fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db"; { sqlite3 *db; @@ -548,11 +545,16 @@ extern "C" LOGIN_EXPORT int changePassword(int user_id, const char *old_password if (sqlite3_step(stmt) == SQLITE_DONE) { sqlite3_finalize(stmt); sqlite3_close(db); - return 1; // 密码修改成功 + return 0; // 密码修改成功 } sqlite3_finalize(stmt); } + } else { + // 用户不存在 + sqlite3_finalize(stmt); + sqlite3_close(db); + return -2; // 用户不存在 } } @@ -565,6 +567,81 @@ extern "C" LOGIN_EXPORT int changePassword(int user_id, const char *old_password } } +extern "C" LOGIN_EXPORT int resetPassword(int user_id) +{ + try { + const char *xnCorePath = std::getenv("XNCore"); + if (!xnCorePath) { + return -1; + } + + fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db"; + { + sqlite3 *db; + if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) { + return -2; + } + + // 首先查询用户名 + sqlite3_stmt *stmt; + const char *queryStr = "SELECT username FROM users WHERE id = ?"; + + if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) != SQLITE_OK) { + sqlite3_close(db); + return -3; // SELECT 语句准备失败 + } + + sqlite3_bind_int(stmt, 1, user_id); + + if (sqlite3_step(stmt) == SQLITE_ROW) { + std::string username = reinterpret_cast(sqlite3_column_text(stmt, 0)); + + // 生成新的加密密码 + std::string salt = generateSalt(username); + std::string new_password_str = "123456"; + std::string encryptedNewPassword = encryptPassword(new_password_str, salt); + + // 更新密码 + sqlite3_finalize(stmt); + stmt = nullptr; + queryStr = "UPDATE users SET password = ? WHERE id = ?"; + + if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) != SQLITE_OK) { + sqlite3_close(db); + return -4; // UPDATE 语句准备失败 + } + + sqlite3_bind_text(stmt, 1, encryptedNewPassword.c_str(), -1, SQLITE_STATIC); + sqlite3_bind_int(stmt, 2, user_id); + + if (sqlite3_step(stmt) == SQLITE_DONE) { + sqlite3_finalize(stmt); + sqlite3_close(db); + return 0; // 密码重置成功 + } else { + // 获取具体的错误信息 + int error_code = sqlite3_errcode(db); + const char *error_msg = sqlite3_errmsg(db); + std::cout << "UPDATE failed with error code: " << error_code + << ", message: " << (error_msg ? error_msg : "unknown") << std::endl; + sqlite3_finalize(stmt); + sqlite3_close(db); + return -5; // UPDATE 语句执行失败 + } + } else { + // 用户不存在 + sqlite3_finalize(stmt); + sqlite3_close(db); + return -6; // 用户不存在 + } + } + + return -7; // 其他错误 + } catch (const std::exception &) { + return -8; + } +} + // 更新用户信息 extern "C" LOGIN_EXPORT int updateUserInfo(int user_id, const char *userinfo_buffer, int userinfo_length) @@ -586,12 +663,7 @@ extern "C" LOGIN_EXPORT int updateUserInfo(int user_id, const char *userinfo_buf return -1; } - fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db"; - std::string connectionName = - "userupdate_" - + std::to_string(std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count()); + fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db"; int result = -1; { @@ -607,7 +679,7 @@ extern "C" LOGIN_EXPORT int updateUserInfo(int user_id, const char *userinfo_buf if (sqlite3_prepare_v2(db, checkQueryStr, -1, &stmt, nullptr) == SQLITE_OK) { sqlite3_bind_int(stmt, 1, user_id); - if (sqlite3_step(stmt) == SQLITE_ROW) { + if (sqlite3_step(stmt) != SQLITE_ROW) { sqlite3_finalize(stmt); sqlite3_close(db); return -2; // 用户不存在 @@ -622,20 +694,35 @@ extern "C" LOGIN_EXPORT int updateUserInfo(int user_id, const char *userinfo_buf "WHERE id = ?"; if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) { - sqlite3_bind_text(stmt, 1, userInfo["full_name"].get().c_str(), -1, - SQLITE_STATIC); - sqlite3_bind_text(stmt, 2, userInfo["phone"].get().c_str(), -1, - SQLITE_STATIC); - sqlite3_bind_text(stmt, 3, userInfo["email"].get().c_str(), -1, - SQLITE_STATIC); - sqlite3_bind_text(stmt, 4, userInfo["department"].get().c_str(), -1, - SQLITE_STATIC); - sqlite3_bind_text(stmt, 5, userInfo["position"].get().c_str(), -1, - SQLITE_STATIC); + // 安全地获取字符串值,处理null情况 + std::string full_name = + userInfo.contains("full_name") && !userInfo["full_name"].is_null() + ? userInfo["full_name"].get() + : ""; + std::string phone = userInfo.contains("phone") && !userInfo["phone"].is_null() + ? userInfo["phone"].get() + : ""; + std::string email = userInfo.contains("email") && !userInfo["email"].is_null() + ? userInfo["email"].get() + : ""; + std::string department = + userInfo.contains("department") && !userInfo["department"].is_null() + ? userInfo["department"].get() + : ""; + std::string position = + userInfo.contains("position") && !userInfo["position"].is_null() + ? userInfo["position"].get() + : ""; + + sqlite3_bind_text(stmt, 1, full_name.c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 2, phone.c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 3, email.c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 4, department.c_str(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(stmt, 5, position.c_str(), -1, SQLITE_TRANSIENT); sqlite3_bind_int(stmt, 6, user_id); if (sqlite3_step(stmt) == SQLITE_DONE) { - result = 1; // 更新成功 + result = 0; // 更新成功 } sqlite3_finalize(stmt); @@ -655,7 +742,7 @@ extern "C" LOGIN_EXPORT int updateUserAccessLevel(int user_id, int access_level) { try { // 验证权限级别 - if (access_level < 0 || access_level >= 3) { + if (access_level < 0 || access_level > 3) { return -3; // 无效的权限级别 } @@ -665,12 +752,7 @@ extern "C" LOGIN_EXPORT int updateUserAccessLevel(int user_id, int access_level) return -1; } - fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db"; - std::string connectionName = - "useraccess_" - + std::to_string(std::chrono::duration_cast( - std::chrono::system_clock::now().time_since_epoch()) - .count()); + fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db"; int result = -1; { @@ -686,7 +768,7 @@ extern "C" LOGIN_EXPORT int updateUserAccessLevel(int user_id, int access_level) if (sqlite3_prepare_v2(db, checkQueryStr, -1, &stmt, nullptr) == SQLITE_OK) { sqlite3_bind_int(stmt, 1, user_id); - if (sqlite3_step(stmt) == SQLITE_ROW) { + if (sqlite3_step(stmt) != SQLITE_ROW) { sqlite3_finalize(stmt); sqlite3_close(db); return -2; // 用户不存在 @@ -725,7 +807,7 @@ extern "C" LOGIN_EXPORT int updateUserAccessLevel(int user_id, int access_level) sqlite3_bind_int(stmt, 2, user_id); if (sqlite3_step(stmt) == SQLITE_DONE) { - result = 1; // 更新成功 + result = 0; // 更新成功 } sqlite3_finalize(stmt); @@ -748,24 +830,25 @@ extern "C" LOGIN_EXPORT int getAllUsersSimpleInfo(char *result, int result_lengt if (!xnCorePath) { return -1; } - fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.db"; + fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db"; sqlite3 *db; if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) { return -1; } - const char *queryStr = "SELECT username, full_name, access_level FROM users"; + const char *queryStr = "SELECT id, username, full_name, access_level FROM users"; sqlite3_stmt *stmt; json arr = json::array(); if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) { while (sqlite3_step(stmt) == SQLITE_ROW) { json userInfo; - std::string username = reinterpret_cast(sqlite3_column_text(stmt, 0)); + userInfo["id"] = sqlite3_column_int(stmt, 0); + std::string username = reinterpret_cast(sqlite3_column_text(stmt, 1)); userInfo["username"] = username; userInfo["full_name"] = - reinterpret_cast(sqlite3_column_text(stmt, 1)); + reinterpret_cast(sqlite3_column_text(stmt, 2)); // access_level 解密 std::string accessLevelEnc = - reinterpret_cast(sqlite3_column_text(stmt, 2)); + reinterpret_cast(sqlite3_column_text(stmt, 3)); std::vector iv_and_ciphertext = hex2bin(accessLevelEnc); if (iv_and_ciphertext.size() < 16) { userInfo["access_level"] = nullptr; @@ -799,3 +882,32 @@ extern "C" LOGIN_EXPORT int getAllUsersSimpleInfo(char *result, int result_lengt return -1; } } + +extern "C" LOGIN_EXPORT int deleteUser(int user_id) +{ + try { + const char *xnCorePath = std::getenv("XNCore"); + if (!xnCorePath) { + return -1; + } + fs::path dbPath = fs::path(xnCorePath) / "database" / "UserInfo.db"; + sqlite3 *db; + if (sqlite3_open(dbPath.string().c_str(), &db) != SQLITE_OK) { + return -1; + } + const char *queryStr = "DELETE FROM users WHERE id = ?"; + sqlite3_stmt *stmt; + if (sqlite3_prepare_v2(db, queryStr, -1, &stmt, nullptr) == SQLITE_OK) { + sqlite3_bind_int(stmt, 1, user_id); + if (sqlite3_step(stmt) == SQLITE_DONE) { + sqlite3_finalize(stmt); + sqlite3_close(db); + return 0; + } + } + sqlite3_close(db); + return -1; + } catch (const std::exception &) { + return -1; + } +} \ No newline at end of file diff --git a/Release/database/UserInfo.db b/Release/database/UserInfo.db new file mode 100644 index 0000000..512d0d6 Binary files /dev/null and b/Release/database/UserInfo.db differ diff --git a/Release/database/XNSim.db b/Release/database/XNSim.db index 013182d..7bfd059 100644 Binary files a/Release/database/XNSim.db and b/Release/database/XNSim.db differ diff --git a/XNSimHtml/components/user-management.js b/XNSimHtml/components/user-management.js index 27f1d88..0d02b10 100644 --- a/XNSimHtml/components/user-management.js +++ b/XNSimHtml/components/user-management.js @@ -2,10 +2,205 @@ class UserManagement extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); + this.users = []; + this.currentUser = null; } connectedCallback() { this.render(); + this.fetchUsers(); + } + + async fetchUsers() { + try { + const response = await fetch('/api/all-users'); + const data = await response.json(); + if (data.success) { + this.users = data.users.filter(user => user.id !== 1); + this.render(); + } else { + console.error('获取用户列表失败:', data.message); + } + } catch (error) { + console.error('获取用户列表出错:', error); + } + } + + showError(message) { + this.shadowRoot.querySelector('.error-message').textContent = message; + this.shadowRoot.querySelector('.error-message').style.display = 'block'; + } + + async handleEditInfo(userId) { + try { + const response = await fetch(`/api/user-info/${userId}`); + const data = await response.json(); + if (data.success) { + this.currentUser = data.user; + this.showEditModal(); + } else { + alert('获取用户信息失败: ' + data.message); + } + } catch (error) { + console.error('获取用户信息出错:', error); + alert('获取用户信息失败'); + } + } + + showEditModal() { + this.shadowRoot.querySelector('.modal').style.display = 'flex'; + this.populateForm(); + } + + hideEditModal() { + this.shadowRoot.querySelector('.modal').style.display = 'none'; + this.currentUser = null; + } + + populateForm() { + const form = this.shadowRoot.querySelector('.edit-form'); + form.username.value = this.currentUser.username || ''; + form.full_name.value = this.currentUser.full_name || ''; + form.email.value = this.currentUser.email || ''; + form.phone.value = this.currentUser.phone || ''; + form.department.value = this.currentUser.department || ''; + form.position.value = this.currentUser.position || ''; + } + + async handleSaveUserInfo() { + const form = this.shadowRoot.querySelector('.edit-form'); + const userInfo = { + full_name: form.full_name.value, + email: form.email.value, + phone: form.phone.value, + department: form.department.value, + position: form.position.value + }; + + try { + const response = await fetch('/api/update-user-info', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + userId: this.currentUser.id, + userInfo: userInfo + }) + }); + const data = await response.json(); + if (data.success) { + alert('用户信息更新成功'); + this.hideEditModal(); + this.fetchUsers(); // 刷新用户列表 + } else { + alert('用户信息更新失败: ' + data.message); + } + } catch (error) { + console.error('更新用户信息出错:', error); + alert('更新用户信息失败'); + } + } + + handleChangeAccessLevel(userId) { + this.currentUser = { id: userId }; + this.showAccessModal(); + } + + showAccessModal() { + this.shadowRoot.querySelector('.access-modal').style.display = 'flex'; + } + + hideAccessModal() { + this.shadowRoot.querySelector('.access-modal').style.display = 'none'; + this.currentUser = null; + } + + async handleSaveAccessLevel() { + const form = this.shadowRoot.querySelector('.access-form'); + const accessLevel = parseInt(form.access_level.value); + + try { + const response = await fetch('/api/update-access-level', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ + userId: this.currentUser.id, + accessLevel: accessLevel + }) + }); + const data = await response.json(); + if (data.success) { + alert('权限级别更新成功'); + this.hideAccessModal(); + this.fetchUsers(); // 刷新用户列表 + } else { + alert('权限级别更新失败: ' + data.message); + } + } catch (error) { + console.error('更新权限级别出错:', error); + alert('更新权限级别失败'); + } + } + + async handleResetPassword(userId) { + if (confirm('确定要重置该用户的密码吗?')) { + try { + const response = await fetch('/api/reset-password', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ userId: parseInt(userId) }) + }); + const data = await response.json(); + if (data.success) { + alert('密码重置成功'); + } else { + alert('密码重置失败: ' + data.message); + } + } catch (error) { + console.error('重置密码出错:', error); + alert('重置密码失败'); + } + } + } + + async handleDelete(userId) { + if (confirm('确定要删除该用户吗?此操作不可恢复!')) { + try { + const response = await fetch('/api/delete-user', { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ userId: parseInt(userId) }) + }); + const data = await response.json(); + if (data.success) { + alert('用户删除成功'); + // 重新获取用户列表 + this.fetchUsers(); + } else { + alert('用户删除失败: ' + data.message); + } + } catch (error) { + console.error('删除用户出错:', error); + alert('删除用户失败'); + } + } + } + + getAccessLevelName(level) { + const accessLevels = { + 0: '访客', + 1: '用户', + 2: '开发人员', + 3: '组长' + }; + return accessLevels[level] || level; } render() { @@ -42,12 +237,406 @@ class UserManagement extends HTMLElement { font-weight: bold; color: #333; } + + .users-table { + width: 100%; + border-collapse: collapse; + table-layout: fixed; + } + + .users-table th, + .users-table td { + padding: 12px; + text-align: left; + border-bottom: 1px solid #e0e0e0; + word-wrap: break-word; + } + + .users-table th { + background-color: #f5f5f5; + font-weight: bold; + color: #333; + } + + .users-table tr:hover { + background-color: #f9f9f9; + } + + .col-id { + width: 8%; + } + + .col-username { + width: 20%; + } + + .col-fullname { + width: 25%; + } + + .col-access { + width: 12%; + } + + .col-actions { + width: 35%; + } + + .error-message { + display: none; + color: #ff4d4f; + margin: 16px 0; + padding: 8px; + background-color: #fff2f0; + border: 1px solid #ffccc7; + border-radius: 4px; + } + + .loading { + text-align: center; + padding: 20px; + color: #666; + } + + .action-button { + padding: 6px 12px; + margin: 0 4px; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 12px; + color: white; + transition: opacity 0.2s; + } + + .edit-info { + background-color: #1890ff; + } + + .change-access { + background-color: #52c41a; + } + + .reset-password { + background-color: #faad14; + } + + .delete { + background-color: #ff4d4f; + } + + .action-button:hover { + opacity: 0.8; + } + + .action-button:active { + opacity: 0.6; + } + + .modal { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + justify-content: center; + align-items: center; + z-index: 1000; + } + + .modal-content { + background-color: white; + border-radius: 8px; + padding: 24px; + width: 500px; + max-width: 90%; + max-height: 90%; + overflow-y: auto; + } + + .modal-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; + padding-bottom: 10px; + border-bottom: 1px solid #e0e0e0; + } + + .modal-title { + font-size: 18px; + font-weight: bold; + color: #333; + } + + .close-button { + background: none; + border: none; + font-size: 20px; + cursor: pointer; + color: #999; + } + + .close-button:hover { + color: #333; + } + + .form-group { + margin-bottom: 16px; + } + + .form-label { + display: block; + margin-bottom: 6px; + font-weight: bold; + color: #333; + } + + .form-input { + width: 100%; + padding: 8px 12px; + border: 1px solid #d9d9d9; + border-radius: 4px; + font-size: 14px; + box-sizing: border-box; + } + + .form-input:focus { + outline: none; + border-color: #1890ff; + box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); + } + + .form-input:read-only { + background-color: #f5f5f5; + color: #666; + cursor: not-allowed; + } + + .form-input:read-only:focus { + border-color: #d9d9d9; + box-shadow: none; + } + + .modal-footer { + display: flex; + justify-content: flex-end; + gap: 12px; + margin-top: 24px; + padding-top: 16px; + border-top: 1px solid #e0e0e0; + } + + .btn { + padding: 8px 16px; + border: none; + border-radius: 4px; + cursor: pointer; + font-size: 14px; + transition: opacity 0.2s; + } + + .btn-primary { + background-color: #1890ff; + color: white; + } + + .btn-secondary { + background-color: #f5f5f5; + color: #333; + border: 1px solid #d9d9d9; + } + + .btn:hover { + opacity: 0.8; + } + + .access-modal { + display: none; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + justify-content: center; + align-items: center; + z-index: 1000; + } + + .access-modal-content { + background-color: white; + border-radius: 8px; + padding: 24px; + width: 400px; + max-width: 90%; + } + + .access-modal-header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 20px; + padding-bottom: 10px; + border-bottom: 1px solid #e0e0e0; + } + + .access-modal-title { + font-size: 18px; + font-weight: bold; + color: #333; + } + + .access-close-button { + background: none; + border: none; + font-size: 20px; + cursor: pointer; + color: #999; + } + + .access-close-button:hover { + color: #333; + } + + .access-form-group { + margin-bottom: 16px; + } + + .access-form-label { + display: block; + margin-bottom: 6px; + font-weight: bold; + color: #333; + } + + .access-form-select { + width: 100%; + padding: 8px 12px; + border: 1px solid #d9d9d9; + border-radius: 4px; + font-size: 14px; + box-sizing: border-box; + background-color: white; + } + + .access-form-select:focus { + outline: none; + border-color: #1890ff; + box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2); + } + + .access-modal-footer { + display: flex; + justify-content: flex-end; + gap: 12px; + margin-top: 24px; + padding-top: 16px; + border-top: 1px solid #e0e0e0; + }
用户管理
-
用户管理组件内容(待实现)
+
+ ${this.users.length === 0 ? + '
正在加载用户数据...
' : + ` + + + + + + + + + + + ${this.users.map(user => ` + + + + + + + + `).join('')} + +
ID用户名姓名权限等级操作
${user.id}${user.username}${user.full_name || '-'}${this.getAccessLevelName(user.access_level)} + + + + +
` + } +
+ + + + + +
+
+
+
调整权限级别
+ +
+
+
+ + +
+
+ +
`; } diff --git a/XNSimHtml/routes/auth.js b/XNSimHtml/routes/auth.js index adfea38..29f7961 100644 --- a/XNSimHtml/routes/auth.js +++ b/XNSimHtml/routes/auth.js @@ -289,6 +289,7 @@ router.post('/update-access-level', (req, res) => { if (result === 0) { res.json({ success: true, message: '用户权限级别更新成功' }); } else { + console.error('更新用户权限级别',accessLevel,'失败,错误码:', result); res.status(400).json({ success: false, message: '用户权限级别更新失败', error: `错误码:${result}` }); } } catch (error) { @@ -328,4 +329,91 @@ router.get('/all-users', (req, res) => { } }); +// 重置用户密码路由 +router.post('/reset-password', (req, res) => { + const { userId } = req.body; + + if (!userId) { + return res.status(400).json({ success: false, message: '用户ID不能为空' }); + } + + try { + if (!loginLib) { + throw new Error('动态库未正确加载'); + } + + const result = loginLib.resetPassword(parseInt(userId)); + + if (result === 0) { + res.json({ success: true, message: '密码重置成功' }); + } else { + res.status(400).json({ success: false, message: '密码重置失败', error: `错误码:${result}` }); + } + } catch (error) { + res.status(500).json({ success: false, message: '服务器内部错误', error: error.message }); + } +}); + +// 删除用户路由 +router.delete('/delete-user', (req, res) => { + const { userId } = req.body; + + if (!userId) { + return res.status(400).json({ success: false, message: '用户ID不能为空' }); + } + + try { + if (!loginLib) { + throw new Error('动态库未正确加载'); + } + + const result = loginLib.deleteUser(parseInt(userId)); + + if (result === 0) { + res.json({ success: true, message: '用户删除成功' }); + } else { + res.status(400).json({ success: false, message: '用户删除失败', error: `错误码:${result}` }); + } + } catch (error) { + res.status(500).json({ success: false, message: '服务器内部错误', error: error.message }); + } +}); + +// 获取用户信息路由 +router.get('/user-info/:userId', (req, res) => { + const { userId } = req.params; + + if (!userId) { + return res.status(400).json({ success: false, message: '用户ID不能为空' }); + } + + try { + if (!loginLib) { + throw new Error('动态库未正确加载'); + } + + const userInfoBuffer = Buffer.alloc(1024); + const result = loginLib.getUserInfo(parseInt(userId), userInfoBuffer, userInfoBuffer.length); + + if (result === 0) { + // 找到字符串结束位置 + const zeroIndex = userInfoBuffer.indexOf(0); + const userInfoStr = userInfoBuffer.toString('utf8', 0, zeroIndex >= 0 ? zeroIndex : userInfoBuffer.length); + + try { + const userInfo = JSON.parse(userInfoStr); + res.json({ success: true, user: userInfo }); + } catch (parseError) { + console.error('解析用户信息失败:', parseError); + res.status(500).json({ success: false, message: '解析用户信息失败', error: parseError.message }); + } + } else { + res.status(400).json({ success: false, message: '获取用户信息失败', error: `错误码:${result}` }); + } + } catch (error) { + console.error('获取用户信息过程出错:', error); + res.status(500).json({ success: false, message: '服务器内部错误', error: error.message }); + } +}); + module.exports = router; \ No newline at end of file diff --git a/XNSimHtml/utils/xnCoreService.js b/XNSimHtml/utils/xnCoreService.js index 4109955..eb1bb5d 100644 --- a/XNSimHtml/utils/xnCoreService.js +++ b/XNSimHtml/utils/xnCoreService.js @@ -37,7 +37,9 @@ try { 'changePassword': ['int', ['int', StringType, 'int', StringType, 'int']], 'updateUserInfo': ['int', ['int', StringType, 'int']], 'updateUserAccessLevel': ['int', ['int', 'int']], - 'getAllUsersSimpleInfo': ['int', [StringType, 'int']] + 'getAllUsersSimpleInfo': ['int', [StringType, 'int']], + 'resetPassword': ['int', ['int']], + 'deleteUser': ['int', ['int']] }); } catch (error) { console.error(`加载 ${loginLibName} 失败:`, error); @@ -566,6 +568,40 @@ function stopCollectData() { } } +// 重置用户密码 +function resetPassword(userId) { + if (!loginLib) { + return '登录库未加载'; + } + try { + const result = loginLib.resetPassword(userId); + if (result === 0) { + return '密码重置成功'; + } else { + return `密码重置失败,错误码:${result}`; + } + } catch (error) { + return `密码重置失败: ${error.message}`; + } +} + +// 删除用户 +function deleteUser(userId) { + if (!loginLib) { + return '登录库未加载'; + } + try { + const result = loginLib.deleteUser(userId); + if (result === 0) { + return '用户删除成功'; + } else { + return `用户删除失败,错误码:${result}`; + } + } catch (error) { + return `用户删除失败: ${error.message}`; + } +} + module.exports = { loginLib, monitorLib, @@ -595,5 +631,7 @@ module.exports = { getCsvDataInjectStatus, startCollectData, getCollectDataStatus, - stopCollectData + stopCollectData, + resetPassword, + deleteUser }; \ No newline at end of file