删除多余文件

This commit is contained in:
cyh 2025-07-21 12:26:01 +08:00
parent 77ae53e43d
commit 3a3bab6909
27 changed files with 34 additions and 4387 deletions

View File

@ -112,10 +112,7 @@
<activity
android:name=".act.RegisterActivity"
android:screenOrientation="portrait" />
<activity
android:name=".act.NewMainActivity"
android:process=":background"
android:screenOrientation="portrait" />
<activity
android:name=".act.LoginActivity"
android:process=":background"
@ -124,9 +121,7 @@
android:name=".webview.BZYWebViewActivity"
android:process=":background"
android:screenOrientation="portrait" />
<activity
android:name=".act.MyPointCardActivity"
android:screenOrientation="portrait" />
<activity
android:name=".act.ShareActivity"
android:process=":background"
@ -134,9 +129,7 @@
<activity
android:name=".act.BandPhoneActivity"
android:screenOrientation="portrait" />
<activity
android:name=".act.ZFBTXActivity"
android:screenOrientation="portrait" />
<activity
android:name=".webview.BZYWebViewOther"
android:process=":background"

View File

@ -1,501 +0,0 @@
package com.yingmao.clash.act
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Build
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.Button
import androidx.activity.result.contract.ActivityResultContract
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.afollestad.materialdialogs.MaterialDialog
import com.yingmao.clash.R
import com.google.gson.Gson
import com.google.gson.JsonArray
import com.tencent.mmkv.MMKV
import com.yingmao.clash.act.ChangeNodeActivity.Companion
import com.yingmao.clash.act.NewMainActivity.Companion.isSubed
import com.yingmao.clash.act.NewMainActivity.Companion.newUuid
import com.yingmao.clash.app.MainApplication
import com.yingmao.clash.base.BaseActivity
import com.cncat.vpn.common.constants.Intents
import com.cncat.vpn.core.Clash
import com.cncat.vpn.core.model.ProviderList
import com.cncat.vpn.core.model.TunnelState
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.conf.Conf
import com.yingmao.clash.listener.BaseCallBack
import com.yingmao.clash.remote.Remote
import com.cncat.vpn.service.ClashManager
import com.cncat.vpn.service.ProfileManager
import com.cncat.vpn.service.model.Profile
import com.cncat.vpn.service.remote.IClashManager
import com.cncat.vpn.service.remote.IProfileManager
import com.cncat.vpn.service.remote.wrap
import com.cncat.vpn.service.store.ServiceStore
import com.yingmao.clash.util.ActivityResultLifecycle
import com.yingmao.clash.util.Utils
import com.yingmao.clash.util.startClashService
import com.yingmao.clash.util.stopClashService
import com.yingmao.clash.util.withClash
import com.yingmao.clash.util.withProfile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.selects.select
import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.withContext
import okhttp3.Response
import java.util.*
import java.util.concurrent.atomic.AtomicInteger
import kotlin.collections.HashMap
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
class MainActivity : BaseActivity() {
private val TAG: String = "GG"
// private lateinit var mainActVM: MainActVM
private lateinit var username: String
enum class Event {
ServiceRecreated,
ActivityStart,
ActivityStop,
ClashStop,
ClashStart,
ProfileLoaded,
ProfileChanged,
ProfileUpdateCompleted,
ProfileUpdateFailed,
}
enum class Request {
ToggleStatus,
OpenProxy,
OpenProfiles,
OpenProviders,
OpenLogs,
OpenSettings,
OpenHelp,
OpenAbout,
}
protected val clashRunning: Boolean
get() = Remote.broadcasts.clashRunning
var clash: ClashManager? = null
// private var clashBinder: IClashManager? = null
var profile: ProfileManager? = null
val reloadLock = Semaphore(10)
private var clashBinder: IClashManager? = null
private var profileBinder: IProfileManager? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main_act)
username = Utils.getUniqueID(this)
// mainActVM = ViewModelProvider(this)[MainActVM::class.java]
// GlobalScope.launch {
clash = ClashManager(this@MainActivity)
profile = ProfileManager(this@MainActivity)
clashBinder = clash?.wrap() as IClashManager?
profileBinder = profile?.wrap() as IProfileManager?
// }
findViewById<Button>(R.id.create_url).setOnClickListener {
launch(Dispatchers.IO) {
createByUrl()
}
}
findViewById<Button>(R.id.query_node).setOnClickListener {
queryProxy();
}
findViewById<Button>(R.id.start_v).setOnClickListener {
launch {
// withClash {
// patchSelector(names[it.index], it.name)
// }
profileBinder?.let { pm ->
val active = pm.queryActive()
if (active == null) {
com.cncat.vpn.common.log.Log.d("startClash: 未选择")
val pro = pm.queryAll().find {
it.name == Conf.getClashConfName(this@MainActivity.applicationContext)
}
pro?.let { profile ->
com.cncat.vpn.common.log.Log.d("new setactive name " + profile.name)
pm.setActive(profile)
newUuid = profile.uuid.toString();
isSubed = true
var selected_name =
MMKV.defaultMMKV()
.decodeString(BZYConstants.NODE_SELECTED_NAME_KEY, "")
}
delay(500)
}
}
if (clashRunning)
stopClashService()
else
startClash()
}
}
findViewById<Button>(R.id.update_but).setOnClickListener {
launch(Dispatchers.IO) {
}
}
// val routerSet = MMKV.defaultMMKV().decodeStringSet(BZYConstants.MMKV_KEY_ROUTER_HOST)
// if (routerSet != null && routerSet.size > 0) {
// isNeedRegister()
// } else {
// getHost()
// }
fetch()
val intentFilter = IntentFilter(Intents.ACTION_NODE_LIST)
if (Build.VERSION.SDK_INT >= 34 && applicationInfo.targetSdkVersion >= 34) {
registerReceiver(
NodeListBR(), intentFilter, Context.RECEIVER_EXPORTED
)
} else {
registerReceiver(NodeListBR(), intentFilter)
}
findViewById<Button>(R.id.setmode_auto).setOnClickListener {
launch(Dispatchers.IO) {
clashBinder?.let { cm ->
var state = cm.queryTunnelState()
var providers = cm.queryProviders()
var providersList = Gson().toJson(providers)
com.cncat.vpn.common.log.Log.d("state==>${state}, providers==>{$providersList}")
val o = cm.queryOverride(Clash.OverrideSlot.Session)
o.mode = TunnelState.Mode.Rule
cm.patchOverride(Clash.OverrideSlot.Session, o)
}
}
}
findViewById<Button>(R.id.setmode_globa).setOnClickListener {
launch(Dispatchers.IO) {
clashBinder?.let { cm ->
val o = cm.queryOverride(Clash.OverrideSlot.Session)
o.mode = TunnelState.Mode.Global
cm.patchOverride(Clash.OverrideSlot.Session, o)
delay(500)
cm.patchSelector("GLOBAL", "日本|中转")
}
}
}
findViewById<Button>(R.id.query_mode).setOnClickListener {
launch(Dispatchers.IO) {
clashBinder?.let { cm ->
var state = cm.queryTunnelState()
var providers = cm.queryProviders()
var providersList = Gson().toJson(providers)
com.cncat.vpn.common.log.Log.d("query_mode 333 state==>${state}, providers==>{$providersList}")
var names = cm.queryProxyGroupNames(false)
if (names.isNotEmpty()) {
cm.queryProxyGroup(names.get(0), uiStore.proxySort)?.let { proxyGroup ->
var list = proxyGroup.proxies
com.cncat.vpn.common.log.Log.d("list==>" + Gson().toJson(list))
}
}
}
}
}
}
class NodeListBR : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
Intents.ACTION_NODE_LIST -> {
// val parcelableArrayListExtra = intent.getParcelableArrayListExtra<Map<String,Any>>("")
var json = intent.getStringExtra("node_list")
Log.d(Conf.TAG, "onReceive: $json")
}
else -> {
}
}
}
}
private fun isNeedRegister() {
// if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_IS_REGISTER, false)) {
// splashAtyVM.checkLogin()
// } else {
// doRegister()
// }
}
private fun queryProxy() {
Log.d(TAG, "queryProxy 333: ")
launch(Dispatchers.IO) {
// withClash {
// val names = queryProxyGroupNames(false)
// Log.d(TAG, "queryProxy: names==>" + Gson().toJson(names))
//// val group = reloadLock.withPermit {
// if (names?.isNotEmpty() == true) {
//// var pg = queryProxyGroup(names[0], uiStore.proxySort);
// var pro = queryProviders();
//// Log.d(TAG, "queryProxyGroup: " + Gson().toJson(pg))
// Log.d(TAG, "queryProviders: " + Gson().toJson(pro))
//
// }
// }
clashBinder?.let { cb ->
val names = cb.queryProxyGroupNames(false)
Log.d(TAG, "queryProxy: names==>" + Gson().toJson(names))
// val group = reloadLock.withPermit {
if (names?.isNotEmpty() == true) {
// var pg = cb.queryProxyGroup(names[0], uiStore.proxySort);
var pro = cb.queryProviders();
// Log.d(TAG, "queryProxyGroup: " + Gson().toJson(pg))
Log.d(TAG, "queryProviders2: " + Gson().toJson(pro))
// cb.patchSelector("八爪鱼机场", "德国|中转")
}
}
}
// }
// val store = ServiceStore(this)
// store.accessControlPackages.forEach {
// Log.d(TAG, "accessControlPackages: $it")
// }
}
//private suspend fun createByUrl() {
// var uuid: UUID? = null
//
// withProfile {
// //创建文件
// uuid = create(Profile.Type.Url, "八爪猫")
//
// Log.d(TAG, "createByUrl: uuid==>" + uuid)
// delay(1000)
//
// val original: Profile? = uuid?.let {
// Log.d(TAG, "createByUrl: release==>" + it)
//// release(it)
// queryByUUID(it)
// }
//
//
//
//
// original?.let {
// Log.d(TAG, "createByUrl: original==>")
// setActive(it)
// patch(
// it.uuid,
// it.name,
//// "https://mojie0201.xn--8stx8olrwkucjq3b.com/api/v1/client/subscribe?token=169110d2674c49604b7e5b5cea341579",
// "https://www.otcopusapp.cc/lx3af288h5i8pz380/api/v1/client/subscribe?token=d6bc98c7ea53099fa5bd1a3ea415ebb6",
// it.interval
// )
// coroutineScope {
//
// commit(it.uuid) {
// Log.d(TAG, "createByUrl: " + it.progress)
// }
// }
// }
//
// }
// Log.d(TAG, "createByUrl: end")
//}
private suspend fun createByUrl() {
var uuid: UUID? = null
profile?.let { p ->
//创建文件
uuid = p.create(Profile.Type.Url, Conf.getClashConfName(this@MainActivity.applicationContext))
Log.d(TAG, "createByUrl: uuid==>" + uuid)
delay(1000)
val original: Profile? = uuid?.let {
Log.d(TAG, "createByUrl: release==>" + it)
// release(it)
p.queryByUUID(it)
}
original?.let {
Log.d(TAG, "createByUrl: original==>")
p.setActive(it)
p.patch(
it.uuid,
it.name,
// "https://mojie0201.xn--8stx8olrwkucjq3b.com/api/v1/client/subscribe?token=169110d2674c49604b7e5b5cea341579",
"https://www.otcopusapp.cc/lx3af288h5i8pz380/api/v1/client/subscribe?token=d6bc98c7ea53099fa5bd1a3ea415ebb6",
it.interval
)
p.commit(it.uuid) {
Log.d(TAG, "createByUrl: " + it.progress)
}
}
}
Log.d(TAG, "createByUrl: end")
}
private suspend fun startClash() {
// val active = withProfile { queryActive() }
//
// if (active == null || !active.imported) {
// Log.d(TAG, "startClash: 未选择")
//
// return
// }
val vpnRequest = startClashService()
try {
if (vpnRequest != null) {
val result = startActivityForResult(
ActivityResultContracts.StartActivityForResult(),
vpnRequest
)
if (result.resultCode == RESULT_OK)
startClashService()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
private val nextRequestKey = AtomicInteger(0)
suspend fun <I, O> startActivityForResult(
contracts: ActivityResultContract<I, O>,
input: I,
): O = withContext(Dispatchers.Main) {
val requestKey = nextRequestKey.getAndIncrement().toString()
ActivityResultLifecycle().use { lifecycle, start ->
suspendCoroutine { c ->
activityResultRegistry.register(requestKey, lifecycle, contracts) {
c.resume(it)
}.apply { start() }.launch(input)
}
}
}
private fun fetch2() {
lifecycleScope.launch {
profile?.let {
}
}
}
private fun fetch() {
// setClashRunning(clashRunning)
Log.d(TAG, "fetch: 1")
launch(Dispatchers.IO) {
// profile?.let { p ->
Log.d(TAG, "fetch: 2")
// withProfile {
// var allPro = queryAll()
// Log.d(TAG, "fetch: allPro==>" + Gson().toJson(allPro))
// allPro?.let {
// if (it.isNotEmpty()) {
// it[0]?.let { pro ->
//
// setActive(pro)
//
// patch(
// pro.uuid,
// pro.name,
//// "https://mojie0201.xn--8stx8olrwkucjq3b.com/api/v1/client/subscribe?token=169110d2674c49604b7e5b5cea341579",
// "https://www.otcopusapp.cc/lx3af288h5i8pz380/api/v1/client/subscribe?token=d6bc98c7ea53099fa5bd1a3ea415ebb6",
// pro.interval
// )
// commit(pro.uuid) {
// Log.d(TAG, "createByUrl: " + it.progress)
// }
// }
// }
// }
// }
profileBinder?.let { pm ->
var allPro = pm.queryAll()
var actname = pm.queryActive()?.name
com.cncat.vpn.common.log.Log.d("actname==>" + actname)
}
var state: TunnelState? = null
var providers: ProviderList? = null
clashBinder?.let { cm ->
state = cm.queryTunnelState()
providers = cm.queryProviders()
com.cncat.vpn.common.log.Log.d("state==>${state}, providers==>{$providers}")
}
// val state = withClash {
// queryTunnelState()
// }
// val providers = withClash {
// queryProviders()
// }
// setMode(state.mode)
// setHasProviders(providers.isNotEmpty())
// withProfile {
// Log.d(TAG, "fetch: " + queryActive())
// }
}
}
}

View File

@ -678,7 +678,7 @@ class MemberRechargeActivity : BaseActivity() {
if (clashRunning) {
HomeFragment().stopClash()
}
UIMainActivity.isSubbed=false
UIMainActivity.isSubed=false
mainAtyVM.stopHeartBeat()
cleanProfile()
val intent=Intent(CommonUtils.getApp(), LoginActivity::class.java)

View File

@ -1,147 +0,0 @@
package com.yingmao.clash.act
import android.os.Bundle
import android.text.Html
import android.widget.EditText
import android.widget.TextView
import androidx.lifecycle.ViewModelProvider
import com.yingmao.clash.view.dialog.RxDialogShapeLoading
import com.orhanobut.logger.Logger
import com.yingmao.clash.R
import com.yingmao.clash.base.BaseActivity
import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.HttpStatus
import com.yingmao.clash.net.http.entity.NormalMessageRsp
import com.yingmao.clash.net.http.entity.NormalRsp
import com.yingmao.clash.view.RxToast
class MyPointCardActivity : BaseActivity() {
private lateinit var pointCardIdEt:EditText
private lateinit var pointCardRechargeTv:TextView
private lateinit var pointCardBalanceTv:TextView
private lateinit var pointCardVM: MyPointCardVM
private lateinit var rxDialogShapeLoading: RxDialogShapeLoading
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_activity_pointcard)
showTitleBar("我的点卡")
pointCardVM = ViewModelProvider(this).get(MyPointCardVM::class.java)
observe(this, pointCardVM)
initView()
pointCardVM.getPointCardSurplus()
}
private fun initView() {
pointCardIdEt = findViewById(R.id.et_point_card_id)
pointCardRechargeTv = findViewById(R.id.tv_point_card_recharge)
pointCardBalanceTv = findViewById(R.id.tv_point_card_balance)
pointCardRechargeTv.setOnClickListener {
rechargePointCard()
}
}
//点卡充值
private fun rechargePointCard() {
if(::pointCardIdEt.isInitialized) {
val pointCardId = pointCardIdEt.text.toString().trim()
if(pointCardId.isEmpty()){
RxToast.warning("请输入点卡卡号")
return
}
val regex = "^[a-z0-9A-Z]{16}$"
val matches = pointCardId.matches(Regex(regex))
if(!matches){
RxToast.warning("您输入点卡卡号有误,请查证后输入!")
return
}
pointCardVM.rechargePointCard(pointCardId)
}
}
override fun httpLoading(httpStatus: HttpStatus.Loading) {
if(httpStatus.reqType == HttpReqType.POINT_CARD_RECHARGE){
if(!::rxDialogShapeLoading.isInitialized) {
rxDialogShapeLoading = RxDialogShapeLoading(this)
}
rxDialogShapeLoading.setMessage("正在充值,请稍后...")
if(!rxDialogShapeLoading.isShowing){
rxDialogShapeLoading.show()
}
}else if(httpStatus.reqType == HttpReqType.GET_POINTCARD_SURPLUS){
if(!::rxDialogShapeLoading.isInitialized) {
rxDialogShapeLoading = RxDialogShapeLoading(this)
}
rxDialogShapeLoading.setMessage("正在查询点卡余额,请稍后...")
if(!rxDialogShapeLoading.isShowing){
rxDialogShapeLoading.show()
}
}
}
override fun httpSuccess(httpStatus: HttpStatus.Success) {
if(httpStatus.reqType == HttpReqType.POINT_CARD_RECHARGE){
if(::rxDialogShapeLoading.isInitialized) {
rxDialogShapeLoading.cancel()
}
if(httpStatus.rsp is NormalMessageRsp){
(httpStatus.rsp as NormalMessageRsp).let {
if(it.code == "1000"){
//TODO 充值成功
RxToast.info("点卡充值成功!")
pointCardIdEt.text.clear()
pointCardVM.getPointCardSurplus()
}else{
RxToast.error("${it.code}${it.message}")
return@httpSuccess
}
}
}
}else if(httpStatus.reqType == HttpReqType.GET_POINTCARD_SURPLUS){
if(::rxDialogShapeLoading.isInitialized) {
rxDialogShapeLoading.cancel()
}
if(httpStatus.rsp is NormalRsp){
(httpStatus.rsp as NormalRsp).let {
if(it.code == "1000"){
//TODO 查询余额成功,展示余额
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
pointCardBalanceTv.text = Html.fromHtml(
"剩余点数:${it.data}",
Html.FROM_HTML_MODE_LEGACY
)
}else{
pointCardBalanceTv.text = Html.fromHtml(
"剩余点数:${it.data}"
)
}
}else{
RxToast.error("${it.code}${it.message}")
return@httpSuccess
}
}
}
}
}
override fun httpFailure(httpStatus: HttpStatus.Failure) {
if(httpStatus.reqType == HttpReqType.POINT_CARD_RECHARGE) {
if (::rxDialogShapeLoading.isInitialized) {
rxDialogShapeLoading.cancel()
}
Logger.d("点卡充值异常:${httpStatus.msg}")
RxToast.error("点卡充值异常")
}else if(httpStatus.reqType == HttpReqType.GET_POINTCARD_SURPLUS) {
if (::rxDialogShapeLoading.isInitialized) {
rxDialogShapeLoading.cancel()
}
Logger.d("查询点卡余额异常:${httpStatus.msg}")
RxToast.error("查询点卡余额异常")
}
}
}

