完成基础功能
This commit is contained in:
parent
855d0c8c28
commit
4370189e81
2
TODO.md
2
TODO.md
@ -9,7 +9,7 @@
|
||||
---
|
||||
|
||||
- [x] 实现子网路由功能
|
||||
- [ ] 实现配置保存和加载功能(支持加密私钥)
|
||||
- [x] 实现配置保存和加载功能(支持加密私钥)
|
||||
|
||||
---
|
||||
|
||||
|
||||
30
src/App.tsx
30
src/App.tsx
@ -151,12 +151,14 @@ function FlowContent(): ReactNode {
|
||||
const handleSaveConfig = async (pass?: string): Promise<void> => {
|
||||
try {
|
||||
const saveConfig: SaveConfig = {settings: settings, nodes: [], edges: [], encrypted: false}
|
||||
if(pass) saveConfig.encrypted = true;
|
||||
|
||||
nodes.forEach(node => {
|
||||
const nodeData = node.data;
|
||||
let privateKey = nodeData.privateKey;
|
||||
if(pass && typeof privateKey === 'string') privateKey = CryptoJS.AES.encrypt(privateKey, pass).toString();
|
||||
let privateKey: string = nodeData.privateKey;
|
||||
if(pass) {
|
||||
privateKey = CryptoJS.AES.encrypt(privateKey, pass).toString();
|
||||
saveConfig.encrypted = true;
|
||||
}
|
||||
saveConfig.nodes.push({...node, data: {...nodeData, privateKey: privateKey}});
|
||||
});
|
||||
|
||||
@ -184,13 +186,13 @@ function FlowContent(): ReactNode {
|
||||
|
||||
if (saveConfig.encrypted) {
|
||||
if (!pass) { toast.error('需要密码以解密私钥'); return; }
|
||||
try {
|
||||
for(let node of saveConfig.nodes) {
|
||||
node.data.privateKey = CryptoJS.AES.decrypt(node.data.privateKey, pass).toString(CryptoJS.enc.Utf8);
|
||||
for(let node of saveConfig.nodes) {
|
||||
const privateKey = CryptoJS.AES.decrypt(node.data.privateKey, pass).toString(CryptoJS.enc.Utf8);
|
||||
if(!privateKey) {
|
||||
toast.error('密码错误');
|
||||
return;
|
||||
}
|
||||
} catch (err) {
|
||||
toast.error('解密失败: ' + err);
|
||||
return;
|
||||
node.data.privateKey = privateKey;
|
||||
}
|
||||
}
|
||||
setSettings(saveConfig.settings);
|
||||
@ -233,11 +235,6 @@ function FlowContent(): ReactNode {
|
||||
|
||||
<div className="toolbar">
|
||||
<div className="toolbar-group">
|
||||
<div className="action-section">
|
||||
<div className="section-title">文件操作</div>
|
||||
<SaveLoadPanel onSave={handleSaveConfig} onLoad={handleLoadConfig} />
|
||||
</div>
|
||||
|
||||
<div className="action-section">
|
||||
<div className="section-title">图表操作</div>
|
||||
<Toggle
|
||||
@ -253,6 +250,11 @@ function FlowContent(): ReactNode {
|
||||
📋 设置
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="action-section">
|
||||
<div className="section-title">文件操作</div>
|
||||
<SaveLoadPanel onSave={handleSaveConfig} onLoad={handleLoadConfig} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
border-radius:4px;
|
||||
}
|
||||
/* Use .toolbar-btn for button styles so Save/Load matches other toolbar actions */
|
||||
.save-load-panel .toolbar-btn{width:100%;text-align:left;padding:8px 16px;border-radius:4px}
|
||||
.save-load-panel .toolbar-btn{width:100%;text-align:center;padding:8px 16px;border-radius:4px}
|
||||
/* divider removed to match toolbar style */
|
||||
|
||||
/* Modal styles */
|
||||
|
||||
@ -73,7 +73,7 @@ export default function SaveLoadPanel({ onSave, onLoad }: Props) {
|
||||
<button className="sl-close" onClick={closeModal}>✕</button>
|
||||
</div>
|
||||
<div className="sl-modal-body">
|
||||
<label className="sl-label">加密密码(可选)</label>
|
||||
<label className="sl-label">加密密码</label>
|
||||
<input type="password" className="sl-input" value={password} onChange={e => setPassword(e.target.value)} />
|
||||
|
||||
{modalType === 'load' ? (
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user