fix(wb): 国际版无独立签到活动,不再调 daily-checkin,详情页展示说明卡
This commit is contained in:
parent
809b8db2d3
commit
f917e5bfd6
@ -459,7 +459,9 @@ private fun parseResourceDetail(body: String): Map<String, String>? {
|
|||||||
/** 今日已签到(幂等) */
|
/** 今日已签到(幂等) */
|
||||||
ALREADY,
|
ALREADY,
|
||||||
/** 签到失败(服务端给了原因,见 message) */
|
/** 签到失败(服务端给了原因,见 message) */
|
||||||
FAILED
|
FAILED,
|
||||||
|
/** 国际站无签到活动(活动未开启/未上线,非错误) */
|
||||||
|
NO_CAMPAIGN
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -486,6 +488,12 @@ private fun parseResourceDetail(body: String): Map<String, String>? {
|
|||||||
if (credential !is Credential.WorkBuddyCredential) {
|
if (credential !is Credential.WorkBuddyCredential) {
|
||||||
return@withContext Result.failure(RepositoryError.InvalidCredential())
|
return@withContext Result.failure(RepositoryError.InvalidCredential())
|
||||||
}
|
}
|
||||||
|
// 国际版没有独立签到档案:积分来自网页/客户端活跃使用,直接返回“无活动”。
|
||||||
|
if (credential.isIntlRegion()) {
|
||||||
|
return@withContext Result.success(
|
||||||
|
CheckinStatus(false, false, 0, 0, 0, "", "", CheckinOutcome.NO_CAMPAIGN)
|
||||||
|
)
|
||||||
|
}
|
||||||
// 两条候选路径 fallback(cpa-plugin 实测:activity-status 优先,旧路径 checkin-status 兜底)
|
// 两条候选路径 fallback(cpa-plugin 实测:activity-status 优先,旧路径 checkin-status 兜底)
|
||||||
// 共享轮换状态:前一条路径轮换出的新 token 会用于下一条,且失败也先落库。
|
// 共享轮换状态:前一条路径轮换出的新 token 会用于下一条,且失败也先落库。
|
||||||
val body = authedPostFirstSuccessful(
|
val body = authedPostFirstSuccessful(
|
||||||
@ -517,6 +525,12 @@ private fun parseResourceDetail(body: String): Map<String, String>? {
|
|||||||
if (credential !is Credential.WorkBuddyCredential) {
|
if (credential !is Credential.WorkBuddyCredential) {
|
||||||
return@withContext Result.failure(RepositoryError.InvalidCredential())
|
return@withContext Result.failure(RepositoryError.InvalidCredential())
|
||||||
}
|
}
|
||||||
|
// 国际版不调用 daily-checkin(无签到营业),直接按无活动处理,避免每次刷新都报错。
|
||||||
|
if (credential.isIntlRegion()) {
|
||||||
|
return@withContext Result.success(
|
||||||
|
CheckinStatus(false, false, 0, 0, 0, "", "", CheckinOutcome.NO_CAMPAIGN)
|
||||||
|
)
|
||||||
|
}
|
||||||
val body = when (val r = authedPost(credential, "/v2/billing/meter/daily-checkin")) {
|
val body = when (val r = authedPost(credential, "/v2/billing/meter/daily-checkin")) {
|
||||||
is AuthedPostResult.Ok -> {
|
is AuthedPostResult.Ok -> {
|
||||||
persistCheckinOutcome(credential, accountId, r.rotatedCredential)
|
persistCheckinOutcome(credential, accountId, r.rotatedCredential)
|
||||||
@ -550,8 +564,15 @@ private fun parseResourceDetail(body: String): Map<String, String>? {
|
|||||||
?: (r["data"] as? JsonObject)?.scalar("msg", "message", "Message")
|
?: (r["data"] as? JsonObject)?.scalar("msg", "message", "Message")
|
||||||
}.getOrNull().orEmpty()
|
}.getOrNull().orEmpty()
|
||||||
val status = fetchCheckinStatus(accountId).getOrNull()
|
val status = fetchCheckinStatus(accountId).getOrNull()
|
||||||
// 已签到语义与上游 cpa-multi-plugins 对齐:code=10001 或文案含「已签/今日/already」。
|
|
||||||
val lowerMsg = msg.lowercase()
|
val lowerMsg = msg.lowercase()
|
||||||
|
// 国际站无签到活动:接口可能返回 data.active=false 或「活动未开启/已过期」。
|
||||||
|
val inactive = runCatching {
|
||||||
|
val r = json.parseToJsonElement(body).jsonObject
|
||||||
|
((r["data"] as? JsonObject)?.get("active") as? JsonPrimitive)?.contentOrNull?.equals("false", true) == true
|
||||||
|
}.getOrDefault(false)
|
||||||
|
val noCampaign = inactive || msg.contains("活动未开启") || msg.contains("已过期") ||
|
||||||
|
lowerMsg.contains("not active")
|
||||||
|
// 已签到语义与上游 cpa-multi-plugins 对齐:code=10001 或文案含「已签/今日/already」。
|
||||||
val already = code == 10001L || msg.contains("已签") || msg.contains("已经签到") ||
|
val already = code == 10001L || msg.contains("已签") || msg.contains("已经签到") ||
|
||||||
msg.contains("今日") || lowerMsg.contains("already") || lowerMsg.contains("checked") ||
|
msg.contains("今日") || lowerMsg.contains("already") || lowerMsg.contains("checked") ||
|
||||||
lowerMsg.contains("claimed")
|
lowerMsg.contains("claimed")
|
||||||
@ -566,6 +587,12 @@ private fun parseResourceDetail(body: String): Map<String, String>? {
|
|||||||
outcome = CheckinOutcome.SUCCESS
|
outcome = CheckinOutcome.SUCCESS
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
noCampaign -> Result.success(
|
||||||
|
(status ?: CheckinStatus(false, false, 0, 0, 0, "")).copy(
|
||||||
|
message = msg,
|
||||||
|
outcome = CheckinOutcome.NO_CAMPAIGN
|
||||||
|
)
|
||||||
|
)
|
||||||
already -> Result.success(
|
already -> Result.success(
|
||||||
(status ?: CheckinStatus(true, true, 0, 0, 0, "")).copy(
|
(status ?: CheckinStatus(true, true, 0, 0, 0, "")).copy(
|
||||||
outcome = CheckinOutcome.ALREADY
|
outcome = CheckinOutcome.ALREADY
|
||||||
@ -617,8 +644,21 @@ private fun parseResourceDetail(body: String): Map<String, String>? {
|
|||||||
val request = Request.Builder()
|
val request = Request.Builder()
|
||||||
.url(credential.originBase() + path)
|
.url(credential.originBase() + path)
|
||||||
.addHeader("Authorization", "Bearer " + access)
|
.addHeader("Authorization", "Bearer " + access)
|
||||||
.addHeader("Accept", "application/json")
|
.addHeader("Accept", "application/json, text/plain, */*")
|
||||||
.addHeader("Content-Type", "application/json")
|
.addHeader("Content-Type", "application/json")
|
||||||
|
.addHeader("User-Agent", "CLI/2.63.2 CodeBuddy/2.63.2")
|
||||||
|
.addHeader("Origin", credential.originBase())
|
||||||
|
.addHeader("Referer", credential.originBase() + "/profile/growth-center")
|
||||||
|
.addHeader("X-CodeBuddy-Request", "1")
|
||||||
|
.addHeader("Accept-Language", if (credential.isIntlRegion()) "en-US" else "zh-CN")
|
||||||
|
.apply {
|
||||||
|
if (credential.isIntlRegion()) {
|
||||||
|
addHeader("X-Domain", "www.workbuddy.ai")
|
||||||
|
addHeader("X-No-Enterprise-Id", "1")
|
||||||
|
} else {
|
||||||
|
addHeader("X-No-Enterprise-Id", "1")
|
||||||
|
}
|
||||||
|
}
|
||||||
.post("{}".toRequestBody(jsonMedia))
|
.post("{}".toRequestBody(jsonMedia))
|
||||||
.build()
|
.build()
|
||||||
val resp = try {
|
val resp = try {
|
||||||
|
|||||||
@ -265,17 +265,23 @@ fun ServiceDetailScreen(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ServiceType.WORKBUDDY -> {
|
ServiceType.WORKBUDDY -> {
|
||||||
item {
|
val wbIntl = uiState.region != null && uiState.region.equals("INTL", ignoreCase = true)
|
||||||
if (uiState.hasCredential) {
|
if (wbIntl) {
|
||||||
CheckinCard(
|
// 国际版没有独立签到体系:积分来自网页/客户端活跃使用,直接展示说明卡
|
||||||
state = checkinState,
|
item { WorkBuddyIntlNoCheckinCard() }
|
||||||
todayCheckedIn = checkinInfo?.todayCheckedIn == true,
|
} else {
|
||||||
streakDays = checkinInfo?.streakDays ?: 0L,
|
item {
|
||||||
isTrae = false,
|
if (uiState.hasCredential) {
|
||||||
onCheckin = { viewModel.checkin() }
|
CheckinCard(
|
||||||
)
|
state = checkinState,
|
||||||
} else {
|
todayCheckedIn = checkinInfo?.todayCheckedIn == true,
|
||||||
CheckinNeedCredentialCard()
|
streakDays = checkinInfo?.streakDays ?: 0L,
|
||||||
|
isTrae = false,
|
||||||
|
onCheckin = { viewModel.checkin() }
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
CheckinNeedCredentialCard()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 资源明细(资源 ID 美化为「资源 #007」+ 余额;套餐/冻结/付费信息归账户信息)
|
// 资源明细(资源 ID 美化为「资源 #007」+ 余额;套餐/冻结/付费信息归账户信息)
|
||||||
@ -1801,6 +1807,29 @@ private fun TraeIntlNoCheckinCard() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
private fun WorkBuddyIntlNoCheckinCard() {
|
||||||
|
Card(
|
||||||
|
modifier = Modifier.fillMaxWidth(),
|
||||||
|
shape = RoundedCornerShape(20.dp),
|
||||||
|
colors = CardDefaults.cardColors(containerColor = MaterialTheme.colorScheme.surface),
|
||||||
|
elevation = CardDefaults.cardElevation(defaultElevation = 0.dp)
|
||||||
|
) {
|
||||||
|
Column(modifier = Modifier.padding(16.dp), verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.wb_intl_no_checkin_title),
|
||||||
|
style = MaterialTheme.typography.titleSmall,
|
||||||
|
fontWeight = FontWeight.SemiBold
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = stringResource(R.string.wb_intl_no_checkin_desc),
|
||||||
|
style = MaterialTheme.typography.bodySmall,
|
||||||
|
color = MaterialTheme.colorScheme.outline
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
internal fun WorkBuddyResourcesCard(state: State) {
|
internal fun WorkBuddyResourcesCard(state: State) {
|
||||||
val balance = when (state) {
|
val balance = when (state) {
|
||||||
|
|||||||
@ -228,6 +228,7 @@
|
|||||||
<string name="checkin_success">签到成功</string>
|
<string name="checkin_success">签到成功</string>
|
||||||
<string name="checkin_already">今日已签到</string>
|
<string name="checkin_already">今日已签到</string>
|
||||||
<string name="checkin_already_streak">今日已签到(连签 %1$d 天)</string>
|
<string name="checkin_already_streak">今日已签到(连签 %1$d 天)</string>
|
||||||
|
<string name="checkin_wb_no_campaign">暂无可领取的签到活动</string>
|
||||||
<string name="checkin_failed">签到失败,请检查凭据</string>
|
<string name="checkin_failed">签到失败,请检查凭据</string>
|
||||||
<string name="checkin_unsupported">该服务不支持签到</string>
|
<string name="checkin_unsupported">该服务不支持签到</string>
|
||||||
<string name="checkin_action_done">今日已签到</string>
|
<string name="checkin_action_done">今日已签到</string>
|
||||||
@ -801,6 +802,8 @@
|
|||||||
<string name="action_trae_recharge">充值 / 升级</string>
|
<string name="action_trae_recharge">充值 / 升级</string>
|
||||||
<string name="trae_intl_plan_title">套餐</string>
|
<string name="trae_intl_plan_title">套餐</string>
|
||||||
<string name="trae_intl_basic_used_title">基础用量已用</string>
|
<string name="trae_intl_basic_used_title">基础用量已用</string>
|
||||||
|
<string name="wb_intl_no_checkin_title">国际版无独立签到</string>
|
||||||
|
<string name="wb_intl_no_checkin_desc">WorkBuddy 国际版积分来自网页/客户端活跃使用,没有独立签到活动。</string>
|
||||||
<string name="trae_intl_no_checkin_title">国际版没有每日签到</string>
|
<string name="trae_intl_no_checkin_title">国际版没有每日签到</string>
|
||||||
<string name="trae_intl_no_checkin_desc">Trae 国际版按美元计费,使用月度请求额度,没有签到积分体系。</string>
|
<string name="trae_intl_no_checkin_desc">Trae 国际版按美元计费,使用月度请求额度,没有签到积分体系。</string>
|
||||||
<string name="trae_intl_monthly_quota">月配额</string>
|
<string name="trae_intl_monthly_quota">月配额</string>
|
||||||
|
|||||||
@ -228,6 +228,7 @@
|
|||||||
<string name="checkin_success">簽到成功</string>
|
<string name="checkin_success">簽到成功</string>
|
||||||
<string name="checkin_already">今日已簽到</string>
|
<string name="checkin_already">今日已簽到</string>
|
||||||
<string name="checkin_already_streak">今日已簽到(連簽 %1$d 天)</string>
|
<string name="checkin_already_streak">今日已簽到(連簽 %1$d 天)</string>
|
||||||
|
<string name="checkin_wb_no_campaign">暫無可領取的簽到活動</string>
|
||||||
<string name="checkin_failed">簽到失敗,請檢查憑證</string>
|
<string name="checkin_failed">簽到失敗,請檢查憑證</string>
|
||||||
<string name="checkin_unsupported">該服務不支援簽到</string>
|
<string name="checkin_unsupported">該服務不支援簽到</string>
|
||||||
<string name="checkin_action_done">今日已簽到</string>
|
<string name="checkin_action_done">今日已簽到</string>
|
||||||
@ -801,6 +802,8 @@
|
|||||||
<string name="action_trae_recharge">儲值 / 升級</string>
|
<string name="action_trae_recharge">儲值 / 升級</string>
|
||||||
<string name="trae_intl_plan_title">套餐</string>
|
<string name="trae_intl_plan_title">套餐</string>
|
||||||
<string name="trae_intl_basic_used_title">基礎用量已用</string>
|
<string name="trae_intl_basic_used_title">基礎用量已用</string>
|
||||||
|
<string name="wb_intl_no_checkin_title">國際版無獨立簽到</string>
|
||||||
|
<string name="wb_intl_no_checkin_desc">WorkBuddy 國際版積分來自網頁/客戶端活躍使用,沒有獨立簽到活動。</string>
|
||||||
<string name="trae_intl_no_checkin_title">國際版沒有每日簽到</string>
|
<string name="trae_intl_no_checkin_title">國際版沒有每日簽到</string>
|
||||||
<string name="trae_intl_no_checkin_desc">Trae 國際版按美元計費,使用月度請求額度,沒有簽到積分體系。</string>
|
<string name="trae_intl_no_checkin_desc">Trae 國際版按美元計費,使用月度請求額度,沒有簽到積分體系。</string>
|
||||||
<string name="trae_intl_monthly_quota">月額度</string>
|
<string name="trae_intl_monthly_quota">月額度</string>
|
||||||
|
|||||||
@ -231,6 +231,7 @@
|
|||||||
<string name="checkin_success">Check-in successful</string>
|
<string name="checkin_success">Check-in successful</string>
|
||||||
<string name="checkin_already">Already checked in today</string>
|
<string name="checkin_already">Already checked in today</string>
|
||||||
<string name="checkin_already_streak">Already checked in (streak %1$d days)</string>
|
<string name="checkin_already_streak">Already checked in (streak %1$d days)</string>
|
||||||
|
<string name="checkin_wb_no_campaign">No active check-in campaign</string>
|
||||||
<string name="checkin_failed">Check-in failed, please check credentials</string>
|
<string name="checkin_failed">Check-in failed, please check credentials</string>
|
||||||
<string name="checkin_unsupported">This service does not support check-in</string>
|
<string name="checkin_unsupported">This service does not support check-in</string>
|
||||||
<string name="checkin_action_done">Checked in today</string>
|
<string name="checkin_action_done">Checked in today</string>
|
||||||
@ -806,6 +807,8 @@
|
|||||||
<string name="action_trae_recharge">Upgrade / Top up</string>
|
<string name="action_trae_recharge">Upgrade / Top up</string>
|
||||||
<string name="trae_intl_plan_title">Plan</string>
|
<string name="trae_intl_plan_title">Plan</string>
|
||||||
<string name="trae_intl_basic_used_title">Basic usage used</string>
|
<string name="trae_intl_basic_used_title">Basic usage used</string>
|
||||||
|
<string name="wb_intl_no_checkin_title">No daily check-in on international</string>
|
||||||
|
<string name="wb_intl_no_checkin_desc">WorkBuddy international credits are earned through active usage, not a check-in campaign.</string>
|
||||||
<string name="trae_intl_no_checkin_title">International edition has no daily check-in</string>
|
<string name="trae_intl_no_checkin_title">International edition has no daily check-in</string>
|
||||||
<string name="trae_intl_no_checkin_desc">TRAE International uses USD billing with monthly request quotas instead of credit check-ins.</string>
|
<string name="trae_intl_no_checkin_desc">TRAE International uses USD billing with monthly request quotas instead of credit check-ins.</string>
|
||||||
<string name="trae_intl_monthly_quota">Monthly quota</string>
|
<string name="trae_intl_monthly_quota">Monthly quota</string>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user