View File

@ -1,36 +0,0 @@
package com.yingmao.clash.act
import com.orhanobut.logger.Logger
import com.tencent.mmkv.MMKV
import com.yingmao.clash.base.BaseViewMode
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.net.http.HttpApi
import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.NetService
class MyPointCardVM: BaseViewMode() {
fun rechargePointCard(cardCode:String){
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 params = hashMapOf(
"phoneNumber" to username,
"cardCode" to cardCode,
"phToken" to phToken
)
doAsync(HttpReqType.POINT_CARD_RECHARGE){httpApi.pointCardSurplusRecharge(params)}
}
fun getPointCardSurplus() {
val username = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME,"")!!
val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN,"")!!
Logger.d("获取点卡信息")
val params =hashMapOf(
"phoneNumber" to username,
"phToken" to phToken
)
val httpApi = NetService.instances.createHttps(HttpApi::class.java)
doAsync(HttpReqType.GET_POINTCARD_SURPLUS) { httpApi.getPointCardSurplus(params) }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -33,8 +33,6 @@ import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import com.tencent.mmkv.MMKV
import com.yingmao.clash.R
import com.yingmao.clash.act.NewMainActivity.Companion.isSubed
import com.yingmao.clash.act.NewMainActivity.Companion.newUuid
import com.yingmao.clash.app.MainApplication
import com.yingmao.clash.base.BaseActivity
import com.yingmao.clash.conf.BZYConstants
@ -104,7 +102,7 @@ class SettingActivity : BaseActivity() {
}
findViewById<View>(R.id.ll_chushihua).setOnClickListener {
if (TextUtils.isEmpty(NewMainActivity.subUrl)){
if (TextUtils.isEmpty(UIMainActivity.subUrl)){
return@setOnClickListener
}
showLoading(resources.getString(R.string.UnderRepair), this@SettingActivity)
@ -116,9 +114,9 @@ class SettingActivity : BaseActivity() {
pm.delete(profile.uuid)
}
delay(1000)
if (NewMainActivity.subUrl?.isNotEmpty() == true) {
if (UIMainActivity.subUrl?.isNotEmpty() == true) {
startTimer()
setSub2(NewMainActivity.subUrl!!,pm);
setSub2(UIMainActivity.subUrl!!,pm);
}
}
}
@ -407,8 +405,8 @@ class SettingActivity : BaseActivity() {
Log.d("new main actname==>" + actname)
// Log.d("setSub2 pro 已存在 ==>" + Gson().toJson(pro))
pm.setActive(it)
newUuid = pro.uuid.toString();
isSubed = true
UIMainActivity.newUuid = pro.uuid.toString();
UIMainActivity.isSubed = true
Log.d("setSub2 setActive end")
finishInit()
} ?: run {
@ -432,8 +430,8 @@ class SettingActivity : BaseActivity() {
"new updateStatus: " + Gson().toJson(status.args) + ", pro==>" + status.progress
)
}
newUuid = qPro.uuid.toString();
isSubed = true
UIMainActivity.newUuid = qPro.uuid.toString();
UIMainActivity.isSubed = true
// }
}
finishInit()

View File

