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,
|
||||
/** 签到失败(服务端给了原因,见 message) */
|
||||
FAILED
|
||||
FAILED,
|
||||
/** 国际站无签到活动(活动未开启/未上线,非错误) */
|
||||
NO_CAMPAIGN
|
||||
}
|
||||
|
||||
/**
|
||||
@ -486,6 +488,12 @@ private fun parseResourceDetail(body: String): Map<String, String>? {
|
||||
if (credential !is Credential.WorkBuddyCredential) {
|
||||
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 兜底)
|
||||
// 共享轮换状态:前一条路径轮换出的新 token 会用于下一条,且失败也先落库。
|
||||
val body = authedPostFirstSuccessful(
|
||||
@ -517,6 +525,12 @@ private fun parseResourceDetail(body: String): Map<String, String>? {
|
||||
if (credential !is Credential.WorkBuddyCredential) {
|
||||
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")) {
|
||||
is AuthedPostResult.Ok -> {
|
||||
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")
|
||||
}.getOrNull().orEmpty()
|
||||
val status = fetchCheckinStatus(accountId).getOrNull()
|
||||
// 已签到语义与上游 cpa-multi-plugins 对齐:code=10001 或文案含「已签/今日/already」。
|
||||
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("已经签到") ||
|
||||
msg.contains("今日") || lowerMsg.contains("already") || lowerMsg.contains("checked") ||
|
||||
lowerMsg.contains("claimed")
|
||||
@ -566,6 +587,12 @@ private fun parseResourceDetail(body: String): Map<String, String>? {
|
||||
outcome = CheckinOutcome.SUCCESS
|
||||
)
|
||||
)
|
||||
noCampaign -> Result.success(
|
||||
(status ?: CheckinStatus(false, false, 0, 0, 0, "")).copy(
|
||||
message = msg,
|
||||
outcome = CheckinOutcome.NO_CAMPAIGN
|
||||
)
|
||||
)
|
||||
already -> Result.success(
|
||||
(status ?: CheckinStatus(true, true, 0, 0, 0, "")).copy(
|
||||
outcome = CheckinOutcome.ALREADY
|
||||
@ -617,8 +644,21 @@ private fun parseResourceDetail(body: String): Map<String, String>? {
|
||||
val request = Request.Builder()
|
||||
.url(credential.originBase() + path)
|
||||
.addHeader("Authorization", "Bearer " + access)
|
||||
.addHeader("Accept", "application/json")
|
||||
.addHeader("Accept", "application/json, text/plain, */*")
|
||||
.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))
|
||||
.build()
|
||||
val resp = try {
|
||||
|
||||
@ -265,17 +265,23 @@ fun ServiceDetailScreen(
|
||||
}
|
||||
}
|
||||
ServiceType.WORKBUDDY -> {
|
||||
item {
|
||||
if (uiState.hasCredential) {
|
||||
CheckinCard(
|
||||
state = checkinState,
|
||||
todayCheckedIn = checkinInfo?.todayCheckedIn == true,
|
||||
streakDays = checkinInfo?.streakDays ?: 0L,
|
||||
isTrae = false,
|
||||
onCheckin = { viewModel.checkin() }
|
||||
)
|
||||
} else {
|
||||
CheckinNeedCredentialCard()
|
||||
val wbIntl = uiState.region != null && uiState.region.equals("INTL", ignoreCase = true)
|
||||
if (wbIntl) {
|
||||
// 国际版没有独立签到体系:积分来自网页/客户端活跃使用,直接展示说明卡
|
||||
item { WorkBuddyIntlNoCheckinCard() }
|
||||
} else {
|
||||
item {
|
||||
if (uiState.hasCredential) {
|
||||
CheckinCard(
|
||||
state = checkinState,
|
||||
todayCheckedIn = checkinInfo?.todayCheckedIn == true,
|
||||
streakDays = checkinInfo?.streakDays ?: 0L,
|
||||
isTrae = false,
|
||||
onCheckin = { viewModel.checkin() }
|
||||
)
|
||||
} else {
|
||||
CheckinNeedCredentialCard()
|
||||
}
|
||||
}
|
||||
}
|
||||
// 资源明细(资源 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
|
||||
internal fun WorkBuddyResourcesCard(state: State) {
|
||||
val balance = when (state) {
|
||||
|
||||
@ -228,6 +228,7 @@
|
||||
<string name="checkin_success">签到成功</string>
|
||||
<string name="checkin_already">今日已签到</string>
|
||||
<string name="checkin_already_streak">今日已签到(连签 %1$d 天)</string>
|
||||
<string name="checkin_wb_no_campaign">暂无可领取的签到活动</string>
|
||||
<string name="checkin_failed">签到失败,请检查凭据</string>
|
||||
<string name="checkin_unsupported">该服务不支持签到</string>
|
||||
<string name="checkin_action_done">今日已签到</string>
|
||||
@ -801,6 +802,8 @@
|
||||
<string name="action_trae_recharge">充值 / 升级</string>
|
||||
<string name="trae_intl_plan_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_desc">Trae 国际版按美元计费,使用月度请求额度,没有签到积分体系。</string>
|
||||
<string name="trae_intl_monthly_quota">月配额</string>
|
||||
|
||||
@ -228,6 +228,7 @@
|
||||
<string name="checkin_success">簽到成功</string>
|
||||
<string name="checkin_already">今日已簽到</string>
|
||||
<string name="checkin_already_streak">今日已簽到(連簽 %1$d 天)</string>
|
||||
<string name="checkin_wb_no_campaign">暫無可領取的簽到活動</string>
|
||||
<string name="checkin_failed">簽到失敗,請檢查憑證</string>
|
||||
<string name="checkin_unsupported">該服務不支援簽到</string>
|
||||
<string name="checkin_action_done">今日已簽到</string>
|
||||
@ -801,6 +802,8 @@
|
||||
<string name="action_trae_recharge">儲值 / 升級</string>
|
||||
<string name="trae_intl_plan_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_desc">Trae 國際版按美元計費,使用月度請求額度,沒有簽到積分體系。</string>
|
||||
<string name="trae_intl_monthly_quota">月額度</string>
|
||||
|
||||
@ -231,6 +231,7 @@
|
||||
<string name="checkin_success">Check-in successful</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_wb_no_campaign">No active check-in campaign</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_action_done">Checked in today</string>
|
||||
@ -806,6 +807,8 @@
|
||||
<string name="action_trae_recharge">Upgrade / Top up</string>
|
||||
<string name="trae_intl_plan_title">Plan</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_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>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user