#465 12123

Stängd
zhangbo wants to merge 41 commits from algorithm/master into algorithm/f-pine-recall-cate12-person
40 ändrade filer med 11426 tillägg och 94 borttagningar
  1. 5 1
      recommend-server-client/pom.xml
  2. 15 2
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/common/Common.java
  3. 979 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/common/TabProto.java
  4. 57 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/common/TabProtoOrBuilder.java
  5. 23 22
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/Recommend.java
  6. 188 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/RecommendRequest.java
  7. 15 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/RecommendRequestOrBuilder.java
  8. 72 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/tab/Tab.java
  9. 1936 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/tab/TabRequest.java
  10. 152 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/tab/TabRequestOrBuilder.java
  11. 958 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/tab/TabResponse.java
  12. 48 0
      recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/tab/TabResponseOrBuilder.java
  13. 8 0
      recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/common.proto
  14. 1 0
      recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/recommend.proto
  15. 27 0
      recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/tab.proto
  16. 1 1
      recommend-server-service/pom.xml
  17. 23 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/common/enums/TabSource.java
  18. 35 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/common/enums/TabType.java
  19. 2 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/model/RecommendParam.java
  20. 14 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/model/Tab.java
  21. 28 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/model/TabParam.java
  22. 22 4
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/RecommendService.java
  23. 3 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankParam.java
  24. 15 1
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankRouter.java
  25. 10 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankService.java
  26. 62 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankSequenceStrategy.java
  27. 124 9
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV536.java
  28. 4 3
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV565.java
  29. 240 37
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV568.java
  30. 15 4
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/tansform/FGEncoderManager.java
  31. 3 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallParam.java
  32. 30 2
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallService.java
  33. 88 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/PersonalizationTabRovnRecallStrategy.java
  34. 3 3
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/UserCate1RecallStrategyV568.java
  35. 3 3
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/UserCate2RecallStrategyV568.java
  36. 1 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/score/ScorerUtils.java
  37. 228 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/tab/TabService.java
  38. 34 0
      recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/web/TabController.java
  39. 15 0
      recommend-server-service/src/main/resources/feeds_score_config_dnn_v25_v7.conf
  40. 5939 0
      recommend-server-service/src/main/resources/fg/feature_list_v25_v7.json

+ 5 - 1
recommend-server-client/pom.xml

@@ -10,7 +10,11 @@
     <modelVersion>4.0.0</modelVersion>
 
     <artifactId>recommend-server-client</artifactId>
-    <version>1.1.13</version>
+    <version>1.1.14</version>
+
+    <!-- <properties> -->
+    <!--     <os.detected.classifier>osx-x86_64</os.detected.classifier> -->
+    <!-- </properties> -->
 
     <dependencies>
         <dependency>

+ 15 - 2
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/common/Common.java

