Limengbo hace 5 años
padre
commit
35693262c1
Se han modificado 85 ficheros con 2601 adiciones y 1129 borrados
  1. 128 2
      android/app/src/main/assets/index.android.bundle
  2. 5 2
      android/app/src/main/java/com/edufound/CustomPackage.java
  3. 1 3
      android/app/src/main/java/com/edufound/mobile/activity/WebActivity.java
  4. 1 1
      android/app/src/main/java/com/edufound/mobile/Util/AndroidUtil.java
  5. 88 0
      android/app/src/main/java/com/edufound/mobile/util/PermissionConstants.java
  6. 335 0
      android/app/src/main/java/com/edufound/mobile/util/PermissionUtils.java
  7. 124 0
      android/app/src/main/java/com/edufound/mobile/util/Utils.java
  8. 24 0
      android/app/src/main/java/com/edufound/mobile/view/modal/BUCK
  9. 65 0
      android/app/src/main/java/com/edufound/mobile/view/modal/ModalHostHelper.java
  10. 38 0
      android/app/src/main/java/com/edufound/mobile/view/modal/ModalHostShadowNode.java
  11. 327 0
      android/app/src/main/java/com/edufound/mobile/view/modal/PopModal.java
  12. 147 0
      android/app/src/main/java/com/edufound/mobile/view/modal/PopModalManager.java
  13. BIN
      android/app/src/main/res/drawable-mdpi/pages_images_userinfo_arrow.png
  14. BIN
      android/app/src/main/res/drawable-mdpi/pages_images_userinfo_back_white.png
  15. BIN
      android/app/src/main/res/drawable-mdpi/pages_images_userinfo_birthday.png
  16. BIN
      android/app/src/main/res/drawable-mdpi/pages_images_userinfo_grade.png
  17. BIN
      android/app/src/main/res/drawable-mdpi/pages_images_userinfo_headportrait.png
  18. BIN
      android/app/src/main/res/drawable-mdpi/pages_images_userinfo_location.png
  19. BIN
      android/app/src/main/res/drawable-mdpi/pages_images_userinfo_logoutbg.png
  20. BIN
      android/app/src/main/res/drawable-mdpi/pages_images_userinfo_nickname.png
  21. BIN
      android/app/src/main/res/drawable-mdpi/pages_images_userinfo_school.png
  22. BIN
      android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_arrow.png
  23. BIN
      android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_back_white.png
  24. BIN
      android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_birthday.png
  25. BIN
      android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_grade.png
  26. BIN
      android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_headportrait.png
  27. BIN
      android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_location.png
  28. BIN
      android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_logoutbg.png
  29. BIN
      android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_nickname.png
  30. BIN
      android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_school.png
  31. BIN
      android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_arrow.png
  32. BIN
      android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_back_white.png
  33. BIN
      android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_birthday.png
  34. BIN
      android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_grade.png
  35. BIN
      android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_headportrait.png
  36. BIN
      android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_location.png
  37. BIN
      android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_logoutbg1.png
  38. BIN
      android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_nickname.png
  39. BIN
      android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_school.png
  40. 21 7
      package-lock.json
  41. 39 39
      package.json
  42. 44 55
      pages/Login.js
  43. 25 25
      pages/PersonalInfo.js
  44. 51 49
      pages/PhoneBind.js
  45. 81 86
      pages/buy/buy.js
  46. 70 59
      pages/buy/ticket.js
  47. 15 2
      pages/components/BirthdayModal.js
  48. 204 199
      pages/components/ChosePhoto.js
  49. 1 1
      pages/components/CourseTitle.js
  50. 2 2
      pages/components/MainPage.js
  51. 261 255
      pages/components/PersonalInfoDialog.js
  52. 335 329
      pages/components/RegionModal.js
  53. 44 0
      pages/components/modol.js
  54. BIN
      pages/images/userInfo/arrow.png
  55. BIN
      pages/images/userInfo/arrow@2x.png
  56. BIN
      pages/images/userInfo/arrow@3x.png
  57. BIN
      pages/images/userInfo/back_white.png
  58. BIN
      pages/images/userInfo/back_white@2x.png
  59. BIN
      pages/images/userInfo/back_white@3x.png
  60. BIN
      pages/images/userInfo/birthday.png
  61. BIN
      pages/images/userInfo/birthday@2x.png
  62. BIN
      pages/images/userInfo/birthday@3x.png
  63. BIN
      pages/images/userInfo/grade.png
  64. BIN
      pages/images/userInfo/grade@2x.png
  65. BIN
      pages/images/userInfo/grade@3x.png
  66. BIN
      pages/images/userInfo/headportrait.png
  67. BIN
      pages/images/userInfo/headportrait@2x.png
  68. BIN
      pages/images/userInfo/headportrait@3x.png
  69. BIN
      pages/images/userInfo/location.png
  70. BIN
      pages/images/userInfo/location@2x.png
  71. BIN
      pages/images/userInfo/location@3x.png
  72. BIN
      pages/images/userInfo/logoutbg.png
  73. BIN
      pages/images/userInfo/logoutbg1.png
  74. BIN
      pages/images/userInfo/logoutbg1@3x.png
  75. BIN
      pages/images/userInfo/logoutbg@2x.png
  76. BIN
      pages/images/userInfo/nickname.png
  77. BIN
      pages/images/userInfo/nickname@2x.png
  78. BIN
      pages/images/userInfo/nickname@3x.png
  79. BIN
      pages/images/userInfo/school.png
  80. BIN
      pages/images/userInfo/school@2x.png
  81. BIN
      pages/images/userInfo/school@3x.png
  82. 5 1
      pages/services/api.js
  83. 10 10
      pages/services/user.js
  84. 2 2
      pages/userCenter.js
  85. 108 0
      pages/utils/ModalUtil.js

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 128 - 2
android/app/src/main/assets/index.android.bundle


+ 5 - 2
android/app/src/main/java/com/edufound/CustomPackage.java

@@ -1,6 +1,7 @@
 package com.edufound;
 
-import com.edufound.mobile.Util.AndroidUtil;
+import com.edufound.mobile.util.AndroidUtil;
+import com.edufound.mobile.view.modal.PopModalManager;
 import com.facebook.react.ReactPackage;
 import com.facebook.react.bridge.NativeModule;
 import com.facebook.react.uimanager.ViewManager;
@@ -23,7 +24,9 @@ public class CustomPackage implements ReactPackage {
     @Nonnull
     @Override
     public List<ViewManager> createViewManagers(@Nonnull ReactApplicationContext reactContext) {
-        return Collections.emptyList();
+        List<ViewManager> views = new ArrayList<>();
+        views.add(new PopModalManager());
+        return views;
     }
 
 

+ 1 - 3
android/app/src/main/java/com/edufound/mobile/activity/WebActivity.java

@@ -19,10 +19,8 @@ import android.webkit.WebViewClient;
 import android.widget.ProgressBar;
 
 import com.edufound.mobile.R;
-import com.edufound.mobile.Util.AndroidUtil;
+import com.edufound.mobile.util.AndroidUtil;
 import com.facebook.react.ReactActivity;
-import com.facebook.react.bridge.ReactApplicationContext;
-import com.facebook.react.bridge.ReactContext;
 
 import java.util.HashMap;
 import java.util.Map;

+ 1 - 1
android/app/src/main/java/com/edufound/mobile/Util/AndroidUtil.java

@@ -1,4 +1,4 @@
-package com.edufound.mobile.Util;
+package com.edufound.mobile.util;
 
 import android.content.Intent;
 import android.support.annotation.Nullable;

+ 88 - 0
android/app/src/main/java/com/edufound/mobile/util/PermissionConstants.java

@@ -0,0 +1,88 @@
+package com.edufound.mobile.util;
+
+/**
+ * Created by wuyunqiang on 2018/2/7.
+ */
+
+
+        import android.Manifest;
+        import android.Manifest.permission;
+        import android.annotation.SuppressLint;
+        import android.support.annotation.StringDef;
+
+        import java.lang.annotation.Retention;
+        import java.lang.annotation.RetentionPolicy;
+
+@SuppressLint("InlinedApi")
+public final class PermissionConstants {
+
+    public static final String CALENDAR   = Manifest.permission_group.CALENDAR;
+    public static final String CAMERA     = Manifest.permission_group.CAMERA;
+    public static final String CONTACTS   = Manifest.permission_group.CONTACTS;
+    public static final String LOCATION   = Manifest.permission_group.LOCATION;
+    public static final String MICROPHONE = Manifest.permission_group.MICROPHONE;
+    public static final String PHONE      = Manifest.permission_group.PHONE;
+    public static final String SENSORS    = Manifest.permission_group.SENSORS;
+    public static final String SMS        = Manifest.permission_group.SMS;
+    public static final String STORAGE    = Manifest.permission_group.STORAGE;
+
+    private static final String[] GROUP_CALENDAR   = {
+            permission.READ_CALENDAR, permission.WRITE_CALENDAR
+    };
+    private static final String[] GROUP_CAMERA     = {
+            permission.CAMERA
+    };
+    private static final String[] GROUP_CONTACTS   = {
+            permission.READ_CONTACTS, permission.WRITE_CONTACTS, permission.GET_ACCOUNTS
+    };
+    private static final String[] GROUP_LOCATION   = {
+            permission.ACCESS_FINE_LOCATION, permission.ACCESS_COARSE_LOCATION
+    };
+    private static final String[] GROUP_MICROPHONE = {
+            permission.RECORD_AUDIO
+    };
+    private static final String[] GROUP_PHONE      = {
+            permission.READ_PHONE_STATE, permission.CALL_PHONE, permission.READ_CALL_LOG, permission.WRITE_CALL_LOG,
+            permission.ADD_VOICEMAIL, permission.USE_SIP, permission.PROCESS_OUTGOING_CALLS
+    };
+    private static final String[] GROUP_SENSORS    = {
+            permission.BODY_SENSORS
+    };
+    private static final String[] GROUP_SMS        = {
+            permission.SEND_SMS, permission.RECEIVE_SMS, permission.READ_SMS,
+            permission.RECEIVE_WAP_PUSH, permission.RECEIVE_MMS,
+    };
+    private static final String[] GROUP_STORAGE    = {
+            permission.READ_EXTERNAL_STORAGE, permission.WRITE_EXTERNAL_STORAGE
+    };
+
+    @StringDef({CALENDAR, CAMERA, CONTACTS, LOCATION, MICROPHONE, PHONE, SENSORS, SMS, STORAGE,})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Permission {
+    }
+
+    public static String[] getPermissions(@Permission final String permission) {
+        switch (permission) {
+            case CALENDAR:
+                return GROUP_CALENDAR;
+            case CAMERA:
+                return GROUP_CAMERA;
+            case CONTACTS:
+                return GROUP_CONTACTS;
+            case LOCATION:
+                return GROUP_LOCATION;
+            case MICROPHONE:
+                return GROUP_MICROPHONE;
+            case PHONE:
+                return GROUP_PHONE;
+            case SENSORS:
+                return GROUP_SENSORS;
+            case SMS:
+                return GROUP_SMS;
+            case STORAGE:
+                return GROUP_STORAGE;
+        }
+        return new String[]{permission};
+    }
+}
+

+ 335 - 0
android/app/src/main/java/com/edufound/mobile/util/PermissionUtils.java

@@ -0,0 +1,335 @@
+/**
+ * Created by wuyunqiang on 2018/2/7.
+ */
+
+package com.edufound.mobile.util;
+        import android.app.Activity;
+        import android.content.Context;
+        import android.content.Intent;
+        import android.content.pm.PackageManager;
+        import android.net.Uri;
+        import android.os.Build;
+        import android.os.Bundle;
+        import android.support.annotation.NonNull;
+        import android.support.annotation.Nullable;
+        import android.support.annotation.RequiresApi;
+        import android.support.v4.content.ContextCompat;
+
+        import java.util.ArrayList;
+        import java.util.Arrays;
+        import java.util.Collections;
+        import java.util.LinkedHashSet;
+        import java.util.List;
+        import java.util.Set;
+
+/**
+ * <pre>
+ *     author: Blankj
+ *     blog  : http://blankj.com
+ *     time  : 2017/12/29
+ *     desc  : 权限相关工具类
+ * </pre>
+ */
+public final class PermissionUtils {
+
+    private static final List<String> PERMISSIONS = getPermissions();
+
+    private static PermissionUtils sInstance;
+
+    private OnRationaleListener mOnRationaleListener;
+    private SimpleCallback      mSimpleCallback;
+    private FullCallback        mFullCallback;
+    private ThemeCallback       mThemeCallback;
+    private Set<String>         mPermissions;
+    private List<String>        mPermissionsRequest;
+    private List<String>        mPermissionsGranted;
+    private List<String>        mPermissionsDenied;
+    private List<String>        mPermissionsDeniedForever;
+
+    /**
+     * 获取应用权限
+     *
+     * @return 清单文件中的权限列表
+     */
+    public static List<String> getPermissions() {
+        return getPermissions(Utils.getApp().getPackageName());
+    }
+
+    /**
+     * 获取应用权限
+     *
+     * @param packageName 包名
+     * @return 清单文件中的权限列表
+     */
+    public static List<String> getPermissions(final String packageName) {
+        PackageManager pm = Utils.getApp().getPackageManager();
+        try {
+            return Arrays.asList(
+                    pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS)
+                            .requestedPermissions
+            );
+        } catch (PackageManager.NameNotFoundException e) {
+            e.printStackTrace();
+            return Collections.emptyList();
+        }
+    }
+
+    /**
+     * 判断权限是否被授予
+     *
+     * @param permissions 权限
+     * @return {@code true}: 是<br>{@code false}: 否
+     */
+    public static boolean isGranted(final String... permissions) {
+        for (String permission : permissions) {
+            if (!isGranted(permission)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static boolean isGranted(final String permission) {
+        return Build.VERSION.SDK_INT < Build.VERSION_CODES.M
+                || PackageManager.PERMISSION_GRANTED
+                == ContextCompat.checkSelfPermission(Utils.getApp(), permission);
+    }
+
+    /**
+     * 打开应用具体设置
+     */
+    public static void openAppSettings() {
+        Intent intent = new Intent("android.settings.APPLICATION_DETAILS_SETTINGS");
+        intent.setData(Uri.parse("package:" + Utils.getApp().getPackageName()));
+        Utils.getApp().startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+    }
+
+    /**
+     * 设置请求权限
+     *
+     * @param permissions 要请求的权限
+     * @return {@link PermissionUtils}
+     */
+    public static PermissionUtils permission(@PermissionConstants.Permission final String... permissions) {
+        return new PermissionUtils(permissions);
+    }
+
+    private PermissionUtils(final String... permissions) {
+        mPermissions = new LinkedHashSet<>();
+        for (String permission : permissions) {
+            for (String aPermission : PermissionConstants.getPermissions(permission)) {
+                if (PERMISSIONS.contains(aPermission)) {
+                    mPermissions.add(aPermission);
+                }
+            }
+        }
+        sInstance = this;
+    }
+
+    /**
+     * 设置拒绝权限后再次请求的回调接口
+     *
+     * @param listener 拒绝权限后再次请求的回调接口
+     * @return {@link PermissionUtils}
+     */
+    public PermissionUtils rationale(final OnRationaleListener listener) {
+        mOnRationaleListener = listener;
+        return this;
+    }
+
+    /**
+     * 设置回调
+     *
+     * @param callback 简单回调接口
+     * @return {@link PermissionUtils}
+     */
+    public PermissionUtils callback(final SimpleCallback callback) {
+        mSimpleCallback = callback;
+        return this;
+    }
+
+    /**
+     * 设置回调
+     *
+     * @param callback 完整回调接口
+     * @return {@link PermissionUtils}
+     */
+    public PermissionUtils callback(final FullCallback callback) {
+        mFullCallback = callback;
+        return this;
+    }
+
+    /**
+     * 设置主题
+     *
+     * @param callback 主题回调接口
+     * @return {@link PermissionUtils}
+     */
+    public PermissionUtils theme(final ThemeCallback callback) {
+        mThemeCallback = callback;
+        return this;
+    }
+
+    /**
+     * 开始请求
+     */
+    public void request() {
+        mPermissionsGranted = new ArrayList<>();
+        mPermissionsRequest = new ArrayList<>();
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
+            mPermissionsGranted.addAll(mPermissions);
+            requestCallback();
+        } else {
+            for (String permission : mPermissions) {
+                if (isGranted(permission)) {
+                    mPermissionsGranted.add(permission);
+                } else {
+                    mPermissionsRequest.add(permission);
+                }
+            }
+            if (mPermissionsRequest.isEmpty()) {
+                requestCallback();
+            } else {
+                startPermissionActivity();
+            }
+        }
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.M)
+    private void startPermissionActivity() {
+        mPermissionsDenied = new ArrayList<>();
+        mPermissionsDeniedForever = new ArrayList<>();
+        PermissionActivity.start(Utils.getApp());
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.M)
+    private boolean rationale(final Activity activity) {
+        boolean isRationale = false;
+        if (mOnRationaleListener != null) {
+            for (String permission : mPermissionsRequest) {
+                if (activity.shouldShowRequestPermissionRationale(permission)) {
+                    getPermissionsStatus(activity);
+                    mOnRationaleListener.rationale(new OnRationaleListener.ShouldRequest() {
+                        @Override
+                        public void again(boolean again) {
+                            if (again) {
+                                startPermissionActivity();
+                            } else {
+                                requestCallback();
+                            }
+                        }
+                    });
+                    isRationale = true;
+                    break;
+                }
+            }
+            mOnRationaleListener = null;
+        }
+        return isRationale;
+    }
+
+    private void getPermissionsStatus(final Activity activity) {
+        for (String permission : mPermissionsRequest) {
+            if (isGranted(permission)) {
+                mPermissionsGranted.add(permission);
+            } else {
+                mPermissionsDenied.add(permission);
+                if (!activity.shouldShowRequestPermissionRationale(permission)) {
+                    mPermissionsDeniedForever.add(permission);
+                }
+            }
+        }
+    }
+
+    private void requestCallback() {
+        if (mSimpleCallback != null) {
+            if (mPermissionsRequest.size() == 0
+                    || mPermissions.size() == mPermissionsGranted.size()) {
+                mSimpleCallback.onGranted();
+            } else {
+                if (!mPermissionsDenied.isEmpty()) {
+                    mSimpleCallback.onDenied();
+                }
+            }
+            mSimpleCallback = null;
+        }
+        if (mFullCallback != null) {
+            if (mPermissionsRequest.size() == 0
+                    || mPermissions.size() == mPermissionsGranted.size()) {
+                mFullCallback.onGranted(mPermissionsGranted);
+            } else {
+                if (!mPermissionsDenied.isEmpty()) {
+                    mFullCallback.onDenied(mPermissionsDeniedForever, mPermissionsDenied);
+                }
+            }
+            mFullCallback = null;
+        }
+        mOnRationaleListener = null;
+        mThemeCallback = null;
+    }
+
+    private void onRequestPermissionsResult(final Activity activity) {
+        getPermissionsStatus(activity);
+        requestCallback();
+    }
+
+    @RequiresApi(api = Build.VERSION_CODES.M)
+    public static class PermissionActivity extends Activity {
+
+        public static void start(final Context context) {
+            Intent starter = new Intent(context, PermissionActivity.class);
+            starter.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            context.startActivity(starter);
+        }
+
+        @Override
+        protected void onCreate(@Nullable Bundle savedInstanceState) {
+            if (sInstance.mThemeCallback != null) {
+                sInstance.mThemeCallback.onActivityCreate(this);
+            }
+            super.onCreate(savedInstanceState);
+
+            if (sInstance.rationale(this)) {
+                finish();
+                return;
+            }
+            if (sInstance.mPermissionsRequest != null) {
+                int size = sInstance.mPermissionsRequest.size();
+                requestPermissions(sInstance.mPermissionsRequest.toArray(new String[size]), 1);
+            }
+        }
+
+        @Override
+        public void onRequestPermissionsResult(int requestCode,
+                                               @NonNull String[] permissions,
+                                               @NonNull int[] grantResults) {
+            sInstance.onRequestPermissionsResult(this);
+            finish();
+        }
+    }
+
+    public interface OnRationaleListener {
+
+        void rationale(ShouldRequest shouldRequest);
+
+        interface ShouldRequest {
+            void again(boolean again);
+        }
+    }
+
+    public interface SimpleCallback {
+        void onGranted();
+
+        void onDenied();
+    }
+
+    public interface FullCallback {
+        void onGranted(List<String> permissionsGranted);
+
+        void onDenied(List<String> permissionsDeniedForever, List<String> permissionsDenied);
+    }
+
+    public interface ThemeCallback {
+        void onActivityCreate(Activity activity);
+    }
+}

+ 124 - 0
android/app/src/main/java/com/edufound/mobile/util/Utils.java

@@ -0,0 +1,124 @@
+package com.edufound.mobile.util;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.app.Application;
+import android.app.Application.ActivityLifecycleCallbacks;
+import android.content.Context;
+import android.graphics.Point;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.view.WindowManager;
+
+import java.lang.ref.WeakReference;
+import java.util.LinkedList;
+import java.util.List;
+
+
+public final class Utils {
+
+    @SuppressLint("StaticFieldLeak")
+    private static Application sApplication;
+
+    static WeakReference<Activity> sTopActivityWeakRef;
+    static List<Activity> sActivityList = new LinkedList<>();
+
+    private static ActivityLifecycleCallbacks mCallbacks = new ActivityLifecycleCallbacks() {
+        @Override
+        public void onActivityCreated(Activity activity, Bundle bundle) {
+            sActivityList.add(activity);
+            setTopActivityWeakRef(activity);
+        }
+
+        @Override
+        public void onActivityStarted(Activity activity) {
+            setTopActivityWeakRef(activity);
+        }
+
+        @Override
+        public void onActivityResumed(Activity activity) {
+            setTopActivityWeakRef(activity);
+        }
+
+        @Override
+        public void onActivityPaused(Activity activity) {
+
+        }
+
+        @Override
+        public void onActivityStopped(Activity activity) {
+
+        }
+
+        @Override
+        public void onActivitySaveInstanceState(Activity activity, Bundle bundle) {
+
+        }
+
+        @Override
+        public void onActivityDestroyed(Activity activity) {
+            sActivityList.remove(activity);
+        }
+    };
+
+    private Utils() {
+        throw new UnsupportedOperationException("u can't instantiate me...");
+    }
+
+    /**
+     * 初始化工具类
+     *
+     * @param app 应用
+     */
+    public static void init(@NonNull final Application app) {
+        Utils.sApplication = app;
+        app.registerActivityLifecycleCallbacks(mCallbacks);
+    }
+
+    /**
+     * 获取 Application
+     *
+     * @return Application
+     */
+    public static Application getApp() {
+        if (sApplication != null) return sApplication;
+        throw new NullPointerException("u should init first");
+    }
+
+    private static void setTopActivityWeakRef(final Activity activity) {
+        if (activity.getClass() == PermissionUtils.PermissionActivity.class) return;
+        if (sTopActivityWeakRef == null || !activity.equals(sTopActivityWeakRef.get())) {
+            sTopActivityWeakRef = new WeakReference<>(activity);
+        }
+    }
+
+    public static int getScreenWidth() {
+        WindowManager wm = (WindowManager) Utils.getApp().getSystemService(Context.WINDOW_SERVICE);
+        if (wm == null) {
+            return Utils.getApp().getResources().getDisplayMetrics().widthPixels;
+        }
+        Point point = new Point();
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+            wm.getDefaultDisplay().getRealSize(point);
+        } else {
+            wm.getDefaultDisplay().getSize(point);
+        }
+        return point.x;
+    }
+
+    public static int getScreenHeight() {
+        WindowManager wm = (WindowManager) Utils.getApp().getSystemService(Context.WINDOW_SERVICE);
+        if (wm == null) {
+            return Utils.getApp().getResources().getDisplayMetrics().heightPixels;
+        }
+        Point point = new Point();
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+            wm.getDefaultDisplay().getRealSize(point);
+        } else {
+            wm.getDefaultDisplay().getSize(point);
+        }
+        return point.y;
+    }
+}
+

