bug fix :1. 单点登录
         2. 用户态
This commit is contained in:
level 2025-07-01 15:02:51 +08:00
parent 53bc91c07a
commit c55d282acc
8 changed files with 159 additions and 12 deletions

View File

@ -30,12 +30,16 @@ import com.stripe.android.model.StripeIntent
import com.tencent.mmkv.MMKV import com.tencent.mmkv.MMKV
import com.yingmao.clash.BuildConfig import com.yingmao.clash.BuildConfig
import com.yingmao.clash.R import com.yingmao.clash.R
import com.yingmao.clash.act.UIMainActivity.Companion.isVip
import com.yingmao.clash.act.UIMainActivity.Companion.profileBinder
import com.yingmao.clash.app.MainApplication import com.yingmao.clash.app.MainApplication
import com.yingmao.clash.base.BaseActivity import com.yingmao.clash.base.BaseActivity
import com.yingmao.clash.conf.BZYConstants import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.entity.CheckLoginRsp import com.yingmao.clash.entity.CheckLoginRsp
import com.yingmao.clash.entity.PayUploadParamData import com.yingmao.clash.entity.PayUploadParamData
import com.yingmao.clash.entity.RechargeModelEntity import com.yingmao.clash.entity.RechargeModelEntity
import com.yingmao.clash.fragment.home.HomeFragment
import com.yingmao.clash.fragment.home.HomeFragment.Companion.clashRunning
import com.yingmao.clash.fragment.recharge.RechargeViewModel import com.yingmao.clash.fragment.recharge.RechargeViewModel
import com.yingmao.clash.fragment.recharge.adapter.RechargeModelAdapter import com.yingmao.clash.fragment.recharge.adapter.RechargeModelAdapter
import com.yingmao.clash.fragment.recharge.adapter.VIPRechargeAdapter import com.yingmao.clash.fragment.recharge.adapter.VIPRechargeAdapter
@ -52,7 +56,9 @@ import com.yingmao.clash.util.ThreadUtils
import com.yingmao.clash.view.RxToast import com.yingmao.clash.view.RxToast
import com.yingmao.clash.view.dialog.DialogDoMainChoose import com.yingmao.clash.view.dialog.DialogDoMainChoose
import com.yingmao.clash.view.dialog.RxDialogShapeLoading import com.yingmao.clash.view.dialog.RxDialogShapeLoading
import com.yingmao.clash.vm.MainAtyVM
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.MainScope import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -77,7 +83,7 @@ class MemberRechargeActivity : BaseActivity() {
private lateinit var rxDialogShapeLoading: RxDialogShapeLoading private lateinit var rxDialogShapeLoading: RxDialogShapeLoading
private var outTradeNo = "" private var outTradeNo = ""
private var selectedGradeID: Int = 0 private var selectedGradeID: Int = 0
private lateinit var mainAtyVM: MainAtyVM
//stripePay 支付 //stripePay 支付
private var paymentIntentClientSecret: String = "" private var paymentIntentClientSecret: String = ""
private val stripe: Stripe by lazy { private val stripe: Stripe by lazy {
@ -96,9 +102,11 @@ class MemberRechargeActivity : BaseActivity() {
} }
private fun initData() { private fun initData() {
mainAtyVM = ViewModelProvider(this)[MainAtyVM::class.java]
val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD) val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD)
setExpireDate(validPeriod) setExpireDate(validPeriod)
if (checkExpire()) { android.util.Log.i("AAAAAAAAAAA:","isvip::"+ isVip)
if (isVip) {
userIdentity.text = resources.getString(R.string.TemporaryUser) userIdentity.text = resources.getString(R.string.TemporaryUser)
} else { } else {
userIdentity.text = resources.getString(R.string.VIPMember) userIdentity.text = resources.getString(R.string.VIPMember)
@ -264,12 +272,19 @@ class MemberRechargeActivity : BaseActivity() {
HttpReqType.GET_RECHARGE_INFO -> { HttpReqType.GET_RECHARGE_INFO -> {
Logger.d("获取充值续费信息请求成功") Logger.d("获取充值续费信息请求成功")
swipeLayout.isRefreshing = false swipeLayout.isRefreshing = false
(httpStatus.rsp as RechargeInfoRsp).let { it -> (httpStatus.rsp as RechargeInfoRsp).let {
if (it.code != "1000") { when (it.code) {
RxToast.error(if (it.message.isNullOrBlank()) resources.getString(R.string.FailedRechargeList) + "${it.code}" else "${it.code}:${it.message}") "1088" -> {
} else { RxToast.info(resources.getString(R.string.LoginOut))
it.data?.let { rechargeInfo -> cleanUserInfo()
initAdapter(rechargeInfo) }
"1000" -> {
it.data?.let { rechargeInfo ->
initAdapter(rechargeInfo)
}
}
else -> {
RxToast.error(if (it.message.isNullOrBlank())resources.getString(R.string.FailedRechargeList)+ "${it.code}" else "${it.code}:${it.message}")
} }
} }
} }
@ -640,4 +655,46 @@ class MemberRechargeActivity : BaseActivity() {
finish() // 关闭当前 Activity finish() // 关闭当前 Activity
super.onBackPressed() super.onBackPressed()
} }
private fun cleanUserInfo() {
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_PH_TOKEN)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_TOKEN)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_CURRENT_NODE)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_SELECTED_NAME_KEY)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_VPN_UserCommand)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.PROFILE_SUB_URL)
Log.d("cleanUserInfo clashRunning==>$clashRunning")
if (clashRunning) {
HomeFragment().stopClash()
}
mainAtyVM.stopHeartBeat()
cleanProfile()
val intent=Intent(CommonUtils.getApp(), LoginActivity::class.java)
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
finish()
}
private fun cleanProfile() {
Log.d("cleanProfile start")
GlobalScope.launch(Dispatchers.IO) {
profileBinder?.let { pm ->
pm.queryAll().forEach { profile ->
Log.d("cleanProfile go delete name==>${profile.name}, uuid==>${profile.uuid}")
pm.delete(profile.uuid)
}
} ?: let {
Log.d("profileBinder is null")
}
}
}
override fun onDestroy() {
super.onDestroy()
if(dialogDoMainChoose!=null){
if(dialogDoMainChoose!!.isShowing){
dialogDoMainChoose!!.dismiss()
dialogDoMainChoose=null
}
}
}
} }

