Bläddra i källkod

[feat]键盘插件,完善拦截器机制,实现登录拦截器

hezihao 8 månader sedan
förälder
incheckning
d043bed465
12 ändrade filer med 167 tillägg och 34 borttagningar
  1. 18 0
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/KeyboardAndroidPlugin.kt
  2. 18 0
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/ComponentConstant.kt
  3. 15 0
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/annotation/Component.kt
  4. 1 1
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/RouteComponent.kt
  5. 0 17
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/interceptor/DefaultRouteInterceptor.kt
  6. 4 1
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/interceptor/IRouteInterceptor.kt
  7. 53 0
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/interceptor/LoginRouteInterceptor.kt
  8. 42 10
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/interceptor/RouteInterceptorManager.kt
  9. 2 2
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/child/impl/ToolBarComponent.kt
  10. 6 0
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/exception/NoLoginException.kt
  11. 3 0
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/page/impl/LoginPageComponent.kt
  12. 5 3
      plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/UserInfoHelper.kt

+ 18 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/KeyboardAndroidPlugin.kt

@@ -2,6 +2,8 @@ package com.atmob.keyboard_android
 
 import android.content.Context
 import android.os.Build
+import com.atmob.keyboard_android.component.base.interceptor.LoginRouteInterceptor
+import com.atmob.keyboard_android.component.base.interceptor.RouteInterceptorManager
 import com.atmob.keyboard_android.floating.FloatingButtonService
 import com.atmob.keyboard_android.util.InputMethodUtil
 import com.atmob.keyboard_android.util.LogUtil