+ 24 - 0
android/app/src/main/java/com/edufound/mobile/view/modal/BUCK

@@ -0,0 +1,24 @@
+load("//tools/build_defs/oss:rn_defs.bzl", "YOGA_TARGET", "react_native_dep", "react_native_target", "rn_android_library")
+
+rn_android_library(
+    name = "modal",
+    srcs = glob(["*.java"]),
+    required_for_source_only_abi = True,
+    visibility = [
+        "PUBLIC",
+    ],
+    deps = [
+        YOGA_TARGET,
+        react_native_dep("third-party/java/infer-annotations:infer-annotations"),
+        react_native_dep("third-party/java/jsr-305:jsr-305"),
+        react_native_target("java/com/facebook/react/bridge:bridge"),
+        react_native_target("java/com/facebook/react/common:common"),
+        react_native_target("java/com/facebook/react/module/annotations:annotations"),
+        react_native_target("java/com/facebook/react/touch:touch"),
+        react_native_target("java/com/facebook/react/uimanager:uimanager"),
+        react_native_target("java/com/facebook/react/uimanager/annotations:annotations"),
+        react_native_target("java/com/facebook/react/views/common:common"),
+        react_native_target("java/com/facebook/react/views/view:view"),
+        react_native_target("res:modal"),
+    ],
+)

+ 65 - 0
android/app/src/main/java/com/edufound/mobile/view/modal/ModalHostHelper.java

@@ -0,0 +1,65 @@
+// Copyright 2004-present Facebook. All Rights Reserved.
+
+package com.edufound.mobile.view.modal;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Point;
+import android.view.Display;
+import android.view.WindowManager;
+
+import com.facebook.infer.annotation.Assertions;
+
+/**
+ * Helper class for Modals.
+ */
+/*package*/ class ModalHostHelper {
+
+  private static final Point MIN_POINT = new Point();
+  private static final Point MAX_POINT = new Point();
+  private static final Point SIZE_POINT = new Point();
+
+  /**
+   * To get the size of the screen, we use information from the WindowManager and
+   * default Display. We don't use DisplayMetricsHolder, or Display#getSize() because
+   * they return values that include the status bar. We only want the values of what
+   * will actually be shown on screen.
+   * We use Display#getSize() to determine if the screen is in portrait or landscape.
+   * We don't use getRotation because the 'natural' rotation will be portrait on phones
+   * and landscape on tablets.
+   * This should only be called on the native modules/shadow nodes thread.
+   */
+  @TargetApi(16)
+  public static Point getModalHostSize(Context context) {
+    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+    Display display = Assertions.assertNotNull(wm).getDefaultDisplay();
+    // getCurrentSizeRange will return the min and max width and height that the window can be
+    display.getCurrentSizeRange(MIN_POINT, MAX_POINT);
+    // getSize will return the dimensions of the screen in its current orientation
+    display.getSize(SIZE_POINT);
+
+    int[] attrs = {android.R.attr.windowFullscreen};
+    Resources.Theme theme = context.getTheme();
+    TypedArray ta = theme.obtainStyledAttributes(attrs);
+    boolean windowFullscreen = ta.getBoolean(0, false);
+
+    // We need to add the status bar height to the height if we have a fullscreen window,
+    // because Display.getCurrentSizeRange doesn't include it.
+    Resources resources = context.getResources();
+    int statusBarId = resources.getIdentifier("status_bar_height", "dimen", "android");
+    int statusBarHeight = 0;
+    if (windowFullscreen && statusBarId > 0) {
+        statusBarHeight = (int) resources.getDimension(statusBarId);
+    }
+
+    if (SIZE_POINT.x < SIZE_POINT.y) {
+      // If we are vertical the width value comes from min width and height comes from max height
+      return new Point(MIN_POINT.x, MAX_POINT.y + statusBarHeight);
+    } else {
+      // If we are horizontal the width value comes from max width and height comes from min height
+      return new Point(MAX_POINT.x, MIN_POINT.y + statusBarHeight);
+    }
+  }
+}

+ 38 - 0
android/app/src/main/java/com/edufound/mobile/view/modal/ModalHostShadowNode.java

@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2015-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+package com.edufound.mobile.view.modal;
+
+import android.graphics.Point;
+
+import com.facebook.react.uimanager.LayoutShadowNode;
+import com.facebook.react.uimanager.ReactShadowNodeImpl;
+
+/**
+ * We implement the Modal by using an Android Dialog. That will fill the entire window of the
+ * application.  To get layout to work properly, we need to layout all the elements within the
+ * Modal's inner content view as if they can fill the entire window.  To do that, we need to
+ * explicitly set the styleWidth and styleHeight on the LayoutShadowNode of the child of this node
+ * to be the window size.  This will then cause the children of the Modal to layout as if they can
+ * fill the window.
+ */
+public class ModalHostShadowNode extends LayoutShadowNode {
+
+  /**
+   * We need to set the styleWidth and styleHeight of the one child (represented by the <View/>
+   * within the <RCTModalHostView/> in Modal.js. This needs to fill the entire window.
+   */
+  @Override
+  public void addChildAt(ReactShadowNodeImpl child, int i) {
+    super.addChildAt(child, i);
+    Point modalSize = ModalHostHelper.getModalHostSize(getThemedContext());
+    child.setStyleWidth(modalSize.x);
+    child.setStyleHeight(modalSize.y);
+  }
+}

+ 327 - 0
android/app/src/main/java/com/edufound/mobile/view/modal/PopModal.java

