diff --git a/Login/login.cpp b/Login/login.cpp index 803da44..49c4d87 100644 --- a/Login/login.cpp +++ b/Login/login.cpp @@ -739,3 +739,63 @@ extern "C" LOGIN_EXPORT int updateUserAccessLevel(int user_id, int access_level) return -1; } } + +// 获取所有用户的username、full_name和access_level,返回JSON数组字符串 +extern "C" LOGIN_EXPORT int getAllUsersSimpleInfo(char *result, int result_length) +{ + try { + const char *xnCorePath = std::getenv("XNCore"); + if (!xnCorePath) { + return -1; + } + fs::path dbPath = fs::path(xnCorePath) / "database" / "XNSim.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"; + 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["username"] = username; + userInfo["full_name"] = + reinterpret_cast(sqlite3_column_text(stmt, 1)); + // access_level 解密 + std::string accessLevelEnc = + reinterpret_cast(sqlite3_column_text(stmt, 2)); + std::vector iv_and_ciphertext = hex2bin(accessLevelEnc); + if (iv_and_ciphertext.size() < 16) { + userInfo["access_level"] = nullptr; + } else { + std::vector iv(iv_and_ciphertext.begin(), + iv_and_ciphertext.begin() + 16); + std::vector ciphertext(iv_and_ciphertext.begin() + 16, + iv_and_ciphertext.end()); + std::string fixed_key = "XNSim_Access_Key"; + std::vector key = derive_aes_key(username, fixed_key); + try { + std::string accessLevelStr = aes_decrypt(ciphertext, key, iv); + userInfo["access_level"] = std::stoi(accessLevelStr); + } catch (...) { + userInfo["access_level"] = nullptr; + } + } + arr.push_back(userInfo); + } + sqlite3_finalize(stmt); + } + sqlite3_close(db); + std::string jsonStr = arr.dump(); + if (result_length >= jsonStr.size() + 1) { + std::strcpy(result, jsonStr.c_str()); + return 0; + } else { + return -1; + } + } catch (const std::exception &) { + return -1; + } +} diff --git a/Release/database/XNSim.db b/Release/database/XNSim.db index d6eeccd..013182d 100644 Binary files a/Release/database/XNSim.db and b/Release/database/XNSim.db differ diff --git a/XNSimHtml/components/todo/todo-service.js b/XNSimHtml/components/todo/todo-service.js index b025161..2bcbf06 100644 --- a/XNSimHtml/components/todo/todo-service.js +++ b/XNSimHtml/components/todo/todo-service.js @@ -8,11 +8,14 @@ class TodoService { } static async fetchUsers() { - const response = await fetch('/api/users/basic-info'); + const response = await fetch('/api/all-users'); if (!response.ok) { throw new Error('获取用户数据失败'); } const data = await response.json(); + if (!data.success) { + throw new Error(data.message || '获取用户数据失败'); + } return data.users || []; } diff --git a/XNSimHtml/routes/auth.js b/XNSimHtml/routes/auth.js index 4546909..adfea38 100644 --- a/XNSimHtml/routes/auth.js +++ b/XNSimHtml/routes/auth.js @@ -204,4 +204,128 @@ router.get('/env', (req, res) => { res.json({ name, value }); }); +// 修改密码路由 +router.post('/change-password', (req, res) => { + const { userId, oldPassword, newPassword } = req.body; + + if (!userId || !oldPassword || !newPassword) { + return res.status(400).json({ success: false, message: '用户ID、旧密码和新密码不能为空' }); + } + + try { + if (!loginLib) { + throw new Error('动态库未正确加载'); + } + + const oldPasswordData = stringToBuffer(oldPassword); + const newPasswordData = stringToBuffer(newPassword); + + const result = loginLib.changePassword( + userId, + oldPasswordData.buffer, + oldPasswordData.length, + newPasswordData.buffer, + newPasswordData.length + ); + + if (result === 0) { + res.json({ success: true, 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 }); + } +}); + +// 更新用户信息路由 +router.post('/update-user-info', (req, res) => { + const { userId, userInfo } = req.body; + + if (!userId || !userInfo) { + return res.status(400).json({ success: false, message: '用户ID和用户信息不能为空' }); + } + + try { + if (!loginLib) { + throw new Error('动态库未正确加载'); + } + + const userInfoData = stringToBuffer(JSON.stringify(userInfo)); + + const result = loginLib.updateUserInfo( + userId, + userInfoData.buffer, + userInfoData.length + ); + + if (result === 0) { + res.json({ success: true, 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 }); + } +}); + +// 更新用户权限级别路由 +router.post('/update-access-level', (req, res) => { + const { userId, accessLevel } = req.body; + + if (!userId || accessLevel === undefined) { + return res.status(400).json({ success: false, message: '用户ID和权限级别不能为空' }); + } + + try { + if (!loginLib) { + throw new Error('动态库未正确加载'); + } + + const result = loginLib.updateUserAccessLevel(userId, accessLevel); + + if (result === 0) { + res.json({ success: true, 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 }); + } +}); + +// 获取所有用户简要信息路由 +router.get('/all-users', (req, res) => { + try { + if (!loginLib) { + throw new Error('动态库未正确加载'); + } + + const resultBuffer = Buffer.alloc(8192); // 分配8KB的缓冲区 + const result = loginLib.getAllUsersSimpleInfo(resultBuffer, resultBuffer.length); + + if (result === 0) { + // 找到字符串结束位置 + const zeroIndex = resultBuffer.indexOf(0); + const usersInfoStr = resultBuffer.toString('utf8', 0, zeroIndex >= 0 ? zeroIndex : resultBuffer.length); + + try { + const usersInfo = JSON.parse(usersInfoStr); + res.json({ success: true, users: usersInfo }); + } 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/routes/users.js b/XNSimHtml/routes/users.js deleted file mode 100644 index 74f17f8..0000000 --- a/XNSimHtml/routes/users.js +++ /dev/null @@ -1,28 +0,0 @@ -const express = require('express'); -const router = express.Router(); -const { getUsers } = require('../utils/db-utils'); - -// 获取所有用户的基本信息(用户名、姓名和权限等级) -router.get('/users/basic-info', async (req, res) => { - try { - const users = await getUsers(); - // 只返回必要的字段 - const simplifiedUsers = users.map(user => ({ - username: user.username, - full_name: user.full_name, - access_level: user.access_level - })); - res.json({ - success: true, - users: simplifiedUsers - }); - } catch (error) { - console.error('获取用户信息失败:', error); - res.status(500).json({ - success: false, - message: '获取用户信息失败' - }); - } -}); - -module.exports = router; \ No newline at end of file diff --git a/XNSimHtml/server.js b/XNSimHtml/server.js index 8ea8ba6..452ee50 100644 --- a/XNSimHtml/server.js +++ b/XNSimHtml/server.js @@ -22,7 +22,6 @@ const interfaceRoutes = require('./routes/interface-config'); const icdImportRoutes = require('./routes/icd-import'); const qaRoutes = require('./routes/qa'); const todoRoutes = require('./routes/todos'); -const userRoutes = require('./routes/users'); const systemLogRoutes = require('./routes/system-log'); const ddsMonitorRoutes = require('./routes/DDSMonitor'); const systemMonitorRoutes = require('./routes/SystemMonitor'); @@ -103,7 +102,6 @@ app.use('/api/interface', interfaceRoutes); app.use('/api/icd', icdImportRoutes); app.use('/api/qa', qaRoutes); app.use('/api/todos', todoRoutes); -app.use('/api', userRoutes); app.use('/api/system-log', systemLogRoutes); app.use('/api/dds-monitor', ddsMonitorRoutes); app.use('/api/system-monitor', systemMonitorRoutes); diff --git a/XNSimHtml/utils/xnCoreService.js b/XNSimHtml/utils/xnCoreService.js index ea4d3b5..4109955 100644 --- a/XNSimHtml/utils/xnCoreService.js +++ b/XNSimHtml/utils/xnCoreService.js @@ -33,7 +33,11 @@ try { 'validateUser': ['int', [StringType, 'int', StringType, 'int']], 'getUserInfo': ['int', ['int', StringType, 'int']], 'cleanup': ['void', []], - 'registerUser': ['int', [StringType, 'int', StringType, 'int', StringType, 'int']] + 'registerUser': ['int', [StringType, 'int', StringType, 'int', StringType, 'int']], + 'changePassword': ['int', ['int', StringType, 'int', StringType, 'int']], + 'updateUserInfo': ['int', ['int', StringType, 'int']], + 'updateUserAccessLevel': ['int', ['int', 'int']], + 'getAllUsersSimpleInfo': ['int', [StringType, 'int']] }); } catch (error) { console.error(`加载 ${loginLibName} 失败:`, error);