@ -45,7 +45,7 @@ import com.yingmao.clash.BuildConfig
import com.yingmao.clash.R
import com.yingmao.clash.app.MainApplication
import com.yingmao.clash.base.BaseActivity
import com.yingmao.clash.captcha.Captcha
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_IS_REGISTER
import com.yingmao.clash.conf.BZYConstants.Companion.MMKV_KEY_NOTE_DEFAULT_PSW
@ -471,56 +471,7 @@ class SplashActivity : BaseActivity() {
super.onStarted()
}
private fun graphicVerificationDialog() {
//开启人机验证
MaterialDialog(this).show {
this.cancelable(false)
cornerRadius(res = R.dimen.dp_10)
customView(
R.layout.graphic_verification_dialog_layout,
scrollable = false,
noVerticalPadding = true,
horizontalPadding = false
)
val captchaSimple = findViewById<Captcha>(R.id.captCha)
captchaSimple.setCaptchaListener(object : Captcha.CaptchaListener {
override fun onAccess(time: Long): String {
Toast.makeText(
this@SplashActivity,
resources.getString(R.string.VerificationSuccessful),
Toast.LENGTH_SHORT
).show()
dismiss()
val intent = Intent(this@SplashActivity, LoginActivity::class.java)
startActivity(intent)
finish()
return resources.getString(R.string.VerificationSuccessful)
.replace("%d", "$time")
}
override fun onFailed(failedCount: Int): String {
Toast.makeText(
this@SplashActivity,
resources.getString(R.string.VerificationFailed),
Toast.LENGTH_SHORT
).show()
return resources.getString(R.string.VerificationSuccessful)
.replace("%d", "$failedCount")
}
override fun onMaxFailed(): String {
Toast.makeText(
this@SplashActivity,
resources.getString(R.string.VerifiedOnce),
Toast.LENGTH_SHORT
)
.show()
finish()
return resources.getString(R.string.VerifiedOnce)
}
})
}
}
private fun isNeedRegister(isNeedRegister: Boolean) {
if (!BuildConfig.is_free && BuildConfig.productId.isNotEmpty()) { //渠道包都自动注册登录广州22222也是非自动注册

View File

@ -85,7 +85,7 @@ import java.util.UUID
class UIMainActivity : BaseActivity() {
private lateinit var bottomNavigationView: BottomNavigationView
private val fragments = arrayListOf<Fragment>()
val fragments = arrayListOf<Fragment>()
private lateinit var mainAtyVM: MainAtyVM
private var payResultLoading: RxDialogShapeLoading? = null
private val clashRunning: Boolean
@ -107,7 +107,7 @@ class UIMainActivity : BaseActivity() {
//记录心跳失败次数
var HEART_BEAT_FAILURE_FREQUENCY = 0
const val REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY = 1000
var isSubbed = false
var isSubed = false
var newUuid: String? = null
var subUrl: String? = null
var clashBinder: IClashManager? = null
@ -153,7 +153,7 @@ class UIMainActivity : BaseActivity() {
}
pm.update(it.uuid)
newUuid = mProfile.uuid.toString()
isSubbed = true
isSubed = true
} ?: run {
Log.d("setSub2 go create")
val uuid: UUID = pm.create(
@ -173,7 +173,7 @@ class UIMainActivity : BaseActivity() {
)
}
newUuid = qPro.uuid.toString()
isSubbed = true
isSubed = true
}
}
}
@ -465,7 +465,7 @@ class UIMainActivity : BaseActivity() {
if (clashRunning) {
fragments.filterIsInstance<HomeFragment>().forEach { it.stopClash() }
}
isSubbed=false
isSubed=false
stopUploadTimer()
mainAtyVM.stopHeartBeat()
cleanProfile()
@ -746,7 +746,7 @@ class UIMainActivity : BaseActivity() {
if (clashRunning) {
fragments.filterIsInstance<HomeFragment>().forEach { it.stopClash() }
}
isSubbed=false
isSubed=false
stopUploadTimer()
mainAtyVM.stopHeartBeat()
cleanProfile()

View File

@ -1,143 +0,0 @@
package com.yingmao.clash.act
import android.os.Bundle
import android.view.View
import android.widget.EditText
import android.widget.TextView
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.observe
import com.yingmao.clash.view.dialog.RxDialogShapeLoading
import com.tencent.mmkv.MMKV
import com.yingmao.clash.R
import com.yingmao.clash.base.BaseActivity
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.HttpStatus
import com.yingmao.clash.net.http.entity.AppDataInfoRsp
import com.yingmao.clash.net.http.entity.GetSMSCodeRsp
import com.yingmao.clash.view.RxToast
class ZFBTXActivity : BaseActivity() {
private lateinit var et_zfb_account: EditText
private lateinit var et_tixian_amount: EditText
private lateinit var tv_can_reward_amount: TextView
private var rewardAmount: String = ""
private lateinit var txAmount: String
private var isTiXia = false
private var zfbAccount = ""
private lateinit var rxDialogShapeLoading: RxDialogShapeLoading
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.layout_activity_zfbtx)
showTitleBar("现金奖励提现")
initView()
}
private fun initView() {
val viewModel = ViewModelProvider(this).get(ZFBTXAtyVM::class.java)
viewModel.statusData.observe(this) {
when (it) {
is HttpStatus.Loading -> {
rxDialogShapeLoading = RxDialogShapeLoading(this)
if (it.reqType == HttpReqType.APPDATAINFO) {
rxDialogShapeLoading.setMessage("正在获取可提现余额...")
} else {
rxDialogShapeLoading.setMessage("正在提现...")
}
rxDialogShapeLoading.show()
}
is HttpStatus.Success -> {
rxDialogShapeLoading.cancel()
if (it.reqType == HttpReqType.APPDATAINFO) {
(it.rsp as AppDataInfoRsp).let { appDataRsp ->
if (appDataRsp.code == 1000) {
rewardAmount = appDataRsp.data?.rewardTotalAmount!!
tv_can_reward_amount.text = "${rewardAmount}"
tv_can_reward_amount.isClickable = false
if (isTiXia) {
val phone = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME,"")!!
viewModel.appRewardAmount(phone, txAmount, zfbAccount)
}
} else {
RxToast.warning("获取可提现金额失败,请重试")
isTiXia = false
tv_can_reward_amount.text = "重试"
tv_can_reward_amount.setOnClickListener {
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
?.let { it1 -> viewModel.appDataInfo(it1) }
}
}
}
} else {
(it.rsp as GetSMSCodeRsp).let { rsp ->
if (rsp.code == 1000) {
RxToast.success("提现发起成功,请等待到账")
setResult(101)
finish()
// viewModel.appDataInfo(MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME))
} else {
RxToast.warning("提现失败:${rsp.message}")
}
}
}
}
is HttpStatus.Failure -> {
rxDialogShapeLoading.cancel()
if (it.reqType == HttpReqType.APPDATAINFO) {
RxToast.warning("获取可提现金额失败,请检查网络")
tv_can_reward_amount.setOnClickListener {
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
?.let { it1 -> viewModel.appDataInfo(it1) }
}
} else {
RxToast.warning("提现失败,请检查网络")
}
}
}
}
et_zfb_account = findViewById(R.id.et_zfb_account)
tv_can_reward_amount = findViewById(R.id.tv_can_reward_amount)
et_tixian_amount = findViewById(R.id.et_tixian_amount)
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
?.let { viewModel.appDataInfo(it) }
findViewById<View>(R.id.btn_tixian).setOnClickListener {
zfbAccount = et_zfb_account.text.trim().toString()
txAmount = et_tixian_amount.text.trim().toString()
if (zfbAccount.isEmpty() || zfbAccount.length < 3) {
RxToast.warning("请输入有效的支付宝账号")
} else {
if (!isNumber(txAmount)) {
RxToast.warning("请输入有效的金额")
return@setOnClickListener
}
if (rewardAmount.isEmpty()) {
RxToast.warning("未能获取到可提现金额,请重试")
return@setOnClickListener
}
if (txAmount.toFloat() > rewardAmount.toFloat()) {
RxToast.warning("已超过可提现金额")
return@setOnClickListener
}
isTiXia = true
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
?.let { it1 -> viewModel.appDataInfo(it1) }
}
}
}
fun isNumber(str: String): Boolean {
val regex = Regex("^[1-9]\\d*(\\.[0-9]+)?$")
return regex.matches(str)
}
}

View File

@ -1,33 +0,0 @@
package com.yingmao.clash.act
import com.tencent.mmkv.MMKV
import com.yingmao.clash.base.PublicViewMode
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.net.http.HttpApi
import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.NetService
class ZFBTXAtyVM : PublicViewMode() {
fun appRewardAmount(phone: String, rewardAmount: String, payAccount: String) {
val httpApi = NetService.instances.createHttps(HttpApi::class.java)
val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN,"")!!
val params = mutableMapOf(
"phoneNumber" to phone,
"rewardAmount" to rewardAmount,
"payAccount" to payAccount,
"phToken" to phToken,
)
doAsync(HttpReqType.APPREWARDAMOUNT) { httpApi.appRewardAmount(params) }
}
fun appDataInfo(phone: String) {
val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN,"")!!
val params = mutableMapOf(
"phoneNumber" to phone,
"phToken" to phToken
)
val httpApi = NetService.instances.createHttps(HttpApi::class.java)
doAsync(HttpReqType.APPDATAINFO) { httpApi.appDataInfo(params) }
}
}

View File

@ -24,7 +24,6 @@ import com.orhanobut.logger.Logger
import com.tencent.mmkv.MMKV
import com.yingmao.clash.BuildConfig
import com.yingmao.clash.R
import com.yingmao.clash.act.MainActivity
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.conf.Conf
import com.cncat.vpn.core.bridge.ClashException

View File

@ -15,7 +15,6 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import com.orhanobut.logger.Logger
import com.yingmao.clash.R
import com.yingmao.clash.act.MainActivity
import com.cncat.vpn.common.log.Log
//import com.yingmao.clash.design.model.DarkMode
//import com.yingmao.clash.design.store.UiStore

View File

@ -1,68 +0,0 @@
package com.yingmao.clash.captcha;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* 网络加载图片的Task类
*
*/
class BitmapLoaderTask extends AsyncTask<String, Integer, Bitmap> {
private Callback callback;
public BitmapLoaderTask(Callback callback) {
this.callback = callback;
}
interface Callback{
void result(Bitmap bitmap);
}
@Override
protected Bitmap doInBackground(String... params) {
Bitmap result = null;
URL url = null;
HttpURLConnection conn = null;
InputStream is = null;
try {
url = new URL(params[0]);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
int code = conn.getResponseCode();
if (code == 200) {
is = conn.getInputStream();
result = BitmapFactory.decodeStream(is);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (is != null) {
is.close();
}
if (conn != null) {
conn.disconnect();
}
} catch (Exception e) {
e.printStackTrace();
}
}
return result;
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
callback.result(bitmap);
}
}

View File

