Compare commits
2 Commits
main
...
playWithSp
Author | SHA1 | Date | |
---|---|---|---|
|
a08a07e845 | ||
|
f698d44eb1 |
85
.vscode/launch.json
vendored
85
.vscode/launch.json
vendored
@ -1,85 +0,0 @@
|
|||||||
{
|
|
||||||
// 使用 IntelliSense 了解相关属性。
|
|
||||||
// 悬停以查看现有属性的描述。
|
|
||||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
|
||||||
"version": "0.2.0",
|
|
||||||
"configurations": [
|
|
||||||
{
|
|
||||||
"name": "cpnav",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "dart"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "cpnav (profile mode)",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "dart",
|
|
||||||
"flutterMode": "profile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "cpnav (release mode)",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "dart",
|
|
||||||
"flutterMode": "release"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "pass_track",
|
|
||||||
"cwd": "plugins\\pass_track",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "dart"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "pass_track (profile mode)",
|
|
||||||
"cwd": "plugins\\pass_track",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "dart",
|
|
||||||
"flutterMode": "profile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "pass_track (release mode)",
|
|
||||||
"cwd": "plugins\\pass_track",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "dart",
|
|
||||||
"flutterMode": "release"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "scence_map",
|
|
||||||
"cwd": "plugins\\scence_map",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "dart"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "scence_map (profile mode)",
|
|
||||||
"cwd": "plugins\\scence_map",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "dart",
|
|
||||||
"flutterMode": "profile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "scence_map (release mode)",
|
|
||||||
"cwd": "plugins\\scence_map",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "dart",
|
|
||||||
"flutterMode": "release"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "example",
|
|
||||||
"cwd": "plugins\\pass_track\\example",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "dart"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "example (profile mode)",
|
|
||||||
"cwd": "plugins\\pass_track\\example",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "dart",
|
|
||||||
"flutterMode": "profile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "example (release mode)",
|
|
||||||
"cwd": "plugins\\pass_track\\example",
|
|
||||||
"request": "launch",
|
|
||||||
"type": "dart",
|
|
||||||
"flutterMode": "release"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
@ -1,26 +1,14 @@
|
|||||||
import 'package:cpnav/appbar.dart';
|
import 'package:cpnav/appbar.dart';
|
||||||
import 'package:cpnav/pages/login/loginprefs.dart';
|
|
||||||
import 'package:cpnav/pages/pass_track/controller.dart';
|
|
||||||
import 'package:cpnav/pages/pass_track/bottomIcon/iconController.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:scence_map/controller.dart';
|
import 'package:scence_map/controller.dart';
|
||||||
import 'pages/login/login_page.dart';
|
|
||||||
import 'pages/login/my_routes.dart';
|
|
||||||
import 'pages/pass_track/view.dart';
|
import 'pages/pass_track/view.dart';
|
||||||
import 'service/pile_cm.dart';
|
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); //设置全屏
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); //设置全屏
|
||||||
Get.put(PassTrackController('WXLMB', 'cp_road'));
|
|
||||||
Get.put(IconController());
|
|
||||||
Get.put(LoginPageController());
|
|
||||||
Get.put(AccountLoginController());
|
|
||||||
Get.put(PhoneLoginController());
|
|
||||||
LoginPrefs loginPrefs = LoginPrefs();
|
|
||||||
loginPrefs.removeToken();
|
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,12 +21,25 @@ class MyApp extends StatelessWidget {
|
|||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'Flutter Demo',
|
title: 'Flutter Demo',
|
||||||
theme: ThemeData(
|
theme: ThemeData(
|
||||||
|
// This is the theme of your application.
|
||||||
|
//
|
||||||
|
// TRY THIS: Try running your application with "flutter run". You'll see
|
||||||
|
// the application has a purple toolbar. Then, without quitting the app,
|
||||||
|
// try changing the seedColor in the colorScheme below to Colors.green
|
||||||
|
// and then invoke "hot reload" (save your changes or press the "hot
|
||||||
|
// reload" button in a Flutter-supported IDE, or press "r" if you used
|
||||||
|
// the command line to start the app).
|
||||||
|
//
|
||||||
|
// Notice that the counter didn't reset back to zero; the application
|
||||||
|
// state is not lost during the reload. To reset the state, use hot
|
||||||
|
// restart instead.
|
||||||
|
//
|
||||||
|
// This works for code too, not just values: Most code changes can be
|
||||||
|
// tested with just a hot reload.
|
||||||
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
|
||||||
useMaterial3: true,
|
useMaterial3: true,
|
||||||
),
|
),
|
||||||
home: const MyHomePage(title: 'Flutter Demo Home Page'),
|
home: const MyHomePage(title: 'Flutter Demo Home Page'),
|
||||||
initialRoute: "home",
|
|
||||||
onGenerateRoute: onGenerateRoute,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,8 +68,8 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
|
|
||||||
final _currentIndex = 0.obs;
|
final _currentIndex = 0.obs;
|
||||||
final List<Widget> _pages = [
|
final List<Widget> _pages = [
|
||||||
PassTrackView(
|
PassTrackWidget(
|
||||||
// date: '',
|
date: '',
|
||||||
),
|
),
|
||||||
Container(
|
Container(
|
||||||
color: Colors.green,
|
color: Colors.green,
|
||||||
|
75
lib/models/login.dart
Normal file
75
lib/models/login.dart
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:get_storage/get_storage.dart';
|
||||||
|
|
||||||
|
import 'package:cpnav/models/user.dart';
|
||||||
|
|
||||||
|
class LoginPrefs extends GetxController {
|
||||||
|
static const String expireStr = "expire"; //用户名
|
||||||
|
static const String tokenStr = "token"; //token
|
||||||
|
static const String phoneStr = "phone";
|
||||||
|
final box = GetStorage(); // 实例化 GetStorage
|
||||||
|
|
||||||
|
Future<String> init() async {
|
||||||
|
await GetStorage.init(); // 初始化 GetStorage
|
||||||
|
return 'ok';
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveExpire(int expire) {
|
||||||
|
box.write(expireStr, expire);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
int getExpire() {
|
||||||
|
return box.read(expireStr) ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveToken(String token) {
|
||||||
|
box.write(tokenStr, token);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getToken() {
|
||||||
|
return box.read(tokenStr) ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeExpire() {
|
||||||
|
box.remove(expireStr);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeToken() {
|
||||||
|
box.remove(tokenStr);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void savePhone(String phone) {
|
||||||
|
box.write(phoneStr, phone);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getPhone() {
|
||||||
|
return box.read(phoneStr) ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearLogin() {
|
||||||
|
box.erase(); // 清除所有数据
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UserController extends GetxController {
|
||||||
|
final box = GetStorage(); // 实例化 GetStorage
|
||||||
|
|
||||||
|
UserModel? getUser() {
|
||||||
|
final userMap = box.read('user');
|
||||||
|
if (userMap != null) {
|
||||||
|
return UserModel.fromJson(userMap);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUser(Map user) {
|
||||||
|
box.write('user', user);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
@ -5,86 +5,29 @@ import 'package:flutter/scheduler.dart';
|
|||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:cpnav/pages/login/loginprefs.dart';
|
import 'package:cpnav/pages/login/loginprefs.dart';
|
||||||
import 'package:cpnav/service/base.dart';
|
import 'package:cpnav/service/base.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
|
|
||||||
// class Login extends StatefulWidget {
|
class Login extends StatefulWidget {
|
||||||
// const Login({super.key});
|
const Login({super.key});
|
||||||
|
|
||||||
// @override
|
|
||||||
// State<Login> createState() => _LoginState();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// class _LoginState extends State<Login> with SingleTickerProviderStateMixin {
|
|
||||||
// //with SingleTickerProviderStateMixin 使this 不报错
|
|
||||||
// late TabController _tabController;
|
|
||||||
// //初始化实例
|
|
||||||
// @override
|
|
||||||
// void initState() {
|
|
||||||
// _tabController = TabController(length: 2, vsync: this);
|
|
||||||
// super.initState();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @override
|
|
||||||
// void dispose() {
|
|
||||||
// _tabController.dispose();
|
|
||||||
// super.dispose();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @override
|
|
||||||
// Widget build(BuildContext context) {
|
|
||||||
// return Scaffold(
|
|
||||||
// appBar: AppBar(
|
|
||||||
// title: const Text('欢迎登录'),
|
|
||||||
// ),
|
|
||||||
// body: Column(
|
|
||||||
// children: <Widget>[
|
|
||||||
// TabBar(
|
|
||||||
// labelColor: Colors.black, // 设置选中标签的字体颜色为黑色
|
|
||||||
// unselectedLabelColor: Colors.grey, // 设置未选中标签的字体颜色为灰色
|
|
||||||
// labelStyle: const TextStyle(color: Colors.black), // 设置选中标签的字体颜色为黑色
|
|
||||||
// unselectedLabelStyle:
|
|
||||||
// const TextStyle(color: Colors.grey), // 设置未选中标签的字体颜色为灰色
|
|
||||||
// controller: _tabController,
|
|
||||||
// tabs: const [
|
|
||||||
// Tab(text: '手机号登录', icon: Icon(Icons.phone_android)),
|
|
||||||
// Tab(text: '账号登录', icon: Icon(Icons.account_box_outlined)),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// Expanded(
|
|
||||||
// child: TabBarView(
|
|
||||||
// controller: _tabController,
|
|
||||||
// children: const [
|
|
||||||
// PhoneLoginPage(),
|
|
||||||
// AccountLoginPage(),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
class LoginPageController extends GetxController
|
|
||||||
with SingleGetTickerProviderMixin {
|
|
||||||
late TabController _tabController;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
State<Login> createState() => _LoginState();
|
||||||
super.onInit();
|
|
||||||
_tabController = TabController(length: 2, vsync: this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onClose() {
|
|
||||||
_tabController.dispose();
|
|
||||||
super.onClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
TabController get tabController => _tabController;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Login extends GetView<LoginPageController> {
|
class _LoginState extends State<Login> with SingleTickerProviderStateMixin {
|
||||||
const Login({super.key});
|
//with SingleTickerProviderStateMixin 使this 不报错
|
||||||
|
late TabController _tabController;
|
||||||
|
//初始化实例
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
_tabController = TabController(length: 2, vsync: this);
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_tabController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -100,7 +43,7 @@ class Login extends GetView<LoginPageController> {
|
|||||||
labelStyle: const TextStyle(color: Colors.black), // 设置选中标签的字体颜色为黑色
|
labelStyle: const TextStyle(color: Colors.black), // 设置选中标签的字体颜色为黑色
|
||||||
unselectedLabelStyle:
|
unselectedLabelStyle:
|
||||||
const TextStyle(color: Colors.grey), // 设置未选中标签的字体颜色为灰色
|
const TextStyle(color: Colors.grey), // 设置未选中标签的字体颜色为灰色
|
||||||
controller: controller.tabController,
|
controller: _tabController,
|
||||||
tabs: const [
|
tabs: const [
|
||||||
Tab(text: '手机号登录', icon: Icon(Icons.phone_android)),
|
Tab(text: '手机号登录', icon: Icon(Icons.phone_android)),
|
||||||
Tab(text: '账号登录', icon: Icon(Icons.account_box_outlined)),
|
Tab(text: '账号登录', icon: Icon(Icons.account_box_outlined)),
|
||||||
@ -108,7 +51,7 @@ class Login extends GetView<LoginPageController> {
|
|||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: TabBarView(
|
child: TabBarView(
|
||||||
controller: controller.tabController,
|
controller: _tabController,
|
||||||
children: const [
|
children: const [
|
||||||
PhoneLoginPage(),
|
PhoneLoginPage(),
|
||||||
AccountLoginPage(),
|
AccountLoginPage(),
|
||||||
@ -121,211 +64,48 @@ class Login extends GetView<LoginPageController> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// class AccountLoginPage extends StatefulWidget {
|
class AccountLoginPage extends StatefulWidget {
|
||||||
// const AccountLoginPage({super.key});
|
const AccountLoginPage({super.key});
|
||||||
|
|
||||||
// @override
|
|
||||||
// State<AccountLoginPage> createState() => _AccountLoginPageState();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// class _AccountLoginPageState extends State<AccountLoginPage> {
|
|
||||||
// //初始化FormState
|
|
||||||
// final _formKey = GlobalKey<FormState>();
|
|
||||||
// String username = "";
|
|
||||||
// String password = "";
|
|
||||||
// String verifyCode = "";
|
|
||||||
// String svgString = "";
|
|
||||||
// String captchaId = "";
|
|
||||||
// @override
|
|
||||||
// void initState() {
|
|
||||||
// super.initState();
|
|
||||||
// SchedulerBinding.instance.addPostFrameCallback((_) async {
|
|
||||||
// await changeCaptcha();
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// changeCaptcha() async {
|
|
||||||
// var captcha = await GetServices().getCaptcha();
|
|
||||||
// setState(() {
|
|
||||||
// svgString = captcha['data'];
|
|
||||||
// captchaId = captcha['captchaId'];
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// showErrorSnackbar(BuildContext context, String text) {
|
|
||||||
// final snackBar = SnackBar(
|
|
||||||
// content: Text(text),
|
|
||||||
// backgroundColor: Colors.red,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// LoginPrefs loginPrefs = LoginPrefs();
|
|
||||||
// bool _obscureText = false;
|
|
||||||
// @override
|
|
||||||
// Widget build(BuildContext context) {
|
|
||||||
// return SingleChildScrollView(
|
|
||||||
// child: Padding(
|
|
||||||
// padding: const EdgeInsets.all(16.0),
|
|
||||||
// child: Column(
|
|
||||||
// children: [
|
|
||||||
// Form(
|
|
||||||
// key: _formKey,
|
|
||||||
// child: Column(
|
|
||||||
// children: [
|
|
||||||
// // 账号输入框
|
|
||||||
// TextFormField(
|
|
||||||
// decoration: const InputDecoration(
|
|
||||||
// labelText: '用户名:',
|
|
||||||
// ),
|
|
||||||
// onSaved: (String? value) => username = value!,
|
|
||||||
// validator: (String? value) {
|
|
||||||
// String str = "";
|
|
||||||
|
|
||||||
// RegExp regex = RegExp(r'^[a-zA-Z0-9]+$');
|
|
||||||
// if (value!.isEmpty) {
|
|
||||||
// str = '用户名不能为空';
|
|
||||||
// } else if (!regex.hasMatch(value)) {
|
|
||||||
// str = '请输入有效的账号';
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return str == "" ? null : str;
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// const SizedBox(height: 16.0),
|
|
||||||
|
|
||||||
// // 密码输入框
|
|
||||||
// TextFormField(
|
|
||||||
// decoration: InputDecoration(
|
|
||||||
// labelText: '密码:',
|
|
||||||
// suffixIcon: IconButton(
|
|
||||||
// icon: Icon(
|
|
||||||
// _obscureText
|
|
||||||
// ? Icons.visibility
|
|
||||||
// : Icons.visibility_off,
|
|
||||||
// ),
|
|
||||||
// onPressed: () {
|
|
||||||
// setState(() {
|
|
||||||
// _obscureText = !_obscureText; // 切换密码可见状态
|
|
||||||
// });
|
|
||||||
// }),
|
|
||||||
// ),
|
|
||||||
// obscureText: _obscureText,
|
|
||||||
// onSaved: (String? value) => password = value!,
|
|
||||||
// validator: (String? value) {
|
|
||||||
// String str = "";
|
|
||||||
// RegExp regex = RegExp(r'^[a-zA-Z0-9@#$]+$');
|
|
||||||
|
|
||||||
// if (value!.isEmpty) {
|
|
||||||
// str = '密码不能为空';
|
|
||||||
// } else if (!regex.hasMatch(value)) {
|
|
||||||
// str = '请输入有效的密码';
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return str == "" ? null : str;
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// const SizedBox(height: 24.0),
|
|
||||||
// Row(
|
|
||||||
// children: [
|
|
||||||
// Expanded(
|
|
||||||
// child: TextFormField(
|
|
||||||
// decoration: const InputDecoration(
|
|
||||||
// labelText: '验证码:',
|
|
||||||
// ),
|
|
||||||
// keyboardType: TextInputType.phone,
|
|
||||||
// validator: (String? value) {
|
|
||||||
// String str = "";
|
|
||||||
|
|
||||||
// if (value!.isEmpty) {
|
|
||||||
// str = '验证码不能为空';
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return str == "" ? null : str;
|
|
||||||
// },
|
|
||||||
// onSaved: (String? value) => verifyCode = value!,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ElevatedButton(
|
|
||||||
// onPressed: () async {
|
|
||||||
// changeCaptcha();
|
|
||||||
// },
|
|
||||||
// child: svgString.isNotEmpty
|
|
||||||
// ? SvgPicture.string(
|
|
||||||
// svgString,
|
|
||||||
// width: 70, // 设置宽度
|
|
||||||
// height: 40, // 设置高度
|
|
||||||
// color: Colors.black,
|
|
||||||
// )
|
|
||||||
// : const Text(""))
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// // 登录按钮
|
|
||||||
// ElevatedButton(
|
|
||||||
// onPressed: () async {
|
|
||||||
// if (_formKey.currentState!.validate()) {
|
|
||||||
// _formKey.currentState!.save(); //必须
|
|
||||||
// var res = await GetServices().getAccountLogin(
|
|
||||||
// captchaId, password, username, verifyCode);
|
|
||||||
// setState(() {
|
|
||||||
// if (res['code'] != 1000) {
|
|
||||||
// changeCaptcha();
|
|
||||||
// showErrorSnackbar(context, res["message"]);
|
|
||||||
// } else {
|
|
||||||
// loginPrefs.saveExpire((res["data"]["expire"]));
|
|
||||||
// loginPrefs.saveToken((res["data"]["token"]));
|
|
||||||
// Navigator.pushNamed(context, 'home'); //跳转至首页
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// child: const Text('登录'),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ))
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
class AccountLoginController extends GetxController {
|
|
||||||
final formKey = GlobalKey<FormState>();
|
|
||||||
final username = ''.obs;
|
|
||||||
final password = ''.obs;
|
|
||||||
final verifyCode = ''.obs;
|
|
||||||
final svgString = ''.obs;
|
|
||||||
final captchaId = ''.obs;
|
|
||||||
final obscureText = false.obs;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
State<AccountLoginPage> createState() => _AccountLoginPageState();
|
||||||
super.onInit();
|
}
|
||||||
changeCaptcha();
|
|
||||||
|
class _AccountLoginPageState extends State<AccountLoginPage> {
|
||||||
|
//初始化FormState
|
||||||
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
String username = "";
|
||||||
|
String password = "";
|
||||||
|
String verifyCode = "";
|
||||||
|
String svgString = "";
|
||||||
|
String captchaId = "";
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
||||||
|
await changeCaptcha();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> changeCaptcha() async {
|
changeCaptcha() async {
|
||||||
var captcha = await GetServices().getCaptcha();
|
var captcha = await GetServices().getCaptcha();
|
||||||
svgString.value = captcha['data'];
|
setState(() {
|
||||||
captchaId.value = captcha['captchaId'];
|
svgString = captcha['data'];
|
||||||
|
captchaId = captcha['captchaId'];
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void showErrorSnackbar(String text) {
|
showErrorSnackbar(BuildContext context, String text) {
|
||||||
final snackBar = SnackBar(
|
final snackBar = SnackBar(
|
||||||
content: Text(text),
|
content: Text(text),
|
||||||
backgroundColor: Colors.red,
|
backgroundColor: Colors.red,
|
||||||
);
|
);
|
||||||
|
|
||||||
ScaffoldMessenger.of(Get.context!).showSnackBar(snackBar);
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LoginPrefs loginPrefs = LoginPrefs();
|
||||||
}
|
bool _obscureText = false;
|
||||||
|
|
||||||
class AccountLoginPage extends GetView<AccountLoginController> {
|
|
||||||
const AccountLoginPage({super.key});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
@ -334,7 +114,7 @@ class AccountLoginPage extends GetView<AccountLoginController> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Form(
|
Form(
|
||||||
key: controller.formKey,
|
key: _formKey,
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// 账号输入框
|
// 账号输入框
|
||||||
@ -342,8 +122,7 @@ class AccountLoginPage extends GetView<AccountLoginController> {
|
|||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: '用户名:',
|
labelText: '用户名:',
|
||||||
),
|
),
|
||||||
onSaved: (String? value) =>
|
onSaved: (String? value) => username = value!,
|
||||||
controller.username.value = value!,
|
|
||||||
validator: (String? value) {
|
validator: (String? value) {
|
||||||
String str = "";
|
String str = "";
|
||||||
|
|
||||||
@ -360,22 +139,23 @@ class AccountLoginPage extends GetView<AccountLoginController> {
|
|||||||
const SizedBox(height: 16.0),
|
const SizedBox(height: 16.0),
|
||||||
|
|
||||||
// 密码输入框
|
// 密码输入框
|
||||||
Obx(() => TextFormField(
|
TextFormField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: '密码:',
|
labelText: '密码:',
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
controller.obscureText.value
|
_obscureText
|
||||||
? Icons.visibility
|
? Icons.visibility
|
||||||
: Icons.visibility_off,
|
: Icons.visibility_off,
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
controller.obscureText.toggle(); // 切换密码可见状态
|
setState(() {
|
||||||
|
_obscureText = !_obscureText; // 切换密码可见状态
|
||||||
|
});
|
||||||
}),
|
}),
|
||||||
),
|
),
|
||||||
obscureText: controller.obscureText.value,
|
obscureText: _obscureText,
|
||||||
onSaved: (String? value) =>
|
onSaved: (String? value) => password = value!,
|
||||||
controller.password.value = value!,
|
|
||||||
validator: (String? value) {
|
validator: (String? value) {
|
||||||
String str = "";
|
String str = "";
|
||||||
RegExp regex = RegExp(r'^[a-zA-Z0-9@#$]+$');
|
RegExp regex = RegExp(r'^[a-zA-Z0-9@#$]+$');
|
||||||
@ -388,7 +168,7 @@ class AccountLoginPage extends GetView<AccountLoginController> {
|
|||||||
|
|
||||||
return str == "" ? null : str;
|
return str == "" ? null : str;
|
||||||
},
|
},
|
||||||
)),
|
),
|
||||||
const SizedBox(height: 24.0),
|
const SizedBox(height: 24.0),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
@ -407,51 +187,46 @@ class AccountLoginPage extends GetView<AccountLoginController> {
|
|||||||
|
|
||||||
return str == "" ? null : str;
|
return str == "" ? null : str;
|
||||||
},
|
},
|
||||||
onSaved: (String? value) =>
|
onSaved: (String? value) => verifyCode = value!,
|
||||||
controller.verifyCode.value = value!,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
controller.changeCaptcha();
|
changeCaptcha();
|
||||||
},
|
},
|
||||||
child: Obx(() => controller.svgString.isNotEmpty
|
child: svgString.isNotEmpty
|
||||||
? SvgPicture.string(
|
? SvgPicture.string(
|
||||||
controller.svgString.value,
|
svgString,
|
||||||
width: 70, // 设置宽度
|
width: 70, // 设置宽度
|
||||||
height: 40, // 设置高度
|
height: 40, // 设置高度
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
)
|
)
|
||||||
: const Text("")))
|
: const Text(""))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// 登录按钮
|
// 登录按钮
|
||||||
|
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (controller.formKey.currentState!.validate()) {
|
if (_formKey.currentState!.validate()) {
|
||||||
controller.formKey.currentState!.save(); //必须
|
_formKey.currentState!.save(); //必须
|
||||||
var res = await GetServices().getAccountLogin(
|
var res = await GetServices().getAccountLogin(
|
||||||
controller.captchaId.value,
|
captchaId, password, username, verifyCode);
|
||||||
controller.password.value,
|
setState(() {
|
||||||
controller.username.value,
|
|
||||||
controller.verifyCode.value);
|
|
||||||
|
|
||||||
if (res['code'] != 1000) {
|
if (res['code'] != 1000) {
|
||||||
controller.changeCaptcha();
|
changeCaptcha();
|
||||||
controller.showErrorSnackbar(res["message"]);
|
showErrorSnackbar(context, res["message"]);
|
||||||
} else {
|
} else {
|
||||||
loginPrefs.saveExpire((res["data"]["expire"]));
|
loginPrefs.saveExpire((res["data"]["expire"]));
|
||||||
loginPrefs.saveToken((res["data"]["token"]));
|
loginPrefs.saveToken((res["data"]["token"]));
|
||||||
Navigator.pushNamed(context, 'home'); //跳转至首页
|
Navigator.pushNamed(context, 'home'); //跳转至首页
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: const Text('登录'),
|
child: const Text('登录'),
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
)
|
],
|
||||||
|
))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -459,248 +234,69 @@ class AccountLoginPage extends GetView<AccountLoginController> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// class PhoneLoginPage extends StatefulWidget {
|
class PhoneLoginPage extends StatefulWidget {
|
||||||
// const PhoneLoginPage({super.key});
|
const PhoneLoginPage({super.key});
|
||||||
|
|
||||||
// @override
|
|
||||||
// State<PhoneLoginPage> createState() => _PhoneLoginPageState();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// class _PhoneLoginPageState extends State<PhoneLoginPage> {
|
|
||||||
// String phoneNumber = "";
|
|
||||||
// String smsCode = "";
|
|
||||||
// bool issmsCode = false;
|
|
||||||
// String smsText = "获取验证码";
|
|
||||||
// int _seconds = 60;
|
|
||||||
// late Timer _timer;
|
|
||||||
// //初始化FormState
|
|
||||||
// final _formKey = GlobalKey<FormState>();
|
|
||||||
// LoginPrefs loginPrefs = LoginPrefs();
|
|
||||||
// @override
|
|
||||||
// void initState() {
|
|
||||||
// super.initState();
|
|
||||||
|
|
||||||
// phoneNumber = loginPrefs.getPhone();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// void startTimer() {
|
|
||||||
// _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
|
||||||
// if (_seconds > 0) {
|
|
||||||
// _seconds -= 1;
|
|
||||||
// smsText = "重新获取(${_seconds}s)";
|
|
||||||
// } else {
|
|
||||||
// _timer.cancel(); // 到0时关闭定时器
|
|
||||||
// smsText = "获取验证码";
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// showErrorSnackbar(BuildContext context, String text) {
|
|
||||||
// final snackBar = SnackBar(
|
|
||||||
// content: Text(text),
|
|
||||||
// backgroundColor: Colors.red,
|
|
||||||
// );
|
|
||||||
|
|
||||||
// ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
|
||||||
// @override
|
|
||||||
// Widget build(BuildContext context) {
|
|
||||||
// return Container(
|
|
||||||
// key: _scaffoldKey,
|
|
||||||
// padding: const EdgeInsets.all(16.0),
|
|
||||||
// child: SingleChildScrollView(
|
|
||||||
// child: Column(
|
|
||||||
// children: <Widget>[
|
|
||||||
// Form(
|
|
||||||
// key: _formKey,
|
|
||||||
// child:
|
|
||||||
// // 手机号输入框
|
|
||||||
// Column(
|
|
||||||
// children: [
|
|
||||||
// TextFormField(
|
|
||||||
// maxLength: 11,
|
|
||||||
// initialValue: phoneNumber,
|
|
||||||
// decoration: const InputDecoration(
|
|
||||||
// labelText: '手机号',
|
|
||||||
// ),
|
|
||||||
// keyboardType: TextInputType.phone,
|
|
||||||
// validator: (String? value) {
|
|
||||||
// String str = "";
|
|
||||||
// final RegExp phoneRegex = RegExp(r'^[1-9]\d{10}$');
|
|
||||||
// if (value!.isEmpty) {
|
|
||||||
// str = '手机号不能为空';
|
|
||||||
// } else if (!phoneRegex.hasMatch(value)) {
|
|
||||||
// str = '请输入有效的手机号';
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return str == "" ? null : str;
|
|
||||||
// },
|
|
||||||
// onSaved: (String? value) => phoneNumber = value!,
|
|
||||||
// ),
|
|
||||||
// Row(
|
|
||||||
// children: [
|
|
||||||
// Expanded(
|
|
||||||
// child: TextFormField(
|
|
||||||
// maxLength: 6,
|
|
||||||
// decoration: const InputDecoration(
|
|
||||||
// labelText: '验证码',
|
|
||||||
// ),
|
|
||||||
// keyboardType: TextInputType.phone,
|
|
||||||
// validator: (String? value) {
|
|
||||||
// String str = "";
|
|
||||||
// if (value!.isEmpty) {
|
|
||||||
// str = '验证码不能为空';
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (issmsCode) {
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
// return str == "" ? null : str;
|
|
||||||
// },
|
|
||||||
// onSaved: (val) => smsCode = val!,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// // 获取验证码按钮
|
|
||||||
// ElevatedButton(
|
|
||||||
// onPressed: () async {
|
|
||||||
// issmsCode = true;
|
|
||||||
// if (_formKey.currentState!.validate()) {
|
|
||||||
// _formKey.currentState!.save();
|
|
||||||
// // 收回键盘
|
|
||||||
// FocusScope.of(context).unfocus();
|
|
||||||
// await GetServices().getsmsCode(phoneNumber);
|
|
||||||
// startTimer(); // 开始定时器
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// child: Text(smsText),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// const SizedBox(height: 16.0),
|
|
||||||
|
|
||||||
// // 登录按钮
|
|
||||||
// ElevatedButton(
|
|
||||||
// onPressed: () async {
|
|
||||||
// issmsCode = false;
|
|
||||||
// if (_formKey.currentState!.validate()) {
|
|
||||||
// _formKey.currentState!.save();
|
|
||||||
// // 表单校验通过,执行提交逻辑...
|
|
||||||
// // 收回键盘
|
|
||||||
// FocusScope.of(context).unfocus();
|
|
||||||
// var res = await GetServices()
|
|
||||||
// .phoneLogin(phoneNumber, smsCode);
|
|
||||||
// setState(() {
|
|
||||||
// if (res['code'] != 1000) {
|
|
||||||
// showErrorSnackbar(
|
|
||||||
// _scaffoldKey.currentContext!, res["message"]);
|
|
||||||
// } else {
|
|
||||||
// loginPrefs.savePhone(phoneNumber);
|
|
||||||
// loginPrefs.saveExpire(res["data"]["expire"]);
|
|
||||||
// loginPrefs.saveToken(res["data"]["token"]);
|
|
||||||
// Navigator.pushNamed(
|
|
||||||
// _scaffoldKey.currentContext!, 'home'); //跳转至首页
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// child: const Text('登录'),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// )),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
class PhoneLoginController extends GetxController {
|
|
||||||
final _formKey = GlobalKey<FormState>();
|
|
||||||
final phoneNumber = ''.obs;
|
|
||||||
final smsCode = ''.obs;
|
|
||||||
final issmsCode = false.obs;
|
|
||||||
final smsText = '获取验证码'.obs;
|
|
||||||
final _seconds = 60.obs;
|
|
||||||
late Timer _timer;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
State<PhoneLoginPage> createState() => _PhoneLoginPageState();
|
||||||
super.onInit();
|
}
|
||||||
phoneNumber.value = LoginPrefs().getPhone();
|
|
||||||
|
class _PhoneLoginPageState extends State<PhoneLoginPage> {
|
||||||
|
String phoneNumber = "";
|
||||||
|
String smsCode = "";
|
||||||
|
bool issmsCode = false;
|
||||||
|
String smsText = "获取验证码";
|
||||||
|
int _seconds = 60;
|
||||||
|
late Timer _timer;
|
||||||
|
//初始化FormState
|
||||||
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
LoginPrefs loginPrefs = LoginPrefs();
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
|
||||||
|
phoneNumber = loginPrefs.getPhone();
|
||||||
}
|
}
|
||||||
|
|
||||||
void startTimer() {
|
void startTimer() {
|
||||||
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
|
||||||
if (_seconds.value > 0) {
|
if (_seconds > 0) {
|
||||||
_seconds.value -= 1;
|
_seconds -= 1;
|
||||||
smsText.value = "重新获取(${_seconds.value}s)";
|
smsText = "重新获取(${_seconds}s)";
|
||||||
} else {
|
} else {
|
||||||
_timer.cancel(); // 到0时关闭定时器
|
_timer.cancel(); // 到0时关闭定时器
|
||||||
smsText.value = "获取验证码";
|
smsText = "获取验证码";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void showErrorSnackbar(String text) {
|
showErrorSnackbar(BuildContext context, String text) {
|
||||||
final snackBar = SnackBar(
|
final snackBar = SnackBar(
|
||||||
content: Text(text),
|
content: Text(text),
|
||||||
backgroundColor: Colors.red,
|
backgroundColor: Colors.red,
|
||||||
);
|
);
|
||||||
|
|
||||||
ScaffoldMessenger.of(Get.context!).showSnackBar(snackBar);
|
ScaffoldMessenger.of(context).showSnackBar(snackBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> getSmsCode() async {
|
final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
issmsCode.value = true;
|
|
||||||
if (_formKey.currentState!.validate()) {
|
|
||||||
_formKey.currentState!.save();
|
|
||||||
// 收回键盘
|
|
||||||
FocusScope.of(Get.context!).unfocus();
|
|
||||||
await GetServices().getsmsCode(phoneNumber.value);
|
|
||||||
startTimer(); // 开始定时器
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> login() async {
|
|
||||||
issmsCode.value = false;
|
|
||||||
if (_formKey.currentState!.validate()) {
|
|
||||||
_formKey.currentState!.save();
|
|
||||||
// 表单校验通过,执行提交逻辑...
|
|
||||||
// 收回键盘
|
|
||||||
FocusScope.of(Get.context!).unfocus();
|
|
||||||
var res =
|
|
||||||
await GetServices().phoneLogin(phoneNumber.value, smsCode.value);
|
|
||||||
if (res['code'] != 1000) {
|
|
||||||
showErrorSnackbar(res["message"]);
|
|
||||||
} else {
|
|
||||||
LoginPrefs().savePhone(phoneNumber.value);
|
|
||||||
LoginPrefs().saveExpire(res["data"]["expire"]);
|
|
||||||
LoginPrefs().saveToken(res["data"]["token"]);
|
|
||||||
Get.offNamed('home'); // 跳转至首页
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PhoneLoginPage extends GetView<PhoneLoginController> {
|
|
||||||
const PhoneLoginPage({super.key});
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Container(
|
return Container(
|
||||||
|
key: _scaffoldKey,
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: <Widget>[
|
children: <Widget>[
|
||||||
Form(
|
Form(
|
||||||
key: controller._formKey,
|
key: _formKey,
|
||||||
child: Column(
|
child:
|
||||||
children: [
|
|
||||||
// 手机号输入框
|
// 手机号输入框
|
||||||
|
Column(
|
||||||
|
children: [
|
||||||
TextFormField(
|
TextFormField(
|
||||||
maxLength: 11,
|
maxLength: 11,
|
||||||
initialValue: controller.phoneNumber.value,
|
initialValue: phoneNumber,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
labelText: '手机号',
|
labelText: '手机号',
|
||||||
),
|
),
|
||||||
@ -716,8 +312,7 @@ class PhoneLoginPage extends GetView<PhoneLoginController> {
|
|||||||
|
|
||||||
return str == "" ? null : str;
|
return str == "" ? null : str;
|
||||||
},
|
},
|
||||||
onSaved: (String? value) =>
|
onSaved: (String? value) => phoneNumber = value!,
|
||||||
controller.phoneNumber.value = value!,
|
|
||||||
),
|
),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
@ -734,21 +329,27 @@ class PhoneLoginPage extends GetView<PhoneLoginController> {
|
|||||||
str = '验证码不能为空';
|
str = '验证码不能为空';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (controller.issmsCode.value) {
|
if (issmsCode) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return str == "" ? null : str;
|
return str == "" ? null : str;
|
||||||
},
|
},
|
||||||
onSaved: (String? value) =>
|
onSaved: (val) => smsCode = val!,
|
||||||
controller.smsCode.value = value!,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// 获取验证码按钮
|
// 获取验证码按钮
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
controller.getSmsCode();
|
issmsCode = true;
|
||||||
|
if (_formKey.currentState!.validate()) {
|
||||||
|
_formKey.currentState!.save();
|
||||||
|
// 收回键盘
|
||||||
|
FocusScope.of(context).unfocus();
|
||||||
|
await GetServices().getsmsCode(phoneNumber);
|
||||||
|
startTimer(); // 开始定时器
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: Obx(() => Text(controller.smsText.value)),
|
child: Text(smsText),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -757,13 +358,32 @@ class PhoneLoginPage extends GetView<PhoneLoginController> {
|
|||||||
// 登录按钮
|
// 登录按钮
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
controller.login();
|
issmsCode = false;
|
||||||
|
if (_formKey.currentState!.validate()) {
|
||||||
|
_formKey.currentState!.save();
|
||||||
|
// 表单校验通过,执行提交逻辑...
|
||||||
|
// 收回键盘
|
||||||
|
FocusScope.of(context).unfocus();
|
||||||
|
var res = await GetServices()
|
||||||
|
.phoneLogin(phoneNumber, smsCode);
|
||||||
|
setState(() {
|
||||||
|
if (res['code'] != 1000) {
|
||||||
|
showErrorSnackbar(
|
||||||
|
_scaffoldKey.currentContext!, res["message"]);
|
||||||
|
} else {
|
||||||
|
loginPrefs.savePhone(phoneNumber);
|
||||||
|
loginPrefs.saveExpire(res["data"]["expire"]);
|
||||||
|
loginPrefs.saveToken(res["data"]["token"]);
|
||||||
|
Navigator.pushNamed(
|
||||||
|
_scaffoldKey.currentContext!, 'home'); //跳转至首页
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
child: const Text('登录'),
|
child: const Text('登录'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
)),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:get_storage/get_storage.dart';
|
import 'package:get_storage/get_storage.dart';
|
||||||
|
|
||||||
import 'package:cpnav/pages/login/user.dart';
|
import 'package:cpnav/models/user.dart';
|
||||||
|
|
||||||
class LoginPrefs extends GetxController {
|
class LoginPrefs extends GetxController {
|
||||||
static const String expireStr = "expire"; //用户名
|
static const String expireStr = "expire"; //用户名
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
//配置路由
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
|
|
||||||
import '../../main.dart';
|
|
||||||
import 'login_page.dart';
|
|
||||||
import 'loginprefs.dart';
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 这个方法是固定写法,功能就像是一个拦截器。
|
|
||||||
*/
|
|
||||||
Route<dynamic>? onGenerateRoute(RouteSettings settings) {
|
|
||||||
Map<String, Widget> routes = {
|
|
||||||
'home': MyHomePage(title: 'Flutter Demo Home Page'), //定义app路径
|
|
||||||
'login': const Login(), //定义login路径
|
|
||||||
};
|
|
||||||
|
|
||||||
String routerName = routeBeforeHook(settings);
|
|
||||||
bool mathMap = false;
|
|
||||||
Route<dynamic>? mathWidget;
|
|
||||||
routes.forEach((key, v) {
|
|
||||||
if (key == routerName) {
|
|
||||||
mathMap = true;
|
|
||||||
mathWidget = MaterialPageRoute(builder: (BuildContext context) => v);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (mathMap) {
|
|
||||||
return mathWidget;
|
|
||||||
}
|
|
||||||
return MaterialPageRoute(
|
|
||||||
builder: (BuildContext context) => const Text('404'));
|
|
||||||
}
|
|
||||||
|
|
||||||
String routeBeforeHook(RouteSettings settings) {
|
|
||||||
if (checkToken() == false) {
|
|
||||||
return 'login';
|
|
||||||
} else {
|
|
||||||
return settings.name!;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool checkToken() {
|
|
||||||
LoginPrefs loginPrefs = LoginPrefs();
|
|
||||||
String token = loginPrefs.getToken();
|
|
||||||
if ('' != token) return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:get/get.dart';
|
|
||||||
|
|
||||||
class IconController extends GetxController {
|
|
||||||
final RxMap<IconData, Color> iconColors = {
|
|
||||||
Icons.article: Colors.green,
|
|
||||||
Icons.speed: const Color.fromARGB(255, 166, 182, 149),
|
|
||||||
Icons.thermostat: const Color.fromARGB(255, 166, 182, 149),
|
|
||||||
Icons.zoom_in: const Color.fromARGB(255, 166, 182, 149),
|
|
||||||
Icons.zoom_out: const Color.fromARGB(255, 166, 182, 149),
|
|
||||||
Icons.refresh: const Color.fromARGB(255, 166, 182, 149),
|
|
||||||
Icons.place: const Color.fromARGB(255, 166, 182, 149),
|
|
||||||
}.obs;
|
|
||||||
// IconData? _selectedIcon;
|
|
||||||
late IconData selectedIcon;
|
|
||||||
@override
|
|
||||||
void onInit() {
|
|
||||||
super.onInit();
|
|
||||||
handleTap1(Icons.close, () {}); // 初始时,默认第一个图标为选中状态,并触发onTap事件(空函数, onTap)
|
|
||||||
handleTap2(Icons.close, () {});
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleTap1(IconData icon, VoidCallback onTap) {
|
|
||||||
selectedIcon = icon;
|
|
||||||
iconColors.forEach((key, value) {
|
|
||||||
iconColors[key] = key == icon
|
|
||||||
? Colors.green // 点击后变浅的颜色
|
|
||||||
: const Color.fromARGB(255, 166, 182, 149); // 其他图标恢复原色
|
|
||||||
});
|
|
||||||
onTap();
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleTap2(IconData icon, VoidCallback onTap) {
|
|
||||||
iconColors[icon] = Colors.green; // 点击后变浅的颜色
|
|
||||||
|
|
||||||
onTap();
|
|
||||||
Future.delayed(Duration(milliseconds: 200), () {
|
|
||||||
iconColors[icon] = const Color.fromARGB(255, 166, 182, 149); // 恢复原色
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +1,26 @@
|
|||||||
import 'dart:ui';
|
import 'dart:ui';
|
||||||
import "dart:ffi" as ffi;
|
|
||||||
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:scence_map/controller.dart';
|
import 'package:scence_map/controller.dart';
|
||||||
import 'package:cpnav/service/base.dart';
|
import 'package:cpnav/service/base.dart';
|
||||||
import 'package:pass_track/pass_track.dart';
|
import 'package:pass_track/pass_track.dart';
|
||||||
import 'sevice/file_handle.dart';
|
import 'sevice/file_handle.dart';
|
||||||
|
|
||||||
|
|
||||||
FileHandle fileHandle = FileHandle();
|
FileHandle fileHandle = FileHandle();
|
||||||
ScenceMapController mapcontroller = Get.put(ScenceMapController());
|
|
||||||
|
|
||||||
class PassTrackController extends GetxController {
|
class PassTrackController extends GetxController {
|
||||||
var tileCount = 0.obs;
|
int allLen = 0;
|
||||||
var tileFirst = 0.obs;
|
|
||||||
var tileLast = 0.obs;
|
|
||||||
final mapController = Get.put(ScenceMapController());
|
final mapController = Get.put(ScenceMapController());
|
||||||
|
|
||||||
String projCode;
|
String projCode;
|
||||||
String projType;
|
String projType;
|
||||||
var speed = 1.obs;
|
|
||||||
late final GetServices service;
|
late final GetServices service;
|
||||||
|
// final PassTrack _passTrackPlugin;
|
||||||
PassTrackController(this.projCode, this.projType);
|
PassTrackController(this.projCode, this.projType);
|
||||||
Map<String, int> deviceMap = {};
|
Map<String, int> deviceMap = {};
|
||||||
Map<String, int> coorTransMap = {};
|
Map<String, int> coorTransMap = {};
|
||||||
// final PassTrack _passTrackPlugin;
|
|
||||||
final PassTrack _passTrackPlugin = PassTrack();
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
super.onInit();
|
super.onInit();
|
||||||
@ -33,72 +29,6 @@ class PassTrackController extends GetxController {
|
|||||||
// loadSideLine();
|
// loadSideLine();
|
||||||
loadBindDevice();
|
loadBindDevice();
|
||||||
// getHisFileList();
|
// getHisFileList();
|
||||||
var future = getHisFileList(_passTrackPlugin);
|
|
||||||
|
|
||||||
// var maxLen =
|
|
||||||
// controller.allLen > 0 ? controller.allLen : 1.0; // 确保 maxLen 大于 0
|
|
||||||
// _rangevalues = SfRangeValues(0.0, maxLen);
|
|
||||||
// SchedulerBinding.instance.addPostFrameCallback((_) async {
|
|
||||||
// sWidth = sqrt(screen.width * screen.width + screen.height * screen.height)
|
|
||||||
// .ceil();
|
|
||||||
|
|
||||||
// // scenceMapController.scale = passTrackPlugin.passTrack_getScale() * 1.0;
|
|
||||||
// fileHandle.date = widget.date;
|
|
||||||
// await fileHandle.init();
|
|
||||||
// //在帧绘制完成后执行数据渲染
|
|
||||||
// // await initPlatformState();
|
|
||||||
// if (fileHandle.pointData.isNotEmpty) {
|
|
||||||
// DecodeDataObj obj = fileHandle.pointData[0].obj!;
|
|
||||||
// scenceMapController.centerXY = Offset(obj.y / 20, obj.x / 20);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for (var item in fileHandle.deviceList) {
|
|
||||||
// if (item["point"] != null) {
|
|
||||||
// bits = item["bits"];
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// // passTrackPlugin.map_setCenterDevice(bits);
|
|
||||||
// setState(() {
|
|
||||||
// if (fileHandle.pointData.isNotEmpty) {
|
|
||||||
// maxLength = fileHandle.pointData.length;
|
|
||||||
// // _value = maxLength;
|
|
||||||
// _rangevalues = SfRangeValues(0.0, maxLength.toDouble());
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
|
|
||||||
var f = initPlatformState();
|
|
||||||
|
|
||||||
f.then((void _) {
|
|
||||||
_passTrackPlugin.setGridColor(const Color.fromARGB(255, 0, 0, 0).value);
|
|
||||||
_passTrackPlugin.drawGrid();
|
|
||||||
|
|
||||||
future.then((value) {
|
|
||||||
_passTrackPlugin.setScale(1);
|
|
||||||
for (var TID in deviceMap.keys) {
|
|
||||||
_passTrackPlugin.addDevice(int.parse(TID), 0);
|
|
||||||
}
|
|
||||||
for (var item in coorTransMap.entries) {
|
|
||||||
print("tid:${item.key} value:${item.value}");
|
|
||||||
}
|
|
||||||
// 统计用时 获取当前时间
|
|
||||||
var start = DateTime.now().millisecondsSinceEpoch;
|
|
||||||
// _passTrackPlugin.generateTile(0, value);
|
|
||||||
_passTrackPlugin.waitForTile(() {
|
|
||||||
var start = DateTime.now().millisecondsSinceEpoch;
|
|
||||||
print("len: ${_passTrackPlugin.allTileCnt()}");
|
|
||||||
tileCount.value = _passTrackPlugin.allTileCnt();
|
|
||||||
// _rangevalues = SfRangeValues(0, _passTrackPlugin.allTileCnt());
|
|
||||||
_passTrackPlugin.playTrack(
|
|
||||||
0, _passTrackPlugin.allTileCnt(), true, 0, ffi.nullptr);
|
|
||||||
var end = DateTime.now().millisecondsSinceEpoch;
|
|
||||||
print("play: ${end - start}");
|
|
||||||
});
|
|
||||||
// _passTrackPlugin.drawGrid();
|
|
||||||
// 获取当前时间
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loadBindDevice() async {
|
loadBindDevice() async {
|
||||||
@ -160,34 +90,12 @@ class PassTrackController extends GetxController {
|
|||||||
var jsData = await GetServices().getHisFil1(file);
|
var jsData = await GetServices().getHisFil1(file);
|
||||||
print("have message");
|
print("have message");
|
||||||
int len = fileHandle.resolveJson(jsData, passTrackPlugin);
|
int len = fileHandle.resolveJson(jsData, passTrackPlugin);
|
||||||
tileCount.value += len;
|
allLen += len;
|
||||||
if (tileCount.value >= 20000) {
|
if (allLen >= 20000) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
coorTransMap = fileHandle.pointsMap;
|
coorTransMap = fileHandle.pointsMap;
|
||||||
return tileCount.value;
|
return allLen;
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> initPlatformState() async {
|
|
||||||
String platformVersion;
|
|
||||||
try {
|
|
||||||
platformVersion = await _passTrackPlugin.getPlatformVersion() ??
|
|
||||||
'Unknown platform version';
|
|
||||||
} on Exception {
|
|
||||||
platformVersion = 'Failed to get platform version.';
|
|
||||||
}
|
|
||||||
await _passTrackPlugin.create(
|
|
||||||
mapcontroller.height.toInt(), mapcontroller.width.toInt());
|
|
||||||
fileHandle.textureId = await _passTrackPlugin.getTextureId() ?? -1;
|
|
||||||
print("textureId: ${fileHandle.textureId}");
|
|
||||||
print("${mapcontroller.height.toInt()}");
|
|
||||||
|
|
||||||
// if (!mounted) Exception('Failed to get textureId.');
|
|
||||||
|
|
||||||
// setState(() {
|
|
||||||
// platformVersion = platformVersion;
|
|
||||||
// });
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,17 +4,49 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:scence_map/controller.dart';
|
import 'package:scence_map/controller.dart';
|
||||||
|
|
||||||
import 'iconController.dart';
|
|
||||||
|
|
||||||
ScenceMapController mapController = Get.put(ScenceMapController());
|
ScenceMapController mapController = Get.put(ScenceMapController());
|
||||||
|
|
||||||
// class IconContainer extends StatefulWidget {
|
class IconContainer extends StatefulWidget {
|
||||||
// @override
|
@override
|
||||||
// _IconContainerState createState() => _IconContainerState();
|
_IconContainerState createState() => _IconContainerState();
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
class _IconContainerState extends State<IconContainer> {
|
||||||
|
final Map<IconData, Color> _iconColors = {
|
||||||
|
Icons.article: Colors.green,
|
||||||
|
Icons.speed: const Color.fromARGB(255, 166, 182, 149),
|
||||||
|
Icons.thermostat: const Color.fromARGB(255, 166, 182, 149),
|
||||||
|
Icons.zoom_in: const Color.fromARGB(255, 166, 182, 149),
|
||||||
|
Icons.zoom_out: const Color.fromARGB(255, 166, 182, 149),
|
||||||
|
Icons.refresh: const Color.fromARGB(255, 166, 182, 149),
|
||||||
|
Icons.place: const Color.fromARGB(255, 166, 182, 149),
|
||||||
|
};
|
||||||
|
IconData? _selectedIcon;
|
||||||
|
|
||||||
|
void _handleTap1(IconData icon, VoidCallback onTap) {
|
||||||
|
setState(() {
|
||||||
|
_selectedIcon = icon;
|
||||||
|
_iconColors.forEach((key, value) {
|
||||||
|
_iconColors[key] = key == icon
|
||||||
|
? Colors.green // 点击后变浅的颜色
|
||||||
|
: const Color.fromARGB(255, 166, 182, 149); // 其他图标恢复原色
|
||||||
|
});
|
||||||
|
});
|
||||||
|
onTap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void _handleTap2(IconData icon, VoidCallback onTap) {
|
||||||
|
setState(() {
|
||||||
|
_iconColors[icon] = Colors.green; // 点击后变浅的颜色
|
||||||
|
});
|
||||||
|
onTap();
|
||||||
|
Future.delayed(Duration(milliseconds: 200), () {
|
||||||
|
setState(() {
|
||||||
|
_iconColors[icon] = const Color.fromARGB(255, 166, 182, 149); // 恢复原色
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// class _IconContainerState extends State<IconContainer> {
|
|
||||||
class IconContainer extends GetView<IconController> {
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;
|
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;
|
||||||
@ -30,7 +62,7 @@ class IconContainer extends GetView<IconController> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: const Color.fromARGB(255, 54, 52, 52),
|
color: Color.fromARGB(255, 54, 52, 52),
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
),
|
),
|
||||||
borderRadius: BorderRadius.circular(5.0),
|
borderRadius: BorderRadius.circular(5.0),
|
||||||
@ -102,7 +134,7 @@ class IconContainer extends GetView<IconController> {
|
|||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.transparent,
|
color: Colors.transparent,
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: const Color.fromARGB(255, 54, 52, 52),
|
color: Color.fromARGB(255, 54, 52, 52),
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
),
|
),
|
||||||
borderRadius: BorderRadius.circular(5.0),
|
borderRadius: BorderRadius.circular(5.0),
|
||||||
@ -171,13 +203,12 @@ class IconContainer extends GetView<IconController> {
|
|||||||
|
|
||||||
//前三个单选
|
//前三个单选
|
||||||
Widget _singleChange(IconData icon, VoidCallback onTap) {
|
Widget _singleChange(IconData icon, VoidCallback onTap) {
|
||||||
return Obx(() {
|
|
||||||
return Container(
|
return Container(
|
||||||
width: 33,
|
width: 33,
|
||||||
height: 33,
|
height: 33,
|
||||||
margin: const EdgeInsets.symmetric(vertical: 2.0),
|
margin: EdgeInsets.symmetric(vertical: 2.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: controller.iconColors[icon],
|
color: _iconColors[icon],
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
@ -188,21 +219,19 @@ class IconContainer extends GetView<IconController> {
|
|||||||
icon,
|
icon,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
onTap: () => controller.handleTap1(icon, onTap),
|
onTap: () => _handleTap1(icon, onTap),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//后三个自动恢复
|
//后三个自动恢复
|
||||||
Widget _automChange(IconData icon, VoidCallback onTap) {
|
Widget _automChange(IconData icon, VoidCallback onTap) {
|
||||||
return Obx(() {
|
|
||||||
return Container(
|
return Container(
|
||||||
width: 33,
|
width: 33,
|
||||||
height: 33,
|
height: 33,
|
||||||
margin: const EdgeInsets.symmetric(vertical: 2.0),
|
margin: EdgeInsets.symmetric(vertical: 2.0),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: controller.iconColors[icon],
|
color: _iconColors[icon],
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
@ -213,9 +242,8 @@ class IconContainer extends GetView<IconController> {
|
|||||||
icon,
|
icon,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
onTap: () => controller.handleTap2(icon, onTap),
|
onTap: () => _handleTap2(icon, onTap),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,13 +9,12 @@ import 'package:scence_map/controller.dart';
|
|||||||
import 'package:scence_map/scence_map.dart';
|
import 'package:scence_map/scence_map.dart';
|
||||||
|
|
||||||
import 'package:syncfusion_flutter_sliders/sliders.dart';
|
import 'package:syncfusion_flutter_sliders/sliders.dart';
|
||||||
import 'bottomIcon/iconContainer.dart';
|
import 'iconContainer.dart';
|
||||||
import "controller.dart";
|
import "controller.dart";
|
||||||
import "package:pass_track/pass_track.dart";
|
import "package:pass_track/pass_track.dart";
|
||||||
import "package:pass_track/pass_track_platform_interface.dart";
|
import "package:pass_track/pass_track_platform_interface.dart";
|
||||||
import "controller.dart";
|
import "controller.dart";
|
||||||
import "dart:ffi" as ffi;
|
import "dart:ffi" as ffi;
|
||||||
|
|
||||||
// import '../login_in/connect/bluetooth_page.dart';
|
// import '../login_in/connect/bluetooth_page.dart';
|
||||||
// import '../login_in/connect/config.dart';
|
// import '../login_in/connect/config.dart';
|
||||||
// import '../login_in/connect/connect_type.dart';
|
// import '../login_in/connect/connect_type.dart';
|
||||||
@ -27,29 +26,37 @@ import "dart:ffi" as ffi;
|
|||||||
|
|
||||||
ScenceMapController mapcontroller = Get.put(ScenceMapController());
|
ScenceMapController mapcontroller = Get.put(ScenceMapController());
|
||||||
|
|
||||||
class PassTrackView extends GetView<PassTrackController> {
|
class PassTrackWidget extends StatefulWidget {
|
||||||
|
final String date;
|
||||||
|
final controller;
|
||||||
|
|
||||||
|
const PassTrackWidget({super.key, required this.date, this.controller});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<PassTrackWidget> createState() => _PasstrackState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PasstrackState extends State<PassTrackWidget> {
|
||||||
final GlobalKey<PopupMenuButtonState<int>> _popupMenuKey =
|
final GlobalKey<PopupMenuButtonState<int>> _popupMenuKey =
|
||||||
GlobalKey<PopupMenuButtonState<int>>();
|
GlobalKey<PopupMenuButtonState<int>>();
|
||||||
// final controller = Get.put(PassTrackController("WXLMB", "cp_road"));
|
final controller = Get.put(PassTrackController("WXLMB", "cp_road"));
|
||||||
final String str = "播放";
|
String str = "播放";
|
||||||
// int sWidth = 800;
|
int sWidth = 800;
|
||||||
// int sHeight = 800;
|
int sHeight = 800;
|
||||||
// int bits = -1;
|
int bits = -1;
|
||||||
// int speed = 50;
|
int speed = 50;
|
||||||
|
List<int> speedList = [1, 2, 10, 20, 50, 100, 200, 500];
|
||||||
// int maxLength = 200;
|
// int maxLength = 200;
|
||||||
// late SfRangeValues _rangevalues;
|
late SfRangeValues _rangevalues;
|
||||||
final PassTrack _passTrackPlugin = PassTrack();
|
final PassTrack _passTrackPlugin = PassTrack();
|
||||||
|
|
||||||
PassTrackView({Key? key}) : super(key: key);
|
@override
|
||||||
|
initState() {
|
||||||
// @override
|
super.initState();
|
||||||
// initState() {
|
var maxLen =
|
||||||
// super.initState();
|
controller.allLen > 0 ? controller.allLen : 1.0; // 确保 maxLen 大于 0
|
||||||
// var maxLen =
|
_rangevalues = SfRangeValues(0.0, maxLen);
|
||||||
// controller.allLen > 0 ? controller.allLen : 1.0; // 确保 maxLen 大于 0
|
SchedulerBinding.instance.addPostFrameCallback((_) async {
|
||||||
// _rangevalues = SfRangeValues(0.0, maxLen);
|
|
||||||
// SchedulerBinding.instance.addPostFrameCallback((_) async {
|
|
||||||
// sWidth = sqrt(screen.width * screen.width + screen.height * screen.height)
|
// sWidth = sqrt(screen.width * screen.width + screen.height * screen.height)
|
||||||
// .ceil();
|
// .ceil();
|
||||||
|
|
||||||
@ -77,76 +84,74 @@ class PassTrackView extends GetView<PassTrackController> {
|
|||||||
// _rangevalues = SfRangeValues(0.0, maxLength.toDouble());
|
// _rangevalues = SfRangeValues(0.0, maxLength.toDouble());
|
||||||
// }
|
// }
|
||||||
// });
|
// });
|
||||||
// });
|
});
|
||||||
// var f = initPlatformState();
|
var f = initPlatformState();
|
||||||
// var future = controller.getHisFileList(_passTrackPlugin);
|
var future = controller.getHisFileList(_passTrackPlugin);
|
||||||
// f.then((void _) {
|
f.then((void _) {
|
||||||
// _passTrackPlugin.setGridColor(const Color.fromARGB(255, 0, 0, 0).value);
|
_passTrackPlugin.setGridColor(const Color.fromARGB(255, 0, 0, 0).value);
|
||||||
|
_passTrackPlugin.drawGrid();
|
||||||
|
|
||||||
|
future.then((value) {
|
||||||
|
_passTrackPlugin.setScale(1);
|
||||||
|
for (var TID in controller.deviceMap.keys) {
|
||||||
|
_passTrackPlugin.addDevice(int.parse(TID), 0);
|
||||||
|
}
|
||||||
|
for (var item in controller.coorTransMap.entries) {
|
||||||
|
print("tid:${item.key} value:${item.value}");
|
||||||
|
}
|
||||||
|
// 统计用时 获取当前时间
|
||||||
|
var start = DateTime.now().millisecondsSinceEpoch;
|
||||||
|
// _passTrackPlugin.generateTile(0, value);
|
||||||
|
_passTrackPlugin.waitForTile(() {
|
||||||
|
var start = DateTime.now().millisecondsSinceEpoch;
|
||||||
|
print("len: ${_passTrackPlugin.allTileCnt()}");
|
||||||
|
controller.allLen = _passTrackPlugin.allTileCnt();
|
||||||
|
_rangevalues = SfRangeValues(0, _passTrackPlugin.allTileCnt());
|
||||||
|
_passTrackPlugin.playTrack(0, _passTrackPlugin.allTileCnt(), true, 0, ffi.nullptr);
|
||||||
|
var end = DateTime.now().millisecondsSinceEpoch;
|
||||||
|
print("play: ${end - start}");
|
||||||
|
});
|
||||||
// _passTrackPlugin.drawGrid();
|
// _passTrackPlugin.drawGrid();
|
||||||
|
// 获取当前时间
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// future.then((value) {
|
Future<void> initPlatformState() async {
|
||||||
// _passTrackPlugin.setScale(1);
|
String platformVersion;
|
||||||
// for (var TID in controller.deviceMap.keys) {
|
try {
|
||||||
// _passTrackPlugin.addDevice(int.parse(TID), 0);
|
platformVersion = await _passTrackPlugin.getPlatformVersion() ??
|
||||||
// }
|
'Unknown platform version';
|
||||||
// for (var item in controller.coorTransMap.entries) {
|
} on Exception {
|
||||||
// print("tid:${item.key} value:${item.value}");
|
platformVersion = 'Failed to get platform version.';
|
||||||
// }
|
}
|
||||||
// // 统计用时 获取当前时间
|
await _passTrackPlugin.create(sWidth, sWidth);
|
||||||
// var start = DateTime.now().millisecondsSinceEpoch;
|
fileHandle.textureId = await _passTrackPlugin.getTextureId() ?? -1;
|
||||||
// // _passTrackPlugin.generateTile(0, value);
|
print("textureId: ${fileHandle.textureId}");
|
||||||
// _passTrackPlugin.waitForTile(() {
|
|
||||||
// var start = DateTime.now().millisecondsSinceEpoch;
|
|
||||||
// print("len: ${_passTrackPlugin.allTileCnt()}");
|
|
||||||
// _rangevalues = SfRangeValues(0, _passTrackPlugin.allTileCnt());
|
|
||||||
// _passTrackPlugin.playTrack(
|
|
||||||
// 0, _passTrackPlugin.allTileCnt(), true, 0, ffi.nullptr);
|
|
||||||
// var end = DateTime.now().millisecondsSinceEpoch;
|
|
||||||
// print("play: ${end - start}");
|
|
||||||
// });
|
|
||||||
// // _passTrackPlugin.drawGrid();
|
|
||||||
// // 获取当前时间
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Future<void> initPlatformState() async {
|
if (!mounted) Exception('Failed to get textureId.');
|
||||||
// String platformVersion;
|
|
||||||
// try {
|
|
||||||
// platformVersion = await _passTrackPlugin.getPlatformVersion() ??
|
|
||||||
// 'Unknown platform version';
|
|
||||||
// } on Exception {
|
|
||||||
// platformVersion = 'Failed to get platform version.';
|
|
||||||
// }
|
|
||||||
// await _passTrackPlugin.create(
|
|
||||||
// mapcontroller.height.toInt(), mapcontroller.width.toInt());
|
|
||||||
// fileHandle.textureId = await _passTrackPlugin.getTextureId() ?? -1;
|
|
||||||
// print("textureId: ${fileHandle.textureId}");
|
|
||||||
|
|
||||||
// if (!mounted) Exception('Failed to get textureId.');
|
setState(() {
|
||||||
|
platformVersion = platformVersion;
|
||||||
// setState(() {
|
});
|
||||||
// platformVersion = platformVersion;
|
return;
|
||||||
// });
|
}
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final size = MediaQuery.of(context).size;
|
final size = MediaQuery.of(context).size;
|
||||||
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;
|
var isPortrait = MediaQuery.of(context).orientation == Orientation.portrait;
|
||||||
var controller = this.controller;
|
|
||||||
return OrientationBuilder(builder: (context, orientation) {
|
return OrientationBuilder(builder: (context, orientation) {
|
||||||
return Stack(
|
return Stack(
|
||||||
children: [
|
children: [
|
||||||
ScenceMapView(
|
ScenceMapView(
|
||||||
children: [
|
children: [
|
||||||
Positioned(
|
Positioned(
|
||||||
top: mapcontroller.top,
|
top: 0,
|
||||||
left: mapcontroller.left,
|
left: 0,
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: mapcontroller.width,
|
width: sWidth * 1.0,
|
||||||
height: mapcontroller.height,
|
height: sWidth * 1.0,
|
||||||
// child: Text('Running on: $_platformVersion\n'),
|
// child: Text('Running on: $_platformVersion\n'),
|
||||||
child: Texture(textureId: fileHandle.textureId))),
|
child: Texture(textureId: fileHandle.textureId))),
|
||||||
],
|
],
|
||||||
@ -160,28 +165,28 @@ class PassTrackView extends GetView<PassTrackController> {
|
|||||||
bottom: 30,
|
bottom: 30,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.only(bottom: 5),
|
padding: const EdgeInsets.only(bottom: 5),
|
||||||
child: Obx(
|
child: SfRangeSlider(
|
||||||
() => SfRangeSlider(
|
|
||||||
min: 0.0,
|
min: 0.0,
|
||||||
// max: maxLength,
|
// max: maxLength,
|
||||||
max: controller.tileCount.value > 0
|
max:
|
||||||
? controller.tileCount.value
|
controller.allLen > 0
|
||||||
|
? controller.allLen
|
||||||
: 1.0, // 确保 max 大于 0
|
: 1.0, // 确保 max 大于 0
|
||||||
values: SfRangeValues(
|
values: _rangevalues,
|
||||||
controller.tileFirst.value, controller.tileLast.value),
|
|
||||||
showTicks: false,
|
showTicks: false,
|
||||||
showLabels: false,
|
showLabels: false,
|
||||||
enableTooltip: true,
|
enableTooltip: true,
|
||||||
minorTicksPerInterval: 1,
|
minorTicksPerInterval: 1,
|
||||||
stepSize: 1,
|
stepSize: 1,
|
||||||
onChanged: (SfRangeValues values) {
|
onChanged: (SfRangeValues values) {
|
||||||
controller.tileFirst.value = values.start.toInt();
|
setState(() {
|
||||||
controller.tileLast.value = values.end.toInt();
|
_rangevalues = SfRangeValues(values.start.roundToDouble(),
|
||||||
|
values.end.roundToDouble());
|
||||||
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
Positioned(
|
Positioned(
|
||||||
left: isPortrait ? 190 : 200,
|
left: isPortrait ? 190 : 200,
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
@ -192,20 +197,20 @@ class PassTrackView extends GetView<PassTrackController> {
|
|||||||
width: 74,
|
width: 74,
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
backgroundColor: WidgetStateProperty.all<Color?>(
|
backgroundColor: MaterialStateProperty.all<Color?>(
|
||||||
str == "播放" ? Colors.blue : Colors.red,
|
str == "播放" ? Colors.blue : Colors.red,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (str == "播放") {
|
if (str == "播放") {
|
||||||
_passTrackPlugin.playTrack(
|
_passTrackPlugin.playTrack(0, 10000, true, 50, ffi.nullptr);
|
||||||
0, 10000, true, 50, ffi.nullptr);
|
|
||||||
} else {
|
} else {
|
||||||
_passTrackPlugin.playPause();
|
_passTrackPlugin.playPause();
|
||||||
}
|
}
|
||||||
// setState(() {
|
setState(() {
|
||||||
// str = str == "播放" ? "暂停" : "播放";
|
str = str == "播放" ? "暂停" : "播放";
|
||||||
// });
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
str,
|
str,
|
||||||
@ -231,14 +236,12 @@ class PassTrackView extends GetView<PassTrackController> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Obx(
|
Text(
|
||||||
() => Text(
|
"$speed X",
|
||||||
"${controller.speed.value} X",
|
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 11, color: Colors.black),
|
fontSize: 11, color: Colors.black),
|
||||||
),
|
),
|
||||||
),
|
Container(
|
||||||
SizedBox(
|
|
||||||
width: 25,
|
width: 25,
|
||||||
child: PopupMenuButton<int>(
|
child: PopupMenuButton<int>(
|
||||||
key: _popupMenuKey,
|
key: _popupMenuKey,
|
||||||
@ -246,7 +249,9 @@ class PassTrackView extends GetView<PassTrackController> {
|
|||||||
icon: const Icon(Icons.arrow_drop_up,
|
icon: const Icon(Icons.arrow_drop_up,
|
||||||
color: Color.fromARGB(255, 47, 48, 47)),
|
color: Color.fromARGB(255, 47, 48, 47)),
|
||||||
onSelected: (int value) {
|
onSelected: (int value) {
|
||||||
controller.speed.value = value;
|
setState(() {
|
||||||
|
speed = value;
|
||||||
|
});
|
||||||
},
|
},
|
||||||
// style: ButtonStyle(
|
// style: ButtonStyle(
|
||||||
// minimumSize: MaterialStateProperty.all<Size>(
|
// minimumSize: MaterialStateProperty.all<Size>(
|
||||||
@ -259,8 +264,7 @@ class PassTrackView extends GetView<PassTrackController> {
|
|||||||
return PopupMenuItem<int>(
|
return PopupMenuItem<int>(
|
||||||
height: 30,
|
height: 30,
|
||||||
value: speed,
|
value: speed,
|
||||||
child: Obx(() =>
|
child: Text("$speed X速度"),
|
||||||
Text("${controller.speed.value} X速度")),
|
|
||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
},
|
},
|
||||||
|
@ -2,8 +2,7 @@ import 'dart:convert';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:http/http.dart';
|
import 'package:http/http.dart';
|
||||||
|
import 'loginprefs.dart';
|
||||||
import '../pages/login/loginprefs.dart';
|
|
||||||
|
|
||||||
LoginPrefs loginPrefs = LoginPrefs();
|
LoginPrefs loginPrefs = LoginPrefs();
|
||||||
|
|
||||||
@ -11,7 +10,7 @@ class BaseService {
|
|||||||
//创建client实例
|
//创建client实例
|
||||||
final _client = http.Client();
|
final _client = http.Client();
|
||||||
final String token =
|
final String token =
|
||||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc1IiOjAsInJvbGVJZHMiOlsiODMiXSwidXNlcm5hbWUiOiJseWNzIiwidXNlcklkIjozNTYsIlBWIjoyLCJvcmciOiJhIiwiaWF0IjoxNzI1OTQ5NDUxLCJleHAiOjE3MjcyNDU0NTF9.o3cwloJcWAPclGXMzlmjIMM2x5GhBseToJe99vM4uVA";
|
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc1IiOjAsInJvbGVJZHMiOlsiODMiXSwidXNlcm5hbWUiOiJseWNzIiwidXNlcklkIjozNTYsIlBWIjoyLCJvcmciOiJhIiwiaWF0IjoxNzI1NTI2MDc0LCJleHAiOjE3MjY4MjIwNzR9.l47sd4L8OswBcHJxamGe9M5ttWqiukoJvE5QfwPARlw";
|
||||||
|
|
||||||
// String baseUrl = "http://192.168.1.189:8001";//本地
|
// String baseUrl = "http://192.168.1.189:8001";//本地
|
||||||
String baseUrl = "http://1.82.251.83:8001"; //线上
|
String baseUrl = "http://1.82.251.83:8001"; //线上
|
||||||
|
74
lib/service/loginprefs.dart
Normal file
74
lib/service/loginprefs.dart
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import 'package:get_storage/get_storage.dart';
|
||||||
|
|
||||||
|
import 'package:cpnav/models/user.dart';
|
||||||
|
|
||||||
|
class LoginPrefs {
|
||||||
|
static const String expireStr = "expire"; //用户名
|
||||||
|
static const String tokenStr = "token"; //token
|
||||||
|
static const String phoneStr = "phone";
|
||||||
|
final box = GetStorage(); // 实例化 GetStorage
|
||||||
|
|
||||||
|
Future<String> init() async {
|
||||||
|
await GetStorage.init(); // 初始化 GetStorage
|
||||||
|
return 'ok';
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveExpire(int expire) {
|
||||||
|
box.write(expireStr, expire);
|
||||||
|
// update();
|
||||||
|
}
|
||||||
|
|
||||||
|
int getExpire() {
|
||||||
|
return box.read(expireStr) ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveToken(String token) {
|
||||||
|
box.write(tokenStr, token);
|
||||||
|
// update();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getToken() {
|
||||||
|
return box.read(tokenStr) ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeExpire() {
|
||||||
|
box.remove(expireStr);
|
||||||
|
// update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeToken() {
|
||||||
|
box.remove(tokenStr);
|
||||||
|
// update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void savePhone(String phone) {
|
||||||
|
box.write(phoneStr, phone);
|
||||||
|
// update();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getPhone() {
|
||||||
|
return box.read(phoneStr) ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearLogin() {
|
||||||
|
box.erase(); // 清除所有数据
|
||||||
|
// update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UserController {
|
||||||
|
final box = GetStorage(); // 实例化 GetStorage
|
||||||
|
|
||||||
|
UserModel? getUser() {
|
||||||
|
final userMap = box.read('user');
|
||||||
|
if (userMap != null) {
|
||||||
|
return UserModel.fromJson(userMap);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUser(Map user) {
|
||||||
|
box.write('user', user);
|
||||||
|
// update();
|
||||||
|
}
|
||||||
|
}
|
75
lib/service/user/loginprefs.dart
Normal file
75
lib/service/user/loginprefs.dart
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:get_storage/get_storage.dart';
|
||||||
|
|
||||||
|
import 'package:cpnav/models/user.dart';
|
||||||
|
|
||||||
|
class LoginPrefs extends GetxController {
|
||||||
|
static const String expireStr = "expire"; //用户名
|
||||||
|
static const String tokenStr = "token"; //token
|
||||||
|
static const String phoneStr = "phone";
|
||||||
|
final box = GetStorage(); // 实例化 GetStorage
|
||||||
|
|
||||||
|
Future<String> init() async {
|
||||||
|
await GetStorage.init(); // 初始化 GetStorage
|
||||||
|
return 'ok';
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveExpire(int expire) {
|
||||||
|
box.write(expireStr, expire);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
int getExpire() {
|
||||||
|
return box.read(expireStr) ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveToken(String token) {
|
||||||
|
box.write(tokenStr, token);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getToken() {
|
||||||
|
return box.read(tokenStr) ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeExpire() {
|
||||||
|
box.remove(expireStr);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeToken() {
|
||||||
|
box.remove(tokenStr);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void savePhone(String phone) {
|
||||||
|
box.write(phoneStr, phone);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
String getPhone() {
|
||||||
|
return box.read(phoneStr) ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearLogin() {
|
||||||
|
box.erase(); // 清除所有数据
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UserController extends GetxController {
|
||||||
|
final box = GetStorage(); // 实例化 GetStorage
|
||||||
|
|
||||||
|
UserModel? getUser() {
|
||||||
|
final userMap = box.read('user');
|
||||||
|
if (userMap != null) {
|
||||||
|
return UserModel.fromJson(userMap);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUser(Map user) {
|
||||||
|
box.write('user', user);
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1 @@
|
|||||||
Subproject commit ad96316e993e3bbb2ca2b5b360b2fb5b6a50f0d2
|
Subproject commit 0b6aef315a6b7b05eec413cc6e9368611fad8e2b
|
@ -1 +1 @@
|
|||||||
Subproject commit aa1ed2754229ed2bc2aaccfaba074765a55adfd8
|
Subproject commit ac2179219ba52d0c91dfd51470fd1d7ebaae69be
|
Loading…
Reference in New Issue
Block a user