@@ -19,6 +21,22 @@ class KeyboardAndroidPlugin : FlutterPlugin, MethodCallHandler {
 
     private lateinit var context: Context
 
+    companion object {
+        init {
+            // 伴生对象的初始化,相当于Java的静态代码块,只初始化一次
+            initRouteInterceptor()
+        }
+
+        /**
+         * 初始化组件路由拦截器
+         */
+        @JvmStatic
+        private fun initRouteInterceptor() {
+            // 登录拦截器
+            RouteInterceptorManager.registerInterceptor(LoginRouteInterceptor())
+        }
+    }
+
     override fun onAttachedToEngine(flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
         context = flutterPluginBinding.applicationContext
         channel = MethodChannel(flutterPluginBinding.binaryMessenger, "keyboard_android")

+ 18 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/ComponentConstant.kt

@@ -0,0 +1,18 @@
+package com.atmob.keyboard_android.component
+
+/**
+ * 组件常量
+ */
+interface ComponentConstant {
+    companion object {
+        /**
+         * 登录路由
+         */
+        const val ROUTE_LOGIN = "/login"
+
+        /**
+         * 路由白名单
+         */
+        val ROUTE_WHITE_LIST = listOf(ROUTE_LOGIN)
+    }
+}

+ 15 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/annotation/Component.kt

@@ -0,0 +1,15 @@
+package com.atmob.keyboard_android.component.annotation
+
+/**
+ * 组件注解
+ */
+// 该注解只能用于类上
+@Target(AnnotationTarget.CLASS)
+// 保留到运行时,可以通过反射获取
+@Retention(AnnotationRetention.RUNTIME)
+annotation class Component(
+    /**
+     * 组件路由
+     */
+    val route: String
+)

+ 1 - 1
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/RouteComponent.kt

@@ -53,7 +53,7 @@ class RouteComponent @JvmOverloads constructor(
             routeCallback?.onLost()
         } else {
             // 找到目标组件,路由前,执行路由拦截器
-            RouteInterceptorManager.executeInterceptors(object : InterceptorCallback {
+            RouteInterceptorManager.executeInterceptors(targetComponent, object : InterceptorCallback {
                 override fun onContinue() {
                     // 拦截器放行,继续路由
                     routeAction.invoke()

+ 0 - 17
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/interceptor/DefaultRouteInterceptor.kt

@@ -1,17 +0,0 @@
-package com.atmob.keyboard_android.component.base.interceptor
-
-/**
- * 默认拦截器
- */
-class DefaultRouteInterceptor : IRouteInterceptor {
-    override fun onInit() {
-    }
-
-    override fun onUnInit() {
-    }
-
-    override fun doProcess(callback: InterceptorCallback) {
-        // 默认放行
-        callback.onContinue()
-    }
-}

+ 4 - 1
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/interceptor/IRouteInterceptor.kt

@@ -1,5 +1,7 @@
 package com.atmob.keyboard_android.component.base.interceptor
 
+import com.atmob.keyboard_android.component.base.IUIComponent
+
 /**
  * 路由拦截器接口
  */
@@ -17,7 +19,8 @@ interface IRouteInterceptor {
     /**
      * 拦截器的处理方法
      *
+     * @param targetComponent 要路由到的目标组件
      * @param callback 拦截器回调
      */
-    fun doProcess(callback: InterceptorCallback)
+    fun doProcess(targetComponent: IUIComponent, callback: InterceptorCallback)
 }

+ 53 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/interceptor/LoginRouteInterceptor.kt

@@ -0,0 +1,53 @@
+package com.atmob.keyboard_android.component.base.interceptor
+
+import com.atmob.keyboard_android.component.ComponentConstant
+import com.atmob.keyboard_android.component.annotation.Component
+import com.atmob.keyboard_android.component.base.IBusinessComponent
+import com.atmob.keyboard_android.component.base.IUIComponent
+import com.atmob.keyboard_android.component.exception.NoLoginException
+import com.atmob.keyboard_android.util.LogUtil
+import com.atmob.keyboard_android.util.UserInfoHelper
+
+/**
+ * 登录路由拦截器
+ */
+class LoginRouteInterceptor : IRouteInterceptor {
+    override fun onInit() {
+    }
+
+    override fun onUnInit() {
+    }
+
+    override fun doProcess(
+        targetComponent: IUIComponent,
+        callback: InterceptorCallback
+    ) {
+        val componentAnnotation = targetComponent.javaClass.getAnnotation(Component::class.java)
+        if (componentAnnotation != null) {
+            // 路由白名单,则直接放行
+            val routePath = componentAnnotation.route
+            if (ComponentConstant.ROUTE_WHITE_LIST.contains(routePath)) {
+                callback.onContinue()
+                return
+            }
+        }
+        if (targetComponent is IBusinessComponent) {
+            // 判断组件是否需要登录才能路由,如果需要登录,则检查登录状态
+            if (targetComponent.isNeedLogin()) {
+                UserInfoHelper.checkLogin(nextAction = {
+                    LogUtil.d("LoginRouteInterceptor => ${targetComponent.javaClass.name} => 已登录,放行")
+                    // 已登录,放行
+                    callback.onContinue()
+                }, noLoginCallback = {
+                    LogUtil.d("LoginRouteInterceptor => ${targetComponent.javaClass.name} => 未登录,拦截,并跳转到登录页")
+                    // 未登录,拦截路由
+                    callback.onInterrupt(NoLoginException())
+                })
+            } else {
+                LogUtil.d("LoginRouteInterceptor => ${targetComponent.javaClass.name} => 不需要登录,直接放行")
+                // 不需要登录,直接放行
+                callback.onContinue()
+            }
+        }
+    }
+}

+ 42 - 10
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/base/interceptor/RouteInterceptorManager.kt

@@ -1,24 +1,27 @@
 package com.atmob.keyboard_android.component.base.interceptor
 
+import com.atmob.keyboard_android.component.base.IUIComponent
+
 /**
  * 路由拦截器管理器
  */
 class RouteInterceptorManager {
     companion object {
+        /**
+         * 拦截器列表
+         */
         private val interceptors = mutableListOf<IRouteInterceptor>()
 
-        init {
-            interceptors.add(DefaultRouteInterceptor())
-        }
-
         /**
          * 注册,路由拦截器
          *
          * @param interceptor 路由拦截器
          */
         fun registerInterceptor(interceptor: IRouteInterceptor) {
-            interceptors.add(interceptor)
-            interceptor.onInit()
+            if (!interceptors.contains(interceptor)) {
+                interceptors.add(interceptor)
+                interceptor.onInit()
+            }
         }
 
         /**
@@ -33,12 +36,41 @@ class RouteInterceptorManager {
         /**
          * 执行路由拦截器
          *
-         * @param callback 拦截器回调
+         * @param targetComponent 要路由到的目标组件
+         * @param finalCallback 最终拦截器回调
          */
-        fun executeInterceptors(callback: InterceptorCallback) {
-            for (interceptor in interceptors) {
-                interceptor.doProcess(callback)
+        fun executeInterceptors(targetComponent: IUIComponent, finalCallback: InterceptorCallback) {
+            // 没有设置拦截器,直接全部放行
+            if (interceptors.isEmpty()) {
+                finalCallback.onContinue()
+                return
             }
+
+            // 当前遍历到的拦截器的索引
+            var currentIndex = 0
+
+            // 定义一个内部的拦截器,当前拦截器执行放行,则执行下一个拦截器,类似链表
+            val chainCallback = object : InterceptorCallback {
+                override fun onContinue() {
+                    // 当前拦截器放行,累加索引
+                    currentIndex++
+                    // 查找下一个拦截器,继续执行拦截器逻辑
+                    if (currentIndex < interceptors.size) {
+                        interceptors[currentIndex].doProcess(targetComponent, this)
+                    } else {
+                        // 所有拦截器都放行了,执行最终回调
+                        finalCallback.onContinue()
+                    }
+                }
+
+                override fun onInterrupt(error: Throwable) {
+                    // 被拦截器,执行最终回调,通知被拦截了
+                    finalCallback.onInterrupt(error)
+                }
+            }
+
+            // 执行内部的回调,启动第一个拦截器
+            interceptors[currentIndex].doProcess(targetComponent, chainCallback)
         }
     }
 }

+ 2 - 2
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/child/impl/ToolBarComponent.kt

@@ -69,9 +69,9 @@ class ToolBarComponent @JvmOverloads constructor(
         }
         vIntimacyLayout.click {
             // 点击亲密度布局,跳转去亲密度页
-            UserInfoHelper.checkLogin {
+            UserInfoHelper.checkLogin(nextAction = {
                 FlutterBridgeManager.jump2IntimacyPage()
-            }
+            })
         }
 
         setupViewModel()

+ 6 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/exception/NoLoginException.kt

@@ -0,0 +1,6 @@
+package com.atmob.keyboard_android.component.exception
+
+/**
+ * 未登录异常
+ */
+class NoLoginException : RuntimeException()

+ 3 - 0
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/component/page/impl/LoginPageComponent.kt

@@ -4,6 +4,8 @@ import android.content.Context
 import android.util.AttributeSet
 import android.view.View
 import com.atmob.keyboard_android.R
+import com.atmob.keyboard_android.component.ComponentConstant
+import com.atmob.keyboard_android.component.annotation.Component
 import com.atmob.keyboard_android.component.base.BaseUIComponent
 import com.atmob.keyboard_android.component.base.animator.impl.TransitionAnimator
 import com.atmob.keyboard_android.component.page.ILoginPageComponent
@@ -15,6 +17,7 @@ import com.atmob.keyboard_android.util.bridge.FlutterBridgeManager
 /**
  * 登录页组件
  */
+@Component(route = ComponentConstant.ROUTE_LOGIN)
 class LoginPageComponent @JvmOverloads constructor(
     context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
 ) : BaseUIComponent<ILoginPageComponent>(context, attrs, defStyleAttr), ILoginPageComponent {

+ 5 - 3
plugins/keyboard_android/android/src/main/kotlin/com/atmob/keyboard_android/util/UserInfoHelper.kt

@@ -43,7 +43,7 @@ object UserInfoHelper {
     /**
      * 已登录,才允许执行下一步
      */
-    fun checkLogin(nextAction: () -> Unit) {
+    fun checkLogin(nextAction: () -> Unit, noLoginCallback: (() -> Unit)? = null) {
         isLogin {
             // 已登录,直接执行
             if (it) {
@@ -53,6 +53,8 @@ object UserInfoHelper {
                 val keyboardRootComponent =
                     ComponentMediator.findComponent(IKeyboardRootComponent::class.java)
                 keyboardRootComponent?.switchLoginPage()
+                // 回调未登录
+                noLoginCallback?.invoke()
             }
         }
     }
@@ -62,7 +64,7 @@ object UserInfoHelper {
      */
     fun checkVip(nextAction: () -> Unit) {
         // 先检查是否登录
-        checkLogin {
+        checkLogin(nextAction = {
             // 再检查,是否是VIP
             isVip {
                 // 已经是VIP,直接执行
@@ -75,6 +77,6 @@ object UserInfoHelper {
                     keyboardRootComponent?.switchVipPage()
                 }
             }
-        }
+        })
     }
 }