| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432 |
- import 'dart:async';
- import 'dart:math';
- import 'dart:typed_data';
- import 'package:f_cache/manager.dart';
- import 'package:grpc/grpc.dart';
- import 'package:fixnum/fixnum.dart' as fixnum;
- import 'package:trackoffical_app/model.dart';
- import 'package:trackoffical_app/service/app.dart';
- import 'package:trackoffical_app/pb.dart' as pb;
- import 'package:trackoffical_app/service/service.dart';
- import 'package:trackoffical_app/utils.dart';
- import 'package:protobuf/protobuf.dart';
- import '../logger.dart';
- import '../global.dart';
- class _Stub{
- _Stub(
- this.channel,
- this.stub
- );
- ClientChannel channel;
- pb.ApiToAppClient stub;
- }
- class ApiService extends IService {
- static ApiService get to => Get.find();
- ClientChannel? channel;
- String? get token {
- final out = App.to.userProfile.token.val;
- if (out.isEmpty) {
- return null;
- }
- return out;
- }
- set token(String? v) {
- App.to.userProfile.token.val = v ?? '';
- }
- String get _appVersion => App.to.appVersion;
- ClientChannel _newChannel(){
- return ClientChannel(
- GlobalVar.apiHost,
- port: GlobalVar.apiPort,
- options: const ChannelOptions(credentials:
- // ChannelCredentials.secure()
- ChannelCredentials.insecure()
- ),
- );
- }
- pb.ApiToAppClient _getStub({Duration? timeout, ClientChannel? channel}){
- if (this.channel == null) {
- throw Exception('$runtimeType 未初始化');
- }
- final metadata = <String, String>{
- 'source': "${pb.LoginSource.ToApp.value}"
- };
- metadata['version'] = _appVersion;
- if (token != null) {
- metadata['token'] = token!;
- }
- info("token: $token");
- return pb.ApiToAppClient(channel??this.channel!,
- options: CallOptions(
- metadata: metadata,
- timeout: timeout,
- ));
- }
- pb.ApiToAppClient get stub {
- return _getStub(timeout: 10.seconds);
- }
- _Stub get _stubForStream {
- final ch = _newChannel();
- return _Stub(ch, _getStub(channel: ch)) ;
- }
- Future<void> syncTime()async{
- try {
- final serverNow = await serverTime();
- App.to.correctByServerNow(serverNow);
- info('服务器时间:${App.to.now}');
- } catch(e){
- warn("获取服务器时间失败: ", e);
- }
- }
- @override
- Future<ApiService> init() async {
- channel = _newChannel();
- syncTime();
- return this;
- }
- Future<bool> isSignIn() async {
- final token = this.token;
- if (token == null) {
- return false;
- }
- if (token.isNotEmpty) {
- // try {
- // await flushUserInfo();
- // } catch (e) {
- // return false;
- // }
- return true;
- } else {
- return false;
- }
- }
- // Future<void> getVfCode() async {
- // await stub.getVfPic(pb.DefaultRequest());
- // }
- // 获取短信验证码
- Future<void> authSendCodeToPhone(String phone, pb.SmsType smsType)async{
- info('authSendCodeToPhone [$phone]');
- await stub.toSendCodeToPhoneV2(pb.ToSendCodeToPhoneRequestV2()
- ..phone= phone
- ..smsType= smsType
- );
- }
- // 场控端_登录
- Future<void> signIn(String userCode, String password, String ip) async {
- final r = await stub.toSignInV2(pb.ToSignInRequestV2()
- ..userCode = userCode
- ..password = password
- ..ip = ip
- );
- token = r.token;
- debug('sign in success: $token');
- }
- // 场控端_登出
- void signOut(){
- stub.toSignOutV2(pb.DefaultRequest());
- token = null;
- }
- @override
- void onClose() {
- channel?.shutdown();
- }
- // 获取系统时间
- Future<DateTime> serverTime() async {
- final begin = DateTime.now();
- final r = await stub.toGetServerTime(pb.DefaultRequest());
- final cost = DateTime.now().difference(begin);
- final serverNow = DateTime.fromMillisecondsSinceEpoch(
- r.millisecondStamp.toInt(),
- isUtc: true)
- .toLocal();
- return serverNow.add(cost);
- }
- Future<Duration> getSmsSendLeftTime(String phone)async{
- final r = await stub.toGetSmsSendLeftTimeV2(pb.GetSmsSendLeftTimeRequest()..phone= phone);
- info('getSmsSendLeftTime: $phone - ${r.second}s');
- return r.second.seconds;
- }
- // Future<pb.GetUpdateVersionReply> getUpdateVersion(String version)async{
- // info('getUpdateVersion: $version');
- // final r = await stub.getUpdateVersion(pb.GetUpdateVersionRequest()..vCode= version);
- // return r;
- // }
- // 场控端_地图列表
- Future<List<MapInfo>> mapList(MPosition? position, int offset, int limit) async{
- info('mapList: $position');
- final req = pb.MapListRequestV2()
- ..offset = offset
- ..limit = limit;
- if (position != null){
- req.position = position.toPb();
- }
- final r = await stub.toMapListV2(req);
- return r.list.map((e) => e.toModel()).toList();
- }
- // 场控端_地图自身信息
- Future<pb.ToMapInfoV2> mapDetail(int mapId, String pin)async{
- info('mapDetail mapId: $mapId pin: $pin');
- final r = await stub.toMapDetailV2(pb.IdRequest()
- ..id = fixnum.Int64(mapId)
- );
- return r;
- }
- // 场控端_地图内正在进行中的活动人员详情
- Future<pb.ToUserDetailQueryReplyV2> userDetailQuery(int mapId, bool isFullQuery)async{
- info('userDetailQuery mapId: $mapId isFullQuery: $isFullQuery');
- final r = await stub.toUserDetailQueryV2(pb.ToUserDetailQueryRequestV2()
- // ..mapId = fixnum.Int64(mapId)
- ..mapId = mapId
- ..isFullQuery = isFullQuery
- );
- return r;
- }
- // Future<Bin> getBinByMd5(Uint8List md5, OnPercentage onPercentage) async{
- // final stream = _getStub().toGetBinaryByMd5(pb.ToGetBinaryByMd5Request()..md5=md5);
- // String ext='';
- // Uint8List? data;
- // var nonce=Uint8List(0);
- // var i = 0;
- //
- // await for (var one in stream){
- // if(data == null){
- // data = Uint8List(one.allCount);
- // ext = one.ext;
- // nonce= Uint8List.fromList(one.nonce);
- // }
- //
- // for(var b in one.data){
- // data[i]=b;
- // i++;
- // }
- //
- // onPercentage(i, data.length);
- // }
- //
- //
- // await stream.cancel();
- // return Bin()
- // ..ext=ext
- // ..data=data??Uint8List(0)
- // ..nonce=nonce;
- // return Bin();
- // }
- Future<BinReader> getBinReaderByMd5(Uint8List md5) async {
- final stream = _getStub().toGetBinaryByMd5(pb.ToGetBinaryByMd5Request()..md5=md5);
- final controller = StreamController<List<int>>();
- controller.onCancel = (){
- stream.cancel();
- };
- Future<void> rcv()async{
- try{
- await for(final one in stream){
- controller.add(one.data);
- }
- }finally{
- controller.close();
- stream.cancel();
- }
- }
- rcv();
- stream.headers.then((value) => debug(value));
- final headers = await stream.headers;
- final lenStr = headers['all-length']!;
- final length = int.parse(lenStr);
- final nonce = headers['nonce']!;
- final ext = headers['ext']!;
- return BinReader(Reader( controller.stream, length))
- ..ext=ext
- ..nonce=nonce
- ;
- }
- }
- // class Bin{
- // var ext='';
- // var data = Uint8List(0);
- // var nonce = Uint8List(0);
- // }
- class BinReader{
- BinReader(this.reader);
- var ext='';
- Reader reader;
- var nonce='';
- }
- // typedef OnPercentage = void Function(int, int);
- class ApiServiceMock extends ApiService {
- @override
- Future<ApiService> init() async {
- debug('$runtimeType ready!');
- return this;
- }
- final random = Random();
- @override
- Future<void> signIn(String userCode, String password, String ip) async {}
- @override
- void onReady() {}
- @override
- void onClose() {}
- @override
- Future<DateTime> serverTime() async {
- return DateTime.now();
- }
- /*
- @override
- Future<pb.MapActivityListReply> mapActivityList(int mapId, String pin)async{
- return pb.MapActivityListReply()
- ..list.addAll([
- pb.MapActivitySimpleInfo()
- ..id=0
- ..name= '穿越荒野:勇闯野性之旅-穿越荒野:勇闯野性之旅-穿越荒野:勇闯野性之旅-穿越荒野:勇闯野性之旅-穿越荒野:勇闯野性之旅'
- ..difficulty= 1
- ..distanceMinMeter= 217.1
- ..closeDoorTime= 190.minutes.toPb()
- ..isUsed= false
- ..routeCount= 28
- ..totalControlNum= 12
- ,
- pb.MapActivitySimpleInfo()
- ..id=1
- ..name= '极限挑战 战胜重力'
- ..difficulty= 2
- ..distanceMinMeter= 8.1
- ..closeDoorTime= 190.minutes.toPb()
- ..isUsed= true
- ..routeCount= 6
- ..totalControlNum= 16
- ,
- ])
- ;
- }
- @override
- Future<pb.ActivityDetailReply> activityDetail(int id) async {
- final simple = pb.MapActivitySimpleInfo()
- ..id= 1
- ..name= '周末爬山健身运动'
- ..closeDoorTime= 90.minutes.toPb()
- ..distanceMinMeter= 71.3;
- return pb.ActivityDetailReply()
- ..baseInfoV2= simple
- ..content= ' 此主题为全民爬山健身定向运动,全民爬山健身运动是我国体育事业发展的重要组成部分,也是实现中华民族伟大复兴中国梦的重要内容。'
- ..routes.addAll([
- pb.MapRoute()
- ..name='XL0002'
- ..distanceMeter= 3331
- ..altitudeDiffMeter= 223
- ..useCount= 0
- ,
- pb.MapRoute()
- ..name= 'XL0003'
- ..distanceMeter= 5430
- ..altitudeDiffMeter= 123
- ..useCount=2
- ,
- ])
- ;
- }
- */
- // @override
- Future<List<MapInfo>> mapRecommendList(MPosition? position)async{
- info('mapRecommendList: $position');
- return [
- MapInfo()
- ..name= '英雄山风景区'
- // ..isOpen=true
- // ..isRecommend=true
- ,
- MapInfo()..name= '板桥广场'
- // ..isRecommend=true
- ];
- }
- @override
- Future<List<MapInfo>> mapList(MPosition? position, int offset, int limit)async{
- info('mapList: $position');
- final out = <MapInfo>[];
- for(var i=0;i< limit;i++){
- out.add(MapInfo()
- ..name ='$offset-${random.nextInt(10000)}公园'
- );
- }
- return out;
- }
- }
- /*
- class StreamGuardianWatch{
- StreamGuardianWatch(
- this.channel,
- this.stream
- );
- ClientChannel channel;
- ResponseStream<pb.PupilInGameWatchReply> stream;
- }
- */
- extension ExtInt64 on fixnum.Int64 {
- pb.IdRequest toIdRequest(){
- return pb.IdRequest()
- ..id = this;
- }
- }
- extension ExtNum on num {
- pb.IdRequest toIdRequest(){
- return pb.IdRequest()
- ..id = fixnum.Int64(toInt());
- }
- }
|