Commit 695103c3 authored by 张宏's avatar 张宏

登录

parent c7d9fb26
...@@ -25,20 +25,13 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> { ...@@ -25,20 +25,13 @@ class AuthBloc extends Bloc<AuthEvent, AuthState> {
Emitter<AuthState> emit, Emitter<AuthState> emit,
) async { ) async {
emit(AuthLoading()); emit(AuthLoading());
try {
// todo 这里暂定返回bool
// final success = await _authService.login(event.username, event.password);
final success = true;
if (success) { try {
final userInfo = const UserInfoBO( await _authService.login(event.username, event.password);
username: "张三丰", const userInfo = UserInfoBO(
); username: "管理员",
emit(AuthSuccess(userInfo)); );
} else { emit(const AuthSuccess(userInfo));
emit(const AuthFailure('登录失败,请检查用户名和密码'));
}
} catch (e) { } catch (e) {
emit(AuthFailure(e.toString())); emit(AuthFailure(e.toString()));
} }
......
import 'package:equatable/equatable.dart';
class LoginBO extends Equatable {
final String? scope;
final String? openid;
final String? accessToken;
final String? refreshToken;
final int? expireIn;
final int? refreshExpireIn;
final String? clientId;
const LoginBO({
this.scope,
this.openid,
this.accessToken,
this.refreshToken,
this.expireIn,
this.refreshExpireIn,
this.clientId,
});
factory LoginBO.fromJson(Map<String, dynamic> json) {
return LoginBO(
scope: json['scope'] as String?,
openid: json['openid'] as String?,
accessToken: json['access_token'] as String?,
refreshToken: json['refresh_token'] as String?,
expireIn: json['expire_in'] as int?,
refreshExpireIn: json['refresh_expire_in'] as int?,
clientId: json['client_id'] as String?,
);
}
@override
List<Object?> get props => [
scope,
openid,
accessToken,
refreshToken,
expireIn,
refreshExpireIn,
clientId,
];
}
\ No newline at end of file
import '../utils/http/response_model.dart'; import '../utils/http/response_model.dart';
import '../utils/http/dio_request.dart'; import '../utils/http/dio_request.dart';
import '../models/bo/login_bo.dart';
class AuthRepository { class AuthRepository {
Future<ResponseModel> login(Map<String, dynamic> params) { Future<ResponseModel<LoginBO>> login(Map<String, dynamic> params) {
return DioRequest.instance.post('/login', data: params); return DioRequest.instance.post<LoginBO>(
'/app/auth/login/password',
data: params,
fromJsonT: (data) => LoginBO.fromJson(data as Map<String, dynamic>),
);
} }
} }
import '../models/bo/login_bo.dart';
import '../repositories/auth_repository.dart'; import '../repositories/auth_repository.dart';
import '../utils/constants.dart'; import '../utils/constants.dart';
import '../utils/storage/storage_service.dart'; import '../utils/storage/storage_service.dart';
...@@ -12,27 +13,23 @@ class AuthService { ...@@ -12,27 +13,23 @@ class AuthService {
}) : _authRepository = authRepository, }) : _authRepository = authRepository,
_storageService = storageService; _storageService = storageService;
Future<bool> login(String username, String password) async { Future<LoginBO> login(String username, String password) async {
final result = await _authRepository.login({ final result = await _authRepository.login({
'username': username, 'username': username,
'password': password, 'password': password,
}); });
if (result.success) { if (result.success && result.data != null) {
final data = result.data; final loginBO = result.data!;
if (data is Map<String, dynamic> && data.containsKey('token')) { if (loginBO.accessToken != null && loginBO.accessToken!.isNotEmpty) {
final token = data['token'] as String?; await _storageService.saveToken(
if (token != null && token.isNotEmpty) { loginBO.accessToken!,
await _storageService.saveToken( expiryHours: Constants.tokenExpiryHours,
token, );
expiryHours: Constants.tokenExpiryHours,
);
return true;
}
} }
return loginBO;
} }
throw Exception(result.msg);
return false;
} }
Future<bool> isTokenExpired() async { Future<bool> isTokenExpired() async {
......
class Constants { class Constants {
// ==================== 环境配置 ==================== // ==================== 环境配置 ====================
static const String baseUrl = 'http://localhost:8080'; static const String baseUrl = 'http://121.41.57.178:9090';
// ==================== 超时配置 ==================== // ==================== 超时配置 ====================
static const int connectTimeout = 30000; static const int connectTimeout = 30000;
......
...@@ -327,9 +327,9 @@ class DioRequest { ...@@ -327,9 +327,9 @@ class DioRequest {
if (response.data is Map<String, dynamic>) { if (response.data is Map<String, dynamic>) {
jsonData = Map<String, dynamic>.from(response.data); jsonData = Map<String, dynamic>.from(response.data);
// 如果响应中有token但没有data,把token放到data里 // 如果响应中有token但没有data,把token放到data里
if (jsonData.containsKey('token') && !jsonData.containsKey('data')) { // if (jsonData.containsKey('token') && !jsonData.containsKey('data')) {
jsonData['data'] = {'token': jsonData['token']}; // jsonData['data'] = {'token': jsonData['token']};
} // }
} else { } else {
jsonData = { jsonData = {
'code': response.statusCode ?? -1, 'code': response.statusCode ?? -1,
......
...@@ -41,7 +41,7 @@ class RequestInterceptor extends Interceptor { ...@@ -41,7 +41,7 @@ class RequestInterceptor extends Interceptor {
} }
void _printRequestLog(RequestOptions options, String uuid) { void _printRequestLog(RequestOptions options, String uuid) {
print('========== Request START =========='); print('==================== Request START ======================');
print('UUID: $uuid'); print('UUID: $uuid');
print('Method: ${options.method}'); print('Method: ${options.method}');
print('URL: ${options.uri}'); print('URL: ${options.uri}');
...@@ -52,6 +52,6 @@ class RequestInterceptor extends Interceptor { ...@@ -52,6 +52,6 @@ class RequestInterceptor extends Interceptor {
if (options.queryParameters.isNotEmpty) { if (options.queryParameters.isNotEmpty) {
print('Params: ${options.queryParameters}'); print('Params: ${options.queryParameters}');
} }
print('========== Request END =========='); print('==================== Request END ======================');
} }
} }
\ No newline at end of file
...@@ -11,10 +11,10 @@ class ResponseInterceptor extends Interceptor { ...@@ -11,10 +11,10 @@ class ResponseInterceptor extends Interceptor {
} }
void _printResponseLog(Response response, String uuid) { void _printResponseLog(Response response, String uuid) {
print('========== Response START =========='); print('==================== Response START ======================');
print('UUID: $uuid'); print('UUID: $uuid');
print('Status Code: ${response.statusCode}'); print('Status Code: ${response.statusCode}');
print('Data: ${response.data}'); print('Data: ${response.data}');
print('========== Response END =========='); print('==================== Response END ======================');
} }
} }
\ No newline at end of file
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:smart_hotel_app/blocs/auth/auth_bloc.dart'; import 'package:smart_hotel_app/blocs/auth/auth_bloc.dart';
import 'package:smart_hotel_app/blocs/auth/auth_event.dart'; import 'package:smart_hotel_app/blocs/auth/auth_event.dart';
import 'package:smart_hotel_app/blocs/auth/auth_state.dart';
import 'package:smart_hotel_app/utils/storage/storage_service.dart'; import 'package:smart_hotel_app/utils/storage/storage_service.dart';
import 'package:smart_hotel_app/views/login/cubit/login_state.dart'; import 'package:smart_hotel_app/views/login/cubit/login_state.dart';
...@@ -11,7 +12,21 @@ class LoginCubit extends Cubit<LoginState> { ...@@ -11,7 +12,21 @@ class LoginCubit extends Cubit<LoginState> {
LoginCubit({ LoginCubit({
required this.authBloc, required this.authBloc,
required this.storageService, required this.storageService,
}) : super(const LoginState()); }) : super(const LoginState()) {
_listenAuthState();
}
void _listenAuthState() {
authBloc.stream.listen((authState) {
if (authState is AuthFailure) {
emit(state.copyWith(isLoading: false, error: authState.error));
} else if (authState is AuthLoading) {
emit(state.copyWith(isLoading: true, error: null));
} else if (authState is AuthSuccess) {
emit(state.copyWith(isLoading: false, error: null));
}
});
}
void toggleRememberPassword(bool value) { void toggleRememberPassword(bool value) {
emit(state.copyWith(rememberPassword: value)); emit(state.copyWith(rememberPassword: value));
...@@ -31,7 +46,10 @@ class LoginCubit extends Cubit<LoginState> { ...@@ -31,7 +46,10 @@ class LoginCubit extends Cubit<LoginState> {
storageService.clearRememberCredentials(); storageService.clearRememberCredentials();
} }
authBloc.add(AuthLoginRequested(username: username, password: password)); authBloc.add(AuthLoginRequested(
username: username,
password: password,
));
} }
Future<void> loadRememberCredentials() async { Future<void> loadRememberCredentials() async {
......
...@@ -3,12 +3,14 @@ import 'package:equatable/equatable.dart'; ...@@ -3,12 +3,14 @@ import 'package:equatable/equatable.dart';
class LoginState extends Equatable { class LoginState extends Equatable {
final bool rememberPassword; final bool rememberPassword;
final bool isLoading; final bool isLoading;
final String? error;
final String? savedUsername; final String? savedUsername;
final String? savedPassword; final String? savedPassword;
const LoginState({ const LoginState({
this.rememberPassword = false, this.rememberPassword = false,
this.isLoading = false, this.isLoading = false,
this.error,
this.savedUsername, this.savedUsername,
this.savedPassword, this.savedPassword,
}); });
...@@ -16,12 +18,14 @@ class LoginState extends Equatable { ...@@ -16,12 +18,14 @@ class LoginState extends Equatable {
LoginState copyWith({ LoginState copyWith({
bool? rememberPassword, bool? rememberPassword,
bool? isLoading, bool? isLoading,
String? error,
String? savedUsername, String? savedUsername,
String? savedPassword, String? savedPassword,
}) { }) {
return LoginState( return LoginState(
rememberPassword: rememberPassword ?? this.rememberPassword, rememberPassword: rememberPassword ?? this.rememberPassword,
isLoading: isLoading ?? this.isLoading, isLoading: isLoading ?? this.isLoading,
error: error,
savedUsername: savedUsername ?? this.savedUsername, savedUsername: savedUsername ?? this.savedUsername,
savedPassword: savedPassword ?? this.savedPassword, savedPassword: savedPassword ?? this.savedPassword,
); );
...@@ -31,6 +35,7 @@ class LoginState extends Equatable { ...@@ -31,6 +35,7 @@ class LoginState extends Equatable {
List<Object?> get props => [ List<Object?> get props => [
rememberPassword, rememberPassword,
isLoading, isLoading,
error,
savedUsername, savedUsername,
savedPassword, savedPassword,
]; ];
......
...@@ -162,8 +162,9 @@ class LoginView extends StatelessWidget { ...@@ -162,8 +162,9 @@ class LoginView extends StatelessWidget {
if (_frmGlobalKey.currentState! if (_frmGlobalKey.currentState!
.validate()) { .validate()) {
cubit.login( cubit.login(
username: _txtUserNameController.text username:
.trim(), _txtUserNameController.text
.trim(),
password: password:
_txtPwdController.text.trim(), _txtPwdController.text.trim(),
rememberPassword: rememberPassword:
......
...@@ -9,7 +9,7 @@ class ProfileCubit extends Cubit<ProfileState> { ...@@ -9,7 +9,7 @@ class ProfileCubit extends Cubit<ProfileState> {
void initData() { void initData() {
emit(state.copyWith( emit(state.copyWith(
phoneNumber: '15391514233', username: '15391514233',
welcomeText: '欢迎来到智能酒店', welcomeText: '欢迎来到智能酒店',
menuList: [ menuList: [
const MenuItem(icon: Icons.list, title: '设备列表'), const MenuItem(icon: Icons.list, title: '设备列表'),
......
...@@ -14,28 +14,28 @@ class MenuItem { ...@@ -14,28 +14,28 @@ class MenuItem {
} }
class ProfileState extends Equatable { class ProfileState extends Equatable {
final String phoneNumber; final String username;
final String welcomeText; final String welcomeText;
final List<MenuItem> menuList; final List<MenuItem> menuList;
const ProfileState({ const ProfileState({
this.phoneNumber = '', this.username = '',
this.welcomeText = '', this.welcomeText = '',
this.menuList = const [], this.menuList = const [],
}); });
ProfileState copyWith({ ProfileState copyWith({
String? phoneNumber, String? username,
String? welcomeText, String? welcomeText,
List<MenuItem>? menuList, List<MenuItem>? menuList,
}) { }) {
return ProfileState( return ProfileState(
phoneNumber: phoneNumber ?? this.phoneNumber, username: username ?? this.username,
welcomeText: welcomeText ?? this.welcomeText, welcomeText: welcomeText ?? this.welcomeText,
menuList: menuList ?? this.menuList, menuList: menuList ?? this.menuList,
); );
} }
@override @override
List<Object?> get props => [phoneNumber, welcomeText, menuList]; List<Object?> get props => [username, welcomeText, menuList];
} }
\ No newline at end of file
...@@ -30,7 +30,7 @@ class ProfileView extends StatelessWidget { ...@@ -30,7 +30,7 @@ class ProfileView extends StatelessWidget {
return Column( return Column(
children: [ children: [
ProfileHeaderBlock( ProfileHeaderBlock(
phoneNumber: state.phoneNumber, username: state.username,
welcomeText: state.welcomeText, welcomeText: state.welcomeText,
), ),
SizedBox(height: 10.h), SizedBox(height: 10.h),
......
...@@ -2,12 +2,12 @@ import 'package:flutter/material.dart'; ...@@ -2,12 +2,12 @@ import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
class ProfileHeaderBlock extends StatelessWidget { class ProfileHeaderBlock extends StatelessWidget {
final String phoneNumber; final String username;
final String welcomeText; final String welcomeText;
const ProfileHeaderBlock({ const ProfileHeaderBlock({
super.key, super.key,
required this.phoneNumber, required this.username,
required this.welcomeText, required this.welcomeText,
}); });
...@@ -59,7 +59,7 @@ class ProfileHeaderBlock extends StatelessWidget { ...@@ -59,7 +59,7 @@ class ProfileHeaderBlock extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
phoneNumber, username,
style: TextStyle( style: TextStyle(
fontSize: 32.sp, fontSize: 32.sp,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
......
# 智慧酒店 App 接口对接方案 # 智慧酒店 App 接口对接方案
...@@ -16,8 +16,8 @@ ...@@ -16,8 +16,8 @@
```dart ```dart
// lib/repositories/xxx_repository.dart // lib/repositories/xxx_repository.dart
import '../http/response_model.dart'; import '../utils/http/response_model.dart';
import '../http/dio_request.dart'; import '../utils/http/dio_request.dart';
import '../models/bo/xxx_bo.dart'; import '../models/bo/xxx_bo.dart';
class XxxRepository { class XxxRepository {
...@@ -178,43 +178,43 @@ class xxxBO extends Equatable { ...@@ -178,43 +178,43 @@ class xxxBO extends Equatable {
### 3.1 接口总览 ### 3.1 接口总览
| 序号 | 方法 | 路径 | 说明 | 所属模块 | | 页面序号 | 方法 | 路径 | 状态 | 所属模块 |
|------|------|------|------|---------| |------|------|------|------|---------|
| 登录页 |POST | /app/auth/login/sms | 已对接 | 用户模块 |
### 3.2 接口详细定义 ### 3.2 接口详细定义
#### 模版 #### 登录
**POST /api/login** **POST /app/auth/login/password**
``` ```
求体: 求体:
{ {
"username": "string", "username": "string", // 用户名
"password": "string" "password": "string", // 密码
"clientId": "string", // 客户端ID 可选
"grantType": "string", // 授权类型 可选
"tenantId": "string", // 租户ID 可选
"code": "string", // 授权码 可选
"uuid": "string" // 唯一标识 可选
} }
应 data: 应 data:
{ {
"token": "string", "code": 0,
"userInfo": { "msg": "string",
"username": "string", "data": {
"phone": "string" "scope": "string",
"openid": "string",
"access_token": "string",
"refresh_token": "string",
"expire_in": 0,
"refresh_expire_in": 0,
"client_id": "string"
} }
} }
``` ```
**GET /api/user/profile**
```
应 data:
{
"phone": "string",
"welcomeText": "string"
}
```
--- ---
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment