V0.25.0.250617_alpha:用户信息改为C++后端获取

This commit is contained in:
jinchao 2025-06-17 16:55:20 +08:00
parent 3af9774439
commit d494ba6e1b
7 changed files with 193 additions and 32 deletions

View File

@ -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<const char *>(sqlite3_column_text(stmt, 0));
userInfo["username"] = username;
userInfo["full_name"] =
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 1));
// access_level 解密
std::string accessLevelEnc =
reinterpret_cast<const char *>(sqlite3_column_text(stmt, 2));
std::vector<unsigned char> iv_and_ciphertext = hex2bin(accessLevelEnc);
if (iv_and_ciphertext.size() < 16) {
userInfo["access_level"] = nullptr;
} else {
std::vector<unsigned char> iv(iv_and_ciphertext.begin(),
iv_and_ciphertext.begin() + 16);
std::vector<unsigned char> ciphertext(iv_and_ciphertext.begin() + 16,
iv_and_ciphertext.end());
std::string fixed_key = "XNSim_Access_Key";
std::vector<unsigned char> 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;
}
}

Binary file not shown.

View File

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

View File

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

View File

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

View File

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

View File

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