From d580086361036f87af843d0f7386bdc54736720a Mon Sep 17 00:00:00 2001 From: zhuzn Date: Mon, 20 Apr 2026 04:26:13 +0800 Subject: feat add clash yaml convert (#3916) * docs(agents): add AI agent guidance documentation * feat(sub): add Clash/Mihomo YAML subscription service Add SubClashService to convert subscription links to Clash/Mihomo YAML format for direct client compatibility. Co-Authored-By: Claude Sonnet 4.6 * feat(sub): integrate Clash YAML endpoint into subscription system - Add Clash route handler in SUBController - Update BuildURLs to include Clash URL - Pass Clash settings through subscription pipeline Co-Authored-By: Claude Sonnet 4.6 * feat(web): add Clash settings to entity and service - Add SubClashEnable, SubClashPath, SubClashURI fields - Add getter methods for Clash configuration - Set default Clash path to /clash/ and enable by default Co-Authored-By: Claude Sonnet 4.6 * feat(ui): add Clash settings to subscription panels - Add Clash enable switch in general subscription settings - Add Clash path/URI configuration in formats panel - Display Clash QR code on subscription page - Rename JSON tab to "Formats" for clarity Co-Authored-By: Claude Sonnet 4.6 * feat(js): add Clash support to frontend models - Add subClashEnable, subClashPath, subClashURI to AllSetting - Generate and display Clash QR code on subscription page - Handle Clash URL in subscription data binding Co-Authored-By: Claude Sonnet 4.6 * fix --------- Co-authored-by: Claude Sonnet 4.6 Co-authored-by: Sanaei --- sub/subService.go | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'sub/subService.go') diff --git a/sub/subService.go b/sub/subService.go index a0508ddc..b6422dd4 100644 --- a/sub/subService.go +++ b/sub/subService.go @@ -1031,6 +1031,7 @@ type PageData struct { TotalByte int64 SubUrl string SubJsonUrl string + SubClashUrl string Result []string } @@ -1080,29 +1081,25 @@ func (s *SubService) ResolveRequest(c *gin.Context) (scheme string, host string, // BuildURLs constructs absolute subscription and JSON subscription URLs for a given subscription ID. // It prioritizes configured URIs, then individual settings, and finally falls back to request-derived components. -func (s *SubService) BuildURLs(scheme, hostWithPort, subPath, subJsonPath, subId string) (subURL, subJsonURL string) { - // Input validation +func (s *SubService) BuildURLs(scheme, hostWithPort, subPath, subJsonPath, subClashPath, subId string) (subURL, subJsonURL, subClashURL string) { if subId == "" { - return "", "" + return "", "", "" } - // Get configured URIs first (highest priority) configuredSubURI, _ := s.settingService.GetSubURI() configuredSubJsonURI, _ := s.settingService.GetSubJsonURI() + configuredSubClashURI, _ := s.settingService.GetSubClashURI() - // Determine base scheme and host (cached to avoid duplicate calls) var baseScheme, baseHostWithPort string - if configuredSubURI == "" || configuredSubJsonURI == "" { + if configuredSubURI == "" || configuredSubJsonURI == "" || configuredSubClashURI == "" { baseScheme, baseHostWithPort = s.getBaseSchemeAndHost(scheme, hostWithPort) } - // Build subscription URL subURL = s.buildSingleURL(configuredSubURI, baseScheme, baseHostWithPort, subPath, subId) - - // Build JSON subscription URL subJsonURL = s.buildSingleURL(configuredSubJsonURI, baseScheme, baseHostWithPort, subJsonPath, subId) + subClashURL = s.buildSingleURL(configuredSubClashURI, baseScheme, baseHostWithPort, subClashPath, subId) - return subURL, subJsonURL + return subURL, subJsonURL, subClashURL } // getBaseSchemeAndHost determines the base scheme and host from settings or falls back to request values @@ -1149,7 +1146,7 @@ func (s *SubService) joinPathWithID(basePath, subId string) string { // BuildPageData parses header and prepares the template view model. // BuildPageData constructs page data for rendering the subscription information page. -func (s *SubService) BuildPageData(subId string, hostHeader string, traffic xray.ClientTraffic, lastOnline int64, subs []string, subURL, subJsonURL string, basePath string) PageData { +func (s *SubService) BuildPageData(subId string, hostHeader string, traffic xray.ClientTraffic, lastOnline int64, subs []string, subURL, subJsonURL, subClashURL string, basePath string) PageData { download := common.FormatTraffic(traffic.Down) upload := common.FormatTraffic(traffic.Up) total := "∞" @@ -1183,6 +1180,7 @@ func (s *SubService) BuildPageData(subId string, hostHeader string, traffic xray TotalByte: traffic.Total, SubUrl: subURL, SubJsonUrl: subJsonURL, + SubClashUrl: subClashURL, Result: subs, } } -- cgit v1.2.3