@@ -0,0 +1,327 @@
+package com.edufound.mobile.view.modal;
+
+import android.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Build;
+import android.support.annotation.RequiresApi;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.PopupWindow;
+
+import com.edufound.mobile.util.Utils;
+import com.facebook.react.bridge.GuardedRunnable;
+import com.facebook.react.bridge.LifecycleEventListener;
+import com.facebook.react.bridge.ReactContext;
+import com.facebook.react.common.annotations.VisibleForTesting;
+import com.facebook.react.uimanager.JSTouchDispatcher;
+import com.facebook.react.uimanager.RootView;
+import com.facebook.react.uimanager.UIManagerModule;
+import com.facebook.react.uimanager.events.EventDispatcher;
+import com.facebook.react.views.view.ReactViewGroup;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+
+import javax.annotation.Nullable;
+
+/**
+ * Created by wuyunqiang on 2018/2/9.
+ */
+
+public class PopModal extends ViewGroup implements LifecycleEventListener {
+
+
+    static final String TAG = "PopModal";
+    private DialogRootViewGroup mHostView;
+    private @Nullable PopupWindow popupWindow;
+    public static Context mContext;
+    // Set this flag to true if changing a particular property on the view requires a new Dialog to
+    // be created.  For instance, animation does since it affects Dialog creation through the theme
+    // but transparency does not since we can access the window to update the property.
+
+    public PopModal(Context context) {
+        super(context);
+        ((ReactContext) context).addLifecycleEventListener(this);
+        mContext = context;
+        mHostView = new DialogRootViewGroup(context);
+        Log.i(TAG,"PopModal");
+    }
+
+    public static Context getReactContext(){
+        return mContext;
+    }
+
+    public boolean isShow(){
+        if(popupWindow!=null){
+            return popupWindow.isShowing();
+        }
+        return false;
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        Log.i(TAG,"onLayout");
+        // Do nothing as we are laid out by UIManager
+    }
+
+    @Override
+    public void addView(View child, int index) {
+        mHostView.addView(child, index);
+        Log.i(TAG,"addView");
+    }
+
+    @Override
+    public int getChildCount() {
+        Log.i(TAG,"getChildCount");
+        return mHostView.getChildCount();
+    }
+
+    @Override
+    public View getChildAt(int index) {
+        Log.i(TAG,"getChildAt");
+        return mHostView.getChildAt(index);
+    }
+
+    @Override
+    public void removeView(View child) {
+        Log.i(TAG,"removeView");
+        mHostView.removeView(child);
+    }
+
+    @Override
+    public void removeViewAt(int index) {
+        View child = getChildAt(index);
+        mHostView.removeView(child);
+        Log.i(TAG,"removeViewAt");
+    }
+
+    @Override
+    public void addChildrenForAccessibility(ArrayList<View> outChildren) {
+        // Explicitly override this to prevent accessibility events being passed down to children
+        // Those will be handled by the mHostView which lives in the dialog
+        Log.i(TAG,"addChildrenForAccessibility");
+    }
+
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        // Explicitly override this to prevent accessibility events being passed down to children
+        // Those will be handled by the mHostView which lives in the dialog
+        Log.i(TAG,"dispatchPopulateAccessibilityEvent");
+        return false;
+    }
+
+    public void onDropInstance() {
+        ((ReactContext) getReactContext()).removeLifecycleEventListener(this);
+        dismiss();
+        Log.i(TAG,"onDropInstance");
+//        mContext = null;
+    }
+
+    public void dismiss() {
+        Log.i(TAG,"dismiss");
+        if (popupWindow != null) {
+            if (popupWindow.isShowing()) {
+                popupWindow.dismiss();
+            }
+            popupWindow = null;
+
+            // We need to remove the mHostView from the parent
+            // It is possible we are dismissing this dialog and reattaching the hostView to another
+            ViewGroup parent = (ViewGroup) mHostView.getParent();
+            parent.removeViewAt(0);
+        }
+    }
+
+    @Override
+    public void onHostResume() {
+        Log.i(TAG,"onHostResume");
+        // We show the dialog again when the host resumes
+//        showOrUpdate();
+    }
+
+    @Override
+    public void onHostPause() {
+        // We dismiss the dialog and reconstitute it onHostResume
+        dismiss();
+        Log.i(TAG,"onHostPause");
+    }
+
+    @Override
+    public void onHostDestroy() {
+        // Drop the instance if the host is destroyed which will dismiss the dialog
+        onDropInstance();
+        Log.i(TAG,"onHostDestroy");
+    }
+
+    @VisibleForTesting
+    public @Nullable PopupWindow getDialog() {
+        Log.i(TAG,"getDialog");
+        return popupWindow;
+    }
+
+    /**
+     * showOrUpdate will display the Dialog.  It is called by the manager once all properties are set
+     * because we need to know all of them before creating the Dialog.  It is also smart during
+     * updates if the changed properties can be applied directly to the Dialog or require the
+     * recreation of a new Dialog.
+     */
+    public void showOrUpdate() {
+        Log.i(TAG,"showOrUpdate");
+        // If the existing Dialog is currently up, we may need to redraw it or we may be able to update
+        // the property without having to recreate the dialog
+        if (popupWindow != null) {
+            fitPopupWindowOverStatusBar(popupWindow,true);
+            popupWindow.showAtLocation(mHostView,Gravity.BOTTOM,0,0);
+            return;
+        }
+
+        Activity currentActivity = getCurrentActivity();
+//        Context context = currentActivity == null ? getReactContext() : currentActivity;
+        Utils.init(getCurrentActivity().getApplication());
+        popupWindow = new PopupWindow(getCurrentActivity());
+        popupWindow.setWidth(LinearLayout.LayoutParams.MATCH_PARENT);
+        popupWindow.setHeight(LinearLayout.LayoutParams.MATCH_PARENT);
+        View v = getContentView();
+        popupWindow.setContentView(v);
+        popupWindow.setWidth(Utils.getScreenWidth());
+        popupWindow.setTouchable(true);// true popwindow优先一切(系统级以外)处理touch  false:popwindow 只是一个view 不影响界面操作
+        popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));//不设置 不是全屏 周围会有空白部分
+        popupWindow.setOutsideTouchable(true);
+        fitPopupWindowOverStatusBar(popupWindow,true);
+        if (currentActivity != null || !currentActivity.isFinishing()) {
+            popupWindow.showAtLocation(mHostView,Gravity.BOTTOM,0,0);
+        }
+    }
+
+    private @Nullable Activity getCurrentActivity() {
+        Log.i(TAG,"getCurrentActivity");
+        return ((ReactContext) getReactContext()).getCurrentActivity();
+    }
+
+    /**
+     * Returns the view that will be the root view of the dialog. We are wrapping this in a
+     * FrameLayout because this is the system's way of notifying us that the dialog size has changed.
+     * This has the pleasant side-effect of us not having to preface all Modals with
+     * "top: statusBarHeight", since that margin will be included in the FrameLayout.
+     */
+    private View getContentView() {
+        Log.i(TAG,"getContentView");
+        FrameLayout frameLayout = new FrameLayout(getReactContext());
+        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
+        frameLayout.setLayoutParams(params);
+        frameLayout.addView(mHostView);
+        frameLayout.setFocusable(true);
+        frameLayout.setFocusableInTouchMode(true);
+        frameLayout.setPadding(0,0,0,0);
+        frameLayout.setFitsSystemWindows(true);
+        return frameLayout;
+    }
+
+    //适配全屏
+    public void fitPopupWindowOverStatusBar(PopupWindow popupWindow,boolean needFullScreen) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+            try {
+                Field mLayoutInScreen = PopupWindow.class.getDeclaredField("mLayoutInScreen");
+                mLayoutInScreen.setAccessible(true);
+                mLayoutInScreen.set(popupWindow, needFullScreen);
+            } catch (NoSuchFieldException e) {
+                e.printStackTrace();
+            } catch (IllegalAccessException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * DialogRootViewGroup is the ViewGroup which contains all the children of a Modal.  It gets all
+     * child information forwarded from PopModal and uses that to create children.  It is
+     * also responsible for acting as a RootView and handling touch events.  It does this the same
+     * way as ReactRootView.
+     *
+     * To get layout to work properly, we need to layout all the elements within the Modal as if they
+     * can fill the entire window.  To do that, we need to explicitly set the styleWidth and
+     * styleHeight on the LayoutShadowNode to be the window size. This is done through the
+     * UIManagerModule, and will then cause the children to layout as if they can fill the window.
+     */
+    static class DialogRootViewGroup extends ReactViewGroup implements RootView {
+
+        private final JSTouchDispatcher mJSTouchDispatcher = new JSTouchDispatcher(this);
+
+        public DialogRootViewGroup(Context context) {
+            super(context);
+        }
+
+        @Override
+        protected void onSizeChanged(final int w, final int h, int oldw, int oldh) {
+            super.onSizeChanged(w, h, oldw, oldh);
+            Log.i(TAG,"onSizeChanged w:"+w+" h:"+h+" oldw:"+oldw + " oldh:"+oldh);
+            if (getChildCount() > 0) {
+                final int viewTag = getChildAt(0).getId();
+                ReactContext reactContext = (ReactContext) getReactContext();
+                reactContext.runOnNativeModulesQueueThread(
+                        new GuardedRunnable(reactContext) {
+                            @Override
+                            public void runGuarded() {
+                                ((ReactContext) getReactContext()).getNativeModule(UIManagerModule.class)
+                                        .updateNodeSize(viewTag, w, h);
+                            }
+                        });
+            }
+        }
+
+        @Override
+        public boolean onInterceptTouchEvent(MotionEvent event) {
+            Log.i(TAG,"onInterceptTouchEvent");
+            mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher());
+            return super.onInterceptTouchEvent(event);
+        }
+
+        @Override
+        public boolean onTouchEvent(MotionEvent event) {
+            Log.i(TAG,"onTouchEvent");
+            mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher());
+            super.onTouchEvent(event);
+            // In case when there is no children interested in handling touch event, we return true from
+            // the root view in order to receive subsequent events related to that gesture
+            return true;
+        }
+
+        @Override
+        public void onChildStartedNativeGesture(MotionEvent androidEvent) {
+            Log.i(TAG,"onChildStartedNativeGesture");
+            mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, getEventDispatcher());
+        }
+
+        @Override
+        public void handleException(Throwable t) {
+
+        }
+
+        @Override
+        public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+            Log.i(TAG,"requestDisallowInterceptTouchEvent");
+            // No-op - override in order to still receive events to onInterceptTouchEvent
+            // even when some other view disallow that
+        }
+
+        private EventDispatcher getEventDispatcher() {
+            Log.i(TAG,"getEventDispatcher");
+            ReactContext reactContext = (ReactContext) getReactContext();
+            return reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
+        }
+    }
+}

+ 147 - 0
android/app/src/main/java/com/edufound/mobile/view/modal/PopModalManager.java

@@ -0,0 +1,147 @@
+package com.edufound.mobile.view.modal;
+
+import android.app.Activity;
+import android.util.Log;
+import android.view.ViewGroup;
+import com.facebook.common.activitylistener.ActivityListener;
+import com.facebook.react.bridge.ActivityEventListener;
+import com.facebook.react.bridge.ReadableArray;
+import com.facebook.react.common.MapBuilder;
+import com.facebook.react.uimanager.LayoutShadowNode;
+import com.facebook.react.uimanager.ThemedReactContext;
+import com.facebook.react.uimanager.UIManagerModule;
+import com.facebook.react.uimanager.ViewGroupManager;
+import com.facebook.react.uimanager.annotations.ReactProp;
+import com.facebook.react.uimanager.annotations.ReactPropGroup;
+import com.facebook.react.uimanager.events.EventDispatcher;
+import java.util.Map;
+import javax.annotation.Nullable;
+
+/**
+ * Created by wuyunqiang on 2018/1/16.
+ */
+
+public class PopModalManager extends ViewGroupManager<PopModal> implements ActivityListener{
+
+    static final String TAG = "ModalAndroid";
+    static final int show = 1;
+    static final int close = 2;
+
+    @Override
+    public String getName() {
+        return "ModalAndroid";
+    }
+
+    @Override
+    protected PopModal createViewInstance(ThemedReactContext reactContext) {
+       final PopModal popModal = new PopModal(reactContext);
+       return popModal;
+    }
+
+    @Override
+    public LayoutShadowNode createShadowNodeInstance() {
+        return new ModalHostShadowNode();
+    }
+
+    @Override
+    public Class<? extends LayoutShadowNode> getShadowNodeClass() {
+        return ModalHostShadowNode.class;
+    }
+
+    @ReactProp(name = "visible")
+    public void setVisible(PopModal view, ReadableArray array) {
+        boolean visible = array.getBoolean(0);
+        boolean update = array.getBoolean(1);//目的是强制更新
+        if(visible){
+           view.showOrUpdate();
+//           if(!view.isShow()){
+//               view.showOrUpdate();
+//           }
+       }else{
+           view.dismiss();
+//           if(view.isShow()){
+//               view.dismiss();
+//           }
+       }
+    }
+
+    @Override
+    public void onActivityCreate(Activity activity) {
+
+    }
+
+    @Override
+    public void onStart(Activity activity) {
+
+    }
+
+    @Override
+    public void onResume(Activity activity) {
+
+    }
+
+    @Override
+    public void onPause(Activity activity) {
+
+    }
+
+    @Override
+    public void onStop(Activity activity) {
+
+    }
+
+    @Override
+    public void onDestroy(Activity activity) {
+        PopModal.mContext = null;
+    }
+
+    @Override
+    public int getPriority() {
+        return 0;
+    }
+
+    @Override
+    public void onDropViewInstance(PopModal view) {
+        Log.i(TAG,"onDropViewInstance");
+        super.onDropViewInstance(view);
+        view.onDropInstance();
+    }
+
+    @Nullable
+    @Override
+    public Map<String, Integer> getCommandsMap() {
+        return MapBuilder.<String, Integer>builder()
+                .put("show", show)
+                .put("close",close)
+                .build();
+    }
+
+    @Override
+    public void receiveCommand(PopModal root, int commandId, @Nullable ReadableArray args) {
+        super.receiveCommand(root, commandId, args);
+        Log.i(TAG,args.getString(0));
+        String key = args.getString(0);
+        switch (commandId){
+            case show:
+                root.showOrUpdate();
+                break;
+            case close:
+                root.dismiss();
+                break;
+        }
+    }
+
+    @Override
+    protected void addEventEmitters(ThemedReactContext reactContext, PopModal view) {
+        super.addEventEmitters(reactContext, view);
+        final EventDispatcher dispatcher =
+                reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
+    }
+
+    @Override
+    protected void onAfterUpdateTransaction(PopModal view) {
+        super.onAfterUpdateTransaction(view);
+//        view.showOrUpdate();
+    }
+
+}

BIN
android/app/src/main/res/drawable-mdpi/pages_images_userinfo_arrow.png


BIN
android/app/src/main/res/drawable-mdpi/pages_images_userinfo_back_white.png


BIN
android/app/src/main/res/drawable-mdpi/pages_images_userinfo_birthday.png


BIN
android/app/src/main/res/drawable-mdpi/pages_images_userinfo_grade.png


BIN
android/app/src/main/res/drawable-mdpi/pages_images_userinfo_headportrait.png


BIN
android/app/src/main/res/drawable-mdpi/pages_images_userinfo_location.png


BIN
android/app/src/main/res/drawable-mdpi/pages_images_userinfo_logoutbg.png


BIN
android/app/src/main/res/drawable-mdpi/pages_images_userinfo_nickname.png


BIN
android/app/src/main/res/drawable-mdpi/pages_images_userinfo_school.png


BIN
android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_arrow.png


BIN
android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_back_white.png


BIN
android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_birthday.png


BIN
android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_grade.png


BIN
android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_headportrait.png


BIN
android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_location.png


BIN
android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_logoutbg.png


BIN
android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_nickname.png


BIN
android/app/src/main/res/drawable-xhdpi/pages_images_userinfo_school.png


BIN
android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_arrow.png


BIN
android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_back_white.png


BIN
android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_birthday.png


BIN
android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_grade.png


BIN
android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_headportrait.png


BIN
android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_location.png


BIN
android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_logoutbg1.png


BIN
android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_nickname.png


BIN
android/app/src/main/res/drawable-xxhdpi/pages_images_userinfo_school.png


+ 21 - 7
package-lock.json

