18034727885
2026-05-09 40a51f28402efe0ed15a42fc7f35d26fb9e24c59
修复问题
4个文件已修改
82 ■■■■■ 已修改文件
app/src/main/java/com/xw/yunwei/ui/user/login/LoginVM.kt 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/xw/yunwei/ui/work/checkInMission/viewmodel/CruiseCheckInViewModel.kt 4 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/xw/yunwei/websocket/WebSocketClient.kt 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/xw/yunwei/websocket/WebSocketConfig.kt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/src/main/java/com/xw/yunwei/ui/user/login/LoginVM.kt
@@ -9,6 +9,7 @@
import com.xw.common.utils.KeyPreferences
import com.xw.common.utils.MMKVManager
import com.xw.common.utils.ToastUtilCommon
import com.xw.yunwei.BuildConfig
import com.xw.yunwei.MyApp
import com.xw.yunwei.R
import com.xw.yunwei.model.AgreeInfo
@@ -32,6 +33,8 @@
    val eyeStatus2 = MutableLiveData(false)
    val protocolStatus = MutableLiveData(false)
    private var loginFailCount = 0
    private var lastFailTime = 0L
    //协议列表
    val agreeList: MutableLiveData<List<AgreeInfo>> = MutableLiveData(mutableListOf<AgreeInfo>())
