update
This commit is contained in:
@@ -12,7 +12,7 @@ export const settingsRepository = {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.all('SELECT key, value FROM settings', (err: any, rows: Setting[]) => { // 添加 err 类型
|
||||
if (err) {
|
||||
console.error('获取所有设置时出错:', err); // 更新日志为中文
|
||||
console.error('[Repository] 获取所有设置时出错:', err); // 更新日志为中文
|
||||
reject(new Error('获取设置失败')); // 更新错误消息为中文
|
||||
} else {
|
||||
resolve(rows);
|
||||
@@ -23,11 +23,13 @@ export const settingsRepository = {
|
||||
|
||||
async getSetting(key: string): Promise<string | null> {
|
||||
return new Promise((resolve, reject) => {
|
||||
console.log(`[Repository] Attempting to get setting with key: ${key}`); // +++ 添加日志 +++
|
||||
db.get('SELECT value FROM settings WHERE key = ?', [key], (err: any, row: { value: string } | undefined) => { // 添加 err 类型
|
||||
if (err) {
|
||||
console.error(`获取设置项 ${key} 时出错:`, err); // 更新日志为中文
|
||||
console.error(`[Repository] 获取设置项 ${key} 时出错:`, err); // 更新日志为中文
|
||||
reject(new Error(`获取设置项 ${key} 失败`)); // 更新错误消息为中文
|
||||
} else {
|
||||
console.log(`[Repository] Found value for key ${key}:`, row ? row.value : null); // +++ 添加日志 +++
|
||||
resolve(row ? row.value : null);
|
||||
}
|
||||
});
|
||||
@@ -37,18 +39,26 @@ export const settingsRepository = {
|
||||
async setSetting(key: string, value: string): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const now = Math.floor(Date.now() / 1000); // 获取当前 Unix 时间戳
|
||||
db.run(
|
||||
`INSERT INTO settings (key, value, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?)
|
||||
ON CONFLICT(key) DO UPDATE SET
|
||||
const sql = `INSERT INTO settings (key, value, created_at, updated_at)
|
||||
VALUES (?, ?, ?, ?)
|
||||
ON CONFLICT(key) DO UPDATE SET
|
||||
value = excluded.value,
|
||||
updated_at = excluded.updated_at`,
|
||||
[key, value, now, now],
|
||||
function (err: any) { // 添加 err 类型
|
||||
updated_at = excluded.updated_at`;
|
||||
const params = [key, value, now, now];
|
||||
|
||||
console.log(`[Repository] Attempting to set setting. Key: ${key}, Value: ${value}`); // +++ 添加日志 +++
|
||||
console.log(`[Repository] Executing SQL: ${sql} with params: ${JSON.stringify(params)}`); // +++ 添加日志 +++
|
||||
|
||||
db.run(
|
||||
sql,
|
||||
params,
|
||||
function (this: any, err: any) { // 使用 this 需要 function 声明, 添加 err 类型
|
||||
if (err) {
|
||||
console.error(`设置设置项 ${key} 时出错:`, err); // 更新日志为中文
|
||||
console.error(`[Repository] 设置设置项 ${key} 时出错:`, err); // 更新日志为中文
|
||||
reject(new Error(`设置设置项 ${key} 失败`)); // 更新错误消息为中文
|
||||
} else {
|
||||
// this.changes 提供了受影响的行数 (对于 INSERT/UPDATE)
|
||||
console.log(`[Repository] Successfully set setting for key: ${key}. Rows affected: ${this.changes}`); // +++ 添加日志 +++
|
||||
resolve();
|
||||
}
|
||||
}
|
||||
@@ -58,11 +68,13 @@ export const settingsRepository = {
|
||||
|
||||
async deleteSetting(key: string): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
db.run('DELETE FROM settings WHERE key = ?', [key], function (err: any) { // 添加 err 类型
|
||||
console.log(`[Repository] Attempting to delete setting with key: ${key}`); // +++ 添加日志 +++
|
||||
db.run('DELETE FROM settings WHERE key = ?', [key], function (this: any, err: any) { // 添加 err 类型
|
||||
if (err) {
|
||||
console.error(`删除设置项 ${key} 时出错:`, err); // 更新日志为中文
|
||||
console.error(`[Repository] 删除设置项 ${key} 时出错:`, err); // 更新日志为中文
|
||||
reject(new Error(`删除设置项 ${key} 失败`)); // 更新错误消息为中文
|
||||
} else {
|
||||
console.log(`[Repository] Successfully deleted setting for key: ${key}. Rows affected: ${this.changes}`); // +++ 添加日志 +++
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
@@ -70,9 +82,11 @@ export const settingsRepository = {
|
||||
},
|
||||
|
||||
async setMultipleSettings(settings: Record<string, string>): Promise<void> {
|
||||
console.log('[Repository] setMultipleSettings called with:', JSON.stringify(settings)); // +++ 添加日志 +++
|
||||
const promises = Object.entries(settings).map(([key, value]) =>
|
||||
this.setSetting(key, value)
|
||||
this.setSetting(key, value) // this 指向 settingsRepository 对象
|
||||
);
|
||||
await Promise.all(promises);
|
||||
console.log('[Repository] setMultipleSettings finished.'); // +++ 添加日志 +++
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
import { settingsRepository, Setting } from '../repositories/settings.repository';
|
||||
|
||||
// +++ 定义默认的焦点切换顺序 +++
|
||||
const DEFAULT_FOCUS_SEQUENCE = ["quickCommandsSearch", "commandHistorySearch", "fileManagerSearch", "commandInput", "terminalSearch"];
|
||||
const FOCUS_SEQUENCE_KEY = 'focusSwitcherSequence'; // +++ 定义设置键常量 +++
|
||||
|
||||
export const settingsService = {
|
||||
// ... (getAllSettings, getSetting, setSetting, setMultipleSettings, deleteSetting, getIpWhitelistSettings, updateIpWhitelistSettings, getFocusSwitcherSequence 保持不变) ...
|
||||
|
||||
/**
|
||||
* 获取所有设置项
|
||||
* @returns 返回包含所有设置项的数组
|
||||
@@ -76,4 +82,57 @@ export const settingsService = {
|
||||
settingsRepository.setSetting('ipWhitelist', whitelist),
|
||||
]);
|
||||
},
|
||||
|
||||
// +++ 新增:获取焦点切换顺序 +++
|
||||
/**
|
||||
* 获取焦点切换顺序
|
||||
* @returns 返回存储的焦点切换顺序数组,如果未设置或无效则返回默认顺序
|
||||
*/
|
||||
async getFocusSwitcherSequence(): Promise<string[]> {
|
||||
console.log(`[Service] Attempting to get setting for key: ${FOCUS_SEQUENCE_KEY}`); // +++ 添加日志 +++
|
||||
try {
|
||||
const sequenceJson = await settingsRepository.getSetting(FOCUS_SEQUENCE_KEY);
|
||||
console.log(`[Service] Raw value from repository for ${FOCUS_SEQUENCE_KEY}:`, sequenceJson); // +++ 添加日志 +++
|
||||
if (sequenceJson) {
|
||||
const sequence = JSON.parse(sequenceJson);
|
||||
// 基本验证:确保它是一个数组并且包含字符串
|
||||
if (Array.isArray(sequence) && sequence.every(item => typeof item === 'string')) {
|
||||
console.log('[Service] Fetched and validated focus switcher sequence:', JSON.stringify(sequence)); // +++ 更新日志 +++
|
||||
return sequence;
|
||||
} else {
|
||||
console.warn('[Service] Invalid focus switcher sequence format found in settings. Returning default.');
|
||||
}
|
||||
} else {
|
||||
console.log('[Service] No focus switcher sequence found in settings. Returning default.');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[Service] Error parsing focus switcher sequence from settings (key: ${FOCUS_SEQUENCE_KEY}):`, error); // +++ 更新日志 +++
|
||||
}
|
||||
// 如果发生错误或未找到/无效,返回默认值
|
||||
console.log('[Service] Returning default focus sequence:', JSON.stringify(DEFAULT_FOCUS_SEQUENCE)); // +++ 添加日志 +++
|
||||
return [...DEFAULT_FOCUS_SEQUENCE]; // 返回默认值的副本
|
||||
},
|
||||
|
||||
// +++ 新增:设置焦点切换顺序 +++
|
||||
/**
|
||||
* 设置焦点切换顺序
|
||||
* @param sequence 要保存的焦点切换顺序数组
|
||||
*/
|
||||
async setFocusSwitcherSequence(sequence: string[]): Promise<void> {
|
||||
console.log('[Service] setFocusSwitcherSequence called with:', JSON.stringify(sequence)); // +++ 添加日志 +++
|
||||
// 基本验证
|
||||
if (!Array.isArray(sequence) || !sequence.every(item => typeof item === 'string')) {
|
||||
console.error('[Service] Attempted to save invalid focus switcher sequence format:', sequence);
|
||||
throw new Error('Invalid sequence format provided.'); // 抛出错误阻止保存无效数据
|
||||
}
|
||||
try {
|
||||
const sequenceJson = JSON.stringify(sequence);
|
||||
console.log(`[Service] Attempting to save setting. Key: ${FOCUS_SEQUENCE_KEY}, Value: ${sequenceJson}`); // +++ 添加日志 +++
|
||||
await settingsRepository.setSetting(FOCUS_SEQUENCE_KEY, sequenceJson);
|
||||
console.log(`[Service] Successfully saved setting for key: ${FOCUS_SEQUENCE_KEY}`); // +++ 添加日志 +++
|
||||
} catch (error) {
|
||||
console.error(`[Service] Error calling settingsRepository.setSetting for key ${FOCUS_SEQUENCE_KEY}:`, error); // +++ 更新日志 +++
|
||||
throw new Error('Failed to save focus switcher sequence.'); // 重新抛出错误
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -6,6 +6,8 @@ import { ipBlacklistService } from '../services/ip-blacklist.service'; // 引入
|
||||
const auditLogService = new AuditLogService(); // 实例化 AuditLogService
|
||||
|
||||
export const settingsController = {
|
||||
// ... (getAllSettings, updateSettings, getFocusSwitcherSequence 保持不变) ...
|
||||
|
||||
/**
|
||||
* 获取所有设置项
|
||||
*/
|
||||
@@ -31,11 +33,11 @@ export const settingsController = {
|
||||
return;
|
||||
}
|
||||
|
||||
// --- 过滤掉外观设置相关的键 ---
|
||||
// --- 过滤掉外观设置和焦点切换顺序相关的键 ---
|
||||
const allowedSettingsKeys = [
|
||||
'language', 'ipWhitelist', 'maxLoginAttempts', 'loginBanDuration',
|
||||
'showPopupFileEditor', 'shareFileEditorTabs', 'ipWhitelistEnabled' // 添加 ipWhitelistEnabled
|
||||
// 在这里添加其他允许的通用设置键
|
||||
'showPopupFileEditor', 'shareFileEditorTabs', 'ipWhitelistEnabled'
|
||||
// 不在此处处理 'focusSwitcherSequence'
|
||||
];
|
||||
const filteredSettings: Record<string, string> = {};
|
||||
for (const key in settingsToUpdate) {
|
||||
@@ -51,29 +53,75 @@ export const settingsController = {
|
||||
}
|
||||
|
||||
// 记录审计日志
|
||||
// 区分 IP 白名单更新和其他设置更新
|
||||
// 注意:现在审计日志可能需要更精细的逻辑,因为它只记录了实际更新的通用设置
|
||||
const updatedKeys = Object.keys(filteredSettings); // 使用过滤后的键
|
||||
if (updatedKeys.length > 0) { // 只有实际更新了才记录
|
||||
const updatedKeys = Object.keys(filteredSettings);
|
||||
if (updatedKeys.length > 0) {
|
||||
if (updatedKeys.includes('ipWhitelist') || updatedKeys.includes('ipWhitelistEnabled')) {
|
||||
auditLogService.logAction('IP_WHITELIST_UPDATED', { updatedKeys });
|
||||
} else {
|
||||
auditLogService.logAction('SETTINGS_UPDATED', { updatedKeys });
|
||||
}
|
||||
}
|
||||
res.status(200).json({ message: '设置已成功更新' }); // 即使没有更新通用设置也返回成功
|
||||
res.status(200).json({ message: '设置已成功更新' });
|
||||
} catch (error: any) {
|
||||
console.error('更新设置时出错:', error);
|
||||
res.status(500).json({ message: '更新设置失败', error: error.message });
|
||||
}
|
||||
},
|
||||
|
||||
// 注意:通常不直接通过 API 提供单个设置项的获取、设置或删除,
|
||||
// 而是通过批量获取/更新来管理。如果需要单独操作,可以添加相应方法。
|
||||
// 例如:
|
||||
// async getSetting(req: Request, res: Response): Promise<void> { ... }
|
||||
// async setSetting(req: Request, res: Response): Promise<void> { ... }
|
||||
// async deleteSetting(req: Request, res: Response): Promise<void> { ... }
|
||||
// +++ 新增:获取焦点切换顺序 +++
|
||||
/**
|
||||
* 获取焦点切换顺序
|
||||
*/
|
||||
async getFocusSwitcherSequence(req: Request, res: Response): Promise<void> {
|
||||
try {
|
||||
console.log('[Controller] Received request to get focus switcher sequence.'); // +++ 添加日志 +++
|
||||
const sequence = await settingsService.getFocusSwitcherSequence();
|
||||
console.log('[Controller] Sending focus switcher sequence to client:', JSON.stringify(sequence)); // +++ 添加日志 +++
|
||||
res.json(sequence);
|
||||
} catch (error: any) {
|
||||
console.error('[Controller] 获取焦点切换顺序时出错:', error); // +++ 更新日志前缀 +++
|
||||
res.status(500).json({ message: '获取焦点切换顺序失败', error: error.message });
|
||||
}
|
||||
},
|
||||
|
||||
// +++ 新增:设置焦点切换顺序 +++
|
||||
/**
|
||||
* 设置焦点切换顺序
|
||||
*/
|
||||
async setFocusSwitcherSequence(req: Request, res: Response): Promise<void> {
|
||||
console.log('[Controller] Received request to set focus switcher sequence.'); // +++ 添加日志 +++
|
||||
try {
|
||||
const { sequence } = req.body;
|
||||
console.log('[Controller] Request body sequence:', JSON.stringify(sequence)); // +++ 添加日志 +++
|
||||
|
||||
// 输入验证
|
||||
if (!Array.isArray(sequence) || !sequence.every(item => typeof item === 'string')) {
|
||||
console.warn('[Controller] Invalid sequence format received:', sequence); // +++ 添加日志 +++
|
||||
res.status(400).json({ message: '无效的请求体,"sequence" 必须是一个字符串数组' });
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('[Controller] Calling settingsService.setFocusSwitcherSequence...'); // +++ 添加日志 +++
|
||||
await settingsService.setFocusSwitcherSequence(sequence);
|
||||
console.log('[Controller] settingsService.setFocusSwitcherSequence completed successfully.'); // +++ 添加日志 +++
|
||||
|
||||
// 记录审计日志 (可选)
|
||||
console.log('[Controller] Logging audit action: FOCUS_SWITCHER_SEQUENCE_UPDATED'); // +++ 添加日志 +++
|
||||
auditLogService.logAction('FOCUS_SWITCHER_SEQUENCE_UPDATED', { sequence });
|
||||
|
||||
console.log('[Controller] Sending success response.'); // +++ 添加日志 +++
|
||||
res.status(200).json({ message: '焦点切换顺序已成功更新' });
|
||||
} catch (error: any) {
|
||||
console.error('[Controller] 设置焦点切换顺序时出错:', error); // +++ 更新日志前缀 +++
|
||||
// 区分是服务层抛出的验证错误还是其他错误
|
||||
if (error.message === 'Invalid sequence format provided.') {
|
||||
res.status(400).json({ message: '设置焦点切换顺序失败: 无效的格式', error: error.message });
|
||||
} else {
|
||||
res.status(500).json({ message: '设置焦点切换顺序失败', error: error.message });
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 获取 IP 黑名单列表 (分页)
|
||||
|
||||
@@ -11,6 +11,13 @@ router.use(isAuthenticated);
|
||||
router.get('/', settingsController.getAllSettings); // GET /api/v1/settings
|
||||
router.put('/', settingsController.updateSettings); // PUT /api/v1/settings
|
||||
|
||||
// +++ 新增:焦点切换顺序路由 +++
|
||||
// GET /api/v1/settings/focus-switcher-sequence - 获取焦点切换顺序
|
||||
router.get('/focus-switcher-sequence', settingsController.getFocusSwitcherSequence);
|
||||
// PUT /api/v1/settings/focus-switcher-sequence - 更新焦点切换顺序
|
||||
router.put('/focus-switcher-sequence', settingsController.setFocusSwitcherSequence);
|
||||
|
||||
|
||||
// --- IP 黑名单管理路由 ---
|
||||
// GET /api/v1/settings/ip-blacklist - 获取 IP 黑名单列表 (需要认证)
|
||||
router.get('/ip-blacklist', settingsController.getIpBlacklist);
|
||||
|
||||
@@ -31,6 +31,7 @@ export type AuditLogActionType =
|
||||
// Settings
|
||||
| 'SETTINGS_UPDATED' // General settings update
|
||||
| 'IP_WHITELIST_UPDATED' // Specific setting update
|
||||
| 'FOCUS_SWITCHER_SEQUENCE_UPDATED' // +++ 新增:焦点切换顺序更新 +++
|
||||
|
||||
// Notifications
|
||||
| 'NOTIFICATION_SETTING_CREATED'
|
||||
|
||||
Reference in New Issue
Block a user