View File

@ -39,6 +39,7 @@ import com.yingmao.clash.base.BaseActivity
import com.yingmao.clash.conf.BZYConstants import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.conf.Conf import com.yingmao.clash.conf.Conf
import com.yingmao.clash.entity.CheckLoginRsp import com.yingmao.clash.entity.CheckLoginRsp
import com.yingmao.clash.fragment.NewAccFragment
import com.yingmao.clash.fragment.home.HomeFragment import com.yingmao.clash.fragment.home.HomeFragment
import com.yingmao.clash.fragment.setting.SettingFragment import com.yingmao.clash.fragment.setting.SettingFragment
import com.yingmao.clash.listener.DownLoadListener import com.yingmao.clash.listener.DownLoadListener
@ -47,6 +48,7 @@ import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.HttpStatus import com.yingmao.clash.net.http.HttpStatus
import com.yingmao.clash.net.http.NetService import com.yingmao.clash.net.http.NetService
import com.yingmao.clash.net.http.entity.AppVersionCheckRsp import com.yingmao.clash.net.http.entity.AppVersionCheckRsp
import com.yingmao.clash.net.http.entity.ExpensesRecordRsp
import com.yingmao.clash.net.http.entity.GetActivityRsp import com.yingmao.clash.net.http.entity.GetActivityRsp
import com.yingmao.clash.net.http.entity.PhDownloadUrlRsp import com.yingmao.clash.net.http.entity.PhDownloadUrlRsp
import com.yingmao.clash.net.http.entity.SubscriptionRsp import com.yingmao.clash.net.http.entity.SubscriptionRsp
@ -99,7 +101,7 @@ class UIMainActivity : BaseActivity() {
private var activityDialog: ActivityViewDialog? = null private var activityDialog: ActivityViewDialog? = null
private var checkPayResultDia: MaterialDialog? = null private var checkPayResultDia: MaterialDialog? = null
private var checkBindAccountDia: MaterialDialog? = null private var checkBindAccountDia: MaterialDialog? = null
private val mPageInfo = PageInfo()
companion object { companion object {
//记录心跳失败次数 //记录心跳失败次数
var HEART_BEAT_FAILURE_FREQUENCY = 0 var HEART_BEAT_FAILURE_FREQUENCY = 0
@ -113,6 +115,7 @@ class UIMainActivity : BaseActivity() {
var hostsMem: ArrayList<String> = ArrayList() var hostsMem: ArrayList<String> = ArrayList()
var isSubed = false var isSubed = false
var newMainActGlo: Boolean = false var newMainActGlo: Boolean = false
var isVip:Boolean=false
} }
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@ -131,6 +134,7 @@ class UIMainActivity : BaseActivity() {
newMainActGlo = isGlobal newMainActGlo = isGlobal
startLog() startLog()
firstEntry() firstEntry()
mainAtyVM.getExpensesRecord(mPageInfo)
} }
private fun initView(savedInstanceState: Bundle?) { private fun initView(savedInstanceState: Bundle?) {
@ -273,7 +277,10 @@ class UIMainActivity : BaseActivity() {
} else { } else {
// RxToast.info(resources.getString(R.string.PaymentResultsStr)) // RxToast.info(resources.getString(R.string.PaymentResultsStr))
} }
} else { }else if(checkLoginRsp.code == -2){
RxToast.info(resources.getString(R.string.LoginOut))
cleanUserInfoToLogout()
}else {
RxToast.info(resources.getString(R.string.QueryFailed)) RxToast.info(resources.getString(R.string.QueryFailed))
} }
payResultLoading?.dismiss() payResultLoading?.dismiss()
@ -305,7 +312,31 @@ class UIMainActivity : BaseActivity() {
} }
} }
} }
HttpReqType.EXPENSES_RECORD ->{
if(httpStatus.rsp is ExpensesRecordRsp){
httpStatus.rsp.let { expensesRecordRsp ->
if(expensesRecordRsp.code == "1000"){
if(expensesRecordRsp.data != null) {
val expensesRecordList = expensesRecordRsp.data.expensesRecords
if(expensesRecordList!=null){
if(expensesRecordList.size>0){
android.util.Log.i("AAAAAAAA:","data::"+expensesRecordList.size)
isVip=true
}else{
isVip=false
}
}else{
isVip=false
}
}else{
isVip=false
}
}else{
isVip=false
}
}
}
}
else -> { else -> {
} }
@ -682,4 +713,37 @@ class UIMainActivity : BaseActivity() {
REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY
) )
} }
private fun cleanUserInfoToLogout() {
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_PH_TOKEN)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_TOKEN)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_CURRENT_NODE)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_SELECTED_NAME_KEY)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_VPN_UserCommand)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.NODE_All_ITEM_NAME_KEY)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.PROFILE_SUB_URL)
Log.d("cleanUserInfo clashRunning==>${clashRunning}")
if (clashRunning) {
fragments.filterIsInstance<HomeFragment>().forEach { it.stopClash() }
}
stopUploadTimer()
mainAtyVM.stopHeartBeat()
cleanProfile()
val intent=Intent(CommonUtils.getApp(), LoginActivity::class.java)
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
startActivity(intent)
finish()
}
class PageInfo {
var page = 1
fun nextPage() {
page++
}
fun reset() {
page = 1
}
val isFirstPage: Boolean
get() = page == 1
}
} }

