88</ head >
99< body >
1010 < div class ="toolbar ">
11- < button id ="newNode " class ="toolbar-btn ">
12- < span class ="icon "> +</ span > 新建节点
13- </ button >
14- < button id ="loadFlowchart " class ="toolbar-btn ">
15- < span class ="icon "> 📂</ span > 加载流程图
16- </ button >
17- < button id ="save " class ="toolbar-btn ">
18- < span class ="icon "> 💾</ span > 保存流程图
19- </ button >
20- < button id ="toggleAllCode " class ="toolbar-btn ">
21- < span class ="icon "> 📝</ span > < span id ="toggleAllCodeText "> 展开所有代码</ span >
22- </ button >
23- < button id ="refresh " class ="toolbar-btn " style ="margin-left: auto; ">
24- < span class ="icon "> ⟳</ span > 刷新页面
25- </ button >
11+ < div class ="toolbar-group ">
12+ < button id ="newNode " class ="toolbar-btn ">
13+ < span class ="icon "> +</ span > 新建节点
14+ </ button >
15+ < button id ="loadFlowchart " class ="toolbar-btn ">
16+ < span class ="icon "> 📂</ span > 加载流程图
17+ </ button >
18+ < button id ="save " class ="toolbar-btn ">
19+ < span class ="icon "> 💾</ span > 保存流程图
20+ </ button >
21+ < button id ="toggleAllCode " class ="toolbar-btn ">
22+ < span class ="icon "> 📝</ span > < span id ="toggleAllCodeText "> 展开代码</ span >
23+ </ button >
24+ < button id ="refresh " class ="toolbar-btn ">
25+ < span class ="icon "> ⟳</ span > 刷新
26+ </ button >
27+ </ div >
2628 </ div >
2729
2830 < div id ="searchPanel " class ="search-panel ">
@@ -65,24 +67,77 @@ <h3>加载流程图</h3>
6567 < div id ="flowchartContainer "> </ div >
6668
6769 < style >
70+ /* iOS 风格的工具栏样式 */
71+ .toolbar {
72+ position : fixed;
73+ top : 0 ;
74+ left : 0 ;
75+ right : 0 ;
76+ background : rgba (255 , 255 , 255 , 0.8 );
77+ backdrop-filter : blur (10px );
78+ border-bottom : 1px solid rgba (0 , 0 , 0 , 0.1 );
79+ padding : 8px 16px ;
80+ z-index : 100 ;
81+ display : flex;
82+ justify-content : center;
83+ box-shadow : 0 1px 3px rgba (0 , 0 , 0 , 0.05 );
84+ }
85+
86+ .toolbar-group {
87+ display : flex;
88+ gap : 8px ;
89+ align-items : center;
90+ }
91+
6892 .toolbar-btn {
6993 display : flex;
7094 align-items : center;
7195 padding : 8px 16px ;
72- margin : 0 4px ;
7396 border : none;
74- border-radius : 4px ;
75- background : # f0f0f0 ;
97+ border-radius : 8px ;
98+ background : rgba (0 , 122 , 255 , 0.1 );
99+ color : # 007AFF ;
100+ font-size : 14px ;
101+ font-weight : 500 ;
76102 cursor : pointer;
77- transition : all 0.3s ;
103+ transition : all 0.2s cubic-bezier (0.4 , 0 , 0.2 , 1 );
104+ white-space : nowrap;
78105 }
79106
80107 .toolbar-btn : hover {
81- background : # e0e0e0 ;
108+ background : rgba (0 , 122 , 255 , 0.15 );
109+ transform : translateY (-1px );
110+ }
111+
112+ .toolbar-btn : active {
113+ transform : translateY (0 );
82114 }
83115
84116 .toolbar-btn .icon {
85- margin-right : 8px ;
117+ margin-right : 6px ;
118+ font-size : 16px ;
119+ }
120+
121+ /* 暗色模式支持 */
122+ @media (prefers-color-scheme : dark) {
123+ .toolbar {
124+ background : rgba (0 , 0 , 0 , 0.8 );
125+ border-bottom-color : rgba (255 , 255 , 255 , 0.1 );
126+ }
127+
128+ .toolbar-btn {
129+ background : rgba (0 , 122 , 255 , 0.2 );
130+ color : # 0A84FF ;
131+ }
132+
133+ .toolbar-btn : hover {
134+ background : rgba (0 , 122 , 255 , 0.25 );
135+ }
136+ }
137+
138+ /* 调整流程图容器的上边距,为工具栏留出空间 */
139+ # flowchartContainer {
140+ margin-top : 60px ;
86141 }
87142
88143 .flowchart-node {
@@ -199,6 +254,8 @@ <h3>加载流程图</h3>
199254 let nodeCounter = 0 ;
200255 let currentMousePos = { x : 0 , y : 0 } ;
201256 let activeNode = null ;
257+ let currentFlowchartId = null ; // 添加当前流程图ID的跟踪
258+ let currentFlowchartName = null ;
202259
203260 // 跟踪鼠标位置
204261 document . addEventListener ( 'mousemove' , ( e ) => {
@@ -210,36 +267,38 @@ <h3>加载流程图</h3>
210267 showSearchPanel ( ) ;
211268 } ) ;
212269
213- document . getElementById ( 'save' ) . addEventListener ( 'click' , ( ) => {
214- document . getElementById ( 'saveDialog' ) . style . display = 'block' ;
270+ document . getElementById ( 'save' ) . addEventListener ( 'click' , async ( ) => {
271+ if ( currentFlowchartId ) {
272+ // 如果有当前流程图ID,直接保存
273+ await saveCurrentFlowChart ( ) ;
274+ } else {
275+ // 否则显示保存对话框
276+ document . getElementById ( 'saveDialog' ) . style . display = 'block' ;
277+ }
215278 } ) ;
216279
217- document . getElementById ( 'confirmSave' ) . addEventListener ( 'click' , async ( ) => {
218- const name = document . getElementById ( 'flowchartName' ) . value ;
280+ async function saveCurrentFlowChart ( ) {
281+ const name = document . getElementById ( 'flowchartName' ) . value || currentFlowchartName ;
219282 if ( name ) {
220283 try {
221- const flowchartContent = saveCurrentFlowchart ( ) ;
222- // 为所有带 noteData 的节点添加流程图名称作为 tag
223- flowchartContent . nodes . forEach ( node => {
224- if ( node . noteData ) {
225- const tags = node . noteData . tags || [ ] ;
226- if ( ! tags . includes ( name ) ) {
227- tags . push ( name ) ;
228- node . noteData . tags = tags ;
229- }
230- }
231- } ) ;
232-
284+ const flowchartContent = getCurrentFlowChartData ( ) ;
233285 const flowchartData = {
286+ id : currentFlowchartId , // 添加ID用于更新
234287 name : name ,
235- content : flowchartContent
288+ data : JSON . stringify ( flowchartContent )
236289 } ;
290+ console . log ( 'await saveFlowchart:' , flowchartData ) ;
237291 await window . saveFlowchart ( flowchartData ) ;
238292 document . getElementById ( 'saveDialog' ) . style . display = 'none' ;
239293 } catch ( error ) {
240294 console . error ( '保存失败:' , error ) ;
241295 }
242296 }
297+ }
298+
299+ document . getElementById ( 'confirmSave' ) . addEventListener ( 'click' , async ( ) => {
300+ console . log ( 'confirmSave' ) ;
301+ await saveCurrentFlowChart ( ) ;
243302 } ) ;
244303
245304 document . getElementById ( 'cancelSave' ) . addEventListener ( 'click' , ( ) => {
@@ -298,7 +357,7 @@ <h3>加载流程图</h3>
298357 } ) ;
299358 }
300359
301- function saveCurrentFlowchart ( ) {
360+ function getCurrentFlowChartData ( ) {
302361 const nodes = Array . from ( document . querySelectorAll ( '.flowchart-node' ) ) . map ( node => {
303362 const nodeData = {
304363 id : node . id ,
@@ -340,7 +399,11 @@ <h3>加载流程图</h3>
340399 return ;
341400 }
342401
343- const data = flowchartData ;
402+ // 设置当前流程图ID
403+ currentFlowchartId = flowchartId ;
404+ currentFlowchartName = flowchartData . name ;
405+
406+ const data = JSON . parse ( flowchartData . data ) ;
344407 if ( ! data || ! data . nodes || ! Array . isArray ( data . nodes ) ) {
345408 console . error ( '流程图数据格式不正确' ) ;
346409 return ;
@@ -352,9 +415,11 @@ <h3>加载流程图</h3>
352415 container . innerHTML = '' ;
353416 nodeCounter = 0 ;
354417
418+ // 设置流程图名称
419+ document . getElementById ( 'flowchartName' ) . value = data . name || '' ;
420+
355421 // 创建节点
356422 data . nodes . forEach ( nodeData => {
357- // 确保 noteData 的字段名称正确
358423 let noteDataForCreate = null ;
359424 if ( nodeData . noteData ) {
360425 noteDataForCreate = {
@@ -466,9 +531,7 @@ <h3>加载流程图</h3>
466531 try {
467532 const tags = document . createElement ( 'div' ) ;
468533 tags . className = 'node-tags' ;
469- const tagArray = noteData . tags . split ( ',' )
470- . map ( tag => tag . trim ( ) )
471- . filter ( tag => tag . length > 0 ) ;
534+ const tagArray = noteData . tags . split ( ',' ) . map ( t => t . trim ( ) ) . filter ( t => t ) ;
472535 if ( tagArray . length > 0 ) {
473536 tags . innerHTML = tagArray . map ( tag =>
474537 `<span class="node-tag">${ tag } </span>`
@@ -628,6 +691,20 @@ <h3>加载流程图</h3>
628691 document . getElementById ( 'contextMenu' ) . style . display = 'none' ;
629692 activeNode = null ;
630693 }
694+
695+ // 添加快捷键保存功能
696+ document . addEventListener ( 'keydown' , async ( e ) => {
697+ if ( ( e . ctrlKey || e . metaKey ) && e . key === 's' ) {
698+ e . preventDefault ( ) ;
699+ if ( currentFlowchartId ) {
700+ // 如果有当前流程图ID,直接保存
701+ await saveCurrentFlowChart ( ) ;
702+ } else {
703+ // 否则显示保存对话框
704+ document . getElementById ( 'saveDialog' ) . style . display = 'block' ;
705+ }
706+ }
707+ } ) ;
631708 </ script >
632709</ body >
633710</ html >
0 commit comments