diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 2778b5d..435d8d7 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -10,6 +10,9 @@
+
+
+
(), OnTabSty
override fun ViewBinding.initListeners() {
registerEvents({ data->
- updateUICashTotal()
- }, VididinEvents.Event_Account_Cash_Changed)
+ when (data?.mEventType) {
+ VididinEvents.Event_Account_Cash_Changed -> {
+ updateUICashTotal()
+ }
+
+ VididinEvents.EVENT_AD_WATCHED_FOR_WITHDRAW -> {
+ var withdrawNum: Float = (data.mData as Double).toFloat()
+ withdrawInit()
+ withdrawPayout()
+ withdrawCheck()
+ }
+ }
+
+ }, VididinEvents.Event_Account_Cash_Changed, VididinEvents.EVENT_AD_WATCHED_FOR_WITHDRAW)
}
override fun ViewBinding.initObservers() {
diff --git a/app/src/main/java/com/gamedog/vididin/features/withdraw/WithdrawViewModel.kt b/app/src/main/java/com/gamedog/vididin/features/withdraw/WithdrawViewModel.kt
index c574c89..90c3aee 100644
--- a/app/src/main/java/com/gamedog/vididin/features/withdraw/WithdrawViewModel.kt
+++ b/app/src/main/java/com/gamedog/vididin/features/withdraw/WithdrawViewModel.kt
@@ -2,6 +2,11 @@ package com.gamedog.vididin.features.withdraw
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
+import com.ama.core.architecture.util.AndroidUtil
+import com.ama.core.architecture.util.DeviceUtil
+import com.ama.core.architecture.util.MD5Util
+import com.ama.core.architecture.util.NetUtil
+import com.gamedog.vididin.VidiConst
import com.gamedog.vididin.beans.req.PayInitReq
import com.gamedog.vididin.beans.req.PayoutCheckReq
import com.gamedog.vididin.beans.req.PayoutReq
@@ -28,9 +33,11 @@ class WithdrawViewModel : ViewModel() {
fun withdrawInit() {
viewModelScope.launch {
+ val requestParam = PayInitReq().applyInitFields()
+
_InitData.value = Result.Loading
_InitData.value = NetworkUtil.callApi {
- NetworkUtil.apiservice().withdrawInit(PayInitReq())
+ NetworkUtil.apiservice().withdrawInit(requestParam)
}
}
}
@@ -38,21 +45,42 @@ class WithdrawViewModel : ViewModel() {
fun withdrawPayout() {
viewModelScope.launch {
+ val requestParam = PayoutReq().applyInitFields().apply {
+ // TODO -
+ }
+
_PayoutResult.value = Result.Loading
_PayoutResult.value = NetworkUtil.callApi {
- NetworkUtil.apiservice().withdrawPayout(PayoutReq())
+ NetworkUtil.apiservice().withdrawPayout(requestParam)
}
}
}
fun withdrawCheck() {
viewModelScope.launch {
+ val requestParam = PayoutCheckReq().applyInitFields().apply {
+ // TODO -
+ }
+
_CheckResult.value = Result.Loading
_CheckResult.value = NetworkUtil.callApi {
- NetworkUtil.apiservice().withdrawCheck(PayoutCheckReq())
+ NetworkUtil.apiservice().withdrawCheck(requestParam)
}
}
}
+ private fun T.applyInitFields(): T {
+ 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 this
+ }
+
}
\ No newline at end of file
diff --git a/core/architecture/src/main/AndroidManifest.xml b/core/architecture/src/main/AndroidManifest.xml
index 643110e..3ccca87 100644
--- a/core/architecture/src/main/AndroidManifest.xml
+++ b/core/architecture/src/main/AndroidManifest.xml
@@ -2,6 +2,10 @@
+
+
+
+
diff --git a/core/architecture/src/main/java/com/ama/core/architecture/util/MD5Util.kt b/core/architecture/src/main/java/com/ama/core/architecture/util/MD5Util.kt
index 065ebad..4ab5874 100644
--- a/core/architecture/src/main/java/com/ama/core/architecture/util/MD5Util.kt
+++ b/core/architecture/src/main/java/com/ama/core/architecture/util/MD5Util.kt
@@ -1,5 +1,7 @@
package com.ama.core.architecture.util
+import java.nio.charset.Charset
+import java.nio.charset.StandardCharsets
import java.security.MessageDigest
object MD5Util {
@@ -22,4 +24,97 @@ object MD5Util {
null
}
}
+
+ /*fun md5ForWithDraw(input: String): String? {
+ return try {
+ val messageDigest = MessageDigest.getInstance("MD5")
+ val digestBytes = messageDigest.digest(input.toByteArray(Charsets.UTF_8))
+ val hashValue = digestBytes.hashCode()
+
+
+
+ val hexString = StringBuilder()
+ for (b in digestBytes) {
+ val hex = Integer.toHexString(0xFF and b.toInt())
+ if (hex.length == 1) {
+ hexString.append('0')
+ }
+ hexString.append(hex)
+ }
+ hexString.toString()
+ } catch (e: Exception) {
+ e.printStackTrace()
+ null
+ }
+ }*/
+
+
+
+ /**
+ * MD5加密函数
+ * @param original 原始字符串
+ * @param charsetName 字符编码名称,默认为"UTF-8"
+ * @return 返回32位小写的MD5哈希字符串
+ */
+ fun md5ForWithDraw(input: String): String {
+ // 元宝
+ val bytes = input.toByteArray(charset("UTF-8")) // 按指定字符集转换为字节数组[6](@ref)
+ val digest = MessageDigest.getInstance("MD5") // 获取MD5实例[6,7,8](@ref)
+ val hashBytes = digest.digest(bytes) // 计算MD5哈希值[6,7,8](@ref)
+
+ // 将字节数组转换为十六进制字符串[6,8](@ref)
+ val hexString = StringBuilder()
+ for (byte in hashBytes) {
+ val hex = (byte.toInt() and 0xFF).toString(16) // 确保无符号转换[6](@ref)
+ if (hex.length == 1) {
+ hexString.append('0') // 单数位前补零[6,8](@ref)
+ }
+ hexString.append(hex)
+ }
+ return hexString.toString().lowercase()
+
+ /* // 百度
+ val md = MessageDigest.getInstance("MD5")
+ val inputBytes = input.toByteArray(StandardCharsets.UTF_8)
+ val hashBytes = md.digest(inputBytes)
+
+ return hashBytes.joinToString("") { byte -> "%02x".format(byte) }*/
+
+
+ /* // 豆包
+ // 1. 对应C#: Encoding.GetEncoding(pCharSet).GetBytes("utf-8")
+ val charset = Charset.forName("UTF-8")
+ val tData = "utf-8".toByteArray(charset)
+
+ // 2. 对应C#: new MD5CryptoServiceProvider().ComputeHash(tData)
+ val md5 = MessageDigest.getInstance("MD5")
+ val tHash = md5.digest(tData)
+
+ // 3. 对应C#: 循环拼接两位小写十六进制(x2)
+ val tResult = StringBuilder(32) // 预初始化容量32,与C#一致
+ for (i in tHash.indices) {
+ // 对应C#: tHash[i].ToString("x2") —— 格式化为两位十六进制(不足补0)
+ tResult.append(String.format("%02x", tHash[i]))
+ }
+
+ // 4. 对应C#: ToString().ToLower()(注:%02x本身已是小写,此处保持ToLower()与原代码一致)
+ return tResult.toString().lowercase()
+ */
+
+ }
+
+
+ /*
+ private static string GetMD5(string pOriginal)
+ {
+ var tData = Encoding.GetEncoding(pCharSet).GetBytes("utf-8");
+ var tHash = new MD5CryptoServiceProvider().ComputeHash(tData);
+ var tResult = new StringBuilder(32);
+ for (int i = 0; i < tHash.Length; i++)
+ {
+ tResult.Append(tHash[i].ToString("x2"));
+ }
+ return tResult.ToString().ToLower();
+ }*/
+
}
\ No newline at end of file
diff --git a/core/architecture/src/main/java/com/ama/core/architecture/util/NetUtil.kt b/core/architecture/src/main/java/com/ama/core/architecture/util/NetUtil.kt
new file mode 100644
index 0000000..79ad13c
--- /dev/null
+++ b/core/architecture/src/main/java/com/ama/core/architecture/util/NetUtil.kt
@@ -0,0 +1,93 @@
+package com.ama.core.architecture.util
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.net.ConnectivityManager
+import android.net.NetworkCapabilities
+import android.net.wifi.WifiManager
+import com.ama.core.architecture.BaseApp
+import java.net.Inet4Address
+import java.net.InetAddress
+import java.net.NetworkInterface
+
+@SuppressLint("StaticFieldLeak")
+object NetUtil {
+ val context = BaseApp.appContext()
+ /**
+ * 获取本机IPv4地址
+ * @param context 上下文对象
+ * @return IPv4地址字符串,无网络连接时返回null
+ */
+ fun getLocalIpAddress(): String? {
+ return when (getNetworkType()) {
+ NetworkType.WIFI -> getWifiIpAddress()
+ NetworkType.MOBILE -> getMobileIpAddress()
+ NetworkType.NONE -> null // 无网络连接
+ }
+ }
+
+ /**
+ * 获取当前网络类型
+ */
+ private fun getNetworkType(): NetworkType {
+ val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
+ val network = connectivityManager.activeNetwork ?: return NetworkType.NONE
+ val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return NetworkType.NONE
+
+ return when {
+ capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> NetworkType.WIFI
+ capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> NetworkType.MOBILE
+ else -> NetworkType.NONE
+ }
+ }
+
+ /**
+ * 获取Wi-Fi网络下的IP地址
+ */
+ private fun getWifiIpAddress(): String? {
+ return try {
+ val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
+ val wifiInfo = wifiManager.connectionInfo
+ val ipAddress = wifiInfo.ipAddress
+ intToIp(ipAddress)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ null
+ }
+ }
+
+ /**
+ * 获取移动数据网络下的IP地址
+ */
+ private fun getMobileIpAddress(): String? {
+ return try {
+ val interfaces: java.util.Enumeration = NetworkInterface.getNetworkInterfaces()
+ while (interfaces.hasMoreElements()) {
+ val networkInterface = interfaces.nextElement()
+ val addresses: java.util.Enumeration = networkInterface.inetAddresses
+ while (addresses.hasMoreElements()) {
+ val address = addresses.nextElement()
+ // 过滤回环地址、链路本地地址,且只返回IPv4地址[2,3](@ref)
+ if (!address.isLoopbackAddress && !address.isLinkLocalAddress && address is Inet4Address) {
+ return address.hostAddress
+ }
+ }
+ }
+ null
+ } catch (e: Exception) {
+ e.printStackTrace()
+ null
+ }
+ }
+
+ /**
+ * 将整数形式的IP地址转换为字符串[1,2,4](@ref)
+ */
+ private fun intToIp(ipAddress: Int): String {
+ return "${(ipAddress and 0xFF)}.${(ipAddress shr 8 and 0xFF)}.${(ipAddress shr 16 and 0xFF)}.${(ipAddress shr 24 and 0xFF)}"
+ }
+
+ private enum class NetworkType {
+ WIFI, MOBILE, NONE
+ }
+}
\ No newline at end of file