@@ -12,7 +12,7 @@ import {
1212} from "@heroui/react" ;
1313import { useEffect , useState } from "react" ;
1414import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" ;
15- import { faBolt } from "@fortawesome/free-solid-svg-icons" ;
15+ import { faBolt , faEye , faEyeSlash } from "@fortawesome/free-solid-svg-icons" ;
1616import { addToast } from "@heroui/toast" ;
1717import { buildApiUrl } from "@/lib/utils" ;
1818
@@ -69,6 +69,7 @@ export default function QuickCreateTunnelModal({ isOpen, onOpenChange, onSaved,
6969 const [ endpoints , setEndpoints ] = useState < EndpointSimple [ ] > ( [ ] ) ;
7070 const [ loading , setLoading ] = useState ( true ) ;
7171 const [ submitting , setSubmitting ] = useState ( false ) ;
72+ const [ isPasswordVisible , setIsPasswordVisible ] = useState ( false ) ;
7273
7374 // 表单数据
7475 const [ formData , setFormData ] = useState ( {
@@ -180,11 +181,7 @@ export default function QuickCreateTunnelModal({ isOpen, onOpenChange, onSaved,
180181 certPath : mode === 'server' && tlsMode === 'mode2' ? certPath . trim ( ) : undefined ,
181182 keyPath : mode === 'server' && tlsMode === 'mode2' ? keyPath . trim ( ) : undefined ,
182183 logLevel,
183- password : ( ( ) => {
184- const selectedEndpoint = endpoints . find ( ep => ep . id === apiEndpoint ) ;
185- const hasVersion = selectedEndpoint && selectedEndpoint . version && selectedEndpoint . version . trim ( ) !== '' ;
186- return hasVersion && password ? password : undefined ;
187- } ) ( ) ,
184+ password : password || undefined ,
188185 min : mode === 'client' && min ? min : undefined ,
189186 max : mode === 'client' && max ? max : undefined
190187 } )
@@ -203,8 +200,9 @@ export default function QuickCreateTunnelModal({ isOpen, onOpenChange, onSaved,
203200
204201 const handleField = ( field :string , value :string ) => {
205202 if ( field === 'apiEndpoint' ) {
206- // 切换主控时清空密码
203+ // 切换主控时清空密码并重置可见性
207204 setFormData ( prev => ( { ...prev , [ field ] :value , password : '' } ) ) ;
205+ setIsPasswordVisible ( false ) ;
208206 } else {
209207 setFormData ( prev => ( { ...prev , [ field ] :value } ) ) ;
210208 }
@@ -265,7 +263,11 @@ export default function QuickCreateTunnelModal({ isOpen, onOpenChange, onSaved,
265263 >
266264 < SelectItem key = "inherit" >
267265 { ( ( ) => {
268- const selectedEndpoint = endpoints . find ( ep => ep . id === formData . apiEndpoint ) ;
266+ // 使用相同的匹配逻辑
267+ const selectedEndpoint1 = endpoints . find ( ep => ep . id === formData . apiEndpoint ) ;
268+ const selectedEndpoint2 = endpoints . find ( ep => String ( ep . id ) === String ( formData . apiEndpoint ) ) ;
269+ const selectedEndpoint3 = endpoints . find ( ep => Number ( ep . id ) === Number ( formData . apiEndpoint ) ) ;
270+ const selectedEndpoint = selectedEndpoint2 || selectedEndpoint1 || selectedEndpoint3 ;
269271 const masterLog = selectedEndpoint ?. log ;
270272 return masterLog ? `继承 (${ masterLog . toUpperCase ( ) } )` : "继承" ;
271273 } ) ( ) }
@@ -292,27 +294,50 @@ export default function QuickCreateTunnelModal({ isOpen, onOpenChange, onSaved,
292294
293295 { /* 密码配置(可选) - 仅在选中主控版本不为空时显示 */ }
294296 { ( ( ) => {
295- const selectedEndpoint = endpoints . find ( ep => ep . id === formData . apiEndpoint ) ;
297+ // 更详细的调试信息
298+ console . log ( '=== 密码显示调试开始 ===' ) ;
299+ console . log ( 'formData.apiEndpoint:' , formData . apiEndpoint , typeof formData . apiEndpoint ) ;
300+ console . log ( 'endpoints:' , endpoints ) ;
301+
302+ // 尝试不同的匹配方式
303+ const selectedEndpoint1 = endpoints . find ( ep => ep . id === formData . apiEndpoint ) ;
304+ const selectedEndpoint2 = endpoints . find ( ep => String ( ep . id ) === String ( formData . apiEndpoint ) ) ;
305+ const selectedEndpoint3 = endpoints . find ( ep => Number ( ep . id ) === Number ( formData . apiEndpoint ) ) ;
306+
307+ console . log ( '匹配方式1 (直接相等):' , selectedEndpoint1 ) ;
308+ console . log ( '匹配方式2 (String转换):' , selectedEndpoint2 ) ;
309+ console . log ( '匹配方式3 (Number转换):' , selectedEndpoint3 ) ;
310+
311+ // 使用最安全的匹配方式
312+ const selectedEndpoint = selectedEndpoint2 || selectedEndpoint1 || selectedEndpoint3 ;
296313 const hasVersion = selectedEndpoint && selectedEndpoint . version && selectedEndpoint . version . trim ( ) !== '' ;
297314
298- // 调试信息
299- console . log ( '密码显示调试:' , {
300- selectedEndpointId : formData . apiEndpoint ,
301- selectedEndpoint,
302- version : selectedEndpoint ?. version ,
303- hasVersion,
304- allEndpoints : endpoints
305- } ) ;
315+ console . log ( '最终选中的endpoint:' , selectedEndpoint ) ;
316+ console . log ( 'version:' , selectedEndpoint ?. version ) ;
317+ console . log ( 'hasVersion:' , hasVersion ) ;
318+ console . log ( '=== 密码显示调试结束 ===' ) ;
306319
307320 if ( ! hasVersion ) return null ;
308321
309322 return (
310323 < Input
311324 label = "隧道密码(可选)"
312- type = " password"
325+ type = { isPasswordVisible ? "text" : " password"}
313326 placeholder = "设置后隧道连接需要提供此密码进行认证"
314327 value = { formData . password }
315328 onValueChange = { ( v ) => handleField ( 'password' , v ) }
329+ endContent = {
330+ < button
331+ className = "focus:outline-none"
332+ type = "button"
333+ onClick = { ( ) => setIsPasswordVisible ( ! isPasswordVisible ) }
334+ >
335+ < FontAwesomeIcon
336+ icon = { isPasswordVisible ? faEyeSlash : faEye }
337+ className = "text-sm text-default-400 pointer-events-none"
338+ />
339+ </ button >
340+ }
316341 />
317342 ) ;
318343 } ) ( ) }
@@ -327,9 +352,24 @@ export default function QuickCreateTunnelModal({ isOpen, onOpenChange, onSaved,
327352 >
328353 < SelectItem key = "inherit" >
329354 { ( ( ) => {
330- const selectedEndpoint = endpoints . find ( ep => ep . id === formData . apiEndpoint ) ;
355+ // 使用相同的匹配逻辑
356+ const selectedEndpoint1 = endpoints . find ( ep => ep . id === formData . apiEndpoint ) ;
357+ const selectedEndpoint2 = endpoints . find ( ep => String ( ep . id ) === String ( formData . apiEndpoint ) ) ;
358+ const selectedEndpoint3 = endpoints . find ( ep => Number ( ep . id ) === Number ( formData . apiEndpoint ) ) ;
359+ const selectedEndpoint = selectedEndpoint2 || selectedEndpoint1 || selectedEndpoint3 ;
331360 const masterTls = selectedEndpoint ?. tls ;
332- return masterTls ? `继承主控 (模式${ masterTls . toUpperCase ( ) } )` : "继承主控" ;
361+
362+ // TLS模式转换
363+ const getTLSModeText = ( mode : string ) => {
364+ switch ( mode ) {
365+ case '0' : return '无 TLS 加密' ;
366+ case '1' : return '自签名证书' ;
367+ case '2' : return '自定义证书' ;
368+ default : return mode ;
369+ }
370+ } ;
371+
372+ return masterTls ? `继承主控 (${ getTLSModeText ( masterTls ) } )` : "继承主控" ;
333373 } ) ( ) }
334374 </ SelectItem >
335375 < SelectItem key = "mode0" > 模式0 无 TLS</ SelectItem >
0 commit comments