@@ -2863,11 +2863,13 @@
         },
         "balanced-match": {
           "version": "1.0.0",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "brace-expansion": {
           "version": "1.1.11",
           "bundled": true,
+          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -2880,15 +2882,18 @@
         },
         "code-point-at": {
           "version": "1.1.0",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "concat-map": {
           "version": "0.0.1",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "console-control-strings": {
           "version": "1.1.0",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "core-util-is": {
           "version": "1.0.2",
@@ -2991,7 +2996,8 @@
         },
         "inherits": {
           "version": "2.0.3",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "ini": {
           "version": "1.3.5",
@@ -3001,6 +3007,7 @@
         "is-fullwidth-code-point": {
           "version": "1.0.0",
           "bundled": true,
+          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
@@ -3013,17 +3020,20 @@
         "minimatch": {
           "version": "3.0.4",
           "bundled": true,
+          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
         },
         "minimist": {
           "version": "0.0.8",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "minipass": {
           "version": "2.3.5",
           "bundled": true,
+          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.2",
             "yallist": "^3.0.0"
@@ -3040,6 +3050,7 @@
         "mkdirp": {
           "version": "0.5.1",
           "bundled": true,
+          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
@@ -3112,7 +3123,8 @@
         },
         "number-is-nan": {
           "version": "1.0.1",
-          "bundled": true
+          "bundled": true,
+          "optional": true
         },
         "object-assign": {
           "version": "4.1.1",
@@ -3122,6 +3134,7 @@
         "once": {
           "version": "1.4.0",
           "bundled": true,
+          "optional": true,
           "requires": {
             "wrappy": "1"
           }
@@ -3227,6 +3240,7 @@
         "string-width": {
           "version": "1.0.2",
           "bundled": true,
+          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",

+ 39 - 39
package.json

@@ -1,41 +1,41 @@
 {
-  "name": "efunbox_mobile_8",
-  "version": "8.0.0",
-  "private": true,
-  "scripts": {
-    "start": "node node_modules/react-native/local-cli/cli.js start",
-    "test": "jest",
-    "add-react-navigation": "yarn add react-navigation && yarn add react-native-gesture-handler -S && react-native link react-native-gesture-handler",
-    "add-react-native-video": "yarn add react-native-video && react-native link  ",
-    "android": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res && react-native run-android"
-  },
-  "dependencies": {
-    "react": "16.8.3",
-    "react-art": "^16.8.6",
-    "react-dom": "^16.8.6",
-    "react-native": "0.59.4",
-    "react-native-device-info": "^2.1.1",
-    "react-native-gesture-handler": "^1.1.0",
-    "react-native-image-picker": "^0.28.1",
-    "react-native-orientation": "^3.1.3",
-    "react-native-splash-screen": "^3.2.0",
-    "react-native-storage": "^1.0.1",
-    "react-native-swiper": "^1.5.14",
-    "react-native-video": "^4.4.1",
-    "react-native-web": "^0.11.2",
-    "react-native-wechat": "^1.9.10",
-    "react-native-yunpeng-alipay": "^2.0.0",
-    "react-navigation": "^3.9.1"
-  },
-  "devDependencies": {
-    "@babel/core": "^7.4.3",
-    "@babel/runtime": "^7.4.3",
-    "babel-jest": "^24.7.1",
-    "jest": "^24.7.1",
-    "metro-react-native-babel-preset": "^0.53.1",
-    "react-test-renderer": "16.8.3"
-  },
-  "jest": {
-    "preset": "react-native"
-  }
+	"name": "efunbox_mobile_8",
+	"version": "8.0.0",
+	"private": true,
+	"scripts": {
+		"start": "node node_modules/react-native/local-cli/cli.js start",
+		"test": "jest",
+		"add-react-navigation": "yarn add react-navigation && yarn add react-native-gesture-handler -S && react-native link react-native-gesture-handler",
+		"add-react-native-video": "yarn add react-native-video && react-native link  ",
+		"android": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res && react-native run-android"
+	},
+	"dependencies": {
+		"react": "16.8.3",
+		"react-art": "^16.8.6",
+		"react-dom": "^16.8.6",
+		"react-native": "0.59.4",
+		"react-native-device-info": "^2.1.1",
+		"react-native-gesture-handler": "^1.1.0",
+		"react-native-image-picker": "^0.28.1",
+		"react-native-orientation": "^3.1.3",
+		"react-native-splash-screen": "^3.2.0",
+		"react-native-storage": "^1.0.1",
+		"react-native-swiper": "^1.5.14",
+		"react-native-video": "^4.4.1",
+		"react-native-web": "^0.11.2",
+		"react-native-wechat": "^1.9.10",
+		"react-native-yunpeng-alipay": "^2.0.0",
+		"react-navigation": "^3.9.1"
+	},
+	"devDependencies": {
+		"@babel/core": "^7.4.3",
+		"@babel/runtime": "^7.4.3",
+		"babel-jest": "^24.7.1",
+		"jest": "^24.7.1",
+		"metro-react-native-babel-preset": "^0.53.1",
+		"react-test-renderer": "16.8.3"
+	},
+	"jest": {
+		"preset": "react-native"
+	}
 }

+ 44 - 55
pages/Login.js

@@ -16,53 +16,54 @@ export default class Login extends BasePage {
 		verification_text: '获取验证码',
 		verification_code: '',
 		http_verification_code: '',
-		deviceCode: '',
-		sss: ''
+		deviceCode: ''
 	};
 	render() {
 		return (
 			<View style={styles.wrapper}>
-				<StatusBar backgroundColor={'white'} translucent={true} barStyle={'dark-content'} />
-				<View style={styles.jump}>
-					<TouchableOpacity style={styles.jumpBtn} onPress={this.jumpBtn.bind(this)}>
-						<Text style={styles.jumpText}>跳过</Text>
-						<Image source={require('./images/common/arrowRight.png')} />
-					</TouchableOpacity>
-				</View>
-				<View style={styles.phoneNumberBox}>
-					<Text style={styles.phoneNumber}>手机号</Text>
-					<TextInput
-						style={styles.phoneText}
-						onChangeText={(text) => this.setState({ phone_num: text })}
-						value={this.state.phone_num}
-						placeholder={'请输入手机号'}
-					/>
-				</View>
-				<View style={styles.signNumberBox}>
-					<Text style={styles.phoneNumber}>验证码</Text>
-					<View style={styles.signNumberLine2}>
+				<View style={{ height: this.getWindowHeight() }}>
+					<StatusBar backgroundColor={'white'} translucent={true} barStyle={'dark-content'} />
+					<View style={styles.jump}>
+						<TouchableOpacity style={styles.jumpBtn} onPress={this.jumpBtn.bind(this)}>
+							<Text style={styles.jumpText}>跳过</Text>
+							<Image source={require('./images/common/arrowRight.png')} />
+						</TouchableOpacity>
+					</View>
+					<View style={styles.phoneNumberBox}>
+						<Text style={styles.phoneNumber}>手机号</Text>
 						<TextInput
-							style={styles.signText}
-							onChangeText={(text) => this.setState({ verification_code: text })}
-							value={this.state.verification_code}
-							placeholder={'请输入验证码'}
+							style={styles.phoneText}
+							onChangeText={(text) => this.setState({ phone_num: text })}
+							value={this.state.phone_num}
+							placeholder={'请输入手机号'}
 						/>
-						<TouchableOpacity onPress={this.getVerification.bind(this)}>
-							<Text style={styles.getSign}> {this.state.verification_text}</Text>
-						</TouchableOpacity>
 					</View>
-				</View>
-				<View style={styles.loginIn}>
-					<Text style={styles.loginText} onPress={this.clickOK.bind(this)}>
-						登录
-					</Text>
-				</View>
-				<View style={styles.wechatLogin}>
-					<Image source={require('./images/common/wechat.png')} />
-					<Text style={styles.wechatLoginText} onPress={this.wechatLogin.bind(this)}>
-						微信登录
-					</Text>
-					<Image source={require('./images/common/arrowRight.png')} />
+					<View style={styles.signNumberBox}>
+						<Text style={styles.phoneNumber}>验证码</Text>
+						<View style={styles.signNumberLine2}>
+							<TextInput
+								style={styles.signText}
+								onChangeText={(text) => this.setState({ verification_code: text })}
+								value={this.state.verification_code}
+								placeholder={'请输入验证码'}
+							/>
+							<TouchableOpacity onPress={this.getVerification.bind(this)}>
+								<Text style={styles.getSign}> {this.state.verification_text}</Text>
+							</TouchableOpacity>
+						</View>
+					</View>
+					<View style={styles.loginIn}>
+						<Text style={styles.loginText} onPress={this.clickOK.bind(this)}>
+							登录
+						</Text>
+					</View>
+					<View style={styles.wechatLogin}>
+						<Image source={require('./images/common/wechat.png')} />
+						<Text style={styles.wechatLoginText} onPress={this.wechatLogin.bind(this)}>
+							微信登录
+						</Text>
+						<Image source={require('./images/common/arrowRight.png')} />
+					</View>
 				</View>
 			</View>
 		);
@@ -133,7 +134,7 @@ export default class Login extends BasePage {
 				body: {
 					mobile: this.state.phone_num,
 					sign: this.state.verification_code,
-					channel: '006',
+					channel: commonutil.getAppCode(),
 					deviceCode: this.state.deviceCode
 				}
 			};
@@ -175,19 +176,7 @@ export default class Login extends BasePage {
 	}
 
 	jumpBtn() {
-		let option = {
-			method: 'POST',
-			body: {
-				channel: '006',
-				deviceCode: this.state.deviceCode,
-				openId: '',
-				unionId: '',
-				avatar: '',
-				sex: '',
-				nickName: ''
-			}
-		};
-		http_user.jumpLogin(option).then((result) => {
+		http_user.jumpLogin(this.state.deviceCode, commonutil.getAppCode()).then((result) => {
 			if (result.code == 200) {
 				//登陆成功了,可以存储用户数据到本地
 				console.log('====================================');
@@ -225,7 +214,7 @@ export default class Login extends BasePage {
 			let option = {
 				method: 'POST',
 				body: {
-					channel: '006',
+					channel: commonutil.getAppCode(),
 					deviceCode: this.state.deviceCode,
 					openId: user['openid'],
 					unionId: user['unionid'],

+ 25 - 25
pages/PersonalInfo.js

@@ -8,27 +8,27 @@
 
 import React, { Component } from 'react';
 import {
-  StyleSheet,
-  Text,
-  View,
-  Image,
-  TouchableOpacity,
-  ImageBackground,
-  ToastAndroid,
-  BackHandler,
+	StyleSheet,
+	Text,
+	View,
+	Image,
+	TouchableOpacity,
+	ImageBackground,
+	ToastAndroid,
+	BackHandler,
 	StatusBar,
 	DeviceEventEmitter
-} from "react-native";
-import BasePage from "./BasePage";
-import CourseTitle from "../pages/components/CourseTitle";
-import ChosePhoto from "../pages/components/ChosePhoto";
-import RegionModal from "../pages/components/RegionModal";
-import BirthdayModal from "../pages/components/BirthdayModal";
-import GradeSelectionModal from "../pages/components/GradeSelectionModal";
-import PersonalInfoDialog from "../pages/components/PersonalInfoDialog";
-import http_user from "./services/user";
-import wechat from "./utils/wechat";
-import commonutil from "./utils/commonutil";
+} from 'react-native';
+import BasePage from './BasePage';
+import CourseTitle from '../pages/components/CourseTitle';
+import ChosePhoto from '../pages/components/ChosePhoto';
+import RegionModal from '../pages/components/RegionModal';
+import BirthdayModal from '../pages/components/BirthdayModal';
+import GradeSelectionModal from '../pages/components/GradeSelectionModal';
+import PersonalInfoDialog from '../pages/components/PersonalInfoDialog';
+import http_user from './services/user';
+import wechat from './utils/wechat';
+import commonutil from './utils/commonutil';
 
 type Props = {};
 
@@ -65,6 +65,7 @@ export default class PersonalInfo extends BasePage {
 				<View style={{ width: '100%', height: this.getWindowHeight() }}>
 					<PersonalInfoDialog
 						ref={(view) => (this.dialog = view)}
+						style={{ height: 10000 }}
 						updateParentState={this.updateState.bind(this)}
 					/>
 					<ChosePhoto ref={(view) => (this.chosephoto = view)} photoback={this.photoback.bind(this)} />
@@ -638,7 +639,7 @@ export default class PersonalInfo extends BasePage {
 										onPress={() => this.logout()}
 									>
 										<ImageBackground
-											source={require('./images/userInfo/logoutbg1.png')}
+											source={require('./images/userInfo/logoutbg.png')}
 											style={{
 												flex: 1,
 												width: '100%',
@@ -950,12 +951,11 @@ export default class PersonalInfo extends BasePage {
 			// ToastAndroid.show('修改失败', ToastAndroid.SHORT);
 		}
 	}
-  personinfoback() {
+	personinfoback() {
 		// this.props.navigation.state.params.infoback();
-		DeviceEventEmitter.emit('infoback')
-    this.props.navigation.goBack();
-  }
-
+		DeviceEventEmitter.emit('infoback');
+		this.props.navigation.goBack();
+	}
 
 	formaterDate(date) {
 		var date = new Date(date);

+ 51 - 49
pages/PhoneBind.js

@@ -32,60 +32,62 @@ export default class PhoneBind extends BasePage {
 	render() {
 		return (
 			<View style={styles.wrapper}>
-				<StatusBar backgroundColor={'white'} translucent={true} barStyle={'dark-content'} />
+				<View style={{ height: this.getWindowHeight() }}>
+					<StatusBar backgroundColor={'white'} translucent={true} barStyle={'dark-content'} />
 
-				<View style={{ flex: 2 }}>
-					<View style={{ marginTop: '6%', flex: 2, flexDirection: 'row' }}>
-						<TouchableOpacity
-							style={{ marginLeft: '5%' }}
-							activeOpacity={1}
-							onPress={this.backresult.bind(this)}
-						>
-							<Image source={require('./images/schedulePage/back_black.png')} />
-						</TouchableOpacity>
+					<View style={{ flex: 2 }}>
+						<View style={{ marginTop: '6%', flex: 2, flexDirection: 'row' }}>
+							<TouchableOpacity
+								style={{ marginLeft: '5%' }}
+								activeOpacity={1}
+								onPress={this.backresult.bind(this)}
+							>
+								<Image source={require('./images/schedulePage/back_black.png')} />
+							</TouchableOpacity>
+						</View>
+						<View style={styles.jump}>
+							<TouchableOpacity style={styles.jumpBtn}>
+								<Text style={styles.jumpText}>{this.state.page_title_text}</Text>
+							</TouchableOpacity>
+						</View>
 					</View>
-					<View style={styles.jump}>
-						<TouchableOpacity style={styles.jumpBtn}>
-							<Text style={styles.jumpText}>{this.state.page_title_text}</Text>
-						</TouchableOpacity>
-					</View>
-				</View>
-				<View style={styles.phoneNumberBox}>
-					<Text style={styles.phoneNumber}>手机号</Text>
-					<TextInput
-						style={styles.phoneText}
-						maxLength={11}
-						onChangeText={(text) => this.setState({ phone_num: text })}
-						value={this.state.phone_num}
-						placeholder={'请输入手机号'}
-					/>
-				</View>
-				<View style={styles.signNumberBox}>
-					<Text style={styles.phoneNumber}>验证码</Text>
-					<View style={styles.signNumberLine2}>
+					<View style={styles.phoneNumberBox}>
+						<Text style={styles.phoneNumber}>手机号</Text>
 						<TextInput
-							style={styles.signText}
-							maxLength={4}
-							onChangeText={(text) => this.setState({ verification_code: text })}
-							value={this.state.verification_code}
-							placeholder={'请输入验证码'}
+							style={styles.phoneText}
+							maxLength={11}
+							onChangeText={(text) => this.setState({ phone_num: text })}
+							value={this.state.phone_num}
+							placeholder={'请输入手机号'}
 						/>
-						<TouchableOpacity>
-							<Text style={styles.getSign} onPress={this.getVerification.bind(this)}>
-								{this.state.verification_text}
-							</Text>
-						</TouchableOpacity>
 					</View>
-				</View>
-				<View style={styles.loginIn}>
-					<Text style={styles.loginText} onPress={this.clickOK.bind(this)}>
-						{this.state.click_ok_text}
-					</Text>
-				</View>
-				<View style={styles.wechatLogin}>
-					{/* <Image source={require('./images/common/wechat.png')} /> */}
-					<Text style={styles.wechatLoginText} />
-					{/* <Image source={require('./images/common/arrowRight.png')} /> */}
+					<View style={styles.signNumberBox}>
+						<Text style={styles.phoneNumber}>验证码</Text>
+						<View style={styles.signNumberLine2}>
+							<TextInput
+								style={styles.signText}
+								maxLength={4}
+								onChangeText={(text) => this.setState({ verification_code: text })}
+								value={this.state.verification_code}
+								placeholder={'请输入验证码'}
+							/>
+							<TouchableOpacity>
+								<Text style={styles.getSign} onPress={this.getVerification.bind(this)}>
+									{this.state.verification_text}
+								</Text>
+							</TouchableOpacity>
+						</View>
+					</View>
+					<View style={styles.loginIn}>
+						<Text style={styles.loginText} onPress={this.clickOK.bind(this)}>
+							{this.state.click_ok_text}
+						</Text>
+					</View>
+					<View style={styles.wechatLogin}>
+						{/* <Image source={require('./images/common/wechat.png')} /> */}
+						<Text style={styles.wechatLoginText} />
+						{/* <Image source={require('./images/common/arrowRight.png')} /> */}
+					</View>
 				</View>
 			</View>
 		);

+ 81 - 86
pages/buy/buy.js

@@ -27,6 +27,7 @@ import CourseTitle from '../components/CourseTitle';
 import wechat from '../utils/wechat';
 import PayServer from '../services/Pay';
 import Alipay from 'react-native-yunpeng-alipay';
+import ModalView from '../utils/ModalUtil';
 
 export default class Buy extends BasePage {
 	state = {
@@ -45,11 +46,11 @@ export default class Buy extends BasePage {
 			}
 		],
 		currentTapindex: 0,
-		slideAnim: new Animated.Value(-150),
 		ifDialogShow: false,
 		payType: 1,
 		ticketPrice: 0,
-		useTicket: false
+		useTicket: false,
+		modalVisible: false
 	};
 	itemTap = (index) => {
 		this.setState({
@@ -78,29 +79,15 @@ export default class Buy extends BasePage {
 		);
 	};
 
-	dialogComeout = (index) => {
-		if (index) {
-			this.setState(
-				{
-					ifDialogShow: true
-				},
-				() => {
-					Animated.timing(this.state.slideAnim, {
-						toValue: 0,
-						duration: 100
-					}).start();
-				}
-			);
+	dialogComeout = () => {
+		if (this.state.modalVisible) {
+			this.setState({
+				modalVisible: false
+			});
 		} else {
-			Animated.timing(this.state.slideAnim, {
-				toValue: -150,
-				duration: 100
-			}).start();
-			setTimeout(() => {
-				this.setState({
-					ifDialogShow: false
-				});
-			}, 210);
+			this.setState({
+				modalVisible: true
+			});
 		}
 	};
 	setPayMethod = (type) => {
@@ -118,6 +105,9 @@ export default class Buy extends BasePage {
 	componentWillMount() {
 		//获取订购数据信息
 		this.getMember();
+		if (this.props.navigation.state.params != undefined) {
+			this.choseTicketCallBack(this.props.navigation.state.params.to_ticket);
+		}
 		BackHandler.addEventListener('hardwareBackPress', this.onBackAndroid);
 	}
 	componentWillUnmount() {
@@ -143,15 +133,8 @@ export default class Buy extends BasePage {
 		this.toNextPage('Ticket', { choseTicketCallBack: this.choseTicketCallBack.bind(this) });
 	};
 	choseTicketCallBack(item) {
-		/**item参数
-         * 	type: 1,
-			price: 12,
-			num: 6,
-			time: '2019-12-12'
-         * 
-         */
 		this.setState({
-			ticketPrice: item.price,
+			ticketPrice: item.amount,
 			useTicket: true
 		});
 	}
@@ -245,7 +228,7 @@ export default class Buy extends BasePage {
 						<Image source={require('../images/common/arrowRight.png')} />
 					</View>
 				</TouchableOpacity>
-				<TouchableOpacity style={styles.payment} activeOpacity={1} onPress={() => this.dialogComeout(true)}>
+				<TouchableOpacity style={styles.payment} activeOpacity={1} onPress={() => this.dialogComeout()}>
 					<Text style={styles.left}>支付方式</Text>
 					<View style={styles.right}>
 						{this.state.payType === 1 ? (
@@ -278,60 +261,73 @@ export default class Buy extends BasePage {
 						<Text style={styles.bottomRightText}>支付</Text>
 					</TouchableOpacity>
 				</View>
-				{this.state.ifDialogShow ? (
-					<TouchableHighlight
-						onPress={() => {
-							this.dialogComeout(false);
-						}}
-						style={{ ...styles.dialog }}
-						underlayColor={0.1}
-					>
-						<Animated.View style={{ ...styles.payMethod, bottom: this.state.slideAnim }} onPress={() => {}}>
-							<Text style={styles.payText}>选择支付方式</Text>
-							<TouchableOpacity
-								activeOpacity={0.9}
-								style={styles.payDialog}
-								onPress={() => this.setPayMethod(1)}
-							>
-								<View style={styles.dialogRow}>
-									<Image style={styles.payIcon} source={require('../images/common/wxPay.png')} />
-									<Text>微信支付</Text>
-								</View>
-								{this.state.payType === 1 ? (
-									<Image source={require('../images/common/check.png')} />
-								) : null}
-							</TouchableOpacity>
-							<TouchableOpacity
-								activeOpacity={0.9}
-								style={styles.payDialog}
-								onPress={() => this.setPayMethod(2)}
-							>
-								<View style={styles.dialogRow}>
-									<Image style={styles.payIcon} source={require('../images/common/aliPay.png')} />
-									<Text>支付宝支付</Text>
-								</View>
-								{this.state.payType === 2 ? (
-									<Image source={require('../images/common/check.png')} />
-								) : null}
-							</TouchableOpacity>
-							{/* <TextInput style={styles.payDialog} /> */}
-							<View style={{ flex: 0.2 }} />
-						</Animated.View>
-					</TouchableHighlight>
-				) : null}
-
-				{/* <Modal
-                    animationType="none "
-                    transparent={true}
-                    visible={true}
-                    onRequestClose={() => {
-                        alert("Modal has been closed.");
-                    }}
-                    
-                ></Modal> */}
+				{this.getModal()}
 			</View>
 		);
 	}
+
+	getModal() {
+		return (
+			<ModalView
+				close={() => {
+					this.setState({ modalVisible: false });
+				}}
+				visible={this.state.modalVisible}
+				customerlayout={{ flex: 1, justifyContent: 'flex-end' }}
+				contentView={this.getView}
+			/>
+		);
+	}
+
+	getView = () => {
+		return (
+			<Modal
+				animationType="slide"
+				transparent={true}
+				visible={this.state.modalVisible}
+				onRequestClose={() => {
+					this.setState({ modalVisible: false });
+				}}
+			>
+				<TouchableHighlight
+					onPress={() => {
+						this.dialogComeout(false);
+					}}
+					style={{ ...styles.dialog }}
+					underlayColor={0.1}
+					activeOpacity={1}
+				>
+					<View style={{ ...styles.payMethod, bottom: 10 }} onPress={() => {}}>
+						<Text style={styles.payText}>选择支付方式</Text>
+						<TouchableOpacity
+							activeOpacity={0.9}
+							style={styles.payDialog}
+							onPress={() => this.setPayMethod(1)}
+						>
+							<View style={styles.dialogRow}>
+								<Image style={styles.payIcon} source={require('../images/common/wxPay.png')} />
+								<Text>微信支付</Text>
+							</View>
+							{this.state.payType === 1 ? <Image source={require('../images/common/check.png')} /> : null}
+						</TouchableOpacity>
+						<TouchableOpacity
+							activeOpacity={0.9}
+							style={styles.payDialog}
+							onPress={() => this.setPayMethod(2)}
+						>
+							<View style={styles.dialogRow}>
+								<Image style={styles.payIcon} source={require('../images/common/aliPay.png')} />
+								<Text>支付宝支付</Text>
+							</View>
+							{this.state.payType === 2 ? <Image source={require('../images/common/check.png')} /> : null}
+						</TouchableOpacity>
+						{/* <TextInput style={styles.payDialog} /> */}
+						<View style={{ flex: 0.2 }} />
+					</View>
+				</TouchableHighlight>
+			</Modal>
+		);
+	};
 }
 
 const styles = StyleSheet.create({
@@ -450,8 +446,7 @@ const styles = StyleSheet.create({
 	dialog: {
 		width: Dimensions.width,
 		height: Dimensions.height,
-		position: 'absolute',
-		backgroundColor: 'rgba(0,0,0,0.4)'
+		position: 'absolute'
 	},
 	payMethod: {
 		width: Dimensions.width,

+ 70 - 59
pages/buy/ticket.js

@@ -11,6 +11,7 @@ import {
 	TouchableOpacity,
 	FlatList,
 	TouchableHighlight,
+	BackHandler,
 	DeviceEventEmitter,
 	StatusBar,
 	ScrollView,
@@ -26,10 +27,55 @@ export default class Ticket extends BasePage {
 		ticket_data: []
 	};
 	renderItem = (item, index) => {
+		return this.choseItem(item);
+	};
+	render() {
 		return (
-			<View style={{}}>
-				{item.type === 1 ? (
-					// 抵用券
+			<View style={{ flex: 1 }}>
+				<StatusBar barStyle={'dark-content'} backgroundColor={'white'} translucent={true} />
+				<View
+					style={{
+						height: 50,
+						backgroundColor: 'white',
+						marginTop: 30
+					}}
+				>
+					<CourseTitle
+						width={this.getWindowWidth()}
+						title="抵用券"
+						lefttype={1}
+						textcolor={'#231F20'}
+						backPress={() => this.goBack()}
+						// backPress={() => alert("左侧按钮")}
+					/>
+				</View>
+				<View style={{ flex: 0.1, backgroundColor: 'rgba(242, 242, 242, 1)' }} />
+				<View style={{ flex: 5, backgroundColor: 'rgba(242, 242, 242, 1)' }}>
+					{this.state.ticket_data.length > 0 ? (
+						<FlatList
+							data={this.state.ticket_data}
+							horizontal={false}
+							renderItem={({ item, index }) => this.renderItem(item, index)}
+							keyExtractor={(item, index) => index.toString()}
+						/>
+					) : (
+						<Text
+							style={{ height: '100%', width: '100%', textAlign: 'center', textAlignVertical: 'center' }}
+						>
+							还没有获取到抵用券
+						</Text>
+					)}
+				</View>
+			</View>
+		);
+	}
+
+	choseItem(item) {
+		switch (item.type) {
+			case 1:
+			default:
+				// 抵用券
+				return (
 					<TouchableOpacity
 						onPress={() => this.userdiscount(item)}
 						activeOpacity={1}
@@ -44,7 +90,7 @@ export default class Ticket extends BasePage {
 							<View style={styles.topInfo}>
 								<View style={{ flex: 0.5 }} />
 								<View style={styles.left2}>
-									<Text style={styles.price}>¥{item.price}</Text>
+									<Text style={styles.price}>¥{item.amount}</Text>
 									<Text style={styles.type}>抵用券</Text>
 								</View>
 								<View style={{ flex: 0.2 }} />
@@ -76,6 +122,7 @@ export default class Ticket extends BasePage {
 												textAlign: 'center',
 												textAlignVertical: 'center'
 											}}
+											onPress={() => this.useTicket(item)}
 										>
 											立即使用
 										</Text>
@@ -86,12 +133,13 @@ export default class Ticket extends BasePage {
 							<View style={{ flex: 0.2 }} />
 							<View style={styles.bottomInfo}>
 								<Text style={styles.greyText}>注:开通会员时方可使用</Text>
-								<Text style={styles.blueText}>查看订单</Text>
+								{/* <Text style={styles.blueText}>查看订单</Text> */}
 							</View>
 						</ImageBackground>
 					</TouchableOpacity>
-				) : (
-					// 优惠券
+				);
+			case 2:
+				return (
 					<ImageBackground
 						source={require('../images/ticket/coupon-bg.png')}
 						style={styles.type2}
@@ -107,60 +155,24 @@ export default class Ticket extends BasePage {
 							<Text style={styles.greyText}>有效期:{item.time}</Text>
 						</View>
 					</ImageBackground>
-				)}
-			</View>
-		);
-	};
-	render() {
-		return (
-			<View style={{ flex: 1 }}>
-				<StatusBar barStyle={'dark-content'} backgroundColor={'white'} translucent={true} />
-				<View
-					style={{
-						height: 50,
-						backgroundColor: 'white',
-						marginTop: 30
-					}}
-				>
-					<CourseTitle
-						width={this.getWindowWidth()}
-						title="抵用券"
-						lefttype={1}
-						textcolor={'#231F20'}
-						backPress={() => this.goBack()}
-						// backPress={() => alert("左侧按钮")}
-					/>
-				</View>
-				<View style={{ flex: 0.1, backgroundColor: 'rgba(242, 242, 242, 1)' }} />
-				<View style={{ flex: 5, backgroundColor: 'rgba(242, 242, 242, 1)' }}>
-					{this.state.ticket_data.length > 0 ? (
-						<FlatList
-							data={this.state.ticket_data}
-							horizontal={false}
-							renderItem={({ item, index }) => this.renderItem(item, index)}
-							keyExtractor={(item, index) => index.toString()}
-						/>
-					) : (
-						<Text
-							style={{ height: '100%', width: '100%', textAlign: 'center', textAlignVertical: 'center' }}
-						>
-							还没有获取到抵用券
-						</Text>
-					)}
-				</View>
-			</View>
-		);
+				);
+		}
 	}
+
 	componentWillMount() {
 		//获取用户优惠券信息
 		this.getVoucher();
+		BackHandler.addEventListener('hardwareBackPress', this.onBackAndroid);
 	}
-
+	componentWillUnmount() {
+		BackHandler.removeEventListener('hardwareBackPress', this.onBackAndroid);
+	}
+	onBackAndroid = () => {
+		this.goBack();
+		return true;
+	};
 	async getVoucher() {
 		await PayServer.getVoucher().then((result) => {
-			console.log('====================================');
-			console.log('getVoucher', result);
-			console.log('====================================');
 			if (result.data.length == 0) {
 			} else {
 				this.setState({
@@ -169,12 +181,11 @@ export default class Ticket extends BasePage {
 			}
 		});
 	}
-
 	userdiscount = (item) => {
-		if (this.props.navigation.state.params != undefined) {
-			this.props.navigation.state.params.choseTicketCallBack(item);
-			this.props.navigation.goBack();
-		}
+		this.useTicket(item);
+	};
+	useTicket = (ticket_item) => {
+		this.toNextPage('Buy', { to_ticket: ticket_item });
 	};
 }
 

+ 15 - 2
pages/components/BirthdayModal.js

@@ -25,6 +25,7 @@ import {
 	findNodeHandle,
 	UIManager
 } from 'react-native';
+import ModalView from '../utils/ModalUtil';
 
 type Props = {};
 export default class BirthdayModal extends Component<Props> {
@@ -77,6 +78,19 @@ export default class BirthdayModal extends Component<Props> {
 
 	render() {
 		return (
+			<ModalView
+				close={() => {
+					this.setState({ modalVisible: false });
+				}}
+				visible={this.state.modalVisible}
+				customerlayout={{ flex: 1, justifyContent: 'flex-end' }}
+				contentView={this.getView}
+			/>
+		);
+	}
+
+	getView = () => {
+		return (
 			<Modal
 				animationType="slide"
 				transparent={true}
@@ -94,7 +108,6 @@ export default class BirthdayModal extends Component<Props> {
 					<TouchableOpacity
 						style={{
 							flex: 3.2,
-							backgroundColor: 'rgba(0, 0, 0, 0.5)',
 							width: '100%'
 						}}
 						activeOpacity={1}
@@ -239,7 +252,7 @@ export default class BirthdayModal extends Component<Props> {
 				</View>
 			</Modal>
 		);
-	}
+	};
 
 	componentWillMount() {
 		var date = new Date();

+ 204 - 199
pages/components/ChosePhoto.js

@@ -6,210 +6,215 @@
  * @flow
  */
 
-import React, { Component } from "react";
+import React, { Component } from 'react';
 import {
-  Platform,
-  StyleSheet,
-  Text,
-  View,
-  Image,
-  TouchableOpacity,
-  ImageBackground,
-  TextInput,
-  Button,
-  StatusBar,
-  Modal,
-  TouchableHighlight,
-  DeviceEventEmitter
-} from "react-native";
-import ImagePicker from "react-native-image-picker";
+	Platform,
+	StyleSheet,
+	Text,
+	View,
+	Image,
+	TouchableOpacity,
+	ImageBackground,
+	TextInput,
+	Button,
+	StatusBar,
+	Modal,
+	TouchableHighlight,
+	DeviceEventEmitter
+} from 'react-native';
+import ImagePicker from 'react-native-image-picker';
+import ModalView from '../utils/ModalUtil';
+
 type Props = {};
 const options = {};
 export default class ChosePhoto extends Component<Props> {
-  state = {
-    modalVisible: false
-  };
+	state = {
+		modalVisible: false
+	};
+
+	setModalVisible(visible) {
+		this.setState({
+			modalVisible: visible
+		});
+	}
 
-  setModalVisible(visible) {
-    this.setState({
-      modalVisible: visible
-    });
-  }
+	render() {
+		return (
+			<ModalView
+				close={() => {
+					this.setState({ modalVisible: false });
+				}}
+				visible={this.state.modalVisible}
+				customerlayout={{ flex: 1, justifyContent: 'flex-end' }}
+				contentView={this.getView}
+			/>
+		);
+	}
 
-  render() {
-    return (
-      <Modal
-        animationType="slide"
-        transparent={true}
-        visible={this.state.modalVisible}
-        onRequestClose={() => {
-          this.setState({ modalVisible: false });
-        }}
-      >
-        <View
-          style={{
-            flex: 1,
-            flexDirection: "column"
-          }}
-        >
-          <TouchableOpacity
-            style={{
-              flex: 2.5,
-              backgroundColor: "rgba(0, 0, 0, 0.5)",
-              width: "100%"
-            }}
-            activeOpacity={1}
-            onPress={() => this.setState({ modalVisible: false })}
-          >
-            <View
-              style={{
-                flex: 2,
-                width: "100%"
-              }}
-            />
-          </TouchableOpacity>
-          <View
-            style={{
-              flex: 1,
-              width: "100%",
-              flexDirection: "column",
-              alignItems: "center",
-              backgroundColor: "rgba(0, 0, 0, 0.5)",
-              justifyContent: "center"
-            }}
-          >
-            <View
-              style={{
-                flex: 2,
-                width: "90%",
-                backgroundColor: "white",
-                borderRadius: 20,
-                flexDirection: "column"
-              }}
-            >
-              <TouchableOpacity
-                style={{
-                  flex: 5,
-                  alignItems: "center",
-                  justifyContent: "center"
-                }}
-                activeOpacity={1}
-                onPress={this.photograph.bind(this)}
-              >
-                <View
-                  style={{
-                    flex: 1,
-                    alignItems: "center",
-                    justifyContent: "center"
-                  }}
-                >
-                  <Text
-                    style={{ fontSize: 22, color: "rgba(88, 168, 250, 1)" }}
-                  >
-                    拍照
-                  </Text>
-                </View>
-              </TouchableOpacity>
-              <View
-                style={{
-                  flex: 0.1,
-                  backgroundColor: "rgba(246, 247, 248, 1)"
-                }}
-              />
-              <TouchableOpacity
-                style={{
-                  flex: 5,
-                  alignItems: "center",
-                  justifyContent: "center"
-                }}
-                activeOpacity={1}
-                onPress={this.album_selection.bind(this)}
-              >
-                <View
-                  style={{
-                    flex: 1,
-                    alignItems: "center",
-                    justifyContent: "center"
-                  }}
-                >
-                  <Text
-                    style={{ fontSize: 22, color: "rgba(88, 168, 250, 1)" }}
-                  >
-                    从相册选择
-                  </Text>
-                </View>
-              </TouchableOpacity>
-            </View>
-            <View
-              style={{
-                flex: 0.1,
-                width: "100%"
-              }}
-            />
-            <TouchableOpacity
-              style={{
-                flex: 1,
-                width: "90%",
-                alignItems: "center",
-                justifyContent: "center",
-                borderRadius: 20,
-                backgroundColor: "white"
-              }}
-              activeOpacity={1}
-              onPress={() => {
-                this.setState({ modalVisible: false });
-              }}
-            >
-              <View
-                style={{
-                  flex: 1,
-                  alignItems: "center",
-                  justifyContent: "center",
-                  borderRadius: 20,
-                  backgroundColor: "white"
-                }}
-              >
-                <Text
-                  style={{
-                    //   fontWeight: "bold",
-                    fontSize: 22,
-                    color: "rgba(88, 168, 250, 1)"
-                  }}
-                >
-                  取消
-                </Text>
-              </View>
-            </TouchableOpacity>
-            <View
-              style={{
-                flex: 0.1,
-                width: "100%"
-              }}
-            />
-          </View>
-        </View>
-      </Modal>
-    );
-  }
-  photograph() {
-    this.setModalVisible(false);
-    //拍照
-    ImagePicker.launchCamera(options, response => {
-      if (response.error) {
-        alert("ImagePicker Error: " + response.error);
-      }
-      this.props.photoback(response.uri);
-    });
-  }
+	getView = () => {
+		return (
+			<Modal
+				animationType="slide"
+				transparent={true}
+				visible={this.state.modalVisible}
+				onRequestClose={() => {
+					this.setState({ modalVisible: false });
+				}}
+			>
+				<View
+					style={{
+						flex: 1,
+						flexDirection: 'column'
+					}}
+				>
+					<TouchableOpacity
+						style={{
+							flex: 2.5,
+							width: '100%'
+						}}
+						activeOpacity={1}
+						onPress={() => this.setState({ modalVisible: false })}
+					>
+						<View
+							style={{
+								flex: 2,
+								width: '100%'
+							}}
+						/>
+					</TouchableOpacity>
+					<View
+						style={{
+							flex: 1,
+							width: '100%',
+							flexDirection: 'column',
+							alignItems: 'center',
+							justifyContent: 'center'
+						}}
+					>
+						<View
+							style={{
+								flex: 2,
+								width: '90%',
+								backgroundColor: 'white',
+								borderRadius: 20,
+								flexDirection: 'column'
+							}}
+						>
+							<TouchableOpacity
+								style={{
+									flex: 5,
+									alignItems: 'center',
+									justifyContent: 'center'
+								}}
+								activeOpacity={1}
+								onPress={this.photograph.bind(this)}
+							>
+								<View
+									style={{
+										flex: 1,
+										alignItems: 'center',
+										justifyContent: 'center'
+									}}
+								>
+									<Text style={{ fontSize: 22, color: 'rgba(88, 168, 250, 1)' }}>拍照</Text>
+								</View>
+							</TouchableOpacity>
+							<View
+								style={{
+									flex: 0.1,
+									backgroundColor: 'rgba(246, 247, 248, 1)'
+								}}
+							/>
+							<TouchableOpacity
+								style={{
+									flex: 5,
+									alignItems: 'center',
+									justifyContent: 'center'
+								}}
+								activeOpacity={1}
+								onPress={this.album_selection.bind(this)}
+							>
+								<View
+									style={{
+										flex: 1,
+										alignItems: 'center',
+										justifyContent: 'center'
+									}}
+								>
+									<Text style={{ fontSize: 22, color: 'rgba(88, 168, 250, 1)' }}>从相册选择</Text>
+								</View>
+							</TouchableOpacity>
+						</View>
+						<View
+							style={{
+								flex: 0.1,
+								width: '100%'
+							}}
+						/>
+						<TouchableOpacity
+							style={{
+								flex: 1,
+								width: '90%',
+								alignItems: 'center',
+								justifyContent: 'center',
+								borderRadius: 20,
+								backgroundColor: 'white'
+							}}
+							activeOpacity={1}
+							onPress={() => {
+								this.setState({ modalVisible: false });
+							}}
+						>
+							<View
+								style={{
+									flex: 1,
+									alignItems: 'center',
+									justifyContent: 'center',
+									borderRadius: 20,
+									backgroundColor: 'white'
+								}}
+							>
+								<Text
+									style={{
+										//   fontWeight: "bold",
+										fontSize: 22,
+										color: 'rgba(88, 168, 250, 1)'
+									}}
+								>
+									取消
+								</Text>
+							</View>
+						</TouchableOpacity>
+						<View
+							style={{
+								flex: 0.1,
+								width: '100%'
+							}}
+						/>
+					</View>
+				</View>
+			</Modal>
+		);
+	};
+	photograph() {
+		this.setModalVisible(false);
+		//拍照
+		ImagePicker.launchCamera(options, (response) => {
+			if (response.error) {
+				alert('ImagePicker Error: ' + response.error);
+			}
+			this.props.photoback(response.uri);
+		});
+	}
 
-  album_selection() {
-    this.setModalVisible(false);
-    //打开系统相册
-    ImagePicker.launchImageLibrary(options, response => {
-      if (response.error) {
-        alert("ImagePicker Error: " + response.error);
-      }
-      this.props.photoback(response.uri);
-    });
-  }
+	album_selection() {
+		this.setModalVisible(false);
+		//打开系统相册
+		ImagePicker.launchImageLibrary(options, (response) => {
+			if (response.error) {
+				alert('ImagePicker Error: ' + response.error);
+			}
+			this.props.photoback(response.uri);
+		});
+	}
 }

+ 1 - 1
pages/components/CourseTitle.js

@@ -68,7 +68,7 @@ export default class CourseTitle extends Component<Props> {
             <Text
               style={{
                 width: "100%",
-                fontSize: 20,
+                fontSize: 16,
                 fontWeight: "bold",
                 color: this.props.textcolor,
                 textAlign: "center"

+ 2 - 2
pages/components/MainPage.js

@@ -236,7 +236,7 @@ export default class MainPage extends BasePage {
 	// 渲染课程表
 	getScheduleElement() {
 		let renderScheduleItem = (item, index) => {
-			const id = item.boothId;
+			const id = item.operationContent;
 			return (
 				<TouchableOpacity
 					style={{
@@ -244,7 +244,7 @@ export default class MainPage extends BasePage {
 						height: Dimensions.getHeight(86),
 						marginRight: 12
 					}}
-					onPress={() => this.toNextPage('SchedulePage', { pagecode: this.state.pageCode })}
+					onPress={() => this.toNextPage('SchedulePage', { pagecode: id })}
 					key={index}
 					activeOpacity={1}
 				>

+ 261 - 255
pages/components/PersonalInfoDialog.js

@@ -6,267 +6,273 @@
  * @flow
  */
 
-import React, { Component } from "react";
+import React, { Component } from 'react';
 import {
-  Platform,
-  StyleSheet,
-  Text,
-  View,
-  Image,
-  TouchableOpacity,
-  ImageBackground,
-  TextInput,
-  Keyboard,
-  Button,
-  StatusBar,
-  Modal,
-  TouchableHighlight,
-  DeviceEventEmitter
-} from "react-native";
+	Platform,
+	StyleSheet,
+	Text,
+	View,
+	Image,
+	TouchableOpacity,
+	ImageBackground,
+	TextInput,
+	Keyboard,
+	Button,
+	StatusBar,
+	Modal,
+	TouchableHighlight,
+	DeviceEventEmitter
+} from 'react-native';
+import ModalView from '../utils/ModalUtil';
 
 type Props = {};
 export default class PersonalInfoDialog extends Component<Props> {
-  state = {
-    modalVisible: false,
-    title: "title",
-    placeholder: "",
-    touchcolor: "white",
-    touchtextcolor: "#58A8FA",
-    touch_cancel_color: "white",
-    touch_cancel_textcolor: "#58A8FA",
-    input_text: "",
-    updateType: 0, //1修改昵称,2修改学校名称,
-    keyBoardHeight: 0
-  };
+	state = {
+		modalVisible: false,
+		title: 'title',
+		placeholder: '',
+		touchcolor: 'white',
+		touchtextcolor: '#58A8FA',
+		touch_cancel_color: 'white',
+		touch_cancel_textcolor: '#58A8FA',
+		input_text: '',
+		updateType: 0, //1修改昵称,2修改学校名称,
+		keyBoardHeight: 0
+	};
 
-  setModalVisible(visible, type) {
-    this.setState({
-      modalVisible: visible,
-      updateType: type,
-      input_text: ""
-    });
-  }
-  setInfo(mytitle, holder) {
-    this.setState({
-      title: mytitle,
-      placeholder: holder
-    });
-  }
+	setModalVisible(visible, type) {
+		this.setState({
+			modalVisible: visible,
+			updateType: type,
+			input_text: ''
+		});
+	}
+	setInfo(mytitle, holder) {
+		this.setState({
+			title: mytitle,
+			placeholder: holder
+		});
+	}
 
-  touchDown() {
-    this.setState({
-      touchcolor: "#58A8FA",
-      touchtextcolor: "white"
-    });
-  }
-  touchUp() {
-    this.setState({
-      touchcolor: "white",
-      touchtextcolor: "#58A8FA"
-    });
-  }
-  touchCancelDown() {
-    this.setState({
-      touch_cancel_color: "#58A8FA",
-      touch_cancel_textcolor: "white"
-    });
-  }
-  touchCancelUp() {
-    this.setState({
-      touch_cancel_color: "white",
-      touch_cancel_textcolor: "#58A8FA"
-    });
-  }
-  setParentState() {
-    this.props.updateParentState(this.state.input_text, this.state.updateType);
-    this.setModalVisible(false);
-  }
-  componentWillMount() {
-    this.keyboardDidShowListener = Keyboard.addListener(
-      "keyboardDidShow",
-      this._keyboardDidShow
-    );
-    this.keyboardDidHideListener = Keyboard.addListener(
-      "keyboardDidHide",
-      this._keyboardDidHide
-    );
-  }
+	touchDown() {
+		this.setState({
+			touchcolor: '#58A8FA',
+			touchtextcolor: 'white'
+		});
+	}
+	touchUp() {
+		this.setState({
+			touchcolor: 'white',
+			touchtextcolor: '#58A8FA'
+		});
+	}
+	touchCancelDown() {
+		this.setState({
+			touch_cancel_color: '#58A8FA',
+			touch_cancel_textcolor: 'white'
+		});
+	}
+	touchCancelUp() {
+		this.setState({
+			touch_cancel_color: 'white',
+			touch_cancel_textcolor: '#58A8FA'
+		});
+	}
+	setParentState() {
+		this.props.updateParentState(this.state.input_text, this.state.updateType);
+		this.setModalVisible(false);
+	}
+	componentWillMount() {
+		this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow);
+		this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide);
+	}
 
-  componentWillUnmount() {
-    this.keyboardDidShowListener.remove();
-    this.keyboardDidHideListener.remove();
-  }
+	componentWillUnmount() {
+		this.keyboardDidShowListener.remove();
+		this.keyboardDidHideListener.remove();
+	}
 
-  _keyboardDidShow = e => {
-    this.setState({
-      keyBoardHeight: 0
-    });
-  };
-  _keyboardDidHide = () => {
-    this.setState({
-      keyBoardHeight: 0
-    });
-  };
-  render() {
-    return (
-      <Modal
-        animationType="fade"
-        transparent={true}
-        visible={this.state.modalVisible}
-        onRequestClose={() => {
-          this.setState({ modalVisible: false });
-        }}
-      >
-        <View
-          style={{
-            flex: 1,
-            width: "100%",
-            height: "100%",
-            backgroundColor: "rgba(0, 0, 0, 0.3)",
-            flexDirection: "column",
-            justifyContent: "flex-end"
-          }}
-        >
-          <View
-            style={{
-              width: "100%",
-              height: 150,
-              backgroundColor: "white",
-              bottom: this.state.keyBoardHeight
-            }}
-          >
-            <View
-              style={{
-                height: "100%",
-                width: "100%",
-                backgroundColor: "white"
-              }}
-            >
-              <View
-                style={{
-                  flex: 1,
-                  alignItems: "center",
-                  justifyContent: "center"
-                }}
-              >
-                <Text
-                  style={{
-                    flex: 1,
-                    textAlignVertical: "center",
-                    fontSize: 16,
-                    color: "black"
-                  }}
-                >
-                  {this.state.title}
-                </Text>
-              </View>
-              <View
-                style={{
-                  flex: 1,
-                  alignItems: "center",
-                  justifyContent: "center"
-                }}
-              >
-                <TextInput
-                  placeholder={this.state.placeholder}
-                  editable={true} //是否可编辑
-                  autoFocus={true}
-                  style={{
-                    width: "90%",
-                    height: "90%",
-                    borderColor: "black",
-                    borderWidth: 0,
-                    marginLeft: 5,
-                    fontSize: 16
-                  }}
-                  onChangeText={text =>
-                    this.setState({
-                      input_text: text
-                    })
-                  }
-                />
-              </View>
-              <View
-                style={{
-                  flex: 0.8,
-                  flexDirection: "row",
-                  alignItems: "center"
-                }}
-              >
-                <View
-                  style={{
-                    flex: 5
-                  }}
-                />
-                <View
-                  style={{
-                    flex: 2,
-                    height: "100%",
-                    borderRadius: 30,
-                    backgroundColor: this.state.touchcolor,
-                    alignItems: "center"
-                  }}
-                >
-                  <TouchableOpacity
-                    activeOpacity={1}
-                    onPressIn={() => this.touchDown()}
-                    onPressOut={() => this.touchUp()}
-                    onPress={() => {
-                      this.setParentState();
-                    }}
-                  >
-                    <Text
-                      style={{
-                        height: "100%",
-                        width: "100%",
-                        textAlignVertical: "center",
-                        textAlign: "center",
-                        fontSize: 18,
-                        borderRadius: 30,
-                        color: this.state.touchtextcolor
-                      }}
-                    >
-                      确定
-                    </Text>
-                  </TouchableOpacity>
-                </View>
-                <View style={{ flex: 0.5 }} />
-                <View
-                  style={{
-                    flex: 2,
-                    height: "100%",
-                    backgroundColor: this.state.touch_cancel_color,
-                    alignItems: "center",
-                    borderRadius: 30
-                  }}
-                >
-                  <TouchableOpacity
-                    activeOpacity={1}
-                    onPressIn={() => this.touchCancelDown()}
-                    onPressOut={() => this.touchCancelUp()}
-                    onPress={() => this.setModalVisible(false)}
-                  >
-                    <Text
-                      style={{
-                        textAlignVertical: "center",
-                        textAlign: "center",
-                        height: "100%",
-                        width: "100%",
-                        fontSize: 18,
-                        color: this.state.touch_cancel_textcolor
-                      }}
-                    >
-                      取消
-                    </Text>
-                  </TouchableOpacity>
-                </View>
-                <View style={{ flex: 0.5 }} />
-              </View>
-              <View style={{ flex: 0.2 }} />
-            </View>
-          </View>
-        </View>
-      </Modal>
-    );
-  }
+	_keyboardDidShow = (e) => {
+		this.setState({
+			keyBoardHeight: 0
+		});
+	};
+	_keyboardDidHide = () => {
+		this.setState({
+			keyBoardHeight: 0
+		});
+	};
+	render() {
+		return (
+			<ModalView
+				close={() => {
+					this.setState({ modalVisible: false });
+				}}
+				visible={this.state.modalVisible}
+				customerlayout={{ flex: 1, justifyContent: 'flex-end' }}
+				contentView={this.getView}
+			/>
+		);
+	}
+
+	getView = () => {
+		return (
+			<Modal
+				animationType="slide"
+				transparent={true}
+				visible={this.state.modalVisible}
+				onRequestClose={() => {
+					this.setState({ modalVisible: false });
+				}}
+			>
+				<View
+					style={{
+						flex: 1,
+						width: '100%',
+						height: '100%',
+						flexDirection: 'column',
+						justifyContent: 'flex-end'
+					}}
+				>
+					<View
+						style={{
+							width: '100%',
+							height: 150,
+							backgroundColor: 'white',
+							bottom: this.state.keyBoardHeight
+						}}
+					>
+						<View
+							style={{
+								height: '100%',
+								width: '100%',
+								backgroundColor: 'white'
+							}}
+						>
+							<View
+								style={{
+									flex: 1,
+									alignItems: 'center',
+									justifyContent: 'center'
+								}}
+							>
+								<Text
+									style={{
+										flex: 1,
+										textAlignVertical: 'center',
+										fontSize: 16,
+										color: 'black'
+									}}
+								>
+									{this.state.title}
+								</Text>
+							</View>
+							<View
+								style={{
+									flex: 1,
+									alignItems: 'center',
+									justifyContent: 'center'
+								}}
+							>
+								<TextInput
+									placeholder={this.state.placeholder}
+									editable={true} //是否可编辑
+									autoFocus={true}
+									style={{
+										width: '90%',
+										height: '90%',
+										borderColor: 'black',
+										borderWidth: 0,
+										marginLeft: 5,
+										fontSize: 16
+									}}
+									onChangeText={(text) =>
+										this.setState({
+											input_text: text
+										})}
+								/>
+							</View>
+							<View
+								style={{
+									flex: 0.8,
+									flexDirection: 'row',
+									alignItems: 'center'
+								}}
+							>
+								<View
+									style={{
+										flex: 5
+									}}
+								/>
+								<View
+									style={{
+										flex: 2,
+										height: '100%',
+										borderRadius: 30,
+										backgroundColor: this.state.touchcolor,
+										alignItems: 'center'
+									}}
+								>
+									<TouchableOpacity
+										activeOpacity={1}
+										onPressIn={() => this.touchDown()}
+										onPressOut={() => this.touchUp()}
+										onPress={() => {
+											this.setParentState();
+										}}
+									>
+										<Text
+											style={{
+												height: '100%',
+												width: '100%',
+												textAlignVertical: 'center',
+												textAlign: 'center',
+												fontSize: 18,
+												borderRadius: 30,
+												color: this.state.touchtextcolor
+											}}
+										>
+											确定
+										</Text>
+									</TouchableOpacity>
+								</View>
+								<View style={{ flex: 0.5 }} />
+								<View
+									style={{
+										flex: 2,
+										height: '100%',
+										backgroundColor: this.state.touch_cancel_color,
+										alignItems: 'center',
+										borderRadius: 30
+									}}
+								>
+									<TouchableOpacity
+										activeOpacity={1}
+										onPressIn={() => this.touchCancelDown()}
+										onPressOut={() => this.touchCancelUp()}
+										onPress={() => this.setModalVisible(false)}
+									>
+										<Text
+											style={{
+												textAlignVertical: 'center',
+												textAlign: 'center',
+												height: '100%',
+												width: '100%',
+												fontSize: 18,
+												color: this.state.touch_cancel_textcolor
+											}}
+										>
+											取消
+										</Text>
+									</TouchableOpacity>
+								</View>
+								<View style={{ flex: 0.5 }} />
+							</View>
+							<View style={{ flex: 0.2 }} />
+						</View>
+					</View>
+				</View>
+			</Modal>
+		);
+	};
 }

+ 335 - 329
pages/components/RegionModal.js

@@ -6,349 +6,355 @@
  * @flow
  */
 
-import React, { Component } from "react";
+import React, { Component } from 'react';
 import {
-  Platform,
-  StyleSheet,
-  Text,
-  View,
-  Image,
-  TouchableOpacity,
-  ImageBackground,
-  TextInput,
-  Button,
-  StatusBar,
-  Modal,
-  ScrollView,
-  TouchableHighlight,
-  DeviceEventEmitter,
-  findNodeHandle,
-  UIManager
-} from "react-native";
+	Platform,
+	StyleSheet,
+	Text,
+	View,
+	Image,
+	TouchableOpacity,
+	ImageBackground,
+	TextInput,
+	Button,
+	StatusBar,
+	Modal,
+	ScrollView,
+	TouchableHighlight,
+	DeviceEventEmitter,
+	findNodeHandle,
+	UIManager
+} from 'react-native';
 
-import CitysData from "../../data/citys.json";
+import CitysData from '../../data/citys.json';
+import ModalView from '../utils/ModalUtil';
 
 type Props = {};
 export default class RegionModal extends Component<Props> {
-  state = {
-    modalVisible: false,
-    cityjson: JSON.parse(JSON.stringify(CitysData.provinces)),
-    provinces: CitysData.provinces[0].provinces,
-    provinces_views: [],
-    provinces_views_index: -1,
-    city_data: CitysData.provinces[0].citys,
-    city_views: [],
-    city_views_index: -1,
-    click_provinces_name: "",
-    click_city_name: "",
-    text_height: -1
-  };
+	state = {
+		modalVisible: false,
+		cityjson: JSON.parse(JSON.stringify(CitysData.provinces)),
+		provinces: CitysData.provinces[0].provinces,
+		provinces_views: [],
+		provinces_views_index: -1,
+		city_data: CitysData.provinces[0].citys,
+		city_views: [],
+		city_views_index: -1,
+		click_provinces_name: '',
+		click_city_name: '',
+		text_height: -1
+	};
 
-  render() {
-    return (
-      <Modal
-        animationType="slide"
-        transparent={true}
-        visible={this.state.modalVisible}
-        onRequestClose={() => {
-          this.setState({ modalVisible: false });
-        }}
-      >
-        <View
-          style={{
-            flex: 1,
-            flexDirection: "column"
-          }}
-        >
-          <TouchableOpacity
-            style={{
-              flex: 3.2,
-              backgroundColor: "rgba(0, 0, 0, 0.5)",
-              width: "100%"
-            }}
-            activeOpacity={1}
-            onPress={() =>
-              this.setState({
-                modalVisible: false
-              })
-            }
-          />
-          <View
-            style={{
-              flex: 2,
-              backgroundColor: "white",
-              flexDirection: "column",
-              justifyContent: "center",
-              alignItems: "center",
-              width: "100%"
-            }}
-          >
-            <View
-              style={{
-                flex: 1,
-                flexDirection: "row",
-                alignItems: "center",
-                justifyContent: "center"
-              }}
-            >
-              <TouchableOpacity
-                style={{
-                  flex: 1
-                }}
-                activeOpacity={1}
-                onPress={() => this.cancel()}
-              >
-                <View
-                  style={{
-                    flex: 1,
-                    alignItems: "center",
-                    justifyContent: "center"
-                  }}
-                >
-                  <Text
-                    style={{
-                      fontSize: 20,
-                      color: "rgba(59, 59, 59, 1)",
-                      textAlignVertical: "center"
-                    }}
-                  >
-                    取消
-                  </Text>
-                </View>
-              </TouchableOpacity>
-              <View style={{ flex: 3.5 }} />
-              <TouchableOpacity
-                style={{
-                  flex: 1
-                }}
-                activeOpacity={1}
-                onPress={() => this.commit()}
-              >
-                <View
-                  style={{
-                    flex: 1,
-                    alignItems: "center",
-                    justifyContent: "center"
-                  }}
-                >
-                  <Text
-                    style={{
-                      fontSize: 20,
-                      color: "rgba(59, 59, 59, 1)",
-                      textAlignVertical: "center"
-                    }}
-                  >
-                    完成
-                  </Text>
-                </View>
-              </TouchableOpacity>
-            </View>
-            <View
-              style={{
-                flex: 0.05,
-                width: "90%",
-                backgroundColor: "rgba(246, 247, 248, 1)"
-                // backgroundColor: "red"
-              }}
-            />
-            <View
-              style={{
-                flex: 5,
-                flexDirection: "row"
-              }}
-            >
-              <View
-                style={{
-                  flex: 1
-                }}
-              >
-                <ScrollView
-                  style={{
-                    flex: 1
-                  }}
-                  ref={view => (this.provinces_scroll = view)}
-                  onLayout={() => this.provinces_onlayout()}
-                  showsVerticalScrollIndicator={false}
-                >
-                  {this.scroll_item()}
-                </ScrollView>
-              </View>
-              <View
-                style={{
-                  flex: 1
-                }}
-              >
-                <ScrollView
-                  ref={view => (this.city_scroll = view)}
-                  onLayout={() => this.city_onlayout()}
-                  style={{
-                    flex: 1
-                  }}
-                  showsVerticalScrollIndicator={false}
-                >
-                  {this.scroll_city_item(this.state.city_data)}
-                </ScrollView>
-              </View>
-            </View>
-          </View>
-        </View>
-      </Modal>
-    );
-  }
-  componentWillMount() {
-    for (var i = 0; i < this.state.cityjson.length; i++) {
-      if (this.props.provinceName === CitysData.provinces[i].provinceName) {
-        this.state.provinces_views_index = i;
-        this.state.click_provinces_name = this.props.provinceName;
-        this.state.city_data = CitysData.provinces[i].citys;
-        for (var j = 0; j < this.state.city_data.length; j++) {
-          if (this.props.citys === this.state.city_data[j].citysName) {
-            this.state.city_views_index = j;
-            this.state.click_city_name = this.props.citys;
-          }
-        }
-      }
-    }
-  }
-  provinces_onlayout() {
-    if (this.state.provinces_views_index != -1) {
-      this.provinces_scroll.scrollTo({
-        x: 0,
-        y: (this.state.text_height + 20) * this.state.provinces_views_index,
-        duration: 500
-      });
-    }
-  }
+	render() {
+		return (
+			<ModalView
+				close={() => {
+					this.setState({ modalVisible: false });
+				}}
+				visible={this.state.modalVisible}
+				customerlayout={{ flex: 1, justifyContent: 'flex-end' }}
+				contentView={this.getView}
+			/>
+		);
+	}
 
-  city_onlayout() {
-    if (this.state.city_views_index != -1) {
-      this.city_scroll.scrollTo({
-        x: 0,
-        y: (this.state.text_height + 20) * this.state.city_views_index,
-        duration: 500
-      });
-    }
-  }
-  commit() {
-    if (
-      this.state.provinces_views_index == -1 ||
-      this.state.city_views_index == -1
-    ) {
-      alert("请选择完整地区");
-    } else {
-      this.props.cityscommit(
-        this.state.click_provinces_name,
-        this.state.click_city_name
-      );
-      this.setModalVisible(false);
-    }
-  }
+	getView = () => {
+		return (
+			<Modal
+				animationType="slide"
+				transparent={true}
+				visible={this.state.modalVisible}
+				onRequestClose={() => {
+					this.setState({ modalVisible: false });
+				}}
+			>
+				<View
+					style={{
+						flex: 1,
+						flexDirection: 'column'
+					}}
+				>
+					<TouchableOpacity
+						style={{
+							flex: 3.2,
+							width: '100%'
+						}}
+						activeOpacity={1}
+						onPress={() =>
+							this.setState({
+								modalVisible: false
+							})}
+					/>
+					<View
+						style={{
+							flex: 2,
+							backgroundColor: 'white',
+							flexDirection: 'column',
+							justifyContent: 'center',
+							alignItems: 'center',
+							width: '100%'
+						}}
+					>
+						<View
+							style={{
+								flex: 1,
+								flexDirection: 'row',
+								alignItems: 'center',
+								justifyContent: 'center'
+							}}
+						>
+							<TouchableOpacity
+								style={{
+									flex: 1
+								}}
+								activeOpacity={1}
+								onPress={() => this.cancel()}
+							>
+								<View
+									style={{
+										flex: 1,
+										alignItems: 'center',
+										justifyContent: 'center'
+									}}
+								>
+									<Text
+										style={{
+											fontSize: 20,
+											color: 'rgba(59, 59, 59, 1)',
+											textAlignVertical: 'center'
+										}}
+									>
+										取消
+									</Text>
+								</View>
+							</TouchableOpacity>
+							<View style={{ flex: 3.5 }} />
+							<TouchableOpacity
+								style={{
+									flex: 1
+								}}
+								activeOpacity={1}
+								onPress={() => this.commit()}
+							>
+								<View
+									style={{
+										flex: 1,
+										alignItems: 'center',
+										justifyContent: 'center'
+									}}
+								>
+									<Text
+										style={{
+											fontSize: 20,
+											color: 'rgba(59, 59, 59, 1)',
+											textAlignVertical: 'center'
+										}}
+									>
+										完成
+									</Text>
+								</View>
+							</TouchableOpacity>
+						</View>
+						<View
+							style={{
+								flex: 0.05,
+								width: '90%',
+								backgroundColor: 'rgba(246, 247, 248, 1)'
+								// backgroundColor: "red"
+							}}
+						/>
+						<View
+							style={{
+								flex: 5,
+								flexDirection: 'row'
+							}}
+						>
+							<View
+								style={{
+									flex: 1
+								}}
+							>
+								<ScrollView
+									style={{
+										flex: 1
+									}}
+									ref={(view) => (this.provinces_scroll = view)}
+									onLayout={() => this.provinces_onlayout()}
+									showsVerticalScrollIndicator={false}
+								>
+									{this.scroll_item()}
+								</ScrollView>
+							</View>
+							<View
+								style={{
+									flex: 1
+								}}
+							>
+								<ScrollView
+									ref={(view) => (this.city_scroll = view)}
+									onLayout={() => this.city_onlayout()}
+									style={{
+										flex: 1
+									}}
+									showsVerticalScrollIndicator={false}
+								>
+									{this.scroll_city_item(this.state.city_data)}
+								</ScrollView>
+							</View>
+						</View>
+					</View>
+				</View>
+			</Modal>
+		);
+	};
+	componentWillMount() {
+		for (var i = 0; i < this.state.cityjson.length; i++) {
+			if (this.props.provinceName === CitysData.provinces[i].provinceName) {
+				this.state.provinces_views_index = i;
+				this.state.click_provinces_name = this.props.provinceName;
+				this.state.city_data = CitysData.provinces[i].citys;
+				for (var j = 0; j < this.state.city_data.length; j++) {
+					if (this.props.citys === this.state.city_data[j].citysName) {
+						this.state.city_views_index = j;
+						this.state.click_city_name = this.props.citys;
+					}
+				}
+			}
+		}
+	}
+	provinces_onlayout() {
+		if (this.state.provinces_views_index != -1) {
+			this.provinces_scroll.scrollTo({
+				x: 0,
+				y: (this.state.text_height + 20) * this.state.provinces_views_index,
+				duration: 500
+			});
+		}
+	}
 
-  cancel() {
-    this.setModalVisible(false);
-  }
+	city_onlayout() {
+		if (this.state.city_views_index != -1) {
+			this.city_scroll.scrollTo({
+				x: 0,
+				y: (this.state.text_height + 20) * this.state.city_views_index,
+				duration: 500
+			});
+		}
+	}
+	commit() {
+		if (this.state.provinces_views_index == -1 || this.state.city_views_index == -1) {
+			alert('请选择完整地区');
+		} else {
+			this.props.cityscommit(this.state.click_provinces_name, this.state.click_city_name);
+			this.setModalVisible(false);
+		}
+	}
 
-  setModalVisible(visible) {
-    this.setState({
-      modalVisible: visible
-    });
-  }
+	cancel() {
+		this.setModalVisible(false);
+	}
 
-  scroll_item() {
-    // console.log(this.state.cityjson);
-    for (var i = 0; i < this.state.cityjson.length; i++) {
-      let index = i;
-      let textstyle = null;
-      if (this.state.provinces_views_index == i) {
-        textstyle = styles.item_text_click;
-      } else {
-        textstyle = styles.item_text;
-      }
-      this.state.provinces_views[i] = (
-        <Text
-          style={textstyle}
-          key={i}
-          onPress={() => this.get_city(index)}
-          onLayout={event => this.onLayout(event)}
-        >
-          {CitysData.provinces[i].provinceName}
-        </Text>
-      );
-    }
-    return this.state.provinces_views;
-  }
-  onLayout = event => {
-    if (this.state.text_height == -1) {
-      this.setState({
-        text_height: event.nativeEvent.layout.height
-      });
-    } else {
-    }
-  };
+	setModalVisible(visible) {
+		this.setState({
+			modalVisible: visible
+		});
+	}
 
-  get_city(index) {
-    this.setState({
-      city_data: CitysData.provinces[index].citys,
-      text_color: "blue",
-      provinces_views_index: index,
-      city_views_index: -1,
-      click_provinces_name: CitysData.provinces[index].provinceName,
-      click_city_name: ""
-    });
+	scroll_item() {
+		// console.log(this.state.cityjson);
+		for (var i = 0; i < this.state.cityjson.length; i++) {
+			let index = i;
+			let textstyle = null;
+			if (this.state.provinces_views_index == i) {
+				textstyle = styles.item_text_click;
+			} else {
+				textstyle = styles.item_text;
+			}
+			this.state.provinces_views[i] = (
+				<Text
+					style={textstyle}
+					key={i}
+					onPress={() => this.get_city(index)}
+					onLayout={(event) => this.onLayout(event)}
+				>
+					{CitysData.provinces[i].provinceName}
+				</Text>
+			);
+		}
+		return this.state.provinces_views;
+	}
+	onLayout = (event) => {
+		if (this.state.text_height == -1) {
+			this.setState({
+				text_height: event.nativeEvent.layout.height
+			});
+		} else {
+		}
+	};
 
-    this.city_scroll.scrollTo({
-      x: 0,
-      y: 0,
-      duration: 100
-    });
-    // this.forceUpdate();
-  }
+	get_city(index) {
+		this.setState({
+			city_data: CitysData.provinces[index].citys,
+			text_color: 'blue',
+			provinces_views_index: index,
+			city_views_index: -1,
+			click_provinces_name: CitysData.provinces[index].provinceName,
+			click_city_name: ''
+		});
 
-  scroll_city_item(citys) {
-    this.state.city_views = [];
-    for (var i = 0; i < citys.length; i++) {
-      let index = i;
-      // console.log("this.state.city_views_index:" + this.state.city_views_index);
-      if (this.state.city_views_index == i) {
-        textstyle = styles.item_text_click;
-      } else {
-        textstyle = styles.item_text;
-      }
-      this.state.city_views[i] = (
-        <Text style={textstyle} key={i} onPress={() => this.click_citys(index)}>
-          {citys[i].citysName}
-        </Text>
-      );
-    }
-    return this.state.city_views;
-  }
+		this.city_scroll.scrollTo({
+			x: 0,
+			y: 0,
+			duration: 100
+		});
+		// this.forceUpdate();
+	}
 
-  click_citys(index) {
-    this.setState({
-      city_views_index: index,
-      click_city_name: this.state.city_data[index].citysName
-    });
-  }
+	scroll_city_item(citys) {
+		this.state.city_views = [];
+		for (var i = 0; i < citys.length; i++) {
+			let index = i;
+			// console.log("this.state.city_views_index:" + this.state.city_views_index);
+			if (this.state.city_views_index == i) {
+				textstyle = styles.item_text_click;
+			} else {
+				textstyle = styles.item_text;
+			}
+			this.state.city_views[i] = (
+				<Text style={textstyle} key={i} onPress={() => this.click_citys(index)}>
+					{citys[i].citysName}
+				</Text>
+			);
+		}
+		return this.state.city_views;
+	}
+
+	click_citys(index) {
+		this.setState({
+			city_views_index: index,
+			click_city_name: this.state.city_data[index].citysName
+		});
+	}
 }
 const styles = StyleSheet.create({
-  item_text: {
-    color: "rgba(77, 77, 77, 1)",
-    fontSize: 18,
-    justifyContent: "center",
-    alignItems: "center",
-    marginTop: 20,
-    width: "100%",
-    textAlignVertical: "center",
-    textAlign: "center"
-  },
-  item_text_click: {
-    color: "rgba(59, 149, 243, 1)",
-    fontSize: 18,
-    justifyContent: "center",
-    alignItems: "center",
-    marginTop: 20,
-    width: "100%",
-    textAlignVertical: "center",
-    textAlign: "center"
-  }
+	item_text: {
+		color: 'rgba(77, 77, 77, 1)',
+		fontSize: 18,
+		justifyContent: 'center',
+		alignItems: 'center',
+		marginTop: 20,
+		width: '100%',
+		textAlignVertical: 'center',
+		textAlign: 'center'
+	},
+	item_text_click: {
+		color: 'rgba(59, 149, 243, 1)',
+		fontSize: 18,
+		justifyContent: 'center',
+		alignItems: 'center',
+		marginTop: 20,
+		width: '100%',
+		textAlignVertical: 'center',
+		textAlign: 'center'
+	}
 });

+ 44 - 0
pages/components/modol.js

@@ -0,0 +1,44 @@
+/**
+ * Created by wuyunqiang on 2018/1/16.
+ */
+import React, { Component } from 'react';
+import {
+    AppRegistry,
+    Platform,
+    StyleSheet,
+    Text,
+    View,
+    ScrollView,
+    Image,
+    UIManager,
+    TouchableOpacity,
+    NativeModules,
+    ImageBackground,
+    DeviceEventEmitter,
+    requireNativeComponent,
+} from 'react-native';
+const ReactNative = require('ReactNative');
+import PropTypes from 'prop-types';
+var ModalView = requireNativeComponent('ModalAndroid', App);//内部使用popwindow实现全屏
+export default class App extends Component {
+    constructor(props){
+        super(props);
+    }
+
+    render() {
+        return (
+            <ModalView
+                ref = {(PopModal)=>{this.PopModal = PopModal}}
+                {...this.props}>
+                <View style={{flex: 1}}>
+                    {this.props.children}
+                </View>
+            </ModalView>
+        )
+    }
+}
+
+ModalView.propTypes = {
+    ...View.propTypes,
+    visible:PropTypes.bool,
+};

BIN
pages/images/userInfo/arrow.png


BIN
pages/images/userInfo/arrow@2x.png


BIN
pages/images/userInfo/arrow@3x.png


BIN
pages/images/userInfo/back_white.png


BIN
pages/images/userInfo/back_white@2x.png


BIN
pages/images/userInfo/back_white@3x.png


BIN
pages/images/userInfo/birthday.png


BIN
pages/images/userInfo/birthday@2x.png


BIN
pages/images/userInfo/birthday@3x.png


BIN
pages/images/userInfo/grade.png


BIN
pages/images/userInfo/grade@2x.png


BIN
pages/images/userInfo/grade@3x.png


BIN
pages/images/userInfo/headportrait.png


BIN
pages/images/userInfo/headportrait@2x.png


BIN
pages/images/userInfo/headportrait@3x.png


BIN
pages/images/userInfo/location.png


BIN
pages/images/userInfo/location@2x.png


BIN
pages/images/userInfo/location@3x.png


BIN
pages/images/userInfo/logoutbg.png


BIN
pages/images/userInfo/logoutbg1.png


BIN
pages/images/userInfo/logoutbg1@3x.png


BIN
pages/images/userInfo/logoutbg@2x.png


BIN
pages/images/userInfo/nickname.png


BIN
pages/images/userInfo/nickname@2x.png


BIN
pages/images/userInfo/nickname@3x.png


BIN
pages/images/userInfo/school.png


BIN
pages/images/userInfo/school@2x.png


BIN
pages/images/userInfo/school@3x.png


+ 5 - 1
pages/services/api.js

@@ -5,7 +5,8 @@ const url = {
 	upload_img: 'http://ott80test-base.yifangjiaoyu.cn/file/upload',
 	get_member: 'http://ott80test-trade.yifangjiaoyu.cn/customer/order/member',
 	pay_url: 'http://ott80test-trade.yifangjiaoyu.cn/mobile',
-	get_voucher: 'http://ott80test-trade.yifangjiaoyu.cn/mobile/voucher'
+	get_voucher: 'http://ott80test-trade.yifangjiaoyu.cn/mobile/voucher',
+	get_isLogin: 'http://ott80test-base.yifangjiaoyu.cn/mobile/user/isLogin'
 };
 
 export default class APIConfig {
@@ -32,4 +33,7 @@ export default class APIConfig {
 	static getVoucherUrl() {
 		return url.get_voucher;
 	}
+	static getIsLogin() {
+		return url.get_isLogin;
+	}
 }

+ 10 - 10
pages/services/user.js

@@ -3,10 +3,6 @@ import efunRequest from '../utils/efunRequest';
 import request from '../utils/request';
 
 export default class user {
-	static update_UserInfo(opts) {
-		console.log('opts', opts);
-		return request(APIConfig.getUserUrl(``), opts);
-	}
 	// 个人中心
 	static userMember() {
 		return request(`http://ott80test-base.yifangjiaoyu.cn/mobile/user/member`, {
@@ -65,21 +61,21 @@ export default class user {
 
 	//绑定微信
 	static bind_wechat(opts) {
-		return request(APIConfig.getUserUrl(`/wechatBind`), opts);
+		return request(APIConfig.getUserUrl() + `/wechatBind`, opts);
 	}
 
 	//获取验证码
 	static getVerificationCode(phone) {
-		return request(APIConfig.getUserUrl(`/sendCode?mobile=` + phone));
+		return request(APIConfig.getUserUrl() + `/sendCode?mobile=` + phone);
 	}
 	//绑定手机号
 	static bind_phone(opts) {
-		return request(APIConfig.getUserUrl(`/mobileBind`), opts);
+		return request(APIConfig.getUserUrl() + `/mobileBind`, opts);
 	}
 
 	//手机号登陆注册
 	static mobileLoginAndReg(opts) {
-		return request(APIConfig.getUserUrl(`/mobileLoginAndReg`), opts);
+		return request(APIConfig.getUserUrl() + `/mobileLoginAndReg`, opts);
 	}
 
 	//微信登陆
@@ -87,8 +83,12 @@ export default class user {
 		return request(APIConfig.getUserUrl(``), opts);
 	}
 	//跳过
-	static jumpLogin(opts) {
-		return request(APIConfig.getUserUrl(``), opts);
+	static jumpLogin(deviceCode, channel) {
+		console.log('====================================');
+		console.log('deviceCode', deviceCode);
+		console.log('channel', channel);
+		console.log('====================================');
+		return request(APIConfig.getIsLogin() + `?deviceCode=` + deviceCode + '&channel=' + channel, { method: 'GET' });
 	}
 }
 

+ 2 - 2
pages/userCenter.js

@@ -145,7 +145,7 @@ export default class userCenter extends BasePage {
 								textcolor={'#fff'}
 								backPress={() => this.goBack()}
 								// backgroundColor={"transparent"}
-								// rightPress={this.showSharedDialog.bind(this)}
+								rightPress={() => this.toNextPage('PersonalInfo')}
 							/>
 						</View>
 						<View style={styles.userInfo}>
@@ -194,7 +194,7 @@ export default class userCenter extends BasePage {
 	}
 	goTo(index) {
 		if (index === 'Phone') {
-			commonUtil.callPhone('15810271473');
+			commonUtil.callPhone('.......');
 		} else {
 			this.toNextPage(index);
 		}

+ 108 - 0
pages/utils/ModalUtil.js

@@ -0,0 +1,108 @@
+/**
+ * Created by wuyunqiang on 2017/8/2.
+ */
+import React, { Component, PropTypes } from 'react';
+import {
+	Text,
+	View,
+	TouchableOpacity,
+	StyleSheet,
+	Platform,
+	Dimensions,
+	Image,
+	Modal,
+	TextInput,
+	NativeModules,
+	InteractionManager,
+	AppState
+} from 'react-native';
+import ModalAndroid from '../components/modol';
+
+export default class ModalView extends Component {
+	constructor(props) {
+		super(props);
+		this.state = {
+			update: false,
+			visible: this.props.visible
+		};
+	}
+
+	componentDidMount() {
+		AppState.addEventListener('change', this._handleAppStateChange);
+	}
+
+	componentWillReceiveProps(props) {
+		this.setState({ visible: props.visible });
+	}
+
+	componentWillUnmount() {
+		AppState.removeEventListener('change', this._handleAppStateChange);
+	}
+
+	_handleAppStateChange = (AppState) => {
+		console.log('AppState', AppState);
+		console.log('AppState _handleAppStateChange', this.state.visible);
+		this.setState({
+			update: !this.state.update,
+			visible: this.state.visible
+		});
+	};
+
+	close = () => {
+		requestAnimationFrame(() => {
+			if (this.props.close) {
+				// console.log("close","执行了父组件的close方法")
+				this.props.close();
+			} else {
+				// console.log("close","执行本组件方法")
+				this.setState({ visible: false });
+			}
+		});
+	};
+
+	renderContent = () => this.props.contentView();
+
+	render() {
+		if (Platform.OS === 'ios') {
+			return (
+				<Modal
+					animationType={this.props.animation ? this.props.animation : 'slide'} // 进场动画 fade
+					onRequestClose={() => this.close()}
+					visible={this.state.visible} // 是否可见
+					transparent
+				>
+					<TouchableOpacity style={{ flex: 1 }} activeOpacity={1} onPress={this.close}>
+						<View style={[ styles.container, this.props.customerlayout ]}>{this.renderContent()}</View>
+					</TouchableOpacity>
+				</Modal>
+			);
+		}
+		return (
+			<ModalAndroid
+				style={{ width: 0, height: 0 }} //避免显示空白
+				ref={(modalAndroid) => {
+					this.modalAndroid = modalAndroid;
+				}}
+				visible={[ this.state.visible, this.state.update ]}
+			>
+				<TouchableOpacity activeOpacity={1} onPress={this.close}>
+					<View style={[ styles.container, this.props.customerlayout ]}>{this.renderContent()}</View>
+				</TouchableOpacity>
+			</ModalAndroid>
+		);
+	}
+}
+
+const styles = StyleSheet.create({
+	container: {
+		flex: 1,
+		position: 'absolute',
+		top: 0,
+		bottom: 0,
+		left: 0,
+		right: 0,
+		backgroundColor: 'rgba(0, 0, 0, 0.7)',
+		justifyContent: 'center',
+		alignItems: 'center'
+	}
+});