import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:hyzp_ybqx/components/doJSON.dart';
import 'package:hyzp_ybqx/pages/Works/TJXX/tj_data.dart';
import 'package:hyzp_ybqx/services/EventBus.dart';
import 'package:hyzp_ybqx/widget/my_superplayer.dart';
import 'package:sprintf/sprintf.dart';

import '../components/hyxx_data_handle.dart';
import '../config/service_url.dart';
import '../res/listContacts.dart';

// import 'package:hyzp_ybqx/widget/player_pro.dart';
// import 'package:hyzp_ybqx/widget/player_pro_new.dart';
import 'UserAuthority.dart';
import 'commonFun.dart';

///球机方向控制
// 接口地址：http://125.64.218.67:9906/api/ptz/{通道ID}/{球机ID}
// static const String setSphericalCameraUrl = 'http://125.64.218.67:9906/api/ptz'; //球机方向控制接口
// 接口提交方式：post
// 接口文本：JSON
// 接口提交参数4个：
// cmdCode  说明：位移方向
// horizonSpeed 说明：横向位移速度
// verticalSpeed说明：垂直位移速度
// zoomSpeed说明：变焦速度

// 区县球机方向控制接口：
// 通过http协议向服务器发送POST数据，数据格式如下：
// http://125.64.218.67:9914/?type=publish&dwip=172.16.3.21&topic=camera&dataType=PTZ&cmdCode=23&to=456&speed=40
//
// -----------------------------------------------
// 云台控制代码：
// 1：停止动作
// 3：启动雨刷
// 11：焦距变大
// 12：焦距变小
// 21：上移
// 22：下移
// 23：左移
// 24：右移
// 25：左上移动
// 26：右上移动
// 27：左下移动
// 28：右下移动
Future setSphericalCameraDio(
    {@required int id,
    @required String dwip,
    @required int cmdCode,
    String move_type = "publish",
    String topic_type = "camera",
    String data_type = "PTZ",
    // int horizonSpeed = 120,
    // int verticalSpeed = 120,
    // int zoomSpeed = 120}) async {
    int speed = 2}) async {
  // ---------------------------------------------------
  // 参数说明：
  // type：动作类型，publish表示向设备发送指令
  // dwip：点位IP，向哪个点位的设备发送指令
  // topic：设备主题类型，camera表示向球机设备发送
  // dataType：控制类型，PTZ表示控制球机云台
  // cmdCode：球机云台的控制代码，整数，如21表示上，22表示下，详情见下方
  // to：客户端ID，暂不用，输入任意整数即可
  // speed：暂不用，输入任意整数即可

  // ---------------------------------------------------
  // http://125.64.218.67:9914/?
  // type=publish&
  // dwip=172.16.3.21&
  // topic=camera&
  // dataType=PTZ&
  // cmdCode=23&
  // to=456&
  // speed=40
  Map map = {
    "type": move_type,
    "dwip": dwip,
    "topic": topic_type,
    "dataType": data_type,
    "cmdCode": cmdCode.toString(),
    "to": id.toString(),
    "speed": speed.toString(),
    // "horizonSpeed": horizonSpeed.toString(),
    // "verticalSpeed": verticalSpeed.toString(),
    // "zoomSpeed": zoomSpeed.toString(),
    "sip": g_sip.toString(), // 新增sip参数，0表示市级平台，1表示区县平台。
  };
  var api = getSphericalCameraApi(map);
  print('api = ${api}');
  // api =
  // OK:    http://125.64.218.67:9914/?type=publish&dwip=172.16.3.21&topic=topic&dataType=dataType&cmdCode=21&to=1&speed=120
  // bug01: http://125.64.218.67:9914/?type=publish&dwip=172.16.3.21&topic=camera&dataType=PTZ&cmdCode=23&to=456&speed=40
  // api =  http://125.64.218.67:9914/?type=publish&dwip=172.16.3.21&topic=camera&dataType=PTZ&cmdCode=21&to=1&speed=120

  try {
    print('开始处理网络请求...');

    Dio dio = Dio();
    print('map = ${map}');
    Response response = await dio.post(api);
    print('response = ${response.toString()}');

    if (response.statusCode == 200) {
      // Map _mapDataRet = await getMapFromJson(response.data);
      // _mapData = _mapDataRet['data'];
      print('${api} 球机移动网络请求过程正常完成');

      ///处理球机停止移动
      // map["cmdCode"] = '0';
      // api = getSphericalCameraApi(map);
      // print('api = ${api}');
      // //I/flutter (28351): api = http://125.64.218.67:9906/api/ptz/34020000001320001016/34020000001320001016?cmdCode=0&horizonSpeed=60&verticalSpeed=60&zoomSpeed=60
      //
      // response = await dio.post(api);
      // print('response = ${response.toString()}');
      // if (response.statusCode == 200) {
      //   print('${api} 球机停止移动网络请求过程正常完成');
      // }
    } else {
      throw Exception('${api} 后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('${api} 网络请求过程异常 e：${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }
}

// cmdCode:8
// horizonSpeed:60
// verticalSpeed:60
// zoomSpeed:60
// 上述调用可以一次性书写为：
// http://125.64.218.67:9906/api/ptz/34020000001320002016/34020000001320002016?cmdCode=8&horizonSpeed=60&verticalSpeed=60&zoomSpeed=60
// String getSphericalCameraApi(int id, Map map) {
//   // var api = ServicePath.setSphericalCameraUrl +
//   var api = setSphericalCameraUrl + getSphericalCameraID(id) + '/' + getSphericalCameraID(id) + '?';
//   map.forEach((key, value) {
//     //print("$key : $value");
//     api += (key + '=' + value + '&');
//   });
//   api = api.substring(0, api.length - 1); // 删除末尾字符
//
//   return api;
// }

// 兴文县：
String getSphericalCameraApi(Map map) {
  // Map map = {
  //   "type": move_type,
  //   "dwip": dwip,
  //   "topic": topic_type,
  //   "dataType": data_type,
  //   "cmdCode": cmdCode.toString(),
  //   "to": id.toString(),
  //   "speed": speed,
  // };
  // http://125.64.218.67:9914/?type=publish&dwip=172.16.3.21&topic=camera&dataType=PTZ&cmdCode=23&to=456&speed=40
  var api = setSphericalCameraUrl + '?';
  map.forEach((key, value) {
    //print("$key : $value");
    api += (key + '=' + value + '&');
    // E/flutter (23744): [ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: type 'int' is not a subtype of type 'String' of 'other'
  });
  api = api.substring(0, api.length - 1); // 删除末尾字符

  return api;
}

///四：球机ID说明：
// 1号：34020000001320001016
//sId = 34020000001320001016
// 2号：34020000001320002016
// 3号：34020000001320003016
// 4号：34020000001320004016
// 5号：34020000001320005016
// 6号：34020000001320006016
// 7号：34020000001320007016
// 8号：34020000001320008016
// 9号：34020000001320009016
// 10号：34020000001320010016
// 11号：34020000001320011016
// 12号：34020000001320012016
// 13号：34020000001320013016
String getSphericalCameraID(int id) {
  String sId = sprintf("%02i", [id]);
  //print('sId =${sId}');
  sId = '340200000013200' + sId + '016';
  //print('sId =${sId}');
  return sId;
}

///从指定 api 接口 获取数据
Future getSomeDioData({@required String api}) async {
  Map _mapGetData = {};
  try {
    print('开始处理网络请求...');
    String random = RandomBit(6); //flutter （dart）生成N位随机数
    Map map = {
      "sign": GenerateMd5(APPkey + random),
      "random": random,
    };

    Dio dio = Dio();
    //static const String getNtimeUrl = ServiceUrl + '?s=App.Car_Hyc.GetNtime'; //获取违章间隔时间数据
    var api = ServicePath.getNtimeUrl;
    print('api = ${api}');
    print('map = ${map}');
    //Response response = await dio.post(api, data: map);
    Response response = await dio.post(api, data: map);

    print('response = ${response.toString()}');

    if (response.statusCode == 200) {
      Map _mapDataRet = await getMapFromJson(response.data);
      _mapGetData = _mapDataRet['data'];
      print('${api} 网络请求过程正常完成');
    } else {
      throw Exception('${api} 后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('${api} 网络请求过程异常 e：${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }

  return _mapGetData;
}

//设置 sfyc （是否延迟）和 tsjj （推送交警）
Future set_sfyc_tsjj(int _zpsj) async {
  String str = mapHyshlx[hyshlx]['apiNtiem'];
  print('str = ${str}');
  //sfyc（是否延迟）
  getSomeDioData(api: mapHyshlx[hyshlx]['apiNtiem']).then((value) async {
    int nowStamp = DateTime.now().millisecondsSinceEpoch ~/ 1000;
    int _Ntime = getSecondsOfNtime(value['value']);
    //int _zpsj = int.parse(listGetZpjl[index]['zpsj']);
    // 	B、若超出规定时间，即当前时间 > 抓拍时间 + 间隔时间，则sfyc=1，不推送交警。
    print('nowStamp = ${nowStamp}, (_zpsj + _Ntime) = ${(_zpsj + _Ntime)}');
    print('nowStamp > (_zpsj + _Ntime) = ${nowStamp > (_zpsj + _Ntime)}');

    sfyc = 0;
    //tsjj = true;  //注释该行，避免 567-未选择推送交警也推送了
    if (nowStamp > (_zpsj + _Ntime)) {
      sfyc = 1;
      tsjj = false;
    }
    print('sfyc = ${sfyc}, tsjj = ${tsjj}');
    //黑烟审核 sfyc 改变广播
    eventBus.fire(HycsDataAuditSfyc('黑烟审核 sfyc 已改变'));
  });
}

//App.Car_Led.Get接口获取的记录数据结构（比App.Car_Led.GetList接口获取的丰富）
// Map _mapGetLedXsxxGetData = {
//   "id": 2,
//   "dwip": "172.16.3.2",
//   "xsnr": "绿水青山就是金山银山     宜宾市翠屏生态环境局宣。",
//   "xsts": 0, //显示抓拍到的多少条违章记录
//   "stime": "07:00",
//   "etime": "23:00",
//   "addtime": "2021-01-20 10:16:07",
//   "updatetime": "2021-02-13 11:48:51"
// };

///从接口 mapHyshlx[theSbgllx]['apiItem'] 获取指定id的单条记录返回 Map
Future getLedXsxxGetData({@required int id, @required String theSbgllx}) async {
  Map _mapGetSbglGetData = {};

  try {
    print('开始处理网络请求...');
    String random = RandomBit(6); //flutter （dart）生成N位随机数
    Map map = {
      "id": id.toString(),
      "sign": GenerateMd5(APPkey + random),
      "random": random,
    };

    Dio dio = Dio();
    print('mapHyshlx[theSbgllx][apiItem] = ${mapHyshlx[theSbgllx]['apiItem']}');
    print('map = ${map}');
    Response response = await dio.post(mapHyshlx[theSbgllx]['apiItem'], data: map);
    printWrapped('response = ${response.toString()}');
    // [log] response = {"ret":200,"data":false,"msg":""}

    if (response.statusCode == 200) {
      Map _mapGetSbglGetDataRet = await getMapFromJson(response.data);
      // 避免 response = {"ret":200,"data":false,"msg":""} 时，报错终止
      if (false == _mapGetSbglGetDataRet['data']) {
        _mapGetSbglGetDataRet['data'] = {
          "id": 1,
          "dwip": "",
          "xsnr": "",
          "xsts": 0, //显示抓拍到的多少条违章记录
          "stime": "",
          "etime": "",
          "addtime": "",
          "updatetime": ""
        };
      }
      _mapGetSbglGetData = _mapGetSbglGetDataRet['data'];

      printWrapped('_mapGetSbglGetData[\'xsts\'] = ${_mapGetSbglGetData['xsts']}');
      print('theSbgllx网络请求过程正常完成');
    } else {
      throw Exception('theSbgllx后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('theSbgllx网络请求过程异常e：${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }

  return _mapGetSbglGetData;
}

//	App.Car_Led.Update
// 更新数据
// 接口地址：http://125.64.218.67:9904/?s=App.Car_Led.Update
// 接口文档
// 根据ID更新数据库中的一条纪录数据
//
// 接口参数
// 参数名字	类型	是否必须	默认值	其他	说明
// sign	字符串	必须
// random	字符串	必须
// id	字符串	必须		最小：1	ID
// xsnr	字符串	必须			字幕内容
// xsts	整型	必须	0	最小：0	同步显示违章记录条数
// stime	字符串	必须	08:00		启用时间段-开始时间
// etime	字符串	必须	21:00		启用时间段-结束时间
// 返回结果
// 返回字段	类型	说明
// code	整型	更新的结果，1表示成功，0表示无更新，false表示失败
// 异常情况
// 错误码	错误描述信息
// 400	表示客户端参数错误
// 404	表示接口服务不存在
// 500	表示服务端内部错误

///从接口 mapHyshlx[theSbgllx]['apiItem'] 更新指定id的LED数据
Future updateLedData({@required int id, @required String theSbgllx, @required Map map}) async {
  Map _mapGetSbglGetData = {};

  try {
    print('开始处理网络请求...');
    String random = RandomBit(6); //flutter （dart）生成N位随机数
    map.addAll({
      "id": id.toString(),
      "sign": GenerateMd5(APPkey + random),
      "random": random,
      "qxdm": qx_code,
    });

    if (!map.containsKey('xsnr')) {
      map['xsnr'] = '';
    }

    if (!map.containsKey('xsts')) {
      map['xsts'] = 0;
    }

    if (!map.containsKey('stime')) {
      map['stime'] = '08:00';
    }

    if (!map.containsKey('xsnr')) {
      map['etime'] = '21:00';
    }

    Dio dio = Dio();
    print('mapHyshlx[theSbgllx][apiItem] = ${mapHyshlx[theSbgllx]['apiItem']}');
    printWrapped('map = ${map}');
    Response response = await dio.post(mapHyshlx[theSbgllx]['apiItem'], data: map);
    print('response = ${response.toString()}');

    if (response.statusCode == 200) {
      Map _mapGetSbglGetDataRet = await getMapFromJson(response.data);
      _mapGetSbglGetData = _mapGetSbglGetDataRet['data'];
      //code	整型	更新的结果，1表示成功，0表示无更新，false表示失败
      print('_mapGetSbglGetData = ${_mapGetSbglGetData.toString()}');
      //_mapGetSbglGetData = {code: 1}
      Map codeMap = {
        0: '没有更新。',
        1: '更新成功。',
        false: '更新失败！',
        '批量更新完成': '批量更新完成',
      };

      Fluttertoast.showToast(
        msg: codeMap[_mapGetSbglGetData['code']],
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
      );

      print('theSbgllx网络请求过程正常完成');
    } else {
      throw Exception('theSbgllx后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('theSbgllx网络请求过程异常e：${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }

  return _mapGetSbglGetData;
}

/*
App.Car_Statis.GetStaAll
获取抓拍集成统计数据
接口地址：http://125.64.218.67:9904/?s=App.Car_Statis.GetStaAll
接口文档
根据dwip获取抓拍记录统计数据

接口参数
参数名字	类型	是否必须	默认值	其他	说明
sign	字符串	必须
random	字符串	必须
dwip	字符串	可选			点位IP
time	字符串	可选			统计日期，格式如:2021-03-10
返回结果
返回字段	类型	说明
dwip	字符串	点位IP
dwmc	字符串	点位名称
zp_all	整型	累计抓拍数
hyc_all	整型	累计已审核数
cll_today	整型	今日车流量
cll_all	整型	累计车流量
zp_today	整型	今日抓拍数
sends	整型	已推送交警数
send_all	整型	累计推送交警数
csnum	整型	已初审数
fsnum	整型	已复核数
异常情况
错误码	错误描述信息
400	表示客户端参数错误
404	表示接口服务不存在
500	表示服务端内部错误
*/

///从接口 App.Car_Statis.GetStaAll 获取今日集成统计数据，返回 Map
///子非鱼: 可指定统计日期和点位参数。若指定，则依次显示当日所有点位。统计日期格式如:2021-03-10
Future getAllStatisData({String ip = '', String date = ''}) async {
  //Map _mapAllStatisData = {};
  List _listAllStatisData = [];

  try {
    print('开始处理网络请求...');
    String random = RandomBit(6); //flutter （dart）生成N位随机数
    Map map = {
      "sign": GenerateMd5(APPkey + random),
      "random": random,
    };

    if (ip.isNotEmpty) {
      map['dwip'] = ip;
    }

    if (date.isNotEmpty) {
      map['time'] = date;
    }

    //注意：访问区县后台接口，需要统一添加区县代码参数
    map['qxdm'] = qx_code;

    Dio dio = Dio();
    String api = ServicePath.getStaAllUrl;
    print('api = ${api}');
    print('map = ${map}');
    Response response = await dio.post(api, data: map);
    print('response = ${response.toString()}');

    if (response.statusCode == 200) {
      Map _mapStatisDataRet = await getMapFromJson(response.data);
      print('_mapStatisDataRet = ${_mapStatisDataRet}');
      print('_mapStatisDataRet[\'data\'] = ${_mapStatisDataRet['data']}');
      // _mapStatisDataRet = {ret: 200, data: {}, msg: }
      // _mapStatisDataRet['data'] = {}
      // 避免统计数据为空时报错：
      // getAllStatisData 网络请求过程异常e：type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'List<dynamic>'
      if (_mapStatisDataRet['data'].length > 0) {
        _listAllStatisData = _mapStatisDataRet['data'];
      }
      print('getAllStatisData 网络请求过程正常完成');
    } else {
      throw Exception('getAllStatisData 后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('getAllStatisData 网络请求过程异常e：${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }

  return _listAllStatisData;
}

/*
_mapAllStatisData

200 OK
cache-control: no-store, no-cache, must-revalidate
connection: keep-alive
content-type: application/json;charset=utf-8
date: Tue, 25 May 2021 01:27:11 GMT
expires: Thu, 19 Nov 1981 08:52:00 GMT
pragma: no-cache
server: openresty/1.15.8.3
transfer-encoding: chunked
x-powered-by: PHP/7.3.4

{
    "ret": 200,
    "data": [
        {
            "id": 1,
            "dwip": "172.16.3.1",
            "dwmc": "锦绣花园",
            "zp_all": 54,
            "hyc_all": 52,
            "zp_today": 1,
            "sends": 0,
            "send_all": 33,
            "csnum": 1,
            "fsnum": 0,
            "cll_today": 6420,
            "cll_all": 3225733
        },
        {
            "id": 2,
            "dwip": "172.16.3.2",
            "dwmc": "石马溪桥",
            "zp_all": 377,
            "hyc_all": 370,
            "zp_today": 1,
            "sends": 0,
            "send_all": 204,
            "csnum": 1,
            "fsnum": 0,
            "cll_today": 3430,
            "cll_all": 2127839
        },
        {
            "id": 3,
            "dwip": "172.16.3.3",
            "dwmc": "森林小区",
            "zp_all": 380,
            "hyc_all": 375,
            "zp_today": 0,
            "sends": 0,
            "send_all": 253,
            "csnum": 0,
            "fsnum": 0,
            "cll_today": 6230,
            "cll_all": 3051847
        },
        {
            "id": 4,
            "dwip": "172.16.3.4",
            "dwmc": "南山星城",
            "zp_all": 232,
            "hyc_all": 229,
            "zp_today": 1,
            "sends": 0,
            "send_all": 164,
            "csnum": 1,
            "fsnum": 0,
            "cll_today": 7900,
            "cll_all": 2989374
        },
        {
            "id": 5,
            "dwip": "172.16.3.5",
            "dwmc": "育才学校",
            "zp_all": 91,
            "hyc_all": 91,
            "zp_today": 0,
            "sends": 0,
            "send_all": 68,
            "csnum": 0,
            "fsnum": 0,
            "cll_today": 0,
            "cll_all": 1664910
        },
        {
            "id": 6,
            "dwip": "172.16.3.6",
            "dwmc": "七星花园",
            "zp_all": 57,
            "hyc_all": 56,
            "zp_today": 0,
            "sends": 0,
            "send_all": 22,
            "csnum": 0,
            "fsnum": 0,
            "cll_today": 4110,
            "cll_all": 2559674
        },
        {
            "id": 7,
            "dwip": "172.16.3.7",
            "dwmc": "市财政局",
            "zp_all": 0,
            "hyc_all": 0,
            "zp_today": 0,
            "sends": 0,
            "send_all": 0,
            "csnum": 0,
            "fsnum": 0,
            "cll_today": 0,
            "cll_all": 0
        },
        {
            "id": 8,
            "dwip": "172.16.3.8",
            "dwmc": "宜威路",
            "zp_all": 100,
            "hyc_all": 97,
            "zp_today": 0,
            "sends": 0,
            "send_all": 66,
            "csnum": 0,
            "fsnum": 0,
            "cll_today": 2835,
            "cll_all": 1891302
        },
        {
            "id": 9,
            "dwip": "172.16.3.9",
            "dwmc": "宜长路",
            "zp_all": 83,
            "hyc_all": 82,
            "zp_today": 0,
            "sends": 0,
            "send_all": 73,
            "csnum": 1,
            "fsnum": 0,
            "cll_today": 4010,
            "cll_all": 2211060
        },
        {
            "id": 10,
            "dwip": "172.16.3.10",
            "dwmc": "临港马家湾",
            "zp_all": 57,
            "hyc_all": 57,
            "zp_today": 0,
            "sends": 0,
            "send_all": 32,
            "csnum": 0,
            "fsnum": 0,
            "cll_today": 0,
            "cll_all": 2235153
        },
        {
            "id": 11,
            "dwip": "172.16.3.11",
            "dwmc": "环城路",
            "zp_all": 111,
            "hyc_all": 110,
            "zp_today": 0,
            "sends": 0,
            "send_all": 75,
            "csnum": 0,
            "fsnum": 0,
            "cll_today": 0,
            "cll_all": 1136968
        },
        {
            "id": 12,
            "dwip": "172.16.3.12",
            "dwmc": "陶瓷厂",
            "zp_all": 47,
            "hyc_all": 46,
            "zp_today": 0,
            "sends": 0,
            "send_all": 12,
            "csnum": 0,
            "fsnum": 0,
            "cll_today": 3315,
            "cll_all": 1574973
        },
        {
            "id": 13,
            "dwip": "172.16.3.13",
            "dwmc": "鑫菁英",
            "zp_all": 170,
            "hyc_all": 170,
            "zp_today": 0,
            "sends": 0,
            "send_all": 87,
            "csnum": 0,
            "fsnum": 0,
            "cll_today": 4090,
            "cll_all": 2613670
        }
    ],
    "msg": ""
}
*/

///从接口 mapStatisType[statisType]['api'] 获取指定 ip 的 statisType 类型的统计数据，返回 Map
Future getStatisData({@required String statisType, String ip = '', String date = ''}) async {
  Map _mapStatisData = {};

  try {
    print('开始处理网络请求...');
    String random = RandomBit(6); //flutter （dart）生成N位随机数
    Map map = {
      "sign": GenerateMd5(APPkey + random),
      "random": random,
    };

    if (ip.isNotEmpty) {
      map['dwip'] = ip;
    }

    if ('sh_hyc_tj' == statisType && date.isNotEmpty) {
      map['time'] = date;
    }

    if ('cllrtj' == statisType) {
      map['stime'] = mapStatisType[statisType]['startDate'];
      map['etime'] = mapStatisType[statisType]['endDate'];
      // print('map[\'stime\'] = ${map['stime']}');
      // print('map[\'etime\'] = ${map['etime']}');
    }

    //注意：访问区县后台接口，需要统一添加区县代码参数
    map['qxdm'] = qx_code;

    Dio dio = Dio();
    String api = mapStatisType[statisType]['api'];
    print('api = ${api}');
    print('map = ${map}');
    Response response = await dio.post(api, data: map);
    print('response = ${response.toString()}');

    if (response.statusCode == 200) {
      Map _mapStatisDataRet = await getMapFromJson(response.data);
      _mapStatisData = _mapStatisDataRet['data'];
      print('$statisType 网络请求过程正常完成');
    } else {
      throw Exception('$statisType 后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('$statisType 网络请求过程异常e：${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }

  return _mapStatisData;
}

//添加LED字幕
Future<bool> insertLedXsxx(String api, Map map, String text) async {
  //var api = ServicePath.insertLedXsxxUrl;
  print(api);

  try {
    print('开始处理网络请求...');
    Response response;
    Dio dio = Dio();

    map['random'] = RandomBit(6);
    map['sign'] = GenerateMd5(APPkey + map['random']);
    print('map = ${map}');

    response = await dio.post(api, data: map);
    print('response = ${response.toString()}');
    if (response.statusCode == 200) {
      print('$text网络请求过程正常完成');
      return true;
    } else {
      throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('网络请求过程异常e：${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }

  return false;
}

//违章信息审核
Future<bool> auditWzxxData(String api) async {
  //var api = ServicePath.auditWzxxUrl;
  print(api);

  try {
    print('开始处理网络请求...');
    Response response;
    Dio dio = Dio();

    mapAuditWzxxData['random'] = RandomBit(6);
    mapAuditWzxxData['sign'] = GenerateMd5(APPkey + mapAuditWzxxData['random']);
    response = await dio.post(api, data: mapAuditWzxxData);
    print('response = ${response.toString()}');
    //I/flutter ( 1563): {"ret":200,"data":{"code":1},"msg":""}
    //I/flutter ( 5157): {"ret":200,"data":{"code":1},"msg":""}
    if (response.statusCode == 200) {
      print('违章信息${mapHyshlx[hyshlx]['text']}网络请求过程正常完成');
      return true;
    } else {
      throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('网络请求过程异常e：${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }

  return false;
}

//1、获取指定id的推送交警记录列表存入listGetTsjj
Future getTsjjData(int id) async {
  Map _mapGetTsjjGetData = await getWzxxItemData(id); //获取指定id的违章信息返回_mapGetHycsGetData

  print('_mapGetTsjjGetData = ${_mapGetTsjjGetData}');
  print('_mapGetTsjjGetData["yjxx_id"] = ${_mapGetTsjjGetData["yjxx_id"]}');

  return listGetTsjj;
}

//1、获取指定id的抓拍记录列表存入listGetZpjl
//2、如果是黑烟复审，还需获取指定id的违章记录审核信息存入mapGetShenheData
Future getItemData(int id) async {
  Map _mapGetHycsGetData = await getWzxxItemData(id); //获取指定id的违章信息返回_mapGetHycsGetData
  //Unhandled Exception: NoSuchMethodError: The method 'split' was called on null.
  print('_mapGetHycsGetData = ${_mapGetHycsGetData}');
  print('_mapGetHycsGetData["yjxx_id"] = ${_mapGetHycsGetData["yjxx_id"]}');

  //1、获取指定id的抓拍记录列表存入listGetZpjl
  List listID = _mapGetHycsGetData["yjxx_id"].split(",");
  listGetZpjl.clear();
  print('listID = ${listID}');
  print('listGetZpjl = ${listGetZpjl}');

  // listID.forEach((element) async {
  //   await getZpjlData(int.parse(element));  //Unhandled Exception: type 'String' is not a subtype of type 'int'
  // });

  for (var _id in listID) {
    //Unhandled Exception: type 'String' is not a subtype of type 'int'
    await getZpjlData(int.parse(_id)); //获取指定id的抓拍记录数据存入listGetZpjl
  }
  print('listGetZpjl = ${listGetZpjl}');

  //2、如果是黑烟复审、非黑烟查询，还需获取指定id的违章记录审核信息存入 listGetShenheData
  listGetShenheData.clear();
  print('listGetShenheData = ${listGetShenheData}');
  if (hyshlx == 'hyfh' || hyshlx == 'fhycx') {
    await getShenheData(id); //获取指定id的审核信息存入 listGetShenheData
    await getMapGetShenheData(); //从listGetShenheData中取出数据分别存入mapGetHycsShenheData、mapGetHyfhShenheData
  }
  print('listGetShenheData = ${listGetShenheData}');
  print('mapGetHycsShenheData = ${mapGetHycsShenheData}');
  print('mapGetHyfhShenheData = ${mapGetHyfhShenheData}');

  return listGetZpjl;
}

//从listGetShenheData中取出数据分别存入mapGetHycsShenheData、mapGetHyfhShenheData
getMapGetShenheData() async {
  mapGetHycsShenheData.clear(); //黑烟初审信息mapGetHycsShenheData
  mapGetHyfhShenheData.clear(); //黑烟复审信息mapGetHyfhShenheData
  for (var _mapShenheItem in listGetShenheData) {
    //注意：只取符合条件的第一条记录的数据
    //workflow	整型	审核记录所属流程：1-初审，2-复审
    if (_mapShenheItem['workflow'] == 1 && mapGetHycsShenheData.isEmpty) {
      mapGetHycsShenheData = _mapShenheItem;
    } else if (_mapShenheItem['workflow'] == 2 && mapGetHyfhShenheData.isEmpty) {
      mapGetHyfhShenheData = _mapShenheItem;
    }
  }
}

//获取指定id的抓拍记录数据存入listGetZpjl
Future getZpjlData(int id) async {
  var api = ServicePath.getZpjlGetUrl;
  print(api);
  //http://125.64.218.67:9904/docs.php?service=App.Car_Yjxx.Get&detail=1&type=fold

  //listGetZpjl.clear();
  Map _mapZpjlGetData = {};

  print('id = ${id}');
  if (id < 1) {
    print('获取${mapHyshlx[hyshlx]['text']}数据的 id 号不正确！');
    Fluttertoast.showToast(
        msg: '获取${mapHyshlx[hyshlx]['text']}数据的 id 号不正确！', gravity: ToastGravity.CENTER);
  } else {
    try {
      print('开始处理网络请求...');
      Response response;
      Dio dio = Dio();

      String random = RandomBit(6); //flutter （dart）生成N位随机数
      response = await dio.post(api, data: {
        "id": id,
        "sign": GenerateMd5(APPkey + random),
        "random": random,
      });
      print('response = ${response.toString()}');
      //I/flutter ( 5232): {"ret":200,"data":{"items":[],"total":0,"page":1,"perpage":10},"msg":""}
      if (response.statusCode == 200) {
        Map mapZpjlGetDataRet = await getMapFromJson(response.data);
        _mapZpjlGetData = mapZpjlGetDataRet['data'];
        listGetZpjl.add(_mapZpjlGetData);
        print('获取${mapHyshlx[hyshlx]['text']}数据的网络请求过程正常完成');
      } else {
        throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
      }
    } catch (e) {
      print('网络请求过程异常e：${e}');
      Fluttertoast.showToast(
        msg: 'ERROR:======>${e}',
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
      );
    }
  }

  return _mapZpjlGetData;
}

// 获取待审核黑烟车记录
Future getReviewedList() async {
  // 获取违章信息分页列表数据
  // static const String getWzxxGetListUrl = serviceUrl_ybqx + '?s=App.Car_Hyc.GetList';
  var api = ServicePath.getWzxxGetListUrl;
  print(api);
  //http://125.64.218.67:9904/docs.php?service=App.Car_Yjxx.Get&detail=1&type=fold

  try {
    print('开始处理网络请求...');
    Response response;
    Dio dio = Dio();

    String random = RandomBit(6); //flutter （dart）生成N位随机数
    response = await dio.post(api, data: {
      "sign": GenerateMd5(APPkey + random),
      "random": random,
      "qxdm": qx_code, //注意：访问区县后台接口，需要统一添加区县代码参数
      "workflow": 1, // workflow	整型	可选		最小：1	审核状态:1=>待审 | 2=>已初审 | 999=>已复审
      "perpage": 100, // perpage	整型	可选	10	最小：1；最大：100	分页数量
    });
    print('response = ${response.toString()}');
    //I/flutter ( 5232): {"ret":200,"data":{"items":[],"total":0,"page":1,"perpage":10},"msg":""}
    //若访问区县后台接口没有添加"qxdm": qx_code，访问后listReviewed将为null
    //I/flutter ( 1820): response = {"ret":400,"data":{},"msg":"非法请求：缺少必要参数qxdm"}
    if (response.statusCode == 200) {
      Map _mapRet = await getMapFromJson(response.data);
      listReviewed = _mapRet['data']["items"];
      print('获取待审核黑烟车记录的网络请求过程正常完成');
    } else {
      throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('网络请求过程异常e：${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }
}

/////////////////////////////////////////////////////////////////////
//处理审核信息数据

//App.Car_Hyc.GetShenhe
// 获取审核信息
// 接口地址：http://125.64.218.67:9904/?s=App.Car_Hyc.GetShenhe
// 接口文档
// 根据ID获取违章记录的审核记录数据
//
// 接口参数
// 参数名字	类型	是否必须	默认值	其他	说明
// sign	字符串	必须
// random	字符串	必须
// id	字符串	必须		最小：1	违章记录ID
// 返回结果
// 返回字段	类型	说明
// id	整型	审核记录ID
// xid	整型	违章记录ID
// title	字符串	审核结果
// shuoming	字符串	审核意见
// uname	字符串	审核人
// addtime	字符串	审核日期
// workflow	整型	审核记录所属流程：1-初审，2-复审
// 异常情况
// 错误码	错误描述信息
// 400	表示客户端参数错误
// 404	表示接口服务不存在
// 500	表示服务端内部错误

//{
//     "ret": 200,
//     "data": [
//         {
//             "id": 362,
//             "xid": 980,
//             "title": "黑烟车",
//             "shuoming": "黑烟超标，交由交警处罚",
//             "uname": "admin",
//             "addtime": "2021-01-31 16:23:26",
//             "workflow": 2
//         },
//         {
//             "id": 354,
//             "xid": 980,
//             "title": "非黑烟车",
//             "shuoming": "误报，或肉眼无法识别",
//             "uname": "admin",
//             "addtime": "2021-01-31 14:07:42",
//             "workflow": 1
//         }
//     ],
//     "msg": ""
//}

// 同时推送交警
bool fh_hyc = true; //复审为黑烟车
int sfyc = 0; //复审接口增加是否延迟字段 sfyc	整型	必须	是否延误，0-正常 1-延误。延误状态的不推送
bool tsjj = true; //同时推送交警

//hyc为黑烟车拼音首字母缩写，fhyc为非黑烟车拼音首字母缩写
String hyc_shyj = '黑烟超标，交由交警处罚。';
String hyc_text = '黑烟车';
String fhyc_shyj = '误报，或肉眼无法识别。';
String fhyc_text = '非黑烟车';

Map mapGetShenheDataret = {
  "ret": 200,
  "data": [
    {
      "id": 420,
      "xid": 1151,
      "title": "黑烟车",
      "shuoming": "黑烟超标，交由交警处罚",
      "uname": "admin",
      "addtime": "2021-02-05 15:45:32",
      "workflow": 2
    },
    {
      "id": 419,
      "xid": 1151,
      "title": "黑烟车",
      "shuoming": "黑烟超标，交由交警处罚",
      "uname": "admin",
      "addtime": "2021-02-05 15:44:09",
      "workflow": 1
    }
  ],
  "msg": ""
};

//返回字段	类型	说明
// id	整型	审核记录ID
// xid	整型	违章记录ID
// title	字符串	审核结果
// shuoming	字符串	审核意见
// uname	字符串	审核人
// addtime	字符串	审核日期
// workflow	整型	审核记录所属流程：1-初审，2-复审

//黑烟审核信息：
List listGetShenheData = [
  {
    "id": 420,
    "xid": 1151,
    "title": "黑烟车",
    "shuoming": "黑烟超标，交由交警处罚",
    "uname": "admin",
    "addtime": "2021-02-05 15:45:32",
    "workflow": 2
  },
  {
    "id": 419,
    "xid": 1151,
    "title": "黑烟车",
    "shuoming": "黑烟超标，交由交警处罚",
    "uname": "admin",
    "addtime": "2021-02-05 15:44:09",
    "workflow": 1
  }
];

//黑烟初审信息
//workflow	整型	审核记录所属流程：1-初审，2-复审
Map mapGetHycsShenheData = {
  "id": 419,
  "xid": 1151,
  "title": "黑烟车",
  "shuoming": "黑烟超标，交由交警处罚",
  "uname": "admin",
  "addtime": "2021-02-05 15:44:09",
  "workflow": 1
};

//黑烟复审信息
//workflow	整型	审核记录所属流程：1-初审，2-复审
Map mapGetHyfhShenheData = {
  "id": 420,
  "xid": 1151,
  "title": "黑烟车",
  "shuoming": "黑烟超标，交由交警处罚",
  "uname": "admin",
  "addtime": "2021-02-05 15:45:32",
  "workflow": 2
};

//获取指定id的违章记录审核信息存入listGetShenheData
Future getShenheData(int id) async {
  var api = ServicePath.getShenheUrl;
  print(api);
  //http://125.64.218.67:9904/?s=App.Car_Hyc.GetShenhe

  listGetShenheData.clear();
  if (id < 1) {
    print('获取${mapHyshlx[hyshlx]['text']}数据的 id 号不正确！');
    Fluttertoast.showToast(
        msg: '获取${mapHyshlx[hyshlx]['text']}数据的 id 号不正确！', gravity: ToastGravity.CENTER);
  } else {
    try {
      print('开始处理网络请求...');
      Response response;
      Dio dio = Dio();

      print('id = ${id}');
      String random = RandomBit(6); //flutter （dart）生成N位随机数
      response = await dio.post(api, data: {
        "id": id,
        "sign": GenerateMd5(APPkey + random),
        "random": random,
      });
      print('response = ${response.toString()}');
      //response = {"ret":200,"data":[{"id":427,"xid":1171,"title":"非黑烟车","shuoming":"误报，或肉眼无法识别",
      // "uname":"admin","addtime":"2021-02-07 12:43:47","workflow":1}],"msg":""}
      if (response.statusCode == 200) {
        //网络请求过程异常e：type 'List<dynamic>' is not a subtype of type 'Map<dynamic, dynamic>'
        //报错原因：_mapGetShenheDataRet['data']是List类型，而非Map类型
        Map _mapGetShenheDataRet = await getMapFromJson(response.data);
        listGetShenheData = _mapGetShenheDataRet['data'];
        print('获取${mapHyshlx[hyshlx]['text']}数据的网络请求过程正常完成');
        // print('listGetZpjl = ${listGetZpjl}');
        // print('listGetZpjl = ${listGetZpjl[0]}');
      } else {
        throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
      }
    } catch (e) {
      print('网络请求过程异常e：${e}');
      Fluttertoast.showToast(
        msg: 'ERROR:======>${e}',
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
      );
    }
  }

  return listGetShenheData;
}

//违章信息审核
//App.Car_Hyc.Workflow
// 审核数据
// 接口地址：http://125.64.218.67:9904/?s=App.Car_Hyc.Workflow
// 接口文档
// 根据ID审核数据库中的一条纪录数据
//
// 接口参数
// 参数名字	类型	是否必须	默认值	其他	说明
// sign	字符串	必须
// random	字符串	必须
// id	整型	必须		最小：1	ID
// workflow	整型	必须	2	最小：1	审核标记： 2=>初审通过 | 999=>复审通过
// shuoming	字符串	必须			审核意见：如 黑烟超标，交由交警处罚
// title	字符串	必须			审核结果：黑烟车 | 非黑烟车
// uid	整型	必须		最小：1	审核用户ID
// uname	字符串	必须			审核用户账号
// checkid	整型	必须		最小：1	用户选中的作为执法依据的抓拍记录ID
// plate_id	字符串	必须			车牌号
// plate_color	字符串	必须			车牌颜色
// 返回结果
// 返回字段	类型	说明
// code	整型	更新的结果，1表示成功，0表示无更新，false表示失败

Map mapAuditWzxxData = {
  'sign': '',
  'random': '',
  'id': '',
  'workflow': 2,
  'shuoming': '',
  'title': '',
  'uid': -1,
  'uname': '',
  'checkid': -1,
  'plate_id': '',
  'plate_color': '',
  'sfyc': -1,
};

Map getMapAuditWzxxData(
    int _id, int _indexZpjl, int _workflow, String _shuoming, String _title, int sfyc) {
  String random = RandomBit(6); //flutter （dart）生成N位随机数

  mapAuditWzxxData['sign'] = GenerateMd5(APPkey + random);
  mapAuditWzxxData['random'] = random;
  mapAuditWzxxData['id'] = _id.toString();
  mapAuditWzxxData['workflow'] = _workflow;
  mapAuditWzxxData['shuoming'] = _shuoming;
  mapAuditWzxxData['title'] = _title;
  mapAuditWzxxData['uid'] = g_userInfo.mapUserInfoRet['data']['user_id'];
  mapAuditWzxxData['uname'] = g_userInfo.username;
  mapAuditWzxxData['checkid'] = listGetZpjl[_indexZpjl]['id'];
  mapAuditWzxxData['plate_id'] = listGetZpjl[_indexZpjl]['car_number'];
  mapAuditWzxxData['plate_color'] = listGetZpjl[_indexZpjl]['cpys'];
  mapAuditWzxxData['sfyc'] = sfyc;

  return mapAuditWzxxData;
}

//App.Car_Bjxx.Workflow
// 核查处理报警数据
// 接口地址：http://125.64.218.67:9904/?s=App.Car_Bjxx.Workflow
// 接口文档
// 根据ID处理报警数据库中的一条纪录数据
//
// 接口参数
// 参数名字	类型	是否必须	默认值	其他	说明
// sign	字符串	必须
// random	字符串	必须
// id	整型	必须		最小：1	ID
// workflow	整型	必须	2	最小：1	处理标记： 999=>已处理
// shuoming	字符串	必须			处理意见：如 已处理,设备恢复正常
// title	字符串	必须			处理结果：已处理 | 误报
// uid	整型	必须		最小：1	审核用户ID
// uname	字符串	必须			审核用户账号
// 返回结果
// 返回字段	类型	说明
// code	整型	更新的结果，1表示成功，0表示无更新，false表示失败

// 核查处理报警数据函数
// int _sbglID,       //设备管理信息ID
// int _workflow      //workflow	整型	必须	2	最小：1	处理标记： 999=>已处理
// String _shuoming,  //处理意见：如 已处理,设备恢复正常
// String _title      //处理结果：已处理 | 误报
// int _uid	          //审核用户ID
// String _uname	    //审核用户账号
// sbglContentFirstAudit 整型返回值：更新的结果，1表示成功，0表示无更新，false表示失败
Future sbglContentAudit(
    {@required String sbgllx,
    @required int sbglID,
    @required String shuoming,
    @required String title}) async {
  var ret = -1;
  //var api = ServicePath.auditSbbjUrl;
  var api = mapHyshlx[sbgllx]['apiAudit'];
  print('api = $api');
  // api = http://125.64.218.67:9904/?s=App.Car_Bjxx.Workflow

  try {
    print('开始处理网络请求...');
    Response response;
    Dio dio = Dio();

    //准备dio数据结构
    String random = RandomBit(6); //flutter （dart）生成N位随机数
    Map map = {}; //必须初始化，否则报错：Tried calling: []=("sign", "a50d481afb6480e2872529cf8092963d")
    map['sign'] = GenerateMd5(APPkey + random);
    map['random'] = random;
    map['id'] = sbglID;
    map['workflow'] = mapHyshlx[sbgllx]['audit_workflow'];
    map['shuoming'] = shuoming;
    map['title'] = title;
    map['uid'] = g_userInfo.mapUserInfoRet['data']['user_id'];
    map['uname'] = g_userInfo.username;
    print('map =\n${map}');
    //map = {sign: 1eec43fe66b350cb599d915d50806b5d, random: 110567, workflow: 999,
    // shuoming: 已做简单处理。低级故障，不影响系统运行, title: 已处理, uid: 135, uname: admin}

    response = await dio.post(api, data: map);
    //return;
    print('response = ${response.toString()}');
    //response = {"ret":200,"data":{"code":1},"msg":""}
    //response = {"ret":400,"data":{},"msg":"非法请求：缺少必要参数id"}
    //网络请求过程异常e：
    // DioError [DioErrorType.DEFAULT]: NoSuchMethodError: The method 'startsWith' was called on null. Receiver: null

    //code	整型返回值：更新的结果，1表示成功，0表示无更新，false表示失败
    //I/flutter ( 5152): {"ret":200,"data":{"code":1},"msg":""}
    if (response.statusCode == 200) {
      print('${mapHyshlx[hyshlx]['text']}核查处理网络请求过程正常完成');
      Map _mapSbglContentFirstAudit = await getMapFromJson(response.data);
      ret = _mapSbglContentFirstAudit["data"]["code"];
      print('_mapSbglContentFirstAudit["data"]["code"] = ${ret}');
    } else {
      throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('网络请求过程异常e：${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }

  return ret;
}

//Web 处理提交成功：
//service	必须  App.Car_Bjxx.Workflow
// sign	必须    3967eaebec0eed0642a1d395ac9293dd
// random	必须  1003
// id	必须      1209
// workflow	必须  2
// shuoming	必须  黑烟超标，交由交警处罚
// title	必须  黑烟车
// uid	必须  135
// uname	必须  admin
// http://125.64.218.67:9904/
// 200 OK
// cache-control: no-store, no-cache, must-revalidate
// connection: keep-alive
// content-type: application/json;charset=utf-8
// date: Thu, 18 Feb 2021 14:11:37 GMT
// expires: Thu, 19 Nov 1981 08:52:00 GMT
// pragma: no-cache
// server: openresty/1.15.8.3
// transfer-encoding: chunked
// x-powered-by: PHP/7.3.4
//
// {
//     "ret": 200,
//     "data": {
//         "code": 1
//     },
//     "msg": ""
// }

// 黑烟审核提交函数
// int _wzxxID,       //违章信息ID
// int _indexZpjl,    //Zpjl 0基索引
// int _workflow      //workflow	整型	必须	2	最小：1	审核标记： 2=>初审通过 | 999=>复审通过
// String _shuoming,  //审核意见
// String _title      //审核结果：黑烟车 | 非黑烟车
// {bool tsjj = true} //是否推送交警：可选参数，默认为true
// {int sfyc}         //复审接口增加是否延迟字段
// hyshContentFirstAudit整型返回值：-1 表示出现异常，其余为更新结果，1表示成功，0表示无更新，false表示失败;
Future hyshContentFirstAudit(
    int _wzxxID, int _indexZpjl, int _workflow, String _shuoming, String _title,
    {@required int sfyc, bool tsjj = true}) async {
  var ret = -1;
  var api = ServicePath.auditWzxxUrl;
  print(api);
  //I/flutter (19102): http://125.64.218.67:9904/?s=App.Car_Hyc.Workflow

  try {
    print('开始处理网络请求...');
    Response response;
    Dio dio = Dio();

    getMapAuditWzxxData(_wzxxID, _indexZpjl, _workflow, _shuoming, _title, sfyc); //准备dio数据结构

    print('mapAuditWzxxData =\n${mapAuditWzxxData}');
    //mapAuditWzxxData = {sign: 29bc5d7562022c53b7be5771e271a53d, random: 295149, id: 1171,
    // workflow: 999, shuoming: 初审为非黑烟车。复审黑烟超标，交由交警处罚。, title: 黑烟车, ui
    // d: 135, uname: admin, checkid: 1347, plate_id: 川QDS607, plate_color: 蓝色}

    //黑烟初审
    //mapAuditWzxxData = {
    // sign: 1c3c8842e987dff27f7d856d6d47ba18, random: 256171,
    // id: 1189, workflow: 2, shuoming: 黑烟超标，交由交警处罚。, title: 黑烟车,
    // uid: 135, uname: admin, checkid: 1365, plate_id: 云CX2728, plate_color: 蓝色}

    //黑烟复审
    //mapAuditWzxxData = {
    // sign: 5659087c5871e8221b1591eca1f7abd1, random: 795268,
    // id: 1170, workflow: 999, shuoming: 初审为黑烟车。复审黑烟超标，交由交警处罚。, title: 黑烟车,
    // uid: 135, uname: admin, checkid: 1345, plate_id: 川15C0895, plate_color: 蓝色}

    //return false;

    response = await dio.post(api, data: mapAuditWzxxData);
    print('response = ${response.toString()}');
    //response = {"ret":200,"data":{"code":1},"msg":""}
    //response = {"ret":200,"data":{"code":1},"msg":""}

    //code	整型	更新的结果，1表示成功，0表示无更新，false表示失败
    //I/flutter ( 5152): {"ret":200,"data":{"code":1},"msg":""}
    if (response.statusCode == 200) {
      print('违章信息${mapHyshlx[hyshlx]['text']}网络请求过程正常完成');
      Map _maphyshContentFirstAuditRet = await getMapFromJson(response.data);
      ret = _maphyshContentFirstAuditRet["data"]["code"];
      print('App.Car_Hyc.Workflow返回值中的code	整型	更新的结果，1表示成功，0表示无更新，false表示失败');
      print('_maphyshContentFirstAuditRet["data"]["code"] = ${ret}');
    } else {
      throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('网络请求过程异常e：${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }

  return ret;
}

//处理审核信息数据
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
//向交警服务器推送数据-模块数据

//推送交警操作函数
Future tsjjFun(int _wzxxID, String _plateAndID) async {
  String ret = '';
  //var ret = -1;//这样会报错：type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'int'
  //推送交警操作函数步骤，注意：
  // 推送交警1、等待5秒，重新读取指定ID的违章信息记录返回_mapGetHycsGetData。因为在复审提交后，可能用户修改了审核结果，所以必须重新延时读取
  //           在 tsjjFun(int _wzxxID) 函数中，调用 _mapGetHycsGetData = getWzxxItemData(_wzxxID); 函数实现
  print('before getWzxxItemData(_wzxxID)');
  getWzxxItemData(_wzxxID).then((_mapGetHycsGetData) async {
    //OK
    //return -1;

    // 推送交警2、第一方面的条件：需要审核状态workflow=999、sfhy(是否黑烟)=黑烟车、且tsjj为真时才允许推送
    //           在 tsjjFun(int _wzxxID) 函数中，用 if (_mapGetHycsGetData['workflow'] == 999 && _mapGetHycsGetData['sfhy'] == hyc_text) 实现
    print('_mapGetHycsGetData = ${_mapGetHycsGetData}');
    print('_mapGetHycsGetData[\'workflow\'] == 999 ： ${_mapGetHycsGetData['workflow'] == 999}');
    print('_mapGetHycsGetData[\'sfhy\'] == hyc_text ： ${_mapGetHycsGetData['sfhy'] == hyc_text}');
    //I/flutter (16661): _mapGetHycsGetData = {id: 1220, plate_id: 川Q565H4, plate_color: 蓝色, zpsj: 1612852562, yjxx_id: 1396, workflow: 999, video_url: video/5_6063_20210209_143
    // 602_川Q565H4.mp4, pic_url: /wwwroot/admin/Api/wwwroot/public/uploads/110012f894b695f4586e23497ff4dc69.jpg, clfl: 集装箱卡车, dwip: 172.16.3.5, dwms: 叙州区柏溪收费站出城方向,
    //  lgmzs: 3, jczxd: 854, sfhy: 黑烟车}
    // I/flutter (16661): _mapGetHycsGetData['workflow'] == 999 ： true
    // I/flutter (16661): _mapGetHycsGetData['sfhy'] == hyc_text ： true

    if (_mapGetHycsGetData['workflow'] == 999 && _mapGetHycsGetData['sfhy'] == hyc_text) {
      print('开始执行：tsjjGetTsStatus(_wzxxID)');
      //I/flutter (16661): 开始执行：tsjjGetTsStatus(_wzxxID)

      // 获取推送交警状态信息
      // tsjjGetTsStatus返回字段	类型	说明
      // id	整型	违章记录ID
      // checkid	整型	推送的抓拍记录ID
      // tszt	整型	推送状态：0-未推送 | 1-推送失败 | 3-推送成功
      // ts_time	字符串	推送时间
      //Future tsjjGetTsStatus(int _wzxxID)
      Map mapTsjjGetTsStatus = await tsjjGetTsStatus(_wzxxID);

      // 推送交警3、第二方面的条件：推送前还需查询违章记录推送状态，未推送、或推送失败的才进行推送
      //           在 tsjjFun(int _wzxxID) 函数中，调用 mapTsjjGetTsStatus = await tsjjGetTsStatus(_wzxxID); 函数实现
      //_mapTsjjUpftpRet["data"] = {id: 1220, checkid: 1396, tszt: 0, ts_time: null}
      if (0 == mapTsjjGetTsStatus['tszt'] || 1 == mapTsjjGetTsStatus['tszt']) {
        // 推送交警4、符合上面两个方面的条件后，再开始向交警服务器推送数据操作
        //           在 tsjjFun(int _wzxxID) 函数中，调用 _mapTsjjUpftp = await tsjjUpftp(_wzxxID, mapTsjjGetTsStatus['checkid']); 函数实现
        //向交警服务器推送数据
        //返回值为Map，mapRet['msg']为字符串：推送成功 | 推送失败 | 服务器连接失败，mapRet['ts_time']为推送完成时间戳秒数字符串
        String _ftpdir = getFtpdir_YYYYMMDD(_mapGetHycsGetData['zpsj']);
        print('_ftpdir = $_ftpdir');

        //tsjjUpftp执行很慢，需要几十秒钟，需要显示等待中的圈圈
        Map _mapTsjjUpftp = await tsjjUpftp(_wzxxID, _ftpdir);
        print('_mapTsjjUpftp = $_mapTsjjUpftp');
        //I/flutter (24008): _mapTsjjUpftp = {msg: 推送成功, ts_time: 1614600887}
        //I/flutter (30430): _mapTsjjUpftp = {msg: 服务器连接失败, ts_time: 1613049849}
        //return -1;

        //_mapTsjjUpftp = {msg: 推送成功, ts_time: 1612858030}

        // 推送交警5、推送完成后，不论成功失败，都需要调用回写接口，把推送状态回写入数据库。
        // 推送本身的上传图片和文件FTP是由接口完成，完成后会返回一个msg，说明是成功还是失败。
        //           调用 var ret = await tsjjFtpUptszt(_wzxxID, _mapTsjjUpftp['msg'], _mapTsjjUpftp['ts_time']); 函数实现
        //回写推送交警状态。整型返回值表示更新的结果，1表示成功，0表示无更新，false表示失败
        //_mapTsjjUpftp = {msg: 推送成功, ts_time: 1612858030}

        ret = _mapTsjjUpftp['msg'];
        var ret2 = await tsjjFtpUptszt(_wzxxID, _mapTsjjUpftp['msg'], _mapTsjjUpftp['ts_time']);
        print('tsjjFtpUptszt_ret2 = $ret2');
        //I/flutter (30430): tsjjFtpUptszt_ret = 1
        //return -1;

        //返回字符串msg：推送成功 | 推送失败 | 服务器连接失败
        String retTsjjFun = '';
        if (null != ret && ret.indexOf('成功') > -1) {
          retTsjjFun = _plateAndID + ' 推送交警成功！';
        } else {
          retTsjjFun = _plateAndID + ' 推送交警失败。';
        }

        eventBus.fire(HycsDataUpdateEvent('${mapHyshlx[hyshlx]['text']}数据已更新'));

        print('after tsjjFun(widget.id)，retTsjjFun = $retTsjjFun');
        Fluttertoast.showToast(msg: retTsjjFun, gravity: ToastGravity.CENTER);
      }
    }
  });
  print('after getWzxxItemData(_wzxxID)');

  //推送交警操作函数 tsjjFun 整型返回值。-1 表示推送失败；其余表示 tsjjFtpUptszt 函数的更新结果，1表示成功，0表示无更新，false表示失败
  return ret;
}

//App.Car_Hyc.GetTs
// 获取推送状态信息
// 接口地址：http://125.64.218.67:9904/?s=App.Car_Hyc.GetTs
// 接口文档
// 根据ID获取违章记录的推送交警服务器状态
//
// 接口参数
// 参数名字	类型	是否必须	默认值	其他	说明
// sign	字符串	必须
// random	字符串	必须
// id	字符串	必须		最小：1	违章记录ID
// 返回结果
// 返回字段	类型	说明
// id	整型	违章记录ID
// checkid	整型	推送的抓拍记录ID
// tszt	整型	推送状态：0-未推送 | 1-推送失败 | 3-推送成功
// ts_time	字符串	推送时间
// 异常情况
// 错误码	错误描述信息
// 400	表示客户端参数错误
// 404	表示接口服务不存在
// 500	表示服务端内部错误

// 推送交警2、第二方面的条件：推送前还需查询违章记录推送状态，未推送、或推送失败的才进行推送
//           在 hyshContentFirstAudit() 函数中调用 tsjjGetTsStatus(_wzxxID) 函数实现
// 获取推送交警状态信息
// tsjjGetTsStatus返回字段	类型	说明
// id	整型	违章记录ID
// checkid	整型	推送的抓拍记录ID
// tszt	整型	推送状态：0-未推送 | 1-推送失败 | 3-推送成功
// ts_time	字符串	推送时间
Future tsjjGetTsStatus(int _wzxxID) async {
  var ret;
  Map _mapTsjjGetTsStatusRet = {'msg': ''};
  var api = ServicePath.tsjjGetTsStatus; //获取推送交警状态信息;
  print(api);

  print('id = ${_wzxxID}');
  if (_wzxxID < 1) {
    ret = '获取${mapHyshlx[hyshlx]['text']}数据的 id 号不正确！';
    print(ret);
    Fluttertoast.showToast(msg: ret, gravity: ToastGravity.CENTER);
    return;
  } else {
    try {
      print('开始处理网络请求...');
      Response response;
      Dio dio = Dio();

      String random = RandomBit(6); //flutter （dart）生成N位随机数
      print('random = ${random}');
      print('response = ${response}'); //I/flutter (16661): response = null

      response = await dio.post(api, data: {
        "id": _wzxxID,
        "sign": GenerateMd5(APPkey + random),
        "random": random,
      });
      print('_wzxxID = ${_wzxxID}');
      print('response = ${response.toString()}');
      //response = {"ret":200,"data":{"id":1220,"checkid":1396,"tszt":0,"ts_time":null},"msg":""}

      if (response.statusCode == 200) {
        _mapTsjjGetTsStatusRet = await getMapFromJson(response.data);

        //msg	字符串	msg的值为：推送成功 | 推送失败 | 服务器连接失败
        print('App.Car_Hyc.GetTs返回值中的tszt字段	整型	推送状态：0-未推送 | 1-推送失败 | 3-推送成功');
        ret = _mapTsjjGetTsStatusRet["data"];
        print('_mapTsjjUpftpRet["data"] = ${ret}');
        //_mapTsjjUpftpRet["data"] = {id: 1220, checkid: 1396, tszt: 0, ts_time: null}

        print('获取${mapHyshlx[hyshlx]['text']}数据的网络请求过程正常完成');
      } else {
        throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
      }
    } catch (e) {
      print('网络请求过程异常e：${e}');
      Fluttertoast.showToast(
        msg: 'ERROR:======>${e}',
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
      );
    }
  }

  print('tsjjGetTsStatus($_wzxxID).ret = ${ret}');

  return ret;
}

//App.Car_Ftp.Upftp
// 上传FTP
// 接口地址：http://125.64.218.67:9904/?s=App.Car_Ftp.Upftp
// 接口文档
// 向交警服务器推送数据
//
// 接口参数
// 参数名字	类型	是否必须	默认值	其他	说明
// sign	字符串	必须
// random	字符串	必须
// id	字符串	必须		最小：1	抓拍记录ID，注意这里是提交违章记录中checkid字段
// ftpdir	字符串	必须			上传目录,为checkid记录的抓拍时间，格式为4位年+2位月+2位日，如：20210208
// 返回结果
// 返回字段	类型	说明
// msg	字符串	msg的值为：推送成功 | 推送失败 | 服务器连接失败
// 异常情况
// 错误码	错误描述信息
// 400	表示客户端参数错误
// 404	表示接口服务不存在
// 500	表示服务端内部错误
//

// 推送交警3、符合上面两个方面的条件后，再进行向交警服务器推送数据操作
//           调用 tsjjUpftp(_wzxxID, _indexZpjl) 函数实现
// 向交警服务器推送数据
//返回值为Map，mapRet['msg']为字符串：推送成功 | 推送失败 | 服务器连接失败，mapRet['ts_time']为推送完成时间戳秒数字符串
Future<Map> tsjjUpftp(int _wzxxID, String _ftpdir) async {
  Map mapRet = {'msg': 'test'};
  var api = ServicePath.tsjjFtpUpftpUrl;
  print(api); // http://125.64.218.67:9904/?s=App.Car_Ftp.Upftp

  print('_wzxxID = ${_wzxxID}'); //_wzxxID = 1220
  if (_wzxxID < 1) {
    mapRet['msg'] = '获取${mapHyshlx[hyshlx]['text']}数据的 id 号不正确！';
    print(mapRet['msg']);
    Fluttertoast.showToast(msg: mapRet['msg'], gravity: ToastGravity.CENTER);
  } else {
    try {
      print('开始处理网络请求...');
      Response response;
      Dio dio = Dio();

      String random = RandomBit(6); //flutter （dart）生成N位随机数
      print('random = ${random}');
      print('response = ${response}'); //I/flutter (16661): response = null
      print('ftpdir = $_ftpdir'); //I/flutter (22207): ftpdir = 20210209

      // ftpdir	字符串	必须			上传目录,为checkid记录的抓拍时间，格式为4位年+2位月+2位日，如：20210208
      response = await dio.post(api, data: {
        "id": _wzxxID,
        'ftpdir': _ftpdir,
        "sign": GenerateMd5(APPkey + random),
        "random": random,
      });
      print('_wzxxID = ${_wzxxID}');
      print(
          'response = ${response.toString()}'); //response = {"ret":200,"data":{"msg":"推送成功"},"msg":""}
      //{
      //     "ret": 200,
      //     "data": {
      //         "msg": "推送成功"
      //     },
      //     "msg": ""
      // }
      if (response.statusCode == 200) {
        Map _mapTsjjUpftpRet = await getMapFromJson(response.data);

        //msg	字符串	msg的值为：推送成功 | 推送失败 | 服务器连接失败
        print('App.Car_Ftp.Upftp返回值中的msg	字符串	msg的值为：推送成功 | 推送失败 | 服务器连接失败');
        print('_mapTsjjUpftpRet = ${_mapTsjjUpftpRet}');
        mapRet['msg'] = _mapTsjjUpftpRet["data"]["msg"];

        print('获取${mapHyshlx[hyshlx]['text']}数据的网络请求过程正常完成');
      } else {
        throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
      }
    } catch (e) {
      print('网络请求过程异常e：${e}');
      //I/flutter (16661): 网络请求过程异常e：RangeError (index): Invalid value: Only valid value is 0: 1396
      mapRet['msg'] = e.toString();
      Fluttertoast.showToast(
        msg: 'ERROR:======>${e}',
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
      );
    }
  }
  //print('DateTimeNowSecnods = ${_dateTime_now.millisecondsSinceEpoch}');
  //print('DateTimeNowSecnods = ${_dateTime_now.millisecondsSinceEpoch / 1000}');
  ////I/flutter ( 4010): DateTimeNowSecnods = 1612857524906
  ////I/flutter ( 4010): DateTimeNowSecnods = 1612857524.906
  //~ 取整操作符
  mapRet['ts_time'] =
      (DateTime.now().millisecondsSinceEpoch ~/ 1000).toString(); //获取App.Car_Ftp.Upftp推送完成时间
  print('mapRet = ${mapRet}');
  //mapRet = {msg: 推送成功, ts_time: 1612858030}
  //mapRet = {msg: 推送成功, ts_time: 1612857648.202}
  //mapRet = {msg: 推送成功, ts_time: 7}
  //I/flutter (16661): mapRet = {msg: RangeError (index): Invalid value: Only valid value is 0: 1396, ts_time: 38}

  //I/flutter (30430): mapRet = {msg: 服务器连接失败, ts_time: 1613049849}

  return mapRet;
}

//App.Car_Ftp.Uptszt
// 更新推送状态
// 接口地址：http://125.64.218.67:9904/?s=App.Car_Ftp.Uptszt
// 接口文档
// 根据ID更新违章记录数据库中的推送状态
//
// 接口参数
// 参数名字	类型	是否必须	默认值	其他	说明
// sign	字符串	必须
// random	字符串	必须
// id	整型	必须		最小：1	违章记录ID
// tszt	整型	必须	2	最小：0	推送状态： 0=>未推送 | 1=>推送失败 | 2=>推送成功
// ts_time	字符串	必须			推送时间,时间戳格式
// 返回结果
// 返回字段	类型	说明
// code	整型	更新的结果，1表示成功，0表示无更新，false表示失败
// 异常情况
// 错误码	错误描述信息
// 400	表示客户端参数错误
// 404	表示接口服务不存在
// 500	表示服务端内部错误

//必须是tsjjGetTsStatus(1221).ret = {id: 1221, checkid: 1398, tszt: 0, ts_time: null}中，
// ts_time: null才能使用tsjjFtpUptszt成功回写，否则回写无更新
Map mapTsjjFtpUptsztRet = {
  "ret": 200,
  "data": {"code": 1},
  "msg": ""
};

//{
//     "ret": 200,
//     "data": {
//         "code": 0
//     },
//     "msg": ""
// }

// 推送交警4、推送完成后，不论成功失败，都需要调用回写接口，把推送状态回写入数据库。
// 推送本身的上传图片和文件FTP是由接口完成，完成后会返回一个msg，说明是成功还是失败。
//           调用 函数实现
//回写推送交警状态。整型返回值表示更新的结果，1表示成功，0表示无更新，false表示失败
//mapTsjjUpftp = {msg: 推送成功, ts_time: 1612858030}
Future tsjjFtpUptszt(int _wzxxID, String _tszt, String _ts_time) async {
  var ret;
  Map _mapTsjjUptsztRet = {'msg': ''};
  var api = ServicePath.tsjjFtpUptsztUrl; //回写推送交警状态
  print(api); //I/flutter (22207): http://125.64.218.67:9904/?s=App.Car_Ftp.Uptszt

  //tszt	整型	必须	2	最小：0	推送状态： 0=>未推送 | 1=>推送失败、或服务器连接失败 | 2=>推送成功
  Map mapTszt = {
    '未推送': 0,
    '服务器连接失败': 1,
    '推送失败': 1,
    '推送成功': 2,
  };

  int _intTszt = 1;
  if (mapTszt.containsKey(_tszt)) {
    _intTszt = mapTszt[_tszt];
  }

  print('id = ${_wzxxID}'); //_wzxxID = 1210
  if (_wzxxID < 1) {
    ret = '获取${mapHyshlx[hyshlx]['text']}数据的 id 号不正确！';
    print(ret);
    Fluttertoast.showToast(msg: ret, gravity: ToastGravity.CENTER);
  } else {
    try {
      print('开始处理网络请求...');
      Response response;
      Dio dio = Dio();

      String random = RandomBit(6); //flutter （dart）生成N位随机数
      print('random = ${random}');
      print('response = ${response}');

      Map _mapDio = {
        "id": _wzxxID,
        'tszt': _intTszt,
        'ts_time': _ts_time,
        "sign": GenerateMd5(APPkey + random),
        "random": random,
      };
      print('_mapDio = ${_mapDio}');
      //_mapDio = {id: 1210, tszt: 2, ts_time: 1612858409, sign: 2212446404dcb8cb07f2476dcd8f9480, random: 455071}
      //_mapDio = {id: 1222, tszt: 0, ts_time: 1613052700, sign: eaeec0973a86d6522fcecd175e07f106, random: 228812}

      response = await dio.post(api, data: _mapDio);
      print('_wzxxID = ${_wzxxID}');
      print('response = ${response.toString()}');
      //I/flutter (25617): response = {"ret":200,"data":{"code":1},"msg":""}
      // response = {"ret":500,"data":{},"msg":"服务器运行错误: Api::$shuoming undefined"}

      //I/flutter ( 5232): {"ret":200,"data":{"items":[],"total":0,"page":1,"perpage":10},"msg":""}
      if (response.statusCode == 200) {
        _mapTsjjUptsztRet = await getMapFromJson(response.data);

        //code	整型	更新的结果，1表示成功，0表示无更新，false表示失败
        print('App.Car_Ftp.Uptszt返回值中的code	整型	更新的结果，1表示成功，0表示无更新，false表示失败');
        print('_mapTsjjUptsztRet = ${_mapTsjjUptsztRet}');
        ret = _mapTsjjUptsztRet["data"]["code"];

        print('获取${mapHyshlx[hyshlx]['text']}数据的网络请求过程正常完成');
      } else {
        throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
      }
    } catch (e) {
      print('网络请求过程异常e：${e}');
      Fluttertoast.showToast(
        msg: 'ERROR:======>${e}',
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
      );
    }
  }

  return ret;
}

// 向交警服务器推送数据-模块数据
/////////////////////////////////////////////////////////////////////

// Map _mapGetHycsGetData = {};
// Map _mapGetHycsGetDataRet = {
//     "ret": 200,
//     "data": {
//         "id": 1221,
//         "plate_id": "云CY4502",
//         "plate_color": "蓝色",
//         "zpsj": 1612856589,
//         "yjxx_id": "1398",
//         "workflow": 999,
//         "video_url": "video/4_6063_20210209_154309_云CY4502.mp4",
//         "pic_url": "/wwwroot/admin/Api/wwwroot/public/uploads/2ec53c6879c3143bbd8471451be734f6.jpg",
//         "clfl": "渣土车",
//         "dwip": "172.16.3.4",
//         "dwms": "叙州区一曼路出城方向",
//         "lgmzs": 3,
//         "jczxd": "983",
//         "sfhy": "黑烟车"
//     },
//     "msg": ""
// };

//获取指定id的违章信息返回_mapGetHycsGetData
Future getWzxxItemData(int id) async {
  var api = ServicePath.getWzxxGetDataUrl;
  print(api);
  //I/flutter (16661): http://125.64.218.67:9904/?s=App.Car_Hyc.Get

  Map _mapGetHycsGetData = {};
  print('id = ${id}');
  if (id < 1) {
    print('获取${mapHyshlx[hyshlx]['text']}数据的 id 号不正确！');
    Fluttertoast.showToast(
        msg: '获取${mapHyshlx[hyshlx]['text']}数据的 id 号不正确！', gravity: ToastGravity.CENTER);
  } else {
    try {
      print('开始处理网络请求...');
      Response response;
      Dio dio = Dio();

      String random = RandomBit(6); //flutter （dart）生成N位随机数
      print('random = ${random}');
      print('response = ${response}');
      print('sign = ${GenerateMd5(APPkey + random)}');
      //I/flutter (16661): response = null

      response = await dio.post(api, data: {
        "id": id,
        "sign": GenerateMd5(APPkey + random),
        "random": random,
      });
      print('id = ${id}');
      print('response = ${response.toString()}');
      //I/flutter (16661): response = {"ret":200,"data":{
      //  "id":1211,"plate_id":"川Q023Y2","plate_color":"蓝色","zpsj":1612840361,"yjxx_id":"1387","workflow":999,
      //  "video_url":"video/3_6063_20210209_111241_川Q023Y2.mp4",
      //  "pic_url":"/wwwroot/admin/Api/wwwroot/public/uploads/c43286bf381af0a393b44272829d1f07.jpg","clfl":"集装箱卡车",
      //  "dwip":"172.16.3.3","dwms":"宜宾市翠屏南收费站出城方向","lgmzs":3,"jczxd":"876","sfhy":"黑烟车"
      //},"msg":""}

      if (response.statusCode == 200) {
        Map _mapGetHycsGetDataRet = await getMapFromJson(response.data);
        _mapGetHycsGetData = _mapGetHycsGetDataRet['data'];
        print('获取${mapHyshlx[hyshlx]['text']}数据的网络请求过程正常完成');
        print('_mapGetHycsGetData = ${_mapGetHycsGetData}');
        //I/flutter (16661): _mapGetHycsGetData = {
        // id: 1217, plate_id: 川QFX088, plate_color: 蓝色, zpsj: 1612847361, yjxx_id: 1393, workflow: 999,
        // video_url: video/3_6063_20210209_130921_川QFX088.mp4,
        // pic_url: /wwwroot/admin/Api/wwwroot/public/uploads/c227c65bcaadcdf53094c5448c2460ce.jpg,
        // clfl: 面包车, dwip: 172.16.3.3, dwms: 宜宾市翠屏南收费站出城方向, lgmzs: 3, jczxd: 992, sfhy: 黑烟车
        //}
      } else {
        throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
      }
    } catch (e) {
      print('网络请求过程异常e：${e}');
      Fluttertoast.showToast(
        msg: 'ERROR:======>${e}',
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
      );
    }
  }

  return _mapGetHycsGetData;
}

//	App.Car_Hyc.GetList
// 根据审核状态获取分页列表数据
// 接口地址：http://125.64.218.67:9904/?s=App.Car_Hyc.GetList
// 接口文档
// 根据审核状态筛选列表数据，支持分页
//
// 接口参数
// 参数名字	类型	是否必须	默认值	其他	说明
// sign	字符串	必须
// random	字符串	必须
// workflow	整型	可选	1	最小：1	审核状态:1=>待审 | 2=>已初审 | 999=>已复审
// sfhy	字符串	可选	黑烟车		是否黑烟车:黑烟车|非黑烟车
// page	整型	可选	1	最小：1	第几页
// perpage	整型	可选	10	最小：1；最大：20	分页数量
// 返回结果
// 返回字段	类型	说明
// items	字符串	列表数据，列表字段请参考get接口
// total	整型	总数量
// page	整型	当前第几页
// perpage	整型	每页数量

//dart是值传递
int iPage = 0;
//perpage应该小于等于100
///从接口 mapHyshlx[hyshlx]['api'] 获取第 iPage 页的列表数据，返回 list
Future getPageList({int perpage = 20, String theHyshlx = '', bool bShowToast = true}) async {
  //从网络获取所有违章数据
  iPage++;

  List list = await getThePageList(
      theHyshlx: theHyshlx, page: iPage, perpage: perpage, bShowToast: bShowToast);

  return list;
}

///从接口 mapHyshlx[theHyshlx]['api'] 获取指定类型第 page 页的列表数据，返回 list
Future getThePageList(
    {String theHyshlx = '', int page = 1, int perpage = 20, bool bShowToast = true}) async {
  List list = [];
  if (theHyshlx.isEmpty) {
    theHyshlx = hyshlx;
  }

  try {
    print('开始处理网络请求...');
    Response response;
    Dio dio = Dio();

    String random = RandomBit(6); //flutter （dart）生成N位随机数
    Map map = {
      "page": page,
      "perpage": perpage,
      "sign": GenerateMd5(APPkey + random),
      "random": random,
    };

    int i = 1;
    print('theHyshlx${i++} = $theHyshlx');
    //增加了一个查询字段 是否黑烟：sfhy	字符串	可选	黑烟车		是否黑烟车:黑烟车|非黑烟车，为空则全部
    if (mapHyshlx[theHyshlx].containsKey('sfhy')) {
      map['sfhy'] = mapHyshlx[theHyshlx]['sfhy'];
    }

    print('theHyshlx${i++} = $theHyshlx');
    if (mapHyshlx[theHyshlx]['get_workflow'] > 0) {
      map['workflow'] = mapHyshlx[theHyshlx]['get_workflow'];
    }

    print('theHyshlx${i++} = $theHyshlx');
    //设备类型
    if (mapHyshlx[theHyshlx].containsKey('sblx')) {
      map['sblx'] = mapHyshlx[theHyshlx]['sblx'];
    }

    //注意：访问区县后台接口，需要统一添加区县代码参数
    map['qxdm'] = qx_code;

    print('mapHyshlx[theHyshlx][api] = ${mapHyshlx[theHyshlx]['api']}');
    // mapHyshlx[theHyshlx][api] = http://125.64.218.67:9904/?s=App.Car_Hyc.GetList
    print('map = ${map}');
    response = await dio.post(mapHyshlx[theHyshlx]['api'], data: map);
    print('response = ${response.toString()}');
    // I/flutter (16869): mapHyshlx[theHyshlx][api] = http://125.64.218.67:9909?s=App.Car_Hyc.GetList
    // I/flutter (16869): map = {page: 1, perpage: 100, sign: ff2b4ea7283c2a2dd86ab665c5fe0f0f, random: 763117, workflow: 1}
    // I/flutter (16869): response = {"ret":400,"data":{},"msg":"非法请求：缺少必要参数qxdm"}

    //I/flutter ( 5232): {"ret":200,"data":{"items":[],"total":0,"page":1,"perpage":10},"msg":""}
    if (response.statusCode == 200) {
      //mapGetWzxxGetListRet = await getMapFromJson(response.data);
      Map mapGetData = await getMapFromJson(response.data);
      print(mapGetData.toString());
      //第一次必须先进行listWzxxGetList2.clear()，否则addAll报错终止
      print('mapGetData[' 'data' '][' 'items' '].length = ${mapGetData['data']['items'].length}');
      if (page > 1 && bShowToast && 0 == mapGetData['data']['items'].length) {
        Fluttertoast.showToast(
          msg: '没有更多了！',
          toastLength: Toast.LENGTH_SHORT,
          gravity: ToastGravity.CENTER,
        );
      } else {
        //listWzxxGetList2.addAll(mapGetData['data']['items']);
        list = mapGetData['data']['items'];
        //eventBus.fire(new WzxxDataUpdateEvent('违章信息数据已更新'));
        //eventBus.fire(dataUpdateEvent);
      }
      //网络请求过程异常e：${e}type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'Iterable<dynamic>'
      print('网络请求过程正常完成');
    } else {
      throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('网络请求过程异常e：${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }

  return list;
}

///点位视频播放相关函数
Future playUrl({@required int index, String url, BuildContext context}) {
  urlnew = url;
  // var ret = Navigator.of(context).push(MaterialPageRoute(
  //     builder: (context) => PlayerProNew(
  //           id: index + 1,
  //           url: urlnew,
  //           title: '点位视频\n${(index + 1)}、${listDwinfoGetList2[index]['dwmc']}',
  //         )));
  var ret = Navigator.of(context).push(MaterialPageRoute(
      builder: (context) => SuperPlayerPage(
            id: index + 1,
            dwip: listDwinfoGetList2[index]['dwip'],
            url: urlnew,
            title: '点位视频\n${(index + 1)}、${listDwinfoGetList2[index]['dwmc']}',
          )));

  print('ret = $ret');
  //正在获取点位视频标志，禁止重入
  getingDwVideo = false;

  //标注正在获取点位视频的记录
  getingIndex = -1;
  print('_getingIndex = $getingIndex');
  eventBus.fire(DwspUpdateEvent('点位视频信息数据更新广播'));

  return ret;
}

int getCurrentTiem() {
  return DateTime.now().millisecondsSinceEpoch ~/ 1000;
}

///直接获取点位视频（Dwsp）播放地址，并开始播放
Future getDwspUrlNew(
    {@required int indexRecord, String theSbgllx = 'dwsp', BuildContext context}) async {
  print('\n --- getingDwVideo = $getingDwVideo --- \n');
  //正在获取点位视频标志，禁止重入
  if (getingDwVideo) {
    Fluttertoast.showToast(
      msg: '正在后台获取 $getingDwmc 点位视频地址，请稍后重试',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
    return '';
  }

  //标注正在获取点位视频的记录
  // eventBus.fire(DwspUpdateEvent('点位视频信息数据更新广播'));

  getingDwVideo = true;
  // getingDwmc = '${(indexRecord + 1)}、${listDwinfoGetList2[indexRecord]['dwmc']}'; //正在获取视频的点位名称
  print('getDwspUrlNew indexRecord = ${indexRecord}');
  // print('listDwinfoGetList2 = ${listDwinfoGetList2}');
  getingDwmc =
      '${listDwinfoGetList2[indexRecord]['id']}、${listDwinfoGetList2[indexRecord]['dwmc']}'; //正在获取视频的点位名称
  print('\n --- 正在后台获取 $getingDwmc 点位视频地址 --- \n');
  print('\n --- getingDwVideo = $getingDwVideo --- \n');

  //MediaQueryData.fromWindow(window).padding.top //这个就是状态栏的高度
  //ScreenUtil().statusBarHeight  //状态栏高度 刘海屏会更高  单位dp
  // print('ScreenUtil().statusBarHeight = ${ScreenUtil().statusBarHeight}');
  // getSumTime = getCurrentTiem();
  // MyDelayToast(
  //     context: context,
  //     showTime: 30,
  //     top: ScreenUtil().statusBarHeight + 2.5,
  //     left: ScreenUtil().screenWidth - 80 - 2.5);

  print('listDwspGetList2 = ${listDwspGetList2}');
  print('indexRecord = ${indexRecord}');
  String _dwspUrl = '';
  if (null != listDwspGetList2[indexRecord]['play_urlhead']) {
    _dwspUrl =
        listDwspGetList2[indexRecord]['play_urlhead'] + listDwspGetList2[indexRecord]['video16'];
    print('开始播放：第$getCount次成功获取的视频地址');
  }

  print('判断_dwspUrl是否是视频地址？');
  print('_dwspUrl ： ${_dwspUrl}');
  if (!isVideoUrl(_dwspUrl)) {
    Fluttertoast.showToast(
      msg: '获取 $getingDwmc 点位视频地址失败，请稍后重试。',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
    //正在获取点位视频标志，禁止重入
    getingDwVideo = false;
  } else {
    print('开始播放视频地址');
    playUrl(index: indexRecord, url: _dwspUrl, context: context);
  }

  //不能放到此处，此处不会等待，将导致禁止重入失败
  //正在获取点位视频标志，禁止重入
  //getingDwVideo = false;

  //print('失败：$getCount次获取的视频地址都失败！');
  return _dwspUrl;
}

///得到点位视频（Dwsp）播放地址，用插件 http: ^0.12.2
// Future getDwspUrl({@required int index, String theSbgllx = 'dwsp', BuildContext context}) async {
//   print('\n --- getingDwVideo = $getingDwVideo --- \n');
//   //正在获取点位视频标志，禁止重入
//   if (getingDwVideo) {
//     Fluttertoast.showToast(
//       msg: '正在后台获取 $getingDwmc 点位视频地址，请稍后重试',
//       toastLength: Toast.LENGTH_SHORT,
//       gravity: ToastGravity.CENTER,
//     );
//     return '';
//   }
//
//   //标注正在获取点位视频的记录
//   getingIndex = index;
//   print('_getingIndex = $getingIndex');
//   eventBus.fire(DwspUpdateEvent('点位视频信息数据更新广播'));
//
//   getingDwVideo = true;
//   getingDwmc = '${(index + 1)}、${listDwinfoGetList2[index]['dwmc']}'; //正在获取视频的点位名称
//   print('\n --- 正在后台获取 $getingDwmc 点位视频地址 --- \n');
//   print('\n --- getingDwVideo = $getingDwVideo --- \n');
//
//   String _dwspUrl;
//   getCount = 1;
//
//   //MediaQueryData.fromWindow(window).padding.top //这个就是状态栏的高度
//   //ScreenUtil().statusBarHeight  //状态栏高度 刘海屏会更高  单位dp
//   print('ScreenUtil().statusBarHeight = ${ScreenUtil().statusBarHeight}');
//   getSumTime = getCurrentTiem();
//   MyDelayToast(
//       context: context,
//       showTime: 30,
//       top: ScreenUtil().statusBarHeight + 2.5,
//       left: ScreenUtil().screenWidth - 80 - 2.5);
//
//   print('开始第$getCount次获取视频地址');
//   getDwspUrl2(index: index, theSbgllx: theSbgllx).then((url) {
//     _dwspUrl = url;
//     if (!isVideoUrl(_dwspUrl)) {
//       print('第$getCount次获取视频地址失败，等待1秒后重试');
//       getCount++;
//       Future.delayed(Duration(seconds: 1), () async {
//         print('开始第$getCount次获取视频地址');
//         getDwspUrl2(index: index, theSbgllx: theSbgllx).then((url) {
//           _dwspUrl = url;
//           if (!isVideoUrl(_dwspUrl)) {
//             print('第$getCount次获取视频地址失败，等待1秒后重试');
//             getCount++;
//             Future.delayed(Duration(seconds: 1), () async {
//               print('开始第$getCount次获取视频地址');
//               getDwspUrl2(index: index, theSbgllx: theSbgllx).then((url) {
//                 _dwspUrl = url;
//                 if (!isVideoUrl(_dwspUrl)) {
//                   print('第$getCount次获取视频地址失败，等待1秒后重试');
//                   getCount++;
//                   Future.delayed(Duration(seconds: 1), () async {
//                     print('开始第$getCount次获取视频地址');
//                     getDwspUrl2(index: index, theSbgllx: theSbgllx).then((url) {
//                       _dwspUrl = url;
//                       if (!isVideoUrl(_dwspUrl)) {
//                         print('第$getCount次获取视频地址失败，等待1秒后重试');
//                         getCount++;
//                         Future.delayed(Duration(seconds: 1), () async {
//                           print('开始第$getCount次获取视频地址');
//                           getDwspUrl2(index: index, theSbgllx: theSbgllx).then((url) {
//                             _dwspUrl = url;
//                             if (!isVideoUrl(_dwspUrl)) {
//                               getSumTime = getCurrentTiem() - getSumTime;
//                               print('第$getCount次获取 $getingDwmc 点位视频地址失败，直接返回。共用时 $getSumTime 秒');
//                               Fluttertoast.showToast(
//                                 msg: '第$getCount次获取 $getingDwmc 点位视频地址失败，请稍后重试。共用时 $getSumTime 秒',
//                                 toastLength: Toast.LENGTH_SHORT,
//                                 gravity: ToastGravity.CENTER,
//                               );
//                               //正在获取点位视频标志，禁止重入
//                               getingDwVideo = false;
//
//                               //标注正在获取点位视频的记录
//                               getingIndex = -1;
//                               print('_getingIndex = $getingIndex');
//                               eventBus.fire(DwspUpdateEvent('点位视频信息数据更新广播'));
//                             } else {
//                               print('开始播放：第$getCount次成功获取的视频地址');
//                               playUrl(index: index, url: _dwspUrl, context: context);
//                             }
//                           });
//                         });
//                       } else {
//                         print('开始播放：第$getCount次成功获取的视频地址');
//                         playUrl(index: index, url: _dwspUrl, context: context);
//                       }
//                     });
//                   });
//                 } else {
//                   print('开始播放：第$getCount次成功获取的视频地址');
//                   playUrl(index: index, url: _dwspUrl, context: context);
//                 }
//               });
//             });
//           } else {
//             print('开始播放：第$getCount次成功获取的视频地址');
//             playUrl(index: index, url: _dwspUrl, context: context);
//           }
//         });
//       });
//     } else {
//       print('开始播放：第$getCount次成功获取的视频地址');
//       playUrl(index: index, url: _dwspUrl, context: context);
//     }
//   });
//
//   //不能放到此处，此处不会等待，将导致禁止重入失败
//   //正在获取点位视频标志，禁止重入
//   //getingDwVideo = false;
//
//   //print('失败：$getCount次获取的视频地址都失败！');
//   return _dwspUrl;
// }

///得到点位视频（Dwsp）播放地址，用插件 http: ^0.12.2
// Future getDwspUrl2({@required int index, String theSbgllx = 'dwsp'}) async {
//   String _dwspUrl = '';
//
//   print('开始处理 ${mapHyshlx[theSbgllx]['text']} 网络请求...');
//   String api = ServicePath.getDwspUrl + '${index.toString()}.php';
//   print('api = ${api}');
//   //api = http://125.64.218.67:9908/rtmp/1.php
//
//   try {
//     my_http.Response response = await my_http.get(api);
//     print('response.statusCode = ${response.statusCode}');
//     //I/flutter (18114): Response status: 200
//
//     //var ret = json.decode(response.body); //报错
//     //print('Utf8Codec().decode(response.bodyBytes) = ${Utf8Codec().decode(response.bodyBytes)}');
//     // I/flutter (18114): rtmp://125.64.218.67:9903/rtp/26CCDAA7
//
//     print('response = ${response.toString()}');
//     //response = Instance of 'Response'
//
//     if (response.statusCode == 200) {
//       //final Map<String, dynamic> responseData = json.decode(response.body);
//       //报错：e：Error on line 1, column 18: Invalid media type: expected application/json;
//       _dwspUrl = Utf8Codec().decode(response.bodyBytes).replaceAll('\n', ''); //删除所有换行符
//       print('_dwspUrl = $_dwspUrl');
//       //_dwspUrl = rtmp://125.64.218.67:9903/rtp/30C91573
//     } else {
//       throw Exception('${mapHyshlx[theSbgllx]['text']} 后端接口出现异常，请检测代码和服务器情况...');
//       getingDwVideo = false; //出现异常必须提前释放禁止重入标志
//     }
//   } catch (e) {
//     print('${mapHyshlx[theSbgllx]['text']} 网络请求过程异常 e：${e}');
//     Fluttertoast.showToast(
//       msg: 'ERROR:======>${e}',
//       toastLength: Toast.LENGTH_SHORT,
//       gravity: ToastGravity.CENTER,
//     );
//     getingDwVideo = false; //出现异常必须提前释放禁止重入标志
//   }
//
//   return _dwspUrl;
// }

/// 获取最新版本号
Future getNewverUrl() async {
  String _text = '获取最新版本号';
  Map _mapGetData = {};

  String api = ServicePath.getVerUrl;
  print('api = ${api}');
  //I/flutter (12498): api = http://125.64.218.67:9904/?s=App.Car_Ver.Getver

  String random = RandomBit(6); //flutter （dart）生成N位随机数
  Map map = {
    "sign": GenerateMd5(APPkey + random),
    "random": random,
  };

  try {
    print('开始处理 $_text 网络请求...');

    Dio dio = Dio();
    print('map = ${map}');
    Response response = await dio.post(api, data: map);
    print('response = ${response.toString()}');
    //I/flutter (12498): response = {"ret":200,"data":{"id":1,"ver":"1.0.0","miaos":"版本说明",
    // "downurl":"http://www.sctastech.com/download/hyzp_20210425.apk","updatetime":1620632231},"msg":""}

    if (response.statusCode == 200) {
      print('${api} 网络请求过程正常完成');
      Map _mapDataRet = await getMapFromJson(response.data);
      // response = {"ret":200,"data":false,"msg":""}
      if (false == _mapDataRet['data']) {
        _mapGetData = {
          "id": 1,
          "ver": "1.0.0",
          "miaos": null,
          "downurl": "",
          "updatetime": 1627543123
        }; // 区县版本升级功能还未实现
      } else {
        _mapGetData = _mapDataRet['data'];
      }
    } else {
      throw Exception('${api} 后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('${api} 网络请求过程异常 e：${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }

  return _mapGetData;
}

///人脸注册上传图片
//App.User_User.Facereg 人脸注册接口
//返回结果
// 返回字段	类型	说明
// user_id	整型	用户ID
// is_reg	布尔型	是否注册成功
//人脸注册，filePath 人脸图片路径，username 用户名，user_id 用户ID，上级 context
Future faceReg_uploadImage(
    {@required String filePath,
    @required String username,
    @required int user_id,
    @required BuildContext context}) async {
  print('开始处理网络请求...');

  //1、将图片转换为 Base64 格式的字符串
  image2Base64(filePath).then((imageBase64) async {
    //2、准备 dio 的 api
    //static const String uploadFaceregUrl = ServiceUrl + '?s=App.User_User.Facereg'; //人脸注册接口
    var api = ServicePath.uploadFaceregUrl;
    print(api);

    //3、准备 dio 参数 map
    String random = RandomBit(6); //flutter （dart）生成N位随机数
    Map map = {
      'sign': GenerateMd5(APPkey + random),
      'random': random,
      'user_id': user_id,
      'face': imageBase64,
    };
    print('map = ${map}');

    //4、准备 dio 相关变量
    faceReg = -1; //复位人脸注册成功标志。1 成功，0 失败，-1 处理中
    Map _mapGetData = {};
    Response response;
    Dio dio = Dio();

    //5、开始调用 dio
    try {
      print('response = ${response}');
      //I/flutter (16661): response = null
      response = await dio.post(api, data: map);
      print('response = ${response}');
      //I/flutter (11748): response = {"ret":200,"data":{"user_id":135,"is_reg":"true","pic_url":"/wwwroot/admin/Api/wwwroot/public/uploads/b5fb2a19db9cabd4d0b1c3fe496981ec.jpg"},"ms
      // g":""}

      if (response.statusCode == 200) {
        Map _mapDataRet = await getMapFromJson(response.data);
        _mapGetData = _mapDataRet['data'];
        print('上传图片 网络请求过程正常完成');
        print('_mapGetData = ${_mapGetData}');
        //I/flutter (11748): _mapGetData = {user_id: 135, is_reg: true, pic_url: /wwwroot/admin/Api/wwwroot/public/uploads/b5fb2a19db9cabd4d0b1c3fe496981ec.jpg}
        //I/flutter (28045): _mapGetData = {code: 1, msg: 未检测到人脸信息, count: 0, data: []}

        //设置人脸注册结果标志
        if ('true' == _mapGetData['is_reg']) {
          //I/flutter (11748): 网络请求过程异常e：type 'String' is not a subtype of type 'bool'
          faceReg = 1; //设置人脸注册成功标志。1 成功，0 失败，-1 处理中
          print('faceReg = $faceReg，人脸注册成功，返回 tabs 页面');
          //Navigator.pushNamed(null, '/tabs'); //返回 tabs 页面
          //I/flutter (11748): 网络请求过程异常e：NoSuchMethodError: The method 'findAncestorStateOfType' was called on null.
          //Navigator.pushNamed(context, '/tabs'); //返回 tabs 页面，红屏报错
          getMyUserinfo().then((value) {
            Fluttertoast.showToast(
              msg: '$username 用户（ID: $user_id）人脸注册成功！',
              toastLength: Toast.LENGTH_SHORT,
              gravity: ToastGravity.CENTER,
            );
          });
          Navigator.pop(context); //返回 tabs 页面，成功返回
        } else {
          faceReg = 0; //设置人脸注册成功标志。1 成功，0 失败，-1 处理中
          Fluttertoast.showToast(
            msg: '$username 用户（ID: $user_id）人脸注册失败。可能原因：${_mapGetData['msg']}',
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.CENTER,
          );
        }
      } else {
        throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
      }
    } catch (e) {
      print('网络请求过程异常e：${e}');
      Fluttertoast.showToast(
        msg: 'ERROR:======>${e}',
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
      );
    }
  });
}

//人脸注册，username 用户名，filePath 人脸图片路径，上级 context
Future faceRegFun(
    {@required String username, @required String filePath, @required BuildContext context}) async {
  //必须先以用户名查找到 user_id，再进行人脸注册
  username = username.trim();
  faceRegUserID = -1; //人脸注册时所需用户ID，-1 非法
  //获取用户分页列表数据
  var api = ServicePath.getUserListUrl;
  print(api);
  int _totalUser = 0; //第一页时保存数据库中用户总数
  int _counter = 0; //已读取的用户数计数器

  int _page = 0;
  String random = RandomBit(6);
  Map map = {
    'random': random,
    'sign': GenerateMd5(APPkey + random),
    'page': _page,
    'perpage': 20,
  };

  print('开始处理登录请求...');
  Response response;
  Dio dio = Dio();

  try {
    while (true) {
      map['page']++;

      response = await dio.post(api, data: map);
      print('response = ${response.toString()}');
      if (response.statusCode == 200) {
        Map _mapUserListInfoRet = await getMapFromJson(response.data);
        //print('_mapUserListInfoRet = $_mapUserListInfoRet');
        if (1 == map['page']) {
          //第一页时保存数据库中用户总数
          _totalUser = _mapUserListInfoRet['data']['total'];
        }

        List _listUserInfo = _mapUserListInfoRet['data']['items'];
        print('_listUserInfo = $_listUserInfo');
        //I/flutter (11748): _listUserInfo = null
        faceRegUserID = findUserID(_listUserInfo, username);
        //查找 faceRegUserID 成功，开始进行人脸注册
        if (faceRegUserID > 0) {
          print('查找 faceRegUserID = $faceRegUserID 成功，开始进行人脸注册');
          faceReg_uploadImage(
              filePath: filePath, username: username, user_id: faceRegUserID, context: context);
          return;
        }

        _counter += _listUserInfo.length; //已读取的用户数计数器
        //已读取的用户数计数器，超过或等于数据库中用户总数时，则终止循环
        if (_counter >= _totalUser) {
          return;
        }

        print('第 ${map['page']} 次网络请求过程正常完成');
      } else {
        throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
      }
    }
  } catch (e) {
    print('网络请求过程异常e = ${e}');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }
}

// List _listUserInfo = [
//   {
//     "id": 144,
//     "username": "dudakui",
//     "truename": "杜大奎",
//     "depname": "监控室",
//     "posname": "管理员",
//     "sex": "男",
//     "face": null
//   },
//   {
//     "id": 143,
//     "username": "pengguoping",
//     "truename": "彭国平",
//     "depname": "局领导",
//     "posname": "领导",
//     "sex": "女",
//     "face": null
//   },
// ];

findUserID(List _listUserInfo, String username) {
  for (var user in _listUserInfo) {
    if (username == user["username"].trim()) {
      return user["id"];
    }
  }
  return -1;
}

Future getMyUserinfo() async {
  print('开始处理网络请求...');
  var api = ServicePath.getUserInfoUrl;
  print(api);
  //I/flutter (30518): http://125.64.218.67:9904/?s=App.User_User.Profile

  Response response;
  Dio dio = Dio();
  String random = RandomBit(6);
  try {
    response = await dio.post(api, data: {
      "user_id": g_userInfo.mapUserInfo['user_id'],
      "token": g_userInfo.mapUserInfo['token'],
      'random': random,
      'sign': GenerateMd5(APPkey + random),
    });
    print('response = ${response.toString()}');
    //I/flutter ( 5242): {"ret":200,"data":{"is_login":true,"user_id":3,"token":"32EE57A0109A3D1D6590CFD3DEBA71820F77AB654093C1DE750347C88D1A41CF"},"msg":""}
    if (response.statusCode == 200) {
      mapUserInfoRet = await getMapFromJson(response.data);
      mapUserInfo = mapUserInfoRet['data']['profile'];
      g_userInfo.username = mapUserInfo['username']; //用于刷脸登录获取用户名
      print('mapUserInfo = $mapUserInfo');
      print('g_userInfo.username = ${g_userInfo.username}');

      print('网络请求过程正常完成');
    } else {
      throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
    }
  } catch (e) {
    print('登录过程异常...');
    Fluttertoast.showToast(
      msg: 'ERROR:======>${e}',
      toastLength: Toast.LENGTH_SHORT,
      gravity: ToastGravity.CENTER,
    );
  }

  return;
}

//App.User_User.Facelogin 人脸识别登录接口
//返回结果
// 返回字段	类型	说明
// is_login	布尔型	是否登录成功
// user_id	整型	用户ID
// token	字符串	登录成功后的token,会话token
//人脸登录，filePath 人脸图片路径，上级 context
Future faceLoginFun({@required String filePath, @required BuildContext context}) async {
  print('开始处理网络请求...');

  //1、将图片转换为 Base64 格式的字符串
  image2Base64(filePath).then((imageBase64) async {
    //2、准备 dio 的 api
    //static const String uploadFaceloginUrl = ServiceUrl + '?s=App.User_User.Facelogin'; //人脸识别登录接口
    var api = ServicePath.uploadFaceloginUrl;
    print(api);
    //I/flutter (30518): http://125.64.218.67:9904/?s=App.User_User.Facelogin

    //3、准备 dio 参数 map
    String random = RandomBit(6); //flutter （dart）生成N位随机数
    Map map = {
      'sign': GenerateMd5(APPkey + random),
      'random': random,
      'face': imageBase64,
    };
    print('map = ${map}');

    //4、准备 dio 相关变量
    faceLogin = -1; //复位人脸识别登录成功标志。1 成功，0 失败，-1 处理中
    Map _mapGetData = {};
    Response response;
    Dio dio = Dio();

    //5、开始调用 dio
    try {
      print('response = ${response}');
      //I/flutter (16661): response = null
      response = await dio.post(api, data: map);
      print('response = ${response}');
      //I/flutter (14273): response = {"ret":200,"data":{"is_login":true,"user_id":135,"token":"4C5B3F93FEACAEF4B6CAA7296F22CC67825D7E48B867614383D19E3F23DFE510"},"msg":""}
      //I/flutter ( 9884): response = {"ret":200,"data":{"code":1,"msg":"未检测到人脸信息","count":0,"data":[]},"msg":""}

      if (response.statusCode == 200) {
        Map _mapDataRet = await getMapFromJson(response.data);
        _mapGetData = _mapDataRet['data'];
        print('上传图片 网络请求过程正常完成');
        print('_mapGetData = ${_mapGetData}');

        //设置人脸验证结果标志
        // I/flutter (14273): _mapGetData = {is_login: true, user_id: 135, token: 4C5B3F93FEACAEF4B6CAA7296F22CC67825D7E48B867614383D19E3F23DFE510}
        // I/flutter ( 9884): _mapGetData = {code: 1, msg: 未检测到人脸信息, count: 0, data: []}
        if (_mapGetData.containsKey('is_login') && _mapGetData['is_login']) {
          print('人脸认证成功！');
          //保存人脸认证成功的用户信息
          g_userInfo.setUserInfoFaceLogin(_mapGetData).then((value) {
            // 一套APP适应多个区县登录过程04、登录成功，开始使用保存的登录信息预加载数据，并设置faceLogin = 1
            faceLogin = 1; //设置人脸验证成功标志。1 成功，0 失败，-1 处理中
            startGetStatisDataNew(); // 2、登录前提前获取统计数据，改善用户登录体验
          });
          //获取其他用户信息
          getMyUserinfo().then((value) {
            //获取用户所属分组和相应权限
            getUserGroupAll().then((value) {
              Navigator.pushNamed(context, '/tabs', arguments: g_iIndex);
              print('欢迎 ${g_userInfo.username} 用户，人脸验证成功！');
              Fluttertoast.showToast(
                msg: '欢迎 ${g_userInfo.username} 用户，人脸验证成功！',
                toastLength: Toast.LENGTH_SHORT,
                gravity: ToastGravity.TOP,
              );
            });
          });
        } else {
          faceLogin = 0; //设置人脸验证成功标志。1 成功，0 失败，-1 处理中
          print('人脸验证失败。');
          Navigator.pushNamed(context, '/');
          Fluttertoast.showToast(
            msg: '人脸验证失败。',
            toastLength: Toast.LENGTH_SHORT,
            gravity: ToastGravity.BOTTOM,
          );
        }
      } else {
        throw Exception('后端接口出现异常，请检测代码和服务器情况.........');
      }
    } catch (e) {
      print('网络请求过程异常e：${e}');
      Fluttertoast.showToast(
        msg: 'ERROR:======>${e}',
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
      );
    }
  });
}
