package com.gamedog.vididin.manager import com.ama.core.architecture.util.AndroidUtil 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.eventbus.NotifyMan import com.gamedog.statisticreporter.StatisticUtil import com.gamedog.vididin.VidiConst import com.gamedog.vididin.VididinEvents import com.gamedog.vididin.beans.RECORD_CASH_WITHDRAW import com.gamedog.vididin.beans.RecordCash import com.gamedog.vididin.beans.req.PayInitReq import com.gamedog.vididin.beans.req.PayoutCheckReq import com.gamedog.vididin.beans.req.PayoutReq import com.gamedog.vididin.beans.resp.PayInit import com.gamedog.vididin.beans.resp.PayoutData import com.gamedog.vididin.core.login.login.AccountManager import com.gamedog.vididin.manager.WithdrawManager.Companion.STATE_NEED_WATCH_AD import com.gamedog.vididin.netbase.NetworkUtil import com.gamedog.vididin.netbase.Result import com.viddin.videos.free.R import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.delay import kotlinx.coroutines.launch class WithdrawManager private constructor() { private val mBgScope = CoroutineScope(SupervisorJob() + Dispatchers.IO) private val mWithdrawItemList: MutableList by lazy { val itemList = SpUtil.instance().getList(SpUtil.KEY_WITHDRAW_ITEM_LIST).toMutableList() if (itemList.isEmpty()) { itemList.addAll(generateItemList()) saveInfos2Sp(itemList) } itemList } companion object { const val EACH_SUB_ITEM_CASH_NUM: Double = 1.0 //----------------------- FROM pagsmile.proto ------------------------------ // init接口 status // 1可提现 2:条件未达成 3:已提现, 4:禁止提现, 5:提现中 const val INIT_OK = 1 const val ERROR_COMMON_UNKNOW = 999 const val ERROR_INIT_NOT_REACH_CONDITION = 2 const val ERROR_INIT_ALREADY_WITHDRAWED = 3 const val ERROR_INIT_FORBID = 4 const val ERROR_INIT_WITHDRAWING = 5 // init接口 服务器 error 字段 // 0成功,1失败,2签名验证失败,3客户端版本过低,4 ts长度错误 const val ERROR_INIT_FAILED_UNKNOW = ERROR_COMMON_UNKNOW const val ERROR_INIT_APP_VERSION_LOW = 3 + 10 /* payout接口: 错误码, 0成功,1失败,2签名验证失败,3客户端版本过低,4uuid错误,5所在地国家或地区不在提现限制内,6提现金额不符对应的产品id,7提现产品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就提现其它的 */ const val ERROR_PAYOUT_UNKNOW = 1 + 20 const val ERROR_PAYOUT_APP_VERSION_LOW = 3 + 20 const val ERROR_PAYOUT_COUNTRY_RESTRICTION = 5 + 20 const val ERROR_PAYOUT_REACH_TOTAL_LIMIT = 8 + 20 const val ERROR_PAYOUT_REACH_TIMES_LIMIT = 9 + 20 const val ERROR_PAYOUT_TODAY_NO_CHANCE = 10 + 20 const val ERROR_PAYOUT_ACCOUNT_REACH_TIMES_LIMIT = 11 + 20 const val ERROR_PAYOUT_ACCOUNT_INVALID = 18 + 20 const val ERROR_PAYOUT_USER_IDENTITY_LIMIT = 12 + 20 const val ERROR_PAYOUT_MUST_WITHDRAW01_FIRST = 25 + 20 // subBean 状态 const val STATE_NEED_WATCH_AD: Int = 0 const val STATE_COULD_WITHDRAW: Int = 1 const val STATE_WITHDRAWING: Int = 2 const val STATE_WITHDRAW_SUCCESS: Int = 3 // 提现交易状态 提现状态 0: 未启动 1:提现中,2:提现成功,3:提现失败 const val TRANSACTION_STATE_UNSTART : Int = 0 const val TRANSACTION_STATE_ONGOING : Int = 1 const val TRANSACTION_STATE_SUCCESS : Int = 2 const val TRANSACTION_STATE_FAIL : Int = 3 @Volatile private var instance: WithdrawManager? = null fun instance(): WithdrawManager { return instance ?: synchronized(this) { instance ?: WithdrawManager().also { instance = it } } } } init { loopCheckTransactionState() } private fun generateItemList(): MutableList { val itemList = mutableListOf() itemList.add(WithdrawItem(0, 0.1, 100, generateSmallItemList(), isBigWithDraw = false)) itemList.add(WithdrawItem(1, 1.0, AndroidUtil.randomInt(50, 70), generateSubItemList(1.0))) itemList.add(WithdrawItem(2, 10.0, AndroidUtil.randomInt(50, 70), generateSubItemList(10.0))) itemList.add(WithdrawItem(3, 20.0, AndroidUtil.randomInt(50, 70), generateSubItemList(20.0))) itemList.add(WithdrawItem(4, 50.0, AndroidUtil.randomInt(50, 70), generateSubItemList(50.0))) itemList.add(WithdrawItem(5, 100.0, AndroidUtil.randomInt(50, 70), generateSubItemList(100.0))) itemList.add(WithdrawItem(6, 300.0, AndroidUtil.randomInt(50, 70), generateSubItemList(300.0))) return itemList } private fun generateSubItemList(totalCashInItem: Double): List { val subItemList = mutableListOf() val subItemCount: Int = (totalCashInItem/EACH_SUB_ITEM_CASH_NUM).toInt() for (i in 0..subItemCount-1) { val initProgress = AndroidUtil.randomInt(50, 70) subItemList.add(WithdrawSubItem(i, EACH_SUB_ITEM_CASH_NUM, initProgress, initProgress, 0.0)) } return subItemList } private fun generateSmallItemList(): List { val subItemList = mutableListOf() subItemList.add(WithdrawSubItem(0, 0.1, 100, 100, 0.1)) return subItemList } private fun saveInfos2Sp(itemList: MutableList) { SpUtil.instance().putList(SpUtil.KEY_WITHDRAW_ITEM_LIST, itemList) } fun getItem(itemIndex: Int): WithdrawItem { return mWithdrawItemList[itemIndex] } fun getHasWithdrawSuccessCashCount(): Double { return RecordsManager.instance().getHasWithdrawSuccessCashCount() } fun addAdEarnForSubBean(itemIndex: Int, selectedSubIndex: Int, earnMoneyNum: Double) : Boolean { if (itemIndex >= 0 && itemIndex < mWithdrawItemList.size) { try { val subBean = mWithdrawItemList[itemIndex].subItemList[selectedSubIndex] subBean.hasEarnMoneyByAd += earnMoneyNum * 5 // dollar 2 bariz calculateSubBeanProgress(subBean) //传入 itembean 更新 selectedIndex为下一个 saveInfos2Sp(mWithdrawItemList) notifyProgressUpdated(subBean) return true } catch (e: Exception) { e.printStackTrace() } } return false } private fun notifyProgressUpdated(subBean: WithdrawSubItem) { NotifyMan.instance().sendEvent(VididinEvents.EVENT_WITHDRAW_SUB_ITEM_PROGRESS_UPDATED, NotifyMan.NotifyData(subBean.dayIndex)) } private fun notifySelectedSubBeanChanged(subBean: WithdrawSubItem) { NotifyMan.instance().sendEvent(VididinEvents.EVENT_WITHDRAW_SELECTED_SUB_ITEM_CHANGED, NotifyMan.NotifyData(subBean.dayIndex)) } private fun notifyItemListChanged() { NotifyMan.instance().sendEvent(VididinEvents.EVENT_WITHDRAW_ITEM_LIST_CHANGED, null) } private fun notifyWithdrawResult(withdrawRecord: RecordCash) { NotifyMan.instance().sendEvent(VididinEvents.EVENT_WITHDRAW_RESULT_UPDATED, NotifyMan.NotifyData(withdrawRecord)) } private fun calculateSubBeanProgress(subBean: WithdrawSubItem) { val needEarnProgress = 100 - subBean.startAdProgress if (subBean.hasEarnMoneyByAd >= subBean.cashTotal) { subBean.currentAdProgress = 100 // update state if (subBean.withdrawState == STATE_NEED_WATCH_AD) { subBean.withdrawState = STATE_COULD_WITHDRAW } } else { val newProgress = subBean.startAdProgress + (needEarnProgress * (subBean.hasEarnMoneyByAd / subBean.cashTotal)).toInt() subBean.currentAdProgress = if (newProgress >= 100) 100 else newProgress } } fun updateSubBeanState(subBean: WithdrawSubItem, newState: Int) { subBean.withdrawState = newState saveInfos2Sp(mWithdrawItemList) } fun startItem(curItem: WithdrawItem) { if (curItem.startMs <= 0L) { curItem.startMs = DateUtil.getCurTimeMs() - (if (curItem.totalCashNum == 50.0) 24 * 3600000 * 4 else 0) saveInfos2Sp(mWithdrawItemList) } } fun updateRecordHasNotifyState(operationUUID: String) { RecordsManager.instance().updateRecordHasNotifyState(operationUUID) } fun saveNewWithdrawRecord(newRecord: RecordCash) { RecordsManager.instance().saveNewWithdrawRecord(newRecord) } private fun checkIfItemFinishAndReset(itemIndex: Int) { var needReset = false if (itemIndex == 0) { needReset = true } else { var allSubItemFinish = true mWithdrawItemList[itemIndex].subItemList.forEach { if (it.withdrawState != STATE_WITHDRAW_SUCCESS) { allSubItemFinish = false return@forEach } } needReset = allSubItemFinish } if (needReset) { resetWithdrawItem(itemIndex) } } private fun resetWithdrawItem(itemIndex: Int) { val needResetItem = mWithdrawItemList[itemIndex] needResetItem.apply { totalProgress = 0 startMs = 0L hasStarted = false loopIndex++ subItemList.forEach { subItem -> subItem.apply { currentAdProgress = startAdProgress hasEarnMoneyByAd = 0.0 withdrawState = STATE_NEED_WATCH_AD } } } notifyItemListChanged() } fun getClonedRecordList(): List { return RecordsManager.instance().getWithdrawRecordList() } private fun getOngoingRecordList(): List { return RecordsManager.instance().getOngoingRecordList() } private fun loopCheckTransactionState() { val ongoingList = getOngoingRecordList() if (ongoingList.isNotEmpty()) { try { ongoingList.forEachIndexed { index, record -> mBgScope.launch { if (!record.payOutReplyNo.isEmpty()) { requestCheck(record) } } } } catch (e: Exception) { e.printStackTrace() } } } private suspend fun requestCheck(withdrawRecord: RecordCash) { val recordNo = withdrawRecord.payOutReplyNo val checkReqParam = applyInitFields(PayoutCheckReq()).apply { record_no = recordNo } val checkReqResult = NetworkUtil.callApi { NetworkUtil.apiservice().withdrawCheck(checkReqParam) } when (checkReqResult) { is Result.Loading -> { } is Result.Error -> { } is Result.Success -> { val checkResult = checkReqResult.data.data var failedType = -1 when (checkResult?.error) { 0 -> { when (checkResult.status) { // 提现状态 1:提现中,2:提现成功,3:提现失败 1 -> { delay(10000) loopCheckTransactionState() } 2 -> { handleLoopCheckWithdrawSuccess(withdrawRecord) } 3 -> { failedType = ERROR_COMMON_UNKNOW } } } 1 -> { failedType = ERROR_COMMON_UNKNOW } 3 -> { failedType = ERROR_PAYOUT_APP_VERSION_LOW } } if (failedType > 0) { handleWithdrawFailed(failedType, withdrawRecord) } } } } fun getFailHintStrRes(failType: Int) : Int { var failTextRes = R.string.withdraw_normal_fail when (failType) { // 仅仅显示三种 ERROR_PAYOUT_ACCOUNT_INVALID -> { failTextRes = R.string.withdraw_account_invalid } ERROR_PAYOUT_REACH_TOTAL_LIMIT, ERROR_PAYOUT_TODAY_NO_CHANCE, ERROR_PAYOUT_ACCOUNT_REACH_TIMES_LIMIT, ERROR_PAYOUT_REACH_TIMES_LIMIT -> { failTextRes = R.string.withdraw_fail_reach_times_limit } else -> { failTextRes = R.string.withdraw_normal_fail } /*ERROR_COMMON_UNKNOW -> { failTextRes = R.string.withdraw_normal_fail } ERROR_INIT_NOT_REACH_CONDITION -> { failTextRes = R.string.withdraw_fail_not_reach_condition } ERROR_INIT_ALREADY_WITHDRAWED -> { failTextRes = R.string.withdraw_fail_already_withdraw } ERROR_INIT_FORBID -> { failTextRes = R.string.withdraw_fail_forbidden } ERROR_INIT_WITHDRAWING -> { failTextRes = R.string.withdraw_fail_withdrawing } ERROR_INIT_FAILED_UNKNOW -> { failTextRes = R.string.withdraw_normal_fail } ERROR_INIT_APP_VERSION_LOW -> { failTextRes = R.string.withdraw_fail_version_toolow } ERROR_PAYOUT_UNKNOW -> { failTextRes = R.string.withdraw_normal_fail } ERROR_PAYOUT_APP_VERSION_LOW -> { failTextRes = R.string.withdraw_fail_version_toolow } ERROR_PAYOUT_COUNTRY_RESTRICTION -> { failTextRes = R.string.withdraw_fail_country_restriction } ERROR_PAYOUT_REACH_TOTAL_LIMIT -> { failTextRes = R.string.withdraw_fail_reach_amount_limit } ERROR_PAYOUT_REACH_TIMES_LIMIT -> { failTextRes = R.string.withdraw_fail_reach_times_limit } ERROR_PAYOUT_TODAY_NO_CHANCE -> { failTextRes = R.string.withdraw_fail_today_no_chance } ERROR_PAYOUT_ACCOUNT_REACH_TIMES_LIMIT -> { failTextRes = R.string.withdraw_account_times_limit } ERROR_PAYOUT_ACCOUNT_INVALID -> { failTextRes = R.string.withdraw_account_invalid } ERROR_PAYOUT_USER_IDENTITY_LIMIT -> { failTextRes = R.string.withdraw_fail_user_identity_limit } ERROR_PAYOUT_MUST_WITHDRAW01_FIRST -> { failTextRes = R.string.withdraw_fail_must_withdraw_01_first }*/ } return failTextRes } fun 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 } fun getItemProgress(itemIndex: Int): Double { var itemProgress = 0.0 if (itemIndex in 0..mWithdrawItemList.size-1) { val curItem = mWithdrawItemList[itemIndex] val userCashTotal = AccountManager.getCash() if (curItem.hasStarted) { return 1.0 } else { itemProgress = if ((userCashTotal / curItem.totalCashNum) > 1.0) 1.0 else userCashTotal / curItem.totalCashNum } } return itemProgress } fun getItemState(itemIndex: Int, subItemIndex: Int): Int { if (itemIndex in 0..mWithdrawItemList.size-1) { val curItem = mWithdrawItemList[itemIndex] if (subItemIndex in 0..curItem.subItemList.size - 1) { return curItem.subItemList[subItemIndex].withdrawState } } return STATE_NEED_WATCH_AD } private fun updateItemState( itemIndex: Int, subItemIndex: Int, newState: Int ) { if (itemIndex in 0..mWithdrawItemList.size-1) { val curItem = mWithdrawItemList[itemIndex] if (subItemIndex in 0..curItem.subItemList.size - 1) { curItem.subItemList[subItemIndex].withdrawState = newState saveInfos2Sp(mWithdrawItemList) } } } fun setItemStarted(itemIndex: Int) { if (itemIndex in 0..mWithdrawItemList.size-1) { val curItem = mWithdrawItemList[itemIndex] if (!curItem.hasStarted) { curItem.hasStarted = true curItem.startMs = System.currentTimeMillis() AccountManager.adjustCash(-1 * curItem.totalCashNum) saveInfos2Sp(mWithdrawItemList) notifyItemListChanged() } } } // ------------------------------- Withdraw Init and Payout ----------------------------------- fun startWithdrawReal(payCashNum: Double, withdrawItemId: Int, withdrawSubItemId: Int, payItemLoopIndex: Int) { mBgScope.launch { val withdrawRecord = RecordCash(RECORD_CASH_WITHDRAW, payCashNum).apply { uuid = AndroidUtil.randomUUid() withdrawState = TRANSACTION_STATE_ONGOING withdrawItemIndex = withdrawItemId withdrawItemSubIndex = withdrawSubItemId withdrawItemLoopIndex = payItemLoopIndex } saveNewWithdrawRecord(withdrawRecord) updateItemState(withdrawItemId, withdrawSubItemId, STATE_WITHDRAWING) notifyItemListChanged() val initReqParam = applyInitFields( PayInitReq()) val initReqResult = NetworkUtil.callApi { NetworkUtil.apiservice().withdrawInit(initReqParam) } when (initReqResult) { is Result.Loading -> { } is Result.Error -> { handleWithdrawFailed(ERROR_COMMON_UNKNOW, withdrawRecord) } is Result.Success -> { val initResp = initReqResult.data.data initResp?.let { var failType = 0 if (it.error == 0 && !it.uuid.isNullOrEmpty() && !it.items.isNullOrEmpty()) { val isSmallWithdraw = withdrawRecord.amountNum <= VidiConst.WITHDRAW_SMALL_NUM val withDrawItem = it.items?.get(if (isSmallWithdraw) 0 else 1)!! if (withDrawItem.status == INIT_OK) { withdrawRecord.withdrawInitUUID = it.uuid!! val shouldUserPayItemIndex = if (isSmallWithdraw) 0 else 1 if (shouldUserPayItemIndex < it.items!!.size) { withdrawRecord.payInitItemId = it.items?.get(shouldUserPayItemIndex)?.id!! } // start payOut requestPayout(withdrawRecord) } else { failType = withDrawItem.status } } else { // 0成功,1失败,2签名验证失败,3客户端版本过低,4 ts长度错误 failType = it.error + 10 } if (failType > 0) { handleWithdrawFailed(failType, withdrawRecord) } } } } } } private fun requestPayout(withdrawRecord: RecordCash) { mBgScope.launch { val payoutReqParam = applyInitFields(PayoutReq()).apply { val bankAccount = AccountManager.getAccount().bankInfo?.bankAccount val accountType = "CPF" account = bankAccount item_id = withdrawRecord.payInitItemId amount = withdrawRecord.amountNum.toString() additional_remark = "communnyboneycashmoneyrewardfastrealgame" uuid = withdrawRecord.withdrawInitUUID account_type = accountType document_type = accountType document_id = bankAccount name = "CapyBucks" clientName = AndroidUtil.getPackageId() dataAdjust.gps_adid = "gaid" dataAdjust.android_id = "androidid" dataAdjust.adid = "adid" dataAdjust.user_agent = "GetUerAgent" dataAdjust.price = amount dataAdjust.currency = "USD" dataShuShu.gps_gaid = "gaid" dataShuShu.android_id = "androidid" dataShuShu.adid = "adid" dataShuShu.user_agent = "GetUerAgent" dataShuShu.price = amount dataShuShu.currency = "USD" dataShuShu.payment_method = "Pix" dataShuShu.payment_type = accountType dataShuShu.payment_number = account dataShuShu.iap_name = "100br" dataShuShu.gamecoin_number = "100" dataShuShu.gamecoin_type = "gold" dataShuShu.ss_account_id = "GetSSAccountId" dataShuShu.ss_distinct_id = "GetSSDistinctId" dataShuShu.ss_super_properties = "GetSSSuper Properties" } val payoutReqResult = NetworkUtil.callApi { NetworkUtil.apiservice().withdrawPayout(payoutReqParam) } when (payoutReqResult) { Result.Loading -> { } is Result.Error -> { handleWithdrawFailed(ERROR_COMMON_UNKNOW, withdrawRecord) } is Result.Success -> { val payoutResultData = payoutReqResult.data.data payoutResultData?.let { withdrawRecord.payOutReplyId = payoutResultData.id?:"" withdrawRecord.payOutReplyNo = payoutResultData.record_no if (payoutResultData.error == 0) { // 1 更新 record并保存 RecordsManager.instance().updateCashRecord(withdrawRecord) // 2 loop check 最终结果 loopCheckTransactionState() } else { var failType: Int? = 0 /* 错误码, 0成功,1失败,2签名验证失败,3客户端版本过低,4uuid错误,5所在地国家或地区不在提现限制内,6提现金额不符对应的产品id,7提现产品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就提现其它的 */ failType = payoutResultData?.error if (failType != null && failType > 0) { failType += 20 handleWithdrawFailed(failType, withdrawRecord) } } } } } } } /** * 统一的失败处理 */ private fun handleWithdrawFailed(failReasonType: Int, withdrawRecord: RecordCash) { mBgScope.launch { // 1. 更新保存 提现记录状态 withdrawRecord.withdrawState = TRANSACTION_STATE_FAIL withdrawRecord.withdrawFailType = failReasonType withdrawRecord.hasShowResultDialog = false RecordsManager.instance().updateCashRecord(withdrawRecord) updateItemState(withdrawRecord.withdrawItemIndex, withdrawRecord.withdrawItemSubIndex, STATE_COULD_WITHDRAW) // 2. 事件通知以便更新UI notifyWithdrawResult(withdrawRecord) notifyItemListChanged() // 3. Statistics StatisticUtil.reportEvents(StatisticUtil.KEY_Withdrawal_Reason, mapOf( "Reason_Type" to "Fail", "Fail_Reason" to failReasonType.toString() + " : " + getFailHintStrRes(failReasonType), "Withdrawal_Position" to withdrawRecord.amountNum, "Withdrawal_Day" to 1, )) } } private fun handleLoopCheckWithdrawSuccess(withdrawRecord: RecordCash) { // 1. 更新record 并保存 withdrawRecord.withdrawState = TRANSACTION_STATE_SUCCESS RecordsManager.instance().updateCashRecord(withdrawRecord) updateItemState(withdrawRecord.withdrawItemIndex, withdrawRecord.withdrawItemSubIndex, STATE_WITHDRAW_SUCCESS) // 2. 更新取现 条目状态 if (withdrawRecord.withdrawItemIndex >= 0) { checkIfItemFinishAndReset(withdrawRecord.withdrawItemIndex) } // 3. event 通知 notifyWithdrawResult(withdrawRecord) notifyItemListChanged() // 4. Statistic StatisticUtil.reportEvents(StatisticUtil.KEY_Withdrawal_Reason, mapOf("Reason_Type" to "Success", "Fail_Reason" to 0, "Withdrawal_Position" to withdrawRecord.amountNum, "Withdrawal_Day" to 1)) // 5. 记录小额提现 已提现 TaskManager.instance().newbieFirstWithdrawStatus().setSmallCashHasWithdrawed() } } data class WithdrawItem( val index: Int, val totalCashNum: Double, var totalProgress: Int = 0, val subItemList: List = emptyList(), var startMs: Long = 0L, var hasStarted: Boolean = false, var isBigWithDraw: Boolean = true, var loopIndex: Int = 1 ) data class WithdrawSubItem( val dayIndex: Int, val cashTotal: Double, val startAdProgress: Int = 0, var currentAdProgress: Int = 0, var hasEarnMoneyByAd: Double = 0.0, var withdrawState: Int = STATE_NEED_WATCH_AD, )