体现接口 调用

This commit is contained in:
renhaoting 2025-12-10 19:21:11 +08:00
parent 2ebaf58f56
commit 1a3b70076a
7 changed files with 244 additions and 7 deletions

View File

@ -10,6 +10,9 @@
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application

View File

@ -14,8 +14,10 @@ object VidiConst {
const val WATCH_AD_FOR_CONVERT_GOLD_2_CASH = 6
/**
* Withdraw related const
*/
const val WITHDRAW_MD5KEY = "eonline~#*^%$@!~0702"

View File

@ -126,8 +126,20 @@ class WithDrawActivity : AppViewsEmptyViewModelActivity<ViewBinding>(), 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() {

View File

@ -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 : PayInitReq> 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
}
}

View File

@ -2,6 +2,10 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application>
<activity android:name=".util.permission.PermissionActivity" android:exported="false" />

View File

@ -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();
}*/
}

View File

@ -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> = NetworkInterface.getNetworkInterfaces()
while (interfaces.hasMoreElements()) {
val networkInterface = interfaces.nextElement()
val addresses: java.util.Enumeration<InetAddress> = 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
}
}