提现transaction check后各种事件通知以及接入处理

This commit is contained in:
renhaoting 2025-12-15 16:17:25 +08:00
parent c944b543b1
commit 4e07aa4630
7 changed files with 463 additions and 131 deletions

View File

@ -47,6 +47,7 @@ object VididinEvents {
// Withdraw related // Withdraw related
const val EVENT_WITHDRAW_SUB_ITEM_PROGRESS_UPDATED = 500 const val EVENT_WITHDRAW_SUB_ITEM_PROGRESS_UPDATED = 500
const val EVENT_WITHDRAW_SELECTED_SUB_ITEM_CHANGED = 501 const val EVENT_WITHDRAW_SELECTED_SUB_ITEM_CHANGED = 501
const val EVENT_WITHDRAW_CHECK_RESULT_UPDATED = 502
} }

View File

@ -1,5 +1,7 @@
package com.gamedog.vididin.beans.resp package com.gamedog.vididin.beans.resp
import com.gamedog.vididin.manager.WithdrawManager.Companion.TRANSACTION_STATE_ONGOING
data class WithDrawRespData ( data class WithDrawRespData (
var items: MutableList<InitIem?>? = null, var items: MutableList<InitIem?>? = null,
@ -95,6 +97,10 @@ data class WithdrawRecord (
var recordNo: String = "", var recordNo: String = "",
var cashNum: Float = 0F, var cashNum: Float = 0F,
var operateMs: Long = 0L, var operateMs: Long = 0L,
var state: Int = 1, // 提现状态 1:提现中,2:提现成功,3:提现失败 var state: Int = TRANSACTION_STATE_ONGOING, // 提现状态 1:提现中,2:提现成功,3:提现失败
var failReason: Int = 0, // TODO - define various fail reasons var failReason: Int = 0, // TODO - define various fail reasons
var itemIndex: Int = 0,
var itemSubIndex: Int = 0,
var hasShowResultDialog: Boolean = false
) )

View File

@ -8,13 +8,10 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.repeatOnLifecycle
import com.ama.core.architecture.appBase.AppViewsEmptyViewModelActivity import com.ama.core.architecture.appBase.AppViewsEmptyViewModelActivity
import com.ama.core.architecture.util.SpUtil
import com.ama.core.architecture.util.setOnClickBatch import com.ama.core.architecture.util.setOnClickBatch
import com.gamedog.vididin.VidiConst import com.gamedog.vididin.VidiConst
import com.vididin.real.money.game.R import com.vididin.real.money.game.R
import com.gamedog.vididin.VididinEvents import com.gamedog.vididin.VididinEvents
import com.gamedog.vididin.beans.WatchAdNotifyBean
import com.gamedog.vididin.beans.resp.PayoutCheck
import com.gamedog.vididin.beans.resp.PayoutReply import com.gamedog.vididin.beans.resp.PayoutReply
import com.gamedog.vididin.beans.resp.WithdrawRecord import com.gamedog.vididin.beans.resp.WithdrawRecord
import com.gamedog.vididin.core.login.login.AccountManager import com.gamedog.vididin.core.login.login.AccountManager
@ -23,6 +20,10 @@ import com.gamedog.vididin.features.withdraw.dialogs.WithdrawFailDialog
import com.gamedog.vididin.features.withdraw.dialogs.WithdrawInfoConfirmDialog import com.gamedog.vididin.features.withdraw.dialogs.WithdrawInfoConfirmDialog
import com.gamedog.vididin.features.withdraw.dialogs.WithdrawSuccessDialog import com.gamedog.vididin.features.withdraw.dialogs.WithdrawSuccessDialog
import com.gamedog.vididin.features.withdraw.widget.WithDrawItemView import com.gamedog.vididin.features.withdraw.widget.WithDrawItemView
import com.gamedog.vididin.manager.WithdrawManager
import com.gamedog.vididin.manager.WithdrawManager.Companion.TRANSACTION_STATE_FAIL
import com.gamedog.vididin.manager.WithdrawManager.Companion.TRANSACTION_STATE_ONGOING
import com.gamedog.vididin.manager.WithdrawManager.Companion.TRANSACTION_STATE_SUCCESS
import com.gamedog.vididin.netbase.Result import com.gamedog.vididin.netbase.Result
import com.gamedog.vididin.router.Router import com.gamedog.vididin.router.Router
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@ -37,9 +38,6 @@ class WithDrawActivity : AppViewsEmptyViewModelActivity<ViewBinding>() {
private val viewModel: WithdrawViewModel by viewModels() private val viewModel: WithdrawViewModel by viewModels()
private val mItemViewList: MutableList<WithDrawItemView> = mutableListOf() private val mItemViewList: MutableList<WithDrawItemView> = mutableListOf()
private val mRecordList: MutableList<WithdrawRecord> by lazy {
SpUtil.instance().getList<WithdrawRecord>(SpUtil.KEY_WITHDRAW_HISTORY_LIST).toMutableList()
}
override fun inflateViewBinding(inflater: LayoutInflater) = ViewBinding.inflate(inflater) override fun inflateViewBinding(inflater: LayoutInflater) = ViewBinding.inflate(inflater)
@ -132,15 +130,27 @@ class WithDrawActivity : AppViewsEmptyViewModelActivity<ViewBinding>() {
} }
VididinEvents.EVENT_AD_WATCHED_FOR_WITHDRAW_SMALL -> { VididinEvents.EVENT_AD_WATCHED_FOR_WITHDRAW_SMALL -> {
val notifyData: WatchAdNotifyBean<Float> = data.mData as WatchAdNotifyBean<Float> /*val notifyData: WatchAdNotifyBean<Float> = data.mData as WatchAdNotifyBean<Float>
//requestInit(notifyData.extraData) requestInit(notifyData.extraData)*/
}
VididinEvents.EVENT_WITHDRAW_CHECK_RESULT_UPDATED -> {
try {
val record = data.mData as WithdrawRecord
if (record.itemIndex == 0) {
showTransactionResultDialog(record)
}
} catch (e: Exception) {
e.printStackTrace()
}
} }
} }
}, VididinEvents.Event_Account_Cash_Changed, VididinEvents.EVENT_AD_WATCHED_FOR_WITHDRAW_SMALL) }, VididinEvents.Event_Account_Cash_Changed,
VididinEvents.EVENT_AD_WATCHED_FOR_WITHDRAW_SMALL,
VididinEvents.EVENT_WITHDRAW_CHECK_RESULT_UPDATED,)
readTransactionsAndShowResult()
checkTransactionState()
} }
@ -244,66 +254,12 @@ class WithDrawActivity : AppViewsEmptyViewModelActivity<ViewBinding>() {
viewModel.withdrawPayout(initUUID, payItemId, payCashNum) viewModel.withdrawPayout(initUUID, payItemId, payCashNum)
} }
private fun requestCheck(recordNo: String, cashNum: Float) {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.CheckResult.collect { result ->
when (result) {
is Result.Loading -> {
}
is Result.Success -> {
val checkResult = result.data?.data
var errHintRes = 0
when (checkResult?.error) {
0 -> {
when (checkResult.status) {
// 提现状态 1:提现中,2:提现成功,3:提现失败
1 -> {
}
2 -> {
showSuccessDialog(cashNum)
updateRecord(recordNo, checkResult)
}
3 -> {
errHintRes = R.string.withdraw_normal_fail
updateRecord(recordNo, checkResult)
}
}
}
1 -> {
errHintRes = R.string.withdraw_normal_fail
}
2 -> {
errHintRes = R.string.withdraw_fail_version_toolow
}
}
if (errHintRes > 0) {
showFailDialog(errHintRes)
}
}
is Result.Error -> {
showFailDialog(R.string.withdraw_fail_unkown_error)
}
}
}
}
}
viewModel.withdrawCheck(recordNo)
}
private fun showSuccessDialog(cashNum: Float) { private fun showSuccessDialog(cashNum: Float) {
WithdrawSuccessDialog(this@WithDrawActivity, cashNum).show() WithdrawSuccessDialog(this@WithDrawActivity, cashNum).show()
} }
private fun showFailDialog(errorHintRes: Int) { private fun showFailDialog(failType: Int) {
WithdrawFailDialog(this@WithDrawActivity, errorHintRes).show() WithdrawFailDialog(this@WithDrawActivity, failType).show()
} }
private fun gotoWithdrawSubActivity(selectedIndex: Int) { private fun gotoWithdrawSubActivity(selectedIndex: Int) {
@ -313,9 +269,30 @@ class WithDrawActivity : AppViewsEmptyViewModelActivity<ViewBinding>() {
// ------------------------ new added -------------------------// // ------------------------ new added -------------------------//
// WithdrawRecord
@Synchronized private fun readTransactionsAndShowResult() {
val recordList = WithdrawManager.instance().getClonedRecordList()
recordList.forEach {
showTransactionResultDialog(it)
}
}
private fun showTransactionResultDialog(record: WithdrawRecord) {
if (record.hasShowResultDialog && record.state != TRANSACTION_STATE_ONGOING) {
when (record.state) {
TRANSACTION_STATE_SUCCESS -> {
showSuccessDialog(record.cashNum)
WithdrawManager.instance().saveRecordHasNotifyState(record.recordNo)
}
TRANSACTION_STATE_FAIL -> {
showFailDialog(record.failReason)
WithdrawManager.instance().saveRecordHasNotifyState(record.recordNo)
}
}
}
}
private fun saveNewRecord(payoutReply: PayoutReply, payCashNum: Float, timeMs: Long) { private fun saveNewRecord(payoutReply: PayoutReply, payCashNum: Float, timeMs: Long) {
val newRecord = WithdrawRecord().apply { val newRecord = WithdrawRecord().apply {
id = payoutReply.id!! id = payoutReply.id!!
@ -325,53 +302,8 @@ class WithDrawActivity : AppViewsEmptyViewModelActivity<ViewBinding>() {
state = 1 state = 1
failReason = 0 failReason = 0
} }
mRecordList.add(newRecord)
SpUtil.instance().putList(SpUtil.KEY_WITHDRAW_HISTORY_LIST, mRecordList) WithdrawManager.instance().saveNewRecord(newRecord)
checkTransactionState()
}
@Synchronized
private fun updateRecord(recordNo: String, payCheck: PayoutCheck) {
var needSaveSp = false
mRecordList.forEachIndexed { index, record ->
if (record.recordNo == recordNo) {
if (record.state != payCheck.status) {
needSaveSp =true
record.state = payCheck.status
}
return@forEachIndexed
}
}
if (needSaveSp) {
SpUtil.instance().putList(SpUtil.KEY_WITHDRAW_HISTORY_LIST, mRecordList)
}
}
@Synchronized
private fun checkTransactionState() {
var unCheckCount = 0
mRecordList.forEach { record ->
if (record.state == FINAL_STATE_ONGING) {
unCheckCount++
}
}
if (unCheckCount > 0) {
mRecordList.forEachIndexed { index, record ->
if (record.state == FINAL_STATE_ONGING) {
requestCheck(record.recordNo, record.cashNum)
}
}
binding.root.postDelayed(object : Runnable {
override fun run() {
checkTransactionState()
}
}, CHECK_DURATION)
}
} }

View File

@ -3,7 +3,11 @@ package com.gamedog.vididin.features.withdraw
import android.app.Activity import android.app.Activity
import android.content.Intent import android.content.Intent
import android.view.LayoutInflater import android.view.LayoutInflater
import androidx.activity.viewModels
import androidx.core.view.isVisible import androidx.core.view.isVisible
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import com.ama.core.architecture.appBase.AppViewsEmptyViewModelActivity import com.ama.core.architecture.appBase.AppViewsEmptyViewModelActivity
import com.ama.core.architecture.util.AndroidUtil import com.ama.core.architecture.util.AndroidUtil
@ -13,20 +17,32 @@ import com.ama.core.architecture.util.setOnClickBatch
import com.gamedog.vididin.VidiConst import com.gamedog.vididin.VidiConst
import com.gamedog.vididin.VididinEvents import com.gamedog.vididin.VididinEvents
import com.gamedog.vididin.beans.WatchAdNotifyBean import com.gamedog.vididin.beans.WatchAdNotifyBean
import com.gamedog.vididin.beans.resp.PayoutReply
import com.gamedog.vididin.beans.resp.WithdrawRecord
import com.gamedog.vididin.core.login.login.AccountManager import com.gamedog.vididin.core.login.login.AccountManager
import com.gamedog.vididin.features.withdraw.WithDrawActivity.Companion.INIT_ACTIVE
import com.gamedog.vididin.features.withdraw.dialogs.WithdrawBindBankDialog import com.gamedog.vididin.features.withdraw.dialogs.WithdrawBindBankDialog
import com.gamedog.vididin.features.withdraw.dialogs.WithdrawFailDialog
import com.gamedog.vididin.features.withdraw.dialogs.WithdrawInfoConfirmDialog import com.gamedog.vididin.features.withdraw.dialogs.WithdrawInfoConfirmDialog
import com.gamedog.vididin.features.withdraw.dialogs.WithdrawSuccessDialog
import com.gamedog.vididin.manager.WithdrawItemBean import com.gamedog.vididin.manager.WithdrawItemBean
import com.gamedog.vididin.manager.WithdrawManager import com.gamedog.vididin.manager.WithdrawManager
import com.gamedog.vididin.manager.WithdrawManager.Companion.TRANSACTION_STATE_FAIL
import com.gamedog.vididin.manager.WithdrawManager.Companion.TRANSACTION_STATE_ONGOING
import com.gamedog.vididin.manager.WithdrawManager.Companion.TRANSACTION_STATE_SUCCESS
import com.gamedog.vididin.router.Router import com.gamedog.vididin.router.Router
import com.vididin.real.money.game.R import com.vididin.real.money.game.R
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import kotlin.getValue
import com.vididin.real.money.game.databinding.ActivityWithdrawSubBinding as ViewBinding import com.vididin.real.money.game.databinding.ActivityWithdrawSubBinding as ViewBinding
@AndroidEntryPoint @AndroidEntryPoint
class WithDrawSubActivity : AppViewsEmptyViewModelActivity<ViewBinding>() { class WithDrawSubActivity : AppViewsEmptyViewModelActivity<ViewBinding>() {
private val viewModel: WithdrawViewModel by viewModels()
private lateinit var mCurItem: WithdrawItemBean private lateinit var mCurItem: WithdrawItemBean
private var mSelectingIndex: Int = 0 private var mSelectingIndex: Int = 0
private var mType: Int = 0 private var mType: Int = 0
@ -75,8 +91,124 @@ class WithDrawSubActivity : AppViewsEmptyViewModelActivity<ViewBinding>() {
} }
} }
private fun requestInit(cashNum: Float) { @Synchronized
private fun saveNewRecord(payoutReply: PayoutReply, payCashNum: Float, timeMs: Long) {
val newRecord = WithdrawRecord().apply {
id = payoutReply.id!!
recordNo = payoutReply.record_no
cashNum = payCashNum
operateMs = timeMs
state = 1
failReason = 0
itemIndex = mCurItem.index
itemSubIndex = mSelectingIndex
}
WithdrawManager.instance().saveNewRecord(newRecord)
}
private fun requestInit(withdrawNum: Float) {
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.InitData.collect { result ->
when (result) {
is com.gamedog.vididin.netbase.Result.Loading -> {
}
is com.gamedog.vididin.netbase.Result.Success -> {
val reqInitBean = result.data.data
reqInitBean?.let {
var errorHintRes = 0
if (it.error == 0 && !it.uuid.isNullOrEmpty() && !it.items.isNullOrEmpty()) {
val itemId = if (withdrawNum <= VidiConst.WITHDRAW_SMALL_NUM) 0 else 1
val withDrawItem = it.items?.get(itemId)!!
if (withDrawItem.status == INIT_ACTIVE) {
requestPayout(it.uuid!!, withDrawItem.id, withdrawNum)
} else {
errorHintRes = R.string.withdraw_fail_reach_day_limit
}
} else {
// 0成功1失败2签名验证失败3客户端版本过低4 ts长度错误
when (it.error) {
3-> errorHintRes = R.string.withdraw_fail_version_toolow
}
}
if (errorHintRes > 0) {
showFailDialog(errorHintRes)
}
}
}
is com.gamedog.vididin.netbase.Result.Error -> {
showFailDialog(R.string.withdraw_fail_unkown_error)
}
}
}
}
}
viewModel.withdrawInit()
}
private fun requestPayout(initUUID: String, payItemId: Int, payCashNum: Float) {
val currentTimeMs = System.currentTimeMillis()
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.PayoutResult.collect { result ->
when (result) {
is com.gamedog.vididin.netbase.Result.Loading -> {
}
is com.gamedog.vididin.netbase.Result.Success -> {
var errHintRes = 0
when (result.data?.data?.error) {
/* 错误码
0成功1失败2签名验证失败3客户端版本过低4uuid错误5所在地国家或地区不在提现限制内6提现金额不符对应的产品id7提现产品id不对8达到提现金额限制9提现次数超过限制10今日没有提现机会11提现账号达到次数限制12身份审核条件不满足不能提现13巴西提现参数 document_type 错误
14巴西提现参数 document_id 错误15 巴西提现参数 AccountType 错误16 巴西提现参数 Name 错误17巴西提现参数 Account DocumentId 不同18巴西提现参数account_type为CPF时 对应的 account 错误19巴西提现参数account_type为CNPJ时 对应的 account 错误20巴西提现参数 account_type 错误
21巴西提现参数 document_type 错误22巴西提现参数account_type为CPF时 对应的 document_id 错误23巴西提现参数account_type为CNPJ时 对应的 document_id 错误24 ts长度错误25 没提0.1就提现其它的
*/
0 -> {
saveNewRecord(result.data.data!!, payCashNum, currentTimeMs)
}
5-> {
errHintRes = R.string.withdraw_fail_region_restricit
}
8-> {
errHintRes = R.string.withdraw_fail_amount_limit
}
9-> {
errHintRes = R.string.withdraw_fail_amount_limit
}
}
if (errHintRes > 0) {
showFailDialog(errHintRes)
}
}
is com.gamedog.vididin.netbase.Result.Error -> {
showFailDialog(R.string.withdraw_fail_unkown_error)
}
}
}
}
}
viewModel.withdrawPayout(initUUID, payItemId, payCashNum)
}
private fun showSuccessDialog(cashNum: Float) {
WithdrawSuccessDialog(this, cashNum).show()
}
private fun showFailDialog(errorHintRes: Int) {
WithdrawFailDialog(this, errorHintRes).show()
} }
private fun handleSubItemClicked(itemIndex: Int) { private fun handleSubItemClicked(itemIndex: Int) {
@ -107,10 +239,22 @@ class WithDrawSubActivity : AppViewsEmptyViewModelActivity<ViewBinding>() {
VididinEvents.EVENT_WITHDRAW_SELECTED_SUB_ITEM_CHANGED -> { VididinEvents.EVENT_WITHDRAW_SELECTED_SUB_ITEM_CHANGED -> {
updateUI() updateUI()
} }
VididinEvents.EVENT_WITHDRAW_CHECK_RESULT_UPDATED -> {
try {
val record = data.mData as WithdrawRecord
if (record.itemIndex > 0) {
showTransactionResultDialog(record)
}
} catch (e: Exception) {
e.printStackTrace()
}
}
} }
}, VididinEvents.EVENT_AD_WATCHED_FOR_WITHDRAW_BIG, }, VididinEvents.EVENT_AD_WATCHED_FOR_WITHDRAW_BIG,
VididinEvents.EVENT_WITHDRAW_SUB_ITEM_PROGRESS_UPDATED, VididinEvents.EVENT_WITHDRAW_SUB_ITEM_PROGRESS_UPDATED,
VididinEvents.EVENT_WITHDRAW_SELECTED_SUB_ITEM_CHANGED) VididinEvents.EVENT_WITHDRAW_SELECTED_SUB_ITEM_CHANGED,
VididinEvents.EVENT_WITHDRAW_CHECK_RESULT_UPDATED )
mCurItem = WithdrawManager.instance().getItem(mType) mCurItem = WithdrawManager.instance().getItem(mType)
@ -121,6 +265,22 @@ class WithDrawSubActivity : AppViewsEmptyViewModelActivity<ViewBinding>() {
updateUI() updateUI()
} }
private fun showTransactionResultDialog(record: WithdrawRecord) {
if (record.hasShowResultDialog && record.state != TRANSACTION_STATE_ONGOING) {
when (record.state) {
TRANSACTION_STATE_SUCCESS -> {
showSuccessDialog(record.cashNum)
WithdrawManager.instance().saveRecordHasNotifyState(record.recordNo)
}
TRANSACTION_STATE_FAIL -> {
showFailDialog(record.failReason)
WithdrawManager.instance().saveRecordHasNotifyState(record.recordNo)
}
}
}
}
private fun handleAdWatched(adNotifyBean: WatchAdNotifyBean<WithdrawItemBean>) { private fun handleAdWatched(adNotifyBean: WatchAdNotifyBean<WithdrawItemBean>) {
val withdrawItemBean = adNotifyBean.extraData val withdrawItemBean = adNotifyBean.extraData
if (WithdrawManager.instance().addAdEarnForSubBean(withdrawItemBean.index, if (WithdrawManager.instance().addAdEarnForSubBean(withdrawItemBean.index,

View File

@ -14,6 +14,7 @@ import com.gamedog.vididin.beans.resp.PayInit
import com.gamedog.vididin.beans.resp.PayoutCheckData import com.gamedog.vididin.beans.resp.PayoutCheckData
import com.gamedog.vididin.beans.resp.PayoutData import com.gamedog.vididin.beans.resp.PayoutData
import com.gamedog.vididin.core.login.login.AccountManager import com.gamedog.vididin.core.login.login.AccountManager
import com.gamedog.vididin.manager.WithdrawManager
import com.gamedog.vididin.netbase.NetworkUtil import com.gamedog.vididin.netbase.NetworkUtil
import com.gamedog.vididin.netbase.Result import com.gamedog.vididin.netbase.Result
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@ -108,16 +109,7 @@ class WithdrawViewModel : ViewModel() {
private fun <T : PayInitReq> T.applyInitFields(): T { private fun <T : PayInitReq> T.applyInitFields(): T {
apply { return WithdrawManager.instance().applyInitFields(this)
platform = "Android"
deviceid = DeviceUtil.generateDeviceId()
version = AndroidUtil.getAppVersionInfo()
ip = NetUtil.getLocalIpAddress()
ts = (System.currentTimeMillis()/1000).toString()
val signOrigin = "${VidiConst.WITHDRAW_MD5KEY}platform=${platform}deviceid=${deviceid}version=${version}ip=${ip}ts=$ts"
sign = MD5Util.md5ForWithDraw(signOrigin)
}
return this
} }
} }

View File

@ -4,11 +4,13 @@ package com.gamedog.vididin.features.withdraw.dialogs
import android.app.Activity import android.app.Activity
import com.ama.core.architecture.util.setOnClickBatch import com.ama.core.architecture.util.setOnClickBatch
import com.ama.core.architecture.widget.BindingDialog import com.ama.core.architecture.widget.BindingDialog
import com.gamedog.vididin.manager.WithdrawManager.Companion.FAIL_TYPE_APP_VERSION_LOW
import com.vididin.real.money.game.databinding.DialogWithdrawFailBinding as ViewBinding import com.vididin.real.money.game.databinding.DialogWithdrawFailBinding as ViewBinding
import com.gamedog.vididin.router.Router import com.gamedog.vididin.router.Router
import com.vididin.real.money.game.R
class WithdrawFailDialog(context: Activity, private val errorHintRes: Int) : BindingDialog<ViewBinding>(context, ViewBinding::inflate) { class WithdrawFailDialog(context: Activity, private val failType: Int) : BindingDialog<ViewBinding>(context, ViewBinding::inflate) {
init { init {
build() build()
@ -39,7 +41,13 @@ class WithdrawFailDialog(context: Activity, private val errorHintRes: Int) : Bin
} }
} }
tvReason.setText(errorHintRes) var failTextRes = R.string.withdraw_normal_fail
when (failType) {
FAIL_TYPE_APP_VERSION_LOW -> {
failTextRes = R.string.withdraw_fail_version_toolow
}
}
tvReason.setText(failTextRes)
} }
} }

View File

@ -2,14 +2,36 @@ package com.gamedog.vididin.manager
import com.ama.core.architecture.util.AndroidUtil import com.ama.core.architecture.util.AndroidUtil
import com.ama.core.architecture.util.DateUtil import com.ama.core.architecture.util.DateUtil
import com.ama.core.architecture.util.DeviceUtil
import com.ama.core.architecture.util.MD5Util
import com.ama.core.architecture.util.NetUtil
import com.ama.core.architecture.util.SpUtil import com.ama.core.architecture.util.SpUtil
import com.ama.core.architecture.util.eventbus.NotifyMan import com.ama.core.architecture.util.eventbus.NotifyMan
import com.gamedog.vididin.VidiConst
import com.gamedog.vididin.VididinEvents import com.gamedog.vididin.VididinEvents
import com.gamedog.vididin.beans.req.PayInitReq
import com.gamedog.vididin.beans.req.PayoutCheckReq
import com.gamedog.vididin.beans.resp.WithdrawRecord
import com.gamedog.vididin.features.withdraw.WithDrawActivity.Companion.FINAL_STATE_ONGING
import com.gamedog.vididin.manager.WithdrawManager.Companion.STATE_NEED_WATCH_AD import com.gamedog.vididin.manager.WithdrawManager.Companion.STATE_NEED_WATCH_AD
import com.gamedog.vididin.netbase.NetworkUtil
import com.gamedog.vididin.netbase.Result
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.concurrent.locks.ReentrantLock
class WithdrawManager private constructor() { class WithdrawManager private constructor() {
private val backgroundScope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
private val mRecordLocker = ReentrantLock()
private val mRecordList: MutableList<WithdrawRecord> by lazy {
SpUtil.instance().getList<WithdrawRecord>(SpUtil.KEY_WITHDRAW_HISTORY_LIST).toMutableList()
}
private val mItemList: MutableList<WithdrawItemBean> by lazy { private val mItemList: MutableList<WithdrawItemBean> by lazy {
val itemList = SpUtil.instance().getList<WithdrawItemBean>(SpUtil.KEY_WITHDRAW_ITEM_LIST).toMutableList() val itemList = SpUtil.instance().getList<WithdrawItemBean>(SpUtil.KEY_WITHDRAW_ITEM_LIST).toMutableList()
@ -20,15 +42,25 @@ class WithdrawManager private constructor() {
itemList itemList
} }
companion object { companion object {
const val EACH_SUB_ITEM_CASH_NUM: Float = 1F const val EACH_SUB_ITEM_CASH_NUM: Float = 1F
// subBean 状态
const val STATE_NEED_WATCH_AD: Int = 0 const val STATE_NEED_WATCH_AD: Int = 0
const val STATE_COULD_WITHDRAW: Int = 1 const val STATE_COULD_WITHDRAW: Int = 1
const val STATE_WITHDRAWING: Int = 2 const val STATE_WITHDRAWING: Int = 2
const val STATE_HAS_WITHDRAWED: Int = 3 const val STATE_HAS_WITHDRAWED: Int = 3
// 提现交易状态 提现状态 1:提现中,2:提现成功,3:提现失败
const val TRANSACTION_STATE_ONGOING : Int = 1
const val TRANSACTION_STATE_SUCCESS : Int = 2
const val TRANSACTION_STATE_FAIL : Int = 3
// 提现失败分类(自定义)
const val FAIL_TYPE_UNKNOWN : Int = 1
const val FAIL_TYPE_APP_VERSION_LOW : Int = 2
@Volatile @Volatile
private var instance: WithdrawManager? = null private var instance: WithdrawManager? = null
@ -41,6 +73,12 @@ class WithdrawManager private constructor() {
} }
} }
init {
loopCheckTransactionState()
}
private fun generateItemList(): MutableList<WithdrawItemBean> { private fun generateItemList(): MutableList<WithdrawItemBean> {
val itemList = mutableListOf<WithdrawItemBean>() val itemList = mutableListOf<WithdrawItemBean>()
itemList.add(WithdrawItemBean(0, 10F, AndroidUtil.randomInt(50, 70), generateSubItemList(10F))) itemList.add(WithdrawItemBean(0, 10F, AndroidUtil.randomInt(50, 70), generateSubItemList(10F)))
@ -127,6 +165,201 @@ class WithdrawManager private constructor() {
} }
} }
fun saveRecordHasNotifyState(recordNo: String) {
val recordBean = getRecord(recordNo)
recordBean?.let {
it.hasShowResultDialog = true
saveRecords2Sp()
}
}
fun saveNewRecord(newRecord: WithdrawRecord) {
try {
mRecordLocker.lock()
mRecordList.add(newRecord)
} finally {
mRecordLocker.unlock()
}
saveRecords2Sp()
loopCheckTransactionState()
}
private fun saveRecords2Sp() {
SpUtil.instance().putList(SpUtil.KEY_WITHDRAW_HISTORY_LIST,getClonedRecordList())
}
fun updateRecord(recordNo: String, newState: Int, failType: Int = 0) {
var needSaveSp = false
try {
mRecordLocker.lock()
mRecordList.forEachIndexed { index, record ->
if (record.recordNo == recordNo) {
if (record.state != newState) {
needSaveSp =true
record.state = newState
record.failReason = failType
}
return@forEachIndexed
}
}
} finally {
mRecordLocker.unlock()
}
if (needSaveSp) {
saveRecords2Sp()
}
}
fun getClonedRecordList(): List<WithdrawRecord> {
try {
mRecordLocker.lock()
val clonedList = mutableListOf<WithdrawRecord>()
clonedList.addAll(mRecordList)
return clonedList
} finally {
mRecordLocker.unlock()
}
return emptyList()
}
private fun getRecord(recordNo: String): WithdrawRecord? {
try {
mRecordLocker.lock()
mRecordList.forEachIndexed { index, record ->
if (record.recordNo == recordNo) {
return record
}
}
} finally {
mRecordLocker.unlock()
}
return null
}
private fun loopCheckTransactionState() {
var unCheckCount = 0
try {
mRecordLocker.lock()
mRecordList.forEach { record ->
if (record.state == FINAL_STATE_ONGING) {
unCheckCount++
}
}
} finally {
mRecordLocker.unlock()
}
if (unCheckCount > 0) {
try {
mRecordLocker.lock()
mRecordList.forEachIndexed { index, record ->
if (record.state == FINAL_STATE_ONGING) {
doTransactionCheck(record.recordNo, record.cashNum)
}
}
} finally {
mRecordLocker.unlock()
}
}
}
private fun doTransactionCheck(recordNo: String, cashNum: Float) {
backgroundScope.launch {
performNetworkRequest(recordNo)
}
}
private suspend fun performNetworkRequest(recordNo: String) {
val requestParam = applyInitFields(PayoutCheckReq()).apply {
record_no = recordNo
}
val reqResult = NetworkUtil.callApi {
NetworkUtil.apiservice().withdrawCheck(requestParam)
}
when (reqResult) {
is Result.Loading -> {
}
is Result.Success -> {
val checkResult = reqResult.data.data
var failedType = 0
when (checkResult?.error) {
0 -> {
when (checkResult.status) {
// 提现状态 1:提现中,2:提现成功,3:提现失败
1 -> {
delay(10000)
loopCheckTransactionState()
}
2 -> {
handleTransactionSuccess(recordNo)
}
3 -> {
failedType = FAIL_TYPE_UNKNOWN
}
}
}
1 -> {
failedType = FAIL_TYPE_UNKNOWN
}
2 -> {
failedType = FAIL_TYPE_APP_VERSION_LOW
}
}
if (failedType > 0) {
handleTransactionFailed(recordNo, failedType)
}
}
is Result.Error -> {
}
}
}
private fun handleTransactionSuccess(recordNo: String) {
updateRecord(recordNo, TRANSACTION_STATE_SUCCESS)
notifyWithdrawCheckResult(recordNo)
}
private fun handleTransactionFailed(recordNo: String, failedType: Int) {
updateRecord(recordNo, TRANSACTION_STATE_FAIL, failedType)
notifyWithdrawCheckResult(recordNo)
}
private fun notifyWithdrawCheckResult(recordNo: String) {
val recordBean = getRecord(recordNo)
recordBean.let {
NotifyMan.instance().sendEvent(VididinEvents.EVENT_WITHDRAW_CHECK_RESULT_UPDATED, NotifyMan.NotifyData(it))
}
}
fun <T : PayInitReq> applyInitFields(dataBean: T): T {
dataBean.apply {
platform = "Android"
deviceid = DeviceUtil.generateDeviceId()
version = AndroidUtil.getAppVersionInfo()
ip = NetUtil.getLocalIpAddress()
ts = (System.currentTimeMillis()/1000).toString()
val signOrigin = "${VidiConst.WITHDRAW_MD5KEY}platform=${platform}deviceid=${deviceid}version=${version}ip=${ip}ts=$ts"
sign = MD5Util.md5ForWithDraw(signOrigin)
}
return dataBean
}
} }