@ -1,352 +0,0 @@
package com.yingmao.clash.captcha;
import android.animation.Animator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import androidx.annotation.AttrRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.yingmao.clash.R;
/**
* Created by luozhanming on 2018/1/17.
*/
public class Captcha extends LinearLayout {
//控件成员
private PictureVertifyView vertifyView; //拼图块
private TextSeekbar seekbar; //滑动条块
private View accessSuccess, accessFailed; //验证成功/失败显示的视图
private TextView accessText, accessFailedText; //验证成功/失败显示的文字
private ImageView refreshView; //刷新按钮
//控件属性
private int drawableId = -1; //验证图片资源id
private int progressDrawableId; //滑动条背景id
private int thumbDrawableId; //滑动条滑块id
private int mMode; //控件验证模式(有滑动条/无滑动条)
private int maxFailedCount; //最大失败次数
private int failCount; //已失败次数
private int blockSize; //拼图缺块大小
//处理滑动条逻辑
private boolean isResponse;
private boolean isDown;
private CaptchaListener mListener;
private BitmapLoaderTask mTask;
/**
* 带滑动条验证模式
*/
public static final int MODE_BAR = 1;
/**
* 不带滑动条验证手触模式
*/
public static final int MODE_NONBAR = 2;
@IntDef(value = {MODE_BAR, MODE_NONBAR})
public @interface Mode {
}
public interface CaptchaListener {
/**
* Called when captcha access.
*
* @param time cost of access time
* @return text to show,show default when return null
*/
String onAccess(long time);
/**
* Called when captcha failed.
*
* @param failCount fail count
* @return text to show,show default when return null
*/
String onFailed(int failCount);
/**
* Called when captcha failed
*
* @return text to show,show default when return null
*/
String onMaxFailed();
}
public Captcha(@NonNull Context context) {
super(context);
}
public Captcha(@NonNull Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public Captcha(@NonNull final Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.Captcha);
// drawableId = typedArray.getResourceId(R.styleable.Captcha_src, R.drawable.gv_icon);
progressDrawableId = typedArray.getResourceId(R.styleable.Captcha_progressDrawable, R.drawable.po_seekbar);
thumbDrawableId = typedArray.getResourceId(R.styleable.Captcha_thumbDrawable,R.drawable.thumb);
mMode = typedArray.getInteger(R.styleable.Captcha_mode, MODE_BAR);
maxFailedCount = typedArray.getInteger(R.styleable.Captcha_max_fail_count, 3);
blockSize = typedArray.getDimensionPixelSize(R.styleable.Captcha_blockSize, Utils.dp2px(getContext(), 50));
typedArray.recycle();
init();
}
private void init() {
View parentView = LayoutInflater.from(getContext()).inflate(R.layout.container, this, true);
vertifyView = (PictureVertifyView) parentView.findViewById(R.id.vertifyView);
seekbar = (TextSeekbar) parentView.findViewById(R.id.seekbar);
accessSuccess = parentView.findViewById(R.id.accessRight);
accessFailed = parentView.findViewById(R.id.accessFailed);
accessText = (TextView) parentView.findViewById(R.id.accessText);
accessFailedText = (TextView) parentView.findViewById(R.id.accessFailedText);
refreshView = (ImageView) parentView.findViewById(R.id.refresh);
setMode(mMode);
if(drawableId!=-1){
vertifyView.setImageResource(drawableId);
}
setBlockSize(blockSize);
vertifyView.callback(new PictureVertifyView.Callback() {
@Override
public void onSuccess(long time) {
if (mListener != null) {
String s = mListener.onAccess(time);
if (s != null) {
accessText.setText(s);
} else {//默认文案
accessText.setText(String.format(getResources().getString(R.string.vertify_access), time));
}
}
accessSuccess.setVisibility(VISIBLE);
accessFailed.setVisibility(GONE);
}
@Override
public void onFailed() {
seekbar.setEnabled(false);
vertifyView.setTouchEnable(false);
failCount = failCount > maxFailedCount ? maxFailedCount : failCount + 1;
accessFailed.setVisibility(VISIBLE);
accessSuccess.setVisibility(GONE);
if (mListener != null) {
if (failCount == maxFailedCount) {
String s = mListener.onMaxFailed();
if (s != null) {
accessFailedText.setText(s);
} else {//默认文案
accessFailedText.setText(String.format(getResources().getString(R.string.vertify_failed), maxFailedCount - failCount));
}
} else {
String s = mListener.onFailed(failCount);
if (s != null) {
accessFailedText.setText(s);
} else {//默认文案
accessFailedText.setText(String.format(getResources().getString(R.string.vertify_failed), maxFailedCount - failCount));
}
}
}
}
});
setSeekBarStyle(progressDrawableId, thumbDrawableId);
//用于处理滑动条渐滑逻辑
seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (isDown) { //手指按下
isDown = false;
if (progress > 10) { //按下位置不正确
isResponse = false;
} else {
isResponse = true;
accessFailed.setVisibility(GONE);
vertifyView.down(0);
}
}
if (isResponse) {
vertifyView.move(progress);
} else {
seekBar.setProgress(0);
}
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
isDown = true;
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
if (isResponse) {
vertifyView.loose();
}
}
});
refreshView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startRefresh(v);
}
});
}
private void startRefresh(View v) {
//点击刷新按钮启动动画
v.animate().rotationBy(360).setDuration(500)
.setInterpolator(new AccelerateDecelerateInterpolator())
.setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
reset(false);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
public void setCaptchaListener(CaptchaListener listener) {
this.mListener = listener;
}
public void setCaptchaStrategy(CaptchaStrategy strategy) {
if (strategy != null) {
vertifyView.setCaptchaStrategy(strategy);
}
}
public void setSeekBarStyle(@DrawableRes int progressDrawable, @DrawableRes int thumbDrawable) {
seekbar.setProgressDrawable(getResources().getDrawable(progressDrawable));
seekbar.setThumb(getResources().getDrawable(thumbDrawable));
seekbar.setThumbOffset(0);
}
/**
* 设置滑块图片大小单位px
*/
public void setBlockSize(int blockSize) {
vertifyView.setBlockSize(blockSize);
}
/**
* 设置滑块验证模式
*/
public void setMode(@Mode int mode) {
this.mMode = mode;
vertifyView.setMode(mode);
if (mMode == MODE_NONBAR) {
seekbar.setVisibility(GONE);
vertifyView.setTouchEnable(true);
} else {
seekbar.setVisibility(VISIBLE);
seekbar.setEnabled(true);
}
hideText();
}
public int getMode() {
return this.mMode;
}
public void setMaxFailedCount(int count) {
this.maxFailedCount = count;
}
public int getMaxFailedCount() {
return this.maxFailedCount;
}
public void setBitmap(int drawableId) {
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), drawableId);
setBitmap(bitmap);
}
public void setBitmap(Bitmap bitmap) {
vertifyView.setImageBitmap(bitmap);
reset(false);
}
public void setBitmap(String url) {
mTask = new BitmapLoaderTask(new BitmapLoaderTask.Callback() {
@Override
public void result(Bitmap bitmap) {
setBitmap(bitmap);
}
});
mTask.execute(url);
}
@Override
protected void onDetachedFromWindow() {
if(mTask!=null&&mTask.getStatus().equals(AsyncTask.Status.RUNNING)){
mTask.cancel(true);
}
super.onDetachedFromWindow();
}
/**
* 复位
* @param clearFailed 是否清除失败次数
*/
public void reset(boolean clearFailed) {
hideText();
vertifyView.reset();
if (clearFailed) {
failCount = 0;
}
if (mMode == MODE_BAR) {
seekbar.setEnabled(true);
seekbar.setProgress(0);
} else {
vertifyView.setTouchEnable(true);
}
}
/**
* 隐藏成功失败文字显示
* */
public void hideText() {
accessFailed.setVisibility(GONE);
accessSuccess.setVisibility(GONE);
}
}

View File

@ -1,70 +0,0 @@
package com.yingmao.clash.captcha;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
/**
* Captcha的拼图区域策咯
*
*/
public abstract class CaptchaStrategy {
protected Context mContext;
public CaptchaStrategy(Context ctx) {
this.mContext = ctx;
}
protected Context getContext() {
return mContext;
}
/**
* 定义缺块的形状
*
* @param blockSize 单位dp注意转化为px
* @return path of the shape
*/
public abstract Path getBlockShape(int blockSize);
/**
* 定义缺块的位置信息
*
* @param width picture width unit:px
* @param height picture height unit:px
* @param blockSize
* @return position info of the block
*/
public abstract PositionInfo getBlockPostionInfo(int width, int height, int blockSize);
/**
* 定义滑块图片的位置信息(只有设置为无滑动条模式有用)
*
* @param width picture width
* @param height picture height
* @return position info of the block
*/
public PositionInfo getPositionInfoForSwipeBlock(int width, int height, int blockSize){
return getBlockPostionInfo(width,height,blockSize);
}
/**
* 获得缺块阴影的Paint
*/
public abstract Paint getBlockShadowPaint();
/**
* 获得滑块图片的Paint
*/
public abstract Paint getBlockBitmapPaint();
/**
* 装饰滑块图片在绘制图片后执行即绘制滑块前景
*/
public void decoreateSwipeBlockBitmap(Canvas canvas, Path shape) {
}
}

View File

@ -1,96 +0,0 @@
package com.yingmao.clash.captcha;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Path;
import androidx.annotation.NonNull;
import java.util.Random;
/**
* 默认CaptchaStrategy
*
*/
public class DefaultCaptchaStrategy extends CaptchaStrategy {
public DefaultCaptchaStrategy(Context ctx) {
super(ctx);
}
@Override
public Path getBlockShape(int blockSize) {
int gap = (int) (blockSize/5f);
Path path = new Path();
path.moveTo(0, gap);
path.rLineTo(blockSize/2.5f, 0);
path.rLineTo(0, -gap);
path.rLineTo(gap, 0);
path.rLineTo(0, gap);
path.rLineTo(2 * gap, 0);
path.rLineTo(0, 4 * gap);
path.rLineTo(-5 * gap, 0);
path.rLineTo(0, -1.5f * gap);
path.rLineTo(gap, 0);
path.rLineTo(0, -gap);
path.rLineTo(-gap, 0);
path.close();
return path;
}
@Override
public @NonNull PositionInfo getBlockPostionInfo(int width, int height, int blockSize) {
Random random = new Random();
int left = random.nextInt(width - blockSize +1);
//Avoid robot frequently and quickly click the start point to access the captcha.
if (left < blockSize) {
left = blockSize;
}
int top = random.nextInt(height - blockSize +1);
if (top < 0) {
top = 0;
}
return new PositionInfo(left, top);
}
@Override
public @NonNull PositionInfo getPositionInfoForSwipeBlock(int width, int height, int blockSize) {
Random random = new Random();
int left = random.nextInt(width - blockSize+1);
int top = random.nextInt(height - blockSize+1);
if (top < 0) {
top = 0;
}
return new PositionInfo(left, top);
}
@Override
public Paint getBlockShadowPaint() {
Paint shadowPaint = new Paint();
shadowPaint.setColor(Color.parseColor("#000000"));
shadowPaint.setAlpha(165);
return shadowPaint;
}
@Override
public Paint getBlockBitmapPaint() {
Paint paint = new Paint();
return paint;
}
@Override
public void decoreateSwipeBlockBitmap(Canvas canvas, Path shape) {
Paint paint = new Paint();
paint.setColor(Color.parseColor("#FFFFFF"));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(10);
paint.setPathEffect(new DashPathEffect(new float[]{20,20},10));
Path path = new Path(shape);
canvas.drawPath(path,paint);
}
}

View File

@ -1,304 +0,0 @@
package com.yingmao.clash.captcha;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatImageView;
/**
* 拼图区域控件
*
*/
class PictureVertifyView extends AppCompatImageView {
//状态码
private static final int STATE_DOWN = 1;
private static final int STATE_MOVE = 2;
private static final int STATE_LOOSEN = 3;
private static final int STATE_IDEL = 4;
private static final int STATE_ACCESS = 5;
private static final int STATE_UNACCESS = 6;
private static final int TOLERANCE = 10; //验证的最大容差
private int mState = STATE_IDEL; //当前状态
private PositionInfo shadowInfo; //拼图缺块阴影的位置
private PositionInfo blockInfo; //拼图缺块的位置
private Bitmap verfityBlock; //拼图缺块Bitmap
private Path blockShape; //拼图缺块形状
private Paint bitmapPaint; //绘制拼图缺块的画笔
private Paint shadowPaint; //绘制拼图缺块阴影的画笔
private long startTouchTime; //滑动/触动开始时间
private long looseTime; //滑动/触动松开时间
private int blockSize = 50;
private boolean mTouchEnable = true; //是否可触动
private Callback callback;
private CaptchaStrategy mStrategy;
private int mMode; //Captcha验证模式
interface Callback {
void onSuccess(long time);
void onFailed();
}
public PictureVertifyView(Context context) {
this(context, null);
}
public PictureVertifyView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public PictureVertifyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mStrategy = new DefaultCaptchaStrategy(context);
shadowPaint = mStrategy.getBlockShadowPaint();
bitmapPaint = mStrategy.getBlockBitmapPaint();
setLayerType(View.LAYER_TYPE_SOFTWARE, bitmapPaint);
}
private void initDrawElements(){
if (shadowInfo == null) {
shadowInfo = mStrategy.getBlockPostionInfo(getWidth(), getHeight(), blockSize);
if (mMode == Captcha.MODE_BAR) {
blockInfo = new PositionInfo(0, shadowInfo.top);
} else {
blockInfo = mStrategy.getPositionInfoForSwipeBlock(getWidth(), getHeight(), blockSize);
}
}
if (blockShape == null) {
blockShape = mStrategy.getBlockShape(blockSize);
blockShape.offset(shadowInfo.left, shadowInfo.top);
}
if (verfityBlock == null) {
verfityBlock = createBlockBitmap();
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
initDrawElements();
if (mState != STATE_ACCESS) {
canvas.drawPath(blockShape, shadowPaint);
}
if (mState == STATE_MOVE || mState == STATE_IDEL || mState == STATE_DOWN || mState == STATE_UNACCESS) {
canvas.drawBitmap(verfityBlock, blockInfo.left, blockInfo.top, bitmapPaint);
}
}
/**
*按下滑动条(滑动条模式)
* */
void down(int progress) {
startTouchTime = System.currentTimeMillis();
mState = STATE_DOWN;
blockInfo.left = (int) (progress / 100f * (getWidth() - blockSize));
invalidate();
}
/**
*触动拼图块(触动模式)
* */
void downByTouch(float x, float y) {
mState = STATE_DOWN;
blockInfo.left = (int) (x - blockSize / 2f);
blockInfo.top = (int) (y - blockSize / 2f);
startTouchTime = System.currentTimeMillis();
invalidate();
}
/**
* 移动拼图缺块(滑动条模式)
*/
void move(int progress) {
mState = STATE_MOVE;
blockInfo.left = (int) (progress / 100f * (getWidth() - blockSize));
invalidate();
}
/**
* 触动拼图缺块(触动模式)
*/
void moveByTouch(float offsetX, float offsetY) {
mState = STATE_MOVE;
blockInfo.left += offsetX;
blockInfo.top += offsetY;
invalidate();
}
/**
* 松开
* */
void loose() {
mState = STATE_LOOSEN;
looseTime = System.currentTimeMillis();
checkAccess();
invalidate();
}
/**
* 复位
* */
void reset() {
mState = STATE_IDEL;
verfityBlock = null;
shadowInfo = null;
blockShape = null;
invalidate();
}
void unAccess() {
mState = STATE_UNACCESS;
invalidate();
}
void access() {
mState = STATE_ACCESS;
invalidate();
}
void callback(Callback callback) {
this.callback = callback;
}
void setCaptchaStrategy(CaptchaStrategy strategy) {
this.mStrategy = strategy;
}
void setBlockSize(int size) {
this.blockSize = size;
this.blockShape = null;
this.blockInfo = null;
this.shadowInfo = null;
this.verfityBlock = null;
invalidate();
}
public void setBitmap(Bitmap bitmap) {
this.blockShape = null;
this.blockInfo = null;
this.shadowInfo = null;
this.verfityBlock.recycle();
this.verfityBlock = null;
setImageBitmap(bitmap);
}
void setMode(@Captcha.Mode int mode) {
this.mMode = mode;
this.blockShape = null;
this.blockInfo = null;
this.shadowInfo = null;
this.verfityBlock = null;
invalidate();
}
void setTouchEnable(boolean enable) {
this.mTouchEnable = enable;
}
/**
* 生成拼图缺块的Bitmap
* */
private Bitmap createBlockBitmap() {
Bitmap tempBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(tempBitmap);
getDrawable().setBounds(0, 0, getWidth(), getHeight());
canvas.clipPath(blockShape);
getDrawable().draw(canvas);
mStrategy.decoreateSwipeBlockBitmap(canvas, blockShape);
return cropBitmap(tempBitmap);
}
/**
* 保留拼图缺块大小的bitmap
* */
private Bitmap cropBitmap(Bitmap bmp) {
Bitmap result = null;
result = Bitmap.createBitmap(bmp, shadowInfo.left, shadowInfo.top, blockSize, blockSize);
bmp.recycle();
return result;
}
/**
* 检测是否通过
*/
private void checkAccess() {
if (Math.abs(blockInfo.left - shadowInfo.left) < TOLERANCE && Math.abs(blockInfo.top - shadowInfo.top) < TOLERANCE) {
access();
if (callback != null) {
long deltaTime = looseTime - startTouchTime;
callback.onSuccess(deltaTime);
}
} else {
unAccess();
if (callback != null) {
callback.onFailed();
}
}
}
private float tempX, tempY, downX, downY;
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
//触动模式下点击超出拼图缺块的区域不进行处理
if (event.getAction() == MotionEvent.ACTION_DOWN && mMode == Captcha.MODE_NONBAR) {
if (event.getX() < blockInfo.left || event.getX() > blockInfo.left + blockSize || event.getY() < blockInfo.top || event.getY() > blockInfo.top + blockSize) {
return false;
}
}
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mMode == Captcha.MODE_NONBAR && verfityBlock != null && mTouchEnable) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downX = x;
downY = y;
downByTouch(x, y);
break;
case MotionEvent.ACTION_UP:
loose();
break;
case MotionEvent.ACTION_MOVE:
float offsetX = x - tempX;
float offsetY = y - tempY;
moveByTouch(offsetX, offsetY);
break;
}
tempX = x;
tempY = y;
}
return true;
}
}

