- **创建群聊费用:** - 创建群聊现在会根据后台配置的积分规则扣除相应费用(派币)。 - 在创建页面会显示当前余额和所需费用。 - 创建时会弹出确认弹窗,显示费用、当前余额和扣除后余额。 - 如果余额不足,将无法创建。 - **群聊人数上限:** - 新增创建群聊时的初始成员人数上限,该上限从后台动态获取。 - 在选择成员界面会显示当前已选人数和上限(例如 `5/10`)。 - 如果选择的成员超过上限,会提示错误并且无法创建。 - **后台数据加载:** - 新增了从外部字典表 (`/outside/dict`) 获取配置的接口和逻辑,用于加载积分规则和群聊人数限制。 - App启动时会预加载这些配置,以确保创建群聊时能正确显示费用和人数限制。
282 lines
10 KiB
Kotlin
282 lines
10 KiB
Kotlin
package com.aiosman.ravenow
|
||
|
||
import android.content.Context
|
||
import android.content.Intent
|
||
import android.icu.util.Calendar
|
||
import android.icu.util.TimeZone
|
||
import android.util.Log
|
||
import androidx.compose.runtime.getValue
|
||
import androidx.compose.runtime.mutableStateOf
|
||
import androidx.compose.runtime.setValue
|
||
import com.aiosman.ravenow.data.AccountService
|
||
import com.aiosman.ravenow.data.AccountServiceImpl
|
||
import com.aiosman.ravenow.data.DictService
|
||
import com.aiosman.ravenow.data.DictServiceImpl
|
||
import com.aiosman.ravenow.data.PointService
|
||
import com.aiosman.ravenow.entity.AccountProfileEntity
|
||
import com.aiosman.ravenow.ui.favourite.FavouriteListViewModel
|
||
import com.aiosman.ravenow.ui.favourite.FavouriteNoticeViewModel
|
||
import com.aiosman.ravenow.ui.follower.FollowerNoticeViewModel
|
||
import com.aiosman.ravenow.ui.index.IndexViewModel
|
||
import com.aiosman.ravenow.ui.index.tabs.message.MessageListViewModel
|
||
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.dynamic.DynamicViewModel
|
||
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.expolre.Explore
|
||
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.hot.HotMomentViewModel
|
||
import com.aiosman.ravenow.ui.index.tabs.moment.tabs.timeline.TimelineMomentViewModel
|
||
import com.aiosman.ravenow.ui.index.tabs.profile.MyProfileViewModel
|
||
import com.aiosman.ravenow.ui.account.AccountEditViewModel
|
||
import com.aiosman.ravenow.ui.index.tabs.search.DiscoverViewModel
|
||
import com.aiosman.ravenow.ui.index.tabs.search.SearchViewModel
|
||
import com.aiosman.ravenow.ui.index.tabs.ai.AgentViewModel
|
||
import com.aiosman.ravenow.ui.index.tabs.ai.tabs.mine.MineAgentViewModel
|
||
import com.aiosman.ravenow.ui.like.LikeNoticeViewModel
|
||
import com.aiosman.ravenow.utils.Utils
|
||
import kotlinx.coroutines.CoroutineScope
|
||
import kotlinx.coroutines.launch
|
||
import kotlin.coroutines.suspendCoroutine
|
||
import com.aiosman.ravenow.im.OpenIMManager
|
||
import io.openim.android.sdk.OpenIMClient
|
||
import io.openim.android.sdk.models.InitConfig
|
||
|
||
|
||
object AppState {
|
||
var UserId: Int? = null
|
||
var profile: AccountProfileEntity? = null
|
||
var darkMode by mutableStateOf(false)
|
||
var appTheme by mutableStateOf<AppThemeData>(LightThemeColors())
|
||
var googleClientId: String? = null
|
||
var enableGoogleLogin: Boolean = false
|
||
var enableChat = false
|
||
var agentCreatedSuccess by mutableStateOf(false)
|
||
var chatBackgroundUrl by mutableStateOf<String?>(null)
|
||
suspend fun initWithAccount(scope: CoroutineScope, context: Context) {
|
||
// 如果是游客模式,使用简化的初始化流程
|
||
if (AppStore.isGuest) {
|
||
initWithGuestAccount(scope)
|
||
return
|
||
}
|
||
|
||
val accountService: AccountService = AccountServiceImpl()
|
||
// 获取用户认证信息
|
||
val resp = accountService.getMyAccount()
|
||
// 更新必要的用户信息
|
||
val calendar: Calendar = Calendar.getInstance()
|
||
val tz: TimeZone = calendar.timeZone
|
||
val offsetInMillis: Int = tz.rawOffset
|
||
accountService.updateUserExtra(
|
||
Utils.getCurrentLanguage(),
|
||
// 时区偏移量单位是秒
|
||
offsetInMillis / 1000,
|
||
tz.displayName
|
||
)
|
||
// 设置当前登录用户 ID
|
||
UserId = resp.id
|
||
try {
|
||
var profileResult = accountService.getMyAccountProfile()
|
||
profile = profileResult
|
||
|
||
} catch (e:Exception) {
|
||
Log.e("AppState", "getMyAccountProfile Error:"+ e.message )
|
||
}
|
||
// 获取当前用户资料
|
||
|
||
// 注册 JPush
|
||
Messaging.registerDevice(scope, context)
|
||
initChat(context)
|
||
|
||
// 设置当前用户并刷新积分信息(完成登录态初始化后)
|
||
PointService.setCurrentUser(UserId)
|
||
try {
|
||
PointService.refreshMyPointsBalance()
|
||
} catch (e: Exception) {
|
||
Log.e("AppState", "刷新积分失败: ${e.message}")
|
||
}
|
||
|
||
// 并行加载积分规则和房间规则配置(不阻塞主流程)
|
||
scope.launch {
|
||
try {
|
||
PointService.refreshPointsRules()
|
||
} catch (e: Exception) {
|
||
Log.e("AppState", "加载积分规则失败: ${e.message}")
|
||
}
|
||
}
|
||
scope.launch {
|
||
try {
|
||
PointService.refreshRoomMaxMembers()
|
||
} catch (e: Exception) {
|
||
Log.e("AppState", "加载房间规则失败: ${e.message}")
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 游客模式的简化初始化
|
||
*/
|
||
private fun initWithGuestAccount(scope: CoroutineScope) {
|
||
// 游客模式下,不初始化推送和TRTC
|
||
// 设置默认的用户信息
|
||
UserId = 0
|
||
profile = null
|
||
enableChat = false
|
||
Log.d("AppState", "Guest mode initialized without push notifications and TRTC")
|
||
|
||
// 游客模式下也加载规则配置(用于查看费用信息)
|
||
scope.launch {
|
||
try {
|
||
PointService.refreshPointsRules()
|
||
} catch (e: Exception) {
|
||
Log.e("AppState", "加载积分规则失败: ${e.message}")
|
||
}
|
||
}
|
||
scope.launch {
|
||
try {
|
||
PointService.refreshRoomMaxMembers()
|
||
} catch (e: Exception) {
|
||
Log.e("AppState", "加载房间规则失败: ${e.message}")
|
||
}
|
||
}
|
||
}
|
||
|
||
private suspend fun initChat(context: Context){
|
||
val dictService :DictService = DictServiceImpl()
|
||
val enableItem = dictService.getDictByKey(ConstVars.DICT_KEY_ENABLE_TRTC)
|
||
val isEnableTrtc = enableItem.value as? Boolean
|
||
if (isEnableTrtc != true) {
|
||
enableChat = false
|
||
return
|
||
}
|
||
val accountService: AccountService = AccountServiceImpl()
|
||
|
||
|
||
val initConfig = InitConfig(
|
||
"https://im.ravenow.ai/api",//SDK api地址
|
||
"wss://im.ravenow.ai/msg_gateway",//SDK WebSocket地址
|
||
OpenIMManager.getStorageDir(context),//SDK数据库存储目录
|
||
)
|
||
// initConfig.isLogStandardOutput = true;
|
||
// initConfig.logLevel = 6
|
||
// 使用 OpenIMManager 初始化 SDK
|
||
OpenIMManager.initSDK(context, initConfig)
|
||
|
||
try {
|
||
if (profile?.chatToken != null && profile?.trtcUserId != null) {
|
||
loginToOpenIM(profile!!.trtcUserId, profile!!.chatToken!!)
|
||
}
|
||
|
||
context.startService(Intent(context, OpenIMService::class.java))
|
||
|
||
enableChat = true
|
||
} catch (e: Exception) {
|
||
e.printStackTrace()
|
||
enableChat = false
|
||
}
|
||
}
|
||
|
||
suspend fun loginToOpenIM(userId: String, imToken: String): Boolean {
|
||
return suspendCoroutine { continuation ->
|
||
OpenIMClient.getInstance().login(object : io.openim.android.sdk.listener.OnBase<String> {
|
||
override fun onError(code: Int, error: String?) {
|
||
Log.e("AppState", "OpenIM 登录失败: code=$code, error=$error")
|
||
continuation.resumeWith(Result.failure(Exception("OpenIM Login failed: $code, $error")))
|
||
}
|
||
|
||
override fun onSuccess(data: String?) {
|
||
Log.d("AppState", "OpenIM 登录成功: $data")
|
||
//其他api调用必须保证登录回调成功后操作
|
||
continuation.resumeWith(Result.success(true))
|
||
}
|
||
}, userId, imToken)
|
||
}
|
||
}
|
||
|
||
// suspend fun updateTrtcUserProfile() {
|
||
// val accountService: AccountService = AccountServiceImpl()
|
||
// val profile = accountService.getMyAccountProfile()
|
||
// val info = V2TIMUserFullInfo()
|
||
// info.setNickname(profile.nickName)
|
||
// info.faceUrl = profile.rawAvatar
|
||
// info.selfSignature = profile.bio
|
||
// return suspendCoroutine { continuation ->
|
||
// V2TIMManager.getInstance().setSelfInfo(info, object : V2TIMCallback {
|
||
// override fun onError(code: Int, desc: String?) {
|
||
// continuation.resumeWith(Result.failure(Exception("Update user profile failed: $code, $desc")))
|
||
// }
|
||
//
|
||
// override fun onSuccess() {
|
||
// continuation.resumeWith(Result.success(Unit))
|
||
// }
|
||
// })
|
||
// }
|
||
// }
|
||
|
||
fun switchTheme() {
|
||
darkMode = !darkMode
|
||
appTheme = if (darkMode) {
|
||
DarkThemeColors()
|
||
} else {
|
||
LightThemeColors()
|
||
}
|
||
AppStore.saveDarkMode(darkMode)
|
||
}
|
||
|
||
/**
|
||
* 检查是否是游客模式,并且是否需要登录
|
||
* @return true 如果是游客模式
|
||
*/
|
||
fun isGuestMode(): Boolean {
|
||
return AppStore.isGuest
|
||
}
|
||
|
||
/**
|
||
* 检查游客模式并提示登录
|
||
* @param onGuestMode 当是游客模式时的回调
|
||
* @return true 如果是游客模式
|
||
*/
|
||
fun checkGuestModeAndPromptLogin(onGuestMode: (() -> Unit)? = null): Boolean {
|
||
if (AppStore.isGuest) {
|
||
onGuestMode?.invoke()
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
fun ReloadAppState(context: Context) {
|
||
// 重置动态列表页面
|
||
TimelineMomentViewModel.ResetModel()
|
||
DynamicViewModel.ResetModel()
|
||
HotMomentViewModel.resetModel()
|
||
|
||
// 重置我的页面
|
||
MyProfileViewModel.ResetModel()
|
||
// 重置编辑资料页面 - 暂时注释掉看是否是这里导致的问题
|
||
// AccountEditViewModel.ResetModel()
|
||
// 重置发现页面
|
||
DiscoverViewModel.ResetModel()
|
||
// 重置搜索页面
|
||
SearchViewModel.ResetModel()
|
||
// 重置消息页面
|
||
MessageListViewModel.ResetModel()
|
||
// 重置点赞通知页面
|
||
LikeNoticeViewModel.ResetModel()
|
||
// 重置收藏页面
|
||
FavouriteListViewModel.ResetModel()
|
||
// 重置收藏通知页面
|
||
FavouriteNoticeViewModel.ResetModel()
|
||
// 重置粉丝通知页面
|
||
FollowerNoticeViewModel.ResetModel()
|
||
// 重置关注通知页面
|
||
IndexViewModel.ResetModel()
|
||
// 重置AI Agent相关页面
|
||
AgentViewModel.ResetModel()
|
||
MineAgentViewModel.ResetModel()
|
||
UserId = null
|
||
// 清空积分全局状态,避免用户切换串号
|
||
PointService.clear()
|
||
|
||
// 清除游客状态
|
||
AppStore.isGuest = false
|
||
|
||
context.stopService(Intent(context, OpenIMService::class.java))
|
||
}
|
||
|
||
} |