wzx 2 vuotta sitten
vanhempi
commit
ddc418c53e

+ 1 - 1
grpc/app_api

@@ -1 +1 @@
-Subproject commit e7598bf06f3ea0f16d2a461a845ec86f1ff4770a
+Subproject commit 953c4f0deb25c72123537679967faba74442dead

+ 308 - 2
grpc/base_pb.js

@@ -29,6 +29,8 @@ goog.exportSymbol('proto.base.v1.DefaultReply', null, global);
 goog.exportSymbol('proto.base.v1.DefaultRequest', null, global);
 goog.exportSymbol('proto.base.v1.ErrorCode', null, global);
 goog.exportSymbol('proto.base.v1.GameGpsInfo', null, global);
+goog.exportSymbol('proto.base.v1.GetSmsSendLeftTimeReply', null, global);
+goog.exportSymbol('proto.base.v1.GetSmsSendLeftTimeRequest', null, global);
 goog.exportSymbol('proto.base.v1.HeartRate', null, global);
 goog.exportSymbol('proto.base.v1.HrBandType', null, global);
 goog.exportSymbol('proto.base.v1.IdRequest', null, global);
@@ -237,6 +239,48 @@ if (goog.DEBUG && !COMPILED) {
    */
   proto.base.v1.ShopList.displayName = 'proto.base.v1.ShopList';
 }
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.base.v1.GetSmsSendLeftTimeRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.base.v1.GetSmsSendLeftTimeRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.base.v1.GetSmsSendLeftTimeRequest.displayName = 'proto.base.v1.GetSmsSendLeftTimeRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.base.v1.GetSmsSendLeftTimeReply = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.base.v1.GetSmsSendLeftTimeReply, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.base.v1.GetSmsSendLeftTimeReply.displayName = 'proto.base.v1.GetSmsSendLeftTimeReply';
+}
 /**
  * Generated by JsPbCodeGenerator.
  * @param {Array=} opt_data Optional initial data array, typically from a
@@ -2068,6 +2112,266 @@ proto.base.v1.ShopList.prototype.setName = function(value) {
 
 
 
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.base.v1.GetSmsSendLeftTimeRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.base.v1.GetSmsSendLeftTimeRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.base.v1.GetSmsSendLeftTimeRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.base.v1.GetSmsSendLeftTimeRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    phone: jspb.Message.getFieldWithDefault(msg, 1, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.base.v1.GetSmsSendLeftTimeRequest}
+ */
+proto.base.v1.GetSmsSendLeftTimeRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.base.v1.GetSmsSendLeftTimeRequest;
+  return proto.base.v1.GetSmsSendLeftTimeRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.base.v1.GetSmsSendLeftTimeRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.base.v1.GetSmsSendLeftTimeRequest}
+ */
+proto.base.v1.GetSmsSendLeftTimeRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPhone(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.base.v1.GetSmsSendLeftTimeRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.base.v1.GetSmsSendLeftTimeRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.base.v1.GetSmsSendLeftTimeRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.base.v1.GetSmsSendLeftTimeRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getPhone();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string phone = 1;
+ * @return {string}
+ */
+proto.base.v1.GetSmsSendLeftTimeRequest.prototype.getPhone = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.base.v1.GetSmsSendLeftTimeRequest} returns this
+ */
+proto.base.v1.GetSmsSendLeftTimeRequest.prototype.setPhone = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.base.v1.GetSmsSendLeftTimeReply.prototype.toObject = function(opt_includeInstance) {
+  return proto.base.v1.GetSmsSendLeftTimeReply.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.base.v1.GetSmsSendLeftTimeReply} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.base.v1.GetSmsSendLeftTimeReply.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    second: jspb.Message.getFieldWithDefault(msg, 1, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.base.v1.GetSmsSendLeftTimeReply}
+ */
+proto.base.v1.GetSmsSendLeftTimeReply.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.base.v1.GetSmsSendLeftTimeReply;
+  return proto.base.v1.GetSmsSendLeftTimeReply.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.base.v1.GetSmsSendLeftTimeReply} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.base.v1.GetSmsSendLeftTimeReply}
+ */
+proto.base.v1.GetSmsSendLeftTimeReply.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setSecond(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.base.v1.GetSmsSendLeftTimeReply.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.base.v1.GetSmsSendLeftTimeReply.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.base.v1.GetSmsSendLeftTimeReply} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.base.v1.GetSmsSendLeftTimeReply.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getSecond();
+  if (f !== 0) {
+    writer.writeInt32(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional int32 second = 1;
+ * @return {number}
+ */
+proto.base.v1.GetSmsSendLeftTimeReply.prototype.getSecond = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 1, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.base.v1.GetSmsSendLeftTimeReply} returns this
+ */
+proto.base.v1.GetSmsSendLeftTimeReply.prototype.setSecond = function(value) {
+  return jspb.Message.setProto3IntField(this, 1, value);
+};
+
+
+
+
+
 if (jspb.Message.GENERATE_TO_OBJECT) {
 /**
  * Creates an object representation of this proto.
@@ -4234,7 +4538,8 @@ proto.base.v1.UserType = {
   APPUSER: 1,
   PARKADMIN: 2,
   IPADMIN: 3,
-  SYSADMIN: 4
+  SYSADMIN: 4,
+  TOADMIN: 5
 };
 
 /**
@@ -4244,7 +4549,8 @@ proto.base.v1.LoginSource = {
   UNDEF: 0,
   USERAPP: 1,
   WEBADMIN: 2,
-  SHOPAPP: 3
+  SHOPAPP: 3,
+  TOAPP: 4
 };
 
 /**

+ 305 - 0
grpc/track_offical_grpc_web_pb.js

@@ -77,6 +77,250 @@ proto.to.v1.ApiToPromiseClient =
 };
 
 
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.to.v1.ToSendCodeToPhoneRequest,
+ *   !proto.base.v1.DefaultReply>}
+ */
+const methodDescriptor_ApiTo_ToSendCodeToPhone = new grpc.web.MethodDescriptor(
+  '/to.v1.ApiTo/ToSendCodeToPhone',
+  grpc.web.MethodType.UNARY,
+  proto.to.v1.ToSendCodeToPhoneRequest,
+  base_pb.DefaultReply,
+  /**
+   * @param {!proto.to.v1.ToSendCodeToPhoneRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  base_pb.DefaultReply.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.to.v1.ToSendCodeToPhoneRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.RpcError, ?proto.base.v1.DefaultReply)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.base.v1.DefaultReply>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.to.v1.ApiToClient.prototype.toSendCodeToPhone =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/to.v1.ApiTo/ToSendCodeToPhone',
+      request,
+      metadata || {},
+      methodDescriptor_ApiTo_ToSendCodeToPhone,
+      callback);
+};
+
+
+/**
+ * @param {!proto.to.v1.ToSendCodeToPhoneRequest} request The
+ *     request proto
+ * @param {?Object<string, string>=} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.base.v1.DefaultReply>}
+ *     Promise that resolves to the response
+ */
+proto.to.v1.ApiToPromiseClient.prototype.toSendCodeToPhone =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/to.v1.ApiTo/ToSendCodeToPhone',
+      request,
+      metadata || {},
+      methodDescriptor_ApiTo_ToSendCodeToPhone);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.base.v1.GetSmsSendLeftTimeRequest,
+ *   !proto.base.v1.GetSmsSendLeftTimeReply>}
+ */
+const methodDescriptor_ApiTo_ToGetSmsSendLeftTime = new grpc.web.MethodDescriptor(
+  '/to.v1.ApiTo/ToGetSmsSendLeftTime',
+  grpc.web.MethodType.UNARY,
+  base_pb.GetSmsSendLeftTimeRequest,
+  base_pb.GetSmsSendLeftTimeReply,
+  /**
+   * @param {!proto.base.v1.GetSmsSendLeftTimeRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  base_pb.GetSmsSendLeftTimeReply.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.base.v1.GetSmsSendLeftTimeRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.RpcError, ?proto.base.v1.GetSmsSendLeftTimeReply)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.base.v1.GetSmsSendLeftTimeReply>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.to.v1.ApiToClient.prototype.toGetSmsSendLeftTime =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/to.v1.ApiTo/ToGetSmsSendLeftTime',
+      request,
+      metadata || {},
+      methodDescriptor_ApiTo_ToGetSmsSendLeftTime,
+      callback);
+};
+
+
+/**
+ * @param {!proto.base.v1.GetSmsSendLeftTimeRequest} request The
+ *     request proto
+ * @param {?Object<string, string>=} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.base.v1.GetSmsSendLeftTimeReply>}
+ *     Promise that resolves to the response
+ */
+proto.to.v1.ApiToPromiseClient.prototype.toGetSmsSendLeftTime =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/to.v1.ApiTo/ToGetSmsSendLeftTime',
+      request,
+      metadata || {},
+      methodDescriptor_ApiTo_ToGetSmsSendLeftTime);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.to.v1.ToSignInRequest,
+ *   !proto.base.v1.SignInReply>}
+ */
+const methodDescriptor_ApiTo_ToSignIn = new grpc.web.MethodDescriptor(
+  '/to.v1.ApiTo/ToSignIn',
+  grpc.web.MethodType.UNARY,
+  proto.to.v1.ToSignInRequest,
+  base_pb.SignInReply,
+  /**
+   * @param {!proto.to.v1.ToSignInRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  base_pb.SignInReply.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.to.v1.ToSignInRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.RpcError, ?proto.base.v1.SignInReply)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.base.v1.SignInReply>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.to.v1.ApiToClient.prototype.toSignIn =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/to.v1.ApiTo/ToSignIn',
+      request,
+      metadata || {},
+      methodDescriptor_ApiTo_ToSignIn,
+      callback);
+};
+
+
+/**
+ * @param {!proto.to.v1.ToSignInRequest} request The
+ *     request proto
+ * @param {?Object<string, string>=} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.base.v1.SignInReply>}
+ *     Promise that resolves to the response
+ */
+proto.to.v1.ApiToPromiseClient.prototype.toSignIn =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/to.v1.ApiTo/ToSignIn',
+      request,
+      metadata || {},
+      methodDescriptor_ApiTo_ToSignIn);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.to.v1.ToSignOutRequest,
+ *   !proto.base.v1.DefaultReply>}
+ */
+const methodDescriptor_ApiTo_ToSignOut = new grpc.web.MethodDescriptor(
+  '/to.v1.ApiTo/ToSignOut',
+  grpc.web.MethodType.UNARY,
+  proto.to.v1.ToSignOutRequest,
+  base_pb.DefaultReply,
+  /**
+   * @param {!proto.to.v1.ToSignOutRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  base_pb.DefaultReply.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.to.v1.ToSignOutRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.RpcError, ?proto.base.v1.DefaultReply)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.base.v1.DefaultReply>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.to.v1.ApiToClient.prototype.toSignOut =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/to.v1.ApiTo/ToSignOut',
+      request,
+      metadata || {},
+      methodDescriptor_ApiTo_ToSignOut,
+      callback);
+};
+
+
+/**
+ * @param {!proto.to.v1.ToSignOutRequest} request The
+ *     request proto
+ * @param {?Object<string, string>=} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.base.v1.DefaultReply>}
+ *     Promise that resolves to the response
+ */
+proto.to.v1.ApiToPromiseClient.prototype.toSignOut =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/to.v1.ApiTo/ToSignOut',
+      request,
+      metadata || {},
+      methodDescriptor_ApiTo_ToSignOut);
+};
+
+
 /**
  * @const
  * @type {!grpc.web.MethodDescriptor<
@@ -443,5 +687,66 @@ proto.to.v1.ApiToPromiseClient.prototype.toAnyUserHistoryGpsQuery =
 };
 
 
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.base.v1.DefaultRequest,
+ *   !proto.base.v1.DefaultReply>}
+ */
+const methodDescriptor_ApiTo_ToTest = new grpc.web.MethodDescriptor(
+  '/to.v1.ApiTo/ToTest',
+  grpc.web.MethodType.UNARY,
+  base_pb.DefaultRequest,
+  base_pb.DefaultReply,
+  /**
+   * @param {!proto.base.v1.DefaultRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  base_pb.DefaultReply.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.base.v1.DefaultRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.RpcError, ?proto.base.v1.DefaultReply)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.base.v1.DefaultReply>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.to.v1.ApiToClient.prototype.toTest =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/to.v1.ApiTo/ToTest',
+      request,
+      metadata || {},
+      methodDescriptor_ApiTo_ToTest,
+      callback);
+};
+
+
+/**
+ * @param {!proto.base.v1.DefaultRequest} request The
+ *     request proto
+ * @param {?Object<string, string>=} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.base.v1.DefaultReply>}
+ *     Promise that resolves to the response
+ */
+proto.to.v1.ApiToPromiseClient.prototype.toTest =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/to.v1.ApiTo/ToTest',
+      request,
+      metadata || {},
+      methodDescriptor_ApiTo_ToTest);
+};
+
+
 module.exports = proto.to.v1;
 