View File

@ -58,6 +58,7 @@ import com.yingmao.clash.act.SplashActivity
import com.yingmao.clash.act.SplashHelper import com.yingmao.clash.act.SplashHelper
import com.yingmao.clash.act.UIMainActivity import com.yingmao.clash.act.UIMainActivity
import com.yingmao.clash.act.UIMainActivity.Companion.isSubed import com.yingmao.clash.act.UIMainActivity.Companion.isSubed
import com.yingmao.clash.act.UIMainActivity.Companion.isVip
import com.yingmao.clash.act.UIMainActivity.Companion.newUuid import com.yingmao.clash.act.UIMainActivity.Companion.newUuid
import com.yingmao.clash.act.UIMainActivity.Companion.profileBinder import com.yingmao.clash.act.UIMainActivity.Companion.profileBinder
import com.yingmao.clash.act.UIMainActivity.Companion.subUrl import com.yingmao.clash.act.UIMainActivity.Companion.subUrl
@ -257,7 +258,7 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc
} }
setExpireDate() setExpireDate()
if (checkExpire()) { if (isVip) {
userIdentity.text = requireActivity().resources.getString(R.string.TemporaryUser) userIdentity.text = requireActivity().resources.getString(R.string.TemporaryUser)
} else { } else {
userIdentity.text = requireActivity().resources.getString(R.string.VIPMember) userIdentity.text = requireActivity().resources.getString(R.string.VIPMember)

View File

@ -12,11 +12,14 @@ import com.yingmao.clash.act.NewMainActivity
import com.yingmao.clash.base.PublicViewMode import com.yingmao.clash.base.PublicViewMode
import com.cncat.vpn.common.log.Log import com.cncat.vpn.common.log.Log
import com.google.gson.Gson import com.google.gson.Gson
import com.yingmao.clash.act.PageInfo
import com.yingmao.clash.act.UIMainActivity
import com.yingmao.clash.app.MainApplication import com.yingmao.clash.app.MainApplication
import com.yingmao.clash.conf.BZYConstants import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.entity.CheckLoginRsp import com.yingmao.clash.entity.CheckLoginRsp
import com.yingmao.clash.entity.ClashNodebBean import com.yingmao.clash.entity.ClashNodebBean
import com.yingmao.clash.entity.Node import com.yingmao.clash.entity.Node
import com.yingmao.clash.fragment.setting.SettingFragment
import com.yingmao.clash.http.OkHttpBase import com.yingmao.clash.http.OkHttpBase
import com.yingmao.clash.listener.AsyncCallBackListener import com.yingmao.clash.listener.AsyncCallBackListener
import com.yingmao.clash.listener.DownLoadListener import com.yingmao.clash.listener.DownLoadListener
@ -343,4 +346,18 @@ class MainAtyVM : PublicViewMode() {
httpApi.appUpStatus(paramsToken,requestBody) httpApi.appUpStatus(paramsToken,requestBody)
} }
} }
fun getExpensesRecord(page : UIMainActivity.PageInfo){
val httpApi = NetService.instances.createHttps(HttpApi::class.java)
val username = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME,"")!!
val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN,"")!!
val userId = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_USER_ID)!!
val params = hashMapOf<String,String>(
"phoneNumber" to username,
"userId" to userId,
"phToken" to phToken,
"pageno" to "${page.page}",
"pageSize" to "5",
)
doAsync(HttpReqType.EXPENSES_RECORD){httpApi.phOrderList(params)}
}
} }

