Skip to content

Commit 4f31d56

Browse files
authored
Merge pull request #538 from huxianc/feat/import_export_settings
feat: 支持导入导出设置
2 parents d3b284c + 918299f commit 4f31d56

File tree

1 file changed

+191
-4
lines changed

1 file changed

+191
-4
lines changed

src/registerCommand.ts

Lines changed: 191 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,22 @@
1-
import { commands, ExtensionContext, window } from 'vscode';
1+
import { commands, ExtensionContext, window, workspace, Uri } from 'vscode';
2+
import * as os from 'os';
3+
import * as path from 'path';
4+
5+
/**
6+
* 获取设置文件的默认路径
7+
* 优先选择当前工作区目录,如果没有工作区则选择下载目录
8+
*/
9+
function getDefaultSettingsPath(filename: string = 'leek-fund.settings.json'): string {
10+
const workspaceFolders = workspace.workspaceFolders;
11+
12+
if (workspaceFolders && workspaceFolders.length > 0) {
13+
// 使用当前工作区目录
14+
return path.join(workspaceFolders[0].uri.fsPath, filename);
15+
} else {
16+
// 使用下载目录作为备选
17+
return path.join(os.homedir(), 'Downloads', filename);
18+
}
19+
}
220
import fundSuggestList from './data/fundSuggestData';
321
import { BinanceProvider } from './explorer/binanceProvider';
422
import BinanceService from './explorer/binanceService';
@@ -367,9 +385,7 @@ export function registerViewEvent(
367385

368386
/* 点击交易对 */
369387
context.subscriptions.push(
370-
commands.registerCommand('leek-fund.binanceItemClick', (code, name) =>
371-
binanceTrend(name)
372-
)
388+
commands.registerCommand('leek-fund.binanceItemClick', (code, name) => binanceTrend(name))
373389
);
374390

375391
/**
@@ -450,6 +466,14 @@ export function registerViewEvent(
450466
label: globalState.stockHeldTipShow ? '关闭持仓高亮' : '开启持仓高亮',
451467
description: 'stockHeldTipShow',
452468
},
469+
{
470+
label: '📤 导出设置',
471+
description: 'exportSettings',
472+
},
473+
{
474+
label: '📥 导入设置',
475+
description: 'importSettings',
476+
},
453477
],
454478
{
455479
placeHolder: '第一步:选择设置项',
@@ -541,6 +565,10 @@ export function registerViewEvent(
541565
commands.executeCommand('leek-fund.toggleKLineChartSwitch');
542566
} else if (type === 'stockHeldTipShow') {
543567
commands.executeCommand('leek-fund.toggleStockHeldTipShow');
568+
} else if (type === 'exportSettings') {
569+
commands.executeCommand('leek-fund.exportSettings');
570+
} else if (type === 'importSettings') {
571+
commands.executeCommand('leek-fund.importSettings');
544572
}
545573
});
546574
})
@@ -633,6 +661,165 @@ export function registerViewEvent(
633661
globalState.immersiveBackground = isChecked;
634662
})
635663
);
664+
665+
// Settings Import/Export Commands
666+
context.subscriptions.push(
667+
commands.registerCommand('leek-fund.exportSettings', async () => {
668+
try {
669+
const workspaceConfig = workspace.getConfiguration();
670+
const allSettings: any = {};
671+
672+
// Get all leek-fund settings dynamically from extension context
673+
const extensionManifest = globalState.context.extension.packageJSON;
674+
const configurationProperties = extensionManifest.contributes?.configuration?.properties || {};
675+
676+
// Filter to only leek-fund configuration keys
677+
const leekFundConfigKeys = Object.keys(configurationProperties).filter(key =>
678+
key.startsWith('leek-fund.')
679+
);
680+
681+
// Get all leek-fund settings that have actual values
682+
leekFundConfigKeys.forEach(key => {
683+
const value = workspaceConfig.get(key);
684+
if (value !== undefined) {
685+
allSettings[key] = value;
686+
}
687+
});
688+
689+
// Additional inspection method as fallback to catch any dynamically created settings
690+
const leekFundInspection = workspaceConfig.inspect('leek-fund');
691+
const inspectionSources = [
692+
leekFundInspection?.globalValue,
693+
leekFundInspection?.workspaceValue,
694+
leekFundInspection?.workspaceFolderValue
695+
];
696+
697+
inspectionSources.forEach(source => {
698+
if (source && typeof source === 'object') {
699+
Object.keys(source).forEach(key => {
700+
const fullKey = `leek-fund.${key}`;
701+
if (!allSettings[fullKey]) {
702+
const value = workspaceConfig.get(fullKey);
703+
if (value !== undefined) {
704+
allSettings[fullKey] = value;
705+
}
706+
}
707+
});
708+
}
709+
});
710+
711+
if (Object.keys(allSettings).length === 0) {
712+
window.showInformationMessage('没有找到任何以 "leek-fund." 开头的设置');
713+
return;
714+
}
715+
716+
// Show save dialog
717+
const uri = await window.showSaveDialog({
718+
defaultUri: Uri.file(getDefaultSettingsPath()),
719+
filters: {
720+
'JSON files': ['json'],
721+
'All files': ['*'],
722+
},
723+
});
724+
725+
if (uri) {
726+
const settingsJson = JSON.stringify(allSettings, null, 2);
727+
await workspace.fs.writeFile(uri, Buffer.from(settingsJson));
728+
window.showInformationMessage(`设置已导出到: ${uri.fsPath}`);
729+
}
730+
} catch (error) {
731+
window.showErrorMessage(`导出设置失败: ${error}`);
732+
}
733+
})
734+
);
735+
736+
context.subscriptions.push(
737+
commands.registerCommand('leek-fund.importSettings', async () => {
738+
try {
739+
// Show open dialog
740+
const uris = await window.showOpenDialog({
741+
defaultUri: Uri.file(getDefaultSettingsPath()),
742+
canSelectFiles: true,
743+
canSelectFolders: false,
744+
canSelectMany: false,
745+
filters: {
746+
'JSON files': ['json'],
747+
'All files': ['*'],
748+
},
749+
});
750+
751+
if (!uris || uris.length === 0) {
752+
return;
753+
}
754+
755+
const uri = uris[0];
756+
const content = await workspace.fs.readFile(uri);
757+
const settingsText = Buffer.from(content).toString('utf8');
758+
759+
let importedSettings: any;
760+
try {
761+
importedSettings = JSON.parse(settingsText);
762+
} catch (parseError) {
763+
window.showErrorMessage('无法解析 JSON 文件,请检查文件格式');
764+
return;
765+
}
766+
767+
// Filter settings that start with 'leek-fund.'
768+
const leekFundSettings: any = {};
769+
Object.keys(importedSettings).forEach((key) => {
770+
if (key.startsWith('leek-fund.')) {
771+
leekFundSettings[key] = importedSettings[key];
772+
}
773+
});
774+
775+
if (Object.keys(leekFundSettings).length === 0) {
776+
window.showInformationMessage('文件中没有找到任何以 "leek-fund." 开头的设置');
777+
return;
778+
}
779+
780+
// Confirm import
781+
const result = await window.showInformationMessage(
782+
`将导入 ${Object.keys(leekFundSettings).length} 个设置项,这将覆盖现有的设置。是否继续?`,
783+
'确认导入',
784+
'取消'
785+
);
786+
787+
if (result !== '确认导入') {
788+
return;
789+
}
790+
791+
// Import settings
792+
const workspaceConfig = workspace.getConfiguration();
793+
let successCount = 0;
794+
let failCount = 0;
795+
796+
for (const [key, value] of Object.entries(leekFundSettings)) {
797+
try {
798+
await workspaceConfig.update(key, value, true);
799+
successCount++;
800+
} catch (error) {
801+
console.error(`Failed to import setting ${key}:`, error);
802+
failCount++;
803+
}
804+
}
805+
806+
if (successCount > 0) {
807+
window.showInformationMessage(
808+
`设置导入完成:成功 ${successCount}${failCount > 0 ? `,失败 ${failCount} 项` : ''}`
809+
);
810+
811+
// Refresh the extension state
812+
commands.executeCommand('leek-fund.refreshFund');
813+
commands.executeCommand('leek-fund.refreshStock');
814+
} else {
815+
window.showErrorMessage('导入设置失败');
816+
}
817+
} catch (error) {
818+
window.showErrorMessage(`导入设置失败: ${error}`);
819+
}
820+
})
821+
);
822+
636823
// checkForUpdate();
637824
}
638825

0 commit comments

Comments
 (0)