alroyso 1 year ago
parent
commit
8181a231a5

+ 4 - 0
lib/app/const/const.dart

@@ -79,6 +79,10 @@ class Files {
     return File(path.join(Paths.config.path, 'proxy.yaml'));
   }
 
+  static File get makeInitProxyConfig {
+    return File(path.join(Paths.config.path, 'init_proxy.yaml'));
+  }
+
   static File get configCountryMmdb {
     return File(path.join(Paths.config.path, 'Country.mmdb'));
   }

+ 63 - 54
lib/app/controller/GlobalController.dart

@@ -20,6 +20,7 @@ class GlobalController extends GetxController {
   final List<String> routeModes = ['sys', 'tun'];
 
   var routeModesSelect = "sys".obs;
+  var modesSelect = "rule".obs;
   var nodeModes = <NodeMode>[].obs;
   var isLoading = false.obs;
   var errorMsg = ''.obs;
@@ -50,31 +51,12 @@ class GlobalController extends GetxController {
     await controllers.tray.initTray();
     controllers.window.initWindow();
     //controllers.protocol.initProtocol();
+    await controllers.config.portDetection();
+    // init clash config
 
     // init config
     await controllers.config.initConfig();
     await controllers.service.initConfig();
-    await initService();
-    // final language = controllers.config.config.value.language.split('_');
-    //
-    // await applyLanguage(Locale(language[0], language[1]));
-
-   //  await controllers.service.initConfig();
-   //  // init service
-   //  await controllers.service.startService();
-   //  if (controllers.service.serviceStatus.value != RunningState.running) return;
-   // // await controllers.service.serviceModeSwitch(true);
-   //  // init clash core
-   //
-   //  await controllers.service.startClashCore();
-   //  if (controllers.service.coreStatus.value != RunningState.running) return;
-   //  await controllers.core.updateVersion();
-    // await controllers.global.updateDate();
-    //await controllers.service.install();
-    initRegularlyUpdate();
-  }
-
-  Future<void> initService() async {
 
     // init service
     await controllers.service.startService();
@@ -82,9 +64,23 @@ class GlobalController extends GetxController {
     // await controllers.service.serviceModeSwitch(true);
     // init clash core
 
-    await controllers.service.startClashCore();
+    await controllers.service.initClashCoreConfig();
     if (controllers.service.coreStatus.value != RunningState.running) return;
     await controllers.core.updateVersion();
+    //initRegularlyUpdate();
+  }
+
+
+  Future<void> updateMode(String route) async {
+    if(allowStatusUpdate){
+
+      return;
+    }
+    modesSelect.value = route;
+    final coreStatus = controllers.service.coreStatus.value;
+    if( coreStatus == RunningState.running){
+      controllers.core.fetchConfigUpdate({'mode': modesSelect.value});
+    }
   }
   Future<void> updateRoute(String route) async {
     if(allowStatusUpdate){
@@ -100,30 +96,35 @@ class GlobalController extends GetxController {
   }
   Future<void> fetchNodes() async {
     nodeModes.value = await ApiService().getNode("/api/client/v4/nodes?vless=1");
-    await makeProxy();
-    if(controllers.service.coreStatus.value == RunningState.stoped){
-      await controllers.service.reloadClashCore();
-    }
-    if (controllers.service.coreStatus.value != RunningState.running) return;
-    await controllers.core.updateVersion();
-    await updateDate();
+    //await makeProxy();
+    // if(controllers.service.coreStatus.value == RunningState.stoped){
+    //   await controllers.service.reloadClashCore();
+    // }
+    // if (controllers.service.coreStatus.value != RunningState.running) return;
+    // await controllers.core.updateVersion();
+    // await updateDate();
     //
-    NodeMode? targetNode;
-    if (selectedNode.value == null) {
-      targetNode = await findNodeWithMinUsers(nodeModes);
-    } else {
-      targetNode = selectedNode.value;
-    }
-    if (targetNode != null){
-      selectNode(targetNode);
-      ProxieProxiesItem? targetProxie = await findProxieByName(targetNode.name);
-      if (targetProxie != null) {
-        handleSetProxieGroup(targetProxie, targetNode.name);
-      }
-    }
+
 
   }
 
+  Future<void> updateNode() async {
+    // NodeMode? targetNode;
+    // if (selectedNode.value == null) {
+    //   targetNode = await findNodeWithMinUsers(nodeModes);
+    // } else {
+    //   targetNode = selectedNode.value;
+    // }
+    // if (targetNode != null){
+    //   selectNode(targetNode);
+    //   ProxieProxiesItem? targetProxie = await findProxieByName(targetNode.name);
+    //   if (targetProxie != null) {
+    //     handleSetProxieGroup(targetProxie, targetNode.name);
+    //   }
+    // }
+    // await updateDate();
+  }
+
   Future<void> startSysMode() async {
 
     await makeProxy();
@@ -135,10 +136,8 @@ class GlobalController extends GetxController {
     }
     if (targetNode != null){
       selectNode(targetNode);
-      ProxieProxiesItem? targetProxie = await findProxieByName(targetNode.name);
-      if (targetProxie != null) {
-        handleSetProxieGroup(targetProxie, targetNode.name);
-      }
+     await swift(targetNode.name);
+
     }
     //await updateDate();
   }
@@ -152,19 +151,30 @@ class GlobalController extends GetxController {
     }
     if (targetNode != null){
       selectNode(targetNode);
-      ProxieProxiesItem? targetProxie = await findProxieByName(targetNode.name);
-      if (targetProxie != null) {
-        handleSetProxieGroup(targetProxie, targetNode.name);
-      }
+      await swift(targetNode.name);
     }
 
   }
 
   Future<void> swift(String name) async {
-    ProxieProxiesItem? targetProxie = await findProxieByName(name);
-    if (targetProxie != null) {
-      handleSetProxieGroup(targetProxie, name);
+
+    try{
+      var g = "proxy";
+      if(modesSelect.value == "global")
+      {
+        g = "GLOBAL";
+      }
+      await controllers.core.fetchSetProxieGroup(g, name);
+      await updateDate();
+      final conn = await controllers.core.fetchConnection();
+      for (final it in conn.connections) {
+        if (it.chains.contains(name)) controllers.core.fetchCloseConnections(it.id);
+      }
+    }catch (e) {
+      log.debug(e.toString());
     }
+
+
   }
   // Future<ProxieProxiesItem> findProxieByName(String name) async {
   //   return proxieGroups.firstWhere((proxie) => proxie['name'] == name, orElse: () => null);
@@ -203,7 +213,6 @@ class GlobalController extends GetxController {
 
   Future<void> systemProxySwitch(bool open) async {
     systemProxySwitchIng.value = true;
-
     await SystemProxy.instance.set(open ? controllers.core.proxyConfig : SystemProxyConfig());
     await controllers.config.setSystemProxy(open);
     systemProxySwitchIng.value = false;

+ 76 - 24
lib/app/controller/config.dart

@@ -4,6 +4,7 @@ import 'package:dio/dio.dart';
 import 'package:get/get.dart';
 import 'package:naiyouwl/app/bean/config.dart';
 import 'package:naiyouwl/app/const/const.dart';
+import 'package:naiyouwl/app/controller/controllers.dart';
 import 'package:yaml/yaml.dart';
 import 'package:path/path.dart' as path;
 import 'package:flutter_emoji/flutter_emoji.dart';
@@ -30,7 +31,9 @@ class ConfigController extends GetxController {
   var clashCoreApiSecret = ''.obs;
   var clashCoreDns = ''.obs;
   var clashCoreTunEnable = false.obs;
-  var servicePort = 0.obs;
+  var servicePort = 9899.obs;
+  var mixedPort = 9788.obs;
+  var ApiAddressPort = 9799.obs;
   Future<void> initConfig() async {
 
    // var port = await getFreePort();
@@ -51,10 +54,10 @@ class ConfigController extends GetxController {
     } else {
       config.value = Config.fromJson(_defaultConfig);
     }
-    bool bg = await isPortOccupied(config.value.servicePort);
-    if(bg) {
-      config.value.servicePort = await getFreePort();
-    }
+    // bool bg = await isPortOccupied(config.value.servicePort);
+    // if(bg) {
+    //   config.value.servicePort = await getFreePort();
+    // }
     if (config.value.subs.isEmpty) {
       if (!await Files.configExample.exists()) {
         await Files.assetsExample.copy(Files.configExample.path);
@@ -63,7 +66,7 @@ class ConfigController extends GetxController {
       config.value.selected = 'example.yaml';
     }
     await save();
-    await readClashCoreApi();
+    await makeInitConfig();
   }
 
   String nodeToYaml(NodeMode node) {
@@ -83,10 +86,38 @@ class ConfigController extends GetxController {
         return '';
     }
   }
+
+
+  Future<void> makeInitConfig() async{
+
+    var mode = controllers.global.modesSelect;
+    var initconfig = '''
+mixed-port: ${mixedPort.value}
+allow-lan: true
+bind-address: '*'
+mode: $mode
+log-level: info
+external-controller: '127.0.0.1:${ApiAddressPort.value}'
+unified-delay: false
+geodata-mode: true
+tcp-concurrent: false
+find-process-mode: strict
+global-client-fingerprint: chrome
+proxies:
+rules:
+  - MATCH,DIRECT
+  ''';
+
+    await Files.makeInitProxyConfig.writeAsString(initconfig);
+    config.value.selected = 'init_proxy.yaml';
+    await readClashCoreApi();
+  }
+
+
   Future<void> makeClashConfig(List<NodeMode> nodes) async{
-    if( Files.makeProxyConfig.existsSync()){
-      Files.makeProxyConfig.deleteSync(recursive: true);
-    }
+    // if( Files.makeProxyConfig.existsSync()){
+    //   Files.makeProxyConfig.deleteSync(recursive: true);
+    // }
 
     var stack = "system";
     if( Platform.isWindows){
@@ -97,18 +128,10 @@ class ConfigController extends GetxController {
     {
       dnsPort = 53;
     }
-    var mixedport  = 9888;
-    bool bg = await isPortOccupied(mixedport);
-    if(bg) {
-      mixedport = await getFreePort();
-    }
-    var extePort  = 9777;
-    final ac = await isPortOccupied(extePort);
-    if(ac) {
-      extePort = await getFreePort();
-    }
-    var proxies = nodes.map(nodeToYaml).toList();
 
+
+   var mode =  controllers.global.modesSelect;
+    var proxies = nodes.map(nodeToYaml).toList();
     var proxyGroups = '''
 proxy-groups:
   - name: proxy
@@ -124,12 +147,12 @@ rules:
   ''';
 
     var initconfig = '''
-mixed-port: $mixedport
+mixed-port: ${mixedPort.value}
 allow-lan: true
 bind-address: '*'
-mode: Rule
+mode: $mode
 log-level: info
-external-controller: '127.0.0.1:$extePort'
+external-controller: '127.0.0.1:${ApiAddressPort.value}'
 unified-delay: false
 geodata-mode: true
 tcp-concurrent: false
@@ -179,7 +202,7 @@ $rules
 
     await Files.makeProxyConfig.writeAsString(initconfig);
     config.value.selected = 'proxy.yaml';
-   // await readClashCoreApi();
+    await readClashCoreApi();
   }
 
   Future<void> save() async {
@@ -187,6 +210,7 @@ $rules
   }
 
   Future<void> readClashCoreApi() async {
+
     final configStr = await File(path.join(Paths.config.path, config.value.selected)).readAsString();
     // final emoji = EmojiParser();
     // final b = emoji.unemojify(_config);
@@ -208,6 +232,11 @@ $rules
       }
     }
   }
+  Future<void> setSerivcePort(int port) async {
+    config.value.servicePort = port;
+    await save();
+    config.refresh();
+  }
 
   Future<void> setLanguage(String language) async {
     config.value.language = language;
@@ -302,12 +331,35 @@ $rules
     config.refresh();
   }
 
+  Future<void> portDetection() async {
+    bool isOk = await isPortOccupied(mixedPort.value);
+    if(isOk){
+      mixedPort.value = await getFreePort();
+    }
+    //await Future.delayed(const Duration(seconds: 5));  // 等待5秒
+
+    isOk = await isPortOccupied(ApiAddressPort.value);
+    if(isOk){
+      ApiAddressPort.value = await getFreePort();
+    }
+    //await Future.delayed(const Duration(seconds: 5));  // 等待5秒
+
+    if(!controllers.service.isRunning){
+      isOk = await isPortOccupied(servicePort.value);
+      if(isOk){
+        servicePort.value = await getFreePort();
+      }
+    }
+
+  }
+
   Future<int> getFreePort() async {
     var server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
     int port = server.port;
     await server.close();
     return port;
   }
+
   Future<bool> isPortOccupied(int port) async {
     bool isOccupied = false;
     ServerSocket? server;

+ 52 - 16
lib/app/controller/service.dart

@@ -5,6 +5,7 @@ import 'dart:convert';
 import 'package:dio/dio.dart';
 import 'package:get/get.dart';
 import 'package:naiyouwl/app/bean/ClashServiceInfo.dart';
+import 'package:naiyouwl/app/common/LogHelper.dart';
 import 'package:naiyouwl/app/const/const.dart';
 import 'package:naiyouwl/app/controller/controllers.dart';
 import 'package:naiyouwl/app/utils/logger.dart';
@@ -46,6 +47,30 @@ class ServiceController extends GetxController {
     _dio.options.baseUrl = 'http://127.0.0.1:${controllers.config.config.value.servicePort}';
   }
 
+  Future<void> startTunService() async {
+
+    try {
+      while (true) {
+        final data = await fetchInfo();
+        if( data.mode != 'service-mode')
+        {
+          if (serviceStatus.value == RunningState.running) {
+            await stopService();
+          }
+          await install();
+        } else {
+          break;
+        }
+      }
+
+    } catch (e) {
+
+      serviceStatus.value = RunningState.error;
+      log.debug(e.toString());
+     // BotToast.showText(text: e.toString());
+    }
+
+  }
   Future<void> startService() async {
     serviceStatus.value = RunningState.starting;
     if (Platform.isLinux) {
@@ -55,7 +80,10 @@ class ServiceController extends GetxController {
     try {
       final data = await fetchInfo();
       serviceMode.value = data.mode == 'service-mode';
+      fetchStop();
     } catch (e) {
+      //await install();
+
       await startUserModeService();
       if (serviceStatus.value == RunningState.error) return;
     }
@@ -74,7 +102,7 @@ class ServiceController extends GetxController {
     serviceMode.value = false;
     try {
       int? exitCode;
-      clashServiceProcess = await Process.start(Files.assetsClashService.path, ['user-mode'], mode: ProcessStartMode.inheritStdio);
+      clashServiceProcess = await Process.start(Files.assetsClashService.path, ['-port','${controllers.config.config.value.servicePort}','user-mode'], mode: ProcessStartMode.inheritStdio);
       clashServiceProcess!.exitCode.then((code) => exitCode = code);
 
       while (true) {
@@ -163,7 +191,7 @@ class ServiceController extends GetxController {
     }
 
     Future<void> install() async {
-      final res = await runAsAdmin(Files.assetsClashService.path, ["stop", "uninstall", "install", "start"]);
+      final res = await runAsAdmin(Files.assetsClashService.path, ["-port","${controllers.config.config.value.servicePort}","stop", "uninstall", "install", "start"]);
       await initConfig();
       log.debug('install', res.stdout, res.stderr);
       if (res.exitCode != 0) throw res.stderr;
@@ -180,15 +208,12 @@ class ServiceController extends GetxController {
     Future<void> serviceModeSwitch(bool open) async {
       if (serviceStatus.value == RunningState.running) await stopService();
       try {
-
         open ? await install() : await uninstall();
-        var data = _dio.post("/info");
-        print(data);
       } catch (e) {
         BotToast.showText(text: e.toString());
       }
       await startService();
-      await startClashCore();
+      //await startClashCore();
     }
 
     Future<void> startClashCore() async {
@@ -220,7 +245,7 @@ class ServiceController extends GetxController {
         coreStatus.value = RunningState.running;
       } catch (e) {
         log.error("core -- $e");
-        BotToast.showText(text: e.toString());
+       // BotToast.showText(text: e.toString());
         coreStatus.value = RunningState.error;
       }
     }
@@ -237,17 +262,28 @@ class ServiceController extends GetxController {
       await fetchStop();
       coreStatus.value = RunningState.stoped;
     }
+    Future<void> initClashCoreConfig() async {
+
+       //await stopClashCore();
+       await startClashCore();
+       if (coreStatus.value == RunningState.error) {
+         //BotToast.showText(text: '重启失败');
+       } else {
+         await controllers.core.updateVersion();
+         //BotToast.showText(text: '重启成功');
+       }
+    }
 
+  Future<void> stopClash() async {
+    controllers.config.config.value.selected = 'init_proxy.yaml';
+    if( coreStatus.value == RunningState.running){
+      await controllers.core.fetchReloadConfig({"path":  path.join(Paths.config.path, controllers.config.config.value.selected),"payload": ""});
+    }
+  }
     Future<void> reloadClashCore() async {
-      BotToast.showText(text: '正在重启 Core ……');
-      await stopClashCore();
-      await controllers.config.readClashCoreApi();
-      await startClashCore();
-      if (coreStatus.value == RunningState.error) {
-        BotToast.showText(text: '重启失败');
-      } else {
-        await controllers.core.updateVersion();
-        BotToast.showText(text: '重启成功');
+      controllers.config.config.value.selected = 'proxy.yaml';
+      if( coreStatus.value == RunningState.running){
+        await controllers.core.fetchReloadConfig({"path":  path.join(Paths.config.path, controllers.config.config.value.selected),"payload":""});
       }
     }
 

+ 47 - 33
lib/app/modules/home/controllers/home_controller.dart

@@ -65,18 +65,26 @@ class HomeController extends GetxController {
   }
 
   void _handleStateChange([dynamic _]) async {
-    final coreStatus = controllers.service.coreStatus.value;
-    final isVisible = controllers.window.isVisible.value;
-
-    if (coreStatus == RunningState.running && isVisible &&  controllers.global.allowStatusUpdate) {
-      updateStatus(ConnectionStatus.connecting);
-      await Future.delayed(const Duration(seconds: 5));
-      updateStatus(ConnectionStatus.stopped);
-      await controllers.global.updateDate();
-      await controllers.global.systemProxySwitch(true);
-    } else {
-      updateStatus(ConnectionStatus.disconnected);
-    }
+    // final coreStatus = controllers.service.coreStatus.value;
+    // final isVisible = controllers.window.isVisible.value;
+    // final serviceStatus =  controllers.service.serviceStatus.value;
+    // if(serviceStatus != RunningState.running){
+    //   updateStatus(ConnectionStatus.disconnected);
+    //   return;
+    // }
+    // if (coreStatus == RunningState.running && isVisible &&  controllers.global.allowStatusUpdate) {
+    //   updateStatus(ConnectionStatus.connecting);
+    //   await Future.delayed(const Duration(seconds: 3));
+    //   updateStatus(ConnectionStatus.stopped);
+    // } else {
+    //   LogHelper().d("stop coreStatus serivce");
+    //   // var routeModes = controllers.global.routeModesSelect.value;
+    //   // if(routeModes != "tun"){
+    //   //   controllers.config.clashCoreTunEnable.value = false;
+    //   // }
+    //   // await controllers.global.systemProxySwitch(false);
+    //   updateStatus(ConnectionStatus.disconnected);
+    // }
   }
 
   Future<void> handleButtonClick() async {
@@ -84,46 +92,52 @@ class HomeController extends GetxController {
     // 如果当前状态是已连接或正在连接,则停止服务
     if (connectStatus.value == ConnectionStatus.connecting ||
         connectStatus.value == ConnectionStatus.stopped) {
-      connectStatus.value = ConnectionStatus.disconnected;
       controllers.global.allowStatusUpdate = false;
+      await controllers.config.setBreakConnections(true);
       // // 停止服务
-      // await controllers.service.stopClashCore();
-      var routeModes = controllers.global.routeModesSelect.value;
-      if(routeModes != "tun"){
-        controllers.config.clashCoreTunEnable.value = false;
-        controllers.service.reloadClashCore();
-        await controllers.global.systemProxySwitch(false);
-        //await controllers.global.updateDate();
-      }
-
+      await controllers.service.stopClash();
+      await controllers.global.systemProxySwitch(false);
+      updateStatus(ConnectionStatus.disconnected);
       return;
     } else {
+      await controllers.config.setBreakConnections(true);
+      controllers.global.allowStatusUpdate = true;
       var routeModes = controllers.global.routeModesSelect.value;
       if(routeModes == "tun"){
-        // final coreStatus = controllers.service.coreStatus.value;
-        // if(coreStatus != RunningState.running){
-        //   controllers.service.serviceModeSwitch(true);
-        // }
         controllers.config.clashCoreTunEnable.value = true;
         controllers.global.startTunMode();
-        controllers.service.stopClashCore();
-
-        //controllers.service.reloadClashCore();
+        await controllers.service.startTunService();
+        final coreStatus = controllers.service.coreStatus.value;
+        if (coreStatus == RunningState.running){
+          await controllers.service.reloadClashCore();
+        }
+        else{
+          await controllers.service.startClashCore();
+        }
 
       } else {
+
         controllers.config.clashCoreTunEnable.value = false;
         controllers.global.startSysMode();
         final coreStatus = controllers.service.coreStatus.value;
         if (coreStatus == RunningState.running){
-          controllers.service.reloadClashCore();
+          await controllers.service.reloadClashCore();
         }
         else{
-          controllers.service.startClashCore();
+          await controllers.service.startClashCore();
         }
+        await controllers.global.systemProxySwitch(true);
       }
-      controllers.global.allowStatusUpdate = true;
+
+      //await controllers.global.handleSetProxieGroup();
+      await controllers.global.updateDate();
+
+      // updateStatus(ConnectionStatus.connecting);
+      // await Future.delayed(const Duration(seconds: 5));
+      // updateStatus(ConnectionStatus.stopped);
+      await controllers.tray.updateTray();
       updateStatus(ConnectionStatus.connecting);
-      await Future.delayed(const Duration(seconds: 5));
+      await Future.delayed(const Duration(seconds: 3));
       updateStatus(ConnectionStatus.stopped);
     }
   }

+ 28 - 19
lib/app/modules/home/views/home_view.dart

@@ -94,7 +94,7 @@ class HomeView extends GetView<HomeController> {
                 ),
                 const SizedBox(height: 30,),
                 Padding(
-                  padding: const EdgeInsets.fromLTRB(20, 0, 20, 0),
+                  padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
                   child: Row(
                     children: [
                       Text(controller.getHttp().toString()),
@@ -129,28 +129,37 @@ class HomeView extends GetView<HomeController> {
                     ),
                   ),
                 ),
-                const SizedBox(height: 20,),
+                const SizedBox(height: 40,),
                 Align(
                   alignment: Alignment.center,
-                  child:ButtonSelect(
-                    labels: ['setting_mode_rules'.tr,'setting_mode_global'.tr,],
-                    value: controllers.global.modes.indexOf(controllers.core.config.value.mode),
-                    onSelect: disabled ? null : (idx) => controllers.core.fetchConfigUpdate({'mode': controllers.global.modes[idx]}),
+                  child: Padding(
+                    padding: const EdgeInsets.fromLTRB(60, 0, 50, 0),
+                    child: Row(
+                      children: [
+                        ButtonSelect(
+                          labels: ['setting_mode_rules'.tr,'setting_mode_global'.tr,],
+                          value: controllers.global.modes.indexOf(controllers.global.modesSelect.value),
+                          onSelect: (idx) => {
+                            controllers.global.updateMode(controllers.global.modes[idx])
+                          },
+                        ),
+                        const SizedBox(width: 10,),
+                        ButtonSelect(
+                            labels: ['route_sys_tile'.tr,'route_tun_title'.tr,],
+                            value: controllers.global.routeModes.indexOf(controllers.global.routeModesSelect.value),
+                            onSelect: (idx) => {
+                              controllers.global.updateRoute(controllers.global.routeModes[idx])
+                            }
+                        ),
+                      ],
+                    ),
                   ),
                 ),
-                const SizedBox(height: 20,),
-                Align(
-                  alignment: Alignment.center,
-                  child:ButtonSelect(
-                    labels: ['route_sys_tile'.tr,'route_tun_title'.tr,],
-                    value: controllers.global.routeModes.indexOf(controllers.global.routeModesSelect.value),
-                    onSelect: disabled ? null : (idx) => {
-
-
-                      controllers.global.updateRoute(controllers.global.routeModes[idx])
-                    },
-                  ),
-                )
+                // const SizedBox(height: 20,),
+                // Align(
+                //   alignment: Alignment.center,
+                //   child:,
+                // )
               ],
             );
           })

+ 4 - 1
lib/app/modules/welcome/views/welcome_view.dart

@@ -28,7 +28,10 @@ class WelcomeView extends GetView<WelcomeController> {
               ),
             ],
           )
-              : Container(), // 当不在加载时,你可能想要显示其他的 Widget
+              : Container(child: TextButton(child: const Text("重新获取"),onPressed: (){
+                controller.fetchSysConfig();
+
+          },),), // 当不在加载时,你可能想要显示其他的 Widget
         );
 
       }),