371 lines
13 KiB
Dart
371 lines
13 KiB
Dart
import 'package:flutter/material.dart';
|
||
import 'package:getx_scaffold/getx_scaffold.dart';
|
||
import 'package:ln_jq_app/common/login_util.dart';
|
||
import 'package:ln_jq_app/common/model/base_model.dart';
|
||
import 'package:ln_jq_app/common/styles/theme.dart';
|
||
import 'package:ln_jq_app/pages/b_page/base_widgets/view.dart';
|
||
import 'package:ln_jq_app/pages/c_page/base_widgets/view.dart';
|
||
import 'package:ln_jq_app/pages/login/controller.dart';
|
||
import 'package:ln_jq_app/storage_service.dart';
|
||
|
||
class LoginPage extends StatefulWidget {
|
||
const LoginPage({super.key});
|
||
|
||
@override
|
||
State<LoginPage> createState() => _LoginPageState();
|
||
}
|
||
|
||
class _LoginPageState extends State<LoginPage> with SingleTickerProviderStateMixin {
|
||
late TabController tabController;
|
||
|
||
//默认司机端
|
||
bool cLogin = true;
|
||
bool _obscureText = true; // 默认密码为隐藏状态
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
// 初始化 TabController,传入 vsync 参数
|
||
tabController = TabController(length: 2, vsync: this);
|
||
tabController.addListener(_tabChangeListener);
|
||
}
|
||
|
||
void _tabChangeListener() {
|
||
// 如果 TabController 不是正在被用户手动滑动(即是初始化或其他操作)
|
||
if (!tabController.indexIsChanging) {
|
||
switchTab(tabController.index);
|
||
}
|
||
}
|
||
|
||
// 切换Tab
|
||
void switchTab(int index) {
|
||
setState(() {
|
||
cLogin = (index == 0);
|
||
});
|
||
}
|
||
|
||
@override
|
||
void dispose() {
|
||
tabController.dispose(); // 销毁 TabController
|
||
super.dispose();
|
||
}
|
||
|
||
// 主视图
|
||
Widget _buildView() {
|
||
// 使用 Get.find 获取控制器
|
||
final controller = Get.find<LoginController>();
|
||
|
||
return Container(
|
||
color: Color(0xFFEFF4F7),
|
||
child: <Widget>[
|
||
Icon(cLogin ? AntdIcon.car : AntdIcon.USB),
|
||
SizedBox(height: 5.h),
|
||
TextX.bodyLarge(cLogin ? '司机端' : "加氢站", weight: FontWeight.w700),
|
||
SizedBox(height: 5.h),
|
||
TextX.bodyLarge(cLogin ? '安全驾驶·智能服务' : "氢能服务·专业运营"),
|
||
Card(
|
||
shape: RoundedRectangleBorder(
|
||
borderRadius: BorderRadius.circular(15), // 设置圆角弧度
|
||
),
|
||
margin: EdgeInsets.all(15),
|
||
elevation: 4,
|
||
child: Container(
|
||
height: cLogin ? 285.h : 350.h,
|
||
padding: EdgeInsets.all(15),
|
||
child: // TabBar切换
|
||
Column(
|
||
children: [
|
||
Card(
|
||
elevation: 2,
|
||
child: Container(
|
||
height: 55.h,
|
||
padding: EdgeInsets.all(3),
|
||
child: TabBar(
|
||
controller: tabController,
|
||
onTap: (index) {
|
||
//保证尺寸变化
|
||
delayed(300, () {
|
||
switchTab(index);
|
||
});
|
||
},
|
||
// 修改TabBar的选中状态和未选中状态样式
|
||
labelColor: Colors.white,
|
||
// 选中时的文字颜色
|
||
unselectedLabelColor: Colors.black,
|
||
// 未选中时的文字颜色
|
||
indicator: BoxDecoration(
|
||
color: AppTheme.themeColor, // 选中的Tab背景色(模拟卡片式效果)
|
||
borderRadius: BorderRadius.circular(12), // 卡片的圆角效果
|
||
boxShadow: [
|
||
BoxShadow(
|
||
color: Colors.blue.withOpacity(0.2),
|
||
spreadRadius: 1,
|
||
blurRadius: 6,
|
||
),
|
||
],
|
||
),
|
||
tabs: [
|
||
Tab(text: '司机端登录'),
|
||
Tab(text: '加氢站登录'),
|
||
],
|
||
isScrollable: false,
|
||
),
|
||
),
|
||
),
|
||
// 根据选择的Tab展示不同的输入框
|
||
Flexible(
|
||
child: TabBarView(
|
||
controller: tabController,
|
||
children: [
|
||
// 司机端登录
|
||
_driverLoginView(controller),
|
||
// 加氢站登录
|
||
_stationLoginView(controller),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
].toColumn(mainAxisSize: MainAxisSize.min).center(),
|
||
);
|
||
}
|
||
|
||
// 司机端登录界面
|
||
Widget _driverLoginView(LoginController controller) {
|
||
return !cLogin
|
||
? SizedBox()
|
||
: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
SizedBox(height: 20.h),
|
||
TextFormField(
|
||
controller: controller.driverIdentityController,
|
||
cursorColor: AppTheme.themeColor,
|
||
maxLength: 8,
|
||
style: TextStyle(fontSize: 14),
|
||
decoration: InputDecoration(
|
||
hintText: '请输入身份后8位',
|
||
border: OutlineInputBorder(),
|
||
hintStyle: TextStyle(fontSize: 14),
|
||
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||
prefixIcon: Icon(Icons.person_2_outlined, color: Colors.grey),
|
||
focusedBorder: OutlineInputBorder(
|
||
borderSide: BorderSide(color: AppTheme.themeColor),
|
||
),
|
||
),
|
||
),
|
||
SizedBox(height: 20.h),
|
||
ElevatedButton(
|
||
onPressed: () async {
|
||
// 司机端登录
|
||
String password = controller.driverIdentityController.text;
|
||
|
||
if (password.isEmpty) {
|
||
showToast("请输入密码");
|
||
return;
|
||
}
|
||
|
||
showLoading('登录中...');
|
||
|
||
try {
|
||
// 调用登录接口
|
||
var responseData = await HttpService.to.post(
|
||
'appointment/login/loginForDriver',
|
||
data: {'idNo': password},
|
||
);
|
||
|
||
if (responseData == null && responseData!.data == null) {
|
||
dismissLoading();
|
||
showToast('登录失败:无法获取凭证');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
var result = BaseModel.fromJson(responseData.data);
|
||
|
||
//保存用户信息
|
||
String token = result.data['token'] ?? '';
|
||
String idCard = result.data['idCard'] ?? '';
|
||
String name = result.data['name'] ?? '';
|
||
String phone = result.data['phone'] ?? '';
|
||
/*{
|
||
"token": "a615cf38a066473ebf8e9a956fc51928",
|
||
"idCard": "330324200010241024",
|
||
"name": "王小龙",
|
||
"phone": "15888331828"
|
||
}*/
|
||
|
||
await StorageService.to.saveLoginInfo(
|
||
token: token,
|
||
userId: "",
|
||
channel: "driver",
|
||
idCard: idCard,
|
||
name: name,
|
||
phone: phone,
|
||
);
|
||
|
||
dismissLoading();
|
||
showToast('登录成功,欢迎您');
|
||
|
||
// 跳转到主页,并清除所有历史页面
|
||
Get.offAll(() => BaseWidgetsPage());
|
||
} catch (e) {
|
||
// 如果解析 JSON 失败
|
||
dismissLoading();
|
||
showToast('登录失败:数据异常');
|
||
}
|
||
} catch (e) {
|
||
dismissLoading();
|
||
}
|
||
},
|
||
style: ElevatedButton.styleFrom(
|
||
backgroundColor: AppTheme.themeColor,
|
||
minimumSize: Size(double.infinity, 50), // 设置按钮宽度占满,指定最小高度
|
||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||
),
|
||
child: Text('登录'),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
// 加氢站登录界面
|
||
Widget _stationLoginView(LoginController controller) {
|
||
return cLogin
|
||
? SizedBox()
|
||
: Column(
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
SizedBox(height: 20),
|
||
TextFormField(
|
||
controller: controller.stationIdController,
|
||
cursorColor: AppTheme.themeColor,
|
||
style: TextStyle(fontSize: 14),
|
||
decoration: InputDecoration(
|
||
hintText: '请输入加氢站编号',
|
||
border: OutlineInputBorder(),
|
||
hintStyle: TextStyle(fontSize: 14),
|
||
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||
prefixIcon: Icon(Icons.person_2_outlined, color: Colors.grey),
|
||
focusedBorder: OutlineInputBorder(
|
||
borderSide: BorderSide(color: AppTheme.themeColor),
|
||
),
|
||
),
|
||
),
|
||
SizedBox(height: 20),
|
||
TextFormField(
|
||
controller: controller.passwordController,
|
||
obscureText: _obscureText,
|
||
style: TextStyle(fontSize: 14),
|
||
cursorColor: AppTheme.themeColor,
|
||
decoration: InputDecoration(
|
||
hintStyle: TextStyle(fontSize: 14),
|
||
contentPadding: EdgeInsets.symmetric(horizontal: 12, vertical: 10),
|
||
hintText: '请输入密码',
|
||
border: OutlineInputBorder(),
|
||
suffixIcon: IconButton(
|
||
icon: Icon(
|
||
_obscureText ? Icons.visibility_off : Icons.visibility, // 切换图标
|
||
),
|
||
onPressed: () {
|
||
setState(() {
|
||
_obscureText = !_obscureText;
|
||
});
|
||
},
|
||
),
|
||
prefixIcon: Icon(Icons.lock_outline, color: Colors.grey),
|
||
focusedBorder: OutlineInputBorder(
|
||
borderSide: BorderSide(color: AppTheme.themeColor),
|
||
),
|
||
),
|
||
),
|
||
SizedBox(height: 20),
|
||
ElevatedButton(
|
||
style: ElevatedButton.styleFrom(
|
||
backgroundColor: AppTheme.themeColor,
|
||
minimumSize: Size(double.infinity, 50), // 设置按钮宽度占满,指定最小高度
|
||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||
),
|
||
onPressed: () async {
|
||
// 加氢站登录逻辑
|
||
String account = controller.stationIdController.text;
|
||
String password = controller.passwordController.text;
|
||
|
||
//todo 删除
|
||
account = "000017";
|
||
password = "LnQn.314000";
|
||
|
||
if (account.isEmpty || password.isEmpty) {
|
||
showToast("请输入账号和密码");
|
||
return;
|
||
}
|
||
|
||
showLoading('登录中...');
|
||
|
||
try {
|
||
// 对密码进行AES加密
|
||
String encryptedPassword = LoginUtil.encrypt(password);
|
||
|
||
// 调用登录接口
|
||
var responseData = await HttpService.to.post(
|
||
'/login/password',
|
||
data: {
|
||
'account': account,
|
||
'password': encryptedPassword,
|
||
'loginType': "station",
|
||
},
|
||
);
|
||
|
||
if (responseData == null && responseData!.data == null) {
|
||
dismissLoading();
|
||
showToast('登录失败:无法获取凭证');
|
||
return;
|
||
}
|
||
|
||
try {
|
||
var result = BaseModel.fromJson(responseData.data);
|
||
|
||
//保存用户信息
|
||
String token = result.data['token'] ?? '';
|
||
//hydrogenId
|
||
String userId = result.data['userId'] ?? '';
|
||
|
||
await StorageService.to.saveLoginInfo(
|
||
token: token,
|
||
userId: userId,
|
||
channel: "station",
|
||
);
|
||
|
||
dismissLoading();
|
||
showToast('登录成功,欢迎您');
|
||
|
||
// 跳转到主页,并清除所有历史页面
|
||
Get.offAll(() => B_BaseWidgetsPage());
|
||
} catch (e) {
|
||
// 如果解析 JSON 失败
|
||
dismissLoading();
|
||
showToast('登录失败:数据异常');
|
||
}
|
||
} catch (e) {
|
||
dismissLoading();
|
||
}
|
||
},
|
||
child: Text('登录'),
|
||
),
|
||
],
|
||
);
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return GetBuilder<LoginController>(
|
||
init: LoginController(),
|
||
id: 'login',
|
||
builder: (_) {
|
||
return Scaffold(body: _buildView());
|
||
},
|
||
);
|
||
}
|
||
}
|