login_main_cubit.dart 6.15 KB
import 'package:appframe/config/constant.dart';
import 'package:appframe/config/locator.dart';
import 'package:appframe/config/routes.dart';
import 'package:appframe/data/repositories/wechat_auth_repository.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:fluwx/fluwx.dart';
import 'package:shared_preferences/shared_preferences.dart';

class LoginMainState extends Equatable {
  final bool agreed;
  final bool showAgreed;
  final bool loading;
  final bool showSnackBar;
  final String snackBarMsg;

  const LoginMainState({
    this.agreed = false,
    this.showAgreed = false,
    this.loading = false,
    this.showSnackBar = false,
    this.snackBarMsg = '',
  });

  LoginMainState copyWith({
    bool? agreed,
    bool? showAgreed,
    bool? loading,
    bool? showSnackBar,
    String? snackBarMsg,
  }) {
    return LoginMainState(
      agreed: agreed ?? this.agreed,
      showAgreed: showAgreed ?? this.showAgreed,
      loading: loading ?? this.loading,
    );
  }

  @override
  List<Object?> get props => [
        agreed,
        showAgreed,
        loading,
        showSnackBar,
        snackBarMsg,
      ];
}

class LoginMainCubit extends Cubit<LoginMainState> {
  late final Fluwx _fluwx;
  late final FluwxCancelable _fluwxCancelable;
  late final WechatAuthRepository _wechatAuthRepository;

  LoginMainCubit(super.initialState) {
    _fluwx = getIt.get<Fluwx>();
    _fluwxCancelable = _fluwx.addSubscriber(_responseListener);
    _wechatAuthRepository = getIt.get<WechatAuthRepository>();
  }

  void toggleAgreed(bool value) {
    emit(state.copyWith(agreed: value));
  }

  void confirmAgreed() {
    emit(state.copyWith(agreed: true, showAgreed: false));
    wechatAuth();
  }

  void cancelAgreed() {
    emit(state.copyWith(showAgreed: false));
  }

  void wechatAuth() async {
    if (!state.agreed) {
      emit(state.copyWith(showAgreed: true));
      return;
    }

    var authResult = await _fluwx.authBy(
      which: NormalAuth(scope: 'snsapi_userinfo', state: 'wechat_sdk_test'),
    );

    if (!authResult) {
      emit(state.copyWith(showSnackBar: true, snackBarMsg: '微信授权处理失败'));
      emit(state.copyWith(showSnackBar: false));
      return;
    }

    // 控制显示加载框
    emit(state.copyWith(loading: true));
  }

  void goLoginPhone() {
    router.go('/loginPhone');
  }

  void goLoginQr() {
    router.go('/loginQr');
  }

  void _responseListener(WeChatResponse response) async {
    if (response is WeChatAuthResponse) {
      if (response.code == null || response.code == '') {
        emit(state.copyWith(loading: false));
        return;
      }

      var resultData = await _wechatAuthRepository.codeToSk(response.code!) as Map<String, dynamic>?;

      // 请求接口异常
      if (resultData == null) {
        emit(state.copyWith(loading: false, showSnackBar: true, snackBarMsg: '登录请求处理失败'));
        emit(state.copyWith(showSnackBar: false));
        return;
      }

      // 状态码错误
      if (resultData['resultCode'] != '001') {
        emit(state.copyWith(loading: false, showSnackBar: true, snackBarMsg: '登录请求状态失败'));
        emit(state.copyWith(showSnackBar: false));
        return;
      }

      var data = resultData['data'] as Map<String, dynamic>;
      var roles = data['roles'];
      // 过滤出家长角色的数据
      roles.removeWhere((element) => element['userType'] != 2);

      var sessionCode = data['sessionCode'];
      var userCode = data['userCode'];
      var classCode = '';
      var userType = 0;
      var stuId = '';

      var sharedPreferences = getIt.get<SharedPreferences>();

      if (roles.isNotEmpty) {
        var role = roles[0];
        classCode = role['classCode'];
        userType = role['userType'];
        stuId = role['stuId'];

        // 将角色中的班级数据处理后,进行缓存
        List<String> classIdList = [];
        for (var role in roles) {
          classIdList.add(role['classCode'] as String);
        }
        debugPrint('classCodeIds:-------------- $classIdList');
        sharedPreferences.setStringList(Constant.classIdSetKey, classIdList);
      } else {
        sharedPreferences.setStringList(Constant.classIdSetKey, []);
      }

      var preUserCode = sharedPreferences.getString('pre_userCode') ?? '';
      if (userCode != preUserCode) {
        // 新用户登录
        sharedPreferences.setString('pre_userCode', userCode);
        sharedPreferences.setString('pre_classCode', classCode);
        sharedPreferences.setInt('pre_userType', userType);
        sharedPreferences.setString('pre_stuId', stuId);
      } else {
        // 前一个登录用户重新登录
        var preClassCode = sharedPreferences.getString('pre_classCode') ?? '';
        var preUserType = sharedPreferences.getInt('pre_userType') ?? 0;
        var preStuId = sharedPreferences.getString('pre_stuId') ?? '';

        if (preClassCode != '' &&
            roles.any((element) =>
                element['classCode'] == preClassCode &&
                element['userType'] == preUserType &&
                element['stuId'] == preStuId)) {
          classCode = preClassCode;
          userType = preUserType;
          stuId = preStuId;
        } else {
          sharedPreferences.setString('pre_userCode', userCode);
          sharedPreferences.setString('pre_classCode', classCode);
          sharedPreferences.setInt('pre_userType', userType);
          sharedPreferences.setString('pre_stuId', stuId);
        }
      }

      sharedPreferences.setString('auth_sessionCode', sessionCode);
      sharedPreferences.setString('auth_userCode', userCode);
      sharedPreferences.setString('auth_classCode', classCode);
      sharedPreferences.setInt('auth_userType', userType);
      sharedPreferences.setString('auth_stuId', stuId);

      router.go(
        '/web',
        extra: {
          'sessionCode': sessionCode,
          'userCode': userCode,
          'classCode': classCode,
          'userType': userType,
          'stuId': stuId,
        },
      );
    }
  }

  @override
  Future<void> close() {
    _fluwxCancelable.cancel();
    return super.close();
  }
}