1、接入添加小程序支付功能
2、登录逻辑处理
This commit is contained in:
shenzuqiang 2026-03-06 18:26:14 +08:00
parent 3828c73d44
commit 054597ea96
21 changed files with 531 additions and 382 deletions

View File

@ -46,7 +46,7 @@ android {
"GT_INSTALL_CHANNEL" to (project.findProperty("GT_INSTALL_CHANNEL") as? String ?: "GT_INSTALL_CHANNEL") "GT_INSTALL_CHANNEL" to (project.findProperty("GT_INSTALL_CHANNEL") as? String ?: "GT_INSTALL_CHANNEL")
)) ))
ndk { ndk {
abiFilters.addAll(listOf("arm64-v8a", "x86_64")) abiFilters.addAll(listOf("arm64-v8a", "x86_64", "x86", "armeabi-v7a"))
} }
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
@ -74,7 +74,7 @@ android {
manifestPlaceholders.putAll(mapOf( manifestPlaceholders.putAll(mapOf(
"GETUI_APPID" to (project.findProperty("GETUI_APPID") as? String ?: ""), "GETUI_APPID" to (project.findProperty("GETUI_APPID") as? String ?: ""),
"GT_INSTALL_CHANNEL" to "general", "GT_INSTALL_CHANNEL" to "general",
"apk.applicationId" to "com.img.rabbit" "apk.applicationId" to "com.img.rabbit",
)) ))
} }
@ -178,6 +178,7 @@ dependencies {
//noinspection GradleDynamicVersion //noinspection GradleDynamicVersion
api("com.alipay.sdk:alipaysdk-android:+@aar") api("com.alipay.sdk:alipaysdk-android:+@aar")
implementation(libs.wechat.sdk) //微信 implementation(libs.wechat.sdk) //微信
// implementation("com.tencent.mm.opensdk:wechat-sdk-android-without-mta:6.7.9")
//Retrofit 依赖 //Retrofit 依赖
implementation(libs.retrofit) implementation(libs.retrofit)
implementation(libs.retrofit.kotlin.serialization) implementation(libs.retrofit.kotlin.serialization)
@ -211,6 +212,6 @@ dependencies {
implementation(libs.facebook.animated.gif) //必须集成,图片加载需要 implementation(libs.facebook.animated.gif) //必须集成,图片加载需要
implementation(libs.bumptech.glide) //必须集成,图片加载需要 implementation(libs.bumptech.glide) //必须集成,图片加载需要
implementation(libs.androidx.webkit) //4.45版本之后 必须集成,用来支持暗黑模式 implementation(libs.androidx.webkit) //4.45版本之后 必须集成,用来支持暗黑模式
implementation("androidx.legacy:legacy-support-v4:1.0.0") implementation(libs.androidx.legacy.support.v4)
} }

View File

@ -26,6 +26,10 @@
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!--开关wifi状态解决国内机型移动网络权限问题需要--> <!--开关wifi状态解决国内机型移动网络权限问题需要-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--Unimp要求-->
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<!-- 安装应用权限 --> <!-- 安装应用权限 -->
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"
@ -93,11 +97,10 @@
<activity <activity
android:name=".wxapi.WXPayEntryActivity" android:name="com.img.rabbit.wxapi.WXPayEntryActivity"
android:excludeFromRecents="true"
android:exported="true" android:exported="true"
android:launchMode="singleTask" android:launchMode="singleTop"
android:theme="@android:style/Theme.Translucent.NoTitleBar" /> android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
<!--如果是小程序模式,还需要添加这行配置--> <!--如果是小程序模式,还需要添加这行配置-->
@ -146,6 +149,15 @@
android:resource="@xml/dcloud_file_provider" /> android:resource="@xml/dcloud_file_provider" />
</provider> </provider>
<meta-data
android:name="UMENG_CHANNEL"
android:value="${UMENG_CHANNEL}" />
<meta-data
android:name="WX_APPID"
android:value="wx7d1a7d1507482cef" />
<meta-data
android:name="WX_SECRET"
android:value="5264c353296db25405fc29e43c40d3a5" />
</application> </application>
</manifest> </manifest>

View File

@ -72,7 +72,7 @@ class BaseApplication : Application() {
UMConfigure.setLogEnabled(true) UMConfigure.setLogEnabled(true)
PlatformConfig.setFileProvider("${BuildConfig.APPLICATION_ID}.fileprovider") PlatformConfig.setFileProvider("${BuildConfig.APPLICATION_ID}.fileprovider")
PlatformConfig.setWeixin(Constants.WechatAppId, Constants.WechatAppSecret) PlatformConfig.setWeixin(Constants.WxAppId, Constants.WxSecret)
MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO) MobclickAgent.setPageCollectionMode(MobclickAgent.PageMode.AUTO)
UMConfigure.setProcessEvent(true) UMConfigure.setProcessEvent(true)

View File

