添加引导页支付显示控制,优化文件下载,添加卓易通判断

This commit is contained in:
wangyu 2026-05-22 15:38:00 +08:00
parent ab284a6108
commit fa120ddbe6
14 changed files with 152 additions and 149 deletions

View File

@ -11,8 +11,8 @@ batiaoSdkConfig {
enableHttpAuth = true
useMavenSdk = true
sdkVersion = "+"
prop("signKey","ckBHUSWBx3TqwNT2kxMrsXyXFuA3PW")
prop("decodeKey","zpzkfp72v3hgatzg5w7pyg86x5342kxt")
prop("signKey", BATIAO_SIGN_KEY)
prop("decodeKey", BATIAO_DECODE_KEY)
}
android {
@ -29,8 +29,8 @@ android {
applicationId "com.cheng.BoLe"
minSdk 26
targetSdk 34
versionCode 281
versionName "2.8.1"
versionCode 282
versionName "2.8.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
@ -44,6 +44,7 @@ android {
flavorDimensions = ["channel"]
productFlavors {
batiao {}
xiaomi {}
oppo {}
vivo {}

View File

@ -24,9 +24,6 @@ object Constants {
const val shareList: String = "${BaseUrl}/static/new5/shareList.html"//第三方共享清单
const val sdkList: String = "${BaseUrl}/static/new5/sdkList.html"//第三方SDK目录
const val Signature = "ckBHUSWBx3TqwNT2kxMrsXyXFuA3PW"
const val decrypt = "zpzkfp72v3hgatzg5w7pyg86x5342kxt"
val dDIN_PRO_M = Typeface.createFromAsset(Utils.getApp().assets, "fonts/D-DIN-PRO-500-Medium.otf")
val almmsht = Typeface.createFromAsset(Utils.getApp().assets, "fonts/AlimamaShuHeiTi.ttf")
val douyinsansB = Typeface.createFromAsset(Utils.getApp().assets, "fonts/DouyinSansBold.otf")

View File

@ -27,8 +27,6 @@ class HttpRetrofit internal constructor() {
//header拦截
httpClient.addInterceptor(RequestHeaderInterceptor())
httpClient.addInterceptor(ContentTypeInterceptor())
//请求拦截
httpClient.addInterceptor(RequestInterceptor())
//响应拦截
httpClient.addInterceptor(ResponseInterceptor())

View File

@ -0,0 +1,21 @@
package com.cheng.blzb.net
import okhttp3.Interceptor
import okhttp3.Response
class NoSignHeaderInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
val requestBuilder = request.newBuilder()
request = requestBuilder
.addHeader("no-sign", "1")
.addHeader("no-decode", "1")
.build()
return chain.proceed(request)
}
}

View File

@ -9,6 +9,7 @@ import com.example.base.utils.Utils
import com.github.gzuliyujiang.oaid.DeviceIdentifier
import com.cheng.blzb.common.Constants
import com.cheng.blzb.manager.UserConfigManager
import com.cheng.blzb.utils.ZhuoyiTongUtils
import okhttp3.Interceptor
import okhttp3.Response
@ -22,7 +23,7 @@ class RequestHeaderInterceptor : Interceptor {
request = requestBuilder
.addHeader("x-token", LoginManager.getToken())
.addHeader("x-version", AppUtils.getAppVersionName())
.addHeader("x-platform", "android")
.addHeader("x-platform", /*if (ZhuoyiTongUtils.isInZhuoyiTong()) "harmony" else */"android")
.addHeader("x-device-id", DeviceIdentifier.getAndroidID(Utils.getApp()))
.addHeader("x-mobile-brand", android.os.Build.BRAND)
.addHeader("x-mobile-model", android.os.Build.MODEL)

View File

@ -1,78 +0,0 @@
package com.cheng.blzb.net
import android.text.TextUtils
import com.cheng.blzb.common.Constants
import com.cheng.blzb.manager.UserConfigManager
import com.cheng.blzb.utils.StringUtils
import com.example.base.utils.L
import okhttp3.Interceptor
import okhttp3.Response
import okio.Buffer
import java.nio.charset.StandardCharsets
import java.util.Arrays
import java.util.Locale
/**
* @date 2020-06-05 13:53
* @desc 网络请求可以在此处添加n多的请求拦截-加密数据
*/
class RequestInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
var request = chain.request()
val method = request.method.lowercase(Locale.getDefault()).trim { it <= ' ' }
val url = request.url
val apiPath = String.format("%s", url)
L.d("TAG-->>url=$apiPath")
//如果请求的不是服务端的接口则不用加密
if (!apiPath.startsWith(Constants.BaseUrl)) {
L.d("TAG-->>content-type=${request.headers["Content-Type"]}")
val requestBody = request.body
L.d("TAG-->>${requestBody.toString()}")
return chain.proceed(request)
}
var queryString = url.encodedQuery
queryString = if (!TextUtils.isEmpty(queryString)) {
(queryString + "&nonce=" + StringUtils.createUUID()) + "&timestamp=" + UserConfigManager.serverTimeMillis() / 1000
} else {
("nonce=" + StringUtils.createUUID()) + "&timestamp=" + UserConfigManager.serverTimeMillis() / 1000
}
val sortQueryString = Arrays.stream(queryString.split("&".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray())
.sorted { obj: String, anotherString: String? -> obj.compareTo(anotherString!!) }
.reduce { x: String, y: String -> "$x&$y" }
.get()
//如果请求方式是get或者delete 则没有body
var paramsStr = ""
var bytes = ByteArray(0)
var signature: String? = ""
if (method == "put" || method == "post") {
val requestBody = request.body
L.d("TAG-->>${requestBody.toString()}")
val buffer = Buffer()
requestBody!!.writeTo(buffer)
bytes = StringUtils.addByte(bytes, buffer.readByteArray())
L.e("签名后bodyByte的长度为" + bytes.size)
paramsStr = String(bytes, StandardCharsets.UTF_8)
// paramsStr = buffer.readUtf8();
L.e("签名后body的长度为" + paramsStr.length)
}
signature = if (bytes.isNotEmpty()) {
L.e("当前的数组长度为----" + bytes.size)
StringUtils.getMD5Byte(
StringUtils.addByte(
StringUtils.addByte("$sortQueryString&".toByteArray(), bytes),
("&" + StringUtils.getMD5String(Constants.Signature)).toByteArray()
)
)
} else {
StringUtils.getMD5String(sortQueryString + "&" + StringUtils.getMD5String(Constants.Signature))
}
val newUrl = apiPath.split("\\?".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()[0] + "?" + queryString + "&signature=" + signature
L.e("签名后的路径---", newUrl)
request = request.newBuilder().url(newUrl).build()
return chain.proceed(request)
}
}

View File

@ -11,6 +11,7 @@ import com.cheng.blzb.BuildConfig
import com.cheng.blzb.common.Constants
import com.cheng.blzb.event.HomeRefreshEvent
import com.cheng.blzb.manager.LoginManager
import com.cheng.blzb.manager.UserConfigManager
import com.cheng.blzb.ui.activity.LoginActivity
import com.cheng.blzb.ui.activity.PublicActivity
import com.cheng.blzb.ui.fragment.mine.vip.VipFragment
@ -31,12 +32,6 @@ class ResponseInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request()
val url = request.url
val apiPath = String.format("%s", url)
//如果请求的不是服务端的接口则不用加密
if (!apiPath.startsWith(if (BuildConfig.DEBUG) Constants.TestUrl else Constants.BaseUrl)) {
return chain.proceed(request)
}
val response = chain.proceed(request)
var charset = Charset.forName("UTF-8")
val contentType = response.header("Content-Type")
@ -55,52 +50,28 @@ class ResponseInterceptor : Interceptor {
}
}
val respBody = buffer.clone().readString(charset!!)
L.d("response=${respBody}")
L.d("ResponseInterceptor>>>>>>>response=${respBody}, request=${request.url}")
if (TextUtils.isEmpty(respBody)) {
return response
}
val code = JSON.parseObject(respBody).getInteger("code")
if (code == 1001003 || code == 1001004 || code == 1001005) {
LoginManager.logout()
val intent = Intent(Utils.getApp(), LoginActivity::class.java)
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
Utils.getApp().startActivity(intent)
}
when (code) {
11018 -> {
RxBus.defaultInstance.post(HomeRefreshEvent())
}
val isEncrypt = JSON.parseObject(respBody).getBoolean("encrypt")
L.e("是否需要解密$isEncrypt")
if (isEncrypt == null || !isEncrypt) { //如果不需要加密 直接返回
L.d("response=${response.body}")
return response
}
val decrybody = JSON.parseObject(respBody).getString("data")
L.e("Json解析后的字符串为$decrybody")
var decryString: String?
try {
decryString = AESpkcs7paddingUtil.decryptNormal(decrybody, Constants.decrypt)
Log.e("ResponseInterceptor", "解密后返回的字符串为$decryString")
val decCode = JSON.parseObject(decryString).getInteger("code")
when (decCode) {
11018 -> {
RxBus.defaultInstance.post(HomeRefreshEvent())
}
19000 -> {
PublicActivity.newStart(Utils.getApp(), VipFragment::class.java, Pair("origin", "interceptor"))
}
19000 -> {
PublicActivity.newStart(Utils.getApp(), VipFragment::class.java, Pair("origin", "interceptor"))
}
1001003, 1001004, 1001005 -> {
LoginManager.logout()
1001003, 1001004, 1001005 -> {
LoginManager.logout()
UserConfigManager.userConfig {
val intent = Intent(Utils.getApp(), LoginActivity::class.java)
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
Utils.getApp().startActivity(intent)
}
}
//返回新创建的response
return response.newBuilder().body(ResponseBody.create("text/plain".toMediaType(), decryString)).build()
} catch (e: Exception) {
e.printStackTrace()
}
}
}

View File

@ -14,6 +14,8 @@ import com.cheng.blzb.bean.GuideTotalBidEntity
import com.cheng.blzb.bean.HotWordEntity
import com.cheng.blzb.common.Constants
import com.cheng.blzb.databinding.FragmentGuideItem5Binding
import com.cheng.blzb.manager.UserConfigManager
import com.cheng.blzb.ui.activity.MainActivity
import com.cheng.blzb.ui.activity.PublicActivity
import com.cheng.blzb.ui.fragment.guide.GuideFragment
import com.cheng.blzb.ui.fragment.guide.GuideViewModel
@ -28,6 +30,7 @@ import com.google.gson.Gson
import com.yy.mobile.rollingtextview.CharOrder
import com.yy.mobile.rollingtextview.strategy.Strategy
import org.jetbrains.anko.sdk27.listeners.onTouch
import org.jetbrains.anko.startActivity
import org.libpag.PAGFile
class GuideItem5Fragment : BaseFragment<FragmentGuideItem5Binding, GuideViewModel>() {
@ -218,12 +221,16 @@ class GuideItem5Fragment : BaseFragment<FragmentGuideItem5Binding, GuideViewMode
binding.tvProgressStatus.text = "打开标讯采集报告..."
binding.progressBar.postDelayed({
if (activity != null) {
PublicActivity.start(
requireContext(),
GuideVipFragment::class.java,
Pair("hotWords", Gson().toJson(hotWordChildList)),
Pair("total", totalInfo)
)
if (UserConfigManager.getGuidePayEnable()){
PublicActivity.start(
requireContext(),
GuideVipFragment::class.java,
Pair("hotWords", Gson().toJson(hotWordChildList)),
Pair("total", totalInfo)
)
} else{
requireActivity().startActivity<MainActivity>()
}
requireActivity().finish()
}
}, 1000)

View File

@ -22,8 +22,10 @@ import com.cheng.blzb.databinding.FragmentGuideItem5KbBinding
import com.cheng.blzb.manager.EventReportManager
import com.cheng.blzb.manager.UserConfigManager
import com.cheng.blzb.ui.activity.GuideActivity
import com.cheng.blzb.ui.activity.MainActivity
import com.cheng.blzb.ui.activity.PublicActivity
import com.cheng.blzb.ui.fragment.guide.GuideFragment
import com.cheng.blzb.ui.fragment.guide.vip.GuideVipFragment
import com.cheng.blzb.ui.fragment.guide_kb.GuideKBViewModel
import com.cheng.blzb.ui.fragment.guide_kb.adapter.GuideItem5KBCityAdapter
import com.cheng.blzb.ui.fragment.guide_kb.adapter.GuideItem5KBKeywordAdapter
@ -37,6 +39,7 @@ import com.google.gson.Gson
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.disposables.Disposable
import org.jetbrains.anko.startActivity
import org.libpag.PAGFile
import org.libpag.PAGImageView
import java.util.concurrent.TimeUnit
@ -245,12 +248,16 @@ class GuideItem5KBFragment : BaseFragment<FragmentGuideItem5KbBinding, GuideKBVi
}
10500L -> {
PublicActivity.start(
requireContext(),
GuideVipKBFragment::class.java,
Pair("hotWords", Gson().toJson(hotWordChildList)),
Pair("total", totalInfo)
)
if (UserConfigManager.getGuidePayEnable()){
PublicActivity.start(
requireContext(),
GuideVipKBFragment::class.java,
Pair("hotWords", Gson().toJson(hotWordChildList)),
Pair("total", totalInfo)
)
} else{
requireActivity().startActivity<MainActivity>()
}
GuideActivity.finishAll()
}
}

View File

@ -22,7 +22,11 @@ object ChannelUtils {
MMKVUtils.put("app_channel", getChannelBy())
}
}
return MMKVUtils.getString("app_channel") ?: ""
var channel = MMKVUtils.getString("app_channel") ?: ""
if (ZhuoyiTongUtils.isInZhuoyiTong()) {
channel = "huawei_zyt"
}
return channel
}
private fun getChannelBy(): String? {

View File

@ -3,6 +3,7 @@ package com.cheng.blzb.utils
import android.os.Handler
import android.os.Looper
import android.util.Log
import com.cheng.blzb.net.NoSignHeaderInterceptor
import com.example.base.utils.L
import okhttp3.*
import okhttp3.Headers.Companion.toHeaders
@ -87,6 +88,7 @@ class DownLoadUtils private constructor() {
.readTimeout(readTimeOut, TimeUnit.SECONDS)
.writeTimeout(writeTimeout, TimeUnit.SECONDS)
.connectTimeout(connectTimeout, TimeUnit.SECONDS)
.addInterceptor(NoSignHeaderInterceptor())
.addInterceptor(interceptor ?: LoggingInterceptor())
.build()
}

View File

@ -0,0 +1,34 @@
package com.cheng.blzb.utils
import java.io.File
object ZhuoyiTongUtils {
private val procPaths = listOf(
"/proc/self/cgroup",
"/proc/1/cgroup",
"/proc/self/mountinfo"
)
private val containerKeywords = listOf(
"isulad",
"zhuoyitong",
"droitong",
"lxc"
)
fun isInZhuoyiTong(): Boolean {
return procPaths.any { path ->
readProcFile(path).let { content ->
containerKeywords.any { keyword -> content.contains(keyword) }
}
}
}
fun isInstalledInZhuoyiTong(): Boolean = isInZhuoyiTong()
private fun readProcFile(path: String): String {
return runCatching {
File(path).takeIf { it.exists() }?.readText().orEmpty().lowercase()
}.getOrDefault("")
}
}

View File

@ -29,4 +29,10 @@ android.injected.testOnly=false
RELEASE_KEY_PASSWORD=sQYG1Jee
RELEASE_KEY_ALIAS=__uni__7e100bb
RELEASE_STORE_PASSWORD=sQYG1Jee
RELEASE_STORE_FILE=bidinfo.keystore
RELEASE_STORE_FILE=bidinfo.keystore
BATIAO_REPO_USERNAME=admin
BATIAO_REPO_PASSWORD=Batiao@12B
BATIAO_SIGN_KEY=ckBHUSWBx3TqwNT2kxMrsXyXFuA3PW
BATIAO_DECODE_KEY=zpzkfp72v3hgatzg5w7pyg86x5342kxt

View File

@ -12,8 +12,8 @@ pluginManagement {
maven {
url "https://maven.batiao8.com/repository/maven-releases/"
credentials {
username "admin"
password "Batiao@12B"
username BATIAO_REPO_USERNAME
password BATIAO_REPO_PASSWORD
}
}
maven { url 'https://maven.aliyun.com/repository/public' }
@ -26,8 +26,40 @@ pluginManagement {
resolutionStrategy {
eachPlugin {
if (requested.id.id == "com.batiao.batiaosdkbuilder") {
useModule("com.batiao:batiao-sdk-builder:${requested.version}")
if (requested.id.id == 'com.batiao.batiaosdkbuilder') {
def repoUrl = 'https://maven.batiao8.com/repository/maven-releases/'
def mavenUser = BATIAO_REPO_USERNAME
def mavenPass = BATIAO_REPO_PASSWORD
def groupId = 'com.batiao'
def artifactId = 'batiao-sdk-builder'
def pluginVersion = requested.version ?: '+'
def isDynamic = pluginVersion.contains('+') ||
pluginVersion.equalsIgnoreCase('latest.release') ||
pluginVersion.equalsIgnoreCase('latest.integration') ||
pluginVersion.equalsIgnoreCase('release.+')
if (isDynamic) {
def base = repoUrl.endsWith('/') ? repoUrl : repoUrl + '/'
def metaUrl = base + groupId.replace('.', '/') + '/' + artifactId + '/maven-metadata.xml'
def conn = new URL(metaUrl).openConnection()
conn.setConnectTimeout(20_000)
conn.setReadTimeout(20_000)
if (mavenUser) {
def creds = "${mavenUser}:${mavenPass ?: ''}".bytes.encodeBase64().toString()
conn.setRequestProperty('Authorization', "Basic ${creds}")
}
if (conn.responseCode != 200) {
throw new GradleException("Batiao: fetch ${metaUrl} failed HTTP ${conn.responseCode}")
}
def xml = new XmlSlurper().parse(conn.inputStream)
pluginVersion = (xml.versioning.release?.text() ?: xml.versioning.latest?.text())?.trim()
if (!pluginVersion) {
throw new GradleException("Batiao: no release/latest in ${metaUrl}")
}
}
useModule("${groupId}:${artifactId}:${pluginVersion}")
}
}
}
@ -38,8 +70,8 @@ dependencyResolutionManagement {
maven {
url "https://maven.batiao8.com/repository/maven-releases/"
credentials {
username "admin"
password "Batiao@12B"
username BATIAO_REPO_USERNAME
password BATIAO_REPO_PASSWORD
}
}
maven { url 'https://maven.aliyun.com/repository/public' }