V0.26.0.250618_alpha:完成了用户管理页面

This commit is contained in:
jinchao 2025-06-18 10:17:38 +08:00
parent d494ba6e1b
commit f0b97d210e
6 changed files with 880 additions and 53 deletions

View File

@ -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<std::chrono::milliseconds>(
@ -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::milliseconds>(
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::milliseconds>(
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<const char *>(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::milliseconds>(
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<std::string>().c_str(), -1,
SQLITE_STATIC);
sqlite3_bind_text(stmt, 2, userInfo["phone"].get<std::string>().c_str(), -1,
SQLITE_STATIC);
sqlite3_bind_text(stmt, 3, userInfo["email"].get<std::string>().c_str(), -1,
SQLITE_STATIC);
sqlite3_bind_text(stmt, 4, userInfo["department"].get<std::string>().c_str(), -1,
SQLITE_STATIC);
sqlite3_bind_text(stmt, 5, userInfo["position"].get<std::string>().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>()
: "";
std::string phone = userInfo.contains("phone") && !userInfo["phone"].is_null()
? userInfo["phone"].get<std::string>()
: "";
std::string email = userInfo.contains("email") && !userInfo["email"].is_null()
? userInfo["email"].get<std::string>()
: "";
std::string department =
userInfo.contains("department") && !userInfo["department"].is_null()
? userInfo["department"].get<std::string>()
: "";
std::string position =
userInfo.contains("position") && !userInfo["position"].is_null()
? userInfo["position"].get<std::string>()
: "";
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::milliseconds>(
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<const char *>(sqlite3_column_text(stmt, 0));
userInfo["id"] = sqlite3_column_int(stmt, 0);
std::string username = reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
userInfo["username"] = username;
userInfo["full_name"] =
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 2));
// access_level 解密
std::string accessLevelEnc =
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 2));
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 3));
std::vector<unsigned char> 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;
}
}

Binary file not shown.

Binary file not shown.

View File

@ -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;
}
</style>
<div class="users-container">
<div class="users-header">
<div class="users-title">用户管理</div>
</div>
<div>用户管理组件内容待实现</div>
<div class="error-message"></div>
${this.users.length === 0 ?
'<div class="loading">正在加载用户数据...</div>' :
`<table class="users-table">
<thead>
<tr>
<th class="col-id">ID</th>
<th class="col-username">用户名</th>
<th class="col-fullname">姓名</th>
<th class="col-access">权限等级</th>
<th class="col-actions">操作</th>
</tr>
</thead>
<tbody>
${this.users.map(user => `
<tr>
<td class="col-id">${user.id}</td>
<td class="col-username">${user.username}</td>
<td class="col-fullname">${user.full_name || '-'}</td>
<td class="col-access">${this.getAccessLevelName(user.access_level)}</td>
<td class="col-actions">
<button class="action-button edit-info" onclick="this.getRootNode().host.handleEditInfo(${user.id})">更改信息</button>
<button class="action-button change-access" onclick="this.getRootNode().host.handleChangeAccessLevel(${user.id})">调整权限</button>
<button class="action-button reset-password" onclick="this.getRootNode().host.handleResetPassword(${user.id})">重置密码</button>
<button class="action-button delete" onclick="this.getRootNode().host.handleDelete(${user.id})">删除</button>
</td>
</tr>
`).join('')}
</tbody>
</table>`
}
</div>
<!-- 编辑用户信息模态对话框 -->
<div class="modal">
<div class="modal-content">
<div class="modal-header">
<div class="modal-title">编辑用户信息</div>
<button class="close-button" onclick="this.getRootNode().host.hideEditModal()">&times;</button>
</div>
<form class="edit-form">
<div class="form-group">
<label class="form-label">用户名</label>
<input type="text" class="form-input" name="username" required readonly>
</div>
<div class="form-group">
<label class="form-label">姓名</label>
<input type="text" class="form-input" name="full_name">
</div>
<div class="form-group">
<label class="form-label">邮箱</label>
<input type="email" class="form-input" name="email">
</div>
<div class="form-group">
<label class="form-label">电话</label>
<input type="text" class="form-input" name="phone">
</div>
<div class="form-group">
<label class="form-label">部门</label>
<input type="text" class="form-input" name="department">
</div>
<div class="form-group">
<label class="form-label">职位</label>
<input type="text" class="form-input" name="position">
</div>
</form>
<div class="modal-footer">
<button class="btn btn-secondary" onclick="this.getRootNode().host.hideEditModal()">取消</button>
<button class="btn btn-primary" onclick="this.getRootNode().host.handleSaveUserInfo()">保存</button>
</div>
</div>
</div>
<!-- 调整权限级别模态对话框 -->
<div class="access-modal">
<div class="access-modal-content">
<div class="access-modal-header">
<div class="access-modal-title">调整权限级别</div>
<button class="access-close-button" onclick="this.getRootNode().host.hideAccessModal()">&times;</button>
</div>
<form class="access-form">
<div class="access-form-group">
<label class="access-form-label">权限级别</label>
<select class="access-form-select" name="access_level" required>
<option value="0">访客</option>
<option value="1">用户</option>
<option value="2">开发人员</option>
<option value="3">组长</option>
</select>
</div>
</form>
<div class="access-modal-footer">
<button class="btn btn-secondary" onclick="this.getRootNode().host.hideAccessModal()">取消</button>
<button class="btn btn-primary" onclick="this.getRootNode().host.handleSaveAccessLevel()">保存</button>
</div>
</div>
</div>
`;
}

View File

@ -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;

View File

@ -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
};