View File

@ -1,13 +0,0 @@
package com.yingmao.clash.captcha;
public class PositionInfo {
int left; //拼图缺块离整张图片左边距离
int top; //拼图缺块离整张图片上方距离
public PositionInfo(int left, int top) {
this.left = left;
this.top = top;
}
}

View File

@ -1,44 +0,0 @@
package com.yingmao.clash.captcha;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import androidx.appcompat.widget.AppCompatSeekBar;
import com.yingmao.clash.R;
class TextSeekbar extends AppCompatSeekBar {
private Paint textPaint;
public TextSeekbar(Context context) {
super(context);
}
public TextSeekbar(Context context, AttributeSet attrs) {
this(context, attrs, R.style.MySeekbarSytle);
}
public TextSeekbar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
textPaint = new Paint();
textPaint.setTextAlign(Paint.Align.CENTER);
int textSize = Utils.dp2px(context, 14);
textPaint.setTextSize(textSize);
textPaint.setAntiAlias(true);
textPaint.setColor(Color.parseColor("#545454"));
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
float top = fontMetrics.top;//为基线到字体上边框的距离,即上图中的top
float bottom = fontMetrics.bottom;//为基线到字体下边框的距离,即上图中的bottom
int baseLineY = (int) (getHeight() / 2 - top / 2 - bottom / 2);//基线中间点的y轴计算公式
canvas.drawText("向右滑动滑块完成拼图", getWidth() / 2, baseLineY, textPaint);
}
}

View File

@ -1,15 +0,0 @@
package com.yingmao.clash.captcha;
import android.content.Context;
public class Utils {
/**
* dp转px
* */
public static int dp2px(Context ctx, float dip) {
float density = ctx.getResources().getDisplayMetrics().density;
return (int) (dip * density);
}
}

View File

@ -29,9 +29,6 @@ import com.orhanobut.logger.Logger
import com.tencent.mmkv.MMKV
import com.yingmao.clash.R
import com.yingmao.clash.act.ChangeNodeActivity
import com.yingmao.clash.act.NewMainActivity
import com.yingmao.clash.act.NewMainActivity.Companion.isSubed
import com.yingmao.clash.act.NewMainActivity.Companion.newUuid
import com.yingmao.clash.act.ProxyModeActivity
import com.yingmao.clash.act.UIMainActivity
import com.yingmao.clash.conf.BZYConstants
@ -193,7 +190,7 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
updateUserInfo()
}
setExpireDate()
setProxyModeView(NewMainActivity.newMainActGlo)
setProxyModeView(UIMainActivity.newMainActGlo)
}
override fun onResume() {
@ -228,8 +225,8 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
return
}
val intent = Intent(CommonUtils.getApp(), ChangeNodeActivity::class.java)
if (!TextUtils.isEmpty(NewMainActivity.newUuid)) {
intent.putExtra(BZYConstants.MMKV_KEY_CURRENT_NODE, NewMainActivity.newUuid)
if (!TextUtils.isEmpty(UIMainActivity.newUuid)) {
intent.putExtra(BZYConstants.MMKV_KEY_CURRENT_NODE, UIMainActivity.newUuid)
intent.putExtra(BZYConstants.EXTRA_KEY_IS_RUNING, clashRunning)
}
startActivityForResult(intent, CHECK_NODE_REQUEST_CODE)
@ -307,15 +304,15 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
com.cncat.vpn.common.log.Log.d("new setactive name " + profile.name)
pm.setActive(profile)
newUuid = profile.uuid.toString();
isSubed = true
UIMainActivity.newUuid = profile.uuid.toString();
UIMainActivity.isSubed = true
} ?: run {
//为空的情况下选择第一个
pm.queryAll().forEach { profile ->
pm.setActive(profile)
newUuid = profile.uuid.toString();
isSubed = true
UIMainActivity.newUuid = profile.uuid.toString();
UIMainActivity.isSubed = true
return@forEach
}
}
@ -661,35 +658,35 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
private fun goRechargeWeb() {
if (activity != null) {
var mact = activity as NewMainActivity
var mact = activity as UIMainActivity
mact.goRechargeWeb()
}
}
private fun goNewRecharge() {
if (activity != null) {
var mact = activity as NewMainActivity
var mact = activity as UIMainActivity
mact.goBackupRechargeWeb()
}
}
private fun updateUserInfo() {
if (activity != null) {
var mact = activity as NewMainActivity
var mact = activity as UIMainActivity
mact.goCheckLogin()
}
}
private fun start_u_timer() {
if (activity != null) {
var mact = activity as NewMainActivity
var mact = activity as UIMainActivity
mact.startUploadTimer()
}
}
private fun stop_u_timer() {
if (activity != null) {
var mact = activity as NewMainActivity
var mact = activity as UIMainActivity
mact.stopUploadTimer()
}
}
@ -764,7 +761,7 @@ class NewAccFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatch
MMKV.defaultMMKV().decodeString(BZYConstants.NODE_SELECTED_NAME_KEY, "");
Log.d("getNodes selected_name==>${selected_name}")
if (TextUtils.isEmpty(selected_name)) {
NewMainActivity.subUrl?.let {
UIMainActivity.subUrl?.let {
accelerateViewModel?.get_Node_Other(it, object : AsyncCallBackListener {
override fun suc(obj: Any?) {
proList = obj as MutableList<ClashNodebBean>

View File

@ -1,249 +0,0 @@
package com.yingmao.clash.fragment.mine
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.appcompat.widget.SwitchCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.observe
import com.yingmao.clash.act.BandPhoneActivity
import com.yingmao.clash.act.ChangePwdActivity
import com.yingmao.clash.act.MyPointCardActivity
import com.yingmao.clash.act.ShareActivity
import com.yingmao.clash.act.ZFBTXActivity
import com.yingmao.clash.view.dialog.DialogBandChoose
import com.tencent.mmkv.MMKV
import com.yingmao.clash.BuildConfig
import com.yingmao.clash.R
import com.yingmao.clash.act.ExpensesRecordActivity
import com.yingmao.clash.act.LoginActivity
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.net.http.HttpStatus
import com.yingmao.clash.net.http.entity.AppDataInfoRsp
import com.yingmao.clash.util.CommonUtils
import com.yingmao.clash.view.RxToast
import java.text.SimpleDateFormat
import java.util.Locale
class MineFragment : Fragment(), View.OnClickListener {
private lateinit var exitTv: TextView
private lateinit var usernameTv: TextView
private lateinit var versionNameTv: TextView
private lateinit var expensesRecordTv: TextView
private lateinit var changePasswordTv: TextView
private lateinit var commonProblemTv: TextView
private lateinit var pointCardTv: TextView
private lateinit var bandGiftTv: TextView
private lateinit var tv_tixian_amount: TextView
private lateinit var expireDateTv: TextView
private lateinit var tvProxyModel: TextView
private lateinit var supportAccelerationStatusTv: TextView
private lateinit var currentVersionRl: RelativeLayout
private lateinit var scProxyModel: SwitchCompat
private lateinit var rl_band_phone: View
private var canRewardAmount: String = ""
companion object {
fun newInstance() = MineFragment()
}
private lateinit var viewModel: MineViewModel
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val view = inflater.inflate(R.layout.fragment_mine, container, false)
initViews(view)
return view
}
private fun initViews(view: View?) {
view?.let {
usernameTv = it.findViewById(R.id.tv_username)
versionNameTv = it.findViewById(R.id.tv_version_name)
versionNameTv.text = BuildConfig.VERSION_NAME
usernameTv.text = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
exitTv = it.findViewById(R.id.tv_exit)
exitTv.setOnClickListener(this)
expensesRecordTv = it.findViewById(R.id.tv_expenses_record)
expensesRecordTv.setOnClickListener(this)
changePasswordTv = it.findViewById(R.id.tv_change_password)
changePasswordTv.setOnClickListener(this)
commonProblemTv = it.findViewById(R.id.tv_common_problem)
commonProblemTv.setOnClickListener(this)
pointCardTv = it.findViewById(R.id.tv_point_card)
pointCardTv.setOnClickListener(this)
currentVersionRl = it.findViewById(R.id.rl_current_version)
currentVersionRl.setOnClickListener(this)
it.findViewById<View>(R.id.rl_kefu).setOnClickListener(this)
it.findViewById<View>(R.id.rl_add_freiend).setOnClickListener(this)
rl_band_phone = it.findViewById(R.id.rl_band_phone)
it.findViewById<View>(R.id.rl_tixian).setOnClickListener(this)
bandGiftTv = it.findViewById(R.id.tv_band_gift)
tv_tixian_amount = it.findViewById(R.id.tv_tixian_amount)
tvProxyModel = it.findViewById(R.id.tv_proxy_model)
scProxyModel = it.findViewById(R.id.sc_proxy_model)
scProxyModel.setOnCheckedChangeListener { _, b ->
MMKV.defaultMMKV().encode(BZYConstants.MMKV_KEY_GLOBAL_MODEL, b)
if (b) {
tvProxyModel.setText("全局模式")
} else {
tvProxyModel.setText("智能模式")
}
RxToast.success("已切换,重连接生效")
}
if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_GLOBAL_MODEL)) {
tvProxyModel.setText("全局模式")
}
if (MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_IS_PERFECT)) {
rl_band_phone.setOnClickListener(this)
rl_band_phone.visibility = View.VISIBLE
}
expireDateTv = it.findViewById(R.id.tv_expire_date)
val validPeriod = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD)
if (validPeriod > 0) {
val dateFormat = SimpleDateFormat("yyyy.MM.dd HH:mm", Locale.CHINA)
expireDateTv.text = dateFormat.format(validPeriod)
} else {
expireDateTv.text = "--"
}
supportAccelerationStatusTv = it.findViewById(R.id.tv_support_acceleration_status)
val isExpired = MMKV.defaultMMKV().decodeBool(BZYConstants.MMKV_KEY_VPN_EXPIRED)
val valid_period = MMKV.defaultMMKV().decodeLong(BZYConstants.MMKV_KEY_VPN_VALID_PERIOD)
updateAccountStatus(isExpired, valid_period)
}
viewModel = ViewModelProvider(this).get(MineViewModel::class.java)
viewModel.statusData.observe(viewLifecycleOwner) {
when (it) {
is HttpStatus.Success -> {
(it.rsp as AppDataInfoRsp).let { data ->
if (data.code == 1000) {
bandGiftTv.text = "完善成功,赠送 ${data.data?.dataGiftdays}"
// tv_tixian_amount.text = "可提现金额 ${data.data?.rewardTotalAmount} 元"
if (data.data?.rewardTotalAmount != null) {
canRewardAmount = data.data?.rewardTotalAmount!!
}
}
}
}
else -> {}
}
}
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME)
?.let { viewModel.appDataInfo(it) }
}
/*override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
}*/
override fun onClick(v: View?) {
when (v?.id) {
R.id.tv_expenses_record -> {
val intent = Intent(CommonUtils.getApp(), ExpensesRecordActivity::class.java)
startActivity(intent)
}
R.id.tv_point_card -> {
val intent = Intent(CommonUtils.getApp(), MyPointCardActivity::class.java)
startActivity(intent)
}
R.id.tv_change_password -> {
val intent = Intent(CommonUtils.getApp(), ChangePwdActivity::class.java)
startActivity(intent)
}
R.id.rl_kefu -> {
val intent = Intent(Intent.ACTION_VIEW)
val uri = Uri.parse("https://t.me/bazhuayuvpn")
intent.setData(uri)
startActivity(intent)
}
R.id.rl_current_version -> {
RxToast.success("已经是最新版本")
}
R.id.tv_exit -> {
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_TOKEN)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_CURRENT_NODE)
startActivity(Intent(CommonUtils.getApp(), LoginActivity::class.java))
activity?.finish()
}
R.id.rl_add_freiend -> {
val intent = Intent(CommonUtils.getApp(), ShareActivity::class.java)
startActivity(intent)
}
R.id.rl_band_phone -> {
val dialog = DialogBandChoose(activity)
dialog.setOnBandClickListener(object : DialogBandChoose.OnBandClickListener {
override fun onBandClick(isPhone: Boolean) {
val intent = Intent(CommonUtils.getApp(), BandPhoneActivity::class.java)
intent.putExtra("isPhone", isPhone)
startActivityForResult(intent, 98)
}
})
dialog.show()
}
R.id.rl_tixian -> {
val intent = Intent(CommonUtils.getApp(), ZFBTXActivity::class.java)
startActivityForResult(intent, 90)
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == 98 && resultCode == 100) {
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_TOKEN)
MMKV.defaultMMKV().removeValueForKey(BZYConstants.MMKV_KEY_CURRENT_NODE)
startActivity(Intent(CommonUtils.getApp(), LoginActivity::class.java))
activity?.finish()
} else if (requestCode == 90 && resultCode == 101) {
// viewModel.appDataInfo(MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME))
}
}
fun updateAccountStatus(isExpired: Boolean, validityPeriod: Long) {
if (::supportAccelerationStatusTv.isInitialized) {
if (isExpired) {
supportAccelerationStatusTv.text = "不支持加速"
} else {
supportAccelerationStatusTv.text = "支持加速"
}
}
if (::expireDateTv.isInitialized) {
if (validityPeriod > 0) {
val dateFormat = SimpleDateFormat("yyyy.MM.dd HH:mm", Locale.CHINA)
expireDateTv.text = dateFormat.format(validityPeriod)
} else {
expireDateTv.text = "--"
}
}
}
}

