Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/MHSanaei/3x-ui.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzhuzn <haimu0427@Outlook.com>2026-04-19 23:26:13 +0300
committerGitHub <noreply@github.com>2026-04-19 23:26:13 +0300
commitd580086361036f87af843d0f7386bdc54736720a (patch)
treef22944b1ab1ea8c29858d796cc248b7b16436427 /web/service
parent1e3b366fba3054698d55e36891d022a513e5a942 (diff)
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 <noreply@anthropic.com> * 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 <noreply@anthropic.com> * 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 <noreply@anthropic.com> * 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 <noreply@anthropic.com> * 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 <noreply@anthropic.com> * fix --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Sanaei <ho3ein.sanaei@gmail.com>
Diffstat (limited to 'web/service')
-rw-r--r--web/service/setting.go39
1 files changed, 33 insertions, 6 deletions
diff --git a/web/service/setting.go b/web/service/setting.go
index 5c93e9fd..7027d466 100644
--- a/web/service/setting.go
+++ b/web/service/setting.go
@@ -71,6 +71,9 @@ var defaultValueMap = map[string]string{
"subURI": "",
"subJsonPath": "/json/",
"subJsonURI": "",
+ "subClashEnable": "true",
+ "subClashPath": "/clash/",
+ "subClashURI": "",
"subJsonFragment": "",
"subJsonNoises": "",
"subJsonMux": "",
@@ -555,6 +558,18 @@ func (s *SettingService) GetSubJsonURI() (string, error) {
return s.getString("subJsonURI")
}
+func (s *SettingService) GetSubClashEnable() (bool, error) {
+ return s.getBool("subClashEnable")
+}
+
+func (s *SettingService) GetSubClashPath() (string, error) {
+ return s.getString("subClashPath")
+}
+
+func (s *SettingService) GetSubClashURI() (string, error) {
+ return s.getString("subClashURI")
+}
+
func (s *SettingService) GetSubJsonFragment() (string, error) {
return s.getString("subJsonFragment")
}
@@ -750,11 +765,13 @@ func (s *SettingService) GetDefaultSettings(host string) (any, error) {
"defaultKey": func() (any, error) { return s.GetKeyFile() },
"tgBotEnable": func() (any, error) { return s.GetTgbotEnabled() },
"subEnable": func() (any, error) { return s.GetSubEnable() },
- "subJsonEnable": func() (any, error) { return s.GetSubJsonEnable() },
- "subTitle": func() (any, error) { return s.GetSubTitle() },
- "subURI": func() (any, error) { return s.GetSubURI() },
- "subJsonURI": func() (any, error) { return s.GetSubJsonURI() },
- "remarkModel": func() (any, error) { return s.GetRemarkModel() },
+ "subJsonEnable": func() (any, error) { return s.GetSubJsonEnable() },
+ "subClashEnable": func() (any, error) { return s.GetSubClashEnable() },
+ "subTitle": func() (any, error) { return s.GetSubTitle() },
+ "subURI": func() (any, error) { return s.GetSubURI() },
+ "subJsonURI": func() (any, error) { return s.GetSubJsonURI() },
+ "subClashURI": func() (any, error) { return s.GetSubClashURI() },
+ "remarkModel": func() (any, error) { return s.GetRemarkModel() },
"datepicker": func() (any, error) { return s.GetDatepicker() },
"ipLimitEnable": func() (any, error) { return s.GetIpLimitEnable() },
}
@@ -776,12 +793,19 @@ func (s *SettingService) GetDefaultSettings(host string) (any, error) {
subJsonEnable = b
}
}
- if (subEnable && result["subURI"].(string) == "") || (subJsonEnable && result["subJsonURI"].(string) == "") {
+ subClashEnable := false
+ if v, ok := result["subClashEnable"]; ok {
+ if b, ok2 := v.(bool); ok2 {
+ subClashEnable = b
+ }
+ }
+ if (subEnable && result["subURI"].(string) == "") || (subJsonEnable && result["subJsonURI"].(string) == "") || (subClashEnable && result["subClashURI"].(string) == "") {
subURI := ""
subTitle, _ := s.GetSubTitle()
subPort, _ := s.GetSubPort()
subPath, _ := s.GetSubPath()
subJsonPath, _ := s.GetSubJsonPath()
+ subClashPath, _ := s.GetSubClashPath()
subDomain, _ := s.GetSubDomain()
subKeyFile, _ := s.GetSubKeyFile()
subCertFile, _ := s.GetSubCertFile()
@@ -811,6 +835,9 @@ func (s *SettingService) GetDefaultSettings(host string) (any, error) {
if subJsonEnable && result["subJsonURI"].(string) == "" {
result["subJsonURI"] = subURI + subJsonPath
}
+ if subClashEnable && result["subClashURI"].(string) == "" {
+ result["subClashURI"] = subURI + subClashPath
+ }
}
return result, nil