flutter/lib/pages/auth/login.dart

305 lines
12 KiB
Dart
Raw Normal View History

2025-07-21 15:46:30 +08:00
/// 注册模板
library;
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:loopin/IM/im_core.dart' as im_core;
import 'package:loopin/IM/im_service.dart';
import 'package:loopin/api/common_api.dart';
import 'package:loopin/controller/video_module_controller.dart';
import 'package:loopin/service/http.dart';
import 'package:loopin/utils/storage.dart';
import 'package:shirne_dialog/shirne_dialog.dart';
import '../../utils/index.dart';
class Login extends StatefulWidget {
const Login({super.key});
@override
State<Login> createState() => _LoginState();
}
class _LoginState extends State<Login> {
final Map authObj = {'phonenumber': '', 'smsCode': '', 'clientId': '428a8310cd442757ae699df5d894f051', 'grantType': 'sms'};
final fieldController = TextEditingController();
Timer? timer;
String vcodeText = '获取验证码';
bool disabled = false;
int time = 6;
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
timer?.cancel();
}
// 清空文本框
void handleClear() {
fieldController.clear();
setState(() {
authObj['phonenumber'] = '';
});
}
// 提交表单
void handleSubmit() async {
FocusScope.of(context).unfocus(); // 收起键盘
if (authObj['phonenumber'] == '') {
MyDialog.toast('手机号不能为空', icon: Icon(Icons.warning), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200)));
} else if (!Utils.checkTel(authObj['phonenumber'])) {
MyDialog.toast('手机号格式不正确', icon: Icon(Icons.warning), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200)));
} else if (authObj['smsCode'] == '') {
MyDialog.toast('验证码不能为空', icon: Icon(Icons.warning), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200)));
} else {
final dialogController = MyDialog.loading('正在登录...');
// 执行登录
logger.i(authObj);
final res = await Http.post(CommonApi.login, data: authObj);
final obj = res['data'];
// 拿到userid和usersing进行im登录
logger.i(res);
String userId = obj['userId'];
String userSig = obj['userSig'];
// 初始化im_sdk
await im_core.ImCore.init(sdkAppId: 1600080789);
// String userId = '1909990634551795712'; //15877777777
// String userId = '18832510385';
// String userSig =
// 'eJwtzcsOgjAQBdB-6dqQKThth8QdG*JrIRHjTqGYiagNDzUx-rsVWN5zJ3M-IlvtgqdtRCzCAMRsyFzae8cVDywJiAhUNEeUmlDLcDpry*vJOS5FLBUAGNCGxsa*HTfWOyKGvhq149vftH8DhHLSli9*Jdrk2hqTVgdK2dKxXSfKbYuXpnPSu1zl*0fd18skg2Ihvj*7ADL4';
// 'eJwtzLEKwjAUheF3ySwlNzXNbcHFxSIOaqTWUUgsF1FDG2tEfHdj2-F8P5wPO2x00tuWFUwknM2GTcbePV1oYEBMhQSeopxyZ65n58iwAjLOOXKF*VhscNTa6FJKEdOonm5-UxJQpZhN2lET3599Xllbv9ZBH2uHuDfvst5tG6FX0EFYVhpOpZ973z8W7PsDmYwyIw__';
try {
final loginRes = await ImService.instance.login(userID: userId, userSig: userSig);
logger.i(loginRes);
if (loginRes.success) {
// 存储登录信息
Storage.write('hasLogged', true);
// Storage.write('userSig', userSig);
Storage.write('userId', userId);
// Storage.write('token', obj['access_token']);
// 刷新短视频列表
final videoController = Get.find<VideoModuleController>();
videoController.markNeedRefresh();
dialogController.close();
Get.back();
}
} catch (e) {
logger.i(e);
}
}
}
// 60s倒计时
void handleVcode() {
logger.i(authObj);
FocusScope.of(context).unfocus(); // 收起键盘
if (authObj['phonenumber'] == '') {
MyDialog.toast('手机号不能为空', icon: Icon(Icons.warning), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200)));
} else if (!Utils.checkTel(authObj['phonenumber'])) {
MyDialog.toast('手机号格式不正确', icon: Icon(Icons.warning), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200)));
} else {
setState(() {
disabled = true;
});
startTimer();
getCode();
}
}
startTimer() {
timer = Timer.periodic(const Duration(seconds: 1), (timer) {
setState(() {
if (time > 0) {
vcodeText = '获取验证码(${time--})';
} else {
vcodeText = '获取验证码';
time = 6;
disabled = false;
timer.cancel();
}
});
});
}
void getCode() async {
final res = await Http.get(CommonApi.getCode, params: {'phonenumber': authObj['phonenumber']});
logger.i(res);
}
@override
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.translucent,
onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
forceMaterialTransparency: true,
toolbarHeight: 0,
),
body: Container(
alignment: Alignment.center,
margin: const EdgeInsets.only(top: 50.0),
child: Column(
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 30.0),
child: Column(
children: [
ClipOval(
child: Image.asset(
'assets/images/logo/logo.png',
height: 75.0,
width: 75.0,
fit: BoxFit.cover,
),
),
const SizedBox(
height: 5.0,
),
const Text('无终街',
style: TextStyle(
color: Color(0xFFFF5000),
fontSize: 28.0,
fontFamily: 'Maven Pro',
)),
],
),
),
Container(
height: 40.0,
margin: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 30.0),
decoration: BoxDecoration(
color: Color(0xFFFAF8F5),
borderRadius: BorderRadius.circular(15.0),
),
child: Row(
children: [
Expanded(
child: TextField(
keyboardType: TextInputType.phone,
controller: fieldController,
inputFormatters: [
LengthLimitingTextInputFormatter(11), // 限制输入长度为 11
FilteringTextInputFormatter.digitsOnly, // 限制只能输入数字
],
decoration: InputDecoration(
hintText: '输入手机号',
hintStyle: const TextStyle(color: Colors.black38),
suffixIcon: Visibility(
visible: authObj['phonenumber'].isNotEmpty,
child: InkWell(
hoverColor: Colors.transparent,
highlightColor: Colors.transparent,
splashColor: Colors.transparent,
onTap: handleClear,
child: const Icon(
Icons.clear,
color: Colors.grey,
size: 16.0,
),
)),
contentPadding: const EdgeInsets.symmetric(vertical: 0, horizontal: 12.0),
border: const OutlineInputBorder(borderSide: BorderSide.none),
),
onChanged: (value) {
setState(() {
authObj['phonenumber'] = value;
});
},
),
)
],
),
),
Container(
height: 40.0,
margin: const EdgeInsets.symmetric(vertical: 5.0, horizontal: 30.0),
decoration: BoxDecoration(color: Color(0xFFFAF8F5), borderRadius: BorderRadius.circular(15.0)),
child: Row(
children: [
Expanded(
child: TextField(
keyboardType: TextInputType.phone,
inputFormatters: [
LengthLimitingTextInputFormatter(6),
FilteringTextInputFormatter.digitsOnly, // 限制只能输入数字
],
decoration: const InputDecoration(
hintText: '验证码',
hintStyle: TextStyle(color: Colors.black38),
contentPadding: EdgeInsets.symmetric(vertical: 0, horizontal: 12.0),
border: OutlineInputBorder(borderSide: BorderSide.none),
),
onChanged: (value) {
setState(() {
authObj['smsCode'] = value;
});
},
),
),
SizedBox(
height: 25.0,
child: Container(
margin: const EdgeInsets.only(right: 8.0),
child: ElevatedButton(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Colors.white),
shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.circular(8.0))),
padding: WidgetStateProperty.all(EdgeInsets.symmetric(horizontal: 15.0))),
onPressed: !disabled ? handleVcode : null,
child: Text(vcodeText, style: const TextStyle(fontSize: 13.0)),
),
),
)
],
),
),
Container(
margin: const EdgeInsets.symmetric(vertical: 10.0, horizontal: 30.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15.0),
// 自定义按钮渐变色
gradient: const LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [Color(0xFFFF389B), Color(0xFFFFBA31)],
)),
child: SizedBox(
width: double.infinity,
height: 45.0,
child: FilledButton(
style: ButtonStyle(
backgroundColor: WidgetStateProperty.all(Colors.transparent),
shadowColor: WidgetStateProperty.all(Colors.transparent),
shape: WidgetStatePropertyAll(RoundedRectangleBorder(borderRadius: BorderRadius.circular(30.0)))),
onPressed: handleSubmit,
child: const Text(
'登录',
style: TextStyle(fontSize: 16.0),
),
),
)),
const SizedBox(
height: 10.0,
),
],
),
),
));
}
}