View File

@ -358,4 +358,6 @@ Service Description\n
<string name="skip">Go to login</string> <string name="skip">Go to login</string>
<string name="email_or_phone_register">Email registration</string> <string name="email_or_phone_register">Email registration</string>
<string name="CZHY">Recharge Membership</string> <string name="CZHY">Recharge Membership</string>
<string name="LoginOut">It is detected that the current account is logged in on other devices. If it is not your own operation, please change the password immediately and log out of the unfamiliar device.</string>
</resources> </resources>

View File

@ -349,4 +349,6 @@
<string name="email_or_phone_register">手動注册</string> <string name="email_or_phone_register">手動注册</string>
<string name="CZHY">充值會員</string> <string name="CZHY">充值會員</string>
<string name="LoginOut">檢測到當前賬號在其他設備登錄,如非本人操作,請立即修改密碼並退出陌生設備。</string>
</resources> </resources>

View File

@ -347,4 +347,6 @@
<string name="app_name_yunti">雲梯加速器</string> <string name="app_name_yunti">雲梯加速器</string>
<string name="email_or_phone_register">手動注册</string> <string name="email_or_phone_register">手動注册</string>
<string name="CZHY">充值會員</string> <string name="CZHY">充值會員</string>
<string name="LoginOut">檢測到當前賬號在其他設備登錄,如非本人操作,請立即修改密碼並退出陌生設備。</string>
</resources> </resources>

View File

@ -369,4 +369,6 @@
<string name="email_or_phone_register">手动注册</string> <string name="email_or_phone_register">手动注册</string>
<string name="CZHY">充值会员</string> <string name="CZHY">充值会员</string>
<string name="LoginOut">检测到当前账号在其他设备登录,如非本人操作,请立即修改密码并退出陌生设备。</string>
</resources> </resources>