@ -52,6 +52,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.ExperimentalPermissionsApi
@ -68,9 +69,11 @@ import com.img.rabbit.pages.dialog.UpdateDialog
import com.img.rabbit.provider.storage.GlobalStateManager import com.img.rabbit.provider.storage.GlobalStateManager
import com.img.rabbit.provider.storage.PreferenceUtil import com.img.rabbit.provider.storage.PreferenceUtil
import com.img.rabbit.provider.storage.PreferenceUtil.saveBDVID import com.img.rabbit.provider.storage.PreferenceUtil.saveBDVID
import com.img.rabbit.utils.AppEventBus
import com.img.rabbit.utils.AppUpdate import com.img.rabbit.utils.AppUpdate
import com.img.rabbit.utils.ChannelUtils import com.img.rabbit.utils.ChannelUtils
import com.img.rabbit.utils.FileUtils import com.img.rabbit.utils.FileUtils
import com.img.rabbit.utils.LoginBindEvent
import com.img.rabbit.utils.UniAppUtils import com.img.rabbit.utils.UniAppUtils
import com.img.rabbit.utils.UniMpUpdate import com.img.rabbit.utils.UniMpUpdate
import com.img.rabbit.utils.UpdateUtils import com.img.rabbit.utils.UpdateUtils
@ -87,6 +90,7 @@ import kotlinx.coroutines.launch
import kotlin.system.exitProcess import kotlin.system.exitProcess
class MainActivity : ComponentActivity(), LoadingCallback { class MainActivity : ComponentActivity(), LoadingCallback {
private lateinit var generalViewModel: GeneralViewModel
@OptIn(DelicateCoroutinesApi::class, ExperimentalPermissionsApi::class) @OptIn(DelicateCoroutinesApi::class, ExperimentalPermissionsApi::class)
@SuppressLint("UnrememberedMutableState", "CoroutineCreationDuringComposition") @SuppressLint("UnrememberedMutableState", "CoroutineCreationDuringComposition")
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -101,13 +105,11 @@ class MainActivity : ComponentActivity(), LoadingCallback {
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
val splashViewModel: SplashViewModel = viewModel() val splashViewModel: SplashViewModel = viewModel()
val generalViewModel: GeneralViewModel = viewModel() generalViewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory.getInstance(application))[GeneralViewModel::class.java]
var loginViewModel: LoginViewModel = viewModel() var loginViewModel: LoginViewModel = viewModel()
val context = LocalContext.current val context = LocalContext.current
var showSplash by remember { mutableStateOf(false) } var showSplash by remember { mutableStateOf(false) }
var globalLogin by mutableStateOf(GlobalStateManager(context).globalLoginNotifyFlow().collectAsState(initial = false))
var globalLogout by mutableStateOf(GlobalStateManager(context).globalLogoutNotifyFlow().collectAsState(initial = false))
var globalBind by mutableStateOf(GlobalStateManager(context).globalBindNotifyFlow().collectAsState(initial = false)) var globalBind by mutableStateOf(GlobalStateManager(context).globalBindNotifyFlow().collectAsState(initial = false))
var globalUnBind by mutableStateOf(GlobalStateManager(context).globalUnBindNotifyFlow().collectAsState(initial = false)) var globalUnBind by mutableStateOf(GlobalStateManager(context).globalUnBindNotifyFlow().collectAsState(initial = false))
var globalUpdate by mutableStateOf(GlobalStateManager(context).globalUpdateNotifyFlow().collectAsState(initial = false)) var globalUpdate by mutableStateOf(GlobalStateManager(context).globalUpdateNotifyFlow().collectAsState(initial = false))
@ -131,34 +133,19 @@ class MainActivity : ComponentActivity(), LoadingCallback {
} }
} }
LaunchedEffect(loginViewModel.userConfigResult.value) {
if (loginViewModel.userConfigResult.value != null){
// 用户配置信息获取成功
loginViewModel.requestUserInfo()
loginViewModel.userConfigResult.value = null
}
}
// 设置启动页显示条件 // 设置启动页显示条件
splashScreen.setKeepOnScreenCondition { splashScreen.setKeepOnScreenCondition {
splashViewModel.isLoading.value // 当为 true 时,启动页不消失 splashViewModel.isLoading.value // 当为 true 时,启动页不消失
} }
//更新用户配置与用户信息
if(globalLogin.value == true || globalBind.value == true || globalUnBind.value == true || globalLogout.value == true){
loginViewModel.requestUserConfig()
loginViewModel.requestUserInfo()
}
// 登录成功后2秒后自动更新状态
if(globalLogin.value == true){
GlobalScope.launch {
//延迟2秒方便处理多有事件都收到通知
delay(2*1000)
GlobalStateManager(context).storeGlobalLoginNotify(false)
}
}
// 退出成功后2秒后自动更新状态
if(globalLogout.value == true){
GlobalScope.launch {
//延迟2秒方便处理多有事件都收到通知
delay(2*1000)
GlobalStateManager(context).storeGlobalLogoutNotify(false)
}
}
// 绑定成功后2秒后自动更新状态 // 绑定成功后2秒后自动更新状态
if(globalBind.value == true){ if(globalBind.value == true){
@ -178,6 +165,24 @@ class MainActivity : ComponentActivity(), LoadingCallback {
} }
} }
// 处理全局事件类似与EventBus订阅
LaunchedEffect(Unit) {
AppEventBus.events.collect { event ->
when (event) {
is LoginBindEvent.Login -> {
Log.i("AppEventBus","--------------登录成功,开始获取配置和个人数据")
if(!event.isLogin){
loginViewModel.reset()
}
loginViewModel.requestUserConfig()
}
is LoginBindEvent.Bind -> {
loginViewModel.requestUserConfig()
}
}
}
}
AppTheme { AppTheme {
SplashScreenContent{ SplashScreenContent{
//未同意提示政策弹窗 //未同意提示政策弹窗
@ -201,17 +206,16 @@ class MainActivity : ComponentActivity(), LoadingCallback {
showSplash = true showSplash = true
} }
if(showSplash || globalLogout.value == true){ if(showSplash){ //|| globalLogout.value == true){
// 全局注销,重新登录 // 全局注销,重新登录
if(globalLogout.value == true){ // if(globalLogout.value == true){
loginViewModel = viewModel() // loginViewModel = viewModel()
loginViewModel.requestUserConfig() // loginViewModel.requestUserConfig()
//loginViewModel.initWXApi(this) // }
}
val token = PreferenceUtil.getAccessToken() val token = PreferenceUtil.getAccessToken()
// 未登录,显示登录页 // 未登录,显示登录页
if (token.isNullOrEmpty() && !loginViewModel.isLogin.value) { if (token.isNullOrEmpty() && loginViewModel.userConfigResult.value == null) {
// 同意隐私协议政策,检验是否有一键登录权限 // 同意隐私协议政策,检验是否有一键登录权限
loginViewModel.oneKeyLoginForGeTuiSdk(context as Activity) { isAllowShowOneKeyScreen -> loginViewModel.oneKeyLoginForGeTuiSdk(context as Activity) { isAllowShowOneKeyScreen ->
if (isAllowShowOneKeyScreen) { if (isAllowShowOneKeyScreen) {

View File

@ -8,8 +8,8 @@ object Constants {
const val privacyUrl = "https://jitutu.batiao8.com/static/policy-jietutu/privacy-ios.html"//隐私政策 const val privacyUrl = "https://jitutu.batiao8.com/static/policy-jietutu/privacy-ios.html"//隐私政策
//const val getuiAppId = "40qbPjPkYs7TnVAYCX0Ig6"//个推appid (gradle.properties) //const val getuiAppId = "40qbPjPkYs7TnVAYCX0Ig6"//个推appid (gradle.properties)
const val WechatAppId = "wx7d1a7d1507482cef"// 微信APPID const val WxAppId = "wx7d1a7d1507482cef"// 微信APPID
const val WechatAppSecret = ""//微信secret const val WxSecret = "5264c353296db25405fc29e43c40d3a5"//微信secret
const val UmengAppkey = "69a641119a7f3764887cd287"// 友盟appKey const val UmengAppkey = "69a641119a7f3764887cd287"// 友盟appKey
const val AppId = ""//appid const val AppId = ""//appid

View File

@ -72,14 +72,14 @@ import com.g.gysdk.EloginActivityParam
import com.g.gysdk.GYManager import com.g.gysdk.GYManager
import com.g.gysdk.GYResponse import com.g.gysdk.GYResponse
import com.g.gysdk.GyCallBack import com.g.gysdk.GyCallBack
import com.img.rabbit.bean.local.toAlipayResult
import com.img.rabbit.config.Constants.agreementUrl import com.img.rabbit.config.Constants.agreementUrl
import com.img.rabbit.config.Constants.privacyUrl import com.img.rabbit.config.Constants.privacyUrl
import com.img.rabbit.pages.toolbar.TitleBar import com.img.rabbit.pages.toolbar.TitleBar
import com.img.rabbit.provider.storage.GlobalStateManager
import com.img.rabbit.provider.storage.PreferenceUtil import com.img.rabbit.provider.storage.PreferenceUtil
import com.img.rabbit.utils.StringUtils import com.img.rabbit.utils.AppEventBus
import com.img.rabbit.utils.LoginBindEvent
import com.img.rabbit.utils.UrlLinkUtils.openAgreement import com.img.rabbit.utils.UrlLinkUtils.openAgreement
import com.img.rabbit.utils.WXAuthEvent
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import org.json.JSONObject import org.json.JSONObject
@ -101,63 +101,35 @@ fun LoginScreen(navController: NavHostController? = null, generalViewModel: Gene
} }
} }
//关于登录的事件监听
LaunchedEffect(Unit) {
AppEventBus.events.collect { event ->
when (event) {
//微信授权结果authType=0 ---->拿着Code登录
is WXAuthEvent.AuthResult -> {
if(loginViewModel.isLoginWxAuthor){
loginViewModel.requestWxLogin(event.code)
loginViewModel.isLoginWxAuthor = false
}
}
}
}
}
// 登录成功后,保存 token // 登录成功后,保存 token
LaunchedEffect(loginViewModel.loginState.value) { LaunchedEffect(loginViewModel.loginResult.value) {
if (loginViewModel.loginState.value !=null && loginViewModel.loginState.value?.data?.token != null) { if (loginViewModel.loginResult.value?.data?.token?.isNotEmpty() == true) {
//登录成功 val loginInfo = loginViewModel.loginResult.value?.data
PreferenceUtil.saveAccessToken(loginViewModel.loginState.value?.data?.token) AppEventBus.post( LoginBindEvent.Login(userId = loginInfo?.user_id?:"", loginType = PreferenceUtil.getLoginType(), isLogin = true, data = loginInfo) )
Toast.makeText(context, "登录成功", Toast.LENGTH_SHORT).show() //提示登录成功
loginViewModel.setLogin(true)
//更新登录状态
GlobalStateManager(context).storeGlobalLoginNotify(true)
//清理loginState
loginViewModel.loginState.value = null
//提示登录成功
Toast.makeText(context, "登录成功", Toast.LENGTH_SHORT).show()
// 当允许返回上一页时,登录成功后,返回上一页
if(isVisibilityBreak){ if(isVisibilityBreak){
navController?.popBackStack() navController?.popBackStack() // 当允许返回上一页时,登录成功后,返回上一页
} }
}else if(loginViewModel.loginState.value !=null && loginViewModel.loginState.value?.data?.token == null){ loginViewModel.loginResult.value = null //清理loginState
//登录失败 }else if(loginViewModel.loginResult.value != null && loginViewModel.loginResult.value?.data?.token == null){
loginViewModel.setLogin(false) // loginViewModel.setLogin(false) //登录失败
Log.w("LoginScreen","登录失败,无有效的Token") Log.w("LoginScreen","登录失败,无有效的Token")
Toast.makeText(context, "登录失败,请重新登录", Toast.LENGTH_SHORT).show() Toast.makeText(context, "登录失败,请重新登录", Toast.LENGTH_SHORT).show()//提示登录成功
}
}
var globalWxAuthorization by mutableStateOf(GlobalStateManager(context).globalWxAuthorizationFlow().collectAsState(initial = ""))
LaunchedEffect(globalWxAuthorization.value) {
if(globalWxAuthorization.value?.isNotEmpty() == true){
loginViewModel.requestWxLogin(globalWxAuthorization.value!!)
//清理globalWxAuthorization
GlobalStateManager(context).storeGlobalWxAuthorization("")
}
}
LaunchedEffect(loginViewModel.authInfoForAlipay.value) {
if(loginViewModel.authInfoForAlipay.value.isEmpty()) return@LaunchedEffect
loginViewModel.loginWithAliPay(context){rawResult ->
Log.i("loginWithAliPay", "支付宝登录结果:$rawResult")
val alipayResult = rawResult.toAlipayResult()
// 处理支付宝登录结果
when (alipayResult.resultStatus) {
"9000" -> {
// 登录成功result 字段中包含 auth_code
val authCode = StringUtils.parseAlipayResult(alipayResult.result ?: "")["auth_code"] ?: ""
loginViewModel.requestAlipayLogin(authCode)
}
"6001" -> {
"用户取消登录"
}
else -> {
alipayResult.memo ?: "登录失败"
}
}
//清理authInfoForAlipay
loginViewModel.authInfoForAlipay.value = ""
} }
} }
@ -673,7 +645,7 @@ private fun OneKeyLoginScreen(context: Context, viewModel: LoginViewModel, gener
"天翼账号提供认证服务" "天翼账号提供认证服务"
} }
"CU" -> {//联通 "CU" -> {//联通
"联通账号提供认证服务" "认证服务由联通统一认证提供"
} }
else -> {//移动 else -> {//移动
"移动账号提供认证服务" "移动账号提供认证服务"
@ -688,7 +660,6 @@ private fun OneKeyLoginScreen(context: Context, viewModel: LoginViewModel, gener
} }
val agreementTextView = view.findViewById<TextView>(R.id.layout_one_key_login_agreement_tv) val agreementTextView = view.findViewById<TextView>(R.id.layout_one_key_login_agreement_tv)
//TODO 服务协议,如:“登录即认可《天翼账号服务与隐私协议》、《用户协议》和《隐私政策》并使用本机号码登录”
val targets = mapOf( val targets = mapOf(
"serviceAgreement" to privacyName, "serviceAgreement" to privacyName,
@ -705,18 +676,28 @@ private fun OneKeyLoginScreen(context: Context, viewModel: LoginViewModel, gener
} }
val loginButton = view.findViewById<TextView>(R.id.layout_one_key_login_btn) val loginButton = view.findViewById<TextView>(R.id.layout_one_key_login_btn)
loginButton.setOnClickListener { // 处理登录点击
// 处理登录点击 oneKeyLogin(
oneKeyLogin( context = context,
context = context, numberTv = phoneTextView,
numberTv = phoneTextView, sloganTv = serviceTextView,
sloganTv = serviceTextView, loginBtn = loginButton,
loginBtn = loginButton, checkBox = checkbox,
checkBox = checkbox, privacyTv = agreementTextView,
privacyTv = agreementTextView, viewModel = viewModel
viewModel = viewModel )
) // loginButton.setOnClickListener {
} // // 处理登录点击
// oneKeyLogin(
// context = context,
// numberTv = phoneTextView,
// sloganTv = serviceTextView,
// loginBtn = loginButton,
// checkBox = checkbox,
// privacyTv = agreementTextView,
// viewModel = viewModel
// )
// }
} }
) )
} }
@ -776,7 +757,7 @@ private fun WxLoginScreen(
// 启动微信验证,请求登录 // 启动微信验证,请求登录
if (viewModel.isPolicyAgreement.value) { if (viewModel.isPolicyAgreement.value) {
//打开微信登录 //打开微信登录
viewModel.loginWithWechat(context, generalViewModel.api) viewModel.authorWechat(context, generalViewModel.api)
} else { } else {
Toast.makeText( Toast.makeText(
context, context,
@ -951,7 +932,7 @@ private fun AliPayLoginScreen(
// 启动支付宝验证,请求登录 // 启动支付宝验证,请求登录
if (viewModel.isPolicyAgreement.value) { if (viewModel.isPolicyAgreement.value) {
// 打开支付宝登录 // 打开支付宝登录
viewModel.requestAliPayAuthParam() viewModel.requestAliPayAuthParam(context)
} else { } else {
Toast.makeText( Toast.makeText(
context, context,
@ -1395,27 +1376,10 @@ private fun oneKeyLogin(
privacyTv: TextView, privacyTv: TextView,
viewModel: LoginViewModel, viewModel: LoginViewModel,
) { ) {
val eloginActivityParam = EloginActivityParam() val gyCallBack = object : GyCallBack {
.setActivity(context as Activity)
.setNumberTextview(numberTv)
.setSloganTextview(sloganTv)
.setLoginButton(loginBtn)
.setPrivacyCheckbox(checkBox)
.setPrivacyTextview(privacyTv)
.setUiErrorListener { msg -> //隐私协议未打勾、界面不合规、setLoginOnClickListener抛出异常等情况下的回调
Log.e("OneKeyLogin", "UIErrorListener.onError:$msg")
}
.setLoginOnClickListener {
if (!checkBox.isChecked) {
// 抛出异常避免sdk进行后续登录动作否则eAccountLogin会回调onFailed错误
throw IllegalStateException("请先仔细阅读协议并勾选,然后再点击登录")
}
//启动登录时候的转圈圈
}
GYManager.getInstance().eAccountLogin(eloginActivityParam, 5000, object : GyCallBack {
override fun onSuccess(response: GYResponse?) { override fun onSuccess(response: GYResponse?) {
// 登录成功,需要与后端交互 loginBtn.isEnabled = true
Log.i("OneKeyLogin", "onSuccess:$response") Log.i("OneKeyLogin", "OneKeyLoginViewModel------onSuccess:$response")
try { try {
val jsonObject = JSONObject(response?.msg?:"{}") val jsonObject = JSONObject(response?.msg?:"{}")
val data = jsonObject.getJSONObject("data") val data = jsonObject.getJSONObject("data")
@ -1427,12 +1391,32 @@ private fun oneKeyLogin(
} }
override fun onFailed(p0: GYResponse?) { override fun onFailed(p0: GYResponse?) {
// 登录失败 loginBtn.isEnabled = true
Log.e("OneKeyLogin", "onFailed:$p0") Log.e("OneKeyLogin", "OneKeyLoginViewModel------onFailed:$p0")
} }
}) }
}
val eloginActivityParam = EloginActivityParam()
.setActivity(context as Activity)
.setNumberTextview(numberTv)
.setSloganTextview(sloganTv)
.setLoginButton(loginBtn)
.setPrivacyCheckbox(checkBox)
.setPrivacyTextview(privacyTv)
.setUiErrorListener { msg ->
loginBtn.isEnabled = true
Log.e("OneKeyLogin", "OneKeyLoginViewModel------UIErrorListener.onError:$msg")
}
.setLoginOnClickListener {
if (!checkBox.isChecked) {
throw IllegalStateException("请先仔细阅读协议并勾选,然后再点击登录")
}
loginBtn.isEnabled = false
}
// 预先注册登录回调
GYManager.getInstance().eAccountLogin(eloginActivityParam, 5000, gyCallBack)
}
enum class LoginScreenType { enum class LoginScreenType {
LOGIN_NORMAL, LOGIN_NORMAL,

View File

@ -58,8 +58,10 @@ import com.img.rabbit.pages.LoadingCallback
import com.img.rabbit.provider.storage.GlobalStateManager import com.img.rabbit.provider.storage.GlobalStateManager
import com.img.rabbit.provider.storage.PreferenceUtil import com.img.rabbit.provider.storage.PreferenceUtil
import com.img.rabbit.route.ScreenRoute import com.img.rabbit.route.ScreenRoute
import com.img.rabbit.utils.AppEventBus
import com.img.rabbit.utils.UniAppUtils import com.img.rabbit.utils.UniAppUtils
import com.img.rabbit.utils.UniMpUpdate import com.img.rabbit.utils.UniMpUpdate
import com.img.rabbit.utils.UniMpWXPayEvent
import com.img.rabbit.viewmodel.GeneralViewModel import com.img.rabbit.viewmodel.GeneralViewModel
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -103,6 +105,15 @@ fun HomeScreen(
} }
} }
LaunchedEffect(Unit) {
AppEventBus.events.collect { event ->
when (event) {
is UniMpWXPayEvent.PayResult -> {
Log.i("HomeScreen", "HomeScreen----->PayResult: ${event.code}")
}
}
}
}
var homeIconConfig by remember { mutableStateOf(PreferenceUtil.getUserConfig()?.config?.homeIconEntity) } var homeIconConfig by remember { mutableStateOf(PreferenceUtil.getUserConfig()?.config?.homeIconEntity) }
var uniVersionConfig by remember { mutableStateOf(PreferenceUtil.getUserConfig()?.config?.uniVersionEntity) } var uniVersionConfig by remember { mutableStateOf(PreferenceUtil.getUserConfig()?.config?.uniVersionEntity) }

View File

@ -72,7 +72,7 @@ fun MineScreen(
val TAG = "Rabbit_Mine" val TAG = "Rabbit_Mine"
val context = LocalContext.current val context = LocalContext.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
var globalLogin by mutableStateOf(GlobalStateManager(context).globalLoginNotifyFlow().collectAsState(initial = false)) // var globalLogin by mutableStateOf(GlobalStateManager(context).globalLoginNotifyFlow().collectAsState(initial = false))
var globalBind by mutableStateOf(GlobalStateManager(context).globalBindNotifyFlow().collectAsState(initial = false)) var globalBind by mutableStateOf(GlobalStateManager(context).globalBindNotifyFlow().collectAsState(initial = false))
var globalUnBind by mutableStateOf(GlobalStateManager(context).globalUnBindNotifyFlow().collectAsState(initial = false)) var globalUnBind by mutableStateOf(GlobalStateManager(context).globalUnBindNotifyFlow().collectAsState(initial = false))
@ -105,7 +105,8 @@ fun MineScreen(
} }
//刷新用户信息 //刷新用户信息
if(globalLogin.value == true || globalBind.value == true || globalUnBind.value == true){ // if(globalLogin.value == true || globalBind.value == true || globalUnBind.value == true){
if(globalBind.value == true || globalUnBind.value == true){
scope.launch { scope.launch {
delay(300) delay(300)
userInfo = PreferenceUtil.getUserInfo() userInfo = PreferenceUtil.getUserInfo()

View File

@ -1,6 +1,7 @@
package com.img.rabbit.pages.screen.mine package com.img.rabbit.pages.screen.mine
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.util.Log
import androidx.compose.foundation.Image import androidx.compose.foundation.Image
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
@ -44,44 +45,23 @@ import androidx.navigation.compose.rememberNavController
import com.img.rabbit.R import com.img.rabbit.R
import com.img.rabbit.pages.toolbar.TitleBar import com.img.rabbit.pages.toolbar.TitleBar
import com.img.rabbit.provider.storage.GlobalStateManager import com.img.rabbit.provider.storage.GlobalStateManager
import com.img.rabbit.provider.storage.PreferenceUtil
import com.img.rabbit.utils.AppDataStoreUtils import com.img.rabbit.utils.AppDataStoreUtils
import com.img.rabbit.utils.AppEventBus
import com.img.rabbit.utils.LoginBindEvent
import com.img.rabbit.viewmodel.LoginViewModel import com.img.rabbit.viewmodel.LoginViewModel
@SuppressLint("UnrememberedMutableState") @SuppressLint("UnrememberedMutableState")
@Composable @Composable
fun SettingScreen(navController: NavHostController, loginViewModel: LoginViewModel) { fun SettingScreen(navController: NavHostController, loginViewModel: LoginViewModel) {
val context = LocalContext.current val context = LocalContext.current
var globalLogin by mutableStateOf(GlobalStateManager(context).globalLoginNotifyFlow().collectAsState(initial = false))
var cacheDataSize by remember { mutableStateOf("正在计算...") } var cacheDataSize by remember { mutableStateOf("正在计算...") }
/*
LaunchedEffect(loginViewModel.logoutState.value) {
if(loginViewModel.logoutState.value?.status == true){
// 执行用户数据清除
PreferenceUtil.clearLogin()
loginViewModel.setLogin(false)
// 跳转登录页面
loginViewModel.restViewModel.intValue = 1
loginViewModel.logoutState.value = null
loginViewModel.loginScreenType.value = LoginScreenType.LOGIN_NORMAL
navController.navigate("login?type=${LoginViewModel.JumpLoginType.FROM_LOGOUT.type}") {
// 清除所有页面,包括登录页
popUpTo(navController.graph.startDestinationId) { inclusive = true }
}
}
}
*/
LaunchedEffect(Unit) { LaunchedEffect(Unit) {
AppDataStoreUtils.getAppStorageStats(context){ _, _, _, totalDataCacheSize -> AppDataStoreUtils.getAppStorageStats(context){ _, _, _, totalDataCacheSize ->
cacheDataSize = totalDataCacheSize cacheDataSize = totalDataCacheSize
} }
} }
if(globalLogin.value == true){
navController.popBackStack()
}
Scaffold{ Scaffold{
@ -289,71 +269,73 @@ fun SettingScreen(navController: NavHostController, loginViewModel: LoginViewMod
} }
} }
//切换/退出账号 if(PreferenceUtil.getUserConfig()?.temp == false){
Column( //切换/退出账号
modifier = Modifier.fillMaxWidth().align(Alignment.BottomCenter) Column(
) { modifier = Modifier.fillMaxWidth().align(Alignment.BottomCenter)
//账号切换
Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(start = 33.dp, end = 33.dp, bottom = 18.dp)
.background(
Color(0x00000000),
shape = RoundedCornerShape(359.dp),
)
.border(width = 1.dp, color = Color(0xFF000000), shape = RoundedCornerShape(359.dp))
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }
) {
//TODO 账号切换
navController.navigate("managerAccount")
}
) { ) {
Text( //账号切换
"账号切换", Box(
color = Color(0xFF1A1A1A),
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier modifier = Modifier
.wrapContentWidth() .fillMaxWidth()
.wrapContentHeight() .wrapContentHeight()
.padding(vertical = 12.dp) .padding(start = 33.dp, end = 33.dp, bottom = 18.dp)
.align(Alignment.Center) .background(
) Color(0x00000000),
} shape = RoundedCornerShape(359.dp),
)
.border(width = 1.dp, color = Color(0xFF000000), shape = RoundedCornerShape(359.dp))
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }
) {
// 账号切换
navController.navigate("managerAccount")
}
) {
Text(
"账号切换",
color = Color(0xFF1A1A1A),
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight()
.padding(vertical = 12.dp)
.align(Alignment.Center)
)
}
//退出登录 //退出登录
Box( Box(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(start = 33.dp, end = 33.dp, bottom = 30.dp)
.background(
Color(0xFF252525),
shape = RoundedCornerShape(359.dp),
)
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }
) {
// 退出登录
loginViewModel.requestLogout(context)
}
) {
Text(
"退出登录",
color = Color(0xFFC2FF43),
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier modifier = Modifier
.wrapContentWidth() .fillMaxWidth()
.wrapContentHeight() .wrapContentHeight()
.padding(vertical = 12.dp) .padding(start = 33.dp, end = 33.dp, bottom = 30.dp)
.align(Alignment.Center) .background(
) Color(0xFF252525),
shape = RoundedCornerShape(359.dp),
)
.clickable(
indication = null,
interactionSource = remember { MutableInteractionSource() }
) {
// 退出登录
loginViewModel.requestLogout(context)
}
) {
Text(
"退出登录",
color = Color(0xFFC2FF43),
fontSize = 16.sp,
fontWeight = FontWeight.Bold,
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight()
.padding(vertical = 12.dp)
.align(Alignment.Center)
)
}
} }
} }
} }

View File

@ -23,7 +23,6 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -50,16 +49,17 @@ import com.img.rabbit.R
import com.img.rabbit.bean.response.UserInfoEntity import com.img.rabbit.bean.response.UserInfoEntity
import com.img.rabbit.pages.dialog.TipsDialog import com.img.rabbit.pages.dialog.TipsDialog
import com.img.rabbit.pages.toolbar.TitleBar import com.img.rabbit.pages.toolbar.TitleBar
import com.img.rabbit.provider.storage.GlobalStateManager
import com.img.rabbit.provider.storage.PreferenceUtil import com.img.rabbit.provider.storage.PreferenceUtil
import com.img.rabbit.utils.AppEventBus
import com.img.rabbit.utils.LoginBindEvent
import com.img.rabbit.viewmodel.AccountManagerViewModel import com.img.rabbit.viewmodel.AccountManagerViewModel
import com.img.rabbit.viewmodel.LoginViewModel import com.img.rabbit.viewmodel.LoginViewModel
import kotlinx.coroutines.delay
@SuppressLint("UnrememberedMutableState") @SuppressLint("UnrememberedMutableState")
@Composable @Composable
fun AccountManagerScreen(navController: NavHostController, viewModel: AccountManagerViewModel = viewModel(), loginViewModel: LoginViewModel) { fun AccountManagerScreen(navController: NavHostController, viewModel: AccountManagerViewModel = viewModel(), loginViewModel: LoginViewModel) {
val context = LocalContext.current val context = LocalContext.current
var globalLogin by mutableStateOf(GlobalStateManager(context).globalLoginNotifyFlow().collectAsState(initial = false))
var showDialogStatus by mutableStateOf(false) var showDialogStatus by mutableStateOf(false)
var selectedUserInfo by mutableStateOf<UserInfoEntity?>(null) var selectedUserInfo by mutableStateOf<UserInfoEntity?>(null)
@ -69,23 +69,19 @@ fun AccountManagerScreen(navController: NavHostController, viewModel: AccountMan
viewModel.requestAccount() viewModel.requestAccount()
} }
if(globalLogin.value == true){
viewModel.requestAccount()
}
LaunchedEffect(viewModel.switchState.value) { LaunchedEffect(viewModel.switchState.value) {
if (viewModel.switchState.value != null && viewModel.switchState.value?.data?.token != null) { if (viewModel.switchState.value != null && viewModel.switchState.value?.data?.token != null) {
// 切换账号成功 val loginInfo = viewModel.switchState.value?.data
PreferenceUtil.saveLoginType(null)
loginInfo?.let { PreferenceUtil.saveLoginInfo(it) }
PreferenceUtil.saveAccessToken(viewModel.switchState.value?.data?.token) PreferenceUtil.saveAccessToken(viewModel.switchState.value?.data?.token)
AppEventBus.post( LoginBindEvent.Login(userId = loginInfo?.user_id?:"", loginType = null, isLogin = true, data = loginInfo) )
loginViewModel.setLogin(true)
//更新登录状态
GlobalStateManager(context).storeGlobalLoginNotify(true)
//清理loginState
loginViewModel.loginState.value = null
Toast.makeText(context, "切换账号成功!", Toast.LENGTH_SHORT).show() Toast.makeText(context, "切换账号成功!", Toast.LENGTH_SHORT).show()
navController.popBackStack() //延迟执行,确保返回时,接口已经拿到最新的用户信息
delay(500)
navController.popBackStack(route = "setting", inclusive = true)
viewModel.switchState.value = null
} }
} }
LaunchedEffect(viewModel.errorState.value) { LaunchedEffect(viewModel.errorState.value) {

View File

@ -73,7 +73,10 @@ import com.img.rabbit.pages.NetworkDisconnectedPage
import com.img.rabbit.pages.toolbar.TitleBar import com.img.rabbit.pages.toolbar.TitleBar
import com.img.rabbit.provider.storage.GlobalStateManager import com.img.rabbit.provider.storage.GlobalStateManager
import com.img.rabbit.utils.AgreementTextHelper import com.img.rabbit.utils.AgreementTextHelper
import com.img.rabbit.utils.AppEventBus
import com.img.rabbit.utils.LoginBindEvent
import com.img.rabbit.utils.UrlLinkUtils.openAgreement import com.img.rabbit.utils.UrlLinkUtils.openAgreement
import com.img.rabbit.utils.WXAuthEvent
import com.img.rabbit.viewmodel.BindViewModel import com.img.rabbit.viewmodel.BindViewModel
import com.img.rabbit.viewmodel.GeneralViewModel import com.img.rabbit.viewmodel.GeneralViewModel
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@ -96,12 +99,18 @@ fun BindScreen(navController: NavHostController, viewModel: BindViewModel = view
} }
} }
var globalWxAuthorization by mutableStateOf(GlobalStateManager(context).globalWxAuthorizationFlow().collectAsState(initial = "")) //关于绑定授权的事件监听
LaunchedEffect(globalWxAuthorization.value) { LaunchedEffect(Unit) {
if(globalWxAuthorization.value?.isNotEmpty() == true){ AppEventBus.events.collect { event ->
viewModel.requestWxBind(globalWxAuthorization.value!!) when (event) {
//清理globalWxAuthorization //微信授权结果authType=1 ---->拿着Code登录
GlobalStateManager(context).storeGlobalWxAuthorization("") is WXAuthEvent.AuthResult -> {
if(viewModel.isBindWxAuthor){
viewModel.requestWxBind(event.code)
viewModel.isBindWxAuthor = false
}
}
}
} }
} }

View File

@ -20,9 +20,6 @@ class GlobalStateManager(
) { ) {
companion object { companion object {
private val GLOBAL_LOADING = booleanPreferencesKey("global_loading") private val GLOBAL_LOADING = booleanPreferencesKey("global_loading")
private val GLOBAL_WX_AUTHORIZATION = stringPreferencesKey("global_wx_authorization")
private val GLOBAL_LOGIN_NOTIFY = booleanPreferencesKey("global_login_notify")
private val GLOBAL_LOGOUT_NOTIFY = booleanPreferencesKey("global_logout_notify")
private val GLOBAL_BIND_NOTIFY = booleanPreferencesKey("global_bind_notify") private val GLOBAL_BIND_NOTIFY = booleanPreferencesKey("global_bind_notify")
private val GLOBAL_UNBIND_NOTIFY = booleanPreferencesKey("global_unbind_notify") private val GLOBAL_UNBIND_NOTIFY = booleanPreferencesKey("global_unbind_notify")
private val GLOBAL_UPDATE_NOTIFY = booleanPreferencesKey("global_update_notify") private val GLOBAL_UPDATE_NOTIFY = booleanPreferencesKey("global_update_notify")
@ -43,32 +40,6 @@ class GlobalStateManager(
} }
} }
suspend fun storeGlobalWxAuthorization(value: String) {
context.storeData.edit { preferences ->
preferences[GLOBAL_WX_AUTHORIZATION] = value
}
}
fun globalWxAuthorizationFlow(): Flow<String?> {
return context.storeData.data.map {
preferences ->
preferences[GLOBAL_WX_AUTHORIZATION]
}
}
suspend fun storeGlobalLoginNotify(value: Boolean) {
context.storeData.edit { preferences ->
preferences[GLOBAL_LOGIN_NOTIFY] = value
}
}
fun globalLoginNotifyFlow(): Flow<Boolean?> {
return context.storeData.data.map {
preferences ->
preferences[GLOBAL_LOGIN_NOTIFY]
}
}
suspend fun storeGlobalBindNotify(value: Boolean) { suspend fun storeGlobalBindNotify(value: Boolean) {
context.storeData.edit { preferences -> context.storeData.edit { preferences ->
preferences[GLOBAL_BIND_NOTIFY] = value preferences[GLOBAL_BIND_NOTIFY] = value
@ -94,19 +65,6 @@ class GlobalStateManager(
} }
suspend fun storeGlobalLogoutNotify(value: Boolean) {
context.storeData.edit { preferences ->
preferences[GLOBAL_LOGOUT_NOTIFY] = value
}
}
fun globalLogoutNotifyFlow(): Flow<Boolean?> {
return context.storeData.data.map {
preferences ->
preferences[GLOBAL_LOGOUT_NOTIFY]
}
}
suspend fun storeGlobalUpdateNotify(value: Boolean) { suspend fun storeGlobalUpdateNotify(value: Boolean) {
context.storeData.edit { preferences -> context.storeData.edit { preferences ->

View File

@ -22,6 +22,7 @@ object PreferenceUtil {
private const val KEY_X_TOKEN = "x_token" private const val KEY_X_TOKEN = "x_token"
private const val KEY_OAID = "android_oaid" private const val KEY_OAID = "android_oaid"
private const val KEY_LOGIN_INFO = "login_info" private const val KEY_LOGIN_INFO = "login_info"
private const val KEY_LOGIN_TYPE = "login_type"
private const val KEY_DB_VID = "bd_vid" private const val KEY_DB_VID = "bd_vid"
private const val KEY_USER_CONFIG = "user_config" private const val KEY_USER_CONFIG = "user_config"
private const val KEY_WX_CODE = "wx_code" private const val KEY_WX_CODE = "wx_code"
@ -89,6 +90,14 @@ object PreferenceUtil {
return gson.fromJson(mmkv.decodeString(KEY_USER_CONFIG, "{}"), UserConfigEntity::class.java) return gson.fromJson(mmkv.decodeString(KEY_USER_CONFIG, "{}"), UserConfigEntity::class.java)
} }
fun saveLoginType(type: String?) {
mmkv.encode(KEY_LOGIN_TYPE, type)
}
fun getLoginType(): String? {
return mmkv.decodeString(KEY_LOGIN_TYPE, null)
}
fun loginInfo(): LoginInfoEntity?{ fun loginInfo(): LoginInfoEntity?{
return getLoginInfos()?.find { it.isLogin } return getLoginInfos()?.find { it.isLogin }

View File

@ -0,0 +1,62 @@
package com.img.rabbit.utils
import com.img.rabbit.pages.LoginScreenType
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
object AppEventBus {
/*
private val _events = MutableSharedFlow<LoginBindEvent>(
replay = 1, // 关键:保存最后 1 条,新订阅者能收到旧消息
onBufferOverflow = BufferOverflow.DROP_OLDEST // 缓冲区满时丢弃旧的
)
val events = _events.asSharedFlow()
*/
private val _events = MutableSharedFlow<Any>()
val events = _events.asSharedFlow()
suspend fun post(event: UniMpWXPayEvent) {
_events.emit(event)
}
suspend fun post(event: LoginBindEvent) {
_events.emit(event)
}
suspend fun post(event: WXAuthEvent) {
_events.emit(event)
}
}
/**
* 登录绑定与退出账号事件
*/
sealed class LoginBindEvent {
/**
* 处理登录与登出isLogintrue 登录false 登出
* 登录类型LoginScreenType
* 传递数据data
*/
data class Login(val userId: String?, val loginType: String?, val isLogin: Boolean, val data: Any?) : LoginBindEvent()
/**
* 处理绑定与解绑isBindtrue 绑定false 解绑
* 绑定类型LoginScreenType仅包含手机LoginScreenType.LOGIN_CAPTCHA和微信LoginScreenType.LOGIN_WX
*/
data class Bind(val userId: String, val loginType: LoginScreenType, val isBind: Boolean) : LoginBindEvent()
}
/**
* 微信授权
* 授权类型authType=0 登录
*/
sealed class WXAuthEvent {
data class AuthResult(val code: String, val authType: Int) : WXAuthEvent()
}
/**
* UniMp小程序调用微信支付事件结果通知
*/
sealed class UniMpWXPayEvent {
data class PayResult(val code: Int) : UniMpWXPayEvent()
}

View File

@ -25,6 +25,9 @@ import kotlin.jvm.java
object UniAppUtils { object UniAppUtils {
/**
* 所有运行的UniMp小程序实体
*/
val uniMpPair = mutableMapOf<String?, IUniMP?>() val uniMpPair = mutableMapOf<String?, IUniMP?>()
//当前正在更新的小程序 //当前正在更新的小程序
@ -33,6 +36,14 @@ object UniAppUtils {
var currentDownloadUniMp: UniVersionEntity? = null var currentDownloadUniMp: UniVersionEntity? = null
//仅当跳转指定小程序时,才需要跳转指定位置 //仅当跳转指定小程序时,才需要跳转指定位置
var currentUniMpJumpPatch: String? = null var currentUniMpJumpPatch: String? = null
/**
*获取当前前台运行的UniMp小程序实体
*/
fun getCurrentUniMp(): IUniMP?{
return uniMpPair.filter { it.value?.isRunning == true }.values.firstOrNull()
}
/** /**
* 是否存在更新 * 是否存在更新
*/ */

View File

@ -26,6 +26,7 @@ import okhttp3.RequestBody.Companion.toRequestBody
class BindViewModel : BaseViewModel() { class BindViewModel : BaseViewModel() {
private val TAG = "BindViewModel" private val TAG = "BindViewModel"
private val ONEKEY_TAG = "BindViewModel_OneKey" private val ONEKEY_TAG = "BindViewModel_OneKey"
var isBindWxAuthor = false
val bindScreenType = mutableStateOf(BindScreenType.BIND_NORMAL) val bindScreenType = mutableStateOf(BindScreenType.BIND_NORMAL)
// 登录状态 // 登录状态
val bindState = mutableStateOf<ResultVo<LoginInfoEntity>?>(null) val bindState = mutableStateOf<ResultVo<LoginInfoEntity>?>(null)
@ -216,6 +217,7 @@ class BindViewModel : BaseViewModel() {
Toast.makeText(context, "您没有安装微信客户端,请先下载安装", Toast.LENGTH_SHORT).show() Toast.makeText(context, "您没有安装微信客户端,请先下载安装", Toast.LENGTH_SHORT).show()
return return
} }
isBindWxAuthor = true
val req = SendAuth.Req() val req = SendAuth.Req()
req.scope = "snsapi_userinfo" // 只能填 snsapi_userinfo req.scope = "snsapi_userinfo" // 只能填 snsapi_userinfo
req.state = context.packageName + Math.random() * 1000 + "_phone" req.state = context.packageName + Math.random() * 1000 + "_phone"

View File

@ -1,8 +1,13 @@
package com.img.rabbit.viewmodel package com.img.rabbit.viewmodel
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application import android.app.Application
import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Context.RECEIVER_EXPORTED
import android.content.Intent
import android.content.IntentFilter
import android.net.ConnectivityManager import android.net.ConnectivityManager
import android.net.Network import android.net.Network
import android.net.NetworkCapabilities import android.net.NetworkCapabilities
@ -10,29 +15,25 @@ import android.net.NetworkRequest
import android.os.Build import android.os.Build
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.core.content.ContextCompat.registerReceiver
import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.img.rabbit.bean.response.UniVersionEntity
import com.img.rabbit.bean.response.VersionEntity
import com.img.rabbit.config.Constants import com.img.rabbit.config.Constants
import com.img.rabbit.provider.api.ApiManager import com.img.rabbit.provider.api.ApiManager
import com.img.rabbit.provider.storage.GlobalStateManager
import com.img.rabbit.provider.storage.PreferenceUtil import com.img.rabbit.provider.storage.PreferenceUtil
import com.img.rabbit.utils.MMKVUtils.mmkv import com.tencent.mm.opensdk.constants.ConstantsAPI
import com.tencent.mm.opensdk.modelpay.PayReq
import com.tencent.mm.opensdk.openapi.IWXAPI import com.tencent.mm.opensdk.openapi.IWXAPI
import com.tencent.mm.opensdk.openapi.WXAPIFactory import com.tencent.mm.opensdk.openapi.WXAPIFactory
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@SuppressLint("ObsoleteSdkInt") @SuppressLint("ObsoleteSdkInt")
class GeneralViewModel(application: Application) : AndroidViewModel(application) { class GeneralViewModel(application: Application) : AndroidViewModel(application) {
lateinit var api: IWXAPI lateinit var api: IWXAPI
lateinit var receiver: android.content.BroadcastReceiver
private val _networkStatus = MutableLiveData<Boolean>() private val _networkStatus = MutableLiveData<Boolean>()
val networkStatus: LiveData<Boolean> = _networkStatus val networkStatus: LiveData<Boolean> = _networkStatus
fun setNetworkStatus(status: Boolean) { fun setNetworkStatus(status: Boolean) {
@ -103,9 +104,36 @@ class GeneralViewModel(application: Application) : AndroidViewModel(application)
} }
private fun initWXApi(context: Context) { private fun initWXApi(context: Context) {
api = WXAPIFactory.createWXAPI(context, Constants.WechatAppId) api = WXAPIFactory.createWXAPI(context, Constants.WxAppId, true)
api.registerApp(Constants.WxAppId)
//建议动态监听微信启动广播进行注册到微信
receiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// 将该app注册到微信
api.registerApp(Constants.WxAppId)
}
}
//建议动态监听微信启动广播进行注册到微信
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.registerReceiver(receiver,
IntentFilter(ConstantsAPI.ACTION_REFRESH_WXAPP), RECEIVER_EXPORTED)
}
} }
// private fun wxPay(api: IWXAPI){
// val request = PayReq()
// request.appId = "wx7d1a7d1507482cef"
// request.partnerId = "1511850511";
// request.prepayId= "wx06112039579543463f9116a0527ce30001"
// request.packageValue = "Sign=WXPay"
// request.nonceStr= "QjlkDdZY54eKmvfKrtawJD9Cws7pvUh0"
// request.timeStamp= "1772767239"
// request.sign= "DOhyV8QBng20nrZxgV8l8+4DD1foi7XKRfPnhHbzf63qWvL2f3miKTqAVtoS1U9syO38ENXrS18XzWHRMNnoyWgTGLp/SxbZjRjqHvrLJKIa1pH0svdv/uPXK1GlvjqsMXgeoTEXn73aHBNlcctNaZ8GCWbxpg77kdcCJfM+qWOSQOMJOpKh8lTx4dQzhWqdOSzABkQJTg6TThNUN3/00yeN7K9wZ4JOpN+Tmtaliztp0wQ3iAHgAqZmhxwv7ZyRev2izpoukdJ2aBn/+xPK/Hs5kI2KM67x6quvrWiQV31GixU2i84ddI3uxn1DwR90f5iEyA10NOylPA+D9rOEUQ=="
// api.sendReq(request)
// }
override fun onCleared() { override fun onCleared() {
super.onCleared() super.onCleared()
connectivityManager.unregisterNetworkCallback(networkCallback) connectivityManager.unregisterNetworkCallback(networkCallback)

View File

@ -8,7 +8,6 @@ import android.widget.Toast
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.State import androidx.compose.runtime.State
import androidx.compose.runtime.mutableIntStateOf
import com.alipay.sdk.app.AuthTask import com.alipay.sdk.app.AuthTask
import com.img.rabbit.pages.LoginScreenType import com.img.rabbit.pages.LoginScreenType
import com.g.gysdk.GYManager import com.g.gysdk.GYManager
@ -19,24 +18,24 @@ import com.github.gzuliyujiang.oaid.DeviceIdentifier
import com.google.gson.JsonObject import com.google.gson.JsonObject
import com.img.rabbit.bean.local.ErrorBean import com.img.rabbit.bean.local.ErrorBean
import com.img.rabbit.bean.local.OnekeyPreLogin import com.img.rabbit.bean.local.OnekeyPreLogin
import com.img.rabbit.bean.local.toAlipayResult
import com.img.rabbit.bean.response.LoginInfoEntity import com.img.rabbit.bean.response.LoginInfoEntity
import com.img.rabbit.bean.response.UniVersionEntity
import com.img.rabbit.bean.response.UserConfigEntity import com.img.rabbit.bean.response.UserConfigEntity
import com.img.rabbit.provider.api.ApiManager import com.img.rabbit.provider.api.ApiManager
import com.img.rabbit.provider.api.ResultVo import com.img.rabbit.provider.api.ResultVo
import com.img.rabbit.provider.storage.GlobalStateManager import com.img.rabbit.provider.storage.GlobalStateManager
import com.img.rabbit.provider.storage.PreferenceUtil import com.img.rabbit.provider.storage.PreferenceUtil
import com.img.rabbit.provider.utils.HeadParamUtils.applicationContext import com.img.rabbit.provider.utils.HeadParamUtils.applicationContext
import com.img.rabbit.utils.AppEventBus
import com.img.rabbit.utils.LoginBindEvent
import com.img.rabbit.utils.MMKVUtils import com.img.rabbit.utils.MMKVUtils
import com.img.rabbit.utils.UniAppUtils import com.img.rabbit.utils.StringUtils
import com.tencent.mm.opensdk.modelmsg.SendAuth import com.tencent.mm.opensdk.modelmsg.SendAuth
import com.tencent.mm.opensdk.openapi.IWXAPI import com.tencent.mm.opensdk.openapi.IWXAPI
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
@ -46,22 +45,24 @@ class LoginViewModel : BaseViewModel() {
private val ONEKEY_TAG = "OneKeyLoginViewModel" private val ONEKEY_TAG = "OneKeyLoginViewModel"
//private lateinit var api: IWXAPI //private lateinit var api: IWXAPI
var isLoginWxAuthor = false
val authInfoForAlipay: MutableState<String> = mutableStateOf("") val authInfoForAlipay: MutableState<String> = mutableStateOf("")
val loginScreenType = mutableStateOf(LoginScreenType.LOGIN_NORMAL) val loginScreenType = mutableStateOf(LoginScreenType.LOGIN_NORMAL)
// 登录用户名 // 登录用户名
val userName = mutableStateOf("") val userName = mutableStateOf("")
// 登录验证码
val captcha = mutableStateOf("")
// 登录验证码发送时间戳
val captchaTimestamp = mutableStateOf("")
fun setCaptcha(loginCaptcha: String) {
captcha.value = loginCaptcha
}
fun setUserName(loginName: String) { fun setUserName(loginName: String) {
userName.value = loginName userName.value = loginName
} }
// 登录验证码
val captcha = mutableStateOf("")
fun setCaptcha(loginCaptcha: String) {
captcha.value = loginCaptcha
}
// 登录验证码发送时间戳
val captchaTimestamp = mutableStateOf("")
private val isGYUIDValid = mutableStateOf(false) private val isGYUIDValid = mutableStateOf(false)
@ -79,20 +80,39 @@ class LoginViewModel : BaseViewModel() {
_policyAgreement.value = isAgreement _policyAgreement.value = isAgreement
} }
private val _isLogin = mutableStateOf(false) // private val _isLogin = mutableStateOf(false)
val isLogin: State<Boolean> = _isLogin // val isLogin: State<Boolean> = _isLogin
//
fun setLogin(isLogin: Boolean) { // fun setLogin(isLogin: Boolean) {
_isLogin.value = isLogin // _isLogin.value = isLogin
} // }
// 登录状态 // 登录获取结果
val loginState = mutableStateOf<ResultVo<LoginInfoEntity>?>(null) val loginResult = mutableStateOf<ResultVo<LoginInfoEntity>?>(null)
// 用户配置获取结果
val userConfigResult = mutableStateOf<ResultVo<UserConfigEntity>?>(null)
// 错误状态 // 错误状态
val errorState = mutableStateOf<ErrorBean?>(null) val errorState = mutableStateOf<ErrorBean?>(null)
fun reset(){
isLoginWxAuthor = false
authInfoForAlipay.value = ""
loginScreenType.value = LoginScreenType.LOGIN_NORMAL
userName.value = ""
captcha.value = ""
captchaTimestamp.value = ""
isGYUIDValid.value = false
oneKeyPreLogin = null
setIsPolicyAgreement(true)
loginResult.value = null
userConfigResult.value = null
errorState.value = null
}
fun requestUserConfig(){ fun requestUserConfig(){
mLaunch { mLaunch {
val oaid = MMKVUtils.getString("oaid") ?: "" val oaid = MMKVUtils.getString("oaid") ?: ""
@ -101,6 +121,7 @@ class LoginViewModel : BaseViewModel() {
PreferenceUtil.saveXToken(response.data.token) PreferenceUtil.saveXToken(response.data.token)
PreferenceUtil.setTimeDiff(response.data.nowtime.toLong() - System.currentTimeMillis() / 1000) PreferenceUtil.setTimeDiff(response.data.nowtime.toLong() - System.currentTimeMillis() / 1000)
PreferenceUtil.saveUserConfig(response.data) PreferenceUtil.saveUserConfig(response.data)
userConfigResult.value = response
applicationContext?.let { GlobalStateManager(it) }?.storeGlobalUserConfigNotify(true) applicationContext?.let { GlobalStateManager(it) }?.storeGlobalUserConfigNotify(true)
}else{ }else{
@ -143,9 +164,7 @@ class LoginViewModel : BaseViewModel() {
// 根据解析结果决定是否继续根据errorCode判断 // 根据解析结果决定是否继续根据errorCode判断
if (oneKeyPreLogin?.errorCode == 0) { if (oneKeyPreLogin?.errorCode == 0) {
oneKeyLoginValid( oneKeyLoginValid(onShowOneKeyScreen = onShowOneKeyScreen)
onShowOneKeyScreen = onShowOneKeyScreen
)
} else { } else {
onShowOneKeyScreen(false) onShowOneKeyScreen(false)
Log.e(ONEKEY_TAG, "预登录校验失败: ${oneKeyPreLogin?.errorDesc}") Log.e(ONEKEY_TAG, "预登录校验失败: ${oneKeyPreLogin?.errorDesc}")
@ -210,7 +229,8 @@ class LoginViewModel : BaseViewModel() {
jsonObject.addProperty("bind", "") jsonObject.addProperty("bind", "")
jsonObject.add("data", jsonOneKey) jsonObject.add("data", jsonOneKey)
requestLogin(jsonObject) Log.i(ONEKEY_TAG, "--->开始登录")
requestLogin(jsonObject, LoginScreenType.LOGIN_ONE_KEY)
} }
@ -252,72 +272,58 @@ class LoginViewModel : BaseViewModel() {
jsonObject.addProperty("login_type", "phone") jsonObject.addProperty("login_type", "phone")
jsonObject.add("phone", jsonPhone) jsonObject.add("phone", jsonPhone)
requestLogin(jsonObject) requestLogin(jsonObject, LoginScreenType.LOGIN_CAPTCHA)
} }
fun loginWithWechat(context: Context, wxApi:IWXAPI) { fun authorWechat(context: Context, wxApi:IWXAPI) {
if (isPolicyAgreement.value) { if (isPolicyAgreement.value) {
doWxAuth(context, wxApi) if (!wxApi.isWXAppInstalled) {
Toast.makeText(context, "您没有安装微信客户端,请先下载安装", Toast.LENGTH_SHORT).show()
return
}
isLoginWxAuthor = true
val req = SendAuth.Req()
req.scope = "snsapi_userinfo" // 只能填 snsapi_userinfo
req.state = context.packageName + Math.random() * 1000 + "_phone"
wxApi.sendReq(req)
}else{ }else{
Toast.makeText(context, "请先同意用户协议和隐私政策", Toast.LENGTH_SHORT).show() Toast.makeText(context, "请先同意用户协议和隐私政策", Toast.LENGTH_SHORT).show()
} }
} }
//获取微信授权 fun requestWxLogin(code: String){
private fun doWxAuth(context: Context, wxApi:IWXAPI) { val jsonObject = getWxLoginParam(code) ?: return
if (!wxApi.isWXAppInstalled) { requestLogin(jsonObject, LoginScreenType.LOGIN_WX)
Toast.makeText(context, "您没有安装微信客户端,请先下载安装", Toast.LENGTH_SHORT).show()
return
}
val req = SendAuth.Req()
req.scope = "snsapi_userinfo" // 只能填 snsapi_userinfo
req.state = context.packageName + Math.random() * 1000 + "_phone"
wxApi.sendReq(req)
} }
/** /**
* 拿着微信授权码完成登录(在WXEntryActivity中调用) * 拿着微信授权码完成登录(在WXEntryActivity中调用)
* @param wechatCode 微信授权码 * @param code 微信授权码
*/ */
fun requestWxLogin(wechatCode: String) { fun getWxLoginParam(code: String): JsonObject? {
if(wechatCode.isEmpty()){ if(code.isEmpty()){
return return null
} }
isLoading.value = true // 开始加载 isLoading.value = true // 开始加载
PreferenceUtil.saveWxCode(wechatCode) PreferenceUtil.saveWxCode(code)
// 调用 API 获取数据 // 调用 API 获取数据
val jsonWx = JsonObject() val jsonWx = JsonObject()
jsonWx.addProperty("code", wechatCode) jsonWx.addProperty("code", code)
jsonWx.addProperty("code_type", "") jsonWx.addProperty("code_type", "")
val jsonObject = JsonObject() val jsonObject = JsonObject()
jsonObject.addProperty("login_type", "weixin") jsonObject.addProperty("login_type", "weixin")
jsonObject.add("weixin", jsonWx) jsonObject.add("weixin", jsonWx)
requestLogin(jsonObject) return jsonObject
} }
/**
* 支付宝登录
* authInfo: 该参数需由后端生成并加签包含 app_idpidtarget_id 等信息
*/
fun loginWithAliPay(context: Context,onAuthResult: (Map<String, String>) -> Unit) {
if(authInfoForAlipay.value.isEmpty()){
Toast.makeText(context, "请先获取支付宝登录授权码", Toast.LENGTH_SHORT).show()
return
}
// 发送请求获取支付宝登录授权码
mLaunch {
onAuthResult(doAlipayLogin(context as Activity, authInfoForAlipay.value))
}
}
/** /**
* 请求支付宝登录参数 * 请求支付宝登录参数
*/ */
fun requestAliPayAuthParam() { fun requestAliPayAuthParam(context: Context) {
isLoading.value = true // 开始加载 isLoading.value = true // 开始加载
mLaunch { mLaunch {
@ -325,11 +331,42 @@ class LoginViewModel : BaseViewModel() {
val data = response.data val data = response.data
val param = data.param val param = data.param
authorAlipay(context = context,authParam = param)
authInfoForAlipay.value = param authInfoForAlipay.value = param
isLoading.value = false // 加载完成 isLoading.value = false // 加载完成
} }
} }
private fun authorAlipay(context: Context, authParam: String){
if(authParam.isEmpty()){
Toast.makeText(context, "请先获取支付宝登录授权码", Toast.LENGTH_SHORT).show()
return
}
// 发送请求获取支付宝登录授权码
mLaunch {
val authorResult = doAlipayLogin(context as Activity, authParam)
Log.i("loginWithAliPay", "支付宝登录结果:$authorResult")
val alipayResult = authorResult.toAlipayResult()
// 处理支付宝登录结果
when (alipayResult.resultStatus) {
"9000" -> {
// 登录成功result 字段中包含 auth_code
val authCode = StringUtils.parseAlipayResult(alipayResult.result ?: "")["auth_code"] ?: ""
val jsonObject = getAlipayLoginParam(authCode) ?: return@mLaunch
requestLogin(jsonObject, LoginScreenType.LOGIN_ALIPAY)
}
"6001" -> {
"用户取消登录"
}
else -> {
alipayResult.memo ?: "登录失败"
}
}
}
}
/** /**
* 封装支付宝登录逻辑 * 封装支付宝登录逻辑
* @param activity 当前 Activity 上下文 * @param activity 当前 Activity 上下文
@ -350,12 +387,12 @@ class LoginViewModel : BaseViewModel() {
} }
/** /**
* 拿着微信授权码完成登录(在WXEntryActivity中调用) * 拿着支付宝授权码完成登录
* @param authCode 微信授权码 * @param authCode 支付宝授权码
*/ */
fun requestAlipayLogin(authCode: String) { private fun getAlipayLoginParam(authCode: String): JsonObject? {
if(authCode.isEmpty()){ if(authCode.isEmpty()){
return return null
} }
isLoading.value = true // 开始加载 isLoading.value = true // 开始加载
@ -368,19 +405,18 @@ class LoginViewModel : BaseViewModel() {
jsonObject.addProperty("bind", "") jsonObject.addProperty("bind", "")
jsonObject.add("data", jsonWx) jsonObject.add("data", jsonWx)
requestLogin(jsonObject) return jsonObject
} }
//请求登录 //请求登录
private fun requestLogin(jsonObject: JsonObject){ private fun requestLogin(jsonObject: JsonObject, loginType: LoginScreenType){
mLaunch { mLaunch {
val response = ApiManager.serviceVo.login(jsonObject.toString().toRequestBody()) val response = ApiManager.serviceVo.login(jsonObject.toString().toRequestBody())
if (response.status) { if (response.status) {
loginState.value = response PreferenceUtil.saveLoginType(loginType.name)
val loginInfoEntity = response.data PreferenceUtil.saveLoginInfo(response.data.apply { isLogin = true })//记录登录数据
loginInfoEntity.isLogin = true PreferenceUtil.saveAccessToken(response.data.token)
//记录登录数据 loginResult.value = response
PreferenceUtil.saveLoginInfo(loginInfoEntity)
}else{ }else{
errorState.value = ErrorBean(response.code.toString(), response.message.ifEmpty { "登录失败" }) errorState.value = ErrorBean(response.code.toString(), response.message.ifEmpty { "登录失败" })
} }
@ -409,12 +445,12 @@ class LoginViewModel : BaseViewModel() {
if (response.status) { if (response.status) {
//logoutState.value = response //logoutState.value = response
PreferenceUtil.clearLogin() PreferenceUtil.clearLogin()
setLogin(false) // setLogin(false)
// 跳转登录页面 // 跳转登录页面
//restViewModel.intValue = 1 // GlobalScope.launch {
GlobalScope.launch { // GlobalStateManager(context).storeGlobalLogoutNotify(true)
GlobalStateManager(context).storeGlobalLogoutNotify(true) // }
} AppEventBus.post( LoginBindEvent.Login(userId = null, loginType = PreferenceUtil.getLoginType(), isLogin = false, data = null) )
} else { } else {
errorState.value = ErrorBean(response.code.toString(), response.message.ifEmpty { "退出登录失败" }) errorState.value = ErrorBean(response.code.toString(), response.message.ifEmpty { "退出登录失败" })
} }

View File

@ -2,7 +2,8 @@
package com.img.rabbit.wxapi package com.img.rabbit.wxapi
import com.img.rabbit.provider.storage.GlobalStateManager import com.img.rabbit.utils.AppEventBus
import com.img.rabbit.utils.WXAuthEvent
import com.tencent.mm.opensdk.constants.ConstantsAPI import com.tencent.mm.opensdk.constants.ConstantsAPI
import com.tencent.mm.opensdk.modelbase.BaseResp import com.tencent.mm.opensdk.modelbase.BaseResp
import com.tencent.mm.opensdk.modelmsg.SendAuth import com.tencent.mm.opensdk.modelmsg.SendAuth
@ -22,8 +23,13 @@ class WXEntryActivity : WXCallbackActivity() {
//val wxState = WxBean(code = authResp.code,state = authResp.state) //val wxState = WxBean(code = authResp.code,state = authResp.state)
GlobalScope.launch { GlobalScope.launch {
GlobalStateManager(this@WXEntryActivity).storeGlobalWxAuthorization(authResp.code) //GlobalStateManager(this@WXEntryActivity).storeGlobalWxAuthorization(authResp.code)
AppEventBus.post(
WXAuthEvent.AuthResult(
code = authResp.code,
authType = 0
)
)
finish() finish()
} }
} }

View File

@ -1,11 +1,46 @@
package com.img.rabbit.wxapi
import android.content.Intent
import android.os.Bundle
import androidx.lifecycle.ViewModelProvider
import com.img.rabbit.utils.UniAppUtils
import com.img.rabbit.viewmodel.GeneralViewModel
import com.tencent.mm.opensdk.constants.ConstantsAPI
import com.tencent.mm.opensdk.modelbase.BaseReq
import com.tencent.mm.opensdk.modelbase.BaseResp
import io.dcloud.feature.payment.weixin.AbsWXPayCallbackActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
package com.img.rabbit.wxapi; class WXPayEntryActivity : AbsWXPayCallbackActivity() {
//val scope = CoroutineScope(Dispatchers.Main)
private lateinit var generalViewModel: GeneralViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
generalViewModel = ViewModelProvider.AndroidViewModelFactory.getInstance(application)
.create(GeneralViewModel::class.java)
generalViewModel.api.handleIntent(intent, this)
}
import io.dcloud.feature.payment.weixin.AbsWXPayCallbackActivity; override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
setIntent(intent)
generalViewModel.api.handleIntent(getIntent(), this)
}
override fun onReq(baseReq: BaseReq?) { }
override fun onResp(baseResp: BaseResp) {
super.onResp(baseResp)
if (baseResp.type == ConstantsAPI.COMMAND_PAY_BY_WX) {
// 处理支付结果
//scope.launch { AppEventBus.post(UniMpWXPayEvent.PayResult(baseResp.errCode)) }
//结果通知到UniMp小程序
UniAppUtils.getCurrentUniMp()?.sendUniMPEvent("wx_pay_result", baseResp.errCode)
finish()
}
}
public class WXPayEntryActivity extends AbsWXPayCallbackActivity{
} }

View File

@ -15,11 +15,15 @@ pluginManagement {
gradlePluginPortal() gradlePluginPortal()
} }
} }
@Suppress("UnstableApiUsage")
dependencyResolutionManagement { dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
flatDir {
dirs("app/libs")
}
maven { url = uri("https://jitpack.io") } maven { url = uri("https://jitpack.io") }
maven { url = uri("https://company/com/maven2") } maven { url = uri("https://company/com/maven2") }
maven { url = uri("https://repo1.maven.org/maven2/") } maven { url = uri("https://repo1.maven.org/maven2/") }
@ -32,8 +36,6 @@ dependencyResolutionManagement {
maven { url = uri("https://developer.hihonor.com/repo/") } maven { url = uri("https://developer.hihonor.com/repo/") }
maven { url = uri("https://artifact.bytedance.com/repository/Volcengine/") } //巨量融合 maven { url = uri("https://artifact.bytedance.com/repository/Volcengine/") } //巨量融合
maven { url = uri("https://repo.eclipse.org/content/repositories/paho-snapshots/") } //mqtt maven { url = uri("https://repo.eclipse.org/content/repositories/paho-snapshots/") } //mqtt
mavenCentral()
google()
} }
} }