美文网首页
Flutter网络请求dio简易封装

Flutter网络请求dio简易封装

作者: 禄子_c79b | 来源:发表于2022-04-22 17:24 被阅读0次

    DioManager

    ///    date   : 2021/7/11
    ///    desc   : 网络请求类
    
    ///成功回调
    typedef Success<T> = Function(T? data);
    
    ///失败回调,若传空,则系统吐司提示,若不会空,自行处理错误结果
    typedef Fail = Function(int? code, String? msg);
    
    class DioManager {
      /// 默认code--返回成功
      static const RESP_OK = 200;
    
      /// 默认code--40001未登录,40002token失效,40010账号被异地登录,40011token来源异常
      static const List RESP_LOGIN_EXPIRE = [40001, 40002, 40010, 40011];
    
      String? signKey;
    
      Dio dio = new Dio();
      static DioManager? _instance;
    
      static DioManager getInstance() {
        if (_instance == null) {
          _instance = new DioManager();
          _instance!._init();
        }
        return _instance!;
      }
    
      void _init() {
        dio.options.baseUrl = "https://www.fastmock.site/mock/6d5084df89b4c7a49b28052a0f51c29a/test/";
        dio.options.connectTimeout = 5000;
        dio.options.receiveTimeout = 5000;
        dio.options.responseType = ResponseType.json;
        dio.interceptors.add(HeaderInterceptor()); //请求头拦截器
        dio.interceptors.add(DioLogInterceptor()); //是否开启请求日志
        // dio.interceptors.add(ResponseInterceptor()); //请求结果回调
      }
    
      void setBaseUrl(String baseUrl) {
        dio.options.baseUrl = baseUrl;
      }
    
      void setSignKey(String signKey) => this.signKey = signKey;
    
      void setHeader(Map<String, dynamic>? headers) {
        dio.options.headers = headers;
      }
    
      ///post form 表单提交操作
      Future postForm<T>(
        String path, {
        SplayTreeMap<String, dynamic>? params,
        required Success<T> success,
        required Fail? fail,
        bool withLoading = true,
      }) async {
        var splayTreeMap = new SplayTreeMap<String, dynamic>();
        if (params != null) {
          splayTreeMap.addAll(params);
        }
    
        if (withLoading) {
          // ToastUtils.getInstance().showLoading();
        }
        try {
          var response = await dio.post(path, data: FormData.fromMap(splayTreeMap));
          parseResponse(response, success, fail);
        } on DioError catch (e) {
          formatError(e, fail);
        }
      }
    
      ///post json
      Future postJson<T>(
        String path, {
        SplayTreeMap<String, dynamic>? params,
        required Success<T> success,
        required Fail? fail,
        bool withLoading = true,
      }) async {
        var splayTreeMap = new SplayTreeMap<String, dynamic>();
        if (params != null) {
          splayTreeMap.addAll(params);
        }
        if (withLoading) {
          // ToastUtils.getInstance().showLoading();
        }
        try {
          var response = await dio.post(path, data: splayTreeMap);
          parseResponse(response, success, fail);
          print('你好============response11${response}');
    
        } on DioError catch (e) {
          formatError(e, fail);
        }
      }
    
      ///get
      Future get<T>(
        String path, {
        SplayTreeMap<String, dynamic>? params,
        required Success<T> success,
        required Fail? fail,
        bool withLoading = true,
      }) async {
        var splayTreeMap = new SplayTreeMap<String, dynamic>();
        if (params != null) {
          splayTreeMap.addAll(params);
        }
    
        if (withLoading) {
          // ToastUtils.getInstance().showLoading();
        }
        try {
          var response = await dio.get(path, queryParameters: splayTreeMap);
          parseResponse(response, success, fail);
        } on DioError catch (e) {
          formatError(e, fail);
        }
      }
    
      void parseResponse<T>(
          Response<dynamic> response, Success<T> success, Fail? fail) {
        // ToastUtils.getInstance().hideLoading();
        if (response.statusCode == 200) {
          Map<String, dynamic> result = response.data;
          if (result["code"] == RESP_OK) {
            success(result["data"]);
            return;
          }
          if (RESP_LOGIN_EXPIRE.contains(result["code"])) {
            //登录过期需要重新登录
            // ToastUtils.getInstance().toastFail(result["msg"]);
            // NativeUtils.sendNativeData(NativeUtils.NATIVE_LOGIN);
            return;
          }
          if (fail != null) {
            // fail(result["code"], result["msg"]);
            fail(result["code"], result["message"]);
          } else {
            // ToastUtils.getInstance().toastFail(result["msg"] ?? '');
          }
        } else {
          if (fail != null) {
            fail(response.statusCode ?? -1, response.statusMessage ?? 'error');
          } else {
            // ToastUtils.getInstance().toastFail(response.statusMessage ?? 'error');
          }
        }
      }
    
      void formatError(DioError e, Fail? fail) {
        print(e.stackTrace);
        if (fail != null) {
          fail(-1, e.message);
        } else {
          // ToastUtils.getInstance().toastFail(e.message);
        }
      }
    }
    

    HeaderInterceptor

    ///    author : luzi
    ///    date   : 2021/7/11
    ///    desc   : 请求头拦截器
    class HeaderInterceptor extends Interceptor {
      @override
      Future<void> onRequest(
        RequestOptions options,
        RequestInterceptorHandler handler,
      ) async {
        Map<String, dynamic> headers = options.headers;
        headers['clientId'] = 1; //渠道(1.APP 2.Web)
        if (Platform.isAndroid) {
          headers['systemName'] = 'Android'; //系统名称
        } else if (Platform.isIOS) {
          headers['systemName'] = 'iOS'; //系统名称
        }
    
        var time = DateTime.now().millisecondsSinceEpoch;
        headers['ts'] = time; //时间戳
        String sign = getParamsStr(options, time);
        headers['sign'] = sign; //参数加密签名
        headers['language'] = Get.locale?.countryCode ?? 'MY'; //语言环境
        headers['Accept'] = 'application/json';
        options.headers = headers;
        handler.next(options);
      }
    
      getParamsStr(RequestOptions options, int time) {
        StringBuffer stringBuffer = new StringBuffer();
        String? paramsStr;
        var method = options.method;
        if (method == 'GET') {
          if (options.queryParameters.isNotEmpty) {
            String query = options.uri.query;
            var splitArray = query.split('&');
            var splayTreeMap = new SplayTreeMap();
            splitArray.forEach((split) {
              var splitChild = split.split('=');
              splayTreeMap[splitChild[0]] = Uri.encodeQueryComponent(splitChild[1]);
            });
            paramsStr = json.encode(splayTreeMap);
            if (paramsStr.isNotEmpty) {
              stringBuffer.write('$paramsStr&');
            } else {
              stringBuffer.write('{}&');
            }
          } else {
            stringBuffer.write('{}&');
          }
        } else if (method == 'POST') {
          var data = options.data;
          if (data is FormData) {
            if (data.fields.isNotEmpty) {
              String replace = data.fields
                  .join(",")
                  .replaceAll('MapEntry', '')
                  .replaceAll('(', '')
                  .replaceAll(')', '');
              paramsStr = replace;
              if (paramsStr.isNotEmpty) {
                stringBuffer.write('{$paramsStr}&');
              } else {
                stringBuffer.write('{}&');
              }
            } else {
              stringBuffer.write('{}&');
            }
          } else {
            paramsStr = jsonEncode(data);
            if (paramsStr.isNotEmpty) {
              stringBuffer.write('$paramsStr&');
            } else {
              stringBuffer.write('{}&');
            }
          }
        }
        // NativeUtils.sendNativeData(NativeUtils.NATIVE_LOG, paramsStr.toString());
        // print(paramsStr.toString());
        stringBuffer.write('ts=$time&');
        stringBuffer.write('tmpsign=${DioManager.getInstance().signKey}');
        String toString = stringBuffer.toString().replaceAll("\"", "");
        // NativeUtils.sendNativeData(NativeUtils.NATIVE_LOG, toString);
        // print(toString);
        // Get.log.printInfo(info: '拼接后:$toString');
        var content = new Utf8Encoder().convert(toString);
        var digest = md5.convert(content);
        String md5Encode = hex.encode(digest.bytes).toUpperCase();
        Get.log.printInfo(info: 'MD5:$md5Encode');
        return md5Encode;
      }
    }
    

    DioLogInterceptor

    ///    date   : 2021/7/11
    ///    desc   : 日志拦截器
    class DioLogInterceptor extends Interceptor {
      /// Print request [Options]
      final bool request;
    
      /// Print request header [Options.headers]
      final bool requestHeader;
    
      /// Print request data [Options.data]
      final bool requestBody;
    
      /// Print [Response.data]
      final bool responseBody;
    
      /// Print [Response.headers]
      final bool responseHeader;
    
      /// Print error message
      final bool error;
    
      /// InitialTab count to logPrint json response
      static const int initialTab = 1;
    
      /// 1 tab length
      static const String tabStep = '    ';
    
      /// Print compact json response
      final bool compact;
    
      /// Width size per logPrint
      final int maxWidth;
    
      /// Log printer; defaults logPrint log to console.
      /// In flutter, you'd better use debugPrint.
      /// you can also write log in a file.
      void Function(Object object) logPrint;
    
      DioLogInterceptor({
        this.request = true,
        this.requestHeader = true,
        this.requestBody = true,
        this.responseHeader = false,
        this.responseBody = true,
        this.error = true,
        this.maxWidth = 90,
        this.compact = true,
        this.logPrint = print,
      });
    
      @override
      void onRequest(
          RequestOptions options, RequestInterceptorHandler handler) async {
        if (request) {
          _printRequestHeader(options);
        }
        if (requestHeader) {
          _printMapAsTable(options.queryParameters, header: 'Query Parameters');
          final requestHeaders = Map();
          requestHeaders.addAll(options.headers);
          requestHeaders['contentType'] = options.contentType?.toString();
          requestHeaders['responseType'] = options.responseType.toString();
          requestHeaders['followRedirects'] = options.followRedirects;
          requestHeaders['connectTimeout'] = options.connectTimeout;
          requestHeaders['receiveTimeout'] = options.receiveTimeout;
          _printMapAsTable(requestHeaders, header: 'Headers');
          _printMapAsTable(options.extra, header: 'Extras');
        }
        if (requestBody && options.method != 'GET') {
          final data = options.data;
          if (data != null) {
            if (data is Map) _printMapAsTable(options.data, header: 'Body');
            if (data is FormData) {
              final formDataMap = Map()
                ..addEntries(data.fields)
                ..addEntries(data.files);
              _printMapAsTable(formDataMap, header: 'Form data | ${data.boundary}');
            } else
              _printBlock(data.toString());
          }
        }
        handler.next(options);
      }
    
      @override
      void onError(
        DioError err,
        ErrorInterceptorHandler handler,
      ) async {
        if (error) {
          if (err.type == DioErrorType.response) {
            final uri = err.response?.requestOptions.uri;
            _printBoxed(
                header:
                    'DioError ║ Status: ${err.response?.statusCode} ${err.response?.statusMessage}',
                text: uri.toString());
            if (err.response != null && err.response?.data != null) {
              logPrint('╔ ${err.type.toString()}');
              if (err.response != null) {
                _printResponse(err.response!);
              }
            }
            _printLine('╚');
            logPrint('');
          } else
            _printBoxed(header: 'DioError ║ ${err.type}', text: err.message);
        }
        handler.next(err);
      }
    
      @override
      void onResponse(
        Response response,
        ResponseInterceptorHandler handler,
      ) async {
        if (responseHeader) {
          final responseHeaders = Map<String, String>();
          response.headers
              .forEach((k, list) => responseHeaders[k] = list.toString());
          _printMapAsTable(responseHeaders, header: 'Headers');
        }
    
        if (responseBody) {
          _printResponseHeader(response);
          logPrint('╔ Body');
          logPrint('║');
          _printResponse(response);
          logPrint('║');
          _printLine('╚');
        }
        handler.next(response);
      }
    
      void _printBoxed({String? header, String? text}) {
        logPrint('');
        logPrint('╔╣ $header');
        logPrint('║  $text');
        _printLine('╚');
      }
    
      void _printResponse(Response response) {
        if (response.data != null) {
          if (response.data is Map)
            _printPrettyMap(response.data);
          else if (response.data is List) {
            logPrint('║${_indent()}[');
            _printList(response.data);
            logPrint('║${_indent()}[');
          } else
            _printBlock(response.data.toString());
        }
      }
    
      void _printResponseHeader(Response? response) {
        final uri = response?.requestOptions.uri;
        final method = response?.requestOptions.method;
        //添加以下代码,防止多接口请求时 response的header和body被分开打印
        String header =
            'Response ║ $method ║ Status: ${response?.statusCode} ${response?.statusMessage}';
        logPrint('╔╣ $header' + ('═' * 70));
        logPrint('║  ${uri.toString()}');
        logPrint('║  ');
      }
    
      void _printRequestHeader(RequestOptions? options) {
        final uri = options?.uri;
        final method = options?.method;
        _printBoxed(header: 'Request ║ $method ', text: uri.toString());
      }
    
      void _printLine([String pre = '', String suf = '╝']) =>
          logPrint('$pre${'═' * maxWidth}$suf');
    
      void _printKV(String key, Object? v) {
        final pre = '╟ $key: ';
        final msg = v.toString();
    
        if (pre.length + msg.length > maxWidth) {
          logPrint(pre);
          _printBlock(msg);
        } else
          logPrint('$pre$msg');
      }
    
      void _printBlock(String msg) {
        int lines = (msg.length / maxWidth).ceil();
        for (int i = 0; i < lines; ++i) {
          logPrint((i >= 0 ? '║ ' : '') +
              msg.substring(i * maxWidth,
                  math.min<int>(i * maxWidth + maxWidth, msg.length)));
        }
      }
    
      String _indent([int tabCount = initialTab]) => tabStep * tabCount;
    
      void _printPrettyMap(Map data,
          {int tabs = initialTab, bool isListItem = false, bool isLast = false}) {
        final bool isRoot = tabs == initialTab;
        final initialIndent = _indent(tabs);
        tabs++;
    
        if (isRoot || isListItem) logPrint('║$initialIndent{');
    
        data.keys.toList().asMap().forEach((index, key) {
          final isLast = index == data.length - 1;
          var value = data[key];
    //      key = '\"$key\"';
          if (value is String) value = '\"$value\"';
          if (value is Map) {
            if (compact && _canFlattenMap(value))
              logPrint('║${_indent(tabs)} $key: $value${!isLast ? ',' : ''}');
            else {
              logPrint('║${_indent(tabs)} $key: {');
              _printPrettyMap(value, tabs: tabs);
            }
          } else if (value is List) {
            if (compact && _canFlattenList(value))
              logPrint('║${_indent(tabs)} $key: ${value.toString()}');
            else {
              logPrint('║${_indent(tabs)} $key: [');
              _printList(value, tabs: tabs);
              logPrint('║${_indent(tabs)} ]${isLast ? '' : ','}');
            }
          } else {
            final msg = value.toString().replaceAll('\n', '');
            final indent = _indent(tabs);
            final linWidth = maxWidth - indent.length;
            if (msg.length + indent.length > linWidth) {
              int lines = (msg.length / linWidth).ceil();
              for (int i = 0; i < lines; ++i) {
                logPrint(
                    '║${_indent(tabs)} ${msg.substring(i * linWidth, math.min<int>(i * linWidth + linWidth, msg.length))}');
              }
            } else
              logPrint('║${_indent(tabs)} $key: $msg${!isLast ? ',' : ''}');
          }
        });
    
        logPrint('║$initialIndent}${isListItem && !isLast ? ',' : ''}');
      }
    
      void _printList(List list, {int tabs = initialTab}) {
        list.asMap().forEach((i, e) {
          final isLast = i == list.length - 1;
          if (e is Map) {
            if (compact && _canFlattenMap(e))
              logPrint('║${_indent(tabs)}  $e${!isLast ? ',' : ''}');
            else
              _printPrettyMap(e, tabs: tabs + 1, isListItem: true, isLast: isLast);
          } else
            logPrint('║${_indent(tabs + 2)} $e${isLast ? '' : ','}');
        });
      }
    
      bool _canFlattenMap(Map map) {
        return map.values.where((val) => val is Map || val is List).isEmpty &&
            map.toString().length < maxWidth;
      }
    
      bool _canFlattenList(List list) {
        return (list.length < 10 && list.toString().length < maxWidth);
      }
    
      void _printMapAsTable(Map? map, {String? header}) {
        if (map == null || map.isEmpty) return;
        logPrint('╔ $header ');
        map.forEach((key, value) => _printKV(key, value));
        _printLine('╚');
      }
    }
    
    

    OperatingCenterEngine

    class OperatingCenterEngine {
    
      static Future queryAlertInfo(Success<Map<String, dynamic>> success,
          {Fail? fail}) async {
        await DioManager.getInstance().get('warning-rules/getConfiguration',
            params: null, success: success, fail: fail);
      }
    
    
      static Future updateAlertInfo(
          String alertAmount, Success<Map<String, dynamic>> success,
          {Fail? fail}) async {
        SplayTreeMap<String, dynamic> map = new SplayTreeMap<String, dynamic>();
        map['alertAmount'] = alertAmount; 
        await DioManager.getInstance().postJson(
            'warning-rules/alertValueConfiguration',
            params: map,
            success: success,
            fail: fail);
      }
    
    
      static Future queryBindBankInfo(Success<Map<String, dynamic>> success,
          {Fail? fail}) async {
        await DioManager.getInstance().postJson('bank-card/cashDetail',
            params: null, success: success, fail: fail);
      }
    
    
      static Future addExample(
          SplayTreeMap<String, dynamic> map, Success<Map<String, dynamic>> success,
          {Fail? fail}) async {
        await DioManager.getInstance()
            .postJson('bank-card/save', params: map, success: success, fail: fail);
      }
    
      static Future updateExample(
          SplayTreeMap<String, dynamic> map, Success<Map<String, dynamic>> success,
          {Fail? fail}) async {
        await DioManager.getInstance().postJson('bank-card/update',
            params: map, success: success, fail: fail);
      }
    
    
      static Future getExampleList(Success<List<dynamic>> success,
          {Fail? fail}) async {
        SplayTreeMap<String, dynamic> map = new SplayTreeMap();
        map['dictCode'] = 'CASH_BANK';
        await DioManager.getInstance()
            .get('dict/listDictValue', params: map, success: success, fail: fail);
      }
    
    
      static Future getImageCodeNew( SplayTreeMap<String, dynamic> map,Success<Map<String, dynamic>> success,
          {Fail? fail}) async {
        // SplayTreeMap<String, dynamic> map = new SplayTreeMap();
        // map['ceshi'] = '123456999999';
        await DioManager.getInstance()
            .postJson('test', params: map, success: success, fail: fail);
    
      }
    }
    

    实际调用

       SplayTreeMap<String, dynamic> map = new SplayTreeMap();
              map['username'] ="你好" ;
              map['loongwind'] ="123456" ;
              OperatingCenterEngine.getImageCodeNew(map,(data) =>{
              print('你好============123456${data!['age']}'),
              });
    
    

    相关文章

      网友评论

          本文标题:Flutter网络请求dio简易封装

          本文链接:https://www.haomeiwen.com/subject/wuunertx.html