+ 643 - 7
grpc/track_offical_pb.js

@@ -23,11 +23,77 @@ goog.exportSymbol('proto.to.v1.ToActionSimple', null, global);
 goog.exportSymbol('proto.to.v1.ToActionUsersDetailReply', null, global);
 goog.exportSymbol('proto.to.v1.ToAnyUserHistoryGpsQueryRequest', null, global);
 goog.exportSymbol('proto.to.v1.ToMapInfo', null, global);
+goog.exportSymbol('proto.to.v1.ToSendCodeToPhoneRequest', null, global);
+goog.exportSymbol('proto.to.v1.ToSignInRequest', null, global);
+goog.exportSymbol('proto.to.v1.ToSignOutRequest', null, global);
 goog.exportSymbol('proto.to.v1.ToUserGpsQueryReply', null, global);
 goog.exportSymbol('proto.to.v1.ToUsersInGameHistoryGpsQueryRequest', null, global);
 goog.exportSymbol('proto.to.v1.UserArriveControlPoint', null, global);
 goog.exportSymbol('proto.to.v1.UserGpsInfo', null, global);
 goog.exportSymbol('proto.to.v1.UserInGameInfo', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.to.v1.ToSignOutRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.to.v1.ToSignOutRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.to.v1.ToSignOutRequest.displayName = 'proto.to.v1.ToSignOutRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.to.v1.ToSendCodeToPhoneRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.to.v1.ToSendCodeToPhoneRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.to.v1.ToSendCodeToPhoneRequest.displayName = 'proto.to.v1.ToSendCodeToPhoneRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.to.v1.ToSignInRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.to.v1.ToSignInRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.to.v1.ToSignInRequest.displayName = 'proto.to.v1.ToSignInRequest';
+}
 /**
  * Generated by JsPbCodeGenerator.
  * @param {Array=} opt_data Optional initial data array, typically from a
@@ -260,6 +326,516 @@ if (goog.DEBUG && !COMPILED) {
   proto.to.v1.UserArriveControlPoint.displayName = 'proto.to.v1.UserArriveControlPoint';
 }
 
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.to.v1.ToSignOutRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.to.v1.ToSignOutRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.to.v1.ToSignOutRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.to.v1.ToSignOutRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    name: jspb.Message.getFieldWithDefault(msg, 1, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.to.v1.ToSignOutRequest}
+ */
+proto.to.v1.ToSignOutRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.to.v1.ToSignOutRequest;
+  return proto.to.v1.ToSignOutRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.to.v1.ToSignOutRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.to.v1.ToSignOutRequest}
+ */
+proto.to.v1.ToSignOutRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setName(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.to.v1.ToSignOutRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.to.v1.ToSignOutRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.to.v1.ToSignOutRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.to.v1.ToSignOutRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getName();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string name = 1;
+ * @return {string}
+ */
+proto.to.v1.ToSignOutRequest.prototype.getName = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.to.v1.ToSignOutRequest} returns this
+ */
+proto.to.v1.ToSignOutRequest.prototype.setName = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.to.v1.ToSendCodeToPhoneRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.to.v1.ToSendCodeToPhoneRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.to.v1.ToSendCodeToPhoneRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.to.v1.ToSendCodeToPhoneRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    phone: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    usertype: jspb.Message.getFieldWithDefault(msg, 2, 0),
+    smstype: jspb.Message.getFieldWithDefault(msg, 3, 0)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.to.v1.ToSendCodeToPhoneRequest}
+ */
+proto.to.v1.ToSendCodeToPhoneRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.to.v1.ToSendCodeToPhoneRequest;
+  return proto.to.v1.ToSendCodeToPhoneRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.to.v1.ToSendCodeToPhoneRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.to.v1.ToSendCodeToPhoneRequest}
+ */
+proto.to.v1.ToSendCodeToPhoneRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPhone(value);
+      break;
+    case 2:
+      var value = /** @type {!proto.base.v1.UserType} */ (reader.readEnum());
+      msg.setUsertype(value);
+      break;
+    case 3:
+      var value = /** @type {!proto.base.v1.SmsType} */ (reader.readEnum());
+      msg.setSmstype(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.to.v1.ToSendCodeToPhoneRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.to.v1.ToSendCodeToPhoneRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.to.v1.ToSendCodeToPhoneRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.to.v1.ToSendCodeToPhoneRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getPhone();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getUsertype();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      2,
+      f
+    );
+  }
+  f = message.getSmstype();
+  if (f !== 0.0) {
+    writer.writeEnum(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string phone = 1;
+ * @return {string}
+ */
+proto.to.v1.ToSendCodeToPhoneRequest.prototype.getPhone = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.to.v1.ToSendCodeToPhoneRequest} returns this
+ */
+proto.to.v1.ToSendCodeToPhoneRequest.prototype.setPhone = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional base.v1.UserType userType = 2;
+ * @return {!proto.base.v1.UserType}
+ */
+proto.to.v1.ToSendCodeToPhoneRequest.prototype.getUsertype = function() {
+  return /** @type {!proto.base.v1.UserType} */ (jspb.Message.getFieldWithDefault(this, 2, 0));
+};
+
+
+/**
+ * @param {!proto.base.v1.UserType} value
+ * @return {!proto.to.v1.ToSendCodeToPhoneRequest} returns this
+ */
+proto.to.v1.ToSendCodeToPhoneRequest.prototype.setUsertype = function(value) {
+  return jspb.Message.setProto3EnumField(this, 2, value);
+};
+
+
+/**
+ * optional base.v1.SmsType smsType = 3;
+ * @return {!proto.base.v1.SmsType}
+ */
+proto.to.v1.ToSendCodeToPhoneRequest.prototype.getSmstype = function() {
+  return /** @type {!proto.base.v1.SmsType} */ (jspb.Message.getFieldWithDefault(this, 3, 0));
+};
+
+
+/**
+ * @param {!proto.base.v1.SmsType} value
+ * @return {!proto.to.v1.ToSendCodeToPhoneRequest} returns this
+ */
+proto.to.v1.ToSendCodeToPhoneRequest.prototype.setSmstype = function(value) {
+  return jspb.Message.setProto3EnumField(this, 3, value);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.to.v1.ToSignInRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.to.v1.ToSignInRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.to.v1.ToSignInRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.to.v1.ToSignInRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    usercode: jspb.Message.getFieldWithDefault(msg, 1, ""),
+    password: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    ip: jspb.Message.getFieldWithDefault(msg, 3, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.to.v1.ToSignInRequest}
+ */
+proto.to.v1.ToSignInRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.to.v1.ToSignInRequest;
+  return proto.to.v1.ToSignInRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.to.v1.ToSignInRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.to.v1.ToSignInRequest}
+ */
+proto.to.v1.ToSignInRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsercode(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPassword(value);
+      break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setIp(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.to.v1.ToSignInRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.to.v1.ToSignInRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.to.v1.ToSignInRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.to.v1.ToSignInRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUsercode();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+  f = message.getPassword();
+  if (f.length > 0) {
+    writer.writeString(
+      2,
+      f
+    );
+  }
+  f = message.getIp();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string userCode = 1;
+ * @return {string}
+ */
+proto.to.v1.ToSignInRequest.prototype.getUsercode = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.to.v1.ToSignInRequest} returns this
+ */
+proto.to.v1.ToSignInRequest.prototype.setUsercode = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+/**
+ * optional string password = 2;
+ * @return {string}
+ */
+proto.to.v1.ToSignInRequest.prototype.getPassword = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 2, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.to.v1.ToSignInRequest} returns this
+ */
+proto.to.v1.ToSignInRequest.prototype.setPassword = function(value) {
+  return jspb.Message.setProto3StringField(this, 2, value);
+};
+
+
+/**
+ * optional string ip = 3;
+ * @return {string}
+ */
+proto.to.v1.ToSignInRequest.prototype.getIp = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.to.v1.ToSignInRequest} returns this
+ */
+proto.to.v1.ToSignInRequest.prototype.setIp = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
+
 /**
  * List of repeated fields within this message type.
  * @private {!Array<number>}
@@ -1566,7 +2142,9 @@ proto.to.v1.UserInGameInfo.toObject = function(includeInstance, msg) {
     totalcontrolnum: jspb.Message.getFieldWithDefault(msg, 11, 0),
     startsecondstamp: jspb.Message.getFieldWithDefault(msg, 12, 0),
     endsecondstamp: jspb.Message.getFieldWithDefault(msg, 13, 0),
-    mstate: jspb.Message.getFieldWithDefault(msg, 14, 0)
+    mstate: jspb.Message.getFieldWithDefault(msg, 14, 0),
+    lasthr: jspb.Message.getFieldWithDefault(msg, 15, 0),
+    phone: jspb.Message.getFieldWithDefault(msg, 16, "")
   };
 
   if (includeInstance) {
@@ -1659,6 +2237,14 @@ proto.to.v1.UserInGameInfo.deserializeBinaryFromReader = function(msg, reader) {
       var value = /** @type {number} */ (reader.readInt32());
       msg.setMstate(value);
       break;
