package wizard import ( "strings" "github.com/charmbracelet/lipgloss" ) var split_line = splitlineStyle.Render( "───────────────────────────────────────────────────────────────") // View 渲染视图 func (m model) View() string { if m.done { return successView() } if m.quitting { return quitView() } if m.err != nil { return errorView(m.err) } var pageContent string switch m.currentPage { case PageAgreement: pageContent = renderLicensePage(m) case PageData: pageContent = renderDataInfoPage(m) case PagePublicNetwork: pageContent = renderPublicNetworkPage(m) case PageInternalNetwork: pageContent = renderInternalNetworkPage(m) case PageDNS: pageContent = renderDNSPage(m) case PageSummary: pageContent = renderSummaryPage(m) default: pageContent = appStyle.Render("无效页面") } return appStyle.Render(pageContent) } func makeRow(label, value string) string { return lipgloss.JoinHorizontal(lipgloss.Left, labelStyle.Render(label+":"), valueStyle.Render(value), ) } func renderLicensePage(m model) string { title := titleStyle.Render("SunHPC Software License Agreement") licenseText := ` ─────────────────────────────────────────────────────────────── 1. License Grant This software grants you a non-exclusive, non-transferable license to use it. 2. Disclaimer of Warranties This software is provided "as is" without any warranties, whether express or implied. 3. Limitation of Liability This software is provided without warranty of any kind, either express or implied. In no event shall the author be liable for any damages arising out of the use of this software. 4. Termination of Agreement If you violate any of the terms of this agreement, the license will automatically terminate. ─────────────────────────────────────────────────────────────── PLEASE READ THE ABOVE TERMS CAREFULLY AND CLICK "ACCEPT" TO AGREE AND FOLLOW THIS AGREEMENT. ─────────────────────────────────────────────────────────────── ` pageComps := m.pageComponents[PageAgreement] acceptBtn := pageComps["accept_btn"].View() rejectBtn := pageComps["reject_btn"].View() // ✅ 添加调试信息(确认 agreementIdx 的值) // debugInfo := lipgloss.NewStyle().Foreground(lipgloss.Color("#888888")). // Render(fmt.Sprintf("[DEBUG: idx=%d]", m.agreementIdx),) hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm") pageContent := lipgloss.JoinVertical(lipgloss.Center, title, "", licenseTextStyle.Render(licenseText), lipgloss.JoinHorizontal(lipgloss.Center, acceptBtn, rejectBtn), hint, ) return appStyle.Render(pageContent) } // ---------------- 页2:基础信息页渲染 ---------------- func renderDataInfoPage(m model) string { pageComps := m.pageComponents[PageData] // 拼接基础信息表单 formContent := lipgloss.JoinVertical(lipgloss.Center, split_line, makeRow("Homepage", pageComps["Homepage_input"].View()), split_line, makeRow("ClusterName", pageComps["ClusterName_input"].View()), split_line, makeRow("Country", pageComps["Country_input"].View()), split_line, makeRow("State", pageComps["State_input"].View()), split_line, makeRow("City", pageComps["City_input"].View()), split_line, makeRow("Contact", pageComps["Contact_input"].View()), split_line, makeRow("Timezone", pageComps["Timezone_input"].View()), split_line, makeRow("DistroDir", pageComps["DistroDir_input"].View()), split_line, ) // 按钮区域 btnArea := lipgloss.JoinHorizontal( lipgloss.Center, pageComps["next_btn"].View(), pageComps["prev_btn"].View(), ) hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm") // 页面整体 pageContent := lipgloss.JoinVertical( lipgloss.Center, titleStyle.Render("基础信息配置(页2/6)"), formContent, btnArea, hint, ) return appStyle.Render(pageContent) } func renderPublicNetworkPage(m model) string { pageComps := m.pageComponents[PagePublicNetwork] // 拼接公网网络表单 formContent := lipgloss.JoinVertical(lipgloss.Center, split_line, makeRow("PublicHostname", pageComps["PublicHostname_input"].View()), split_line, makeRow("PublicInterface", pageComps["PublicInterface_input"].View()), split_line, makeRow("PublicIPAddress", pageComps["PublicIPAddress_input"].View()), split_line, makeRow("PublicNetmask", pageComps["PublicNetmask_input"].View()), split_line, makeRow("PublicGateway", pageComps["PublicGateway_input"].View()), split_line, makeRow("PublicDomain", pageComps["PublicDomain_input"].View()), split_line, makeRow("PublicMTU", pageComps["PublicMTU_input"].View()), split_line, ) // 按钮区域 btnArea := lipgloss.JoinHorizontal( lipgloss.Center, pageComps["next_btn"].View(), pageComps["prev_btn"].View(), ) networkInterfaces := getNetworkInterfaces() autoDetect := infoStyle.Render( "[*] Auto Detect Interfaces: " + strings.Join(networkInterfaces, ", ")) hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm") // 页面整体 pageContent := lipgloss.JoinVertical( lipgloss.Center, titleStyle.Render("公网网络配置(页3/6)"), autoDetect, formContent, btnArea, hint, ) return appStyle.Render(pageContent) } func renderInternalNetworkPage(m model) string { pageComps := m.pageComponents[PageInternalNetwork] // 拼接内网网络表单 formContent := lipgloss.JoinVertical(lipgloss.Center, split_line, makeRow("PrivateHostname", pageComps["PrivateHostname_input"].View()), split_line, makeRow("PrivateInterface", pageComps["PrivateInterface_input"].View()), split_line, makeRow("PrivateIPAddress", pageComps["PrivateIPAddress_input"].View()), split_line, makeRow("PrivateNetmask", pageComps["PrivateNetmask_input"].View()), split_line, makeRow("PrivateDomain", pageComps["PrivateDomain_input"].View()), split_line, makeRow("PrivateMTU", pageComps["PrivateMTU_input"].View()), split_line, ) // 按钮区域 btnArea := lipgloss.JoinHorizontal( lipgloss.Center, pageComps["next_btn"].View(), pageComps["prev_btn"].View(), ) hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm") // 页面整体 pageContent := lipgloss.JoinVertical( lipgloss.Center, titleStyle.Render("内网网络配置(页4/6)"), formContent, btnArea, hint, ) return appStyle.Render(pageContent) } func renderDNSPage(m model) string { pageComps := m.pageComponents[PageDNS] // 拼接 DNS 表单 formContent := lipgloss.JoinVertical(lipgloss.Center, split_line, makeRow("Pri DNS", pageComps["Pri_DNS_input"].View()), split_line, makeRow("Sec DNS", pageComps["Sec_DNS_input"].View()), split_line, ) // 按钮区域 btnArea := lipgloss.JoinHorizontal( lipgloss.Center, pageComps["next_btn"].View(), pageComps["prev_btn"].View(), ) hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm") // 页面整体 pageContent := lipgloss.JoinVertical( lipgloss.Center, titleStyle.Render("DNS 配置(页5/6)"), formContent, btnArea, hint, ) return appStyle.Render(pageContent) } func renderSummaryPage(m model) string { pageComps := m.pageComponents[PageSummary] // 拼接 Summary 表单 formContent := lipgloss.JoinVertical(lipgloss.Center, split_line, makeRow("ClusterName", m.config.ClusterName), split_line, makeRow("Country", m.config.Country), split_line, makeRow("State", m.config.State), split_line, makeRow("City", m.config.City), split_line, makeRow("Contact", m.config.Contact), split_line, makeRow("Timezone", m.config.Timezone), split_line, makeRow("Homepage", m.config.HomePage), split_line, makeRow("DBPath", m.config.DBAddress), split_line, makeRow("DistroDir", m.config.DistroDir), split_line, makeRow("PublicInterface", m.config.PublicInterface), split_line, makeRow("PublicIPAddress", m.config.PublicIPAddress), split_line, makeRow("PublicNetmask", m.config.PublicNetmask), split_line, makeRow("PublicGateway", m.config.PublicGateway), split_line, makeRow("PrivateInterface", m.config.PrivateInterface), split_line, makeRow("PrivateIPAddress", m.config.PrivateIPAddress), split_line, makeRow("PrivateNetmask", m.config.PrivateNetmask), split_line, makeRow("PrivateMTU", m.config.PrivateMTU), split_line, makeRow("Pri DNS", m.config.DNSPrimary), split_line, makeRow("Sec DNS", m.config.DNSSecondary), split_line, ) // 按钮区域 btnArea := lipgloss.JoinHorizontal( lipgloss.Center, pageComps["confirm_btn"].View(), pageComps["cancel_btn"].View(), ) hint := hintStyle.Render("Use Left/Right OR Tab Change,Enter Confirm") // 页面整体 pageContent := lipgloss.JoinVertical( lipgloss.Center, titleStyle.Render("确认信息(页6/6)"), formContent, btnArea, hint, ) return appStyle.Render(pageContent) } func successView() string { content := lipgloss.JoinVertical(lipgloss.Center, successTitle.Render("Initialization Completed!"), "", successMsg.Render( "System configuration has been saved, and the system is initializing..."), "", ) return appStyle.Render(content) } func quitView() string { content := lipgloss.JoinVertical(lipgloss.Center, split_line, errorTitle.Render("Canceled"), "", errorMsg.Render("Initialization canceled, no configuration saved"), split_line, "\n", ) return quitStyle.Render(content) } func errorView(err error) string { content := lipgloss.JoinVertical(lipgloss.Center, errorTitle.Render("Error"), "", errorMsg.Render(err.Error()), "", hintStyle.Render("Press Ctrl+C to exit"), ) return appStyle.Render(content) }