From 9590f90735a69f77aeb690e6d8a16759be2e8c83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=8F=E6=B2=AB=E8=8A=B1=E7=81=ABzzz?= Date: Tue, 19 Dec 2023 18:11:56 +0800 Subject: [PATCH] [+]proxies list --- analysis_options.yaml | 4 +- lib/controller/dsetting.dart | 7 +-- lib/controller/frpc.dart | 3 +- lib/controller/proxies.dart | 76 +++++++++++++++++++++++++++++++-- lib/controller/user.dart | 12 +++--- lib/dio/proxies/get.dart | 49 ++++++++++++++++++++- lib/main.dart | 8 ++-- lib/model/ProxyInfo.dart | 30 +++++++++++++ lib/ui/auth/login.dart | 45 ++++++++++++------- lib/ui/home.dart | 8 ++-- lib/ui/panel/console.dart | 13 +++++- lib/ui/panel/proxies.dart | 21 ++++++--- lib/ui/setting/frpcmanager.dart | 1 + lib/ui/setting/launcher.dart | 1 + 14 files changed, 230 insertions(+), 48 deletions(-) create mode 100644 lib/model/ProxyInfo.dart diff --git a/analysis_options.yaml b/analysis_options.yaml index 7161cfd7..c2787f56 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -21,8 +21,8 @@ linter: # `// ignore_for_file: name_of_lint` syntax on the line or in the file # producing the lint. rules: - # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + # avoid_print: false # Uncomment to disable the `avoid_print` rule # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options diff --git a/lib/controller/dsetting.dart b/lib/controller/dsetting.dart index df71661e..039c2d23 100644 --- a/lib/controller/dsetting.dart +++ b/lib/controller/dsetting.dart @@ -24,11 +24,12 @@ class DSettingController extends GetxController { } //Future _getList() async { - //final ct = CancelToken(); - //await FrpcDownloadDio()(arch: 'amd64', platform: 'windows', progressCallback: () {}, cancelToken: ct); + //final ct = CancelToken(); + //await FrpcDownloadDio()(arch: 'amd64', platform: 'windows', progressCallback: () {}, cancelToken: ct); //} - DropdownMenuItem _buildDMIWidget({required String version, required int value}) { + DropdownMenuItem _buildDMIWidget( + {required String version, required int value}) { return DropdownMenuItem( child: Text(version), value: value, diff --git a/lib/controller/frpc.dart b/lib/controller/frpc.dart index 82061f60..caec62ed 100644 --- a/lib/controller/frpc.dart +++ b/lib/controller/frpc.dart @@ -10,7 +10,6 @@ class FrpcController extends GetxController { load() async { exist.value = await file().exists(); - } /// 获取Frpc文件对象 @@ -27,4 +26,4 @@ class FrpcController extends GetxController { String path = await _support_path + "/frpc/frpc_info.json"; return await File(path).readAsString(); } -} \ No newline at end of file +} diff --git a/lib/controller/proxies.dart b/lib/controller/proxies.dart index 272dca4f..0c42b090 100644 --- a/lib/controller/proxies.dart +++ b/lib/controller/proxies.dart @@ -1,15 +1,83 @@ +import 'dart:io'; + import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:nyalcf/dio/proxies/get.dart'; +import 'package:nyalcf/model/ProxyInfo.dart'; + +import 'frpc.dart'; class ProxiesController extends GetxController { + final FrpcController f_c = Get.find(); var proxiesListWidgets = [ DataRow(cells: [ DataCell(Text("加载中喵喵喵?")), - DataCell(Text("加载中喵喵喵?")), - DataCell(Text("加载中喵喵喵?")), - DataCell(Text("加载中喵喵喵?")) + DataCell(Text("-")), + DataCell(Text("-")), + DataCell(Text("-")), + DataCell(Text("-")), + DataCell(Text("-")), + DataCell(Text("-")), ]) ].obs; - load() {} + load(username, token) async { + var proxies = await ProxiesGetDio().get(username, token); + if (proxies is List) { + List widgets = []; + proxies.forEach((element) => widgets.add(DataRow(cells: [ + DataCell( + Container( + width: 150.0, + height: 30.0, + child: SelectableText(element.proxy_name), + ), + ), + DataCell(SelectableText(element.id.toString())), + DataCell(SelectableText(element.node.toString())), + DataCell(SelectableText(element.proxy_type)), + DataCell(SelectableText(element.local_ip)), + DataCell( + SelectableText("${element.local_port} -> ${element.remote_port}"), + ), + DataCell( + Row( + children: [ + IconButton( + icon: Icon(Icons.play_circle), + onPressed: () { + Process.run("cmd.exe", ["start", "cmd.exe"]); + }, + ), + IconButton( + icon: Icon(Icons.edit), + onPressed: () { + Get.snackbar("谁让你点了?", "还没写,爬去面板编辑喵喵喵!"); + }, + ), + ], + ), + ), + ]))); + proxiesListWidgets.value = widgets; + } else { + proxiesListWidgets.value = [ + DataRow(cells: [ + DataCell(Text("获取失败,请尝试刷新一下~")), + DataCell(Text("-")), + DataCell(Text("-")), + DataCell(Text("-")), + DataCell(Text("-")), + DataCell(Text("-")), + DataCell(Text("-")), + ]) + ]; + Get.snackbar( + "发生错误", + "无法获取隧道列表信息: ${proxies}", + snackPosition: SnackPosition.BOTTOM, + animationDuration: Duration(milliseconds: 300), + ); + } + } } diff --git a/lib/controller/user.dart b/lib/controller/user.dart index 4da940fe..42f0b033 100644 --- a/lib/controller/user.dart +++ b/lib/controller/user.dart @@ -5,13 +5,13 @@ import 'package:nyalcf/model/User.dart'; class UserController extends GetxController { var user = "".obs; var email = "".obs; - var token = "".obs; - var avatar = "https://cravatar.cn/avatar/".obs; + var token = ''.obs; + var avatar = 'https://cravatar.cn/avatar/'.obs; var inbound = 0.obs; var outbound = 0.obs; - var frp_token = "".obs; + var frp_token = ''.obs; - var welcomeText = "好".obs; + var welcomeText = '好'.obs; load() async { User userinfo = await InfoCache.getInfo(); @@ -26,9 +26,9 @@ class UserController extends GetxController { int hour = DateTime.now().hour; if (hour <= 12) { - welcomeText.value = "上午好"; + welcomeText.value = '上午好'; } else { - welcomeText.value = "下午好"; + welcomeText.value = '下午好'; } } } diff --git a/lib/dio/proxies/get.dart b/lib/dio/proxies/get.dart index 147c8261..b975da36 100644 --- a/lib/dio/proxies/get.dart +++ b/lib/dio/proxies/get.dart @@ -1,7 +1,54 @@ import 'package:dio/dio.dart'; +import 'package:nyalcf/dio/basicConfig.dart'; +import 'package:nyalcf/model/ProxyInfo.dart'; class ProxiesGetDio { final dio = Dio(); - Future get() async {} + Future get(username, token) async { + try { + Map params_map = Map(); + params_map['username'] = username; + + Options options = Options(); + Map options_map = Map(); + options_map['Content-Type'] = + 'application/x-www-form-urlencoded;charset=UTF-8'; + options_map['Authorization'] = 'Bearer $token'; + options = options.copyWith(headers: options_map); + + //print(options.headers?.keys); + + var response = await dio.get( + "${basicConfig.api_v2_url}/proxies/getlist", + queryParameters: params_map, + options: options, + ); + Map resJson = response.data; + Map resData = resJson['data']; + print(resData['proxies']); + List> proxies = List.from(resData['proxies']); + List list = []; + proxies.forEach((element) { + list.add(ProxyInfo( + proxy_name: element['proxy_name'], + use_compression: bool.parse(element['use_compression']), + local_ip: element['local_ip'], + node: element['node'], + local_port: element['local_port'], + remote_port: int.parse(element['remote_port']), + domain: element['domain'], + icp: element['icp'], + sk: element['sk'], + id: element['id'], + proxy_type: element['proxy_type'], + use_encryption: bool.parse(element['use_encryption']), + status: element['status'])); + }); + return list; + } catch (e) { + print(e); + return e; + } + } } diff --git a/lib/main.dart b/lib/main.dart index 07c54b2d..72affdb8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -45,9 +45,9 @@ class App extends StatelessWidget { theme: ThemeData( useMaterial3: true, fontFamily: 'HarmonyOS Sans', - colorScheme: ColorScheme.fromSeed(seedColor: Colors.pink.shade300).copyWith( - primary: Colors.pink.shade500, - secondary: Colors.pink.shade400 - ))); + colorScheme: ColorScheme.fromSeed(seedColor: Colors.pink.shade300) + .copyWith( + primary: Colors.pink.shade500, + secondary: Colors.pink.shade400))); } } diff --git a/lib/model/ProxyInfo.dart b/lib/model/ProxyInfo.dart new file mode 100644 index 00000000..ce4e5b8d --- /dev/null +++ b/lib/model/ProxyInfo.dart @@ -0,0 +1,30 @@ +class ProxyInfo { + ProxyInfo( + {required this.proxy_name, + required this.use_compression, + required this.local_ip, + required this.node, + required this.local_port, + required this.remote_port, + required this.domain, + required this.icp, + required this.sk, + required this.id, + required this.proxy_type, + required this.use_encryption, + required this.status}); + + final String proxy_name; + final bool use_compression; + final String local_ip; + final int node; + final int local_port; + final int remote_port; + final String domain; + final String? icp; + final String sk; + final int id; + final String proxy_type; + final bool use_encryption; + final status; +} diff --git a/lib/ui/auth/login.dart b/lib/ui/auth/login.dart index 9a15d8ff..df78a556 100644 --- a/lib/ui/auth/login.dart +++ b/lib/ui/auth/login.dart @@ -89,17 +89,26 @@ class _LoginState extends State { _login() async { if (userController.text == "") { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text('请输入用户名'), - )); + Get.snackbar( + "无效数据", + '请输入用户名', + snackPosition: SnackPosition.BOTTOM, + animationDuration: Duration(milliseconds: 300), + ); } else if (passwordController.text == "") { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text('请输入密码'), - )); + Get.snackbar( + "无效数据", + '请输入密码', + snackPosition: SnackPosition.BOTTOM, + animationDuration: Duration(milliseconds: 300), + ); } else { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text('正在登录...'), - )); + Get.snackbar( + "登录中", + '正在请求...', + snackPosition: SnackPosition.BOTTOM, + animationDuration: Duration(milliseconds: 300), + ); final res = await LoginDio() .requestLogin(userController.text, passwordController.text); if (res is User) { @@ -107,14 +116,20 @@ class _LoginState extends State { //print(UserInfoCache.info); await InfoCache.setInfo(res); InfoCache.saveToFile(); - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text('登录成功,欢迎您 ${res.user}'), - )); + Get.snackbar( + "登录成功", + "欢迎您,指挥官 ${res.user}", + snackPosition: SnackPosition.BOTTOM, + animationDuration: Duration(milliseconds: 300), + ); Get.toNamed("/panel/home"); } else { - ScaffoldMessenger.of(context).showSnackBar(SnackBar( - content: Text('登陆失败:${res}'), - )); + Get.snackbar( + '登陆失败', + res, + snackPosition: SnackPosition.BOTTOM, + animationDuration: Duration(milliseconds: 300), + ); } } } diff --git a/lib/ui/home.dart b/lib/ui/home.dart index b0744a07..10ef4355 100644 --- a/lib/ui/home.dart +++ b/lib/ui/home.dart @@ -1,13 +1,15 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:nyalcf/controller/frpc.dart'; import 'package:nyalcf/ui/model/FloatingActionButton.dart'; import 'model/AppbarActions.dart'; class Home extends StatelessWidget { - const Home({super.key, required this.title}); + Home({super.key, required this.title}); final String title; + final FrpcController f_c = Get.put(FrpcController()); @override Widget build(BuildContext context) { @@ -27,9 +29,7 @@ class Home extends StatelessWidget { "欢迎使用Nya LoCyanFrp! Launcher", style: TextStyle(fontSize: 30), ), - const Text( - "にゃ~にゃ~,请选择一项操作" - ), + const Text("にゃ~にゃ~,请选择一项操作"), Container( margin: const EdgeInsets.all(20.0), child: Row( diff --git a/lib/ui/panel/console.dart b/lib/ui/panel/console.dart index ae0da829..60603aaf 100644 --- a/lib/ui/panel/console.dart +++ b/lib/ui/panel/console.dart @@ -4,6 +4,7 @@ import 'package:nyalcf/controller/user.dart'; import 'package:nyalcf/ui/model/AppbarActions.dart'; import 'package:nyalcf/ui/model/Drawer.dart'; import 'package:nyalcf/ui/model/FloatingActionButton.dart'; +import 'package:url_launcher/url_launcher.dart'; class PanelConsole extends StatelessWidget { PanelConsole({super.key, required this.title}); @@ -30,7 +31,17 @@ class PanelConsole extends StatelessWidget { .actions(), ), drawer: DrawerX(context: context).drawer(), - body: ListView(children: []), + body: Center( + child: ListView(children: [ + Text("这里还什么都没有,不过你可以为这里贡献一下ww~"), + ElevatedButton( + onPressed: () { + launchUrl(Uri.parse("https://github.com/Muska-Ami/NyaLCF")); + }, + child: SelectableText("https://github.com/Muska-Ami/NyaLCF"), + ), + ]), + ), floatingActionButton: FloatingActionButtonX().button()); } } diff --git a/lib/ui/panel/proxies.dart b/lib/ui/panel/proxies.dart index 89949fcd..c84a820b 100644 --- a/lib/ui/panel/proxies.dart +++ b/lib/ui/panel/proxies.dart @@ -15,6 +15,8 @@ class PanelProxies extends StatelessWidget { @override Widget build(BuildContext context) { + p_c.load(c.user, c.token); + return Scaffold( appBar: AppBar( title: @@ -33,12 +35,19 @@ class PanelProxies extends StatelessWidget { ), drawer: DrawerX(context: context).drawer(), body: ListView(children: [ - Obx(() => DataTable(columns: [ - DataColumn(label: Expanded(child: Text("ID"))), - DataColumn(label: Expanded(child: Text("节点"))), - DataColumn(label: Expanded(child: Text("端口"))), - DataColumn(label: Expanded(child: Text("操作"))) - ], rows: p_c.proxiesListWidgets)) + Obx(() => DataTable( + columnSpacing: 5.0, + columns: [ + DataColumn(label: Expanded(child: Text("名称"))), + DataColumn(label: Expanded(child: Text("ID"))), + DataColumn(label: Expanded(child: Text("节点"))), + DataColumn(label: Expanded(child: Text("协议"))), + DataColumn(label: Expanded(child: Text("本地IP"))), + DataColumn(label: Expanded(child: Text("端口"))), + DataColumn(label: Expanded(child: Text("操作"))) + ], + rows: p_c.proxiesListWidgets, + )) ]), floatingActionButton: FloatingActionButtonX().button()); } diff --git a/lib/ui/setting/frpcmanager.dart b/lib/ui/setting/frpcmanager.dart index a133f789..8037d4f3 100644 --- a/lib/ui/setting/frpcmanager.dart +++ b/lib/ui/setting/frpcmanager.dart @@ -4,6 +4,7 @@ import 'package:nyalcf/controller/dsetting.dart'; class FrpcManagerSX { final DSettingController ds_c = Get.find(); + Widget widget() { return ListView( children: [ diff --git a/lib/ui/setting/launcher.dart b/lib/ui/setting/launcher.dart index 48eeb6de..89e7ef06 100644 --- a/lib/ui/setting/launcher.dart +++ b/lib/ui/setting/launcher.dart @@ -4,6 +4,7 @@ import 'package:nyalcf/controller/dsetting.dart'; class LauncherSX { final DSettingController ds_c = Get.find(); + Widget widget() { return Placeholder(); }