+    case 15:
+      var value = /** @type {number} */ (reader.readInt32());
+      msg.setLasthr(value);
+      break;
+    case 16:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setPhone(value);
+      break;
     default:
       reader.skipField();
       break;
@@ -1786,6 +2372,20 @@ proto.to.v1.UserInGameInfo.serializeBinaryToWriter = function(message, writer) {
       f
     );
   }
+  f = message.getLasthr();
+  if (f !== 0) {
+    writer.writeInt32(
+      15,
+      f
+    );
+  }
+  f = message.getPhone();
+  if (f.length > 0) {
+    writer.writeString(
+      16,
+      f
+    );
+  }
 };
 
 
@@ -2041,6 +2641,42 @@ proto.to.v1.UserInGameInfo.prototype.setMstate = function(value) {
 };
 
 
+/**
+ * optional int32 lastHr = 15;
+ * @return {number}
+ */
+proto.to.v1.UserInGameInfo.prototype.getLasthr = function() {
+  return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 15, 0));
+};
+
+
+/**
+ * @param {number} value
+ * @return {!proto.to.v1.UserInGameInfo} returns this
+ */
+proto.to.v1.UserInGameInfo.prototype.setLasthr = function(value) {
+  return jspb.Message.setProto3IntField(this, 15, value);
+};
+
+
+/**
+ * optional string phone = 16;
+ * @return {string}
+ */
+proto.to.v1.UserInGameInfo.prototype.getPhone = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 16, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.to.v1.UserInGameInfo} returns this
+ */
+proto.to.v1.UserInGameInfo.prototype.setPhone = function(value) {
+  return jspb.Message.setProto3StringField(this, 16, value);
+};
+
+
 
 /**
  * List of repeated fields within this message type.
@@ -2675,7 +3311,7 @@ proto.to.v1.UserGpsInfo.toObject = function(includeInstance, msg) {
     longitude: jspb.Message.getFloatingPointFieldWithDefault(msg, 2, 0.0),
     latitude: jspb.Message.getFloatingPointFieldWithDefault(msg, 3, 0.0),
     directionradian: jspb.Message.getFloatingPointFieldWithDefault(msg, 4, 0.0),
-    gpstimemillisecondstamp: jspb.Message.getFieldWithDefault(msg, 5, 0)
+    gpstimesecondstamp: jspb.Message.getFieldWithDefault(msg, 5, 0)
   };
 
   if (includeInstance) {
@@ -2730,7 +3366,7 @@ proto.to.v1.UserGpsInfo.deserializeBinaryFromReader = function(msg, reader) {
       break;
     case 5:
       var value = /** @type {number} */ (reader.readInt64());
-      msg.setGpstimemillisecondstamp(value);
+      msg.setGpstimesecondstamp(value);
       break;
     default:
       reader.skipField();
@@ -2789,7 +3425,7 @@ proto.to.v1.UserGpsInfo.serializeBinaryToWriter = function(message, writer) {
       f
     );
   }