@@ -19,6 +19,11 @@ public final class Common {
   static final 
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_Result_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_TabProto_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_TabProto_fieldAccessorTable;
 
   public static com.google.protobuf.Descriptors.FileDescriptor
       getDescriptor() {
@@ -30,8 +35,10 @@ public final class Common {
     java.lang.String[] descriptorData = {
       "\n/com/tzld/piaoquan/recommend/server/com" +
       "mon.proto\"\'\n\006Result\022\014\n\004code\030\001 \001(\005\022\017\n\007mes" +
-      "sage\030\002 \001(\tB1\n-com.tzld.piaoquan.recommen" +
-      "d.server.gen.commonP\001b\006proto3"
+      "sage\030\002 \001(\t\"D\n\010TabProto\022\013\n\003key\030\001 \001(\t\022\r\n\005t" +
+      "itle\030\002 \001(\t\022\014\n\004type\030\003 \001(\t\022\016\n\006source\030\004 \001(\t" +
+      "B1\n-com.tzld.piaoquan.recommend.server.g" +
+      "en.commonP\001b\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
@@ -43,6 +50,12 @@ public final class Common {
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_Result_descriptor,
         new java.lang.String[] { "Code", "Message", });
+    internal_static_TabProto_descriptor =
+      getDescriptor().getMessageTypes().get(1);
+    internal_static_TabProto_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_TabProto_descriptor,
+        new java.lang.String[] { "Key", "Title", "Type", "Source", });
   }
 
   // @@protoc_insertion_point(outer_class_scope)

+ 979 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/common/TabProto.java

@@ -0,0 +1,979 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/common.proto
+
+package com.tzld.piaoquan.recommend.server.gen.common;
+
+/**
+ * <pre>
+ * Tab标签信息
+ * </pre>
+ *
+ * Protobuf type {@code TabProto}
+ */
+public final class TabProto extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:TabProto)
+    TabProtoOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use TabProto.newBuilder() to construct.
+  private TabProto(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private TabProto() {
+    key_ = "";
+    title_ = "";
+    type_ = "";
+    source_ = "";
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new TabProto();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private TabProto(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            key_ = s;
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            title_ = s;
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            type_ = s;
+            break;
+          }
+          case 34: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            source_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return com.tzld.piaoquan.recommend.server.gen.common.Common.internal_static_TabProto_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return com.tzld.piaoquan.recommend.server.gen.common.Common.internal_static_TabProto_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            com.tzld.piaoquan.recommend.server.gen.common.TabProto.class, com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder.class);
+  }
+
+  public static final int KEY_FIELD_NUMBER = 1;
+  private volatile java.lang.Object key_;
+  /**
+   * <code>string key = 1;</code>
+   * @return The key.
+   */
+  @java.lang.Override
+  public java.lang.String getKey() {
+    java.lang.Object ref = key_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      key_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string key = 1;</code>
+   * @return The bytes for key.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getKeyBytes() {
+    java.lang.Object ref = key_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      key_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int TITLE_FIELD_NUMBER = 2;
+  private volatile java.lang.Object title_;
+  /**
+   * <code>string title = 2;</code>
+   * @return The title.
+   */
+  @java.lang.Override
+  public java.lang.String getTitle() {
+    java.lang.Object ref = title_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      title_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string title = 2;</code>
+   * @return The bytes for title.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getTitleBytes() {
+    java.lang.Object ref = title_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      title_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int TYPE_FIELD_NUMBER = 3;
+  private volatile java.lang.Object type_;
+  /**
+   * <code>string type = 3;</code>
+   * @return The type.
+   */
+  @java.lang.Override
+  public java.lang.String getType() {
+    java.lang.Object ref = type_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      type_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string type = 3;</code>
+   * @return The bytes for type.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getTypeBytes() {
+    java.lang.Object ref = type_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      type_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int SOURCE_FIELD_NUMBER = 4;
+  private volatile java.lang.Object source_;
+  /**
+   * <code>string source = 4;</code>
+   * @return The source.
+   */
+  @java.lang.Override
+  public java.lang.String getSource() {
+    java.lang.Object ref = source_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      source_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string source = 4;</code>
+   * @return The bytes for source.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getSourceBytes() {
+    java.lang.Object ref = source_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      source_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (!getKeyBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 1, key_);
+    }
+    if (!getTitleBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, title_);
+    }
+    if (!getTypeBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, type_);
+    }
+    if (!getSourceBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 4, source_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (!getKeyBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, key_);
+    }
+    if (!getTitleBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, title_);
+    }
+    if (!getTypeBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, type_);
+    }
+    if (!getSourceBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(4, source_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof com.tzld.piaoquan.recommend.server.gen.common.TabProto)) {
+      return super.equals(obj);
+    }
+    com.tzld.piaoquan.recommend.server.gen.common.TabProto other = (com.tzld.piaoquan.recommend.server.gen.common.TabProto) obj;
+
+    if (!getKey()
+        .equals(other.getKey())) return false;
+    if (!getTitle()
+        .equals(other.getTitle())) return false;
+    if (!getType()
+        .equals(other.getType())) return false;
+    if (!getSource()
+        .equals(other.getSource())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + KEY_FIELD_NUMBER;
+    hash = (53 * hash) + getKey().hashCode();
+    hash = (37 * hash) + TITLE_FIELD_NUMBER;
+    hash = (53 * hash) + getTitle().hashCode();
+    hash = (37 * hash) + TYPE_FIELD_NUMBER;
+    hash = (53 * hash) + getType().hashCode();
+    hash = (37 * hash) + SOURCE_FIELD_NUMBER;
+    hash = (53 * hash) + getSource().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static com.tzld.piaoquan.recommend.server.gen.common.TabProto parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.common.TabProto parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.common.TabProto parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.common.TabProto parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.common.TabProto parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.common.TabProto parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.common.TabProto parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.common.TabProto parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.common.TabProto parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.common.TabProto parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.common.TabProto parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.common.TabProto parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(com.tzld.piaoquan.recommend.server.gen.common.TabProto prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * <pre>
+   * Tab标签信息
+   * </pre>
+   *
+   * Protobuf type {@code TabProto}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:TabProto)
+      com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.tzld.piaoquan.recommend.server.gen.common.Common.internal_static_TabProto_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.tzld.piaoquan.recommend.server.gen.common.Common.internal_static_TabProto_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.tzld.piaoquan.recommend.server.gen.common.TabProto.class, com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.common.TabProto.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      key_ = "";
+
+      title_ = "";
+
+      type_ = "";
+
+      source_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return com.tzld.piaoquan.recommend.server.gen.common.Common.internal_static_TabProto_descriptor;
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.common.TabProto getDefaultInstanceForType() {
+      return com.tzld.piaoquan.recommend.server.gen.common.TabProto.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.common.TabProto build() {
+      com.tzld.piaoquan.recommend.server.gen.common.TabProto result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.common.TabProto buildPartial() {
+      com.tzld.piaoquan.recommend.server.gen.common.TabProto result = new com.tzld.piaoquan.recommend.server.gen.common.TabProto(this);
+      result.key_ = key_;
+      result.title_ = title_;
+      result.type_ = type_;
+      result.source_ = source_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof com.tzld.piaoquan.recommend.server.gen.common.TabProto) {
+        return mergeFrom((com.tzld.piaoquan.recommend.server.gen.common.TabProto)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(com.tzld.piaoquan.recommend.server.gen.common.TabProto other) {
+      if (other == com.tzld.piaoquan.recommend.server.gen.common.TabProto.getDefaultInstance()) return this;
+      if (!other.getKey().isEmpty()) {
+        key_ = other.key_;
+        onChanged();
+      }
+      if (!other.getTitle().isEmpty()) {
+        title_ = other.title_;
+        onChanged();
+      }
+      if (!other.getType().isEmpty()) {
+        type_ = other.type_;
+        onChanged();
+      }
+      if (!other.getSource().isEmpty()) {
+        source_ = other.source_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      com.tzld.piaoquan.recommend.server.gen.common.TabProto parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (com.tzld.piaoquan.recommend.server.gen.common.TabProto) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+
+    private java.lang.Object key_ = "";
+    /**
+     * <code>string key = 1;</code>
+     * @return The key.
+     */
+    public java.lang.String getKey() {
+      java.lang.Object ref = key_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        key_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string key = 1;</code>
+     * @return The bytes for key.
+     */
+    public com.google.protobuf.ByteString
+        getKeyBytes() {
+      java.lang.Object ref = key_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        key_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string key = 1;</code>
+     * @param value The key to set.
+     * @return This builder for chaining.
+     */
+    public Builder setKey(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      key_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string key = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearKey() {
+      
+      key_ = getDefaultInstance().getKey();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string key = 1;</code>
+     * @param value The bytes for key to set.
+     * @return This builder for chaining.
+     */
+    public Builder setKeyBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      key_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object title_ = "";
+    /**
+     * <code>string title = 2;</code>
+     * @return The title.
+     */
+    public java.lang.String getTitle() {
+      java.lang.Object ref = title_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        title_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string title = 2;</code>
+     * @return The bytes for title.
+     */
+    public com.google.protobuf.ByteString
+        getTitleBytes() {
+      java.lang.Object ref = title_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        title_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string title = 2;</code>
+     * @param value The title to set.
+     * @return This builder for chaining.
+     */
+    public Builder setTitle(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      title_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string title = 2;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearTitle() {
+      
+      title_ = getDefaultInstance().getTitle();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string title = 2;</code>
+     * @param value The bytes for title to set.
+     * @return This builder for chaining.
+     */
+    public Builder setTitleBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      title_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object type_ = "";
+    /**
+     * <code>string type = 3;</code>
+     * @return The type.
+     */
+    public java.lang.String getType() {
+      java.lang.Object ref = type_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        type_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string type = 3;</code>
+     * @return The bytes for type.
+     */
+    public com.google.protobuf.ByteString
+        getTypeBytes() {
+      java.lang.Object ref = type_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        type_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string type = 3;</code>
+     * @param value The type to set.
+     * @return This builder for chaining.
+     */
+    public Builder setType(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      type_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string type = 3;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearType() {
+      
+      type_ = getDefaultInstance().getType();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string type = 3;</code>
+     * @param value The bytes for type to set.
+     * @return This builder for chaining.
+     */
+    public Builder setTypeBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      type_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object source_ = "";
+    /**
+     * <code>string source = 4;</code>
+     * @return The source.
+     */
+    public java.lang.String getSource() {
+      java.lang.Object ref = source_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        source_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string source = 4;</code>
+     * @return The bytes for source.
+     */
+    public com.google.protobuf.ByteString
+        getSourceBytes() {
+      java.lang.Object ref = source_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        source_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string source = 4;</code>
+     * @param value The source to set.
+     * @return This builder for chaining.
+     */
+    public Builder setSource(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      source_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string source = 4;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearSource() {
+      
+      source_ = getDefaultInstance().getSource();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string source = 4;</code>
+     * @param value The bytes for source to set.
+     * @return This builder for chaining.
+     */
+    public Builder setSourceBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      source_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:TabProto)
+  }
+
+  // @@protoc_insertion_point(class_scope:TabProto)
+  private static final com.tzld.piaoquan.recommend.server.gen.common.TabProto DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new com.tzld.piaoquan.recommend.server.gen.common.TabProto();
+  }
+
+  public static com.tzld.piaoquan.recommend.server.gen.common.TabProto getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<TabProto>
+      PARSER = new com.google.protobuf.AbstractParser<TabProto>() {
+    @java.lang.Override
+    public TabProto parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new TabProto(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<TabProto> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<TabProto> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.common.TabProto getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 57 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/common/TabProtoOrBuilder.java

@@ -0,0 +1,57 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/common.proto
+
+package com.tzld.piaoquan.recommend.server.gen.common;
+
+public interface TabProtoOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:TabProto)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>string key = 1;</code>
+   * @return The key.
+   */
+  java.lang.String getKey();
+  /**
+   * <code>string key = 1;</code>
+   * @return The bytes for key.
+   */
+  com.google.protobuf.ByteString
+      getKeyBytes();
+
+  /**
+   * <code>string title = 2;</code>
+   * @return The title.
+   */
+  java.lang.String getTitle();
+  /**
+   * <code>string title = 2;</code>
+   * @return The bytes for title.
+   */
+  com.google.protobuf.ByteString
+      getTitleBytes();
+
+  /**
+   * <code>string type = 3;</code>
+   * @return The type.
+   */
+  java.lang.String getType();
+  /**
+   * <code>string type = 3;</code>
+   * @return The bytes for type.
+   */
+  com.google.protobuf.ByteString
+      getTypeBytes();
+
+  /**
+   * <code>string source = 4;</code>
+   * @return The source.
+   */
+  java.lang.String getSource();
+  /**
+   * <code>string source = 4;</code>
+   * @return The bytes for source.
+   */
+  com.google.protobuf.ByteString
+      getSourceBytes();
+}

+ 23 - 22
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/Recommend.java

@@ -61,7 +61,7 @@ public final class Recommend {
       "\n2com/tzld/piaoquan/recommend/server/rec" +
       "ommend.proto\032\031google/protobuf/any.proto\032" +
       "/com/tzld/piaoquan/recommend/server/comm" +
-      "on.proto\"\241\006\n\020RecommendRequest\022\022\n\nrequest" +
+      "on.proto\"\271\006\n\020RecommendRequest\022\022\n\nrequest" +
       "_id\030\001 \001(\t\022\013\n\003mid\030\002 \001(\t\022\013\n\003uid\030\003 \001(\t\022\014\n\004s" +
       "ize\030\004 \001(\005\022\020\n\010app_type\030\005 \001(\005\022\021\n\tcity_code" +
       "\030\006 \001(\t\022\025\n\rprovince_code\030\007 \001(\t\022\023\n\013ab_exp_" +
@@ -80,26 +80,27 @@ public final class Recommend {
       "_list\030\034 \003(\0132\025.VideoActionInfoProto\022\030\n\020re" +
       "quest_video_id\030\035 \001(\003\022\033\n\023current_page_sou" +
       "rce\030\036 \001(\t\022\017\n\007openGId\030\037 \001(\t\022\020\n\010union_id\030 " +
-      " \001(\t\032.\n\014EventIdEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005val" +
-      "ue\030\002 \001(\t:\0028\001\"\177\n\020MachineInfoProto\022\r\n\005bran" +
-      "d\030\001 \001(\t\022\r\n\005model\030\002 \001(\t\022\020\n\010platform\030\003 \001(\t" +
-      "\022\023\n\013sdk_version\030\004 \001(\t\022\016\n\006system\030\005 \001(\t\022\026\n" +
-      "\016wechat_version\030\006 \001(\t\"H\n\021RecommendRespon" +
-      "se\022\027\n\006result\030\001 \001(\0132\007.Result\022\032\n\005video\030\002 \003" +
-      "(\0132\013.VideoProto\"\336\001\n\nVideoProto\022\020\n\010video_" +
-      "id\030\001 \001(\003\022\021\n\trov_score\030\002 \001(\001\022\021\n\tpush_from" +
-      "\030\003 \001(\t\022\017\n\007ab_code\030\004 \001(\t\022\022\n\nsort_score\030\005 " +
-      "\001(\001\022\020\n\010position\030\006 \001(\005\022\021\n\tflow_pool\030\007 \001(\t" +
-      "\022\027\n\017is_in_flow_pool\030\010 \001(\005\022\014\n\004rand\030\t \001(\001\022" +
-      "\'\n\017push_from_index\030\n \003(\0132\016.PushFromIndex" +
-      "\"1\n\rPushFromIndex\022\021\n\tpush_from\030\001 \001(\t\022\r\n\005" +
-      "index\030\002 \003(\t\"4\n\024VideoActionInfoProto\022\020\n\010v" +
-      "ideo_id\030\001 \001(\003\022\n\n\002ts\030\002 \001(\0032\212\001\n\020RecommendS" +
-      "ervice\022:\n\021HomepageRecommend\022\021.RecommendR" +
-      "equest\032\022.RecommendResponse\022:\n\021RelevantRe" +
-      "commend\022\021.RecommendRequest\032\022.RecommendRe" +
-      "sponseB7\n0com.tzld.piaoquan.recommend.se" +
-      "rver.gen.recommendP\001\210\001\001b\006proto3"
+      " \001(\t\022\026\n\003tab\030! \001(\0132\t.TabProto\032.\n\014EventIdE" +
+      "ntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"\177\n\020" +
+      "MachineInfoProto\022\r\n\005brand\030\001 \001(\t\022\r\n\005model" +
+      "\030\002 \001(\t\022\020\n\010platform\030\003 \001(\t\022\023\n\013sdk_version\030" +
+      "\004 \001(\t\022\016\n\006system\030\005 \001(\t\022\026\n\016wechat_version\030" +
+      "\006 \001(\t\"H\n\021RecommendResponse\022\027\n\006result\030\001 \001" +
+      "(\0132\007.Result\022\032\n\005video\030\002 \003(\0132\013.VideoProto\"" +
+      "\336\001\n\nVideoProto\022\020\n\010video_id\030\001 \001(\003\022\021\n\trov_" +
+      "score\030\002 \001(\001\022\021\n\tpush_from\030\003 \001(\t\022\017\n\007ab_cod" +
+      "e\030\004 \001(\t\022\022\n\nsort_score\030\005 \001(\001\022\020\n\010position\030" +
+      "\006 \001(\005\022\021\n\tflow_pool\030\007 \001(\t\022\027\n\017is_in_flow_p" +
+      "ool\030\010 \001(\005\022\014\n\004rand\030\t \001(\001\022\'\n\017push_from_ind" +
+      "ex\030\n \003(\0132\016.PushFromIndex\"1\n\rPushFromInde" +
+      "x\022\021\n\tpush_from\030\001 \001(\t\022\r\n\005index\030\002 \003(\t\"4\n\024V" +
+      "ideoActionInfoProto\022\020\n\010video_id\030\001 \001(\003\022\n\n" +
+      "\002ts\030\002 \001(\0032\212\001\n\020RecommendService\022:\n\021Homepa" +
+      "geRecommend\022\021.RecommendRequest\032\022.Recomme" +
+      "ndResponse\022:\n\021RelevantRecommend\022\021.Recomm" +
+      "endRequest\032\022.RecommendResponseB7\n0com.tz" +
+      "ld.piaoquan.recommend.server.gen.recomme" +
+      "ndP\001\210\001\001b\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
@@ -112,7 +113,7 @@ public final class Recommend {
     internal_static_RecommendRequest_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_RecommendRequest_descriptor,
-        new java.lang.String[] { "RequestId", "Mid", "Uid", "Size", "AppType", "CityCode", "ProvinceCode", "AbExpCode", "EventId", "VersionAuditStatus", "RecommendTraceId", "VideoId", "City", "Province", "MachineInfo", "NewExpGroup", "SessionId", "SubSessionId", "PageSource", "CategoryId", "HotSceneType", "ClientIp", "VersionCode", "RootSourceId", "UserShareDepth", "PageNum", "RootSessionId", "ShareList", "RequestVideoId", "CurrentPageSource", "OpenGId", "UnionId", });
+        new java.lang.String[] { "RequestId", "Mid", "Uid", "Size", "AppType", "CityCode", "ProvinceCode", "AbExpCode", "EventId", "VersionAuditStatus", "RecommendTraceId", "VideoId", "City", "Province", "MachineInfo", "NewExpGroup", "SessionId", "SubSessionId", "PageSource", "CategoryId", "HotSceneType", "ClientIp", "VersionCode", "RootSourceId", "UserShareDepth", "PageNum", "RootSessionId", "ShareList", "RequestVideoId", "CurrentPageSource", "OpenGId", "UnionId", "Tab", });
     internal_static_RecommendRequest_EventIdEntry_descriptor =
       internal_static_RecommendRequest_descriptor.getNestedTypes().get(0);
     internal_static_RecommendRequest_EventIdEntry_fieldAccessorTable = new

+ 188 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/RecommendRequest.java

@@ -273,6 +273,19 @@ private static final long serialVersionUID = 0L;
             unionId_ = s;
             break;
           }
+          case 266: {
+            com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder subBuilder = null;
+            if (tab_ != null) {
+              subBuilder = tab_.toBuilder();
+            }
+            tab_ = input.readMessage(com.tzld.piaoquan.recommend.server.gen.common.TabProto.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(tab_);
+              tab_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
           default: {
             if (!parseUnknownField(
                 input, unknownFields, extensionRegistry, tag)) {
@@ -1342,6 +1355,32 @@ private static final long serialVersionUID = 0L;
     }
   }
 
+  public static final int TAB_FIELD_NUMBER = 33;
+  private com.tzld.piaoquan.recommend.server.gen.common.TabProto tab_;
+  /**
+   * <code>.TabProto tab = 33;</code>
+   * @return Whether the tab field is set.
+   */
+  @java.lang.Override
+  public boolean hasTab() {
+    return tab_ != null;
+  }
+  /**
+   * <code>.TabProto tab = 33;</code>
+   * @return The tab.
+   */
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.common.TabProto getTab() {
+    return tab_ == null ? com.tzld.piaoquan.recommend.server.gen.common.TabProto.getDefaultInstance() : tab_;
+  }
+  /**
+   * <code>.TabProto tab = 33;</code>
+   */
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder getTabOrBuilder() {
+    return getTab();
+  }
+
   private byte memoizedIsInitialized = -1;
   @java.lang.Override
   public final boolean isInitialized() {
@@ -1455,6 +1494,9 @@ private static final long serialVersionUID = 0L;
     if (!getUnionIdBytes().isEmpty()) {
       com.google.protobuf.GeneratedMessageV3.writeString(output, 32, unionId_);
     }
+    if (tab_ != null) {
+      output.writeMessage(33, getTab());
+    }
     unknownFields.writeTo(output);
   }
 
@@ -1583,6 +1625,10 @@ private static final long serialVersionUID = 0L;
     if (!getUnionIdBytes().isEmpty()) {
       size += com.google.protobuf.GeneratedMessageV3.computeStringSize(32, unionId_);
     }
+    if (tab_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(33, getTab());
+    }
     size += unknownFields.getSerializedSize();
     memoizedSize = size;
     return size;
@@ -1665,6 +1711,11 @@ private static final long serialVersionUID = 0L;
         .equals(other.getOpenGId())) return false;
     if (!getUnionId()
         .equals(other.getUnionId())) return false;
+    if (hasTab() != other.hasTab()) return false;
+    if (hasTab()) {
+      if (!getTab()
+          .equals(other.getTab())) return false;
+    }
     if (!unknownFields.equals(other.unknownFields)) return false;
     return true;
   }
@@ -1751,6 +1802,10 @@ private static final long serialVersionUID = 0L;
     hash = (53 * hash) + getOpenGId().hashCode();
     hash = (37 * hash) + UNION_ID_FIELD_NUMBER;
     hash = (53 * hash) + getUnionId().hashCode();
+    if (hasTab()) {
+      hash = (37 * hash) + TAB_FIELD_NUMBER;
+      hash = (53 * hash) + getTab().hashCode();
+    }
     hash = (29 * hash) + unknownFields.hashCode();
     memoizedHashCode = hash;
     return hash;
@@ -1978,6 +2033,12 @@ private static final long serialVersionUID = 0L;
 
       unionId_ = "";
 
+      if (tabBuilder_ == null) {
+        tab_ = null;
+      } else {
+        tab_ = null;
+        tabBuilder_ = null;
+      }
       return this;
     }
 
@@ -2054,6 +2115,11 @@ private static final long serialVersionUID = 0L;
       result.currentPageSource_ = currentPageSource_;
       result.openGId_ = openGId_;
       result.unionId_ = unionId_;
+      if (tabBuilder_ == null) {
+        result.tab_ = tab_;
+      } else {
+        result.tab_ = tabBuilder_.build();
+      }
       onBuilt();
       return result;
     }
@@ -2246,6 +2312,9 @@ private static final long serialVersionUID = 0L;
         unionId_ = other.unionId_;
         onChanged();
       }
+      if (other.hasTab()) {
+        mergeTab(other.getTab());
+      }
       this.mergeUnknownFields(other.unknownFields);
       onChanged();
       return this;
@@ -4643,6 +4712,125 @@ private static final long serialVersionUID = 0L;
       onChanged();
       return this;
     }
+
+    private com.tzld.piaoquan.recommend.server.gen.common.TabProto tab_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.tzld.piaoquan.recommend.server.gen.common.TabProto, com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder, com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder> tabBuilder_;
+    /**
+     * <code>.TabProto tab = 33;</code>
+     * @return Whether the tab field is set.
+     */
+    public boolean hasTab() {
+      return tabBuilder_ != null || tab_ != null;
+    }
+    /**
+     * <code>.TabProto tab = 33;</code>
+     * @return The tab.
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.TabProto getTab() {
+      if (tabBuilder_ == null) {
+        return tab_ == null ? com.tzld.piaoquan.recommend.server.gen.common.TabProto.getDefaultInstance() : tab_;
+      } else {
+        return tabBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.TabProto tab = 33;</code>
+     */
+    public Builder setTab(com.tzld.piaoquan.recommend.server.gen.common.TabProto value) {
+      if (tabBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        tab_ = value;
+        onChanged();
+      } else {
+        tabBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.TabProto tab = 33;</code>
+     */
+    public Builder setTab(
+        com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder builderForValue) {
+      if (tabBuilder_ == null) {
+        tab_ = builderForValue.build();
+        onChanged();
+      } else {
+        tabBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.TabProto tab = 33;</code>
+     */
+    public Builder mergeTab(com.tzld.piaoquan.recommend.server.gen.common.TabProto value) {
+      if (tabBuilder_ == null) {
+        if (tab_ != null) {
+          tab_ =
+            com.tzld.piaoquan.recommend.server.gen.common.TabProto.newBuilder(tab_).mergeFrom(value).buildPartial();
+        } else {
+          tab_ = value;
+        }
+        onChanged();
+      } else {
+        tabBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.TabProto tab = 33;</code>
+     */
+    public Builder clearTab() {
+      if (tabBuilder_ == null) {
+        tab_ = null;
+        onChanged();
+      } else {
+        tab_ = null;
+        tabBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.TabProto tab = 33;</code>
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder getTabBuilder() {
+      
+      onChanged();
+      return getTabFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.TabProto tab = 33;</code>
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder getTabOrBuilder() {
+      if (tabBuilder_ != null) {
+        return tabBuilder_.getMessageOrBuilder();
+      } else {
+        return tab_ == null ?
+            com.tzld.piaoquan.recommend.server.gen.common.TabProto.getDefaultInstance() : tab_;
+      }
+    }
+    /**
+     * <code>.TabProto tab = 33;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.tzld.piaoquan.recommend.server.gen.common.TabProto, com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder, com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder> 
+        getTabFieldBuilder() {
+      if (tabBuilder_ == null) {
+        tabBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.tzld.piaoquan.recommend.server.gen.common.TabProto, com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder, com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder>(
+                getTab(),
+                getParentForChildren(),
+                isClean());
+        tab_ = null;
+      }
+      return tabBuilder_;
+    }
     @java.lang.Override
     public final Builder setUnknownFields(
         final com.google.protobuf.UnknownFieldSet unknownFields) {

+ 15 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/recommend/RecommendRequestOrBuilder.java

@@ -402,4 +402,19 @@ public interface RecommendRequestOrBuilder extends
    */
   com.google.protobuf.ByteString
       getUnionIdBytes();
+
+  /**
+   * <code>.TabProto tab = 33;</code>
+   * @return Whether the tab field is set.
+   */
+  boolean hasTab();
+  /**
+   * <code>.TabProto tab = 33;</code>
+   * @return The tab.
+   */
+  com.tzld.piaoquan.recommend.server.gen.common.TabProto getTab();
+  /**
+   * <code>.TabProto tab = 33;</code>
+   */
+  com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder getTabOrBuilder();
 }

+ 72 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/tab/Tab.java

@@ -0,0 +1,72 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/tab.proto
+
+package com.tzld.piaoquan.recommend.server.gen.tab;
+
+public final class Tab {
+  private Tab() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_TabRequest_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_TabRequest_fieldAccessorTable;
+  static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_TabResponse_descriptor;
+  static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_TabResponse_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n,com/tzld/piaoquan/recommend/server/tab" +
+      ".proto\032\031google/protobuf/any.proto\032/com/t" +
+      "zld/piaoquan/recommend/server/common.pro" +
+      "to\"\326\001\n\nTabRequest\022\022\n\nrequest_id\030\001 \001(\t\022\013\n" +
+      "\003mid\030\002 \001(\t\022\013\n\003uid\030\003 \001(\t\022\020\n\010app_type\030\004 \001(" +
+      "\005\022\020\n\010union_id\030\005 \001(\t\022\021\n\tcity_code\030\006 \001(\t\022\025" +
+      "\n\rprovince_code\030\007 \001(\t\022\014\n\004city\030\010 \001(\t\022\020\n\010p" +
+      "rovince\030\t \001(\t\022\023\n\013ab_exp_code\030\n \003(\t\022\027\n\017ro" +
+      "ot_session_id\030\013 \001(\t\">\n\013TabResponse\022\027\n\006re" +
+      "sult\030\001 \001(\0132\007.Result\022\026\n\003tab\030\002 \003(\0132\t.TabPr" +
+      "otoB1\n*com.tzld.piaoquan.recommend.serve" +
+      "r.gen.tabP\001\210\001\001b\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          com.google.protobuf.AnyProto.getDescriptor(),
+          com.tzld.piaoquan.recommend.server.gen.common.Common.getDescriptor(),
+        });
+    internal_static_TabRequest_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_TabRequest_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_TabRequest_descriptor,
+        new java.lang.String[] { "RequestId", "Mid", "Uid", "AppType", "UnionId", "CityCode", "ProvinceCode", "City", "Province", "AbExpCode", "RootSessionId", });
+    internal_static_TabResponse_descriptor =
+      getDescriptor().getMessageTypes().get(1);
+    internal_static_TabResponse_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_TabResponse_descriptor,
+        new java.lang.String[] { "Result", "Tab", });
+    com.google.protobuf.AnyProto.getDescriptor();
+    com.tzld.piaoquan.recommend.server.gen.common.Common.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}

+ 1936 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/tab/TabRequest.java

@@ -0,0 +1,1936 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/tab.proto
+
+package com.tzld.piaoquan.recommend.server.gen.tab;
+
+/**
+ * Protobuf type {@code TabRequest}
+ */
+public final class TabRequest extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:TabRequest)
+    TabRequestOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use TabRequest.newBuilder() to construct.
+  private TabRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private TabRequest() {
+    requestId_ = "";
+    mid_ = "";
+    uid_ = "";
+    unionId_ = "";
+    cityCode_ = "";
+    provinceCode_ = "";
+    city_ = "";
+    province_ = "";
+    abExpCode_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+    rootSessionId_ = "";
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new TabRequest();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private TabRequest(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            requestId_ = s;
+            break;
+          }
+          case 18: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            mid_ = s;
+            break;
+          }
+          case 26: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            uid_ = s;
+            break;
+          }
+          case 32: {
+
+            appType_ = input.readInt32();
+            break;
+          }
+          case 42: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            unionId_ = s;
+            break;
+          }
+          case 50: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            cityCode_ = s;
+            break;
+          }
+          case 58: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            provinceCode_ = s;
+            break;
+          }
+          case 66: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            city_ = s;
+            break;
+          }
+          case 74: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            province_ = s;
+            break;
+          }
+          case 82: {
+            java.lang.String s = input.readStringRequireUtf8();
+            if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+              abExpCode_ = new com.google.protobuf.LazyStringArrayList();
+              mutable_bitField0_ |= 0x00000001;
+            }
+            abExpCode_.add(s);
+            break;
+          }
+          case 90: {
+            java.lang.String s = input.readStringRequireUtf8();
+
+            rootSessionId_ = s;
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000001) != 0)) {
+        abExpCode_ = abExpCode_.getUnmodifiableView();
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return com.tzld.piaoquan.recommend.server.gen.tab.Tab.internal_static_TabRequest_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return com.tzld.piaoquan.recommend.server.gen.tab.Tab.internal_static_TabRequest_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            com.tzld.piaoquan.recommend.server.gen.tab.TabRequest.class, com.tzld.piaoquan.recommend.server.gen.tab.TabRequest.Builder.class);
+  }
+
+  public static final int REQUEST_ID_FIELD_NUMBER = 1;
+  private volatile java.lang.Object requestId_;
+  /**
+   * <code>string request_id = 1;</code>
+   * @return The requestId.
+   */
+  @java.lang.Override
+  public java.lang.String getRequestId() {
+    java.lang.Object ref = requestId_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      requestId_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string request_id = 1;</code>
+   * @return The bytes for requestId.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getRequestIdBytes() {
+    java.lang.Object ref = requestId_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      requestId_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int MID_FIELD_NUMBER = 2;
+  private volatile java.lang.Object mid_;
+  /**
+   * <code>string mid = 2;</code>
+   * @return The mid.
+   */
+  @java.lang.Override
+  public java.lang.String getMid() {
+    java.lang.Object ref = mid_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      mid_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string mid = 2;</code>
+   * @return The bytes for mid.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getMidBytes() {
+    java.lang.Object ref = mid_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      mid_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int UID_FIELD_NUMBER = 3;
+  private volatile java.lang.Object uid_;
+  /**
+   * <code>string uid = 3;</code>
+   * @return The uid.
+   */
+  @java.lang.Override
+  public java.lang.String getUid() {
+    java.lang.Object ref = uid_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      uid_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string uid = 3;</code>
+   * @return The bytes for uid.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getUidBytes() {
+    java.lang.Object ref = uid_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      uid_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int APP_TYPE_FIELD_NUMBER = 4;
+  private int appType_;
+  /**
+   * <pre>
+   * default 4
+   * </pre>
+   *
+   * <code>int32 app_type = 4;</code>
+   * @return The appType.
+   */
+  @java.lang.Override
+  public int getAppType() {
+    return appType_;
+  }
+
+  public static final int UNION_ID_FIELD_NUMBER = 5;
+  private volatile java.lang.Object unionId_;
+  /**
+   * <code>string union_id = 5;</code>
+   * @return The unionId.
+   */
+  @java.lang.Override
+  public java.lang.String getUnionId() {
+    java.lang.Object ref = unionId_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      unionId_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string union_id = 5;</code>
+   * @return The bytes for unionId.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getUnionIdBytes() {
+    java.lang.Object ref = unionId_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      unionId_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int CITY_CODE_FIELD_NUMBER = 6;
+  private volatile java.lang.Object cityCode_;
+  /**
+   * <code>string city_code = 6;</code>
+   * @return The cityCode.
+   */
+  @java.lang.Override
+  public java.lang.String getCityCode() {
+    java.lang.Object ref = cityCode_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      cityCode_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string city_code = 6;</code>
+   * @return The bytes for cityCode.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getCityCodeBytes() {
+    java.lang.Object ref = cityCode_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      cityCode_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int PROVINCE_CODE_FIELD_NUMBER = 7;
+  private volatile java.lang.Object provinceCode_;
+  /**
+   * <code>string province_code = 7;</code>
+   * @return The provinceCode.
+   */
+  @java.lang.Override
+  public java.lang.String getProvinceCode() {
+    java.lang.Object ref = provinceCode_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      provinceCode_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string province_code = 7;</code>
+   * @return The bytes for provinceCode.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getProvinceCodeBytes() {
+    java.lang.Object ref = provinceCode_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      provinceCode_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int CITY_FIELD_NUMBER = 8;
+  private volatile java.lang.Object city_;
+  /**
+   * <code>string city = 8;</code>
+   * @return The city.
+   */
+  @java.lang.Override
+  public java.lang.String getCity() {
+    java.lang.Object ref = city_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      city_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string city = 8;</code>
+   * @return The bytes for city.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getCityBytes() {
+    java.lang.Object ref = city_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      city_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int PROVINCE_FIELD_NUMBER = 9;
+  private volatile java.lang.Object province_;
+  /**
+   * <code>string province = 9;</code>
+   * @return The province.
+   */
+  @java.lang.Override
+  public java.lang.String getProvince() {
+    java.lang.Object ref = province_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      province_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string province = 9;</code>
+   * @return The bytes for province.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getProvinceBytes() {
+    java.lang.Object ref = province_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      province_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  public static final int AB_EXP_CODE_FIELD_NUMBER = 10;
+  private com.google.protobuf.LazyStringList abExpCode_;
+  /**
+   * <code>repeated string ab_exp_code = 10;</code>
+   * @return A list containing the abExpCode.
+   */
+  public com.google.protobuf.ProtocolStringList
+      getAbExpCodeList() {
+    return abExpCode_;
+  }
+  /**
+   * <code>repeated string ab_exp_code = 10;</code>
+   * @return The count of abExpCode.
+   */
+  public int getAbExpCodeCount() {
+    return abExpCode_.size();
+  }
+  /**
+   * <code>repeated string ab_exp_code = 10;</code>
+   * @param index The index of the element to return.
+   * @return The abExpCode at the given index.
+   */
+  public java.lang.String getAbExpCode(int index) {
+    return abExpCode_.get(index);
+  }
+  /**
+   * <code>repeated string ab_exp_code = 10;</code>
+   * @param index The index of the value to return.
+   * @return The bytes of the abExpCode at the given index.
+   */
+  public com.google.protobuf.ByteString
+      getAbExpCodeBytes(int index) {
+    return abExpCode_.getByteString(index);
+  }
+
+  public static final int ROOT_SESSION_ID_FIELD_NUMBER = 11;
+  private volatile java.lang.Object rootSessionId_;
+  /**
+   * <code>string root_session_id = 11;</code>
+   * @return The rootSessionId.
+   */
+  @java.lang.Override
+  public java.lang.String getRootSessionId() {
+    java.lang.Object ref = rootSessionId_;
+    if (ref instanceof java.lang.String) {
+      return (java.lang.String) ref;
+    } else {
+      com.google.protobuf.ByteString bs = 
+          (com.google.protobuf.ByteString) ref;
+      java.lang.String s = bs.toStringUtf8();
+      rootSessionId_ = s;
+      return s;
+    }
+  }
+  /**
+   * <code>string root_session_id = 11;</code>
+   * @return The bytes for rootSessionId.
+   */
+  @java.lang.Override
+  public com.google.protobuf.ByteString
+      getRootSessionIdBytes() {
+    java.lang.Object ref = rootSessionId_;
+    if (ref instanceof java.lang.String) {
+      com.google.protobuf.ByteString b = 
+          com.google.protobuf.ByteString.copyFromUtf8(
+              (java.lang.String) ref);
+      rootSessionId_ = b;
+      return b;
+    } else {
+      return (com.google.protobuf.ByteString) ref;
+    }
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (!getRequestIdBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 1, requestId_);
+    }
+    if (!getMidBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 2, mid_);
+    }
+    if (!getUidBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 3, uid_);
+    }
+    if (appType_ != 0) {
+      output.writeInt32(4, appType_);
+    }
+    if (!getUnionIdBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 5, unionId_);
+    }
+    if (!getCityCodeBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 6, cityCode_);
+    }
+    if (!getProvinceCodeBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 7, provinceCode_);
+    }
+    if (!getCityBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 8, city_);
+    }
+    if (!getProvinceBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 9, province_);
+    }
+    for (int i = 0; i < abExpCode_.size(); i++) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 10, abExpCode_.getRaw(i));
+    }
+    if (!getRootSessionIdBytes().isEmpty()) {
+      com.google.protobuf.GeneratedMessageV3.writeString(output, 11, rootSessionId_);
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (!getRequestIdBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, requestId_);
+    }
+    if (!getMidBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, mid_);
+    }
+    if (!getUidBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, uid_);
+    }
+    if (appType_ != 0) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeInt32Size(4, appType_);
+    }
+    if (!getUnionIdBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(5, unionId_);
+    }
+    if (!getCityCodeBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(6, cityCode_);
+    }
+    if (!getProvinceCodeBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(7, provinceCode_);
+    }
+    if (!getCityBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(8, city_);
+    }
+    if (!getProvinceBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(9, province_);
+    }
+    {
+      int dataSize = 0;
+      for (int i = 0; i < abExpCode_.size(); i++) {
+        dataSize += computeStringSizeNoTag(abExpCode_.getRaw(i));
+      }
+      size += dataSize;
+      size += 1 * getAbExpCodeList().size();
+    }
+    if (!getRootSessionIdBytes().isEmpty()) {
+      size += com.google.protobuf.GeneratedMessageV3.computeStringSize(11, rootSessionId_);
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof com.tzld.piaoquan.recommend.server.gen.tab.TabRequest)) {
+      return super.equals(obj);
+    }
+    com.tzld.piaoquan.recommend.server.gen.tab.TabRequest other = (com.tzld.piaoquan.recommend.server.gen.tab.TabRequest) obj;
+
+    if (!getRequestId()
+        .equals(other.getRequestId())) return false;
+    if (!getMid()
+        .equals(other.getMid())) return false;
+    if (!getUid()
+        .equals(other.getUid())) return false;
+    if (getAppType()
+        != other.getAppType()) return false;
+    if (!getUnionId()
+        .equals(other.getUnionId())) return false;
+    if (!getCityCode()
+        .equals(other.getCityCode())) return false;
+    if (!getProvinceCode()
+        .equals(other.getProvinceCode())) return false;
+    if (!getCity()
+        .equals(other.getCity())) return false;
+    if (!getProvince()
+        .equals(other.getProvince())) return false;
+    if (!getAbExpCodeList()
+        .equals(other.getAbExpCodeList())) return false;
+    if (!getRootSessionId()
+        .equals(other.getRootSessionId())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    hash = (37 * hash) + REQUEST_ID_FIELD_NUMBER;
+    hash = (53 * hash) + getRequestId().hashCode();
+    hash = (37 * hash) + MID_FIELD_NUMBER;
+    hash = (53 * hash) + getMid().hashCode();
+    hash = (37 * hash) + UID_FIELD_NUMBER;
+    hash = (53 * hash) + getUid().hashCode();
+    hash = (37 * hash) + APP_TYPE_FIELD_NUMBER;
+    hash = (53 * hash) + getAppType();
+    hash = (37 * hash) + UNION_ID_FIELD_NUMBER;
+    hash = (53 * hash) + getUnionId().hashCode();
+    hash = (37 * hash) + CITY_CODE_FIELD_NUMBER;
+    hash = (53 * hash) + getCityCode().hashCode();
+    hash = (37 * hash) + PROVINCE_CODE_FIELD_NUMBER;
+    hash = (53 * hash) + getProvinceCode().hashCode();
+    hash = (37 * hash) + CITY_FIELD_NUMBER;
+    hash = (53 * hash) + getCity().hashCode();
+    hash = (37 * hash) + PROVINCE_FIELD_NUMBER;
+    hash = (53 * hash) + getProvince().hashCode();
+    if (getAbExpCodeCount() > 0) {
+      hash = (37 * hash) + AB_EXP_CODE_FIELD_NUMBER;
+      hash = (53 * hash) + getAbExpCodeList().hashCode();
+    }
+    hash = (37 * hash) + ROOT_SESSION_ID_FIELD_NUMBER;
+    hash = (53 * hash) + getRootSessionId().hashCode();
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabRequest parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabRequest parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabRequest parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabRequest parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabRequest parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabRequest parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabRequest parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabRequest parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabRequest parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabRequest parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabRequest parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabRequest parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(com.tzld.piaoquan.recommend.server.gen.tab.TabRequest prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code TabRequest}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:TabRequest)
+      com.tzld.piaoquan.recommend.server.gen.tab.TabRequestOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.tzld.piaoquan.recommend.server.gen.tab.Tab.internal_static_TabRequest_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.tzld.piaoquan.recommend.server.gen.tab.Tab.internal_static_TabRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.tzld.piaoquan.recommend.server.gen.tab.TabRequest.class, com.tzld.piaoquan.recommend.server.gen.tab.TabRequest.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.tab.TabRequest.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      requestId_ = "";
+
+      mid_ = "";
+
+      uid_ = "";
+
+      appType_ = 0;
+
+      unionId_ = "";
+
+      cityCode_ = "";
+
+      provinceCode_ = "";
+
+      city_ = "";
+
+      province_ = "";
+
+      abExpCode_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+      bitField0_ = (bitField0_ & ~0x00000001);
+      rootSessionId_ = "";
+
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return com.tzld.piaoquan.recommend.server.gen.tab.Tab.internal_static_TabRequest_descriptor;
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.tab.TabRequest getDefaultInstanceForType() {
+      return com.tzld.piaoquan.recommend.server.gen.tab.TabRequest.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.tab.TabRequest build() {
+      com.tzld.piaoquan.recommend.server.gen.tab.TabRequest result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.tab.TabRequest buildPartial() {
+      com.tzld.piaoquan.recommend.server.gen.tab.TabRequest result = new com.tzld.piaoquan.recommend.server.gen.tab.TabRequest(this);
+      int from_bitField0_ = bitField0_;
+      result.requestId_ = requestId_;
+      result.mid_ = mid_;
+      result.uid_ = uid_;
+      result.appType_ = appType_;
+      result.unionId_ = unionId_;
+      result.cityCode_ = cityCode_;
+      result.provinceCode_ = provinceCode_;
+      result.city_ = city_;
+      result.province_ = province_;
+      if (((bitField0_ & 0x00000001) != 0)) {
+        abExpCode_ = abExpCode_.getUnmodifiableView();
+        bitField0_ = (bitField0_ & ~0x00000001);
+      }
+      result.abExpCode_ = abExpCode_;
+      result.rootSessionId_ = rootSessionId_;
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof com.tzld.piaoquan.recommend.server.gen.tab.TabRequest) {
+        return mergeFrom((com.tzld.piaoquan.recommend.server.gen.tab.TabRequest)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(com.tzld.piaoquan.recommend.server.gen.tab.TabRequest other) {
+      if (other == com.tzld.piaoquan.recommend.server.gen.tab.TabRequest.getDefaultInstance()) return this;
+      if (!other.getRequestId().isEmpty()) {
+        requestId_ = other.requestId_;
+        onChanged();
+      }
+      if (!other.getMid().isEmpty()) {
+        mid_ = other.mid_;
+        onChanged();
+      }
+      if (!other.getUid().isEmpty()) {
+        uid_ = other.uid_;
+        onChanged();
+      }
+      if (other.getAppType() != 0) {
+        setAppType(other.getAppType());
+      }
+      if (!other.getUnionId().isEmpty()) {
+        unionId_ = other.unionId_;
+        onChanged();
+      }
+      if (!other.getCityCode().isEmpty()) {
+        cityCode_ = other.cityCode_;
+        onChanged();
+      }
+      if (!other.getProvinceCode().isEmpty()) {
+        provinceCode_ = other.provinceCode_;
+        onChanged();
+      }
+      if (!other.getCity().isEmpty()) {
+        city_ = other.city_;
+        onChanged();
+      }
+      if (!other.getProvince().isEmpty()) {
+        province_ = other.province_;
+        onChanged();
+      }
+      if (!other.abExpCode_.isEmpty()) {
+        if (abExpCode_.isEmpty()) {
+          abExpCode_ = other.abExpCode_;
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          ensureAbExpCodeIsMutable();
+          abExpCode_.addAll(other.abExpCode_);
+        }
+        onChanged();
+      }
+      if (!other.getRootSessionId().isEmpty()) {
+        rootSessionId_ = other.rootSessionId_;
+        onChanged();
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      com.tzld.piaoquan.recommend.server.gen.tab.TabRequest parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (com.tzld.piaoquan.recommend.server.gen.tab.TabRequest) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private java.lang.Object requestId_ = "";
+    /**
+     * <code>string request_id = 1;</code>
+     * @return The requestId.
+     */
+    public java.lang.String getRequestId() {
+      java.lang.Object ref = requestId_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        requestId_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string request_id = 1;</code>
+     * @return The bytes for requestId.
+     */
+    public com.google.protobuf.ByteString
+        getRequestIdBytes() {
+      java.lang.Object ref = requestId_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        requestId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string request_id = 1;</code>
+     * @param value The requestId to set.
+     * @return This builder for chaining.
+     */
+    public Builder setRequestId(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      requestId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string request_id = 1;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearRequestId() {
+      
+      requestId_ = getDefaultInstance().getRequestId();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string request_id = 1;</code>
+     * @param value The bytes for requestId to set.
+     * @return This builder for chaining.
+     */
+    public Builder setRequestIdBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      requestId_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object mid_ = "";
+    /**
+     * <code>string mid = 2;</code>
+     * @return The mid.
+     */
+    public java.lang.String getMid() {
+      java.lang.Object ref = mid_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        mid_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string mid = 2;</code>
+     * @return The bytes for mid.
+     */
+    public com.google.protobuf.ByteString
+        getMidBytes() {
+      java.lang.Object ref = mid_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        mid_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string mid = 2;</code>
+     * @param value The mid to set.
+     * @return This builder for chaining.
+     */
+    public Builder setMid(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      mid_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string mid = 2;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearMid() {
+      
+      mid_ = getDefaultInstance().getMid();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string mid = 2;</code>
+     * @param value The bytes for mid to set.
+     * @return This builder for chaining.
+     */
+    public Builder setMidBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      mid_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object uid_ = "";
+    /**
+     * <code>string uid = 3;</code>
+     * @return The uid.
+     */
+    public java.lang.String getUid() {
+      java.lang.Object ref = uid_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        uid_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string uid = 3;</code>
+     * @return The bytes for uid.
+     */
+    public com.google.protobuf.ByteString
+        getUidBytes() {
+      java.lang.Object ref = uid_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        uid_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string uid = 3;</code>
+     * @param value The uid to set.
+     * @return This builder for chaining.
+     */
+    public Builder setUid(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      uid_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string uid = 3;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearUid() {
+      
+      uid_ = getDefaultInstance().getUid();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string uid = 3;</code>
+     * @param value The bytes for uid to set.
+     * @return This builder for chaining.
+     */
+    public Builder setUidBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      uid_ = value;
+      onChanged();
+      return this;
+    }
+
+    private int appType_ ;
+    /**
+     * <pre>
+     * default 4
+     * </pre>
+     *
+     * <code>int32 app_type = 4;</code>
+     * @return The appType.
+     */
+    @java.lang.Override
+    public int getAppType() {
+      return appType_;
+    }
+    /**
+     * <pre>
+     * default 4
+     * </pre>
+     *
+     * <code>int32 app_type = 4;</code>
+     * @param value The appType to set.
+     * @return This builder for chaining.
+     */
+    public Builder setAppType(int value) {
+      
+      appType_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <pre>
+     * default 4
+     * </pre>
+     *
+     * <code>int32 app_type = 4;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearAppType() {
+      
+      appType_ = 0;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object unionId_ = "";
+    /**
+     * <code>string union_id = 5;</code>
+     * @return The unionId.
+     */
+    public java.lang.String getUnionId() {
+      java.lang.Object ref = unionId_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        unionId_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string union_id = 5;</code>
+     * @return The bytes for unionId.
+     */
+    public com.google.protobuf.ByteString
+        getUnionIdBytes() {
+      java.lang.Object ref = unionId_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        unionId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string union_id = 5;</code>
+     * @param value The unionId to set.
+     * @return This builder for chaining.
+     */
+    public Builder setUnionId(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      unionId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string union_id = 5;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearUnionId() {
+      
+      unionId_ = getDefaultInstance().getUnionId();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string union_id = 5;</code>
+     * @param value The bytes for unionId to set.
+     * @return This builder for chaining.
+     */
+    public Builder setUnionIdBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      unionId_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object cityCode_ = "";
+    /**
+     * <code>string city_code = 6;</code>
+     * @return The cityCode.
+     */
+    public java.lang.String getCityCode() {
+      java.lang.Object ref = cityCode_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        cityCode_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string city_code = 6;</code>
+     * @return The bytes for cityCode.
+     */
+    public com.google.protobuf.ByteString
+        getCityCodeBytes() {
+      java.lang.Object ref = cityCode_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        cityCode_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string city_code = 6;</code>
+     * @param value The cityCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCityCode(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      cityCode_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string city_code = 6;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearCityCode() {
+      
+      cityCode_ = getDefaultInstance().getCityCode();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string city_code = 6;</code>
+     * @param value The bytes for cityCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCityCodeBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      cityCode_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object provinceCode_ = "";
+    /**
+     * <code>string province_code = 7;</code>
+     * @return The provinceCode.
+     */
+    public java.lang.String getProvinceCode() {
+      java.lang.Object ref = provinceCode_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        provinceCode_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string province_code = 7;</code>
+     * @return The bytes for provinceCode.
+     */
+    public com.google.protobuf.ByteString
+        getProvinceCodeBytes() {
+      java.lang.Object ref = provinceCode_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        provinceCode_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string province_code = 7;</code>
+     * @param value The provinceCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setProvinceCode(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      provinceCode_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string province_code = 7;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearProvinceCode() {
+      
+      provinceCode_ = getDefaultInstance().getProvinceCode();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string province_code = 7;</code>
+     * @param value The bytes for provinceCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setProvinceCodeBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      provinceCode_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object city_ = "";
+    /**
+     * <code>string city = 8;</code>
+     * @return The city.
+     */
+    public java.lang.String getCity() {
+      java.lang.Object ref = city_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        city_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string city = 8;</code>
+     * @return The bytes for city.
+     */
+    public com.google.protobuf.ByteString
+        getCityBytes() {
+      java.lang.Object ref = city_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        city_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string city = 8;</code>
+     * @param value The city to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCity(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      city_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string city = 8;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearCity() {
+      
+      city_ = getDefaultInstance().getCity();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string city = 8;</code>
+     * @param value The bytes for city to set.
+     * @return This builder for chaining.
+     */
+    public Builder setCityBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      city_ = value;
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object province_ = "";
+    /**
+     * <code>string province = 9;</code>
+     * @return The province.
+     */
+    public java.lang.String getProvince() {
+      java.lang.Object ref = province_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        province_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string province = 9;</code>
+     * @return The bytes for province.
+     */
+    public com.google.protobuf.ByteString
+        getProvinceBytes() {
+      java.lang.Object ref = province_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        province_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string province = 9;</code>
+     * @param value The province to set.
+     * @return This builder for chaining.
+     */
+    public Builder setProvince(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      province_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string province = 9;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearProvince() {
+      
+      province_ = getDefaultInstance().getProvince();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string province = 9;</code>
+     * @param value The bytes for province to set.
+     * @return This builder for chaining.
+     */
+    public Builder setProvinceBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      province_ = value;
+      onChanged();
+      return this;
+    }
+
+    private com.google.protobuf.LazyStringList abExpCode_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+    private void ensureAbExpCodeIsMutable() {
+      if (!((bitField0_ & 0x00000001) != 0)) {
+        abExpCode_ = new com.google.protobuf.LazyStringArrayList(abExpCode_);
+        bitField0_ |= 0x00000001;
+       }
+    }
+    /**
+     * <code>repeated string ab_exp_code = 10;</code>
+     * @return A list containing the abExpCode.
+     */
+    public com.google.protobuf.ProtocolStringList
+        getAbExpCodeList() {
+      return abExpCode_.getUnmodifiableView();
+    }
+    /**
+     * <code>repeated string ab_exp_code = 10;</code>
+     * @return The count of abExpCode.
+     */
+    public int getAbExpCodeCount() {
+      return abExpCode_.size();
+    }
+    /**
+     * <code>repeated string ab_exp_code = 10;</code>
+     * @param index The index of the element to return.
+     * @return The abExpCode at the given index.
+     */
+    public java.lang.String getAbExpCode(int index) {
+      return abExpCode_.get(index);
+    }
+    /**
+     * <code>repeated string ab_exp_code = 10;</code>
+     * @param index The index of the value to return.
+     * @return The bytes of the abExpCode at the given index.
+     */
+    public com.google.protobuf.ByteString
+        getAbExpCodeBytes(int index) {
+      return abExpCode_.getByteString(index);
+    }
+    /**
+     * <code>repeated string ab_exp_code = 10;</code>
+     * @param index The index to set the value at.
+     * @param value The abExpCode to set.
+     * @return This builder for chaining.
+     */
+    public Builder setAbExpCode(
+        int index, java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureAbExpCodeIsMutable();
+      abExpCode_.set(index, value);
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>repeated string ab_exp_code = 10;</code>
+     * @param value The abExpCode to add.
+     * @return This builder for chaining.
+     */
+    public Builder addAbExpCode(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureAbExpCodeIsMutable();
+      abExpCode_.add(value);
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>repeated string ab_exp_code = 10;</code>
+     * @param values The abExpCode to add.
+     * @return This builder for chaining.
+     */
+    public Builder addAllAbExpCode(
+        java.lang.Iterable<java.lang.String> values) {
+      ensureAbExpCodeIsMutable();
+      com.google.protobuf.AbstractMessageLite.Builder.addAll(
+          values, abExpCode_);
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>repeated string ab_exp_code = 10;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearAbExpCode() {
+      abExpCode_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+      bitField0_ = (bitField0_ & ~0x00000001);
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>repeated string ab_exp_code = 10;</code>
+     * @param value The bytes of the abExpCode to add.
+     * @return This builder for chaining.
+     */
+    public Builder addAbExpCodeBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      ensureAbExpCodeIsMutable();
+      abExpCode_.add(value);
+      onChanged();
+      return this;
+    }
+
+    private java.lang.Object rootSessionId_ = "";
+    /**
+     * <code>string root_session_id = 11;</code>
+     * @return The rootSessionId.
+     */
+    public java.lang.String getRootSessionId() {
+      java.lang.Object ref = rootSessionId_;
+      if (!(ref instanceof java.lang.String)) {
+        com.google.protobuf.ByteString bs =
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        rootSessionId_ = s;
+        return s;
+      } else {
+        return (java.lang.String) ref;
+      }
+    }
+    /**
+     * <code>string root_session_id = 11;</code>
+     * @return The bytes for rootSessionId.
+     */
+    public com.google.protobuf.ByteString
+        getRootSessionIdBytes() {
+      java.lang.Object ref = rootSessionId_;
+      if (ref instanceof String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        rootSessionId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+    /**
+     * <code>string root_session_id = 11;</code>
+     * @param value The rootSessionId to set.
+     * @return This builder for chaining.
+     */
+    public Builder setRootSessionId(
+        java.lang.String value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  
+      rootSessionId_ = value;
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string root_session_id = 11;</code>
+     * @return This builder for chaining.
+     */
+    public Builder clearRootSessionId() {
+      
+      rootSessionId_ = getDefaultInstance().getRootSessionId();
+      onChanged();
+      return this;
+    }
+    /**
+     * <code>string root_session_id = 11;</code>
+     * @param value The bytes for rootSessionId to set.
+     * @return This builder for chaining.
+     */
+    public Builder setRootSessionIdBytes(
+        com.google.protobuf.ByteString value) {
+      if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+      
+      rootSessionId_ = value;
+      onChanged();
+      return this;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:TabRequest)
+  }
+
+  // @@protoc_insertion_point(class_scope:TabRequest)
+  private static final com.tzld.piaoquan.recommend.server.gen.tab.TabRequest DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new com.tzld.piaoquan.recommend.server.gen.tab.TabRequest();
+  }
+
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabRequest getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<TabRequest>
+      PARSER = new com.google.protobuf.AbstractParser<TabRequest>() {
+    @java.lang.Override
+    public TabRequest parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new TabRequest(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<TabRequest> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<TabRequest> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.tab.TabRequest getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 152 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/tab/TabRequestOrBuilder.java

@@ -0,0 +1,152 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/tab.proto
+
+package com.tzld.piaoquan.recommend.server.gen.tab;
+
+public interface TabRequestOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:TabRequest)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>string request_id = 1;</code>
+   * @return The requestId.
+   */
+  java.lang.String getRequestId();
+  /**
+   * <code>string request_id = 1;</code>
+   * @return The bytes for requestId.
+   */
+  com.google.protobuf.ByteString
+      getRequestIdBytes();
+
+  /**
+   * <code>string mid = 2;</code>
+   * @return The mid.
+   */
+  java.lang.String getMid();
+  /**
+   * <code>string mid = 2;</code>
+   * @return The bytes for mid.
+   */
+  com.google.protobuf.ByteString
+      getMidBytes();
+
+  /**
+   * <code>string uid = 3;</code>
+   * @return The uid.
+   */
+  java.lang.String getUid();
+  /**
+   * <code>string uid = 3;</code>
+   * @return The bytes for uid.
+   */
+  com.google.protobuf.ByteString
+      getUidBytes();
+
+  /**
+   * <pre>
+   * default 4
+   * </pre>
+   *
+   * <code>int32 app_type = 4;</code>
+   * @return The appType.
+   */
+  int getAppType();
+
+  /**
+   * <code>string union_id = 5;</code>
+   * @return The unionId.
+   */
+  java.lang.String getUnionId();
+  /**
+   * <code>string union_id = 5;</code>
+   * @return The bytes for unionId.
+   */
+  com.google.protobuf.ByteString
+      getUnionIdBytes();
+
+  /**
+   * <code>string city_code = 6;</code>
+   * @return The cityCode.
+   */
+  java.lang.String getCityCode();
+  /**
+   * <code>string city_code = 6;</code>
+   * @return The bytes for cityCode.
+   */
+  com.google.protobuf.ByteString
+      getCityCodeBytes();
+
+  /**
+   * <code>string province_code = 7;</code>
+   * @return The provinceCode.
+   */
+  java.lang.String getProvinceCode();
+  /**
+   * <code>string province_code = 7;</code>
+   * @return The bytes for provinceCode.
+   */
+  com.google.protobuf.ByteString
+      getProvinceCodeBytes();
+
+  /**
+   * <code>string city = 8;</code>
+   * @return The city.
+   */
+  java.lang.String getCity();
+  /**
+   * <code>string city = 8;</code>
+   * @return The bytes for city.
+   */
+  com.google.protobuf.ByteString
+      getCityBytes();
+
+  /**
+   * <code>string province = 9;</code>
+   * @return The province.
+   */
+  java.lang.String getProvince();
+  /**
+   * <code>string province = 9;</code>
+   * @return The bytes for province.
+   */
+  com.google.protobuf.ByteString
+      getProvinceBytes();
+
+  /**
+   * <code>repeated string ab_exp_code = 10;</code>
+   * @return A list containing the abExpCode.
+   */
+  java.util.List<java.lang.String>
+      getAbExpCodeList();
+  /**
+   * <code>repeated string ab_exp_code = 10;</code>
+   * @return The count of abExpCode.
+   */
+  int getAbExpCodeCount();
+  /**
+   * <code>repeated string ab_exp_code = 10;</code>
+   * @param index The index of the element to return.
+   * @return The abExpCode at the given index.
+   */
+  java.lang.String getAbExpCode(int index);
+  /**
+   * <code>repeated string ab_exp_code = 10;</code>
+   * @param index The index of the value to return.
+   * @return The bytes of the abExpCode at the given index.
+   */
+  com.google.protobuf.ByteString
+      getAbExpCodeBytes(int index);
+
+  /**
+   * <code>string root_session_id = 11;</code>
+   * @return The rootSessionId.
+   */
+  java.lang.String getRootSessionId();
+  /**
+   * <code>string root_session_id = 11;</code>
+   * @return The bytes for rootSessionId.
+   */
+  com.google.protobuf.ByteString
+      getRootSessionIdBytes();
+}

+ 958 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/tab/TabResponse.java

@@ -0,0 +1,958 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/tab.proto
+
+package com.tzld.piaoquan.recommend.server.gen.tab;
+
+/**
+ * Protobuf type {@code TabResponse}
+ */
+public final class TabResponse extends
+    com.google.protobuf.GeneratedMessageV3 implements
+    // @@protoc_insertion_point(message_implements:TabResponse)
+    TabResponseOrBuilder {
+private static final long serialVersionUID = 0L;
+  // Use TabResponse.newBuilder() to construct.
+  private TabResponse(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    super(builder);
+  }
+  private TabResponse() {
+    tab_ = java.util.Collections.emptyList();
+  }
+
+  @java.lang.Override
+  @SuppressWarnings({"unused"})
+  protected java.lang.Object newInstance(
+      UnusedPrivateParameter unused) {
+    return new TabResponse();
+  }
+
+  @java.lang.Override
+  public final com.google.protobuf.UnknownFieldSet
+  getUnknownFields() {
+    return this.unknownFields;
+  }
+  private TabResponse(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    this();
+    if (extensionRegistry == null) {
+      throw new java.lang.NullPointerException();
+    }
+    int mutable_bitField0_ = 0;
+    com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+        com.google.protobuf.UnknownFieldSet.newBuilder();
+    try {
+      boolean done = false;
+      while (!done) {
+        int tag = input.readTag();
+        switch (tag) {
+          case 0:
+            done = true;
+            break;
+          case 10: {
+            com.tzld.piaoquan.recommend.server.gen.common.Result.Builder subBuilder = null;
+            if (result_ != null) {
+              subBuilder = result_.toBuilder();
+            }
+            result_ = input.readMessage(com.tzld.piaoquan.recommend.server.gen.common.Result.parser(), extensionRegistry);
+            if (subBuilder != null) {
+              subBuilder.mergeFrom(result_);
+              result_ = subBuilder.buildPartial();
+            }
+
+            break;
+          }
+          case 18: {
+            if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+              tab_ = new java.util.ArrayList<com.tzld.piaoquan.recommend.server.gen.common.TabProto>();
+              mutable_bitField0_ |= 0x00000001;
+            }
+            tab_.add(
+                input.readMessage(com.tzld.piaoquan.recommend.server.gen.common.TabProto.parser(), extensionRegistry));
+            break;
+          }
+          default: {
+            if (!parseUnknownField(
+                input, unknownFields, extensionRegistry, tag)) {
+              done = true;
+            }
+            break;
+          }
+        }
+      }
+    } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+      throw e.setUnfinishedMessage(this);
+    } catch (java.io.IOException e) {
+      throw new com.google.protobuf.InvalidProtocolBufferException(
+          e).setUnfinishedMessage(this);
+    } finally {
+      if (((mutable_bitField0_ & 0x00000001) != 0)) {
+        tab_ = java.util.Collections.unmodifiableList(tab_);
+      }
+      this.unknownFields = unknownFields.build();
+      makeExtensionsImmutable();
+    }
+  }
+  public static final com.google.protobuf.Descriptors.Descriptor
+      getDescriptor() {
+    return com.tzld.piaoquan.recommend.server.gen.tab.Tab.internal_static_TabResponse_descriptor;
+  }
+
+  @java.lang.Override
+  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internalGetFieldAccessorTable() {
+    return com.tzld.piaoquan.recommend.server.gen.tab.Tab.internal_static_TabResponse_fieldAccessorTable
+        .ensureFieldAccessorsInitialized(
+            com.tzld.piaoquan.recommend.server.gen.tab.TabResponse.class, com.tzld.piaoquan.recommend.server.gen.tab.TabResponse.Builder.class);
+  }
+
+  public static final int RESULT_FIELD_NUMBER = 1;
+  private com.tzld.piaoquan.recommend.server.gen.common.Result result_;
+  /**
+   * <code>.Result result = 1;</code>
+   * @return Whether the result field is set.
+   */
+  @java.lang.Override
+  public boolean hasResult() {
+    return result_ != null;
+  }
+  /**
+   * <code>.Result result = 1;</code>
+   * @return The result.
+   */
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.common.Result getResult() {
+    return result_ == null ? com.tzld.piaoquan.recommend.server.gen.common.Result.getDefaultInstance() : result_;
+  }
+  /**
+   * <code>.Result result = 1;</code>
+   */
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder getResultOrBuilder() {
+    return getResult();
+  }
+
+  public static final int TAB_FIELD_NUMBER = 2;
+  private java.util.List<com.tzld.piaoquan.recommend.server.gen.common.TabProto> tab_;
+  /**
+   * <code>repeated .TabProto tab = 2;</code>
+   */
+  @java.lang.Override
+  public java.util.List<com.tzld.piaoquan.recommend.server.gen.common.TabProto> getTabList() {
+    return tab_;
+  }
+  /**
+   * <code>repeated .TabProto tab = 2;</code>
+   */
+  @java.lang.Override
+  public java.util.List<? extends com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder> 
+      getTabOrBuilderList() {
+    return tab_;
+  }
+  /**
+   * <code>repeated .TabProto tab = 2;</code>
+   */
+  @java.lang.Override
+  public int getTabCount() {
+    return tab_.size();
+  }
+  /**
+   * <code>repeated .TabProto tab = 2;</code>
+   */
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.common.TabProto getTab(int index) {
+    return tab_.get(index);
+  }
+  /**
+   * <code>repeated .TabProto tab = 2;</code>
+   */
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder getTabOrBuilder(
+      int index) {
+    return tab_.get(index);
+  }
+
+  private byte memoizedIsInitialized = -1;
+  @java.lang.Override
+  public final boolean isInitialized() {
+    byte isInitialized = memoizedIsInitialized;
+    if (isInitialized == 1) return true;
+    if (isInitialized == 0) return false;
+
+    memoizedIsInitialized = 1;
+    return true;
+  }
+
+  @java.lang.Override
+  public void writeTo(com.google.protobuf.CodedOutputStream output)
+                      throws java.io.IOException {
+    if (result_ != null) {
+      output.writeMessage(1, getResult());
+    }
+    for (int i = 0; i < tab_.size(); i++) {
+      output.writeMessage(2, tab_.get(i));
+    }
+    unknownFields.writeTo(output);
+  }
+
+  @java.lang.Override
+  public int getSerializedSize() {
+    int size = memoizedSize;
+    if (size != -1) return size;
+
+    size = 0;
+    if (result_ != null) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(1, getResult());
+    }
+    for (int i = 0; i < tab_.size(); i++) {
+      size += com.google.protobuf.CodedOutputStream
+        .computeMessageSize(2, tab_.get(i));
+    }
+    size += unknownFields.getSerializedSize();
+    memoizedSize = size;
+    return size;
+  }
+
+  @java.lang.Override
+  public boolean equals(final java.lang.Object obj) {
+    if (obj == this) {
+     return true;
+    }
+    if (!(obj instanceof com.tzld.piaoquan.recommend.server.gen.tab.TabResponse)) {
+      return super.equals(obj);
+    }
+    com.tzld.piaoquan.recommend.server.gen.tab.TabResponse other = (com.tzld.piaoquan.recommend.server.gen.tab.TabResponse) obj;
+
+    if (hasResult() != other.hasResult()) return false;
+    if (hasResult()) {
+      if (!getResult()
+          .equals(other.getResult())) return false;
+    }
+    if (!getTabList()
+        .equals(other.getTabList())) return false;
+    if (!unknownFields.equals(other.unknownFields)) return false;
+    return true;
+  }
+
+  @java.lang.Override
+  public int hashCode() {
+    if (memoizedHashCode != 0) {
+      return memoizedHashCode;
+    }
+    int hash = 41;
+    hash = (19 * hash) + getDescriptor().hashCode();
+    if (hasResult()) {
+      hash = (37 * hash) + RESULT_FIELD_NUMBER;
+      hash = (53 * hash) + getResult().hashCode();
+    }
+    if (getTabCount() > 0) {
+      hash = (37 * hash) + TAB_FIELD_NUMBER;
+      hash = (53 * hash) + getTabList().hashCode();
+    }
+    hash = (29 * hash) + unknownFields.hashCode();
+    memoizedHashCode = hash;
+    return hash;
+  }
+
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabResponse parseFrom(
+      java.nio.ByteBuffer data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabResponse parseFrom(
+      java.nio.ByteBuffer data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabResponse parseFrom(
+      com.google.protobuf.ByteString data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabResponse parseFrom(
+      com.google.protobuf.ByteString data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabResponse parseFrom(byte[] data)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabResponse parseFrom(
+      byte[] data,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws com.google.protobuf.InvalidProtocolBufferException {
+    return PARSER.parseFrom(data, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabResponse parseFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabResponse parseFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabResponse parseDelimitedFrom(java.io.InputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabResponse parseDelimitedFrom(
+      java.io.InputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabResponse parseFrom(
+      com.google.protobuf.CodedInputStream input)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input);
+  }
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabResponse parseFrom(
+      com.google.protobuf.CodedInputStream input,
+      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+      throws java.io.IOException {
+    return com.google.protobuf.GeneratedMessageV3
+        .parseWithIOException(PARSER, input, extensionRegistry);
+  }
+
+  @java.lang.Override
+  public Builder newBuilderForType() { return newBuilder(); }
+  public static Builder newBuilder() {
+    return DEFAULT_INSTANCE.toBuilder();
+  }
+  public static Builder newBuilder(com.tzld.piaoquan.recommend.server.gen.tab.TabResponse prototype) {
+    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+  }
+  @java.lang.Override
+  public Builder toBuilder() {
+    return this == DEFAULT_INSTANCE
+        ? new Builder() : new Builder().mergeFrom(this);
+  }
+
+  @java.lang.Override
+  protected Builder newBuilderForType(
+      com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+    Builder builder = new Builder(parent);
+    return builder;
+  }
+  /**
+   * Protobuf type {@code TabResponse}
+   */
+  public static final class Builder extends
+      com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+      // @@protoc_insertion_point(builder_implements:TabResponse)
+      com.tzld.piaoquan.recommend.server.gen.tab.TabResponseOrBuilder {
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return com.tzld.piaoquan.recommend.server.gen.tab.Tab.internal_static_TabResponse_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return com.tzld.piaoquan.recommend.server.gen.tab.Tab.internal_static_TabResponse_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              com.tzld.piaoquan.recommend.server.gen.tab.TabResponse.class, com.tzld.piaoquan.recommend.server.gen.tab.TabResponse.Builder.class);
+    }
+
+    // Construct using com.tzld.piaoquan.recommend.server.gen.tab.TabResponse.newBuilder()
+    private Builder() {
+      maybeForceBuilderInitialization();
+    }
+
+    private Builder(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      super(parent);
+      maybeForceBuilderInitialization();
+    }
+    private void maybeForceBuilderInitialization() {
+      if (com.google.protobuf.GeneratedMessageV3
+              .alwaysUseFieldBuilders) {
+        getTabFieldBuilder();
+      }
+    }
+    @java.lang.Override
+    public Builder clear() {
+      super.clear();
+      if (resultBuilder_ == null) {
+        result_ = null;
+      } else {
+        result_ = null;
+        resultBuilder_ = null;
+      }
+      if (tabBuilder_ == null) {
+        tab_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+      } else {
+        tabBuilder_.clear();
+      }
+      return this;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.Descriptor
+        getDescriptorForType() {
+      return com.tzld.piaoquan.recommend.server.gen.tab.Tab.internal_static_TabResponse_descriptor;
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.tab.TabResponse getDefaultInstanceForType() {
+      return com.tzld.piaoquan.recommend.server.gen.tab.TabResponse.getDefaultInstance();
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.tab.TabResponse build() {
+      com.tzld.piaoquan.recommend.server.gen.tab.TabResponse result = buildPartial();
+      if (!result.isInitialized()) {
+        throw newUninitializedMessageException(result);
+      }
+      return result;
+    }
+
+    @java.lang.Override
+    public com.tzld.piaoquan.recommend.server.gen.tab.TabResponse buildPartial() {
+      com.tzld.piaoquan.recommend.server.gen.tab.TabResponse result = new com.tzld.piaoquan.recommend.server.gen.tab.TabResponse(this);
+      int from_bitField0_ = bitField0_;
+      if (resultBuilder_ == null) {
+        result.result_ = result_;
+      } else {
+        result.result_ = resultBuilder_.build();
+      }
+      if (tabBuilder_ == null) {
+        if (((bitField0_ & 0x00000001) != 0)) {
+          tab_ = java.util.Collections.unmodifiableList(tab_);
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.tab_ = tab_;
+      } else {
+        result.tab_ = tabBuilder_.build();
+      }
+      onBuilt();
+      return result;
+    }
+
+    @java.lang.Override
+    public Builder clone() {
+      return super.clone();
+    }
+    @java.lang.Override
+    public Builder setField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.setField(field, value);
+    }
+    @java.lang.Override
+    public Builder clearField(
+        com.google.protobuf.Descriptors.FieldDescriptor field) {
+      return super.clearField(field);
+    }
+    @java.lang.Override
+    public Builder clearOneof(
+        com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+      return super.clearOneof(oneof);
+    }
+    @java.lang.Override
+    public Builder setRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        int index, java.lang.Object value) {
+      return super.setRepeatedField(field, index, value);
+    }
+    @java.lang.Override
+    public Builder addRepeatedField(
+        com.google.protobuf.Descriptors.FieldDescriptor field,
+        java.lang.Object value) {
+      return super.addRepeatedField(field, value);
+    }
+    @java.lang.Override
+    public Builder mergeFrom(com.google.protobuf.Message other) {
+      if (other instanceof com.tzld.piaoquan.recommend.server.gen.tab.TabResponse) {
+        return mergeFrom((com.tzld.piaoquan.recommend.server.gen.tab.TabResponse)other);
+      } else {
+        super.mergeFrom(other);
+        return this;
+      }
+    }
+
+    public Builder mergeFrom(com.tzld.piaoquan.recommend.server.gen.tab.TabResponse other) {
+      if (other == com.tzld.piaoquan.recommend.server.gen.tab.TabResponse.getDefaultInstance()) return this;
+      if (other.hasResult()) {
+        mergeResult(other.getResult());
+      }
+      if (tabBuilder_ == null) {
+        if (!other.tab_.isEmpty()) {
+          if (tab_.isEmpty()) {
+            tab_ = other.tab_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureTabIsMutable();
+            tab_.addAll(other.tab_);
+          }
+          onChanged();
+        }
+      } else {
+        if (!other.tab_.isEmpty()) {
+          if (tabBuilder_.isEmpty()) {
+            tabBuilder_.dispose();
+            tabBuilder_ = null;
+            tab_ = other.tab_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+            tabBuilder_ = 
+              com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                 getTabFieldBuilder() : null;
+          } else {
+            tabBuilder_.addAllMessages(other.tab_);
+          }
+        }
+      }
+      this.mergeUnknownFields(other.unknownFields);
+      onChanged();
+      return this;
+    }
+
+    @java.lang.Override
+    public final boolean isInitialized() {
+      return true;
+    }
+
+    @java.lang.Override
+    public Builder mergeFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      com.tzld.piaoquan.recommend.server.gen.tab.TabResponse parsedMessage = null;
+      try {
+        parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        parsedMessage = (com.tzld.piaoquan.recommend.server.gen.tab.TabResponse) e.getUnfinishedMessage();
+        throw e.unwrapIOException();
+      } finally {
+        if (parsedMessage != null) {
+          mergeFrom(parsedMessage);
+        }
+      }
+      return this;
+    }
+    private int bitField0_;
+
+    private com.tzld.piaoquan.recommend.server.gen.common.Result result_;
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.tzld.piaoquan.recommend.server.gen.common.Result, com.tzld.piaoquan.recommend.server.gen.common.Result.Builder, com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder> resultBuilder_;
+    /**
+     * <code>.Result result = 1;</code>
+     * @return Whether the result field is set.
+     */
+    public boolean hasResult() {
+      return resultBuilder_ != null || result_ != null;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     * @return The result.
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.Result getResult() {
+      if (resultBuilder_ == null) {
+        return result_ == null ? com.tzld.piaoquan.recommend.server.gen.common.Result.getDefaultInstance() : result_;
+      } else {
+        return resultBuilder_.getMessage();
+      }
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public Builder setResult(com.tzld.piaoquan.recommend.server.gen.common.Result value) {
+      if (resultBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        result_ = value;
+        onChanged();
+      } else {
+        resultBuilder_.setMessage(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public Builder setResult(
+        com.tzld.piaoquan.recommend.server.gen.common.Result.Builder builderForValue) {
+      if (resultBuilder_ == null) {
+        result_ = builderForValue.build();
+        onChanged();
+      } else {
+        resultBuilder_.setMessage(builderForValue.build());
+      }
+
+      return this;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public Builder mergeResult(com.tzld.piaoquan.recommend.server.gen.common.Result value) {
+      if (resultBuilder_ == null) {
+        if (result_ != null) {
+          result_ =
+            com.tzld.piaoquan.recommend.server.gen.common.Result.newBuilder(result_).mergeFrom(value).buildPartial();
+        } else {
+          result_ = value;
+        }
+        onChanged();
+      } else {
+        resultBuilder_.mergeFrom(value);
+      }
+
+      return this;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public Builder clearResult() {
+      if (resultBuilder_ == null) {
+        result_ = null;
+        onChanged();
+      } else {
+        result_ = null;
+        resultBuilder_ = null;
+      }
+
+      return this;
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.Result.Builder getResultBuilder() {
+      
+      onChanged();
+      return getResultFieldBuilder().getBuilder();
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder getResultOrBuilder() {
+      if (resultBuilder_ != null) {
+        return resultBuilder_.getMessageOrBuilder();
+      } else {
+        return result_ == null ?
+            com.tzld.piaoquan.recommend.server.gen.common.Result.getDefaultInstance() : result_;
+      }
+    }
+    /**
+     * <code>.Result result = 1;</code>
+     */
+    private com.google.protobuf.SingleFieldBuilderV3<
+        com.tzld.piaoquan.recommend.server.gen.common.Result, com.tzld.piaoquan.recommend.server.gen.common.Result.Builder, com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder> 
+        getResultFieldBuilder() {
+      if (resultBuilder_ == null) {
+        resultBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+            com.tzld.piaoquan.recommend.server.gen.common.Result, com.tzld.piaoquan.recommend.server.gen.common.Result.Builder, com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder>(
+                getResult(),
+                getParentForChildren(),
+                isClean());
+        result_ = null;
+      }
+      return resultBuilder_;
+    }
+
+    private java.util.List<com.tzld.piaoquan.recommend.server.gen.common.TabProto> tab_ =
+      java.util.Collections.emptyList();
+    private void ensureTabIsMutable() {
+      if (!((bitField0_ & 0x00000001) != 0)) {
+        tab_ = new java.util.ArrayList<com.tzld.piaoquan.recommend.server.gen.common.TabProto>(tab_);
+        bitField0_ |= 0x00000001;
+       }
+    }
+
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        com.tzld.piaoquan.recommend.server.gen.common.TabProto, com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder, com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder> tabBuilder_;
+
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public java.util.List<com.tzld.piaoquan.recommend.server.gen.common.TabProto> getTabList() {
+      if (tabBuilder_ == null) {
+        return java.util.Collections.unmodifiableList(tab_);
+      } else {
+        return tabBuilder_.getMessageList();
+      }
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public int getTabCount() {
+      if (tabBuilder_ == null) {
+        return tab_.size();
+      } else {
+        return tabBuilder_.getCount();
+      }
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.TabProto getTab(int index) {
+      if (tabBuilder_ == null) {
+        return tab_.get(index);
+      } else {
+        return tabBuilder_.getMessage(index);
+      }
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public Builder setTab(
+        int index, com.tzld.piaoquan.recommend.server.gen.common.TabProto value) {
+      if (tabBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureTabIsMutable();
+        tab_.set(index, value);
+        onChanged();
+      } else {
+        tabBuilder_.setMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public Builder setTab(
+        int index, com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder builderForValue) {
+      if (tabBuilder_ == null) {
+        ensureTabIsMutable();
+        tab_.set(index, builderForValue.build());
+        onChanged();
+      } else {
+        tabBuilder_.setMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public Builder addTab(com.tzld.piaoquan.recommend.server.gen.common.TabProto value) {
+      if (tabBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureTabIsMutable();
+        tab_.add(value);
+        onChanged();
+      } else {
+        tabBuilder_.addMessage(value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public Builder addTab(
+        int index, com.tzld.piaoquan.recommend.server.gen.common.TabProto value) {
+      if (tabBuilder_ == null) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        ensureTabIsMutable();
+        tab_.add(index, value);
+        onChanged();
+      } else {
+        tabBuilder_.addMessage(index, value);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public Builder addTab(
+        com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder builderForValue) {
+      if (tabBuilder_ == null) {
+        ensureTabIsMutable();
+        tab_.add(builderForValue.build());
+        onChanged();
+      } else {
+        tabBuilder_.addMessage(builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public Builder addTab(
+        int index, com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder builderForValue) {
+      if (tabBuilder_ == null) {
+        ensureTabIsMutable();
+        tab_.add(index, builderForValue.build());
+        onChanged();
+      } else {
+        tabBuilder_.addMessage(index, builderForValue.build());
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public Builder addAllTab(
+        java.lang.Iterable<? extends com.tzld.piaoquan.recommend.server.gen.common.TabProto> values) {
+      if (tabBuilder_ == null) {
+        ensureTabIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, tab_);
+        onChanged();
+      } else {
+        tabBuilder_.addAllMessages(values);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public Builder clearTab() {
+      if (tabBuilder_ == null) {
+        tab_ = java.util.Collections.emptyList();
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+      } else {
+        tabBuilder_.clear();
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public Builder removeTab(int index) {
+      if (tabBuilder_ == null) {
+        ensureTabIsMutable();
+        tab_.remove(index);
+        onChanged();
+      } else {
+        tabBuilder_.remove(index);
+      }
+      return this;
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder getTabBuilder(
+        int index) {
+      return getTabFieldBuilder().getBuilder(index);
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder getTabOrBuilder(
+        int index) {
+      if (tabBuilder_ == null) {
+        return tab_.get(index);  } else {
+        return tabBuilder_.getMessageOrBuilder(index);
+      }
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public java.util.List<? extends com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder> 
+         getTabOrBuilderList() {
+      if (tabBuilder_ != null) {
+        return tabBuilder_.getMessageOrBuilderList();
+      } else {
+        return java.util.Collections.unmodifiableList(tab_);
+      }
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder addTabBuilder() {
+      return getTabFieldBuilder().addBuilder(
+          com.tzld.piaoquan.recommend.server.gen.common.TabProto.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder addTabBuilder(
+        int index) {
+      return getTabFieldBuilder().addBuilder(
+          index, com.tzld.piaoquan.recommend.server.gen.common.TabProto.getDefaultInstance());
+    }
+    /**
+     * <code>repeated .TabProto tab = 2;</code>
+     */
+    public java.util.List<com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder> 
+         getTabBuilderList() {
+      return getTabFieldBuilder().getBuilderList();
+    }
+    private com.google.protobuf.RepeatedFieldBuilderV3<
+        com.tzld.piaoquan.recommend.server.gen.common.TabProto, com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder, com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder> 
+        getTabFieldBuilder() {
+      if (tabBuilder_ == null) {
+        tabBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+            com.tzld.piaoquan.recommend.server.gen.common.TabProto, com.tzld.piaoquan.recommend.server.gen.common.TabProto.Builder, com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder>(
+                tab_,
+                ((bitField0_ & 0x00000001) != 0),
+                getParentForChildren(),
+                isClean());
+        tab_ = null;
+      }
+      return tabBuilder_;
+    }
+    @java.lang.Override
+    public final Builder setUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.setUnknownFields(unknownFields);
+    }
+
+    @java.lang.Override
+    public final Builder mergeUnknownFields(
+        final com.google.protobuf.UnknownFieldSet unknownFields) {
+      return super.mergeUnknownFields(unknownFields);
+    }
+
+
+    // @@protoc_insertion_point(builder_scope:TabResponse)
+  }
+
+  // @@protoc_insertion_point(class_scope:TabResponse)
+  private static final com.tzld.piaoquan.recommend.server.gen.tab.TabResponse DEFAULT_INSTANCE;
+  static {
+    DEFAULT_INSTANCE = new com.tzld.piaoquan.recommend.server.gen.tab.TabResponse();
+  }
+
+  public static com.tzld.piaoquan.recommend.server.gen.tab.TabResponse getDefaultInstance() {
+    return DEFAULT_INSTANCE;
+  }
+
+  private static final com.google.protobuf.Parser<TabResponse>
+      PARSER = new com.google.protobuf.AbstractParser<TabResponse>() {
+    @java.lang.Override
+    public TabResponse parsePartialFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return new TabResponse(input, extensionRegistry);
+    }
+  };
+
+  public static com.google.protobuf.Parser<TabResponse> parser() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.google.protobuf.Parser<TabResponse> getParserForType() {
+    return PARSER;
+  }
+
+  @java.lang.Override
+  public com.tzld.piaoquan.recommend.server.gen.tab.TabResponse getDefaultInstanceForType() {
+    return DEFAULT_INSTANCE;
+  }
+
+}
+

+ 48 - 0
recommend-server-client/src/main/java/com/tzld/piaoquan/recommend/server/gen/tab/TabResponseOrBuilder.java

@@ -0,0 +1,48 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: com/tzld/piaoquan/recommend/server/tab.proto
+
+package com.tzld.piaoquan.recommend.server.gen.tab;
+
+public interface TabResponseOrBuilder extends
+    // @@protoc_insertion_point(interface_extends:TabResponse)
+    com.google.protobuf.MessageOrBuilder {
+
+  /**
+   * <code>.Result result = 1;</code>
+   * @return Whether the result field is set.
+   */
+  boolean hasResult();
+  /**
+   * <code>.Result result = 1;</code>
+   * @return The result.
+   */
+  com.tzld.piaoquan.recommend.server.gen.common.Result getResult();
+  /**
+   * <code>.Result result = 1;</code>
+   */
+  com.tzld.piaoquan.recommend.server.gen.common.ResultOrBuilder getResultOrBuilder();
+
+  /**
+   * <code>repeated .TabProto tab = 2;</code>
+   */
+  java.util.List<com.tzld.piaoquan.recommend.server.gen.common.TabProto> 
+      getTabList();
+  /**
+   * <code>repeated .TabProto tab = 2;</code>
+   */
+  com.tzld.piaoquan.recommend.server.gen.common.TabProto getTab(int index);
+  /**
+   * <code>repeated .TabProto tab = 2;</code>
+   */
+  int getTabCount();
+  /**
+   * <code>repeated .TabProto tab = 2;</code>
+   */
+  java.util.List<? extends com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder> 
+      getTabOrBuilderList();
+  /**
+   * <code>repeated .TabProto tab = 2;</code>
+   */
+  com.tzld.piaoquan.recommend.server.gen.common.TabProtoOrBuilder getTabOrBuilder(
+      int index);
+}

+ 8 - 0
recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/common.proto

@@ -6,4 +6,12 @@ option java_package = "com.tzld.piaoquan.recommend.server.gen.common";
 message Result {
   int32 code = 1; // 1 成功
   string message = 2;
+}
+
+// Tab标签信息
+message TabProto{
+  string key = 1;
+  string title = 2;
+  string type = 3;
+  string source = 4;
 }

+ 1 - 0
recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/recommend.proto

@@ -41,6 +41,7 @@ message RecommendRequest {
   string current_page_source = 30;
   string openGId = 31;
   string union_id = 32;
+  TabProto tab = 33;
 }
 
 message MachineInfoProto {

+ 27 - 0
recommend-server-client/src/main/proto/com/tzld/piaoquan/recommend/server/tab.proto

@@ -0,0 +1,27 @@
+syntax = "proto3";
+
+import "google/protobuf/any.proto";
+import "com/tzld/piaoquan/recommend/server/common.proto";
+
+option java_multiple_files = true;
+option java_package = "com.tzld.piaoquan.recommend.server.gen.tab";
+option java_generic_services = true;
+
+message TabRequest{
+  string request_id = 1;
+  string mid = 2;
+  string uid = 3;
+  int32 app_type = 4; // default 4
+  string union_id = 5;
+  string city_code = 6;
+  string province_code = 7;
+  string city = 8;
+  string province = 9;
+  repeated string ab_exp_code = 10;
+  string root_session_id = 11;
+}
+
+message TabResponse{
+  Result result = 1;
+  repeated TabProto tab = 2;
+}

+ 1 - 1
recommend-server-service/pom.xml

@@ -175,7 +175,7 @@
         <dependency>
             <groupId>com.tzld.piaoquan</groupId>
             <artifactId>recommend-server-client</artifactId>
-            <version>1.1.13</version>
+            <version>1.1.14</version>
         </dependency>
         <dependency>
             <groupId>com.tzld.piaoquan</groupId>

+ 23 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/common/enums/TabSource.java

@@ -0,0 +1,23 @@
+package com.tzld.piaoquan.recommend.server.common.enums;
+
+import lombok.Getter;
+import lombok.ToString;
+
+@Getter
+@ToString
+public enum TabSource {
+
+    profile("profile", "画像"),
+    share_cate2("share_cate2", "分享二级品类"),
+    return_cate2("return_cate2", "回流二级品类"),
+    default_hot("default_hot", "默认-热度"),
+    other("", "其他");
+
+    private final String source;
+    private final String desc;
+
+    TabSource(String source, String desc) {
+        this.source = source;
+        this.desc = desc;
+    }
+}

+ 35 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/common/enums/TabType.java

@@ -0,0 +1,35 @@
+package com.tzld.piaoquan.recommend.server.common.enums;
+
+import lombok.Getter;
+import lombok.ToString;
+
+import java.util.Arrays;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+@Getter
+@ToString
+public enum TabType {
+
+    territory("territory", "地域"),
+    personalization("personalization", "个性化"),
+
+    other("other", "其他"),
+
+    ;
+    private final String type;
+    private final String desc;
+
+    private static final Map<String, TabType> typeMap = Arrays.stream(TabType.values())
+            .collect(Collectors.toMap(TabType::getType, Function.identity()));
+
+    TabType(String type, String desc) {
+        this.type = type;
+        this.desc = desc;
+    }
+
+    public static TabType getByType(String type) {
+        return typeMap.getOrDefault(type, other);
+    }
+}

+ 2 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/model/RecommendParam.java

@@ -69,5 +69,7 @@ public class RecommendParam {
     private String openGId;
 
     private String unionId;
+
+    private Tab tab;
 }
 

+ 14 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/model/Tab.java

@@ -0,0 +1,14 @@
+package com.tzld.piaoquan.recommend.server.model;
+
+import lombok.Data;
+
+@Data
+public class Tab {
+
+    private String key;
+
+    private String type;
+
+    private String source;
+
+}

+ 28 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/model/TabParam.java

@@ -0,0 +1,28 @@
+package com.tzld.piaoquan.recommend.server.model;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Set;
+
+@Data
+@NoArgsConstructor
+public class TabParam {
+
+    private String requestId;
+
+    private String mid;
+    private String uid;
+    private String unionId;
+
+    private int appType;
+
+    private String cityCode;
+    private String provinceCode;
+    private String city;
+    private String province;
+
+    private Set<String> abExpCodes;
+
+    private String rootSessionId;
+}

+ 22 - 4
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/RecommendService.java

@@ -14,9 +14,11 @@ import com.tzld.piaoquan.recommend.server.feign.GrowthManagerFeign;
 import com.tzld.piaoquan.recommend.server.feign.model.CommonResponse;
 import com.tzld.piaoquan.recommend.server.feign.model.VideoCharacteristicInfo;
 import com.tzld.piaoquan.recommend.server.gen.common.Result;
+import com.tzld.piaoquan.recommend.server.gen.common.TabProto;
 import com.tzld.piaoquan.recommend.server.gen.recommend.*;
 import com.tzld.piaoquan.recommend.server.model.MachineInfo;
 import com.tzld.piaoquan.recommend.server.model.RecommendParam;
+import com.tzld.piaoquan.recommend.server.model.Tab;
 import com.tzld.piaoquan.recommend.server.model.Video;
 import com.tzld.piaoquan.recommend.server.repository.WxUserInfo;
 import com.tzld.piaoquan.recommend.server.repository.WxUserInfoRepository;
@@ -35,6 +37,7 @@ import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
 import com.tzld.piaoquan.recommend.server.service.recall.RecallResult;
 import com.tzld.piaoquan.recommend.server.service.recall.RecallService;
 import com.tzld.piaoquan.recommend.server.service.recall.strategy.*;
+import com.tzld.piaoquan.recommend.server.service.tab.TabService;
 import com.tzld.piaoquan.recommend.server.util.CommonCollectionUtils;
 import com.tzld.piaoquan.recommend.server.util.FeatureUtils;
 import com.tzld.piaoquan.recommend.server.util.JSONUtils;
@@ -91,7 +94,8 @@ public class RecommendService {
     private FunnelLogService funnelLogService;
     @Autowired
     private FeatureService featureService;
-
+    @Autowired
+    private TabService tabService;
     @Autowired
     private GrowthManagerFeign growthManagerFeign;
 
@@ -198,8 +202,7 @@ public class RecommendService {
             RecommendParam param = genRecommendParam(request, recommendType);
             long genRecommendParamTime = stopwatch.stop().elapsed(TimeUnit.MILLISECONDS);
             timerLogMapTL.get().put("genRecommendParamTime", genRecommendParamTime);
-            // log.info("genRecommendParam={},genRecommendParam cost={}", JSONUtils.toJson(param),
-            //         genRecommendParamTime);
+
             List<Video> videos = videoRecommend(param, request);
             stopwatch.reset().start();
             updateCache(request, param, videos);
@@ -315,6 +318,7 @@ public class RecommendService {
                 if (MapUtils.isNotEmpty(logUploadFieldSwitch) && StringUtils.equals("1", logUploadFieldSwitch.get("ext"))) {
                     extJson.put("rankVideoInfoMap", v.getRankVideoInfoMap());
                 }
+                extJson.put("tab", param.getTab());
                 map.put("ext", JSONUtils.toJson(extJson));
 
                 return map;
@@ -470,6 +474,15 @@ public class RecommendService {
             param.setMachineInfo(machineInfo);
         }
 
+        if (request.hasTab()) {
+            TabProto tabProto = request.getTab();
+            Tab tab = new Tab();
+            tab.setKey(tabProto.getKey());
+            tab.setType(tabProto.getType());
+            tab.setSource(tabProto.getSource());
+            param.setTab(tab);
+        }
+
         if (StringUtils.isNotBlank(request.getCategoryId()) && StringUtils.isNumeric(request.getCategoryId())) {
             param.setCategoryId(Integer.parseInt(request.getCategoryId()));
         }
@@ -732,7 +745,7 @@ public class RecommendService {
         recallParam.setCreativeInfoFeature(param.getCreativeInfoFeature());
         recallParam.setOpenGId(param.getOpenGId());
         recallParam.setUnionId(param.getUnionId());
-
+        recallParam.setTab(param.getTab());
         return recallParam;
     }
 
@@ -767,10 +780,14 @@ public class RecommendService {
         rankParam.setCreativeInfoFeature(param.getCreativeInfoFeature());
         rankParam.setOpenGId(param.getOpenGId());
         rankParam.setUnionId(param.getUnionId());
+        rankParam.setTab(param.getTab());
         return rankParam;
     }
 
     public void updateCache(RecommendRequest request, RecommendParam param, List<Video> videos) {
+
+        tabService.updateUserTabCache(param, videos);
+
         if (StringUtils.isBlank(request.getMid())
                 || CollectionUtils.isEmpty(videos)) {
             return;
@@ -788,6 +805,7 @@ public class RecommendService {
         updateFlowPoolCache(request, param, videos);
 
         updateDouHotVideoCache(request, param, videos);
+
     }
 
     private void updateFlowPoolCache(RecommendRequest request, RecommendParam param,

+ 3 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankParam.java

@@ -1,6 +1,7 @@
 package com.tzld.piaoquan.recommend.server.service.rank;
 
 import com.tzld.piaoquan.recommend.server.model.MachineInfo;
+import com.tzld.piaoquan.recommend.server.model.Tab;
 import com.tzld.piaoquan.recommend.server.service.funnel.FunnelContext;
 import com.tzld.piaoquan.recommend.server.service.rank.bo.UserSRBO;
 import com.tzld.piaoquan.recommend.server.service.rank.bo.UserShareReturnProfile;
@@ -54,4 +55,6 @@ public class RankParam {
     private Map<String, Map<String, String>> behaviorVideos;
     private String openGId;
     private String unionId;
+
+    private Tab tab;
 }

+ 15 - 1
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankRouter.java

@@ -1,10 +1,13 @@
 package com.tzld.piaoquan.recommend.server.service.rank;
 
+import com.tzld.piaoquan.recommend.server.common.enums.TabType;
+import com.tzld.piaoquan.recommend.server.model.Tab;
 import com.tzld.piaoquan.recommend.server.service.ExperimentService;
 import com.tzld.piaoquan.recommend.server.service.ServiceBeanFactory;
 import com.tzld.piaoquan.recommend.server.service.rank.strategy.*;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
@@ -26,6 +29,7 @@ public class RankRouter {
     private LinkedHashMap<String, RankService> strategyMap;
 
     private static final String relevantRank = "relevant";
+    private static final String sequenceRank = "sequence";
     private static final Map<String, Class<? extends RankService>> STRATEGY_CLASSES = new HashMap<>();
 
     static {
@@ -39,6 +43,7 @@ public class RankRouter {
         STRATEGY_CLASSES.put("569", RankStrategy4RegionMergeModelV569.class);
         STRATEGY_CLASSES.put("568", RankStrategy4RegionMergeModelV568.class);
         STRATEGY_CLASSES.put("839", RankStrategy4RegionMergeModelV839.class);
+        STRATEGY_CLASSES.put("sequence", RankSequenceStrategy.class);
         STRATEGY_CLASSES.put(relevantRank, RankStrategy4RelevantModelV1.class);
     }
 
@@ -59,11 +64,20 @@ public class RankRouter {
             return strategyMap.get(relevantRank).rank(param);
         }
 
+        Tab tab = param.getTab();
+        if (Objects.nonNull(tab) && StringUtils.isNotBlank(tab.getType())) {
+            TabType type = TabType.getByType(tab.getType());
+            if (Objects.equals(TabType.territory, type)) {
+                return strategyMap.get(sequenceRank).rank(param);
+            }if (Objects.equals(TabType.personalization, type)){
+                return strategyMap.get(sequenceRank).rank(param);
+            }
+        }
+
         // 裂变层实验,使用RootSessionId尾号进行实验
         for (Map.Entry<String, RankService> entry : strategyMap.entrySet()) {
             boolean hitExp = experimentService.judgeHitAlgoExp(param.getAppType(), param.getRootSessionId(), null, entry.getKey());
             if (hitExp) {
-                // log.info("apType: {}, rootSessionId: {} 命中实验: {} strategies: {}", param.getAppType(), param.getRootSessionId(), entry.getKey(), entry.getValue().getClass().getSimpleName());
                 return entry.getValue().rank(param);
             }
         }

+ 10 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/RankService.java

@@ -112,7 +112,9 @@ public abstract class RankService {
         return result;
     }
 
-    /** 阶段 4 + 阶段 5: 合并 + 排序打分 — rovRecallRank 顺序即合并顺序,Video.sortScore 是 rank 模型最终分 */
+    /**
+     * 阶段 4 + 阶段 5: 合并 + 排序打分 — rovRecallRank 顺序即合并顺序,Video.sortScore 是 rank 模型最终分
+     */
     private static void writeFunnelMergedStage(RankParam param, List<Video> rovRecallRank) {
         if (param == null || param.getFunnelContext() == null || CollectionUtils.isEmpty(rovRecallRank)) return;
         FunnelContext ctx = param.getFunnelContext();
@@ -125,7 +127,9 @@ public abstract class RankService {
         }
     }
 
-    /** 阶段 6: 排序截断 — 纯 rank 排序后的前 size 条(不含冷启,作为冷启替换前的快照) */
+    /**
+     * 阶段 6: 排序截断 — 纯 rank 排序后的前 size 条(不含冷启,作为冷启替换前的快照)
+     */
     private static void writeFunnelRankTruncatedStage(RankParam param, List<Video> rovRecallRank, int size) {
         if (param == null || param.getFunnelContext() == null || CollectionUtils.isEmpty(rovRecallRank)) return;
         FunnelContext ctx = param.getFunnelContext();
@@ -334,4 +338,8 @@ public abstract class RankService {
             log.error("addPushFromVideoRank ", e);
         }
     }
+
+    private void sequenceReturn() {
+
+    }
 }

+ 62 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankSequenceStrategy.java

@@ -0,0 +1,62 @@
+package com.tzld.piaoquan.recommend.server.service.rank.strategy;
+
+import com.google.common.collect.Lists;
+import com.tzld.piaoquan.recommend.server.common.enums.TabType;
+import com.tzld.piaoquan.recommend.server.model.Tab;
+import com.tzld.piaoquan.recommend.server.model.Video;
+import com.tzld.piaoquan.recommend.server.service.rank.RankParam;
+import com.tzld.piaoquan.recommend.server.service.rank.RankResult;
+import com.tzld.piaoquan.recommend.server.service.rank.RankService;
+import com.tzld.piaoquan.recommend.server.service.recall.strategy.*;
+import com.tzld.piaoquan.recommend.server.util.RecallUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+
+@Slf4j
+@Service
+public class RankSequenceStrategy extends RankService {
+
+    private static final List<String> territoryRecall = Lists.newArrayList(
+            CityRovnAllRovRecallStrategy.PUSH_FROM,
+            CityRovnRecallStrategy.PUSH_FROM,
+            RegionHRecallStrategy.PUSH_FORM,
+            RegionRealtimeRecallStrategyV1.PUSH_FORM
+    );
+    private static final List<String> personalizationRecall = Lists.newArrayList(
+            PersonalizationTabRovnRecallStrategy.PUSH_FROM
+    );
+
+    @Override
+    public List<Video> mergeAndRankRovRecall(RankParam param) {
+        List<Video> rovRecallRank = new ArrayList<>();
+        Tab tab = param.getTab();
+        if (Objects.nonNull(tab) && StringUtils.isNotBlank(tab.getType())) {
+            TabType type = TabType.getByType(tab.getType());
+            if (Objects.equals(TabType.territory, type)) {
+                this.extractRecall(param, territoryRecall, rovRecallRank);
+            } else if (Objects.equals(TabType.personalization, type)) {
+                this.extractRecall(param, personalizationRecall, rovRecallRank);
+            }
+        }
+
+        // 记录召回源中的视频
+        this.rankBeforePostProcessor(rovRecallRank);
+        return rovRecallRank;
+    }
+
+    private void extractRecall(RankParam param, List<String> recalls, List<Video> videos) {
+        Set<Long> setVideo = new HashSet<>();
+        setVideo.add(param.getHeadVid());
+        for (String recall : recalls) {
+            RecallUtils.extractRecall(100, param, recall, setVideo, videos);
+        }
+    }
+
+    @Override
+    public RankResult mergeAndSort(RankParam param, List<Video> rovRecallRank, List<Video> flowPoolRank, List<Video> douHotFlowPoolRank) {
+        return new RankResult(rovRecallRank);
+    }
+}

+ 124 - 9
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV536.java

@@ -40,9 +40,9 @@ public class RankStrategy4RegionMergeModelV536 extends RankStrategy4RegionMergeM
     private FeatureService featureService;
 
     /**
-     * V536 个性化召回白名单 (6 路):召回 key 含 mid/uid,依赖该用户行为信号。
+     * V536 个性化召回白名单 (8 路): V536 实验新增 dk_elements 系列的 UserProfileDkElements + UserProfileDkElementsXF 两路
+     * V536 实验路径: UserProfileDkElements (用户元素画像 s_z_y_s/zt_gyf)
      * 注:YearReturnCate2 因线上效果不佳, 2026-06-04 起移到非个性化白名单。
-     * 注:YearShareDkElements 在 V536 中移到非个性化白名单 (相对 V562 的实验差异点)。
      */
     private static final Set<String> PERSONAL_RECALL_PUSH_FROMS = new HashSet<>(Arrays.asList(
             UserCate1RecallStrategy.PUSH_FORM,
@@ -50,12 +50,14 @@ public class RankStrategy4RegionMergeModelV536 extends RankStrategy4RegionMergeM
             Return1Cate2RosRecallStrategy.PUSH_FORM,
             Return1Cate2StrRecallStrategy.PUSH_FORM,
             YearShareCate1RecallStrategy.PUSH_FROM,
-            YearShareCate2RecallStrategy.PUSH_FROM
+            YearShareCate2RecallStrategy.PUSH_FROM,
+            UserProfileDkElementsRecallStrategy.PUSH_FROM,
+            UserProfileDkElementsXFRecallStrategy.PUSH_FROM
     ));
 
     /**
-     * V536 非个性化召回白名单 (18 路):只依赖 headVid + 地域/品类/相似度(vid-vid CF 也归此类)。
-     * 含 5 路旧地域、新地域、城市、head province/cate、先验省份、return 相似、scene CF、YearReturnCate2、YearShareDkElements
+     * V536 非个性化召回白名单 (17 路):只依赖 headVid + 地域/品类/相似度(vid-vid CF 也归此类)。
+     * 含 5 路旧地域、新地域、城市、head province/cate、先验省份、return 相似、scene CF、YearReturnCate2。
      */
     private static final Set<String> NON_PERSONAL_RECALL_PUSH_FROMS = new HashSet<>(Arrays.asList(
             RegionHRecallStrategy.PUSH_FORM,
@@ -74,8 +76,7 @@ public class RankStrategy4RegionMergeModelV536 extends RankStrategy4RegionMergeM
             ReturnVideoRecallStrategy.PUSH_FORM,
             SceneCFRovnRecallStrategy.PUSH_FORM,
             SceneCFRosnRecallStrategy.PUSH_FORM,
-            YearReturnCate2RecallStrategy.PUSH_FROM,
-            YearShareDkElementsRecallStrategy.PUSH_FROM
+            YearReturnCate2RecallStrategy.PUSH_FROM
     ));
 
     /** PERSONAL ∪ NON_PERSONAL = 23 路。用于 fetchCoarseRankScores 跳过流量池等不参与截断的 vid。 */
@@ -183,9 +184,9 @@ public class RankStrategy4RegionMergeModelV536 extends RankStrategy4RegionMergeM
                 newC7Map, newC8Map, featureOriginUser, userBehaviorVideoMap, featureOriginVideo, featureMapToString, userFeatureMap, rankItems);
 
 
-        // 4. 排序模型计算
+        // 4. 排序模型计算 (V536 实验: 接入 v25_v7 DNN 模型 recsys_dbmtl_v25_v7_2026071401)
         Map<String, Float> sceneFeatureMap = new HashMap<>(0);
-        List<RankItem> items = ScorerUtils.getScorerPipeline("feeds_score_config_dnn_20260407.conf").scoring(sceneFeatureMap, userFeatureMap, rankItems);
+        List<RankItem> items = ScorerUtils.getScorerPipeline("feeds_score_config_dnn_v25_v7.conf").scoring(sceneFeatureMap, userFeatureMap, rankItems);
 
         // 5. 排序公式特征
         double xgbRovNegRate = mergeWeight.getOrDefault("xgbRovNegRate", 0.059);
@@ -555,6 +556,8 @@ public class RankStrategy4RegionMergeModelV536 extends RankStrategy4RegionMergeM
                                       Map<String, String> featureMapToString,
                                       Map<String, Float> userFeatureMap,
                                       List<RankItem> rankItems) {
+        // V536 新增: 提取用户偏好元素 (s_z_y_s + zt_gyf) 用于交叉特征计算
+        Map<String, Double> userElementScores = extractUserElementScores(userOriginInfo);
         if (CollectionUtils.isNotEmpty(rankItems)) {
             List<Future<Integer>> futures = new ArrayList<>();
             for (RankItem item : rankItems) {
@@ -564,6 +567,10 @@ public class RankStrategy4RegionMergeModelV536 extends RankStrategy4RegionMergeM
                     Map<String, Float> featureMap = new HashMap<>(userFeatureMap);
                     Map<String, Float> videoFeature = getVideoFeature(currentMs, vid, userProfile, creativeInfo, headInfo, rankInfo, c7Map, c8Map, userOriginInfo, historyVideoMap, videoOriginInfo);
                     featureMap.putAll(videoFeature);
+
+                    // V536 新增: 计算用户偏好元素×视频实质元素交叉特征
+                    computeUserPrefVideoCrossFeatures(userElementScores, rankInfo, featureMap);
+
                     item.featureMap = featureMap;
 
                     Map<String, String> userNetworkSeqFeature = userOriginInfo.getOrDefault("alg_user_network_seq_feature", new HashMap<>());
@@ -645,4 +652,112 @@ public class RankStrategy4RegionMergeModelV536 extends RankStrategy4RegionMergeM
         }
         return newScore;
     }
+
+    /**
+     * V536 新增: 从 userNetworkSeqFeature 提取用户偏好元素→归一分映射
+     * 数据源: alg_user_network_seq_feature.s_z_y_s (元素名) + zt_gyf (归一分)
+     * @return Map<元素名, 归一分>, 空 map 表示无数据
+     */
+    private static Map<String, Double> extractUserElementScores(Map<String, Map<String, String>> userOriginInfo) {
+        if (MapUtils.isEmpty(userOriginInfo)) {
+            return Collections.emptyMap();
+        }
+        Map<String, String> seqFeature = userOriginInfo.getOrDefault("alg_user_network_seq_feature", Collections.emptyMap());
+        if (MapUtils.isEmpty(seqFeature)) {
+            return Collections.emptyMap();
+        }
+        List<String> elements = FeatureUtils.extractVidsFromUserNetworkSeqFeature(seqFeature, "s_z_y_s");
+        List<String> scores = FeatureUtils.extractVidsFromUserNetworkSeqFeature(seqFeature, "zt_gyf");
+        if (CollectionUtils.isEmpty(elements) || elements.size() != scores.size()) {
+            return Collections.emptyMap();
+        }
+        Map<String, Double> result = new LinkedHashMap<>();
+        for (int i = 0; i < elements.size(); i++) {
+            String elem = elements.get(i);
+            if (StringUtils.isBlank(elem)) continue;
+            try {
+                result.put(elem.trim(), Double.parseDouble(scores.get(i)));
+            } catch (NumberFormatException e) {
+                result.put(elem.trim(), 0.0);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * V536 新增: 计算用户偏好元素 × 视频实质元素 的 3 个交叉特征
+     * 视频数据源: alg_vid_feature_basic_info → 实质元素 JSON {"花卉":0.0089,"晚安祝福":0.0089,...}
+     * 离线训练使用的是视频的实质元素分(非用户×视频乘积),与离线口径保持一致。
+     * 写入 item.featureMap: user_pref_video_overlap_cnt / user_pref_video_max_score / user_pref_video_sum_score
+     *
+     * 标准化到 0-1: 除以离线数据 global_max(20260713 分区 10万条样本统计极值+安全余量)
+     *   overlap_cnt_max = 14  (10万样本 max=12, +2余量)
+     *   max_score_max   = 0.21 (10万样本 max=0.186)
+     *   sum_score_max   = 0.89 (10万样本 max=0.8335)
+     */
+    private static final double OVERLAP_CNT_MAX = 14.0;
+    private static final double MAX_SCORE_MAX = 0.21;
+    private static final double SUM_SCORE_MAX = 0.89;
+
+    private static void computeUserPrefVideoCrossFeatures(Map<String, Double> userElementScores,
+                                                          Map<String, String> rankInfo,
+                                                          Map<String, Float> featureMap) {
+        if (MapUtils.isEmpty(userElementScores)) {
+            featureMap.put("user_pref_video_overlap_cnt", 0.0f);
+            featureMap.put("user_pref_video_max_score", 0.0f);
+            featureMap.put("user_pref_video_sum_score", 0.0f);
+            return;
+        }
+
+        String videoElementsJson = rankInfo.get("实质元素");
+        if (StringUtils.isBlank(videoElementsJson)) {
+            featureMap.put("user_pref_video_overlap_cnt", 0.0f);
+            featureMap.put("user_pref_video_max_score", 0.0f);
+            featureMap.put("user_pref_video_sum_score", 0.0f);
+            return;
+        }
+
+        Map<String, Double> videoElements = new LinkedHashMap<>();
+        try {
+            Map<String, Object> rawMap = JSON.parseObject(videoElementsJson, Map.class);
+            if (rawMap != null) {
+                for (Map.Entry<String, Object> entry : rawMap.entrySet()) {
+                    Object val = entry.getValue();
+                    if (val instanceof Number) {
+                        videoElements.put(entry.getKey(), ((Number) val).doubleValue());
+                    }
+                }
+            }
+        } catch (Exception e) {
+            // 解析失败,videoElements 保持空
+        }
+
+        if (MapUtils.isEmpty(videoElements)) {
+            featureMap.put("user_pref_video_overlap_cnt", 0.0f);
+            featureMap.put("user_pref_video_max_score", 0.0f);
+            featureMap.put("user_pref_video_sum_score", 0.0f);
+            return;
+        }
+
+        double overlapCnt = 0;
+        double maxScore = 0;
+        double sumScore = 0;
+
+        for (Map.Entry<String, Double> userElem : userElementScores.entrySet()) {
+            String elementName = userElem.getKey();
+            if (videoElements.containsKey(elementName)) {
+                overlapCnt++;
+                double videoScore = videoElements.getOrDefault(elementName, 0.0);
+                sumScore += videoScore;
+                if (videoScore > maxScore) {
+                    maxScore = videoScore;
+                }
+            }
+        }
+
+        // 标准化到 0-1
+        featureMap.put("user_pref_video_overlap_cnt", (float) Math.min(overlapCnt / OVERLAP_CNT_MAX, 1.0));
+        featureMap.put("user_pref_video_max_score", (float) Math.min(maxScore / MAX_SCORE_MAX, 1.0));
+        featureMap.put("user_pref_video_sum_score", (float) Math.min(sumScore / SUM_SCORE_MAX, 1.0));
+    }
 }

+ 4 - 3
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV565.java

@@ -46,13 +46,14 @@ public class RankStrategy4RegionMergeModelV565 extends RankStrategy4RegionMergeM
      * 注:YearReturnCate2 因线上效果不佳, 2026-06-04 起移到非个性化白名单。
      */
     private static final Set<String> PERSONAL_RECALL_PUSH_FROMS = new HashSet<>(Arrays.asList(
-            UserCate1RecallStrategyV565.PUSH_FORM,
-            UserCate2RecallStrategyV565.PUSH_FORM,
+            UserCate1RecallStrategy.PUSH_FORM,
+            UserCate2RecallStrategy.PUSH_FORM,
             Return1Cate2RosRecallStrategy.PUSH_FORM,
             Return1Cate2StrRecallStrategy.PUSH_FORM,
             YearShareCate1RecallStrategy.PUSH_FROM,
             YearShareCate2RecallStrategy.PUSH_FROM,
-            UserProfileDkElementsRecallStrategy.PUSH_FROM
+            UserProfileDkElementsRecallStrategy.PUSH_FROM,
+            UserProfileDkElementsXFRecallStrategy.PUSH_FROM
     ));
 
     /**

+ 240 - 37
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/strategy/RankStrategy4RegionMergeModelV568.java

@@ -7,7 +7,9 @@ import com.tzld.piaoquan.recommend.server.common.base.RankItem;
 import com.tzld.piaoquan.recommend.server.model.MachineInfo;
 import com.tzld.piaoquan.recommend.server.model.Video;
 import com.tzld.piaoquan.recommend.server.service.FeatureService;
+import com.tzld.piaoquan.recommend.server.service.funnel.FunnelContext;
 import com.tzld.piaoquan.recommend.server.service.rank.RankParam;
+import com.tzld.piaoquan.recommend.server.service.rank.RankResult;
 import com.tzld.piaoquan.recommend.server.service.rank.bo.UserShareReturnProfile;
 import com.tzld.piaoquan.recommend.server.service.rank.extractor.ExtractVideoMergeCate;
 import com.tzld.piaoquan.recommend.server.service.rank.tansform.FeatureV6;
@@ -17,6 +19,7 @@ import com.tzld.piaoquan.recommend.server.util.*;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.collections4.MapUtils;
+import org.apache.commons.lang3.RandomUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -36,6 +39,62 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
     @Autowired
     private FeatureService featureService;
 
+    /**
+     * V565 个性化召回白名单 (7 路: V566 基础 6 路 + 1 路 dk_elements 画像路实验):召回 key 含 mid/uid,
+     * 依赖该用户行为信号。
+     * V565 实验路径: UserProfileDkElements (用户元素画像 s_z_y_s/zt_gyf)
+     * 注:YearReturnCate2 因线上效果不佳, 2026-06-04 起移到非个性化白名单。
+     */
+    private static final Set<String> PERSONAL_RECALL_PUSH_FROMS = new HashSet<>(Arrays.asList(
+            UserCate1RecallStrategyV568.PUSH_FORM,
+            UserCate2RecallStrategyV568.PUSH_FORM,
+            Return1Cate2RosRecallStrategy.PUSH_FORM,
+            Return1Cate2StrRecallStrategy.PUSH_FORM,
+            YearShareCate1RecallStrategy.PUSH_FROM,
+            YearShareCate2RecallStrategy.PUSH_FROM,
+            UserProfileDkElementsRecallStrategy.PUSH_FROM,
+            UserProfileDkElementsXFRecallStrategy.PUSH_FROM
+    ));
+
+    /**
+     * V565 非个性化召回白名单 (17 路):只依赖 headVid + 地域/品类/相似度(vid-vid CF 也归此类)。
+     * 含 5 路旧地域、新地域、城市、head province/cate、先验省份、return 相似、scene CF、YearReturnCate2。
+     */
+    private static final Set<String> NON_PERSONAL_RECALL_PUSH_FROMS = new HashSet<>(Arrays.asList(
+            RegionHRecallStrategy.PUSH_FORM,
+            RegionHDupRecallStrategy.PUSH_FORM,
+            Region24HRecallStrategy.PUSH_FORM,
+            RegionRelative24HRecallStrategy.PUSH_FORM,
+            RegionRelative24HDupRecallStrategy.PUSH_FORM,
+            RegionRealtimeRecallStrategyV1.PUSH_FORM,
+            CityRovnRecallStrategy.PUSH_FROM,
+            HeadProvinceCate1RecallStrategy.PUSH_FORM,
+            HeadProvinceCate2RecallStrategy.PUSH_FORM,
+            HeadCate2RovRecallStrategy.PUSH_FROM,
+            PrioriProvinceRovnRecallStrategy.PUSH_FROM,
+            PrioriProvinceStrRecallStrategy.PUSH_FROM,
+            PrioriProvinceRosRecallStrategy.PUSH_FROM,
+            ReturnVideoRecallStrategy.PUSH_FORM,
+            SceneCFRovnRecallStrategy.PUSH_FORM,
+            SceneCFRosnRecallStrategy.PUSH_FORM,
+            YearReturnCate2RecallStrategy.PUSH_FROM
+    ));
+
+    /** PERSONAL ∪ NON_PERSONAL = 23 路。用于 fetchCoarseRankScores 跳过流量池等不参与截断的 vid。 */
+    private static final Set<String> ALL_ROV_PUSH_FROMS;
+    static {
+        Set<String> all = new HashSet<>(PERSONAL_RECALL_PUSH_FROMS);
+        all.addAll(NON_PERSONAL_RECALL_PUSH_FROMS);
+        ALL_ROV_PUSH_FROMS = Collections.unmodifiableSet(all);
+    }
+
+    /*
+     * 设计要点:
+     *   - fail-closed 白名单:RecallService 未来加新路不会自动进 V565,避免污染 vs V568 AB 对比
+     *   - 流量池 3 路 (flow_pool / quick_flow_pool / recall_strategy_hotspot) 不在任何名单——独立通道
+     *   - 调用顺序 = 个性化优先:同 vid 双类命中时归个性化,保护用户兴趣信号
+     */
+
     @Override
     public List<Video> mergeAndRankRovRecall(RankParam param) {
         Map<String, Double> mergeWeight = this.mergeWeight != null ? this.mergeWeight : new HashMap<>(0);
@@ -49,42 +108,30 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
         Set<Long> setVideo = new HashSet<>();
         setVideo.add(param.getHeadVid());
         List<Video> rovRecallRank = new ArrayList<>();
-        // -------------------5路特殊旧召回------------------
-        RecallUtils.extractOldSpecialRecall(mergeWeight.getOrDefault("oldSpecialN", (double) param.getSize()).intValue(), param, setVideo, rovRecallRank);
-        //-------------------return相似召回------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("v6", 5.0).intValue(), param, ReturnVideoRecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
-        //-------------------新地域召回------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("v1", 5.0).intValue(), param, RegionRealtimeRecallStrategyV1.PUSH_FORM, setVideo, rovRecallRank);
-        //-------------------scene cf rovn------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("sceneCFRovn", 5.0).intValue(), param, SceneCFRovnRecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
-        //-------------------scene cf rosn------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("sceneCFRosn", 5.0).intValue(), param, SceneCFRosnRecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
-        // -------------------user cate1------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("cate1RecallN", 5.0).intValue(), param, UserCate1RecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
-        // -------------------user cate2------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("cate2RecallN", 5.0).intValue(), param, UserCate2RecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
-        // -------------------head province cate1------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("headCate1RecallN", 3.0).intValue(), param, HeadProvinceCate1RecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
-        // -------------------head province cate2------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("headCate2RecallN", 3.0).intValue(), param, HeadProvinceCate2RecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
-        //-------------------head cate2 of rovn------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("headCate2Rov", 5.0).intValue(), param, HeadCate2RovRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
-        //-------------------city rovn------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("cityRov", 5.0).intValue(), param, CityRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
-        //-------------------priori province rovn------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceRov", 3.0).intValue(), param, PrioriProvinceRovnRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
-        //-------------------priori province str------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceStr", 1.0).intValue(), param, PrioriProvinceStrRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
-        //-------------------priori province ros------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("prioriProvinceRos", 1.0).intValue(), param, PrioriProvinceRosRecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
-        //-------------------return1 cate2 ros------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("return1Cate2Ros", 5.0).intValue(), param, Return1Cate2RosRecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
-        //-------------------return1 cate2 str------------------
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("return1Cate2Str", 5.0).intValue(), param, Return1Cate2StrRecallStrategy.PUSH_FORM, setVideo, rovRecallRank);
-
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("yearShareCate1", 5.0).intValue(), param, YearShareCate1RecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("yearShareCate2", 5.0).intValue(), param, YearShareCate2RecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
-        RecallUtils.extractRecall(mergeWeight.getOrDefault("yearReturnCate2", 5.0).intValue(), param, YearReturnCate2RecallStrategy.PUSH_FROM, setVideo, rovRecallRank);
+
+        // ============================================================
+        // V565 实验:统一粗排分截断 (个性化 / 非个性化 两配额, 动态补足)
+        // 总配额 coarseRankTopN,个性化占 personalRatio。先个性化按上限抢位,
+        // 个性化不足时剩余名额转给非个性化,保证精排算力满载。
+        //
+        // 粗排分 = alg_vid_recommend_exp_feature_20250212.rovn_1h / rovn_24h 平均
+        // ============================================================
+        int totalTopN = mergeWeight.getOrDefault("coarseRankTopN", 80.0).intValue();
+        double personalRatio = mergeWeight.getOrDefault("personalRatio", 0.8);
+        int personalTopN = (int) Math.round(totalTopN * personalRatio);
+        Map<Long, Double> coarseRankMap = fetchCoarseRankScores(param);
+
+        int personalCandidates = RecallUtils.countDistinctCandidates(param, setVideo, PERSONAL_RECALL_PUSH_FROMS);
+        int sizeBeforePersonal = rovRecallRank.size();
+        RecallUtils.extractAllAndTruncateByCoarseRank(personalTopN, param, setVideo, rovRecallRank, coarseRankMap, PERSONAL_RECALL_PUSH_FROMS);
+        int personalActual = rovRecallRank.size() - sizeBeforePersonal;
+        int nonPersonalBudget = totalTopN - personalActual;  // 个性化不足时, 名额转给非个性化
+        int nonPersonalCandidates = RecallUtils.countDistinctCandidates(param, setVideo, NON_PERSONAL_RECALL_PUSH_FROMS);
+        int sizeBeforeNonPersonal = rovRecallRank.size();
+        RecallUtils.extractAllAndTruncateByCoarseRank(nonPersonalBudget, param, setVideo, rovRecallRank, coarseRankMap, NON_PERSONAL_RECALL_PUSH_FROMS);
+        int nonPersonalActual = rovRecallRank.size() - sizeBeforeNonPersonal;
+        log.info("coarse_rank_summary exp=565 quota={} pc={} ps={} nc={} ns={}",
+                totalTopN, personalCandidates, personalActual, nonPersonalCandidates, nonPersonalActual);
 
         // 记录召回源中的视频
         this.rankBeforePostProcessor(rovRecallRank);
@@ -168,6 +215,11 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
         double dnRovn1hW = mergeWeight.getOrDefault("dn_rovn_1h_w", 0d);
         double dnRovn24hW = mergeWeight.getOrDefault("dn_rovn_24h_w", 0d);
 
+        // V568 rov 融合:newNorDNNScore(预测 ROV) 与 coarseRankScore(统计 ROV) 加权和
+        // 默认 predRovW=1.0 / statRovW=0.0 → 退化为原公式,保底不掉指标
+        double predRovW = mergeWeight.getOrDefault("predRovW", 1.0d);
+        double statRovW = mergeWeight.getOrDefault("statRovW", 0.0d);
+
         Map<String, Map<String, String>> vid2MapFeature = this.getVideoRedisFeature(vids, "redis:vid_hasreturn_vor:");
 
 
@@ -190,6 +242,15 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
             item.getScoresMap().put("rosAdd", rosAdd);
             item.getScoresMap().put("rosW", rosW);
 
+            // 统计 ROV:coarseRankScore = plusSmooth(return_n_uv, exp, 30, 1), 1h+24h 加权
+            // 数据源同 fetchCoarseRankScores 计算, 缺失 vid 兜底 0 (退回纯预测)
+            double statRov = coarseRankMap.getOrDefault(item.getVideoId(), 0d);
+            double fusedRov = predRovW * newNorDNNScore + statRovW * statRov;
+            item.getScoresMap().put("statRov", statRov);
+            item.getScoresMap().put("predRovW", predRovW);
+            item.getScoresMap().put("statRovW", statRovW);
+            item.getScoresMap().put("fusedRov", fusedRov);
+
             double vor = Double.parseDouble(vid2MapFeature.getOrDefault(item.getVideoId() + "", new HashMap<>()).getOrDefault("vor", "0"));
             item.getScoresMap().put("vor", vor);
             item.getScoresMap().put("vorAdd", vorAdd);
@@ -244,7 +305,7 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
             item.getScoresMap().put("dnRovn24hW", dnRovn24hW);
             item.getScoresMap().put("dnRovn24h", dnRovn24h);
 
-            score = fmRov * (rosAdd + rosW * newNorDNNScore) * (vorAdd + vorW * vor) + c1RovnScore + b0StrScore + b0RorScore + cnRovnScore + dnRovnScore;
+            score = fmRov * (rosAdd + rosW * fusedRov) * (vorAdd + vorW * vor) + c1RovnScore + b0StrScore + b0RorScore + cnRovnScore + dnRovnScore;
 
             Video video = item.getVideo();
             video.setScore(score);
@@ -289,6 +350,148 @@ public class RankStrategy4RegionMergeModelV568 extends RankStrategy4RegionMergeM
         return result;
     }
 
+    /**
+     * 同 V567 极简 fusion:只保留"流量池相关 + 兜底相关"逻辑
+     *   1. rov 空兜底:rov 池为空时流量池直接顶上 (Basic 段 1)
+     *   7. 流量池按比例强插:topK 头部锁 rov + topK..size 按 flowPoolP / newFlowPoolSelectRate 概率门
+     *      混入 flowVideos / douHotFlowPoolVideos,否则用 rov 中段;一侧用光时另一侧兜底回填 (Basic 段 7)
+     *
+     * 删除(相对 Basic):标签 filter / rov boost / 强插 / 品类降权 / 节日降权 / 密度控制
+     */
+    @Override
+    public RankResult mergeAndSort(RankParam param, List<Video> rovVideos, List<Video> flowVideos, List<Video> douHotFlowPoolVideos) {
+
+        // 1 兜底策略,rov池子不足时,用冷启池填补。直接返回。
+        if (CollectionUtils.isEmpty(rovVideos)) {
+            if (param.getSize() < flowVideos.size()) {
+                return new RankResult(flowVideos.subList(0, param.getSize()));
+            } else {
+                return new RankResult(flowVideos);
+            }
+        }
+
+        // 7 流量池按比例强插
+        FunnelContext funnelCtx = param.getFunnelContext();
+        List<Video> result = new ArrayList<>();
+        for (int i = 0; i < param.getTopK() && i < rovVideos.size(); i++) {
+            result.add(rovVideos.get(i));
+        }
+        double flowPoolP = getFlowPoolP(param);
+        int flowPoolIndex = 0;
+        int rovPoolIndex = param.getTopK();
+        for (int i = 0; i < param.getSize() - param.getTopK(); i++) {
+            double rand = RandomUtils.nextDouble(0, 1);
+            if (rand < flowPoolP) {
+                if (flowPoolIndex < flowVideos.size()) {
+                    Video v = flowVideos.get(flowPoolIndex++);
+                    result.add(v);
+                    markColdStartInserted(funnelCtx, v);
+                } else {
+                    break;
+                }
+            } else if (this.isInsertDouHotFlowPoolVideo()) {
+                if (flowPoolIndex < douHotFlowPoolVideos.size()) {
+                    Video v = douHotFlowPoolVideos.get(flowPoolIndex++);
+                    result.add(v);
+                    markColdStartInserted(funnelCtx, v);
+                } else {
+                    break;
+                }
+            } else {
+                if (rovPoolIndex < rovVideos.size()) {
+                    result.add(rovVideos.get(rovPoolIndex++));
+                } else {
+                    break;
+                }
+            }
+        }
+        if (rovPoolIndex >= rovVideos.size()) {
+            for (int i = flowPoolIndex; i < flowVideos.size() && result.size() < param.getSize(); i++) {
+                Video v = flowVideos.get(i);
+                result.add(v);
+                markColdStartInserted(funnelCtx, v);
+            }
+        }
+        if (flowPoolIndex >= flowVideos.size()) {
+            for (int i = rovPoolIndex; i < rovVideos.size() && result.size() < param.getSize(); i++) {
+                result.add(rovVideos.get(i));
+            }
+        }
+
+        return new RankResult(result);
+    }
+
+    /**
+     * V565 实验:拉取粗排分(按 vid → score 返回)。
+     *
+     * 数据源:alg_vid_recommend_exp_feature_20250212。
+     * 表里没有现成 rovn 字段,需要从原子字段 (return_n_uv_*, exp_*) 用 plusSmooth 算出来。
+     * 公式 = FeatureV6.oneTypeStatFeature 同口径:rovn = plusSmooth(return_n_uv, exp, plus, 1)
+     * 默认 plus=30 与 FeatureV6.largerSmoothPlus 对齐,AB 对比不会因口径不同污染结论。
+     *
+     * Apollo 可调维度:
+     *   - coarseRovn1hW / coarseRovn24hW:1h 和 24h 的加权(默认 0.5/0.5)
+     *   - coarseRovn1hSmoothPlus / coarseRovn24hSmoothPlus:贝叶斯平滑系数(默认 30/30)
+     *
+     * 缺失自动归一化:单值缺失时剩下的撑起全部权重;两值都缺失则 caller 兜底 RovScore。
+     */
+    private Map<Long, Double> fetchCoarseRankScores(RankParam param) {
+        if (param == null || param.getRecallResult() == null
+                || CollectionUtils.isEmpty(param.getRecallResult().getData())) {
+            return Collections.emptyMap();
+        }
+        Map<String, Double> mergeWeight = this.mergeWeight != null ? this.mergeWeight : Collections.emptyMap();
+        double w1h = mergeWeight.getOrDefault("coarseRovn1hW", 0.5);
+        double w24h = mergeWeight.getOrDefault("coarseRovn24hW", 0.5);
+        double plus1h = mergeWeight.getOrDefault("coarseRovn1hSmoothPlus", 30.0);
+        double plus24h = mergeWeight.getOrDefault("coarseRovn24hSmoothPlus", 30.0);
+        // 只对参与统一截断的 23 路 vid 拉粗排分(跳过流量池 3 路,省 proto + RPC 延迟)
+        List<String> vids = param.getRecallResult().getData().stream()
+                .filter(d -> d != null && CollectionUtils.isNotEmpty(d.getVideos()))
+                .filter(d -> ALL_ROV_PUSH_FROMS.contains(d.getPushFrom()))
+                .flatMap(d -> d.getVideos().stream())
+                .map(v -> String.valueOf(v.getVideoId()))
+                .distinct()
+                .collect(Collectors.toList());
+        if (vids.isEmpty()) return Collections.emptyMap();
+
+        Map<String, Map<String, Map<String, String>>> feats = featureService.getVideoCoarseRankFeature(vids);
+        Map<Long, Double> result = new HashMap<>(vids.size());
+        for (String vid : vids) {
+            Map<String, String> row = feats.getOrDefault(vid, Collections.emptyMap())
+                    .getOrDefault("alg_vid_recommend_exp_feature_20250212", Collections.emptyMap());
+            Double rovn1h = computeRovn(row, "1h", plus1h);
+            Double rovn24h = computeRovn(row, "24h", plus24h);
+            // 加权平均,缺失自动归一化
+            double sumW = (rovn1h != null ? w1h : 0) + (rovn24h != null ? w24h : 0);
+            if (sumW <= 0) continue;
+            double sumWS = (rovn1h != null ? rovn1h * w1h : 0) + (rovn24h != null ? rovn24h * w24h : 0);
+            try {
+                result.put(Long.parseLong(vid), sumWS / sumW);
+            } catch (NumberFormatException ignore) { }
+        }
+        return result;
+    }
+
+    /**
+     * 与 FeatureV6.oneTypeStatFeature 同口径:rovn = plusSmooth(return_n_uv, exp, plus, 1)
+     *
+     * 字段语义(区分 0 vs null):
+     *   - exp 是 period 有效性 anchor:null 或 ≤0 → 整个 period 无效(return null)
+     *   - return_n_uv 缺失视为 0(真实信号"无回访"):rovn=0,参与加权(不会让另一时段兜底)
+     */
+    private static Double computeRovn(Map<String, String> row, String period, double smoothPlus) {
+        Double exp = parseDoubleOrNull(row.get("exp_" + period));
+        if (exp == null || exp <= 0) return null;
+        Double returnNuv = parseDoubleOrNull(row.get("return_n_uv_" + period));
+        return FeatureUtils.plusSmooth(returnNuv != null ? returnNuv : 0, exp, smoothPlus, 1);
+    }
+
+    private static Double parseDoubleOrNull(String s) {
+        if (StringUtils.isBlank(s)) return null;
+        try { return Double.parseDouble(s); } catch (NumberFormatException e) { return null; }
+    }
+
     private UserShareReturnProfile parseUserProfile(Map<String, Map<String, String>> userOriginInfo) {
         if (null != userOriginInfo) {
             Map<String, String> c9 = userOriginInfo.get("alg_recsys_feature_user_share_return_stat");

+ 15 - 4
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/rank/tansform/FGEncoderManager.java

@@ -9,6 +9,7 @@ import com.ctrip.framework.apollo.ConfigService;
 import lombok.Getter;
 import lombok.extern.slf4j.Slf4j;
 
+import java.io.InputStream;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -47,14 +48,24 @@ public class FGEncoderManager {
 
     public void registerFGEncoder(final String fgConfigJsonPath) {
         log.info("register FG Encoder start: {}", fgConfigJsonPath);
-        FGEncoder fgEncoder = new FGEncoder(client.getObject(this.bucketName, fgConfigJsonPath).getObjectContent());
+        FGEncoder fgEncoder = loadFGEncoder(fgConfigJsonPath);
         log.info("register FG Encoder end: {}", fgConfigJsonPath);
         this.featureFGEncoderMap.put(fgConfigJsonPath, fgEncoder);
     }
 
+    private FGEncoder loadFGEncoder(String fgConfigJsonPath) {
+        // 优先从 classpath 加载(本地开发兼容)
+        InputStream classpathStream = getClass().getClassLoader().getResourceAsStream(fgConfigJsonPath);
+        if (classpathStream != null) {
+            log.info("FG Encoder loaded from classpath: {}", fgConfigJsonPath);
+            return new FGEncoder(classpathStream);
+        }
+        // 回退到 OSS 加载
+        log.info("FG Encoder loading from OSS: {}", fgConfigJsonPath);
+        return new FGEncoder(client.getObject(this.bucketName, fgConfigJsonPath).getObjectContent());
+    }
+
     public FGEncoder getFGEncoder(final String fgConfigJsonPath) {
-        return featureFGEncoderMap.computeIfAbsent(fgConfigJsonPath, path -> new FGEncoder(
-                client.getObject(this.bucketName, path).getObjectContent()
-        ));
+        return featureFGEncoderMap.computeIfAbsent(fgConfigJsonPath, path -> loadFGEncoder(path));
     }
 }

+ 3 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallParam.java

@@ -1,5 +1,6 @@
 package com.tzld.piaoquan.recommend.server.service.recall;
 
+import com.tzld.piaoquan.recommend.server.model.Tab;
 import com.tzld.piaoquan.recommend.server.service.funnel.FunnelContext;
 import com.tzld.piaoquan.recommend.server.service.rank.bo.UserSRBO;
 import com.tzld.piaoquan.recommend.server.service.rank.bo.UserShareReturnProfile;
@@ -62,4 +63,6 @@ public class RecallParam {
     private Map<String, String> userNetworkSeqFeature;
 
     private Map<Long, Map<String, String>> userNetworkSeqVideoInfoMap;
+
+    private Tab tab;
 }

+ 30 - 2
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/RecallService.java

@@ -3,6 +3,7 @@ package com.tzld.piaoquan.recommend.server.service.recall;
 import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
 import com.tzld.piaoquan.recommend.server.common.ThreadPoolFactory;
 import com.tzld.piaoquan.recommend.server.common.enums.AppTypeEnum;
+import com.tzld.piaoquan.recommend.server.common.enums.TabType;
 import com.tzld.piaoquan.recommend.server.model.Video;
 import com.tzld.piaoquan.recommend.server.service.ExperimentService;
 import com.tzld.piaoquan.recommend.server.service.funnel.FunnelContext;
@@ -124,6 +125,21 @@ public class RecallService implements ApplicationContextAware {
             return strategies;
         }
 
+        // 标签页的召回
+        if (Objects.nonNull(param.getTab())) {
+            TabType tabType = TabType.getByType(param.getTab().getType());
+            if (TabType.territory.equals(tabType)) {
+                strategies.add(strategyMap.get(CityRovnAllRovRecallStrategy.class.getSimpleName()));
+                strategies.add(strategyMap.get(CityRovnRecallStrategy.class.getSimpleName()));
+                strategies.add(strategyMap.get(RegionHRecallStrategy.class.getSimpleName()));
+                strategies.add(strategyMap.get(RegionRealtimeRecallStrategyV1.class.getSimpleName()));
+                return strategies;
+            } else if (TabType.personalization.equals(tabType)) {
+                strategies.add(strategyMap.get(PersonalizationTabRovnRecallStrategy.class.getSimpleName()));
+                return strategies;
+            }
+        }
+
         //1:通过“产品”控制“召回子策略”. 票圈美好祝福与内部tab只走祝福召回。APP只走固定列表。特殊配置的app只有固定召回列表。
         if (this.matchSpecialApp(param.getAppType())) {
             strategies.add(strategyMap.get(RegionRealtimeRecallStrategyV5Hand.class.getSimpleName()));
@@ -170,6 +186,12 @@ public class RecallService implements ApplicationContextAware {
             // }
         }
 
+        boolean isHit568Exp = experimentService.judgeHitAlgoExp(param.getAppType(), param.getRootSessionId(), abExpCodes, "568");
+        if (isHit568Exp) {
+            strategies.add(strategyMap.get(UserCate1RecallStrategyV568.class.getSimpleName()));
+            strategies.add(strategyMap.get(UserCate2RecallStrategyV568.class.getSimpleName()));
+        }
+
         boolean isHit842Exp = experimentService.judgeHitAlgoExp(param.getAppType(), param.getRootSessionId(), abExpCodes, "842");
         if (isHit842Exp) {
             strategies.add(strategyMap.get(UserDeconstructionKeywordsRecallStrategy.class.getSimpleName()));
@@ -190,6 +212,8 @@ public class RecallService implements ApplicationContextAware {
         boolean isHit839Exp = experimentService.judgeHitAlgoExp(param.getAppType(), param.getRootSessionId(), abExpCodes, "839");
         if (isHit536Exp) {
             strategies.add(strategyMap.get(YearShareDkElementsRecallStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(UserProfileDkElementsRecallStrategy.class.getSimpleName()));
+            strategies.add(strategyMap.get(UserProfileDkElementsXFRecallStrategy.class.getSimpleName()));
         }
         if (isHit839Exp) {
             strategies.add(strategyMap.get(YearValidPlayDkElementsRecallStrategy.class.getSimpleName()));
@@ -197,8 +221,12 @@ public class RecallService implements ApplicationContextAware {
         boolean isHit565Exp = experimentService.judgeHitAlgoExp(param.getAppType(), param.getRootSessionId(), abExpCodes, "565");
         if (isHit565Exp) {
             strategies.add(strategyMap.get(UserProfileDkElementsRecallStrategy.class.getSimpleName()));
-            strategies.add(strategyMap.get(UserCate1RecallStrategyV565.class.getSimpleName()));
-            strategies.add(strategyMap.get(UserCate2RecallStrategyV565.class.getSimpleName()));
+            // V565 (tail=6,7) 追加 XF 画像路, 与老 dk_elements 并存跑对比
+            strategies.add(strategyMap.get(UserProfileDkElementsXFRecallStrategy.class.getSimpleName()));
+        }
+        if (isHit568Exp) {
+            // V568 (tail=5,d) 新增 XF 画像路 (isHit568Exp 已在上方 UserCate1/2RecallStrategyV568 处判定)
+            strategies.add(strategyMap.get(UserProfileDkElementsXFRecallStrategy.class.getSimpleName()));
         }
         boolean isHit562Exp = experimentService.judgeHitAlgoExp(param.getAppType(), param.getRootSessionId(), abExpCodes, "562");
         if (isHit562Exp) {

+ 88 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/PersonalizationTabRovnRecallStrategy.java

@@ -0,0 +1,88 @@
+package com.tzld.piaoquan.recommend.server.service.recall.strategy;
+
+import com.tzld.piaoquan.recommend.server.model.Tab;
+import com.tzld.piaoquan.recommend.server.model.Video;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterParam;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterResult;
+import com.tzld.piaoquan.recommend.server.service.filter.FilterService;
+import com.tzld.piaoquan.recommend.server.service.recall.FilterParamFactory;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallParam;
+import com.tzld.piaoquan.recommend.server.service.recall.RecallStrategy;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Component
+public class PersonalizationTabRovnRecallStrategy implements RecallStrategy {
+
+    @Autowired
+    private FilterService filterService;
+    @Autowired
+    @Qualifier("redisTemplate")
+    public RedisTemplate<String, String> redisTemplate;
+
+    public static final String PUSH_FROM = "personalized_tab_rovn_recall";
+
+    private static final String redisKeyFormat = "personalized_tab_rovn_recall:%s";
+
+    @Override
+    public List<Video> recall(RecallParam param) {
+        List<Video> result = new ArrayList<>();
+
+        Tab tab = param.getTab();
+        if (Objects.isNull(tab) || StringUtils.isBlank(tab.getKey())) {
+            return result;
+        }
+
+        String key = String.format(redisKeyFormat, tab.getKey());
+        String value = redisTemplate.opsForValue().get(key);
+        if (StringUtils.isBlank(value)) {
+            return result;
+        }
+        List<String[]> collect = Arrays.stream(value.split("\t"))
+                .map(i -> i.split(","))
+                .collect(Collectors.toList());
+        if (collect.size() != 2) {
+            return result;
+        }
+        String[] vids = collect.get(0);
+        String[] scores = collect.get(1);
+        if (vids.length != scores.length) {
+            return result;
+        }
+
+        Map<Long, Double> vidAndScoreMap = new HashMap<>();
+        for (int i = 0; i < vids.length; i++) {
+            vidAndScoreMap.put(Long.parseLong(vids[i]), Double.parseDouble(scores[i]));
+        }
+
+        FilterParam filterParam = FilterParamFactory.create(param, new ArrayList<>(vidAndScoreMap.keySet()), pushFrom(), vidAndScoreMap);
+        FilterResult filterResult = filterService.filter(filterParam);
+        if (Objects.isNull(filterResult) || CollectionUtils.isEmpty(filterResult.getVideoIds())){
+            return result;
+        }
+        for (Long videoId : filterResult.getVideoIds()) {
+            Video video = new Video();
+            video.setVideoId(videoId);
+            video.setRovScore(vidAndScoreMap.get(videoId));
+            video.setPushFrom(pushFrom());
+
+            result.add(video);
+        }
+
+        return result;
+    }
+
+    @Override
+    public String pushFrom() {
+        return PUSH_FROM;
+    }
+}

+ 3 - 3
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/UserCate1RecallStrategyV565.java → recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/UserCate1RecallStrategyV568.java

@@ -22,13 +22,13 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 /**
- * V565 实验专属:UserCate1RecallStrategy 的 topN=100 变体。
+ * V568 实验专属:UserCate1RecallStrategy 的 topN=100 变体。
  * 与原版共用同一 Redis key 前缀,仅拉取更多 cate 达到扩大召回量的效果。
  * 使用独立 PUSH_FORM 避免污染其他实验组。
  */
 @Component
 @Slf4j
-public class UserCate1RecallStrategyV565 implements RecallStrategy {
+public class UserCate1RecallStrategyV568 implements RecallStrategy {
     private final String CLASS_NAME = this.getClass().getSimpleName();
     @Autowired
     private FilterService filterService;
@@ -37,7 +37,7 @@ public class UserCate1RecallStrategyV565 implements RecallStrategy {
     public RedisTemplate<String, String> redisTemplate;
 
     public static final int topN = 100;
-    public static final String PUSH_FORM = "recall_strategy_user_cate1_v565";
+    public static final String PUSH_FORM = "recall_strategy_user_cate1_v568";
     public static final String redisKeyPrefix = "merge_cate_recall:cate1";
 
     @Override

+ 3 - 3
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/UserCate2RecallStrategyV565.java → recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/recall/strategy/UserCate2RecallStrategyV568.java

@@ -22,13 +22,13 @@ import java.util.*;
 import java.util.stream.Collectors;
 
 /**
- * V565 实验专属:UserCate2RecallStrategy 的 topN=100 变体。
+ * V568 实验专属:UserCate2RecallStrategy 的 topN=100 变体。
  * 与原版共用同一 Redis key 前缀,仅拉取更多 cate 达到扩大召回量的效果。
  * 使用独立 PUSH_FORM 避免污染其他实验组。
  */
 @Component
 @Slf4j
-public class UserCate2RecallStrategyV565 implements RecallStrategy {
+public class UserCate2RecallStrategyV568 implements RecallStrategy {
     private final String CLASS_NAME = this.getClass().getSimpleName();
     @Autowired
     private FilterService filterService;
@@ -37,7 +37,7 @@ public class UserCate2RecallStrategyV565 implements RecallStrategy {
     public RedisTemplate<String, String> redisTemplate;
 
     public static final int topN = 100;
-    public static final String PUSH_FORM = "recall_strategy_user_cate2_v565";
+    public static final String PUSH_FORM = "recall_strategy_user_cate2_v568";
     public static final String redisKeyPrefix = "merge_cate_recall:cate2";
 
     @Override

+ 1 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/score/ScorerUtils.java

@@ -42,6 +42,7 @@ public final class ScorerUtils {
         ScorerUtils.init("feeds_score_config_dnn_20260407.conf");
         ScorerUtils.init("feeds_score_config_dnn_20260417.conf");
         ScorerUtils.init("feeds_score_config_dnn_20260424.conf");
+        ScorerUtils.init("feeds_score_config_dnn_v25_v7.conf");
         ScorerUtils.init("feeds_score_config_str_ros_dnn_20260424.conf");
 
         // 召回配置

+ 228 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/service/tab/TabService.java

@@ -0,0 +1,228 @@
+package com.tzld.piaoquan.recommend.server.service.tab;
+
+import com.alibaba.fastjson.JSON;
+import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
+import com.google.common.collect.Sets;
+import com.tzld.piaoquan.recommend.server.common.enums.TabSource;
+import com.tzld.piaoquan.recommend.server.common.enums.TabType;
+import com.tzld.piaoquan.recommend.server.gen.common.Result;
+import com.tzld.piaoquan.recommend.server.gen.common.TabProto;
+import com.tzld.piaoquan.recommend.server.gen.tab.TabRequest;
+import com.tzld.piaoquan.recommend.server.gen.tab.TabResponse;
+import com.tzld.piaoquan.recommend.server.model.RecommendParam;
+import com.tzld.piaoquan.recommend.server.model.TabParam;
+import com.tzld.piaoquan.recommend.server.model.Video;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Slf4j
+@Service
+public class TabService {
+
+
+    @Autowired
+    @Qualifier("redisTemplate")
+    protected RedisTemplate<String, String> redisTemplate;
+
+    @ApolloJsonValue("${homepage.default.tab:[历史名人,知识科普]}")
+    private List<String> homepageDefaultTab;
+
+    @ApolloJsonValue("${personalization.tab.size:2}")
+    private Integer personalizationTabSize;
+
+    /**
+     * 中国行政区划代码(GB/T 2260)省級前缀,前2位。
+     * 11-15 华北, 21-23 东北, 31-37 华东, 41-46 中南, 50-54 西南, 61-65 西北,
+     * 71 台湾, 81-82 香港/澳门
+     */
+    private static final Set<String> CHINA_PROVINCE_CODE_PREFIXES = Sets.newHashSet(
+            "11", "12", "13", "14", "15",
+            "21", "22", "23",
+            "31", "32", "33", "34", "35", "36", "37",
+            "41", "42", "43", "44", "45", "46",
+            "50", "51", "52", "53", "54",
+            "61", "62", "63", "64", "65",
+            "71", "81", "82"
+    );
+
+    private static final String personalizationTabCondidateFormat = "personalized_tab_candidate:%s";
+
+    private static final String userInvalidTabCache = "user:invalid:tab:cache:%s";
+
+    private static final String PERSONALIZATION_TAB_SEPARATOR = "&";
+
+    public TabResponse homepageTab(TabRequest request) {
+        TabParam tabParam = this.requestCoverToParam(request);
+
+        Set<String> tabs = new HashSet<>();
+
+        List<TabProto> tabProtos = new ArrayList<>();
+
+        List<TabProto> territoryTabs = this.territoryTab(tabParam, tabs);
+
+        // 地域Tab
+        if (CollectionUtils.isNotEmpty(territoryTabs)) {
+            tabProtos.addAll(territoryTabs);
+        }
+
+        // 个性化Tab
+        List<TabProto> personalizationTabs = this.personalizationTab(tabParam, tabs);
+        if (CollectionUtils.isNotEmpty(personalizationTabs)) {
+            tabProtos.addAll(personalizationTabs.subList(0, Math.min(personalizationTabs.size(), personalizationTabSize)));
+        }
+
+        return TabResponse.newBuilder()
+                .setResult(Result.newBuilder().setCode(1).setMessage("success"))
+                .addAllTab(tabProtos)
+                .build();
+    }
+
+    private List<TabProto> territoryTab(TabParam tabParam, Set<String> tabs) {
+        List<TabProto> tabProtos = new ArrayList<>();
+        // 非中国地域不返回地域Tab
+        if (isChinaRegion(tabParam.getProvinceCode())) {
+            String province = tabParam.getProvince().replaceAll("省$", "");
+            List<TabProto> provinceTab = this.buildTabProto(Collections.singletonList(province), tabParam.getUnionId(), TabSource.other, TabType.territory, tabs);
+            provinceTab = provinceTab.stream().map(i -> i.toBuilder().setTitle("同城").build()).collect(Collectors.toList());
+            tabProtos.addAll(provinceTab);
+        }
+        return tabProtos;
+    }
+
+    private List<TabProto> personalizationTab(TabParam tabParam, Set<String> tabs) {
+
+        List<TabProto> defaultTab = this.buildTabProto(homepageDefaultTab, tabParam.getUnionId(), TabSource.default_hot, TabType.personalization, tabs);
+        List<TabProto> tabProtos = new ArrayList<>(defaultTab);
+
+        if (StringUtils.isBlank(tabParam.getUnionId())) {
+            // log.info("unionId is empty");
+            return tabProtos;
+        }
+
+        String key = String.format(personalizationTabCondidateFormat, tabParam.getUnionId());
+        String value = redisTemplate.opsForValue().get(key);
+        if (StringUtils.isBlank(value)) {
+            // log.error("unionId is not exist");
+            return tabProtos;
+        }
+
+        List<List<String>> tabCollect = Arrays.stream(value.split("\t"))
+                .map(i -> Arrays.asList(i.split(PERSONALIZATION_TAB_SEPARATOR)))
+                .collect(Collectors.toList());
+        if (tabCollect.size() != 4) {
+            // log.error("redis value size nq 4, {}", value);
+            return tabProtos;
+        }
+
+        log.info("tabCollect: {}", JSON.toJSONString(tabCollect));
+
+        List<TabProto> profileTab = this.buildTabProto(tabCollect.get(0), tabParam.getUnionId(), TabSource.profile, TabType.personalization, tabs);
+        List<TabProto> shareCate2Tab = this.buildTabProto(tabCollect.get(1), tabParam.getUnionId(), TabSource.share_cate2, TabType.personalization, tabs);
+        List<TabProto> returnCate2Tab = this.buildTabProto(tabCollect.get(2), tabParam.getUnionId(), TabSource.return_cate2, TabType.personalization, tabs);
+        List<TabProto> defaultHotTab = this.buildTabProto(tabCollect.get(3), tabParam.getUnionId(), TabSource.default_hot, TabType.personalization, tabs);
+
+        // 默认兜底Tab
+        tabProtos.addAll(0, defaultHotTab);
+        tabProtos.addAll(0, returnCate2Tab);
+        tabProtos.addAll(0, shareCate2Tab);
+        tabProtos.addAll(0, profileTab);
+        return tabProtos;
+    }
+
+    /**
+     * 包含tab去重,tab过滤
+     */
+    private List<TabProto> buildTabProto(List<String> tabNames, String unionId, TabSource source, TabType type, Set<String> tabs) {
+        if (CollectionUtils.isEmpty(tabNames)) {
+            return Collections.emptyList();
+        }
+
+
+        String invalidTabCacheKey = String.format(userInvalidTabCache, unionId);
+        Set<String> invalidTabCache = Optional.ofNullable(redisTemplate.opsForSet().members(invalidTabCacheKey)).orElse(new HashSet<>());
+
+        List<TabProto> tabProtos = new ArrayList<>();
+        for (String tabName : tabNames) {
+            if (StringUtils.isBlank(tabName)
+                    || tabs.contains(tabName)
+                    || invalidTabCache.contains(tabName)) {
+                continue;
+            }
+            tabProtos.add(
+                    TabProto.newBuilder()
+                            .setKey(tabName)
+                            .setTitle(tabName)
+                            .setSource(source.getSource())
+                            .setType(type.getType())
+                            .build()
+            );
+            tabs.add(tabName);
+        }
+        return tabProtos;
+    }
+
+    private TabParam requestCoverToParam(TabRequest request) {
+        TabParam param = new TabParam();
+        param.setRequestId(request.getRequestId());
+
+        param.setMid(request.getMid());
+        param.setUid(request.getUid());
+        param.setUnionId(request.getUnionId());
+
+        param.setAppType(request.getAppType());
+
+        param.setCityCode(request.getCityCode());
+        param.setProvinceCode(request.getProvinceCode());
+        param.setCity(request.getCity());
+        param.setProvince(request.getProvince());
+
+        if (request.getAbExpCodeCount() > 0) {
+            Set<String> abExpCodes = new HashSet<>(request.getAbExpCodeList());
+            param.setAbExpCodes(abExpCodes);
+        }
+        param.setRootSessionId(request.getRootSessionId());
+
+        return param;
+    }
+
+    /**
+     * 判断行政区划代码是否属于中国。
+     * 通过省份代码前2位匹配 GB/T 2260 中的中国省级前缀来校验。
+     *
+     * @param provinceCode 省份代码(2位或6位均可)
+     * @return true 表示是中国地域
+     */
+    private boolean isChinaRegion(String provinceCode) {
+        if (StringUtils.isBlank(provinceCode) || provinceCode.length() < 2) {
+            return false;
+        }
+        return CHINA_PROVINCE_CODE_PREFIXES.contains(provinceCode.substring(0, 2));
+    }
+
+    public void updateUserTabCache(RecommendParam param, List<Video> videos) {
+        try {
+
+            if (Objects.isNull(param.getTab()) || StringUtils.isBlank(param.getTab().getKey())) {
+                return;
+            }
+            int size = param.getSize();
+            if (CollectionUtils.isEmpty(videos) || videos.size() < size) {
+                String key = String.format(userInvalidTabCache, param.getUnionId());
+                redisTemplate.opsForSet().add(key, param.getTab().getKey());
+                redisTemplate.expire(key, 360 * 3600, TimeUnit.SECONDS);
+            }
+        } catch (Exception e) {
+            log.error("updateUserTabCache error", e);
+        }
+    }
+
+}

+ 34 - 0
recommend-server-service/src/main/java/com/tzld/piaoquan/recommend/server/web/TabController.java

@@ -0,0 +1,34 @@
+package com.tzld.piaoquan.recommend.server.web;
+
+import com.tzld.piaoquan.recommend.server.client.ProtobufUtils;
+import com.tzld.piaoquan.recommend.server.gen.tab.TabRequest;
+import com.tzld.piaoquan.recommend.server.gen.tab.TabResponse;
+import com.tzld.piaoquan.recommend.server.service.tab.TabService;
+import lombok.extern.slf4j.Slf4j;
+import org.slf4j.MDC;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RestController;
+
+@Slf4j
+@RestController
+public class TabController {
+
+    @Autowired
+    private TabService tabService;
+
+    @PostMapping("/homepage/tab")
+    public String homepageTab(@RequestBody TabRequest request) {
+        MDC.put("appType", String.valueOf(request.getAppType()));
+        TabResponse tabResponse = tabService.homepageTab(request);
+        String result = "";
+        try {
+            result = ProtobufUtils.toJson(tabResponse);
+        } catch (Exception e) {
+            log.error("homepageTab ProtobufUtils.toJson", e);
+        }
+        return result;
+    }
+
+}

+ 15 - 0
recommend-server-service/src/main/resources/feeds_score_config_dnn_v25_v7.conf

@@ -0,0 +1,15 @@
+scorer-config = {
+  pai-eas-score-config = {
+     scorer-name = "com.tzld.piaoquan.recommend.server.service.score.PAIScorer"
+     scorer-priority = 100
+     param = {
+       dnnConfig = {
+         "fgConfigFilePath": "fg/feature_list_v25_v7.json",
+         "easToken": "YjBhMmVjNjI5NjgyNGE0MGY5NDBmZmQ0NzA5NjkyMzBkOTZhZTYyZg==",
+         "easDirectEndpoint": "1894469520484605.vpc.cn-hangzhou.pai-eas.aliyuncs.com",
+         "modelName": "recsys_dbmtl_v25_v7_2026071401",
+         "fetchs":["y_return_n_uv","probs_is_share"]
+       }
+     }
+  }
+}

+ 5939 - 0
recommend-server-service/src/main/resources/fg/feature_list_v25_v7.json

@@ -0,0 +1,5939 @@
+{
+  "features": [
+    {
+      "feature_name": "ctx_app",
+      "feature_key": "ctx_app",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "b0_12h_exp",
+      "feature_key": "b0_12h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_is_return_1",
+      "feature_key": "b0_12h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_is_share",
+      "feature_key": "b0_12h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_return_1_uv",
+      "feature_key": "b0_12h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_return_n_uv",
+      "feature_key": "b0_12h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_ros1_l",
+      "feature_key": "b0_12h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_ros_l",
+      "feature_key": "b0_12h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_ros_minus1_l",
+      "feature_key": "b0_12h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_ros_minus_l",
+      "feature_key": "b0_12h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_ros_n1_l",
+      "feature_key": "b0_12h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_ros_n_l",
+      "feature_key": "b0_12h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_ros_one",
+      "feature_key": "b0_12h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_rovn1_l",
+      "feature_key": "b0_12h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_rovn_l",
+      "feature_key": "b0_12h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_share_cnt",
+      "feature_key": "b0_12h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_str",
+      "feature_key": "b0_12h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_12h_str_plus",
+      "feature_key": "b0_12h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_exp",
+      "feature_key": "b0_1h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_is_return_1",
+      "feature_key": "b0_1h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_is_share",
+      "feature_key": "b0_1h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_return_1_uv",
+      "feature_key": "b0_1h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_return_n_uv",
+      "feature_key": "b0_1h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_ros1_l",
+      "feature_key": "b0_1h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_ros_l",
+      "feature_key": "b0_1h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_ros_minus1_l",
+      "feature_key": "b0_1h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_ros_minus_l",
+      "feature_key": "b0_1h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_ros_n1_l",
+      "feature_key": "b0_1h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_ros_n_l",
+      "feature_key": "b0_1h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_ros_one",
+      "feature_key": "b0_1h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_rovn1_l",
+      "feature_key": "b0_1h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_rovn_l",
+      "feature_key": "b0_1h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_share_cnt",
+      "feature_key": "b0_1h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_str",
+      "feature_key": "b0_1h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_1h_str_plus",
+      "feature_key": "b0_1h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_exp",
+      "feature_key": "b0_3h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_is_return_1",
+      "feature_key": "b0_3h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_is_share",
+      "feature_key": "b0_3h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_return_1_uv",
+      "feature_key": "b0_3h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_return_n_uv",
+      "feature_key": "b0_3h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_ros1_l",
+      "feature_key": "b0_3h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_ros_l",
+      "feature_key": "b0_3h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_ros_minus1_l",
+      "feature_key": "b0_3h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_ros_minus_l",
+      "feature_key": "b0_3h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_ros_n1_l",
+      "feature_key": "b0_3h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_ros_n_l",
+      "feature_key": "b0_3h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_ros_one",
+      "feature_key": "b0_3h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_rovn1_l",
+      "feature_key": "b0_3h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_rovn_l",
+      "feature_key": "b0_3h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_share_cnt",
+      "feature_key": "b0_3h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_str",
+      "feature_key": "b0_3h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_3h_str_plus",
+      "feature_key": "b0_3h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_exp",
+      "feature_key": "b0_6h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_is_return_1",
+      "feature_key": "b0_6h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_is_share",
+      "feature_key": "b0_6h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_return_1_uv",
+      "feature_key": "b0_6h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_return_n_uv",
+      "feature_key": "b0_6h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_ros1_l",
+      "feature_key": "b0_6h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_ros_l",
+      "feature_key": "b0_6h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_ros_minus1_l",
+      "feature_key": "b0_6h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_ros_minus_l",
+      "feature_key": "b0_6h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_ros_n1_l",
+      "feature_key": "b0_6h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_ros_n_l",
+      "feature_key": "b0_6h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_ros_one",
+      "feature_key": "b0_6h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_rovn1_l",
+      "feature_key": "b0_6h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_rovn_l",
+      "feature_key": "b0_6h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_share_cnt",
+      "feature_key": "b0_6h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_str",
+      "feature_key": "b0_6h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b0_6h_str_plus",
+      "feature_key": "b0_6h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_12h_exp",
+      "feature_key": "b10_12h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_12h_is_return_1",
+      "feature_key": "b10_12h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_12h_is_share",
+      "feature_key": "b10_12h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_12h_return_n_uv",
+      "feature_key": "b10_12h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_12h_ros_l",
+      "feature_key": "b10_12h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_12h_ros_minus_l",
+      "feature_key": "b10_12h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_12h_ros_n_l",
+      "feature_key": "b10_12h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_12h_ros_one",
+      "feature_key": "b10_12h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_12h_rovn_l",
+      "feature_key": "b10_12h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_12h_share_cnt",
+      "feature_key": "b10_12h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_12h_str",
+      "feature_key": "b10_12h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_12h_str_plus",
+      "feature_key": "b10_12h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_1h_is_share",
+      "feature_key": "b10_1h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_1h_return_n_uv",
+      "feature_key": "b10_1h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_1h_ros_l",
+      "feature_key": "b10_1h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_1h_ros_minus_l",
+      "feature_key": "b10_1h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_1h_rovn_l",
+      "feature_key": "b10_1h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_1h_str",
+      "feature_key": "b10_1h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b10_1h_str_plus",
+      "feature_key": "b10_1h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b11_12h_is_share",
+      "feature_key": "b11_12h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b11_12h_return_n_uv",
+      "feature_key": "b11_12h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b11_12h_ros_l",
+      "feature_key": "b11_12h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b11_12h_ros_minus_l",
+      "feature_key": "b11_12h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b11_12h_rovn_l",
+      "feature_key": "b11_12h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b11_12h_str",
+      "feature_key": "b11_12h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b11_12h_str_plus",
+      "feature_key": "b11_12h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_12h_exp",
+      "feature_key": "b13_12h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_12h_is_return_1",
+      "feature_key": "b13_12h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_12h_is_share",
+      "feature_key": "b13_12h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_12h_return_n_uv",
+      "feature_key": "b13_12h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_12h_ros_l",
+      "feature_key": "b13_12h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_12h_ros_minus_l",
+      "feature_key": "b13_12h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_12h_ros_n_l",
+      "feature_key": "b13_12h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_12h_ros_one",
+      "feature_key": "b13_12h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_12h_rovn_l",
+      "feature_key": "b13_12h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_12h_share_cnt",
+      "feature_key": "b13_12h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_12h_str",
+      "feature_key": "b13_12h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_12h_str_plus",
+      "feature_key": "b13_12h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_1h_exp",
+      "feature_key": "b13_1h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_1h_is_return_1",
+      "feature_key": "b13_1h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_1h_is_share",
+      "feature_key": "b13_1h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_1h_return_n_uv",
+      "feature_key": "b13_1h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_1h_ros_l",
+      "feature_key": "b13_1h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_1h_ros_minus_l",
+      "feature_key": "b13_1h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_1h_ros_n_l",
+      "feature_key": "b13_1h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_1h_ros_one",
+      "feature_key": "b13_1h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_1h_rovn_l",
+      "feature_key": "b13_1h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_1h_share_cnt",
+      "feature_key": "b13_1h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_1h_str",
+      "feature_key": "b13_1h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_1h_str_plus",
+      "feature_key": "b13_1h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_24h_exp",
+      "feature_key": "b13_24h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_24h_is_return_1",
+      "feature_key": "b13_24h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_24h_is_share",
+      "feature_key": "b13_24h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_24h_return_n_uv",
+      "feature_key": "b13_24h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_24h_ros_l",
+      "feature_key": "b13_24h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_24h_ros_minus_l",
+      "feature_key": "b13_24h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_24h_ros_n_l",
+      "feature_key": "b13_24h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_24h_ros_one",
+      "feature_key": "b13_24h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_24h_rovn_l",
+      "feature_key": "b13_24h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_24h_share_cnt",
+      "feature_key": "b13_24h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_24h_str",
+      "feature_key": "b13_24h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_24h_str_plus",
+      "feature_key": "b13_24h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_3h_exp",
+      "feature_key": "b13_3h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_3h_is_return_1",
+      "feature_key": "b13_3h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_3h_is_share",
+      "feature_key": "b13_3h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_3h_return_n_uv",
+      "feature_key": "b13_3h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_3h_ros_l",
+      "feature_key": "b13_3h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_3h_ros_minus_l",
+      "feature_key": "b13_3h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_3h_ros_n_l",
+      "feature_key": "b13_3h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_3h_ros_one",
+      "feature_key": "b13_3h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_3h_rovn_l",
+      "feature_key": "b13_3h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_3h_share_cnt",
+      "feature_key": "b13_3h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_3h_str",
+      "feature_key": "b13_3h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_3h_str_plus",
+      "feature_key": "b13_3h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_6h_exp",
+      "feature_key": "b13_6h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_6h_is_return_1",
+      "feature_key": "b13_6h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_6h_is_share",
+      "feature_key": "b13_6h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_6h_return_n_uv",
+      "feature_key": "b13_6h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_6h_ros_l",
+      "feature_key": "b13_6h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_6h_ros_minus_l",
+      "feature_key": "b13_6h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_6h_ros_n_l",
+      "feature_key": "b13_6h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_6h_ros_one",
+      "feature_key": "b13_6h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_6h_rovn_l",
+      "feature_key": "b13_6h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_6h_share_cnt",
+      "feature_key": "b13_6h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_6h_str",
+      "feature_key": "b13_6h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_6h_str_plus",
+      "feature_key": "b13_6h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_72h_exp",
+      "feature_key": "b13_72h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_72h_is_return_1",
+      "feature_key": "b13_72h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_72h_is_share",
+      "feature_key": "b13_72h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_72h_return_n_uv",
+      "feature_key": "b13_72h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_72h_ros_l",
+      "feature_key": "b13_72h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_72h_ros_minus_l",
+      "feature_key": "b13_72h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_72h_ros_n_l",
+      "feature_key": "b13_72h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_72h_ros_one",
+      "feature_key": "b13_72h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_72h_rovn_l",
+      "feature_key": "b13_72h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_72h_share_cnt",
+      "feature_key": "b13_72h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_72h_str",
+      "feature_key": "b13_72h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b13_72h_str_plus",
+      "feature_key": "b13_72h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_exp",
+      "feature_key": "b14_12h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_is_return_1",
+      "feature_key": "b14_12h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_is_share",
+      "feature_key": "b14_12h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_return_1_uv",
+      "feature_key": "b14_12h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_return_n_uv",
+      "feature_key": "b14_12h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_ros1_l",
+      "feature_key": "b14_12h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_ros_l",
+      "feature_key": "b14_12h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_ros_minus1_l",
+      "feature_key": "b14_12h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_ros_minus_l",
+      "feature_key": "b14_12h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_ros_n1_l",
+      "feature_key": "b14_12h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_ros_n_l",
+      "feature_key": "b14_12h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_ros_one",
+      "feature_key": "b14_12h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_rovn1_l",
+      "feature_key": "b14_12h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_rovn_l",
+      "feature_key": "b14_12h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_share_cnt",
+      "feature_key": "b14_12h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_str",
+      "feature_key": "b14_12h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_12h_str_plus",
+      "feature_key": "b14_12h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_exp",
+      "feature_key": "b14_1h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_is_return_1",
+      "feature_key": "b14_1h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_is_share",
+      "feature_key": "b14_1h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_return_1_uv",
+      "feature_key": "b14_1h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_return_n_uv",
+      "feature_key": "b14_1h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_ros1_l",
+      "feature_key": "b14_1h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_ros_l",
+      "feature_key": "b14_1h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_ros_minus1_l",
+      "feature_key": "b14_1h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_ros_minus_l",
+      "feature_key": "b14_1h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_ros_n1_l",
+      "feature_key": "b14_1h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_ros_n_l",
+      "feature_key": "b14_1h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_ros_one",
+      "feature_key": "b14_1h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_rovn1_l",
+      "feature_key": "b14_1h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_rovn_l",
+      "feature_key": "b14_1h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_share_cnt",
+      "feature_key": "b14_1h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_str",
+      "feature_key": "b14_1h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_1h_str_plus",
+      "feature_key": "b14_1h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_exp",
+      "feature_key": "b14_2h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_is_return_1",
+      "feature_key": "b14_2h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_is_share",
+      "feature_key": "b14_2h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_return_1_uv",
+      "feature_key": "b14_2h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_return_n_uv",
+      "feature_key": "b14_2h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_ros1_l",
+      "feature_key": "b14_2h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_ros_l",
+      "feature_key": "b14_2h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_ros_minus1_l",
+      "feature_key": "b14_2h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_ros_minus_l",
+      "feature_key": "b14_2h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_ros_n1_l",
+      "feature_key": "b14_2h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_ros_n_l",
+      "feature_key": "b14_2h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_ros_one",
+      "feature_key": "b14_2h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_rovn1_l",
+      "feature_key": "b14_2h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_rovn_l",
+      "feature_key": "b14_2h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_share_cnt",
+      "feature_key": "b14_2h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_str",
+      "feature_key": "b14_2h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_2h_str_plus",
+      "feature_key": "b14_2h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_exp",
+      "feature_key": "b14_3h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_is_return_1",
+      "feature_key": "b14_3h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_is_share",
+      "feature_key": "b14_3h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_return_1_uv",
+      "feature_key": "b14_3h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_return_n_uv",
+      "feature_key": "b14_3h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_ros1_l",
+      "feature_key": "b14_3h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_ros_l",
+      "feature_key": "b14_3h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_ros_minus1_l",
+      "feature_key": "b14_3h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_ros_minus_l",
+      "feature_key": "b14_3h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_ros_n1_l",
+      "feature_key": "b14_3h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_ros_n_l",
+      "feature_key": "b14_3h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_ros_one",
+      "feature_key": "b14_3h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_rovn1_l",
+      "feature_key": "b14_3h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_rovn_l",
+      "feature_key": "b14_3h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_share_cnt",
+      "feature_key": "b14_3h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_str",
+      "feature_key": "b14_3h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_3h_str_plus",
+      "feature_key": "b14_3h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_exp",
+      "feature_key": "b14_6h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_is_return_1",
+      "feature_key": "b14_6h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_is_share",
+      "feature_key": "b14_6h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_return_1_uv",
+      "feature_key": "b14_6h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_return_n_uv",
+      "feature_key": "b14_6h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_ros1_l",
+      "feature_key": "b14_6h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_ros_l",
+      "feature_key": "b14_6h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_ros_minus1_l",
+      "feature_key": "b14_6h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_ros_minus_l",
+      "feature_key": "b14_6h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_ros_n1_l",
+      "feature_key": "b14_6h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_ros_n_l",
+      "feature_key": "b14_6h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_ros_one",
+      "feature_key": "b14_6h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_rovn1_l",
+      "feature_key": "b14_6h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_rovn_l",
+      "feature_key": "b14_6h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_share_cnt",
+      "feature_key": "b14_6h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_str",
+      "feature_key": "b14_6h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b14_6h_str_plus",
+      "feature_key": "b14_6h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_exp",
+      "feature_key": "b15_12h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_is_return_1",
+      "feature_key": "b15_12h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_is_share",
+      "feature_key": "b15_12h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_return_1_uv",
+      "feature_key": "b15_12h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_return_n_uv",
+      "feature_key": "b15_12h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_ros1_l",
+      "feature_key": "b15_12h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_ros_l",
+      "feature_key": "b15_12h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_ros_minus1_l",
+      "feature_key": "b15_12h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_ros_minus_l",
+      "feature_key": "b15_12h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_ros_n1_l",
+      "feature_key": "b15_12h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_ros_n_l",
+      "feature_key": "b15_12h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_ros_one",
+      "feature_key": "b15_12h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_rovn1_l",
+      "feature_key": "b15_12h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_rovn_l",
+      "feature_key": "b15_12h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_share_cnt",
+      "feature_key": "b15_12h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_str",
+      "feature_key": "b15_12h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_12h_str_plus",
+      "feature_key": "b15_12h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_exp",
+      "feature_key": "b15_1h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_is_return_1",
+      "feature_key": "b15_1h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_is_share",
+      "feature_key": "b15_1h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_return_1_uv",
+      "feature_key": "b15_1h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_return_n_uv",
+      "feature_key": "b15_1h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_ros1_l",
+      "feature_key": "b15_1h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_ros_l",
+      "feature_key": "b15_1h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_ros_minus1_l",
+      "feature_key": "b15_1h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_ros_minus_l",
+      "feature_key": "b15_1h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_ros_n1_l",
+      "feature_key": "b15_1h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_ros_n_l",
+      "feature_key": "b15_1h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_ros_one",
+      "feature_key": "b15_1h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_rovn1_l",
+      "feature_key": "b15_1h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_rovn_l",
+      "feature_key": "b15_1h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_share_cnt",
+      "feature_key": "b15_1h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_str",
+      "feature_key": "b15_1h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_1h_str_plus",
+      "feature_key": "b15_1h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_exp",
+      "feature_key": "b15_2h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_is_return_1",
+      "feature_key": "b15_2h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_is_share",
+      "feature_key": "b15_2h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_return_1_uv",
+      "feature_key": "b15_2h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_return_n_uv",
+      "feature_key": "b15_2h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_ros1_l",
+      "feature_key": "b15_2h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_ros_l",
+      "feature_key": "b15_2h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_ros_minus1_l",
+      "feature_key": "b15_2h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_ros_minus_l",
+      "feature_key": "b15_2h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_ros_n1_l",
+      "feature_key": "b15_2h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_ros_n_l",
+      "feature_key": "b15_2h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_ros_one",
+      "feature_key": "b15_2h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_rovn1_l",
+      "feature_key": "b15_2h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_rovn_l",
+      "feature_key": "b15_2h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_share_cnt",
+      "feature_key": "b15_2h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_str",
+      "feature_key": "b15_2h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_2h_str_plus",
+      "feature_key": "b15_2h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_exp",
+      "feature_key": "b15_3h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_is_return_1",
+      "feature_key": "b15_3h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_is_share",
+      "feature_key": "b15_3h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_return_1_uv",
+      "feature_key": "b15_3h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_return_n_uv",
+      "feature_key": "b15_3h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_ros1_l",
+      "feature_key": "b15_3h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_ros_l",
+      "feature_key": "b15_3h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_ros_minus1_l",
+      "feature_key": "b15_3h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_ros_minus_l",
+      "feature_key": "b15_3h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_ros_n1_l",
+      "feature_key": "b15_3h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_ros_n_l",
+      "feature_key": "b15_3h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_ros_one",
+      "feature_key": "b15_3h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_rovn1_l",
+      "feature_key": "b15_3h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_rovn_l",
+      "feature_key": "b15_3h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_share_cnt",
+      "feature_key": "b15_3h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_str",
+      "feature_key": "b15_3h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_3h_str_plus",
+      "feature_key": "b15_3h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_exp",
+      "feature_key": "b15_6h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_is_return_1",
+      "feature_key": "b15_6h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_is_share",
+      "feature_key": "b15_6h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_return_1_uv",
+      "feature_key": "b15_6h@return_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_return_n_uv",
+      "feature_key": "b15_6h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_ros1_l",
+      "feature_key": "b15_6h@ros1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_ros_l",
+      "feature_key": "b15_6h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_ros_minus1_l",
+      "feature_key": "b15_6h@ros_minus1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_ros_minus_l",
+      "feature_key": "b15_6h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_ros_n1_l",
+      "feature_key": "b15_6h@ros_n1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_ros_n_l",
+      "feature_key": "b15_6h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_ros_one",
+      "feature_key": "b15_6h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_rovn1_l",
+      "feature_key": "b15_6h@rovn1_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_rovn_l",
+      "feature_key": "b15_6h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_share_cnt",
+      "feature_key": "b15_6h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_str",
+      "feature_key": "b15_6h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b15_6h_str_plus",
+      "feature_key": "b15_6h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_168h_exp",
+      "feature_key": "b1_168h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_168h_is_return_1",
+      "feature_key": "b1_168h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_168h_is_share",
+      "feature_key": "b1_168h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_168h_return_n_uv",
+      "feature_key": "b1_168h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_168h_ros_l",
+      "feature_key": "b1_168h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_168h_ros_minus_l",
+      "feature_key": "b1_168h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_168h_ros_n_l",
+      "feature_key": "b1_168h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_168h_ros_one",
+      "feature_key": "b1_168h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_168h_rovn_l",
+      "feature_key": "b1_168h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_168h_share_cnt",
+      "feature_key": "b1_168h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_168h_str",
+      "feature_key": "b1_168h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_168h_str_plus",
+      "feature_key": "b1_168h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_1h_exp",
+      "feature_key": "b1_1h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_1h_is_return_1",
+      "feature_key": "b1_1h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_1h_is_share",
+      "feature_key": "b1_1h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_1h_return_n_uv",
+      "feature_key": "b1_1h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_1h_ros_l",
+      "feature_key": "b1_1h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_1h_ros_minus_l",
+      "feature_key": "b1_1h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_1h_ros_n_l",
+      "feature_key": "b1_1h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_1h_ros_one",
+      "feature_key": "b1_1h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_1h_rovn_l",
+      "feature_key": "b1_1h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_1h_share_cnt",
+      "feature_key": "b1_1h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_1h_str",
+      "feature_key": "b1_1h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_1h_str_plus",
+      "feature_key": "b1_1h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_24h_exp",
+      "feature_key": "b1_24h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_24h_is_return_1",
+      "feature_key": "b1_24h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_24h_is_share",
+      "feature_key": "b1_24h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_24h_return_n_uv",
+      "feature_key": "b1_24h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_24h_ros_l",
+      "feature_key": "b1_24h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_24h_ros_minus_l",
+      "feature_key": "b1_24h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_24h_ros_n_l",
+      "feature_key": "b1_24h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_24h_ros_one",
+      "feature_key": "b1_24h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_24h_rovn_l",
+      "feature_key": "b1_24h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_24h_share_cnt",
+      "feature_key": "b1_24h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_24h_str",
+      "feature_key": "b1_24h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_24h_str_plus",
+      "feature_key": "b1_24h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_3h_exp",
+      "feature_key": "b1_3h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_3h_is_return_1",
+      "feature_key": "b1_3h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_3h_is_share",
+      "feature_key": "b1_3h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_3h_return_n_uv",
+      "feature_key": "b1_3h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_3h_ros_l",
+      "feature_key": "b1_3h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_3h_ros_minus_l",
+      "feature_key": "b1_3h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_3h_ros_n_l",
+      "feature_key": "b1_3h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_3h_ros_one",
+      "feature_key": "b1_3h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_3h_rovn_l",
+      "feature_key": "b1_3h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_3h_share_cnt",
+      "feature_key": "b1_3h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_3h_str",
+      "feature_key": "b1_3h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_3h_str_plus",
+      "feature_key": "b1_3h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_6h_exp",
+      "feature_key": "b1_6h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_6h_is_return_1",
+      "feature_key": "b1_6h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_6h_is_share",
+      "feature_key": "b1_6h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_6h_return_n_uv",
+      "feature_key": "b1_6h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_6h_ros_l",
+      "feature_key": "b1_6h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_6h_ros_minus_l",
+      "feature_key": "b1_6h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_6h_ros_n_l",
+      "feature_key": "b1_6h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_6h_ros_one",
+      "feature_key": "b1_6h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_6h_rovn_l",
+      "feature_key": "b1_6h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_6h_share_cnt",
+      "feature_key": "b1_6h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_6h_str",
+      "feature_key": "b1_6h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_6h_str_plus",
+      "feature_key": "b1_6h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_72h_exp",
+      "feature_key": "b1_72h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_72h_is_return_1",
+      "feature_key": "b1_72h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_72h_is_share",
+      "feature_key": "b1_72h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_72h_return_n_uv",
+      "feature_key": "b1_72h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_72h_ros_l",
+      "feature_key": "b1_72h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_72h_ros_minus_l",
+      "feature_key": "b1_72h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_72h_ros_n_l",
+      "feature_key": "b1_72h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_72h_ros_one",
+      "feature_key": "b1_72h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_72h_rovn_l",
+      "feature_key": "b1_72h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_72h_share_cnt",
+      "feature_key": "b1_72h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_72h_str",
+      "feature_key": "b1_72h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b1_72h_str_plus",
+      "feature_key": "b1_72h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_1h_exp",
+      "feature_key": "b2_1h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_1h_is_return_1",
+      "feature_key": "b2_1h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_1h_is_share",
+      "feature_key": "b2_1h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_1h_return_n_uv",
+      "feature_key": "b2_1h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_1h_ros_l",
+      "feature_key": "b2_1h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_1h_ros_minus_l",
+      "feature_key": "b2_1h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_1h_ros_n_l",
+      "feature_key": "b2_1h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_1h_ros_one",
+      "feature_key": "b2_1h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_1h_rovn_l",
+      "feature_key": "b2_1h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_1h_share_cnt",
+      "feature_key": "b2_1h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_1h_str",
+      "feature_key": "b2_1h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_1h_str_plus",
+      "feature_key": "b2_1h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_24h_exp",
+      "feature_key": "b2_24h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_24h_is_return_1",
+      "feature_key": "b2_24h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_24h_is_share",
+      "feature_key": "b2_24h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_24h_return_n_uv",
+      "feature_key": "b2_24h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_24h_ros_l",
+      "feature_key": "b2_24h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_24h_ros_minus_l",
+      "feature_key": "b2_24h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_24h_ros_n_l",
+      "feature_key": "b2_24h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_24h_ros_one",
+      "feature_key": "b2_24h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_24h_rovn_l",
+      "feature_key": "b2_24h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_24h_share_cnt",
+      "feature_key": "b2_24h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_24h_str",
+      "feature_key": "b2_24h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_24h_str_plus",
+      "feature_key": "b2_24h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_3h_exp",
+      "feature_key": "b2_3h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_3h_is_return_1",
+      "feature_key": "b2_3h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_3h_is_share",
+      "feature_key": "b2_3h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_3h_return_n_uv",
+      "feature_key": "b2_3h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_3h_ros_l",
+      "feature_key": "b2_3h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_3h_ros_minus_l",
+      "feature_key": "b2_3h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_3h_ros_n_l",
+      "feature_key": "b2_3h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_3h_ros_one",
+      "feature_key": "b2_3h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_3h_rovn_l",
+      "feature_key": "b2_3h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_3h_share_cnt",
+      "feature_key": "b2_3h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_3h_str",
+      "feature_key": "b2_3h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_3h_str_plus",
+      "feature_key": "b2_3h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_6h_exp",
+      "feature_key": "b2_6h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_6h_is_return_1",
+      "feature_key": "b2_6h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_6h_is_share",
+      "feature_key": "b2_6h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_6h_return_n_uv",
+      "feature_key": "b2_6h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_6h_ros_l",
+      "feature_key": "b2_6h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_6h_ros_minus_l",
+      "feature_key": "b2_6h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_6h_ros_n_l",
+      "feature_key": "b2_6h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_6h_ros_one",
+      "feature_key": "b2_6h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_6h_rovn_l",
+      "feature_key": "b2_6h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_6h_share_cnt",
+      "feature_key": "b2_6h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_6h_str",
+      "feature_key": "b2_6h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b2_6h_str_plus",
+      "feature_key": "b2_6h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_24h_exp",
+      "feature_key": "b3_24h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_24h_is_return_1",
+      "feature_key": "b3_24h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_24h_is_share",
+      "feature_key": "b3_24h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_24h_return_n_uv",
+      "feature_key": "b3_24h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_24h_ros_l",
+      "feature_key": "b3_24h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_24h_ros_minus_l",
+      "feature_key": "b3_24h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_24h_ros_n_l",
+      "feature_key": "b3_24h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_24h_ros_one",
+      "feature_key": "b3_24h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_24h_rovn_l",
+      "feature_key": "b3_24h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_24h_share_cnt",
+      "feature_key": "b3_24h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_24h_str",
+      "feature_key": "b3_24h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_24h_str_plus",
+      "feature_key": "b3_24h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_3h_exp",
+      "feature_key": "b3_3h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_3h_is_return_1",
+      "feature_key": "b3_3h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_3h_is_share",
+      "feature_key": "b3_3h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_3h_return_n_uv",
+      "feature_key": "b3_3h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_3h_ros_l",
+      "feature_key": "b3_3h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_3h_ros_minus_l",
+      "feature_key": "b3_3h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_3h_ros_n_l",
+      "feature_key": "b3_3h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_3h_ros_one",
+      "feature_key": "b3_3h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_3h_rovn_l",
+      "feature_key": "b3_3h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_3h_share_cnt",
+      "feature_key": "b3_3h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_3h_str",
+      "feature_key": "b3_3h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_3h_str_plus",
+      "feature_key": "b3_3h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_6h_exp",
+      "feature_key": "b3_6h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_6h_is_return_1",
+      "feature_key": "b3_6h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_6h_is_share",
+      "feature_key": "b3_6h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_6h_return_n_uv",
+      "feature_key": "b3_6h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_6h_ros_l",
+      "feature_key": "b3_6h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_6h_ros_minus_l",
+      "feature_key": "b3_6h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_6h_ros_n_l",
+      "feature_key": "b3_6h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_6h_ros_one",
+      "feature_key": "b3_6h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_6h_rovn_l",
+      "feature_key": "b3_6h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_6h_share_cnt",
+      "feature_key": "b3_6h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_6h_str",
+      "feature_key": "b3_6h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_6h_str_plus",
+      "feature_key": "b3_6h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_72h_is_share",
+      "feature_key": "b3_72h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_72h_return_n_uv",
+      "feature_key": "b3_72h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_72h_ros_l",
+      "feature_key": "b3_72h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_72h_ros_minus_l",
+      "feature_key": "b3_72h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_72h_ros_n_l",
+      "feature_key": "b3_72h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_72h_ros_one",
+      "feature_key": "b3_72h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_72h_rovn_l",
+      "feature_key": "b3_72h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_72h_str",
+      "feature_key": "b3_72h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b3_72h_str_plus",
+      "feature_key": "b3_72h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_12h_exp",
+      "feature_key": "b4_12h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_12h_is_return_1",
+      "feature_key": "b4_12h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_12h_is_share",
+      "feature_key": "b4_12h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_12h_return_n_uv",
+      "feature_key": "b4_12h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_12h_ros_l",
+      "feature_key": "b4_12h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_12h_ros_minus_l",
+      "feature_key": "b4_12h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_12h_ros_n_l",
+      "feature_key": "b4_12h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_12h_ros_one",
+      "feature_key": "b4_12h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_12h_rovn_l",
+      "feature_key": "b4_12h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_12h_share_cnt",
+      "feature_key": "b4_12h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_12h_str",
+      "feature_key": "b4_12h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_12h_str_plus",
+      "feature_key": "b4_12h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_1h_exp",
+      "feature_key": "b4_1h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_1h_is_return_1",
+      "feature_key": "b4_1h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_1h_is_share",
+      "feature_key": "b4_1h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_1h_return_n_uv",
+      "feature_key": "b4_1h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_1h_ros_l",
+      "feature_key": "b4_1h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_1h_ros_minus_l",
+      "feature_key": "b4_1h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_1h_ros_n_l",
+      "feature_key": "b4_1h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_1h_ros_one",
+      "feature_key": "b4_1h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_1h_rovn_l",
+      "feature_key": "b4_1h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_1h_share_cnt",
+      "feature_key": "b4_1h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_1h_str",
+      "feature_key": "b4_1h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_1h_str_plus",
+      "feature_key": "b4_1h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_24h_exp",
+      "feature_key": "b4_24h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_24h_is_return_1",
+      "feature_key": "b4_24h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_24h_is_share",
+      "feature_key": "b4_24h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_24h_return_n_uv",
+      "feature_key": "b4_24h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_24h_ros_l",
+      "feature_key": "b4_24h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_24h_ros_minus_l",
+      "feature_key": "b4_24h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_24h_ros_n_l",
+      "feature_key": "b4_24h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_24h_ros_one",
+      "feature_key": "b4_24h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_24h_rovn_l",
+      "feature_key": "b4_24h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_24h_share_cnt",
+      "feature_key": "b4_24h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_24h_str",
+      "feature_key": "b4_24h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_24h_str_plus",
+      "feature_key": "b4_24h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_3h_exp",
+      "feature_key": "b4_3h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_3h_is_return_1",
+      "feature_key": "b4_3h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_3h_is_share",
+      "feature_key": "b4_3h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_3h_return_n_uv",
+      "feature_key": "b4_3h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_3h_ros_l",
+      "feature_key": "b4_3h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_3h_ros_minus_l",
+      "feature_key": "b4_3h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_3h_ros_n_l",
+      "feature_key": "b4_3h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_3h_ros_one",
+      "feature_key": "b4_3h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_3h_rovn_l",
+      "feature_key": "b4_3h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_3h_share_cnt",
+      "feature_key": "b4_3h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_3h_str",
+      "feature_key": "b4_3h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_3h_str_plus",
+      "feature_key": "b4_3h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_6h_exp",
+      "feature_key": "b4_6h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_6h_is_return_1",
+      "feature_key": "b4_6h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_6h_is_share",
+      "feature_key": "b4_6h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_6h_return_n_uv",
+      "feature_key": "b4_6h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_6h_ros_l",
+      "feature_key": "b4_6h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_6h_ros_minus_l",
+      "feature_key": "b4_6h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_6h_ros_n_l",
+      "feature_key": "b4_6h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_6h_ros_one",
+      "feature_key": "b4_6h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_6h_rovn_l",
+      "feature_key": "b4_6h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_6h_share_cnt",
+      "feature_key": "b4_6h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_6h_str",
+      "feature_key": "b4_6h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_6h_str_plus",
+      "feature_key": "b4_6h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_72h_exp",
+      "feature_key": "b4_72h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_72h_is_return_1",
+      "feature_key": "b4_72h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_72h_is_share",
+      "feature_key": "b4_72h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_72h_return_n_uv",
+      "feature_key": "b4_72h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_72h_ros_l",
+      "feature_key": "b4_72h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_72h_ros_minus_l",
+      "feature_key": "b4_72h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_72h_ros_n_l",
+      "feature_key": "b4_72h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_72h_ros_one",
+      "feature_key": "b4_72h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_72h_rovn_l",
+      "feature_key": "b4_72h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_72h_share_cnt",
+      "feature_key": "b4_72h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_72h_str",
+      "feature_key": "b4_72h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b4_72h_str_plus",
+      "feature_key": "b4_72h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_12h_exp",
+      "feature_key": "b5_12h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_12h_is_return_1",
+      "feature_key": "b5_12h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_12h_is_share",
+      "feature_key": "b5_12h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_12h_return_n_uv",
+      "feature_key": "b5_12h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_12h_ros_l",
+      "feature_key": "b5_12h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_12h_ros_minus_l",
+      "feature_key": "b5_12h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_12h_ros_n_l",
+      "feature_key": "b5_12h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_12h_ros_one",
+      "feature_key": "b5_12h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_12h_rovn_l",
+      "feature_key": "b5_12h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_12h_share_cnt",
+      "feature_key": "b5_12h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_12h_str",
+      "feature_key": "b5_12h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_12h_str_plus",
+      "feature_key": "b5_12h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_1h_exp",
+      "feature_key": "b5_1h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_1h_is_return_1",
+      "feature_key": "b5_1h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_1h_is_share",
+      "feature_key": "b5_1h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_1h_return_n_uv",
+      "feature_key": "b5_1h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_1h_ros_l",
+      "feature_key": "b5_1h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_1h_ros_minus_l",
+      "feature_key": "b5_1h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_1h_ros_n_l",
+      "feature_key": "b5_1h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_1h_ros_one",
+      "feature_key": "b5_1h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_1h_rovn_l",
+      "feature_key": "b5_1h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_1h_share_cnt",
+      "feature_key": "b5_1h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_1h_str",
+      "feature_key": "b5_1h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_1h_str_plus",
+      "feature_key": "b5_1h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_24h_exp",
+      "feature_key": "b5_24h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_24h_is_return_1",
+      "feature_key": "b5_24h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_24h_is_share",
+      "feature_key": "b5_24h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_24h_return_n_uv",
+      "feature_key": "b5_24h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_24h_ros_l",
+      "feature_key": "b5_24h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_24h_ros_minus_l",
+      "feature_key": "b5_24h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_24h_ros_n_l",
+      "feature_key": "b5_24h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_24h_ros_one",
+      "feature_key": "b5_24h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_24h_rovn_l",
+      "feature_key": "b5_24h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_24h_share_cnt",
+      "feature_key": "b5_24h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_24h_str",
+      "feature_key": "b5_24h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_24h_str_plus",
+      "feature_key": "b5_24h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_3h_exp",
+      "feature_key": "b5_3h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_3h_is_return_1",
+      "feature_key": "b5_3h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_3h_is_share",
+      "feature_key": "b5_3h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_3h_return_n_uv",
+      "feature_key": "b5_3h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_3h_ros_l",
+      "feature_key": "b5_3h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_3h_ros_minus_l",
+      "feature_key": "b5_3h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_3h_ros_n_l",
+      "feature_key": "b5_3h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_3h_ros_one",
+      "feature_key": "b5_3h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_3h_rovn_l",
+      "feature_key": "b5_3h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_3h_share_cnt",
+      "feature_key": "b5_3h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_3h_str",
+      "feature_key": "b5_3h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_3h_str_plus",
+      "feature_key": "b5_3h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_6h_exp",
+      "feature_key": "b5_6h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_6h_is_return_1",
+      "feature_key": "b5_6h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_6h_is_share",
+      "feature_key": "b5_6h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_6h_return_n_uv",
+      "feature_key": "b5_6h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_6h_ros_l",
+      "feature_key": "b5_6h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_6h_ros_minus_l",
+      "feature_key": "b5_6h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_6h_ros_n_l",
+      "feature_key": "b5_6h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_6h_ros_one",
+      "feature_key": "b5_6h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_6h_rovn_l",
+      "feature_key": "b5_6h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_6h_share_cnt",
+      "feature_key": "b5_6h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_6h_str",
+      "feature_key": "b5_6h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_6h_str_plus",
+      "feature_key": "b5_6h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_72h_exp",
+      "feature_key": "b5_72h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_72h_is_return_1",
+      "feature_key": "b5_72h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_72h_is_share",
+      "feature_key": "b5_72h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_72h_return_n_uv",
+      "feature_key": "b5_72h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_72h_ros_l",
+      "feature_key": "b5_72h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_72h_ros_minus_l",
+      "feature_key": "b5_72h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_72h_ros_n_l",
+      "feature_key": "b5_72h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_72h_ros_one",
+      "feature_key": "b5_72h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_72h_rovn_l",
+      "feature_key": "b5_72h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_72h_share_cnt",
+      "feature_key": "b5_72h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_72h_str",
+      "feature_key": "b5_72h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b5_72h_str_plus",
+      "feature_key": "b5_72h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_1h_is_share",
+      "feature_key": "b6_1h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_1h_return_n_uv",
+      "feature_key": "b6_1h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_1h_ros_l",
+      "feature_key": "b6_1h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_1h_ros_minus_l",
+      "feature_key": "b6_1h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_1h_ros_n_l",
+      "feature_key": "b6_1h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_1h_ros_one",
+      "feature_key": "b6_1h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_1h_rovn_l",
+      "feature_key": "b6_1h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_1h_str",
+      "feature_key": "b6_1h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_1h_str_plus",
+      "feature_key": "b6_1h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_24h_is_share",
+      "feature_key": "b6_24h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_24h_return_n_uv",
+      "feature_key": "b6_24h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_24h_ros_l",
+      "feature_key": "b6_24h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_24h_ros_minus_l",
+      "feature_key": "b6_24h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_24h_ros_n_l",
+      "feature_key": "b6_24h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_24h_ros_one",
+      "feature_key": "b6_24h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_24h_rovn_l",
+      "feature_key": "b6_24h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_24h_str",
+      "feature_key": "b6_24h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b6_24h_str_plus",
+      "feature_key": "b6_24h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_12h_exp",
+      "feature_key": "b7_12h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_12h_is_return_1",
+      "feature_key": "b7_12h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_12h_is_share",
+      "feature_key": "b7_12h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_12h_return_n_uv",
+      "feature_key": "b7_12h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_12h_ros_l",
+      "feature_key": "b7_12h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_12h_ros_minus_l",
+      "feature_key": "b7_12h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_12h_ros_n_l",
+      "feature_key": "b7_12h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_12h_ros_one",
+      "feature_key": "b7_12h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_12h_rovn_l",
+      "feature_key": "b7_12h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_12h_share_cnt",
+      "feature_key": "b7_12h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_12h_str",
+      "feature_key": "b7_12h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_12h_str_plus",
+      "feature_key": "b7_12h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_1h_exp",
+      "feature_key": "b7_1h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_1h_is_return_1",
+      "feature_key": "b7_1h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_1h_is_share",
+      "feature_key": "b7_1h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_1h_return_n_uv",
+      "feature_key": "b7_1h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_1h_ros_l",
+      "feature_key": "b7_1h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_1h_ros_minus_l",
+      "feature_key": "b7_1h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_1h_ros_n_l",
+      "feature_key": "b7_1h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_1h_ros_one",
+      "feature_key": "b7_1h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_1h_rovn_l",
+      "feature_key": "b7_1h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_1h_share_cnt",
+      "feature_key": "b7_1h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_1h_str",
+      "feature_key": "b7_1h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_1h_str_plus",
+      "feature_key": "b7_1h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_24h_exp",
+      "feature_key": "b7_24h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_24h_is_return_1",
+      "feature_key": "b7_24h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_24h_is_share",
+      "feature_key": "b7_24h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_24h_return_n_uv",
+      "feature_key": "b7_24h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_24h_ros_l",
+      "feature_key": "b7_24h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_24h_ros_minus_l",
+      "feature_key": "b7_24h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_24h_ros_n_l",
+      "feature_key": "b7_24h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_24h_ros_one",
+      "feature_key": "b7_24h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_24h_rovn_l",
+      "feature_key": "b7_24h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_24h_share_cnt",
+      "feature_key": "b7_24h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_24h_str",
+      "feature_key": "b7_24h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_24h_str_plus",
+      "feature_key": "b7_24h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_3h_exp",
+      "feature_key": "b7_3h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_3h_is_return_1",
+      "feature_key": "b7_3h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_3h_is_share",
+      "feature_key": "b7_3h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_3h_return_n_uv",
+      "feature_key": "b7_3h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_3h_ros_l",
+      "feature_key": "b7_3h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_3h_ros_minus_l",
+      "feature_key": "b7_3h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_3h_ros_n_l",
+      "feature_key": "b7_3h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_3h_ros_one",
+      "feature_key": "b7_3h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_3h_rovn_l",
+      "feature_key": "b7_3h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_3h_share_cnt",
+      "feature_key": "b7_3h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_3h_str",
+      "feature_key": "b7_3h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_3h_str_plus",
+      "feature_key": "b7_3h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_6h_exp",
+      "feature_key": "b7_6h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_6h_is_return_1",
+      "feature_key": "b7_6h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_6h_is_share",
+      "feature_key": "b7_6h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_6h_return_n_uv",
+      "feature_key": "b7_6h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_6h_ros_l",
+      "feature_key": "b7_6h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_6h_ros_minus_l",
+      "feature_key": "b7_6h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_6h_ros_n_l",
+      "feature_key": "b7_6h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_6h_ros_one",
+      "feature_key": "b7_6h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_6h_rovn_l",
+      "feature_key": "b7_6h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_6h_share_cnt",
+      "feature_key": "b7_6h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_6h_str",
+      "feature_key": "b7_6h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_6h_str_plus",
+      "feature_key": "b7_6h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_72h_is_share",
+      "feature_key": "b7_72h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_72h_return_n_uv",
+      "feature_key": "b7_72h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_72h_ros_l",
+      "feature_key": "b7_72h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_72h_ros_minus_l",
+      "feature_key": "b7_72h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_72h_ros_n_l",
+      "feature_key": "b7_72h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_72h_ros_one",
+      "feature_key": "b7_72h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_72h_rovn_l",
+      "feature_key": "b7_72h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_72h_str",
+      "feature_key": "b7_72h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b7_72h_str_plus",
+      "feature_key": "b7_72h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_1h_exp",
+      "feature_key": "b8_1h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_1h_is_return_1",
+      "feature_key": "b8_1h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_1h_is_share",
+      "feature_key": "b8_1h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_1h_return_n_uv",
+      "feature_key": "b8_1h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_1h_ros_l",
+      "feature_key": "b8_1h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_1h_ros_minus_l",
+      "feature_key": "b8_1h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_1h_ros_n_l",
+      "feature_key": "b8_1h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_1h_ros_one",
+      "feature_key": "b8_1h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_1h_rovn_l",
+      "feature_key": "b8_1h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_1h_share_cnt",
+      "feature_key": "b8_1h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_1h_str",
+      "feature_key": "b8_1h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_1h_str_plus",
+      "feature_key": "b8_1h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_24h_exp",
+      "feature_key": "b8_24h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_24h_is_return_1",
+      "feature_key": "b8_24h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_24h_is_share",
+      "feature_key": "b8_24h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_24h_return_n_uv",
+      "feature_key": "b8_24h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_24h_ros_l",
+      "feature_key": "b8_24h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_24h_ros_minus_l",
+      "feature_key": "b8_24h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_24h_ros_n_l",
+      "feature_key": "b8_24h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_24h_ros_one",
+      "feature_key": "b8_24h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_24h_rovn_l",
+      "feature_key": "b8_24h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_24h_share_cnt",
+      "feature_key": "b8_24h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_24h_str",
+      "feature_key": "b8_24h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_24h_str_plus",
+      "feature_key": "b8_24h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_3h_exp",
+      "feature_key": "b8_3h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_3h_is_return_1",
+      "feature_key": "b8_3h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_3h_is_share",
+      "feature_key": "b8_3h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_3h_return_n_uv",
+      "feature_key": "b8_3h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_3h_ros_l",
+      "feature_key": "b8_3h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_3h_ros_minus_l",
+      "feature_key": "b8_3h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_3h_ros_n_l",
+      "feature_key": "b8_3h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_3h_ros_one",
+      "feature_key": "b8_3h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_3h_rovn_l",
+      "feature_key": "b8_3h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_3h_share_cnt",
+      "feature_key": "b8_3h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_3h_str",
+      "feature_key": "b8_3h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b8_3h_str_plus",
+      "feature_key": "b8_3h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_1h_exp",
+      "feature_key": "b9_1h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_1h_is_return_1",
+      "feature_key": "b9_1h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_1h_is_share",
+      "feature_key": "b9_1h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_1h_return_n_uv",
+      "feature_key": "b9_1h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_1h_ros_l",
+      "feature_key": "b9_1h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_1h_ros_minus_l",
+      "feature_key": "b9_1h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_1h_ros_n_l",
+      "feature_key": "b9_1h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_1h_ros_one",
+      "feature_key": "b9_1h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_1h_rovn_l",
+      "feature_key": "b9_1h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_1h_share_cnt",
+      "feature_key": "b9_1h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_1h_str",
+      "feature_key": "b9_1h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_1h_str_plus",
+      "feature_key": "b9_1h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_24h_exp",
+      "feature_key": "b9_24h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_24h_is_return_1",
+      "feature_key": "b9_24h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_24h_is_share",
+      "feature_key": "b9_24h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_24h_return_n_uv",
+      "feature_key": "b9_24h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_24h_ros_l",
+      "feature_key": "b9_24h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_24h_ros_minus_l",
+      "feature_key": "b9_24h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_24h_ros_n_l",
+      "feature_key": "b9_24h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_24h_ros_one",
+      "feature_key": "b9_24h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_24h_rovn_l",
+      "feature_key": "b9_24h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_24h_share_cnt",
+      "feature_key": "b9_24h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_24h_str",
+      "feature_key": "b9_24h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_24h_str_plus",
+      "feature_key": "b9_24h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_3h_exp",
+      "feature_key": "b9_3h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_3h_is_return_1",
+      "feature_key": "b9_3h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_3h_is_share",
+      "feature_key": "b9_3h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_3h_return_n_uv",
+      "feature_key": "b9_3h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_3h_ros_l",
+      "feature_key": "b9_3h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_3h_ros_minus_l",
+      "feature_key": "b9_3h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_3h_ros_n_l",
+      "feature_key": "b9_3h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_3h_ros_one",
+      "feature_key": "b9_3h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_3h_rovn_l",
+      "feature_key": "b9_3h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_3h_share_cnt",
+      "feature_key": "b9_3h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_3h_str",
+      "feature_key": "b9_3h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "b9_3h_str_plus",
+      "feature_key": "b9_3h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "user_brand",
+      "feature_key": "user_brand",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c1_168h_exp",
+      "feature_key": "c1_168h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_168h_is_return_1",
+      "feature_key": "c1_168h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_168h_is_share",
+      "feature_key": "c1_168h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_168h_return_n_uv",
+      "feature_key": "c1_168h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_168h_ros_l",
+      "feature_key": "c1_168h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_168h_ros_minus_l",
+      "feature_key": "c1_168h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_168h_ros_n_l",
+      "feature_key": "c1_168h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_168h_ros_one",
+      "feature_key": "c1_168h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_168h_rovn_l",
+      "feature_key": "c1_168h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_168h_share_cnt",
+      "feature_key": "c1_168h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_168h_str",
+      "feature_key": "c1_168h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_168h_str_plus",
+      "feature_key": "c1_168h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_72h_exp",
+      "feature_key": "c1_72h@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_72h_is_return_1",
+      "feature_key": "c1_72h@is_return_1",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_72h_is_share",
+      "feature_key": "c1_72h@is_share",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_72h_return_n_uv",
+      "feature_key": "c1_72h@return_n_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_72h_ros_l",
+      "feature_key": "c1_72h@ros_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_72h_ros_minus_l",
+      "feature_key": "c1_72h@ros_minus_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_72h_ros_n_l",
+      "feature_key": "c1_72h@ros_n_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_72h_ros_one",
+      "feature_key": "c1_72h@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_72h_rovn_l",
+      "feature_key": "c1_72h@rovn_#",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_72h_share_cnt",
+      "feature_key": "c1_72h@share_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_72h_str",
+      "feature_key": "c1_72h@str",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c1_72h_str_plus",
+      "feature_key": "c1_72h@str_plus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_m_r_uv",
+      "feature_key": "c9@m_r_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_m_s_cnt",
+      "feature_key": "c9@m_s_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_r_pv",
+      "feature_key": "c9@r_pv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_r_uv",
+      "feature_key": "c9@r_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_ros",
+      "feature_key": "c9@ros",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_ros_l",
+      "feature_key": "c9@ros_l",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_ros_minus",
+      "feature_key": "c9@ros_minus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_ros_minus_l",
+      "feature_key": "c9@ros_minus_l",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_ros_one",
+      "feature_key": "c9@ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_s_cnt",
+      "feature_key": "c9@s_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_s_pv",
+      "feature_key": "c9@s_pv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c1s_mu",
+      "feature_key": "c9@c1s_mu",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c1s_ros",
+      "feature_key": "c9@c1s_ros",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c1s_ros_l",
+      "feature_key": "c9@c1s_ros_l",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c1s_ros_minus",
+      "feature_key": "c9@c1s_ros_minus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c1s_ros_minus_l",
+      "feature_key": "c9@c1s_ros_minus_l",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c1s_ros_one",
+      "feature_key": "c9@c1s_ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c1s_rp",
+      "feature_key": "c9@c1s_rp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c1s_ru",
+      "feature_key": "c9@c1s_ru",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c1s_sp",
+      "feature_key": "c9@c1s_sp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c2s_mu",
+      "feature_key": "c9@c2s_mu",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c2s_ros",
+      "feature_key": "c9@c2s_ros",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c2s_ros_l",
+      "feature_key": "c9@c2s_ros_l",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c2s_ros_minus",
+      "feature_key": "c9@c2s_ros_minus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c2s_ros_minus_l",
+      "feature_key": "c9@c2s_ros_minus_l",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c2s_ros_one",
+      "feature_key": "c9@c2s_ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c2s_rp",
+      "feature_key": "c9@c2s_rp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c2s_ru",
+      "feature_key": "c9@c2s_ru",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_c2s_sp",
+      "feature_key": "c9@c2s_sp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l1s_mu",
+      "feature_key": "c9@l1s_mu",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l1s_ros",
+      "feature_key": "c9@l1s_ros",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l1s_ros_l",
+      "feature_key": "c9@l1s_ros_l",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l1s_ros_minus",
+      "feature_key": "c9@l1s_ros_minus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l1s_ros_minus_l",
+      "feature_key": "c9@l1s_ros_minus_l",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l1s_ros_one",
+      "feature_key": "c9@l1s_ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l1s_rp",
+      "feature_key": "c9@l1s_rp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l1s_ru",
+      "feature_key": "c9@l1s_ru",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l1s_sp",
+      "feature_key": "c9@l1s_sp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l2s_mu",
+      "feature_key": "c9@l2s_mu",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l2s_ros",
+      "feature_key": "c9@l2s_ros",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l2s_ros_l",
+      "feature_key": "c9@l2s_ros_l",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l2s_ros_minus",
+      "feature_key": "c9@l2s_ros_minus",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l2s_ros_minus_l",
+      "feature_key": "c9@l2s_ros_minus_l",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l2s_ros_one",
+      "feature_key": "c9@l2s_ros_one",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l2s_rp",
+      "feature_key": "c9@l2s_rp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l2s_ru",
+      "feature_key": "c9@l2s_ru",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_l2s_sp",
+      "feature_key": "c9@l2s_sp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_lr1s_1_cate1",
+      "feature_key": "c9@lr1s_1_cate1",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lr1s_1_cate2",
+      "feature_key": "c9@lr1s_1_cate2",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lr1s_1_ts",
+      "feature_key": "c9@lr1s_1_ts",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_lr1s_1_uv",
+      "feature_key": "c9@lr1s_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_lr1s_1_hour",
+      "feature_key": "c9@lr1s_1_hour",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lr1s_1_week",
+      "feature_key": "c9@lr1s_1_week",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lr1s_2_cate1",
+      "feature_key": "c9@lr1s_2_cate1",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lr1s_2_cate2",
+      "feature_key": "c9@lr1s_2_cate2",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lr1s_2_ts",
+      "feature_key": "c9@lr1s_2_ts",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_lr1s_2_uv",
+      "feature_key": "c9@lr1s_2_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_lr1s_2_hour",
+      "feature_key": "c9@lr1s_2_hour",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lr1s_2_week",
+      "feature_key": "c9@lr1s_2_week",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lrs_1_ts",
+      "feature_key": "c9@lrs_1_ts",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_lrs_1_uv",
+      "feature_key": "c9@lrs_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_lrs_1_hour",
+      "feature_key": "c9@lrs_1_hour",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lrs_1_week",
+      "feature_key": "c9@lrs_1_week",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lrs_2_ts",
+      "feature_key": "c9@lrs_2_ts",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_lrs_2_uv",
+      "feature_key": "c9@lrs_2_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_lrs_2_hour",
+      "feature_key": "c9@lrs_2_hour",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lrs_2_week",
+      "feature_key": "c9@lrs_2_week",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lss_1_cate1",
+      "feature_key": "c9@lss_1_cate1",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lss_1_cate2",
+      "feature_key": "c9@lss_1_cate2",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lss_1_cnt",
+      "feature_key": "c9@lss_1_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_lss_1_ts",
+      "feature_key": "c9@lss_1_ts",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_lss_1_hour",
+      "feature_key": "c9@lss_1_hour",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lss_1_week",
+      "feature_key": "c9@lss_1_week",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lss_2_cate1",
+      "feature_key": "c9@lss_2_cate1",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lss_2_cate2",
+      "feature_key": "c9@lss_2_cate2",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lss_2_cnt",
+      "feature_key": "c9@lss_2_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_lss_2_ts",
+      "feature_key": "c9@lss_2_ts",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_lss_2_hour",
+      "feature_key": "c9@lss_2_hour",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_lss_2_week",
+      "feature_key": "c9@lss_2_week",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_mrs_1_ts",
+      "feature_key": "c9@mrs_1_ts",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_mrs_1_uv",
+      "feature_key": "c9@mrs_1_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_mrs_1_hour",
+      "feature_key": "c9@mrs_1_hour",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_mrs_1_week",
+      "feature_key": "c9@mrs_1_week",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_mrs_2_ts",
+      "feature_key": "c9@mrs_2_ts",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_mrs_2_uv",
+      "feature_key": "c9@mrs_2_uv",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_mrs_2_hour",
+      "feature_key": "c9@mrs_2_hour",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_mrs_2_week",
+      "feature_key": "c9@mrs_2_week",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_mss_1_cnt",
+      "feature_key": "c9@mss_1_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_mss_1_ts",
+      "feature_key": "c9@mss_1_ts",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_mss_1_hour",
+      "feature_key": "c9@mss_1_hour",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_mss_1_week",
+      "feature_key": "c9@mss_1_week",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_mss_2_cnt",
+      "feature_key": "c9@mss_2_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_mss_2_ts",
+      "feature_key": "c9@mss_2_ts",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "c9_mss_2_hour",
+      "feature_key": "c9@mss_2_hour",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "c9_mss_2_week",
+      "feature_key": "c9@mss_2_week",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "user_city",
+      "feature_key": "user_city",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "d1_ros_cf_rank",
+      "feature_key": "d1@ros_cf_rank",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "d1_ros_cf_score",
+      "feature_key": "d1@ros_cf_score",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "d1_rov_cf_rank",
+      "feature_key": "d1@rov_cf_rank",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "d1_rov_cf_score",
+      "feature_key": "d1@rov_cf_score",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "d2_rank",
+      "feature_key": "d2@rank",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "d2_score",
+      "feature_key": "d2@score",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "d3_exp",
+      "feature_key": "d3@exp",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "d3_return_n",
+      "feature_key": "d3@return_n",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "d3_rovn",
+      "feature_key": "d3@rovn",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "e1_ghid",
+      "feature_key": "e1@ghid",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "e1_name",
+      "feature_key": "e1@name",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "h_bit_rate",
+      "feature_key": "h@bit_rate",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "h_cate1_list",
+      "feature_key": "h@cate1_list",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "h_cate2",
+      "feature_key": "h@cate2",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "h_channel",
+      "feature_key": "h@channel",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "h_festive_label1",
+      "feature_key": "h@festive_label1",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "h_keywords",
+      "feature_key": "h@keywords",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "h_merge_first_level_cate",
+      "feature_key": "h@merge_first_level_cate",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "h_merge_second_level_cate",
+      "feature_key": "h@merge_second_level_cate",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "h_resolution",
+      "feature_key": "h@resolution",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "h_total_time",
+      "feature_key": "h@total_time",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "h_ts",
+      "feature_key": "h@ts",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "h_time_type",
+      "feature_key": "h@time_type",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "h_uid",
+      "feature_key": "h@uid",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "h_vid_source",
+      "feature_key": "h@vid_source",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "ctx_hot",
+      "feature_key": "ctx_hot",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "ctx_hour_val",
+      "feature_key": "hour",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "ctx_hour",
+      "feature_key": "ctx_hour",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "user_model",
+      "feature_key": "user_model",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "page_is_return",
+      "feature_key": "page_is_return",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "user_province",
+      "feature_key": "user_province",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "r_bit_rate",
+      "feature_key": "r@bit_rate",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "r_cate1_list",
+      "feature_key": "r@cate1_list",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "r_cate2",
+      "feature_key": "r@cate2",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "r_channel",
+      "feature_key": "r@channel",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "r_festive_label1",
+      "feature_key": "r@festive_label1",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "r_keywords",
+      "feature_key": "r@keywords",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "r_merge_first_level_cate",
+      "feature_key": "r@merge_first_level_cate",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "r_merge_second_level_cate",
+      "feature_key": "r@merge_second_level_cate",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "r_resolution",
+      "feature_key": "r@resolution",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "r_total_time",
+      "feature_key": "r@total_time",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "r_ts",
+      "feature_key": "r@ts",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "r_time_type",
+      "feature_key": "r@time_type",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "r_uid",
+      "feature_key": "r@uid",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "user_system",
+      "feature_key": "user_system",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "user_channel",
+      "feature_key": "user_channel",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "user_level",
+      "feature_key": "user_level",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "ctx_week",
+      "feature_key": "ctx_week",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "r_vid_source",
+      "feature_key": "r@vid_source",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "r_vid",
+      "feature_key": "r@vid",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "headvideoid",
+      "feature_key": "headvideoid",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "act_vid_seq",
+      "feature_key": "act_vid_seq",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "act_type_seq",
+      "feature_key": "act_type_seq",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "act_cate1_seq",
+      "feature_key": "act_cate1_seq",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "act_cate2_seq",
+      "feature_key": "act_cate2_seq",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "net_vid_seq",
+      "feature_key": "net_vid_seq",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "net_union_id_seq",
+      "feature_key": "net_union_id_seq",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "net_cate1_seq",
+      "feature_key": "net_cate1_seq",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "net_cate2_seq",
+      "feature_key": "net_cate2_seq",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "union_id",
+      "feature_key": "union_id",
+      "value_type": "String",
+      "default_value": "-1024"
+    },
+    {
+      "feature_name": "user_pref_video_overlap_cnt",
+      "feature_key": "user_pref_video_overlap_cnt",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "user_pref_video_max_score",
+      "feature_key": "user_pref_video_max_score",
+      "value_type": "Double",
+      "default_value": "0"
+    },
+    {
+      "feature_name": "user_pref_video_sum_score",
+      "feature_key": "user_pref_video_sum_score",
+      "value_type": "Double",
+      "default_value": "0"
+    }
+  ],
+  "reserves": []
+}