fix(proxy): 测试按区域选凭据不再误用默认账号;签到成功/已签即时落本地记录
Some checks are pending
Release / build (push) Waiting to run
Some checks are pending
Release / build (push) Waiting to run
This commit is contained in:
parent
4ac90449e5
commit
063658a90d
@ -46,7 +46,7 @@ class TraeChatProxy @Inject constructor(
|
|||||||
forcedRegion: ProviderRegion? = null,
|
forcedRegion: ProviderRegion? = null,
|
||||||
): ProxyUpstreamResponse? =
|
): ProxyUpstreamResponse? =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val credential = credentialRepository.get(ServiceType.TRAE, accountId)
|
val credential = pickCredential(accountId, forcedRegion)
|
||||||
?: return@withContext null
|
?: return@withContext null
|
||||||
if (credential !is Credential.TraeCredential) return@withContext null
|
if (credential !is Credential.TraeCredential) return@withContext null
|
||||||
val jwt = credential.jwt.trim().takeIf { it.isNotBlank() }
|
val jwt = credential.jwt.trim().takeIf { it.isNotBlank() }
|
||||||
@ -81,7 +81,7 @@ class TraeChatProxy @Inject constructor(
|
|||||||
accountId: String? = null,
|
accountId: String? = null,
|
||||||
forcedRegion: ProviderRegion? = null,
|
forcedRegion: ProviderRegion? = null,
|
||||||
): ProxyUpstreamStream? = withContext(Dispatchers.IO) {
|
): ProxyUpstreamStream? = withContext(Dispatchers.IO) {
|
||||||
val credential = credentialRepository.get(ServiceType.TRAE, accountId)
|
val credential = pickCredential(accountId, forcedRegion)
|
||||||
?: return@withContext null
|
?: return@withContext null
|
||||||
if (credential !is Credential.TraeCredential) return@withContext null
|
if (credential !is Credential.TraeCredential) return@withContext null
|
||||||
val jwt = credential.jwt.trim().takeIf { it.isNotBlank() }
|
val jwt = credential.jwt.trim().takeIf { it.isNotBlank() }
|
||||||
@ -233,6 +233,30 @@ class TraeChatProxy @Inject constructor(
|
|||||||
* INTL 统一走 Web 网关 core-normal.trae.ai(实测 api-us-east/a0ai 均不提供
|
* INTL 统一走 Web 网关 core-normal.trae.ai(实测 api-us-east/a0ai 均不提供
|
||||||
* llm_utils_chat 路由);CN 走 IDE 网关 trae-api-cn.mchost.guru。
|
* llm_utils_chat 路由);CN 走 IDE 网关 trae-api-cn.mchost.guru。
|
||||||
*/
|
*/
|
||||||
|
/** 按区域选凭据:显式 accountId 优先;未指定时优先同区域账号,再兼容默认账号。 */
|
||||||
|
private suspend fun pickCredential(
|
||||||
|
accountId: String?,
|
||||||
|
region: ProviderRegion?,
|
||||||
|
): Credential.TraeCredential? {
|
||||||
|
if (!accountId.isNullOrBlank()) {
|
||||||
|
return credentialRepository.get(ServiceType.TRAE, accountId) as? Credential.TraeCredential
|
||||||
|
}
|
||||||
|
val accounts = credentialRepository.accountsFor(ServiceType.TRAE)
|
||||||
|
if (accounts.isEmpty()) {
|
||||||
|
val legacy = credentialRepository.get(ServiceType.TRAE, null) as? Credential.TraeCredential
|
||||||
|
?: return null
|
||||||
|
return if (region == null || legacy.region.equals(region.name, ignoreCase = true)) legacy else null
|
||||||
|
}
|
||||||
|
val all = accounts.mapNotNull { account ->
|
||||||
|
credentialRepository.get(ServiceType.TRAE, account.id) as? Credential.TraeCredential
|
||||||
|
}
|
||||||
|
if (all.isEmpty()) return null
|
||||||
|
if (region != null) {
|
||||||
|
all.firstOrNull { it.region.equals(region.name, ignoreCase = true) }?.let { return it }
|
||||||
|
}
|
||||||
|
return all.first()
|
||||||
|
}
|
||||||
|
|
||||||
private fun chatBase(region: ProviderRegion?): String =
|
private fun chatBase(region: ProviderRegion?): String =
|
||||||
if (region == ProviderRegion.INTL) {
|
if (region == ProviderRegion.INTL) {
|
||||||
"https://core-normal.trae.ai"
|
"https://core-normal.trae.ai"
|
||||||
|
|||||||
@ -36,7 +36,7 @@ class WorkBuddyChatProxy @Inject constructor(
|
|||||||
forcedRegion: ProviderRegion? = null,
|
forcedRegion: ProviderRegion? = null,
|
||||||
): ProxyUpstreamResponse? =
|
): ProxyUpstreamResponse? =
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val credential = credentialRepository.get(ServiceType.WORKBUDDY, accountId)
|
val credential = pickCredential(accountId, forcedRegion)
|
||||||
?: return@withContext null
|
?: return@withContext null
|
||||||
if (credential !is Credential.WorkBuddyCredential) return@withContext null
|
if (credential !is Credential.WorkBuddyCredential) return@withContext null
|
||||||
val accessToken = credential.accessToken.trim().takeIf { it.isNotBlank() }
|
val accessToken = credential.accessToken.trim().takeIf { it.isNotBlank() }
|
||||||
@ -78,7 +78,7 @@ class WorkBuddyChatProxy @Inject constructor(
|
|||||||
accountId: String? = null,
|
accountId: String? = null,
|
||||||
forcedRegion: ProviderRegion? = null,
|
forcedRegion: ProviderRegion? = null,
|
||||||
): ProxyUpstreamStream? = withContext(Dispatchers.IO) {
|
): ProxyUpstreamStream? = withContext(Dispatchers.IO) {
|
||||||
val credential = credentialRepository.get(ServiceType.WORKBUDDY, accountId)
|
val credential = pickCredential(accountId, forcedRegion)
|
||||||
?: return@withContext null
|
?: return@withContext null
|
||||||
if (credential !is Credential.WorkBuddyCredential) return@withContext null
|
if (credential !is Credential.WorkBuddyCredential) return@withContext null
|
||||||
val accessToken = credential.accessToken.trim().takeIf { it.isNotBlank() }
|
val accessToken = credential.accessToken.trim().takeIf { it.isNotBlank() }
|
||||||
@ -120,6 +120,30 @@ class WorkBuddyChatProxy @Inject constructor(
|
|||||||
return@withContext null
|
return@withContext null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 按区域选凭据:显式 accountId 优先;未指定时优先同区域账号,再兼容单账号旧档。 */
|
||||||
|
private suspend fun pickCredential(
|
||||||
|
accountId: String?,
|
||||||
|
region: ProviderRegion?,
|
||||||
|
): Credential.WorkBuddyCredential? {
|
||||||
|
if (!accountId.isNullOrBlank()) {
|
||||||
|
return credentialRepository.get(ServiceType.WORKBUDDY, accountId) as? Credential.WorkBuddyCredential
|
||||||
|
}
|
||||||
|
val accounts = credentialRepository.accountsFor(ServiceType.WORKBUDDY)
|
||||||
|
if (accounts.isEmpty()) {
|
||||||
|
val legacy = credentialRepository.get(ServiceType.WORKBUDDY, null) as? Credential.WorkBuddyCredential
|
||||||
|
?: return null
|
||||||
|
return if (region == null || legacy.region.equals(region.name, ignoreCase = true)) legacy else null
|
||||||
|
}
|
||||||
|
val all = accounts.mapNotNull { account ->
|
||||||
|
credentialRepository.get(ServiceType.WORKBUDDY, account.id) as? Credential.WorkBuddyCredential
|
||||||
|
}
|
||||||
|
if (all.isEmpty()) return null
|
||||||
|
if (region != null) {
|
||||||
|
all.firstOrNull { it.region.equals(region.name, ignoreCase = true) }?.let { return it }
|
||||||
|
}
|
||||||
|
return all.first()
|
||||||
|
}
|
||||||
|
|
||||||
private fun buildChatRequest(
|
private fun buildChatRequest(
|
||||||
base: String,
|
base: String,
|
||||||
path: String,
|
path: String,
|
||||||
|
|||||||
@ -166,17 +166,32 @@ class AutoCheckinManager @Inject constructor(
|
|||||||
ServiceType.TRAE -> refreshBalanceUseCase.checkInTrae(account.id).fold(
|
ServiceType.TRAE -> refreshBalanceUseCase.checkInTrae(account.id).fold(
|
||||||
onSuccess = { r ->
|
onSuccess = { r ->
|
||||||
when (r.outcome) {
|
when (r.outcome) {
|
||||||
TraeRepository.CheckinOutcome.SUCCESS -> ServiceResult(
|
TraeRepository.CheckinOutcome.SUCCESS -> {
|
||||||
service = service,
|
checkinStatusStore.record(
|
||||||
accountLabel = label,
|
ServiceType.TRAE,
|
||||||
newlyCheckedIn = true,
|
account.id,
|
||||||
checkedInToday = true,
|
CheckinStatusStore.STATUS_SUCCESS,
|
||||||
creditsGained = r.points,
|
checkinId = java.util.UUID.randomUUID().toString(),
|
||||||
message = "",
|
credits = r.points
|
||||||
failed = false
|
)
|
||||||
)
|
ServiceResult(
|
||||||
TraeRepository.CheckinOutcome.ALREADY ->
|
service = service,
|
||||||
|
accountLabel = label,
|
||||||
|
newlyCheckedIn = true,
|
||||||
|
checkedInToday = true,
|
||||||
|
creditsGained = r.points,
|
||||||
|
message = "",
|
||||||
|
failed = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
TraeRepository.CheckinOutcome.ALREADY -> {
|
||||||
|
checkinStatusStore.record(
|
||||||
|
ServiceType.TRAE,
|
||||||
|
account.id,
|
||||||
|
CheckinStatusStore.STATUS_ALREADY
|
||||||
|
)
|
||||||
ServiceResult(service, label, false, true, 0, "", false)
|
ServiceResult(service, label, false, true, 0, "", false)
|
||||||
|
}
|
||||||
// INTL 不支持签到:静默跳过,不进弹窗(避免误报「已签到」)
|
// INTL 不支持签到:静默跳过,不进弹窗(避免误报「已签到」)
|
||||||
TraeRepository.CheckinOutcome.INTL_UNSUPPORTED -> null
|
TraeRepository.CheckinOutcome.INTL_UNSUPPORTED -> null
|
||||||
TraeRepository.CheckinOutcome.DEVICE_BLOCKED -> {
|
TraeRepository.CheckinOutcome.DEVICE_BLOCKED -> {
|
||||||
@ -201,19 +216,40 @@ class AutoCheckinManager @Inject constructor(
|
|||||||
ServiceType.WORKBUDDY -> refreshBalanceUseCase.checkInWorkBuddy(account.id).fold(
|
ServiceType.WORKBUDDY -> refreshBalanceUseCase.checkInWorkBuddy(account.id).fold(
|
||||||
onSuccess = { s ->
|
onSuccess = { s ->
|
||||||
when (s.outcome) {
|
when (s.outcome) {
|
||||||
WorkBuddyRepository.CheckinOutcome.SUCCESS -> ServiceResult(
|
WorkBuddyRepository.CheckinOutcome.SUCCESS -> {
|
||||||
service = service,
|
checkinStatusStore.record(
|
||||||
accountLabel = label,
|
ServiceType.WORKBUDDY,
|
||||||
newlyCheckedIn = true,
|
account.id,
|
||||||
checkedInToday = true,
|
CheckinStatusStore.STATUS_SUCCESS,
|
||||||
creditsGained = (s.todayCredit.takeIf { it > 0 } ?: s.dailyCredit),
|
checkinId = java.util.UUID.randomUUID().toString(),
|
||||||
message = "",
|
credits = (s.todayCredit.takeIf { it > 0 } ?: s.dailyCredit)
|
||||||
failed = false
|
)
|
||||||
)
|
ServiceResult(
|
||||||
WorkBuddyRepository.CheckinOutcome.ALREADY ->
|
service = service,
|
||||||
|
accountLabel = label,
|
||||||
|
newlyCheckedIn = true,
|
||||||
|
checkedInToday = true,
|
||||||
|
creditsGained = (s.todayCredit.takeIf { it > 0 } ?: s.dailyCredit),
|
||||||
|
message = "",
|
||||||
|
failed = false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
WorkBuddyRepository.CheckinOutcome.ALREADY -> {
|
||||||
|
checkinStatusStore.record(
|
||||||
|
ServiceType.WORKBUDDY,
|
||||||
|
account.id,
|
||||||
|
CheckinStatusStore.STATUS_ALREADY
|
||||||
|
)
|
||||||
ServiceResult(service, label, false, true, 0, "", false)
|
ServiceResult(service, label, false, true, 0, "", false)
|
||||||
WorkBuddyRepository.CheckinOutcome.QUERY ->
|
}
|
||||||
|
WorkBuddyRepository.CheckinOutcome.QUERY -> {
|
||||||
|
checkinStatusStore.record(
|
||||||
|
ServiceType.WORKBUDDY,
|
||||||
|
account.id,
|
||||||
|
CheckinStatusStore.STATUS_ALREADY
|
||||||
|
)
|
||||||
ServiceResult(service, label, false, true, 0, "", false)
|
ServiceResult(service, label, false, true, 0, "", false)
|
||||||
|
}
|
||||||
WorkBuddyRepository.CheckinOutcome.NO_CAMPAIGN ->
|
WorkBuddyRepository.CheckinOutcome.NO_CAMPAIGN ->
|
||||||
// 国际站没有签到活动不是账号失败:静默跳过,不记失败日志
|
// 国际站没有签到活动不是账号失败:静默跳过,不记失败日志
|
||||||
ServiceResult(service, label, false, false, 0, s.message, false)
|
ServiceResult(service, label, false, false, 0, s.message, false)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user