@@ -94,13 +97,40 @@
            ToastUtilCommon.showError("请输入密码!")
            return
        }
        val psw = psw.value ?: ""
        if (psw.length < 8) {
            ToastUtilCommon.showError("密码长度至少8位!")
            return
        }
        if (!psw.matches(Regex(".*[A-Z].*")) && !BuildConfig.DEBUG) {
            ToastUtilCommon.showError("密码需包含大写字母!")
            return
        }
        if (!psw.matches(Regex(".*[a-z].*")) && !BuildConfig.DEBUG) {
            ToastUtilCommon.showError("密码需包含小写字母!")
            return
        }
        if (!psw.matches(Regex(".*[0-9].*"))) {
            ToastUtilCommon.showError("密码需包含数字!")
            return
        }
        val now = System.currentTimeMillis()
        if (loginFailCount >= 5 && now - lastFailTime < 60_000) {
            ToastUtilCommon.showError("登录失败次数过多,请1分钟后重试")
            return
        }
        launchRequestFlow(
            tips = "登录中...",
            flowBlock = {
                val map =
                    mapOf("phoneNumber" to phone.value, "password" to psw.value, "deviceType" to 1)
                    mapOf("phoneNumber" to phone.value, "password" to psw, "deviceType" to 1)
                userRepository.loginByPassword(map)
            },
            error = { code, msg ->
                ToastUtilCommon.showError(msg)
                loginFailCount++
                lastFailTime = System.currentTimeMillis()
            },
            onCollect = { data ->
                data?.let {
                    Constants.token = it.token?.access_token ?: ""
app/src/main/java/com/xw/yunwei/ui/work/checkInMission/viewmodel/CruiseCheckInViewModel.kt
@@ -102,8 +102,8 @@
            finish()
        } else {
            find?.takeIf {
                it.lon?.toDouble() == endPoint?.coordinate?.latitude &&
                        it.lon?.toDouble() == endPoint?.coordinate?.longitude
                it.lat?.toDoubleOrNull() == endPoint?.coordinate?.latitude &&
                        it.lon?.toDoubleOrNull() == endPoint?.coordinate?.longitude
            }?.also {
                finish()
            }
app/src/main/java/com/xw/yunwei/websocket/WebSocketClient.kt
@@ -18,7 +18,9 @@
import okio.ByteString
import org.json.JSONObject
import java.util.LinkedList
import java.util.concurrent.CopyOnWriteArrayList
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicBoolean
//WebSocket客户端
class WebSocketClient(
@@ -26,15 +28,15 @@
) {
    private var webSocket: WebSocket? = null
    private var okHttpClient: OkHttpClient? = null
    private var isConnecting = false
    private var isConnected = false
    private var isConnecting = AtomicBoolean(false)
    private var isConnected = AtomicBoolean(false)
    private var reconnectCount = 0
    private val gson = Gson()
    private val ioCoroutineScope = CoroutineScope(Dispatchers.IO)
    // 监听器列表
    private val listeners = mutableListOf<IWebSocketListener>()
    private val listeners = CopyOnWriteArrayList<IWebSocketListener>()
    // 心跳相关
    private var heartbeatJob: Job? = null
@@ -81,12 +83,12 @@
     * 连接WebSocket
     */
    fun connect(isFirstConnect: Boolean) {
        if (isConnecting || isConnected) {
        if (isConnecting.get() || isConnected.get()) {
            LogUtils.d(TAG, "WebSocket正在连接或已连接")
            return
        }
        isConnecting = true
        isConnecting.set(true)
        reconnectCount = 0
        ioCoroutineScope.launch {
@@ -101,7 +103,7 @@
                LogUtils.i(TAG, "开始连接WebSocket: ${config.WS_URL}")
            } catch (e: Exception) {
                isConnecting = false
                isConnecting.set(false)
                LogUtils.d(TAG, "连接WebSocket失败: ${e.message}")
                notifyConnectFailed(e)
            }
@@ -116,8 +118,8 @@
            override fun onOpen(webSocket: WebSocket, response: Response) {
                LogUtils.i(TAG, "WebSocket连接成功")
                isConnecting = false
                isConnected = true
                isConnecting.set(false)
                isConnected.set(true)
                reconnectCount = 0
                this@WebSocketClient.webSocket = webSocket
@@ -143,13 +145,13 @@
            override fun onClosing(webSocket: WebSocket, code: Int, reason: String) {
                LogUtils.w(TAG, "WebSocket正在关闭: code=$code, reason=$reason")
                isConnected = false
                isConnected.set(false)
                stopHeartbeat()
            }
            override fun onClosed(webSocket: WebSocket, code: Int, reason: String) {
                LogUtils.w(TAG, "WebSocket已关闭: code=$code, reason=$reason")
                isConnected = false
                isConnected.set(false)
                stopHeartbeat()
                notifyDisconnected(code, reason)
@@ -161,8 +163,8 @@
            override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
                LogUtils.d(TAG, "WebSocket连接失败: ${t.message}")
                isConnecting = false
                isConnected = false
                isConnecting.set(false)
                isConnected.set(false)
                stopHeartbeat()
                notifyConnectFailed(t)
@@ -178,7 +180,7 @@
     * 发送消息
     */
    fun sendMessage(message: String): Boolean {
        return if (isConnected) {
        return if (isConnected.get()) {
            try {
                webSocket?.send(message)
                LogUtils.d(TAG, "发送消息成功: $message")
@@ -257,8 +259,8 @@
        LogUtils.i(TAG, "主动断开WebSocket连接")
        stopHeartbeat()
        isConnecting = false
        isConnected = false
        isConnecting.set(false)
        isConnected.set(false)
        reconnectCount = config.MAX_RECONNECT_COUNT  // 阻止重连
        webSocket?.close(code, reason)
@@ -276,7 +278,7 @@
     * 重新连接
     */
    fun reconnect() {
        if (isConnecting) {
        if (isConnecting.get()) {
            LogUtils.d(TAG, "已经在重连中...")
            return
        }
@@ -317,8 +319,8 @@
     */
    fun getConnectionState(): ConnectionState {
        return when {
            isConnected -> ConnectionState.CONNECTED
            isConnecting -> ConnectionState.CONNECTING
            isConnected.get() -> ConnectionState.CONNECTED
            isConnecting.get() -> ConnectionState.CONNECTING
            else -> ConnectionState.DISCONNECTED
        }
    }
@@ -328,9 +330,9 @@
        stopHeartbeat()
        heartbeatJob = ioCoroutineScope.launch {
            while (isActive && isConnected) {
            while (isActive && isConnected.get()) {
                delay(config.PING_INTERVAL * 1000)
                if (isConnected) {
                if (isConnected.get()) {
                    setAuthMessage()
                    setHeartbeatMessage()
                    setPositionMessage()
@@ -357,7 +359,7 @@
        ioCoroutineScope.launch {
            delay(delay * 1000)
            if (!isConnected && !isConnecting) {
            if (!isConnected.get() && !isConnecting.get()) {
                connect(false)
            }
        }
app/src/main/java/com/xw/yunwei/websocket/WebSocketConfig.kt
@@ -8,5 +8,5 @@
    const val WS_TIMEOUT = 10L  // 连接超时(秒)
    const val PING_INTERVAL = 25L  // 心跳间隔(秒)
    const val RECONNECT_DELAY = 3L  // 重连延迟(秒)
    const val MAX_RECONNECT_COUNT = Int.MAX_VALUE  // 最大重连次数
    const val MAX_RECONNECT_COUNT = 1200  // 最大重连次数
}