-  f = message.getGpstimemillisecondstamp();
+  f = message.getGpstimesecondstamp();
   if (f !== 0) {
     writer.writeInt64(
       5,
@@ -2872,10 +3508,10 @@ proto.to.v1.UserGpsInfo.prototype.setDirectionradian = function(value) {
 
 
 /**
- * optional int64 gpsTimeMillisecondStamp = 5;
+ * optional int64 gpsTimeSecondStamp = 5;
  * @return {number}
  */
-proto.to.v1.UserGpsInfo.prototype.getGpstimemillisecondstamp = function() {
+proto.to.v1.UserGpsInfo.prototype.getGpstimesecondstamp = function() {
   return /** @type {number} */ (jspb.Message.getFieldWithDefault(this, 5, 0));
 };
 
@@ -2884,7 +3520,7 @@ proto.to.v1.UserGpsInfo.prototype.getGpstimemillisecondstamp = function() {
  * @param {number} value
  * @return {!proto.to.v1.UserGpsInfo} returns this
  */
-proto.to.v1.UserGpsInfo.prototype.setGpstimemillisecondstamp = function(value) {
+proto.to.v1.UserGpsInfo.prototype.setGpstimesecondstamp = function(value) {
   return jspb.Message.setProto3IntField(this, 5, value);
 };
 

+ 7 - 4
main.js

@@ -1,6 +1,7 @@
 // #ifndef VUE3
 import Vue from 'vue'
 import App from './App'
+import store from './store'
 import {
 	ApiToClient
 } from "./grpc/track_offical_grpc_web_pb.js"
@@ -12,10 +13,10 @@ App.mpType = 'app'
 // 建立grpc连接服务 
 
 // 测试版
-let client = new ApiToClient("http://192.168.0.3:10000", null, null)
+// let client = new ApiToClient("http://192.168.0.3:10000", null, null)
 
 // 正式版
-// let client = new ApiToClient("http://otapi.beswell.com:10000", null, null)
+let client = new ApiToClient("http://otapi.beswell.com:10000", null, null)
 
 // 挂载为全局方法 
 Vue.prototype.$client = client
@@ -26,6 +27,7 @@ Vue.prototype.$client = client
 import SqliteHelper from './utils/SqliteHelper.js'
 import nfc from './utils/ouu-nfc.js'
 
+Vue.prototype.$store = store
 Vue.prototype.$dbHelper = SqliteHelper
 Vue.prototype.$nfc = nfc
 nfc.listenNFCStatus();
@@ -35,8 +37,8 @@ nfc.listenNFCStatus();
 // #ifdef H5
 
 // 提交前需要注释  本地调试使用
-const vconsole = require('vconsole')
-Vue.prototype.$vconsole = new vconsole() // 使用vconsole
+// const vconsole = require('vconsole')
+// Vue.prototype.$vconsole = new vconsole() // 使用vconsole
 
 import IndexedDB from '@/utils/IndexedDB'
 Vue.prototype.$dbHelper = IndexedDB
@@ -44,6 +46,7 @@ Vue.prototype.$dbHelper = IndexedDB
 // #endif
 
 const app = new Vue({
+	store,
 	...App
 })
 app.$mount()

+ 12 - 24
pages.json

@@ -1,28 +1,16 @@
 {
 	"pages": [{
+		"path": "pages/AO/actionList",
+		"style": {
+			"navigationBarTitleText": "活动列表",
+			"enablePullDownRefresh": true
+		}
+	}, {
 		"path": "pages/AO/mapShow",
 		"style": {
 			"navigationBarTitleText": "场控地图",
 			"enablePullDownRefresh": false
 		}
-	// }, {
-	// 	"path": "pages/AO/mapShow1",
-	// 	"style": {
-	// 		"navigationBarTitleText": "场控地图1",
-	// 		"enablePullDownRefresh": false
-	// 	}
-	// }, {
-	// 	"path": "pages/AO/mapShow2",
-	// 	"style": {
-	// 		"navigationBarTitleText": "场控地图2",
-	// 		"enablePullDownRefresh": false
-	// 	}
-	// }, {
-	// 	"path": "pages/AO/checkPointDetail",
-	// 	"style": {
-	// 		"navigationBarTitleText": "检查点详情",
-	// 		"enablePullDownRefresh": false
-	// 	}
 	}, {
 		"path": "pages/nfc/nfc",
 		"style": {
@@ -52,11 +40,11 @@
 		"borderStyle": "black",
 		"backgroundColor": "#FFFFFF",
 		"list": [{
-		// 	"pagePath": "pages/AO/mapShow",
-		// 	"iconPath": "static/tabbar/checkpoint.png",
-		// 	"selectedIconPath": "static/tabbar/checkpoint_active.png",
-		// 	"text": "场控地图"
-		// }, {
+			// 	"pagePath": "pages/AO/mapShow",
+			// 	"iconPath": "static/tabbar/checkpoint.png",
+			// 	"selectedIconPath": "static/tabbar/checkpoint_active.png",
+			// 	"text": "场控地图"
+			// }, {
 			"pagePath": "pages/verify/verify",
 			"iconPath": "static/tabbar/verify.png",
 			"selectedIconPath": "static/tabbar/verify_active.png",
@@ -68,4 +56,4 @@
 			"text": "NFC"
 		}]
 	}
-}
+}

+ 95 - 0
pages/AO/actionList.vue

@@ -0,0 +1,95 @@
+<template>
+	<view class="warp">
+		<!-- <uni-section title="地点列表" type="line">
+			<uni-data-select v-model="placeId" :localdata="placeList" placeholder="请选择地点" @change="handleShopChange"
+				class="padding" />
+		</uni-section> -->
+
+		<uni-section v-if="actionList.length > 0" title="活动列表" type="line">
+			<uni-list>
+				<uni-list-item v-for="item in actionList" :key="item.id" showArrow :title="item.name" :clickable="true"
+					@click="handleItemClick(item.id)" />
+			</uni-list>
+		</uni-section>
+	</view>
+</template>
+
+<script>
+	import {
+		mapState,
+		mapGetters
+	} from 'vuex'
+	import {
+		DefaultRequest,
+		IdRequest
+	} from "@/grpc/base_pb.js"
+
+	export default {
+		components: {},
+		data() {
+			return {
+				placeId: 0,
+				actionList: [],
+			}
+		},
+		computed: {
+			...mapState([
+				'username', // 映射 this.username 为 store.state.username
+			]),
+			...mapGetters([
+				'metadata'
+			]),
+		},
+		mounted() {},
+		onLoad() {
+			this.loadData()
+		},
+		methods: {
+			async loadData() {
+				this.actionList = await this.getToActionList()
+			},
+			async getToActionList() {
+				try {
+					return new Promise((resolve, reject) => {
+						// 创建请求参数并赋值
+						var request = new DefaultRequest()
+						// 调用客户端相应的grpc方法,发送grpc请求,并接受后台发送回来的返回值
+						this.$client.toActionList(request, this.metadata, (err,
+							response) => {
+							if (err) {
+								console.warn(`[toActionList] err: code = ${err.code}` +
+									`, message = "${err.message}"`)
+								reject(err)
+							} else {
+								let res = response.toObject()
+								// console.log('[toActionList]', res)
+								resolve(res.listList)
+							}
+						})
+					});
+				} catch (e) {
+					console.log('[getToActionList] err', e)
+					reject(e)
+				}
+			},
+			// handleShopChange(actionId) {
+			// 	console.log("actionId:" + actionId)
+			// 	this.getControlInfoList(actionId)
+			// 	this.getShopMap(actionId)
+			// },
+			handleItemClick(actionId) {
+				console.log("actionId:" + actionId)
+				uni.navigateTo({
+					// url: '/pages/checkPoint/checkPointDetail',
+					url: './mapShow?actionId=' + actionId
+				})
+			},
+		}
+	}
+</script>
+
+<style lang="scss">
+	.padding {
+		padding: 0 20rpx;
+	}
+</style>

+ 284 - 111
pages/AO/mapShow.vue

@@ -7,15 +7,44 @@
 				:vertical="fab.vertical" :direction="fab.direction" @trigger="trigger" @fabClick="fabClick" />
 		</view> -->
 
-		<view v-show="popupShow" :style="{ height: popupHeight + 'px' }" class="popup">
-			<scroll-view :scroll-top="0" scroll-y="true" :style="{ height: popupHeight + 'px' }" class="scroll-Y">
-				<uni-list v-for="(item, index) in players" :key="index" :border="true">
-					<!-- 右侧带角标 -->
-					<!-- <uni-list-chat :title="item.name" avatar="https://web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png"
-					note="您收到一条新的消息" time="2020-02-02 20:20" badge-text="12"></uni-list-chat> -->
-					<uni-list-item
-						:title="item.name + ' 打点数: ' + item.effectivenum + ' / ' + item.totalcontrolnum + ' 距离: ' + item.distance + '米 配速: ' + item.pace"
-						:note="'平均心率: ' + item.avghr + ' 最大心率: ' + item.maxhr + ' CAL: ' + item.calorie + ' Ck: ' + item.ck + ' Ei: ' + item.ei">
+		<view v-show="popupShow" :style="extraIcon" class="popup">
+			<scroll-view :scroll-top="0" scroll-y="true"
+				:style="{ height: popupHeight + 'px', width: popupWidth + 'px' }" class="scroll-Y">
+				<uni-list v-for="(item, index) in players" :key="index" :border="true" class="list">
+
+					<!-- <uni-list-item :show-extra-icon="true" :extra-icon="{color: '#4cd964', size: '22', type: 'spinner'}"
+						:title="'(' + (index+1) + ') ' + item.name + ' 打点: ' + item.effectivenum + ' / ' + item.totalcontrolnum + ' 距离: ' + item.distance + '米 配速: ' + item.pace"
+						:note="'平均心率: ' + item.avghr + ' 最大心率: ' + item.maxhr + ' CAL: ' + item.calorie + ' Ck: ' + item.ck + ' Ei: ' + item.ei"
+						:clickable="true" @click="onPlayerListItemClick(item)" :class="{ 
+							'list-item': focusPlayerId != item.id,
+							'list-item-focus': focusPlayerId == item.id 
+							}">
+					</uni-list-item> -->
+
+					<uni-list-item :clickable="true" @click="onPlayerListItemClick(item)" class="list-item" :class="{ 
+							'list-item-focus': focusPlayerId == item.id 
+							}">
+						<template v-slot:header>
+							<!-- <image class="slot-image" src="/static/logo.png" mode="widthFix"></image> -->
+							<div class="slot-image" :style="'background-color:' + getPlayerColor(item.id)"></div>
+						</template>
+						<template v-slot:body>
+							<view class="slot-box">
+								<view class="slot-title">
+									[{{index+1}}] <span class="slot-phone" @click="onPhoneClick(item.phone)">
+										{{item.name}} </span>
+									打点 {{item.effectivenum}}/{{item.totalcontrolnum}} 距离
+									{{item.distance}}米 配速 {{item.pace}}
+								</view>
+								<view class="slot-note">
+									心率 {{item.lasthr}} 平均 {{item.avghr}} 最大 {{item.maxhr}} | CAL
+									{{Math.round(item.calorie/1000)}} Ck {{Math.round(item.ck/1000)}} Ei {{Math.round(item.ei*100)/100}}
+								</view>
+							</view>
+						</template>
+						<!-- <template v-slot:footer>
+							<image class="slot-image" src="/static/logo.png" mode="widthFix"></image>
+						</template> -->
 					</uni-list-item>
 				</uni-list>
 			</scroll-view>
@@ -24,79 +53,8 @@
 	</view>
 </template>
 
-<script module="leaflet" lang="renderjs">
-	import 'leaflet/dist/leaflet.css'
-	import '@/utils/map/leafletHelper.css'
-
-	// import mapHelper from '@/utils/mapHelper'
-	import leafletHelper from '@/utils/map/leafletHelper'
-
-	export default {
-		components: {},
-		// data() {
-		// 	return {},
-		// },
-		// mounted() {
-		// 	uni.$on('myEvent', this.myEventHandler);
-		// },
-		// destroyed() {
-		// 	uni.$off('myEvent', this.myEventHandler);
-		// },
-		beforeDestroy() {
-			// console.log("beforeDestroy")
-			// clearInterval(this.interval)
-			leafletHelper.free()
-		},
-		methods: {
-			// myEventHandler(data) {
-			// 	console.log('视图层接收到数据:', data);
-			// },
-			initMap() {
-				// leafletHelper.init(this, 'map', [36.67175772119628, 117.12792580603369], 17)
-
-				// const mapid = this.actionDetail.mapinfo.lid
-				const mapurl = this.actionDetail.mapinfo.mapurl
-				const centPoint = [this.actionDetail.mapinfo.centerlatitude, this.actionDetail.mapinfo.centerlongitude]
-				const zoomNum = this.actionDetail.mapinfo.defscale
-				leafletHelper.init(this, 'map', centPoint, zoomNum)
-				leafletHelper.addMapLayer(mapurl)
-			},
-			handleMapDrawRoute() {
-				// leafletHelper.global.setCheckPoints(this.checkPoints)
-				leafletHelper.global.setRoutes(this.actionDetail.routesList)
-
-				// leafletHelper.checkPoint.drawAllCheckPoints()
-				// leafletHelper.checkPoint.drawPath()
-				leafletHelper.route.drawAllRoutes()
-				leafletHelper.route.drawAllPath()
-			},
-			handleMapDrawPlayer() {
-				leafletHelper.global.setPlayers(this.players)
-				leafletHelper.global.setPlayersPosition(this.players_position)
-				leafletHelper.player.drawAllPlayers()
-				// leafletHelper.player.drawOnePlayer(2)
-				// leafletHelper.player.drawOnePlayer(3)
-
-				leafletHelper.player.dealStaleData()
-			},
-			handleMapDrawTrail() {
-				// leafletHelper.player.drawOneTrail(2, 10000)
-				// leafletHelper.player.drawOneTrail(3, 10000)
-				// leafletHelper.player.drawOneTrail(2, 0, false)
-				leafletHelper.player.drawAllTrails(3000)
-			},
-			handleMapToggle() {
-				// leafletHelper.checkPoint.toggle(true)
-				leafletHelper.route.toggle(true)
-				leafletHelper.player.togglePlayer(true)
-				leafletHelper.player.toggleTooltip(true)
-				leafletHelper.player.toggleTrail(true)
-			},
-		},
-	}
-</script>
-
 <script>
+	import { mapState, mapGetters } from 'vuex'
 	import {
 		DefaultRequest,
 		IdRequest
@@ -113,11 +71,19 @@
 				deviceOrientation: 'portrait', // 设备方向(竖屏 portrait | 横屏 landscape)
 				flexDirection: 'column',
 				pageHeight: 0,
+				pageWidth: 0,
 				// mapHeight: 0,
 				popupHeight: 0,
-				popupHeightPortrait: 200,	// 竖屏状态下的底部弹框高度
+				popupWidth: 0,
+				popupHeightPortrait: 300, // 竖屏状态下的底部弹框高度
+				popupWidthlandscape: 390, // 横屏状态下的右侧弹框宽度
 				popupType: 'bottom',
 				popupShow: false,
+				extraIcon: {
+					color: '#4cd964',
+					size: '22',
+					type: 'gear-filled'
+				},
 
 				actionId: 2,
 				actionDetail: {},
@@ -128,17 +94,31 @@
 				checkPoints: [],
 				players: [],
 				players_position: [],
+				focusPlayerId: 0,
+				trailTime: 90000,
 			}
 		},
-		computed: {},
+		computed: {
+			...mapState([
+				'username',	// 映射 this.username 为 store.state.username
+			]),
+			...mapGetters([
+				'metadata'
+			]),
+		},
 		mounted() {},
-		onLoad() {
+		onLoad(option) {
+			// console.log('[mapShow] onLoad')
+			// console.log(option.actionId)
+			if (option.actionId > 0) {
+				this.actionId = option.actionId
+				this.loadData(this.actionId)
+			}
 			// 逻辑层中触发自定义事件
 			// uni.$emit('myEvent', {
 			// 	name: 'Uniapp',
 			// 	version: '2.0.0'
 			// })
-			this.loadData(this.actionId)
 		},
 		onReady() {
 			this.layoutInit()
@@ -156,6 +136,39 @@
 			// leafletHelper.free()
 		},
 		methods: {
+			// 全屏展示
+			fullscreen() {
+				if (document.fullscreenElement || document.webkitFullScreenElement || document.mozFullScreenElement ||
+					document.msFullScreenElement) {
+					// alert('当前是全屏')
+					if (document.webkitCancelFullScreen) {
+						document.webkitCancelFullScreen();
+					} else if (document.mozCancelFullScreen) {
+						document.mozCancelFullScreen();
+					} else if (document.exitFullscreen) {
+						document.exitFullscreen();
+					} else {
+						uni.showToast({
+							title: '浏览器不支持全屏API或已被禁用',
+							icon: 'none'
+						})
+					}
+				} else {
+					let elem = document.body;
+					if (elem.webkitRequestFullScreen) {
+						elem.webkitRequestFullScreen();
+					} else if (elem.mozRequestFullScreen) {
+						elem.mozRequestFullScreen();
+					} else if (elem.requestFullScreen) {
+						elem.requestFullscreen();
+					} else {
+						uni.showToast({
+							title: '浏览器不支持全屏API或已被禁用',
+							icon: 'none'
+						})
+					}
+				}
+			},
 			// 布局初始化 设置地图高度
 			layoutInit(windowSize = '') {
 				var windowHeight, windowWidth
@@ -170,12 +183,14 @@
 					windowWidth = windowSize.windowWidth
 				}
 				this.pageHeight = windowHeight
+				this.pageWidth = windowWidth
 
 				if (windowHeight > windowWidth) {
 					console.log('[layoutInit] 竖屏')
 					this.deviceOrientation = 'portrait'
 					this.flexDirection = 'column'
 					this.popupHeight = this.popupHeightPortrait
+					this.popupWidth = this.pageWidth
 					// if (this.popupShow) {
 					// 	this.mapHeight = this.pageHeight - this.popupHeight
 					// } else {
@@ -186,14 +201,18 @@
 					this.deviceOrientation = 'landscape'
 					this.flexDirection = 'row'
 					this.popupHeight = this.pageHeight
+					this.popupWidth = this.popupWidthlandscape
 					// this.mapHeight = this.pageHeight
 				}
 
 			},
 			popupToggle() {
-				// console.log('[popupToggle]')
 				this.popupShow = !this.popupShow
 			},
+			fullScreenToggle() {
+				this.fullscreen()
+				this.layoutInit()
+			},
 			async loadData() {
 				this.actionDetail = await this.getToActionDetail(this.actionId)
 				uni.setNavigationBarTitle({
@@ -225,6 +244,7 @@
 					//// leaflet.leafletHelper.global.setPlayers(that.players)
 					// leafletHelper.global.setPlayersPosition(that.players_position)
 					that.handleMapDrawPlayer()
+					that.handleMapDrawTrail()
 				}, 1000);
 
 				// await mapHelper.handleMapInfo(this, this.mapInfo)
@@ -238,9 +258,9 @@
 						var request = new IdRequest()
 						request.setId(actId)
 						// 调用客户端相应的grpc方法,发送grpc请求,并接受后台发送回来的返回值
-						this.$client.toActionDetail(request, {}, (err, response) => {
+						this.$client.toActionDetail(request, this.metadata, (err, response) => {
 							if (err) {
-								console.log(`[toActionDetail] err: code = ${err.code}` +
+								console.warn(`[toActionDetail] err: code = ${err.code}` +
 									`, message = "${err.message}"`)
 								reject(err)
 							} else {
@@ -263,17 +283,18 @@
 						var request = new IdRequest()
 						request.setId(actId)
 						// 调用客户端相应的grpc方法,发送grpc请求,并接受后台发送回来的返回值
-						this.$client.toUsersInGameDetail(request, {}, (err, response) => {
-							if (err) {
-								console.log(`[toUsersInGameDetail] err: code = ${err.code}` +
-									`, message = "${err.message}"`)
-								reject(err)
-							} else {
-								let res = response.toObject()
-								// console.log('[toUsersInGameDetail]', res)
-								resolve(res.usersList)
-							}
-						})
+						this.$client.toUsersInGameDetail(request, this.metadata, (err,
+							response) => {
+								if (err) {
+									console.warn(`[toUsersInGameDetail] err: code = ${err.code}` +
+										`, message = "${err.message}"`)
+									reject(err)
+								} else {
+									let res = response.toObject()
+									// console.log('[toUsersInGameDetail]', res)
+									resolve(res.usersList)
+								}
+							})
 					});
 				} catch (e) {
 					console.log('[getToUsersInGameDetail] err', e)
@@ -288,23 +309,40 @@
 						var request = new IdRequest()
 						request.setId(actId)
 						// 调用客户端相应的grpc方法,发送grpc请求,并接受后台发送回来的返回值
-						this.$client.toUsersInGameGpsQuery(request, {}, (err, response) => {
-							if (err) {
-								console.log(`[toUsersInGameGpsQuery] err: code = ${err.code}` +
-									`, message = "${err.message}"`)
-								reject(err)
-							} else {
-								let res = response.toObject()
-								// console.log('[toUsersInGameGpsQuery]', res)
-								resolve(res.gpsinfoList)
-							}
-						})
+						this.$client.toUsersInGameGpsQuery(request, this.metadata, (err,
+							response) => {
+								if (err) {
+									console.warn(`[toUsersInGameGpsQuery] err: code = ${err.code}` +
+										`, message = "${err.message}"`)
+									reject(err)
+								} else {
+									let res = response.toObject()
+									// console.log('[toUsersInGameGpsQuery]', res)
+									resolve(res.gpsinfoList)
+								}
+							})
 					});
 				} catch (e) {
 					console.log('[getToUsersInGameGpsQuery] err', e)
 					reject(e)
 				}
 			},
+			onPlayerListItemClick(item) {
+				// console.log("onListItemClick", item)
+				this.handlePlayerListItemClick(item)
+			},
+			onPhoneClick(phoneNumber) {
+				if (phoneNumber.length == 11) {
+					uni.makePhoneCall({
+						phoneNumber: phoneNumber
+					})
+				} else {
+					uni.showToast({
+						title: '手机号码不正确',
+						icon: 'none'
+					})
+				}
+			}
 			// trigger(e) {
 			// 	console.log(e)
 			// 	this.content[e.index].active = !e.item.active
@@ -330,6 +368,88 @@
 	}
 </script>
 
+<script module="leaflet" lang="renderjs">
+	import 'leaflet/dist/leaflet.css'
+	import '@/utils/map/leafletHelper.css'
+
+	// import mapHelper from '@/utils/mapHelper'
+	import leafletHelper from '@/utils/map/leafletHelper'
+
+	export default {
+		components: {},
+		// data() {
+		// 	return {},
+		// },
+		// mounted() {
+		// 	uni.$on('myEvent', this.myEventHandler);
+		// },
+		// destroyed() {
+		// 	uni.$off('myEvent', this.myEventHandler);
+		// },
+		beforeDestroy() {
+			// console.log("beforeDestroy")
+			// clearInterval(this.interval)
+			leafletHelper.free()
+		},
+		methods: {
+			// myEventHandler(data) {
+			// 	console.log('视图层接收到数据:', data);
+			// },
+			initMap() {
+				// leafletHelper.init(this, 'map', [36.67175772119628, 117.12792580603369], 17)
+
+				// const mapid = this.actionDetail.mapinfo.lid
+				const mapurl = this.actionDetail.mapinfo.mapurl
+				const centPoint = [this.actionDetail.mapinfo.centerlatitude, this.actionDetail.mapinfo.centerlongitude]
+				const zoomNum = this.actionDetail.mapinfo.defscale
+				leafletHelper.init(this, 'map', centPoint, zoomNum)
+				leafletHelper.addMapLayer(mapurl)
+			},
+			handleMapDrawRoute() {
+				// leafletHelper.global.setCheckPoints(this.checkPoints)
+				leafletHelper.global.setRoutes(this.actionDetail.routesList)
+
+				// leafletHelper.checkPoint.drawAllCheckPoints()
+				// leafletHelper.checkPoint.drawPath()
+				leafletHelper.route.drawAllRoutes()
+				leafletHelper.route.drawAllPath()
+			},
+			handleMapDrawPlayer() {
+				leafletHelper.global.setPlayers(this.players)
+				leafletHelper.global.setPlayersPosition(this.players_position)
+				leafletHelper.player.drawAllPlayers()
+				// leafletHelper.player.drawOnePlayer(2)
+				// leafletHelper.player.drawOnePlayer(3)
+
+				leafletHelper.global.dealStaleData()
+			},
+			handleMapDrawTrail() {
+				// leafletHelper.player.drawOneTrail(2, 10000)
+				// leafletHelper.player.drawOneTrail(3, 10000)
+				// leafletHelper.player.drawOneTrail(2, 0, false)
+				leafletHelper.player.drawAllTrails(this.trailTime)
+			},
+			handleMapToggle() {
+				// leafletHelper.checkPoint.toggle(true)
+				leafletHelper.route.toggle(true)
+				leafletHelper.player.togglePlayer(true)
+				leafletHelper.player.toggleTooltip(true)
+				leafletHelper.player.toggleTrail(true)
+			},
+			handlePlayerListItemClick(item) {
+				this.focusPlayerId = item.id
+				leafletHelper.player.handleFocusPlayer(this.focusPlayerId)
+			},
+			getPlayerColor(playerId) {
+				if (playerId != this.focusPlayerId)
+					return leafletHelper.player.getPlayerColor(playerId)
+				else
+					return leafletHelper.config.gStyle.marker.focus.fillColor
+			}
+		},
+	}
+</script>
+
 <style lang="scss" scoped>
 	.page {
 		// background-color: red;
@@ -347,13 +467,66 @@
 
 	.popup {
 		// height: 200px;
-		overflow: hidden;
+		// overflow: hidden;
 	}
 
 	.scroll-Y {
 		// height: 100vh;
 	}
 
+	.list {}
+
+	.list-item {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		height: 60px;
+	}
+
+	.list-item-focus {
+		background-color: #fffaef;
+	}
+
+	.slot-box {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: column;
+		align-items: flex-start;
+	}
+
+	.slot-image {
+		/* #ifndef APP-NVUE */
+		display: block;
+		/* #endif */
+		margin-right: 10px;
+		width: 6px;
+		height: 39px;
+		align-self: center;
+	}
+
+	.slot-title {
+		flex: 1;
+		font-size: 14px;
+		color: #424242;
+		// margin-right: 10px;
+	}
+
+	.slot-note {
+		flex: 1;
+		font-size: 12px;
+		color: #7d8da7;
+		// margin-right: 10px;
+	}
+
+	.slot-phone {
+		padding: 0 5px;
+		color: #000;
+		font-weight: bold;
+	}
+
 	// .fab {
 	// 	z-index: 1000;
 	// 	width: 20px;

+ 31 - 0
store/index.js

@@ -0,0 +1,31 @@
+import Vue from 'vue'
+import Vuex from 'vuex'
+
+Vue.use(Vuex); //vue的插件机制
+
+//Vuex.Store 构造器选项
+const store = new Vuex.Store({
+	state: { //存放状态
+		username: "admin",
+		token: 'c74d427b805beeb5501345f87f1a55af',
+	},
+	getters: {
+		metadata: state => {
+			return {
+				token: state.token
+			}
+		}
+	},
+	mutations: {
+		setUsername(state, username) {
+            state.username = username;
+            console.log("[setUsername] state.username = " + username);
+        },
+		setToken(state, token) {
+		    state.token = token;
+		    console.log("[setUsername] state.token = " + token);
+		},
+	}
+})
+
+export default store

+ 16 - 1
utils/map/leafletHelper.js

@@ -26,12 +26,16 @@ export default {
 	init(caller, mapid, centPoint, zoomNum = 17) {
 		patch.run()
 		
+		global.init()
 		global.setCaller(caller)
 
 		global.map = L.map(mapid, {
 			center: centPoint,
 			zoom: zoomNum,
 			zoomControl: true,
+			updateWhenIdle: false,
+			updateInterval: 10,
+			keepBuffer: 1024,
 			attributionControl: false
 		});
 		// global.map = L.map(mapid, {
@@ -93,7 +97,7 @@ export default {
 		route.init()
 	},
 
-	addMapLayer(mapurl, minZoom = 15, maxZoom = 20) {
+	addMapLayer(mapurl, minZoom = 16, maxZoom = 18) {
 		// console.log('[addMapLayer] mapurl', mapurl)
 		// var mapurl = 'static/map/' + mapid + '/{z}/{x}/{y}.png'
 		global.map_layer = L.tileLayer(mapurl, {
@@ -153,6 +157,9 @@ export default {
 				this.elList = L.DomUtil.create('a', 'leaflet-control-common')
 				this.elList.innerHTML = '<span>列表</span>'
 				
+				this.elFullScreen = L.DomUtil.create('a', 'leaflet-control-common')
+				this.elFullScreen.innerHTML = '<span>全屏</span>'
+				
 				// this._container.style.display = 'flex'
 				// this._container.appendChild(this.elCheckPoint)
 				this._container.appendChild(this.elRoute)
@@ -160,6 +167,7 @@ export default {
 				this._container.appendChild(this.elPlayerTooltip)
 				this._container.appendChild(this.elPlayerTrail)
 				this._container.appendChild(this.elList)
+				this._container.appendChild(this.elFullScreen)
 				
 				//注册事件
 				// L.DomEvent.addListener(this.elCheckPoint, 'click', function (ev) {
@@ -199,6 +207,13 @@ export default {
 					// global._caller.popup('bottom')
 				}, this)
 				
+				L.DomEvent.addListener(this.elFullScreen, 'click dblclick', function (ev) {
+				    L.DomEvent.stopPropagation(ev)
+					L.DomEvent.preventDefault(ev)
+					global._caller.fullScreenToggle()
+					// global._caller.popup('bottom')
+				}, this)
+				
 				//返回这个主元素
 				return this._container
 			},

+ 22 - 13
utils/map/sub/config.js

@@ -1,13 +1,18 @@
 export default {
 	// 全局样式
 	gStyle: {
+		// 通用样式
+		common: {
+			stroke: true, // 是否描边
+			color: 'white', // 描边颜色
+		},
 		// 玩家定位标记点
 		marker: {
 			default: {
 				radius: 8, // 圆的半径 px
-				stroke: true, // 是否描边
-				color: 'blue', // 描边颜色
-				weight: 3, // 描边宽度 px
+				// stroke: true, // 是否描边
+				// color: 'white', // 描边颜色
+				weight: 1.6, // 描边宽度 px
 				opacity: 1.0, // 描边不透明度
 				fill: true, // 是否填充
 				fillColor: 'blue', // 填充颜色
@@ -16,9 +21,9 @@ export default {
 			},
 			focus: {
 				radius: 8,
-				stroke: true, // 是否描边
-				color: 'red', // 描边颜色
-				weight: 3, // 描边宽度 px
+				// stroke: true, // 是否描边
+				// color: 'white', // 描边颜色
+				weight: 1.6, // 描边宽度 px
 				opacity: 1.0, // 描边不透明度
 				fill: true, // 是否填充
 				fillColor: 'red', // 填充颜色
@@ -38,22 +43,22 @@ export default {
 				smoothFactor: 0.5, // 值越大线条越平滑,值越小线条越精确
 				stroke: true, // 是否描边
 				color: 'blue', // 描边颜色
-				weight: 3, // 描边宽度 px
+				// weight: 8, // 描边宽度 px
 				opacity: 1.0, // 描边不透明度
 				fill: false, // 是否填充
-				fillColor: 'blue', // 填充颜色
-				fillOpacity: 1.0, // 填充不透明度
+				// fillColor: 'blue', // 填充颜色
+				// fillOpacity: 1.0, // 填充不透明度
 				pane: 'markerPane'
 			},
 			focus: {
 				smoothFactor: 0.5, // 值越大线条越平滑,值越小线条越精确
 				stroke: true, // 是否描边
 				color: 'red', // 描边颜色
-				weight: 3, // 描边宽度 px
+				// weight: 8, // 描边宽度 px
 				opacity: 1.0, // 描边不透明度
 				fill: false, // 是否填充
-				fillColor: 'red', // 填充颜色
-				fillOpacity: 1.0, // 填充不透明度
+				// fillColor: 'red', // 填充颜色
+				// fillOpacity: 1.0, // 填充不透明度
 				pane: 'markerPane'
 			}
 		},
@@ -101,5 +106,9 @@ export default {
 				interactive: true
 			}
 		},
-	}
+	},	
+	playerColorList: [
+		"#D112B7", "#5312D1", "#1272D1", "#21AEAE", "#612D61",
+		"#F6DE00", "#FF7904", "#FF8E97", "#003C71", "#850000"
+	]
 }

+ 51 - 0
utils/map/sub/global.js

@@ -21,6 +21,17 @@ export default {
 	checkPoints: [], // 检查点列表(指针复制 每次grpc获取数据后之前旧数据会丢弃)
 	routes: [], // 路线列表(指针复制 每次grpc获取数据后之前旧数据会丢弃)
 	
+	init() {
+		this._caller = null
+		this.storePlayers.length = 0 // 清空数组
+		this.map = null
+		this.map_layer = null
+		this.players.length = 0 // 清空数组
+		this.players_position.length = 0 // 清空数组
+		this.focusPlayerId = 0
+		this.checkPoints.length = 0 // 清空数组
+		this.routes.length = 0 // 清空数组
+	},
 	setCaller(data) {
 		this._caller = data // 指针复制,是同一个对象
 	},
@@ -90,4 +101,44 @@ export default {
 		// console.log("[getCheckPointById]", rtId, route)
 		return route
 	},
+	// 处理过期数据
+	dealStaleData() {
+		for (let i = 0; i < this.storePlayers.length; i++) {
+			var storePlayer = this.storePlayers[i]
+	
+			if (storePlayer == null || !(storePlayer.id > 0)) {
+				continue
+			}
+	
+			// 查找最新的玩家记录列表
+			var player = this.getPlayerById(storePlayer.id)
+			if (player == null) { // 未找到 说明记录已过期
+				// console.warn('[dealStaleData] 发现过期数据', storePlayer)
+	
+				if (storePlayer.marker != null) {
+					storePlayer.marker.removeFrom(storePlayer.markerLayerGroup)
+					storePlayer.marker = null
+				}
+	
+				if (storePlayer.trail != null) {
+					storePlayer.trail.removeFrom(storePlayer.trailLayerGroup)
+					storePlayer.trail2.removeFrom(storePlayer.trailLayerGroup)
+					storePlayer.trail = null
+					storePlayer.trail2 = null
+					storePlayer.trailData = []
+				}
+	
+				if (storePlayer.interval_creatCircleMarker != null) {
+					clearInterval(storePlayer.interval_creatCircleMarker)
+				}
+	
+				if (storePlayer.interval_creatCircleMarker != null) {
+					clearInterval(storePlayer.interval_showTrail)
+				}
+				
+				// delete删除元素之后数组长度不变,只是被删除元素被置为empty
+				// delete this.storePlayers[i] 
+			}
+		}
+	},
 }

+ 148 - 97
utils/map/sub/player.js

@@ -70,41 +70,7 @@ export default {
 			toggleTrailFlag = true
 		}
 	},
-	// 处理过期数据
-	dealStaleData() {
-		for (let i = 0; i < global.storePlayers.length; i++) {
-			var storePlayer = global.storePlayers[i]
-
-			if (!(storePlayer.id > 0)) {
-				continue
-			}
-
-			// 查找最新的玩家记录列表
-			var player = global.getPlayerById(storePlayer.id)
-			if (player == null) { // 未找到 说明记录已过期
-				console.warn('[dealStaleData] 发现过期数据', storePlayer)
-
-				if (storePlayer.marker != null) {
-					storePlayer.marker.removeFrom(this.playerLayerGroup)
-					storePlayer.marker = null
-				}
-
-				if (storePlayer.trail != null) {
-					storePlayer.trail.removeFrom(this.trailLayerGroup)
-					storePlayer.trail = null
-					storePlayer.trailData = []
-				}
-
-				if (storePlayer.interval_creatCircleMarker != null) {
-					clearInterval(storePlayer.interval_creatCircleMarker)
-				}
 
-				if (storePlayer.interval_creatCircleMarker != null) {
-					clearInterval(storePlayer.interval_showTrail)
-				}
-			}
-		}
-	},
 	drawAllPlayers() {
 		// console.log('[drawAllPlayers]', global.players)
 		// if (this.playerLayerGroup != null)
@@ -173,6 +139,7 @@ export default {
 				storePlayer = {
 					id: playerId,
 					marker: marker, // 玩家标识
+					markerLayerGroup: this.playerLayerGroup,
 					trail: null, // 玩家轨迹
 					trailData: [], // 玩家轨迹信息
 					interval_creatCircleMarker: null,
@@ -181,6 +148,7 @@ export default {
 				global.storePlayers.push(storePlayer)
 			} else {
 				storePlayer.marker = marker
+				storePlayer.markerLayerGroup = this.playerLayerGroup
 			}
 		}
 		// 非首次创建,直接移动位置
@@ -228,6 +196,19 @@ export default {
 
 		return interval_creatCircleMarker
 	},
+	getPopupContent(player) {
+		var popupContent = '<div style="line-height: 20px;">'
+		popupContent += '<div style="color: blue">' + ' <span onClick="uni.makePhoneCall({phoneNumber: \'' + player
+			.phone + '\'});">' + player.name + '</span></div>'
+		popupContent += '<div>打点 ' + player.effectivenum + '/' + player.totalcontrolnum +
+			' 距离 ' + player.distance + '米 配速 ' + player.pace + '</div>'
+		popupContent += '<div>' + '心率 ' + player.lasthr + ' 平均 ' + player.avghr + ' 最大 ' + player.maxhr + '</div>'
+		popupContent += '<div>CAL ' + Math.round(player.calorie / 1000) + ' Ck ' + Math.round(player.ck / 1000) +
+			' Ei ' + Math.round(player.ei * 100) / 100 + '</div>'
+		popupContent += '</div>'
+
+		return popupContent
+	},
 	drawOnePlayer(playerId, animate = true) {
 		var that = this
 		var player = global.getPlayerById(playerId)
@@ -235,19 +216,30 @@ export default {
 		var storePlayer = global.getStorePlayersById(playerId)
 		// console.log('[drawOnePlayer]', player, player_position)
 
-		if (player == null || player_position == null) {
-			console.warn('[drawOnePlayer] 关键数据为空', player, player_position)
+		if (player == null) {
+			console.warn('[drawOnePlayer] 玩家数据为空', player)
+			return
+		}
+		if (player_position == null) {
+			// console.log('[drawOnePlayer] 玩家位置数据为空', player_position)
 			return
 		}
 
+		var popupContent = this.getPopupContent(player)
+
 		// 首次创建
 		if (storePlayer == null || storePlayer.marker == null) {
 			// console.log('[drawOnePlayer] storePlayer == null', playerId)
-			var marker = L.circleMarker([player_position.latitude, player_position.longitude], config.gStyle.marker
-					.default)
+			var playerColor = this.getPlayerColor(playerId)
+			var options = config.gStyle.marker.default
+			options.fillColor = playerColor
+			options.stroke = config.gStyle.common.stroke
+			options.color = config.gStyle.common.color
+			// console.log('[drawOnePlayer] options', options)
+
+			var marker = L.circleMarker([player_position.latitude, player_position.longitude], options)
 				.addTo(this.playerLayerGroup)
-				// .addTo(global.map)
-				// .bindPopup("Hello, I'm a Marker!<br><img src='my-image.png' width='100'>").openPopup()
+				.bindPopup(popupContent)
 				.bindTooltip(`${player.name}`, config.gStyle.marker.tooltip)
 
 			marker.type = 'circleMarker'
@@ -272,7 +264,7 @@ export default {
 
 			var interval_creatCircleMarker = null
 			if (animate) {
-				interval_creatCircleMarker = this.animateCircle(marker, 3, 9, 0.5)
+				interval_creatCircleMarker = this.animateCircle(marker, 5, 10, 0.5)
 			}
 
 			// this.playerLayerGroup.addTo(global.map)
@@ -281,7 +273,10 @@ export default {
 				storePlayer = {
 					id: playerId,
 					marker: marker, // 玩家标识
-					trail: null, // 玩家轨迹
+					markerLayerGroup: this.playerLayerGroup,
+					trail: null, // 玩家轨迹 外层描边轨迹
+					trail2: null, // 玩家轨迹 内层填充轨迹
+					trailLayerGroup: null,
 					trailData: [], // 玩家轨迹信息
 					interval_creatCircleMarker: interval_creatCircleMarker,
 					interval_showTrail: null,
@@ -289,6 +284,7 @@ export default {
 				global.storePlayers.push(storePlayer)
 			} else {
 				storePlayer.marker = marker
+				storePlayer.markerLayerGroup = this.playerLayerGroup
 				storePlayer.interval_creatCircleMarker = interval_creatCircleMarker
 			}
 		}
@@ -297,8 +293,9 @@ export default {
 			if (!toggleTrailFlag) {
 				var marker = storePlayer.marker
 				var curPoint = [player_position.latitude, player_position.longitude]
-				// console.warn('[drawOnePlayer] 更新玩家的标记位置', storePlayer.marker, curPoint)
+				// console.log('[drawOnePlayer] 更新玩家的标记位置', storePlayer.marker, curPoint)
 				marker.setLatLng(curPoint)
+				marker.setPopupContent(popupContent)
 			}
 		}
 	},
@@ -308,28 +305,46 @@ export default {
 		if (global.focusPlayerId > 0) {
 			// 先把之前选中的目标恢复成默认状态
 			var unfocusPlayer = global.getStorePlayersById(global.focusPlayerId)
-			// var unfocusPlayer = global.getPlayerById(global.focusPlayerId)
-			if (unfocusPlayer.marker != null && unfocusPlayer.marker.type == 'circleMarker') {
-				unfocusPlayer.marker.setStyle(config.gStyle.marker.default)
+			// console.log("unfocusPlayer", unfocusPlayer)
+			var playerColor = this.getPlayerColor(global.focusPlayerId)
+			if (unfocusPlayer != null && unfocusPlayer.marker != null && unfocusPlayer.marker.type == 'circleMarker') {
+				var options = config.gStyle.marker.default
+				options.fillColor = playerColor
+
+				unfocusPlayer.marker.setStyle(options)
 			}
-			if (unfocusPlayer.trail != null) {
-				unfocusPlayer.trail.setStyle(config.gStyle.trail.default)
+			if (unfocusPlayer != null && unfocusPlayer.trail != null) {
+				var options = config.gStyle.trail.default
+				options.color = playerColor
+
+				unfocusPlayer.trail2.setStyle(options)
 			}
 		}
 
 		global.focusPlayerId = playerId
+		global._caller.focusPlayerId = playerId
 		var focusPlayer = global.getStorePlayersById(global.focusPlayerId)
-		// var focusPlayer = global.getPlayerById(global.focusPlayerId)
-		if (focusPlayer.marker != null && focusPlayer.marker.type == 'circleMarker') {
-			focusPlayer.marker.setStyle(config.gStyle.marker.focus)
+		// console.log("focusPlayer", focusPlayer)
+		if (focusPlayer != null && focusPlayer.trail != null) {
+			var options = config.gStyle.trail.focus
+		
+			focusPlayer.trail2.setStyle(options)
+			focusPlayer.trail.bringToFront()
+			focusPlayer.trail2.bringToFront()
 		}
-		if (focusPlayer.trail != null) {
-			focusPlayer.trail.setStyle(config.gStyle.trail.focus)
+		
+		if (focusPlayer != null && focusPlayer.marker != null && focusPlayer.marker.type == 'circleMarker') {
+			var options = config.gStyle.marker.focus
+			options.stroke = config.gStyle.common.stroke
+			options.color = config.gStyle.common.color
+
+			focusPlayer.marker.setStyle(options)
+			focusPlayer.marker.bringToFront()
 		}
 	},
 	drawAllTrails(duration) {
-		if (this.trailLayerGroup != null)
-			this.trailLayerGroup.clearLayers()
+		// if (this.trailLayerGroup != null)
+		// 	this.trailLayerGroup.clearLayers()
 
 		for (let i = 0; i < global.players.length; i++) {
 			this.drawOneTrail(global.players[i].id, duration)
@@ -342,29 +357,53 @@ export default {
 		var storePlayer = global.getStorePlayersById(playerId)
 		// console.log('[drawOneTrail] param', player, player_position, storePlayer)
 
-		if (player == null || player_position == null) {
-			console.warn('[drawOneTrail] 关键数据为空', player, player_position)
+		if (player == null) {
+			console.warn('[drawOneTrail] 玩家数据为空', player)
+			return
+		}
+		if (player_position == null) {
+			// console.log('[drawOneTrail] 玩家位置数据为空', player_position)
 			return
 		}
-
-		var trail = null
-		var curPoint = [player_position.latitude, player_position.longitude, new Date()]
-		// console.log('[drawOneTrail] curPoint', curPoint)
 
 		if (storePlayer == null || storePlayer.trail == null) {
 			// console.warn('[drawOneTrail] 轨迹数据为空', player, storePlayer)
+
+			var trail = null
+			var trail2 = null
+			var curPoint = [player_position.latitude, player_position.longitude, new Date()]
+			// console.log('[drawOneTrail] curPoint', curPoint)
+
 			var trailData = [curPoint]
+			var options = config.gStyle.trail.default
 
-			trail = L.polyline(trailData, config.gStyle.trail.default)
+			// 外层描边轨迹
+			if (config.gStyle.common.stroke) {
+				options.weight = 6.9
+			} else {
+				options.weight = 0
+			}
+			options.color = config.gStyle.common.color
+			trail = L.polyline(trailData, options)
 				.addTo(this.trailLayerGroup)
-			// .addTo(global.map)
 			// console.log('[drawOneTrail] trail', trail)
 
+			// 内层填充轨迹
+			var playerColor = this.getPlayerColor(playerId)
+			options.weight = 3.9
+			options.color = playerColor
+			// options.fillColor = playerColor
+			trail2 = L.polyline(trailData, options)
+				.addTo(this.trailLayerGroup)
+
 			if (storePlayer == null) {
 				storePlayer = {
 					id: playerId,
 					marker: null, // 玩家标识
-					trail: trail, // 玩家轨迹
+					markerLayerGroup: null,
+					trail: trail, // 玩家轨迹 外层描边轨迹
+					trail2: trail2, // 玩家轨迹 内层填充轨迹
+					trailLayerGroup: this.trailLayerGroup,
 					trailData: trailData, // 玩家轨迹信息
 					interval_creatCircleMarker: null,
 					interval_showTrail: null,
@@ -372,10 +411,12 @@ export default {
 				global.storePlayers.push(storePlayer)
 			} else {
 				storePlayer.trail = trail
+				storePlayer.trail2 = trail2
+				storePlayer.trailLayerGroup = this.trailLayerGroup
 				storePlayer.trailData = trailData
 			}
 
-			// var that = this
+			var that = this
 			var interval_showTrail = setInterval(function() {
 				// 去除过期的历史轨迹
 				if (duration > 0) {
@@ -384,20 +425,24 @@ export default {
 						return now - point[2] < duration;
 					});
 				}
-				
+
 				player_position = global.getPlayerPositionById(playerId)
 				curPoint = [player_position.latitude, player_position.longitude, new Date()]
 				storePlayer.trailData.push(curPoint)
 				// storePlayer.trailData.push(curPoint.slice(0, 2))
-				
+
 				if (toggleTrailFlag) {
 					// console.log('interval_showTrail', storePlayer.trailData)
 					trail.setLatLngs(storePlayer.trailData);
+					trail2.setLatLngs(storePlayer.trailData);
 
 					if (storePlayer.marker != null) {
 						if (toggleTrailFlag) {
 							// console.warn('[drawOneTrail] 更新玩家的标记位置', storePlayer.marker, curPoint)
 							storePlayer.marker.setLatLng(curPoint.slice(0, 2)) // 更新玩家的标记位置
+							storePlayer.marker.bringToFront()
+							var popupContent = that.getPopupContent(player)
+							storePlayer.marker.setPopupContent(popupContent)
 						}
 					}
 					// global.map.setView(point.slice(0, 2), 18); //地图中心跟踪最新位置
@@ -405,39 +450,45 @@ export default {
 			}, 500);
 
 			storePlayer.interval_showTrail = interval_showTrail
+		} else {
+			// console.log('[drawOneTrail] 更新玩家轨迹', storePlayer, storePlayer.trail)
 		}
 	},
-	// duration: 轨迹保存时间 为0表示保存全部轨迹
-	getCurPos(lastpos, duration, player_trail) {
-		// console.log(lastpos, pointsT)
-		var now = +new Date();
-		if (duration > 0) {
-			player_trail.points = player_trail.points.filter(function(point) {
-				return now - point[2] < duration;
-			});
-		}
-
-		var step = 0.00001
-		var t = 10
-		var point = null
-		if (player_trail.pointsT < 20 * t)
-			point = [lastpos[0] + Math.random() * step, lastpos[1] + Math.random() * step, now];
-		else if (player_trail.pointsT >= 20 * t && player_trail.pointsT < 40 * t)
-			point = [lastpos[0] - Math.random() * step, lastpos[1] + Math.random() * step, now];
-		else if (player_trail.pointsT >= 40 * t && player_trail.pointsT < 60 * t)
-			point = [lastpos[0] - Math.random() * step, lastpos[1] - Math.random() * step, now];
-		else if (player_trail.pointsT >= 60 * t && player_trail.pointsT < 80 * t)
-			point = [lastpos[0] + Math.random() * step, lastpos[1] - Math.random() * step, now];
-
-		// point = [point[0] - Math.random() * 0.00001, point[1] - Math.random() * 0.00001, now];
-
-		player_trail.pointsT++
-		if (player_trail.pointsT >= 80 * t)
-			player_trail.pointsT = 0
-		player_trail.points.push(point);
-
-		return point
+	getPlayerColor(playerId) {
+		var colorIndex = playerId % 10
+		return config.playerColorList[colorIndex]
 	},
+	// // duration: 轨迹保存时间 为0表示保存全部轨迹
+	// getCurPos(lastpos, duration, player_trail) {
+	// 	// console.log(lastpos, pointsT)
+	// 	var now = +new Date();
+	// 	if (duration > 0) {
+	// 		player_trail.points = player_trail.points.filter(function(point) {
+	// 			return now - point[2] < duration;
+	// 		});
+	// 	}
+
+	// 	var step = 0.00001
+	// 	var t = 10
+	// 	var point = null
+	// 	if (player_trail.pointsT < 20 * t)
+	// 		point = [lastpos[0] + Math.random() * step, lastpos[1] + Math.random() * step, now];
+	// 	else if (player_trail.pointsT >= 20 * t && player_trail.pointsT < 40 * t)
+	// 		point = [lastpos[0] - Math.random() * step, lastpos[1] + Math.random() * step, now];
+	// 	else if (player_trail.pointsT >= 40 * t && player_trail.pointsT < 60 * t)
+	// 		point = [lastpos[0] - Math.random() * step, lastpos[1] - Math.random() * step, now];
+	// 	else if (player_trail.pointsT >= 60 * t && player_trail.pointsT < 80 * t)
+	// 		point = [lastpos[0] + Math.random() * step, lastpos[1] - Math.random() * step, now];
+
+	// 	// point = [point[0] - Math.random() * 0.00001, point[1] - Math.random() * 0.00001, now];
+
+	// 	player_trail.pointsT++
+	// 	if (player_trail.pointsT >= 80 * t)
+	// 		player_trail.pointsT = 0
+	// 	player_trail.points.push(point);
+
+	// 	return point
+	// },
 	free() {
 		for (let i = 0; i < global.storePlayers.length; i++) {
 			var storePlayer = global.storePlayers[i]

+ 10 - 7
utils/map/sub/route.js

@@ -136,22 +136,25 @@ export default {
 	},
 	drawOnePath(rtId) {
 		var cpList = global.getRouteById(rtId).controlPointSortedListList
+		// console.log("[drawOnePath] cpList", cpList)
 
 		var latlngs = []
 		for (var i = 0; i < cpList.length; i++) {
 			var position = cpList[i].ciposition
-			latlngs.push([position.latitude, position.longitude])
+			if (position.latitude != null && position.longitude != null) {
+				latlngs.push([position.latitude, position.longitude])
+			}
 		}
 
 		var radius = config.gStyle.checkPoint.default.radius
-		var Lines = this.getIntersection(latlngs, radius) // 获取(圆与路线的)交叉点坐标
+		// var Lines = this.getIntersection(latlngs, radius) // 获取(圆与路线的)交叉点坐标
 
-		// var polyline = L.polyline(latlngs, config.gStyle.checkPointPath.default)
-		var polyline = L.polyline(Lines, config.gStyle.checkPointPath.default)
-			.addTo(this.cpPathLayerGroup)
+		// // var polyline = L.polyline(latlngs, config.gStyle.checkPointPath.default)
+		// var polyline = L.polyline(Lines, config.gStyle.checkPointPath.default)
+		// 	.addTo(this.cpPathLayerGroup)
 
-		// this.cpPathLayerGroup.addTo(global.map)
-		this.cpPathLayerGroup.bringToBack()
+		// // this.cpPathLayerGroup.addTo(global.map)
+		// this.cpPathLayerGroup.bringToBack()
 	},
 	// 获取(圆与路线的)交叉点坐标
 	getIntersection(LatLngArry, radius) {