View File

@ -1,25 +0,0 @@
package com.yingmao.clash.fragment.mine
import com.tencent.mmkv.MMKV
import com.yingmao.clash.base.PublicViewMode
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.net.http.HttpApi
import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.NetService
class MineViewModel : PublicViewMode() {
fun appDataInfo(phone: String) {
val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN,"")!!
val params = mutableMapOf(
"phoneNumber" to phone,
"phToken" to phToken
)
val httpApi = NetService.instances.createHttps(HttpApi::class.java)
doAsync(HttpReqType.APPDATAINFO) { httpApi.appDataInfo(params) }
}
}

View File

@ -1,952 +0,0 @@
package com.yingmao.clash.fragment.recharge
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.ProgressBar
import android.widget.RelativeLayout
import android.widget.Switch
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.widget.AppCompatImageView
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.customview.customView
import com.afollestad.materialdialogs.customview.getCustomView
import com.alipay.sdk.app.PayTask
import com.chad.library.adapter.base.BaseQuickAdapter
//import com.google.zxing.BarcodeFormat
//import com.google.zxing.MultiFormatWriter
//import com.journeyapps.barcodescanner.BarcodeEncoder
import com.orhanobut.logger.Logger
import com.stripe.android.PaymentConfiguration
import com.stripe.android.Stripe
import com.stripe.android.confirmAlipayPayment
import com.stripe.android.model.ConfirmPaymentIntentParams
import com.stripe.android.model.StripeIntent
import com.tencent.mmkv.MMKV
import com.yingmao.clash.R
import com.yingmao.clash.act.ExpensesRecordActivity
import com.yingmao.clash.act.NewMainActivity
import com.yingmao.clash.act.SplashHelper
import com.yingmao.clash.conf.BZYConstants
import com.yingmao.clash.conf.PayType
import com.yingmao.clash.entity.CheckLoginRsp
import com.yingmao.clash.entity.PayUploadParamData
import com.yingmao.clash.fragment.BaseFragment
import com.yingmao.clash.fragment.NewAccFragment
import com.yingmao.clash.fragment.recharge.adapter.RechargeListAdapter
import com.yingmao.clash.net.http.HttpReqType
import com.yingmao.clash.net.http.HttpStatus
import com.yingmao.clash.net.http.entity.BiLaiPayStatusRsp
import com.yingmao.clash.net.http.entity.Grade
import com.yingmao.clash.net.http.entity.NormalMessageRsp
import com.yingmao.clash.net.http.entity.NormalRsp
import com.yingmao.clash.net.http.entity.PayRsp
import com.yingmao.clash.net.http.entity.QRPayRsp
import com.yingmao.clash.net.http.entity.QRPayStatusRsp
import com.yingmao.clash.net.http.entity.RechargeInfoRsp
import com.yingmao.clash.net.http.entity.Trade
import com.yingmao.clash.util.CommonUtils
import com.yingmao.clash.util.PayUtils
import com.yingmao.clash.util.ThreadUtils.runOnUiThread
import com.yingmao.clash.view.RxToast
import com.yingmao.clash.view.dialog.DialogDoMainChoose
import com.yingmao.clash.view.dialog.DialogPayTypeChoose
import com.yingmao.clash.view.dialog.RxDialogShapeLoading
import com.yingmao.clash.webview.BZYWebViewActivity
import com.yingmao.clash.webview.BZYWebViewNormal
import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import java.text.DecimalFormat
class RechargeFragment : BaseFragment() {
private lateinit var viewModel: RechargeViewModel
private lateinit var rechargeListRv: RecyclerView
private lateinit var pointCardSurplusSwitch: Switch
private lateinit var pointLoadingPb: ProgressBar
private lateinit var pointTv: TextView
private lateinit var payTv: TextView
private var selectedGrade: Grade? = null
private var pointCard: String = "0"
private var mPayType: String = "1"
private lateinit var rxDialogShapeLoading: RxDialogShapeLoading
private lateinit var dialogPayTypeChoose: DialogPayTypeChoose
private lateinit var swipeLayout: SwipeRefreshLayout
private var wx_pay_outTradeNo: String = ""
private var customizedProduct = "八爪鱼"
private lateinit var tv_pay: TextView
private var qrPayDialog: MaterialDialog? = null
private var outTradeNo = ""
//实际需要支付金额
private lateinit var actualPaymentAmount: String
private var selectedGradeID: Int = 0
companion object {
//记录心跳失败次数
const val REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY = 1000
}
var baseLoading: RxDialogShapeLoading? = null
//stripePay 支付
private var paymentIntentClientSecret: String = ""
private val stripe: Stripe by lazy {
Stripe(
requireActivity(),
PaymentConfiguration.getInstance(requireActivity()).publishableKey
)
}
override fun init(
titleBarRl: RelativeLayout,
backIv: ImageView,
moreTv: TextView,
titleTv: TextView,
container: FrameLayout,
) {
titleBarRl.visibility = View.VISIBLE
backIv.visibility = View.VISIBLE
moreTv.visibility = View.VISIBLE
titleTv.visibility = View.VISIBLE
moreTv.setOnClickListener {
startActivity(Intent(activity, ExpensesRecordActivity::class.java))
}
backIv.setOnClickListener {
activity?.finish()
}
titleTv.text = resources.getString(R.string.recharge)
moreTv.text = resources.getString(R.string.expenses_record)
val view = View.inflate(CommonUtils.getApp(), R.layout.fragment_recharge_new, null)
initViews(view)
container.addView(view)
}
private fun initViews(view: View) {
tv_pay = view.findViewById<TextView>(R.id.tv_pay)
swipeLayout = view.findViewById(R.id.swipeLayout)
payTv = view.findViewById(R.id.tv_pay)
payTv.text = resources.getString(R.string.PayNow)
swipeLayout.setColorSchemeColors(Color.rgb(47, 223, 189))
swipeLayout.setOnRefreshListener {
selectedGrade = null
payTv.text = resources.getString(R.string.PayNow)
val username =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!!
val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!!
// viewModel.getPointCardSurplus(username, phToken)
//获取充值列表
val userId = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_USER_ID)!!
viewModel.getPhRechargeInfo(username, phToken, userId)
}
rechargeListRv = view.findViewById(R.id.rv_recharge_list)
pointLoadingPb = view.findViewById(R.id.pb_point_loading)
pointTv = view.findViewById(R.id.tv_point)
pointCardSurplusSwitch = view.findViewById(R.id.switch_balance)
pointCardSurplusSwitch.setOnCheckedChangeListener { _, isChecked ->
if (selectedGrade != null) {
val point = pointCard.toFloat()
val amount = selectedGrade!!.amount?.toFloat()
if (amount != null) {
val decimalFormat = DecimalFormat("¥#0.00")
if (isChecked) {
if (amount > point) {
pointCardSurplusSwitch.isChecked = false //暂时先这样,点数不够一次付款不能用点
RxToast.warning(resources.getString(R.string.InsufficientPoints))
} else {
tv_pay.text = resources.getString(R.string.PayNow) + "(¥0.00)"
}
} else {
tv_pay.text =
resources.getString(R.string.PayNow) + "(${decimalFormat.format(amount)})"
}
}
} else {
RxToast.warning(resources.getString(R.string.PleaseChoosePackage))
pointCardSurplusSwitch.isChecked = false //暂时先这样,点数不够一次付款不能用点
}
}
payTv.setOnClickListener {
if (selectedGrade == null) {
RxToast.info(resources.getString(R.string.selectRechargeAmount))
return@setOnClickListener
}
var isUsePointCard = false
if (pointCardSurplusSwitch.isChecked) { //使用点卡
val point = pointCard.toFloat()
val amount = selectedGrade!!.amount?.toFloat()
if (amount != null) {
// if(amount > point) { //点卡不足
// isUsePointCard = true
// actualPaymentAmount = "${amount-point}"
// }else { //点卡充足使用纯点卡支付
Logger.d("纯点卡支付")
viewModel.purePointCardPayment(selectedGrade!!, pointCard)
return@setOnClickListener
}
} else {
isUsePointCard = false
actualPaymentAmount = "${selectedGrade!!.amount}"
}
actualPaymentAmount = "${selectedGrade!!.amount}"
activity?.apply {
viewModel.pay("1", selectedGrade!!, pointCard)
// if (!::dialogPayTypeChoose.isInitialized) {
// dialogPayTypeChoose = DialogPayTypeChoose(this)
// }
// dialogPayTypeChoose.setTitle("请选择支付方式")
// dialogPayTypeChoose.setOnPayTypeCheckedListener(object : DialogPayTypeChoose.OnPayTypeCheckedListener {
// var isNeedGetOutTradeNo = false //是否需要先获取订单号再进行支付。
// override fun onPayTypeChecked(payType: String) {
//
// mPayType = if (isUsePointCard) {
// when (payType) {
// PayType.PAY_TYPE_ALI_APP -> { //吊起App支付
// isNeedGetOutTradeNo = true
// PayType.PAY_TYPE_ALI_POINT
// }
//
// else -> {
// if (payType != PayType.PAY_TYPE_Stripe) {//stripe不需要先获取订单号
// isNeedGetOutTradeNo = true
// }
// payType
// }
// }
// } else {
// if (payType == PayType.PAY_TYPE_ALI_APP) {
// isNeedGetOutTradeNo = true
// PayType.PAY_TYPE_ALI
// } else {
// payType
// }
// }
//
//
// if (isNeedGetOutTradeNo) {
// viewModel.pay(mPayType, selectedGrade!!, pointCard)
// } else if (payType == PayType.PAY_TYPE_Stripe) {
// //跳转到浏览器进行支付无需获取订单号
// val intent = Intent(activity, BZYWebViewOther::class.java)
// intent.putExtra("payUrl", selectedGrade!!.stripePay)
// // startActivityForResult(intent,MainActivity.REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY)
// startActivityFromFragment(this@RechargeFragment, intent, REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY)
// } else if (payType == PayType.PAY_TYPE_BiLai_ZFB) { //币来
// viewModel.pay("1", selectedGrade!!, pointCard)
// } else if (payType == PayType.PAY_TYPE_BiLai_WX) { //币来
// viewModel.pay("2", selectedGrade!!, pointCard)
// } else if (payType == PayType.PAY_TYPE_BiLai_JD) {//币来
// viewModel.pay("1", selectedGrade!!, pointCard)
// } else if (payType == PayType.PAY_TYPE_BiLai_WEB) {// todo 币来网页支付
// viewModel.pay("1", selectedGrade!!, pointCard)
// } else {
// val money = selectedGrade!!.amount?.toFloat()?.toInt().toString()
// viewModel.codePay(mPayType, selectedGrade!!, money, customizedProduct)
// }
//
// if (dialogPayTypeChoose.isShowing) {
// dialogPayTypeChoose.cancel()
// }
// }
// })
// if (!dialogPayTypeChoose.isShowing) {
// dialogPayTypeChoose.show()
// }
}
}
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
viewModel = ViewModelProvider(this).get(RechargeViewModel::class.java)
//获取充值列表
val username =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!!
val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!!
// viewModel.getPointCardSurplus(username, phToken)
val userId = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_USER_ID)!!
viewModel.getPhRechargeInfo(username, phToken, userId)
observe(this, viewModel)
}
override fun onResume() {
super.onResume()
// val username = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME,"")!!
// val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN,"")!!
// viewModel.getPointCardSurplus(username, phToken)
}
override fun httpLoading(httpStatus: HttpStatus.Loading) {
when (httpStatus.reqType) {
HttpReqType.GET_POINTCARD_SURPLUS -> {
Logger.d("开始获取点卡余额")
pointCardSurplusSwitch.isEnabled = false
pointLoadingPb.visibility = View.VISIBLE
pointTv.visibility = View.GONE
}
HttpReqType.GET_RECHARGE_INFO -> {
Logger.d("获取充值续费信息")
swipeLayout.isRefreshing = true
}
HttpReqType.PAY -> {
Logger.d("支付获取订单号")
showLoadingDialog(resources.getString(R.string.GeneratingOrder))
}
HttpReqType.APP_ALI_PAY -> {
Logger.d("RechargeFragment支付宝支付")
showLoadingDialog(resources.getString(R.string.RequestingPayment))
}
HttpReqType.PURE_POINT_CARD_PAYMENT -> {
Logger.d("纯点卡支付")
showLoadingDialog(resources.getString(R.string.PaymentIn))
}
HttpReqType.QRPAY -> {
showLoadingDialog(resources.getString(R.string.GeneratingOrder))
}
HttpReqType.QRPAYSTATU -> {
showLoadingDialog(resources.getString(R.string.QueryingPaymentResult))
}
HttpReqType.WEBPAYQUERY -> {
showLoadingDialog(resources.getString(R.string.QueryingPaymentResult))
}
else -> {}
}
}
private fun hideLoadingDialog() {
if (::rxDialogShapeLoading.isInitialized && rxDialogShapeLoading.isShowing) {
rxDialogShapeLoading.cancel()
}
}
private fun showLoadingDialog(content: String) {
activity?.apply {
if (!::rxDialogShapeLoading.isInitialized) {
rxDialogShapeLoading = RxDialogShapeLoading(this)
}
rxDialogShapeLoading.setLoadingText(content)
rxDialogShapeLoading.setCancelable(false)
if (!rxDialogShapeLoading.isShowing) {
rxDialogShapeLoading.show()
}
}
}
override fun httpSuccess(httpStatus: HttpStatus.Success) {
when (httpStatus.reqType) {
HttpReqType.GET_POINTCARD_SURPLUS -> {
Logger.d("获取点卡余额请求成功")
pointLoadingPb.visibility = View.GONE
pointTv.visibility = View.VISIBLE
if (pointCardSurplusSwitch.isChecked) {
pointCardSurplusSwitch.isChecked = false
}
(httpStatus.rsp as NormalRsp).let {
if (it.code != "1000") {
//RxToast.error(if (it.message.isNullOrBlank()) "获取点卡余额失败(${it.code}" else "${it.code}:${it.message}")
pointTv.text = resources.getString(R.string.retry)
pointCard = "0"
pointTv.setTextColor(resources.getColor(R.color.white_50))
pointTv.setOnClickListener {
val username = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!!
val phToken = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!!
viewModel.getPointCardSurplus(username, phToken)
}
} else {
pointCard = "${it.data}"
pointCardSurplusSwitch.isEnabled = pointCard.toInt() > 0
pointTv.setTextColor(resources.getColor(R.color.white))
pointTv.text =
resources.getString(R.string.RemainingPoints) + ": ${if (it.data.isNullOrEmpty()) "0.00" else it.data}"
}
}
}
HttpReqType.GET_RECHARGE_INFO -> {
Logger.d("获取充值续费信息请求成功")
dialogDoMainChoose?.dismiss()
swipeLayout.isRefreshing = false
(httpStatus.rsp as RechargeInfoRsp).let { it ->
if (it.code != "1000") {
RxToast.error(if (it.message.isNullOrBlank()) resources.getString(R.string.FailedRechargeList) + "${it.code}" else "${it.code}:${it.message}")
} else {
it.data?.let { it1 ->
Logger.d("AAAAAAAAAAA:::${it1.grade}")
it1.grade?.let {
Logger.d("AAAAAAAAAAA:::${it} size ${it.size}")
if (it.size > 0) {
customizedProduct = it1.customizedProduct!!
initAdapter(it)
}
}
}
}
}
}
HttpReqType.PAY -> {
hideLoadingDialog()
Logger.d("生成订单请求成功")
(httpStatus.rsp as PayRsp).let { rsp ->
if (rsp.code != "1000") {
RxToast.error(if (rsp.message.isNullOrBlank()) resources.getString(R.string.OrderGenerationFailed) + "${rsp.code}" else "${rsp.code}:${rsp.message}")
} else {
activity.let {
outTradeNo = rsp.data?.outTradeNo!!
val newUrl = rsp.data?.payUrl.toString()
orderPayment(rsp.data)
Logger.e("支付url${newUrl}")
}
}
}
}
HttpReqType.unionPay -> {
(httpStatus.rsp as PayRsp).let { rsp ->
if (rsp.code != "1000") {
RxToast.error(if (rsp.message.isNullOrBlank()) resources.getString(R.string.OrderGenerationFailed) + "${rsp.code}" else "${rsp.code}:${rsp.message}")
} else {
if (rsp.data != null) {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(rsp.data.payUrl)))
}
}
}
}
HttpReqType.PURE_POINT_CARD_PAYMENT -> {
Logger.d("纯点卡支付请求成功")
val username =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!!
val phToken = MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!!
viewModel.getPointCardSurplus(username, phToken)
hideLoadingDialog()
(httpStatus.rsp as NormalMessageRsp).let {
if (it.code != "1000") {
RxToast.error(if (it.message.isNullOrBlank()) resources.getString(R.string.PointCardFailed) + "${it.code}" else "${it.code}:${it.message}")
} else {
RxToast.success(resources.getString(R.string.PointCardSuccessful))
Logger.d("点卡支付成功更新有效期")
viewModel.checkLogin()
}
}
}
HttpReqType.CHECK_LOGIN -> {
Logger.d("支付成功更新有效期")
val checkLoginRsp = httpStatus.rsp
if (checkLoginRsp is CheckLoginRsp) {
if (checkLoginRsp.code == 0) {
Logger.d("支付成功更新有效期${activity}")
val expired = checkLoginRsp.data?.expired
val mmkv = MMKV.defaultMMKV()
mmkv.encode(BZYConstants.MMKV_KEY_VPN_EXPIRED, expired ?: true)
mmkv.encode(
BZYConstants.MMKV_KEY_VPN_VALID_PERIOD,
checkLoginRsp.data?.vpnExpireTime ?: 0
)
if (activity is NewMainActivity) {
val newMainAt = activity as NewMainActivity
newMainAt.setExpireDate()
for (fragment in newMainAt.fragments) {
if (fragment is NewAccFragment) {
fragment.setExpireDate()
}
}
}
} else {
Logger.d("微信或者支付宝支付成功更新有效期失败:${checkLoginRsp.code}${checkLoginRsp.msg}")
}
}
}
HttpReqType.QRPAY -> {
hideLoadingDialog()
(httpStatus.rsp as QRPayRsp).let {
if (it.code == 1000) {
val url = it.data?.code_url
outTradeNo = it.data?.outTradeNo!!
activity?.let {
qrPayDialog = MaterialDialog(it).show {
this.cancelable(false)
cornerRadius(res = R.dimen.dp_10)
customView(
R.layout.qrpay_dialog_layout,
scrollable = false,
noVerticalPadding = true,
horizontalPadding = false
)
if (mPayType == PayType.PAY_TYPE_ALI) {
getCustomView().findViewById<TextView>(R.id.tv_qr_pay_note)
.setText(R.string.qr_pay_note_zfb)
} else {
getCustomView().findViewById<TextView>(R.id.tv_qr_pay_note)
.setText(R.string.qr_pay_note_wx)
}
val ivQr = getCustomView().findViewById<ImageView>(R.id.iv_qr)
// val writer = MultiFormatWriter()
// val matrix = writer.encode(url, BarcodeFormat.QR_CODE, 300, 300)
// val encoder = BarcodeEncoder()
// val bitmap = encoder.createBitmap(matrix)
// ivQr.setImageBitmap(bitmap)
getCustomView().findViewById<TextView>(R.id.tv_pay_finish)
.setOnClickListener {
showLoadingDialog(resources.getString(R.string.QueryingPaymentResult))
viewModel.codePayStatus(outTradeNo)
}
// getCustomView().findViewById<TextView>(R.id.tv_pay_cancle).setOnClickListener {
// if (bitmap != null && !bitmap.isRecycled) {
// bitmap.recycle()
// dismiss()
// }
// }
}
}
} else {
RxToast.error(resources.getString(R.string.FailedPaymentQRCode))
}
}
}
HttpReqType.QRPAYSTATU -> {
hideLoadingDialog()
(httpStatus.rsp as QRPayStatusRsp).let {
if (it.code == 1000) {
RxToast.success(resources.getString(R.string.upUser))
qrPayDialog?.dismiss()
viewModel.checkLogin()
} else {
RxToast.error(resources.getString(R.string.paymentFound))
}
}
}
HttpReqType.WEBPAYQUERY -> {
hideLoadingDialog()
(httpStatus.rsp as NormalMessageRsp).let {
if (it.code == "1000") {
RxToast.success(resources.getString(R.string.upUser))
qrPayDialog?.dismiss()
viewModel.checkLogin()
} else {
RxToast.error(resources.getString(R.string.paymentFound))
}
}
}
HttpReqType.BILAIPAYSTATUS -> {
hideLoadingDialog()
(httpStatus.rsp as BiLaiPayStatusRsp).let {
if (it.code == 1000) {
RxToast.error(resources.getString(R.string.paymentFound))
qrPayDialog?.dismiss()
viewModel.checkLogin()
} else {
RxToast.error(resources.getString(R.string.paymentFound))
}
}
}
HttpReqType.BILAIPAY -> {
hideLoadingDialog()
// if (mPayType == PayType.PAY_TYPE_BiLai_ZFB) {
// goWebViewStartPayClient(httpStatus.rsp, false)
// } else if (mPayType == PayType.PAY_TYPE_BiLai_WX) {
// goWebViewStartPayClient(httpStatus.rsp, false)
// } else if (mPayType == PayType.PAY_TYPE_BiLai_WEB) {
// goWebViewStartPayClient(httpStatus.rsp, true)
// } else {
// goWebViewStartPayClient(httpStatus.rsp, false)
// }
}
HttpReqType.StripeType -> {
(httpStatus.rsp as PayUploadParamData).let {
if (it.data != null) {
paymentIntentClientSecret = it.data.clientSecret.toString()
startCheckout()
} else {
hideLoading()
RxToast.info(getString(R.string.NoPaymentReceipt))
}
}
}
else -> {}
}
}
private fun orderPayment(data: Trade) {
if (data.payType != null) {
activity?.let {
MaterialDialog(it).show {
this.cancelable(true)
cornerRadius(res = R.dimen.dp_10)
customView(
R.layout.backup_payment_dialog,
scrollable = false,
noVerticalPadding = true,
horizontalPadding = false
)
getCustomView().findViewById<AppCompatImageView>(R.id.ivBack)
.setOnClickListener {
dismiss()
}
}
}
}
}
fun goWebPay(it: Activity, realPayUrl: String) {
val intent = Intent(context, BZYWebViewNormal::class.java)
intent.putExtra(BZYConstants.EXTRA_KEY_PAY_TYPE, PayType.PAY_TYPE_WX)
intent.putExtra("url", realPayUrl)
intent.putExtra(BZYConstants.EXTRA_KEY_WX_PAY_OUT_TRADE_NO, wx_pay_outTradeNo)
startActivityForResult(intent, REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY)
qrPayDialog = MaterialDialog(it).show {
this.cancelable(false)
cornerRadius(res = R.dimen.dp_10)
customView(
R.layout.payconfirm_dialog_layout,
scrollable = false,
noVerticalPadding = true,
horizontalPadding = false
)
getCustomView().findViewById<TextView>(R.id.tv_pay_finish).setOnClickListener {
showLoadingDialog(resources.getString(R.string.QueryingPaymentResult))
// viewModel.biLaiPayStatus(outTradeNo)
viewModel.webPayStatus(outTradeNo)
}
getCustomView().findViewById<TextView>(R.id.tv_pay_cancle).setOnClickListener {
dismiss()
}
}
}
var dialogDoMainChoose: DialogDoMainChoose? = null
private fun showDomainList() {
try {
SplashHelper(viewModel).getHostWithFallback { success ->
MainScope().launch {
if (success) {
if (dialogDoMainChoose == null) {
dialogDoMainChoose = DialogDoMainChoose(this@RechargeFragment.activity)
}
if (dialogDoMainChoose?.isShowing == false) {
dialogDoMainChoose?.setOnTryButtonListener(object :
DialogDoMainChoose.OnTryButtonListener {
override fun tryButton() {
val username = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!!
val phToken = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!!
// viewModel.getPointCardSurplus(username, phToken)
val userId = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_USER_ID)!!
viewModel.getPhRechargeInfo(username, phToken, userId)
}
override fun cancel() {
com.cncat.vpn.common.log.Log.d("tryButton CHECK_LOGIN cancel")
dialogDoMainChoose?.dismiss()
}
})
dialogDoMainChoose?.setOnListItemListener(object :
DialogDoMainChoose.OnListItemListener {
override fun listItemClick() {
val username = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!!
val phToken = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!!
// viewModel.getPointCardSurplus(username, phToken)
val userId = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_USER_ID)!!
viewModel.getPhRechargeInfo(username, phToken, userId)
}
})
dialogDoMainChoose?.show()
}
}
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun httpFailure(httpStatus: HttpStatus.Failure) {
if (::rxDialogShapeLoading.isInitialized && rxDialogShapeLoading.isShowing) {
rxDialogShapeLoading.cancel()
}
if (HttpReqType.CHECK_LOGIN == httpStatus.reqType) {
Logger.d("微信或者支付宝支付成功更新有效期异常")
}
val msgs: String = when (httpStatus.reqType) {
HttpReqType.GET_POINTCARD_SURPLUS -> {
Logger.d("获取点卡余额异常${httpStatus.msg}")
if (pointCardSurplusSwitch.isChecked) {
pointCardSurplusSwitch.isChecked = false
}
pointLoadingPb.visibility = View.GONE
pointTv.visibility = View.VISIBLE
pointTv.text = resources.getString(R.string.retry)
pointTv.setOnClickListener {
val username = MMKV.defaultMMKV()
.decodeString(BZYConstants.MMKV_KEY_REMEMBER_USERNAME, "")!!
val phToken =
MMKV.defaultMMKV().decodeString(BZYConstants.MMKV_KEY_PH_TOKEN, "")!!
viewModel.getPointCardSurplus(username, phToken)
}
resources.getString(R.string.AbnormalPointCard)
}
HttpReqType.GET_RECHARGE_INFO -> {
showDomainList()
Logger.d("获取充值续费信息异常${httpStatus.msg}")
swipeLayout.isRefreshing = false
resources.getString(R.string.DataError)
}
HttpReqType.PAY -> {
Logger.d("获取支付订单号异常${httpStatus.msg}")
resources.getString(R.string.DataPayNumber)
}
HttpReqType.APP_ALI_PAY -> {
Logger.d("支付宝支付异常${httpStatus.msg}")
resources.getString(R.string.AlipayDataError)
}
HttpReqType.APP_WX_PAY -> {
Logger.d("微信支付异常${httpStatus.msg}")
resources.getString(R.string.weChatPayError)
}
HttpReqType.PURE_POINT_CARD_PAYMENT -> {
Logger.d("纯点卡支付异常${httpStatus.msg}")
resources.getString(R.string.PayCardException)
}
HttpReqType.QRPAY -> {
resources.getString(R.string.AbnormalQRCode)
}
HttpReqType.BILAIPAYSTATUS -> {
resources.getString(R.string.paymentResultsFailed)
}
HttpReqType.WEBPAYQUERY -> {
resources.getString(R.string.paymentResultsFailed)
}
HttpReqType.BILAIPAY -> {
resources.getString(R.string.paymentResultsFailed)
}
HttpReqType.StripeType -> {
hideLoading()
resources.getString(R.string.NoPaymentReceipt)
}
else -> {
hideLoading()
Logger.d("${httpStatus.reqType}${resources.getString(R.string.RequestException)}${httpStatus.msg}")
resources.getString(R.string.RequestException) + "${httpStatus.reqType}"
}
}
RxToast.error(msgs)
}
private fun initAdapter(recharge: MutableList<Grade>) {
val rechargeListAdapter = RechargeListAdapter(R.layout.recharge_list_item_layout)
rechargeListAdapter.animationEnable = false
rechargeListRv.layoutManager = LinearLayoutManager(CommonUtils.getApp())
rechargeListAdapter.data = recharge
rechargeListRv.adapter = rechargeListAdapter
// rechargeListAdapter.setOnItemClickListener { adapter, view, position ->
//
// }
rechargeListAdapter.setOnItemClickListener { baseQuickAdapter: BaseQuickAdapter<*, *>, view: View, position: Int ->
val selectedItem = baseQuickAdapter.getItem(position)
Logger.d("################$selectedItem")
if (selectedItem is Grade) {
selectedGrade = selectedItem
// RxToast.info(baseQuickAdapter.getItem(position).toString())
// rechargeListAdapter.notifyItemChanged(rechargeListAdapter.selectorPosition)
if (rechargeListAdapter.selectorPosition == position) {
return@setOnItemClickListener
}
rechargeListAdapter.selectorPosition = position
// rechargeListAdapter.notifyItemChanged(position)
rechargeListAdapter.notifyDataSetChanged()
val amount = selectedGrade!!.amount?.toFloat()
if (amount != null) {
Log.i("AAAAAAAAA11", "${selectedGrade!!.id!!}")
if (selectedGrade!!.id != null) {
Log.i("AAAAAAAAA222", "${selectedGrade!!.id!!}")
selectedGradeID = selectedGrade!!.id!!
}
val decimalFormat = DecimalFormat("¥#0.00")
tv_pay.text =
resources.getString(R.string.PayNow) + "(${decimalFormat.format(amount)})"
// if (pointCardSurplusSwitch.isChecked) {
// val point = pointCard.toFloat()
// if (amount > point) {
// tv_pay.text = resources.getString(R.string.PayNow)+"(${decimalFormat.format(amount - point)})"
// } else {
// tv_pay.text =resources.getString(R.string.PayNow)+ "(¥0.00)"
// }
// } else {
// tv_pay.text = resources.getString(R.string.PayNow)+"(${decimalFormat.format(amount)})"
// }
}
}
}
}
override fun onDestroy() {
super.onDestroy()
// val main = activity as NewMainActivity
// main.tv_rechar.visibility = View.VISIBLE
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if (requestCode == REQUEST_CODE_PAY_WEB_VIEW_ACTIVITY) {
if (resultCode == BZYConstants.REQUEST_CODE_PAY_WEB_Stripe) {
RxToast.success(resources.getString(R.string.upUser), Toast.LENGTH_LONG)
viewModel.checkLogin()
} else if (resultCode == BZYWebViewActivity.ALI_PAY_SUCCESS || resultCode == BZYWebViewActivity.WX_PAY_SUCCESS) {
viewModel.checkLogin()
RxToast.success(resources.getString(R.string.upUser), Toast.LENGTH_LONG)
Log.e("data", "微信或者支付宝支付成功更新有效期")
} else if (resultCode == BZYConstants.REQUEST_CODE_PAY_WEB_BiLai) {
// activity?.let {
// MaterialDialog(it).show {
// this.cancelable(false)
// cornerRadius(res = R.dimen.dp_10)
// customView(R.layout.payconfirm_dialog_layout, scrollable = false, noVerticalPadding = true, horizontalPadding = false)
//
// getCustomView().findViewById<TextView>(R.id.tv_pay_finish).setOnClickListener {
// showLoadingDialog("正在查询支付结果...")
// viewModel.codePayStatus(outTradeNo)
// }
//
// getCustomView().findViewById<TextView>(R.id.tv_pay_cancle).setOnClickListener {
// dismiss()
// }
// }
// }
}
}
super.onActivityResult(requestCode, resultCode, data)
}
@OptIn(DelicateCoroutinesApi::class)
private fun startCheckout() {
GlobalScope.launch {
runCatching {
stripe.confirmAlipayPayment(
ConfirmPaymentIntentParams.createAlipay(paymentIntentClientSecret),
{ data -> PayTask(requireActivity()).payV2(data, true) }
)
}.fold(
onSuccess = { result ->
hideLoading()
val paymentIntent = result.intent
when (paymentIntent.status) {
StripeIntent.Status.Succeeded -> {
Log.i("startCheckout", "支付成功")
runOnUiThread {
RxToast.info(getString(R.string.PaymentCompleted))
}
}
StripeIntent.Status.RequiresAction -> {
Log.i("startCheckout", "RequiresAction")
runOnUiThread {
RxToast.info(getString(R.string.PaymentCancellation))
}
}
else -> {
Log.i("startCheckout", "status::${paymentIntent.status}")
}
}
},
onFailure = {
Log.i("startCheckout", "支付失败${it.message}")
hideLoading()
runOnUiThread {
RxToast.info(getString(R.string.NoPaymentReceipt))
}
}
)
}
}
private fun showLoading(str: String, context: Context) {
val message = if (TextUtils.isEmpty(str)) "进行中..." else str
if (baseLoading == null) {
baseLoading = RxDialogShapeLoading(context)
}
baseLoading?.setMessage(message)
if (baseLoading?.isShowing == false) {
baseLoading?.show()
}
}
fun hideLoading() {
if (baseLoading != null && baseLoading?.isShowing == true) {
baseLoading?.cancel()
}
}
}

View File

@ -648,7 +648,7 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc
//清除源切换记录
UIMainActivity.isSubbed=false
UIMainActivity.isSubed=false
Log.d("cleanUserInfo clashRunning==>${clashRunning}")
if (clashRunning) {
fragments.filterIsInstance<HomeFragment>().forEach { it.stopClash() }
@ -914,7 +914,7 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc
Log.d("new main actname==>" + actName)
pm.setActive(it)
newUuid = pro.uuid.toString();
UIMainActivity.isSubbed = true
UIMainActivity.isSubed = true
Log.d("setSub2 setActive end")
finishInit()
} ?: run {
@ -935,7 +935,7 @@ class SettingFragment : BaseFragment(), CoroutineScope by CoroutineScope(Dispatc
)
}
newUuid = qPro.uuid.toString();
UIMainActivity.isSubbed = true
UIMainActivity.isSubed = true
// }
}
finishInit()

View File

@ -8,7 +8,6 @@ import com.yingmao.clash.net.http.entity.HeartBeatRsp
import com.orhanobut.logger.Logger
import com.tencent.mmkv.MMKV
import com.yingmao.clash.BuildConfig
import com.yingmao.clash.act.NewMainActivity
import com.yingmao.clash.base.PublicViewMode
import com.cncat.vpn.common.log.Log
import com.google.gson.Gson