Merge pull request #5430 from deepseek-harness/fix/hide-empty-bonus-row

fix(web): 无赠金时隐藏设置页赠金行并修正引导充值文案入口
This commit is contained in:
lsdsjy authored and GitHub committed 2026-09-29 13:08:06 +08:00
commit 7ca920cec8
9 files changed
+19 -20

No files matched your search

@@ -24,8 +24,8 @@
en: 6b3ad3b6860100cf
zh: aeced4fb37642f15
/deepseek-ai-dsh-client-ui-settings-account/further-exploration:
en: c785923662681191
zh: f24389c25e954035
en: a28acdef21b1643a
zh: 5e2e357a6b716274
/deepseek-ai-dsh-client-ui-settings-account/model-experience:
en: ee1df7ca3467ee3f
zh: 84904a5148da3862
@@ -77,7 +77,7 @@ Account login uses a dismissible dialog before the model onboarding credential e
A terminal account-state stream failure appears in the sign-in dialog or Account settings. Plugin unload suppresses late failure reports.
The balance card shows recharge funds and bonus credit in separate rows. The bonus row is present while signed in; without positive bonus credit it states that no bonus is available. A failed wallet read shows the existing unavailable copy as a link to Platform — the same destination and behavior as the Usage action, so the embedded page opens on Desktop and a new tab elsewhere — while the loading and empty states stay plain text. Currencies retain their own amounts, and a notice date is rendered only inside the server’s own message.
The balance card shows recharge funds and bonus credit in separate rows. While signed in, the bonus row appears during loading, after a failed wallet read, and when a wallet holds positive bonus credit; a successful read without positive bonus credit omits the row. A failed wallet read shows the existing unavailable copy as a link to Platform — the same destination and behavior as the Usage action, so the embedded page opens on Desktop and a new tab elsewhere — while the loading state stays plain text. Currencies retain their own amounts, and a notice date is rendered only inside the server’s own message.
A successful login selects the first available `deepseek-account` model as the default when no other provider has a configured API key, even if a previous default was saved. Configured keys preserve the existing default even when their provider has no available models. Session-specific selections remain unchanged.
@@ -77,7 +77,7 @@ Desktop preload 标记在账号凭证已存储后启用引导。进度属于本
账户状态流的终止错误会显示在登录对话框或账户设置中。插件卸载后不再报告延迟到达的错误。
余额卡片分行展示充值余额与赠金余额。赠金行在登录态下常驻;没有正额赠金时显示暂无可用赠金。余额或赠金读取失败时,沿用既有的不可用文案并改为指向 Platform 的链接,目标与行为同“查询用量”一致:Desktop 打开内嵌页面,其它环境新开标签页;加载中与暂无赠金仍为纯文本。不同币种分别显示;日期只在服务端自己的消息中出现。
余额卡片分行展示充值余额与赠金余额。登录态下,赠金行在加载中、余额读取失败以及存在正额赠金时显示;读取成功但没有正额赠金时不显示该行。余额或赠金读取失败时,沿用既有的不可用文案并改为指向 Platform 的链接,目标与行为同“查询用量”一致:Desktop 打开内嵌页面,其它环境新开标签页;加载中仍为纯文本。不同币种分别显示;日期只在服务端自己的消息中出现。
登录成功时,若其他提供方均未配置 API key,则将 `deepseek-account` 的第一个可用模型设为默认值,即使此前保存过默认选择。其他提供方只要配置了 key,就保留原默认值,即使其没有可用模型。会话内的显式选择保持不变。
@@ -93,6 +93,7 @@ export function AccountSection({ t, useAccount, useTheme, start, cancel, openPla
const wallets = details?.balance?.status === 'ready' ? details.balance.value : undefined
const bonusWallets = details?.balance?.status === 'ready'
? details.balance.bonusWallets.filter(wallet => new Big(wallet.balance).gt(0)) : []
const showBonusRow = details?.balance?.status !== 'ready' || bonusWallets.length > 0
const attempt = state?.attempt
const active = attempt !== null && attempt !== undefined
&& ['initializing', 'waiting-browser', 'exchanging', 'committing'].includes(attempt.phase)
@@ -183,7 +184,7 @@ export function AccountSection({ t, useAccount, useTheme, start, cancel, openPla
? <span className={css.unavailable}>{t(!signedIn ? 'balanceSignedOut' : 'loading')}</span>
: platformLink(t('balanceUnavailable'), css.unavailableLink)}
</div>
{signedIn && <>
{signedIn && showBonusRow && <>
<div className={css.divider} />
<div className={css.row}>
<span>{t('bonusBalance')}</span>
@@ -194,9 +195,7 @@ export function AccountSection({ t, useAccount, useTheme, start, cancel, openPla
</span>)}</span>
: details?.balance === undefined
? <span className={css.unavailable}>{t('loading')}</span>
: details.balance.status === 'failed'
? platformLink(t('balanceUnavailable'), css.unavailableLink)
: <span className={css.unavailable}>{t('bonusEmpty')}</span>}
: platformLink(t('balanceUnavailable'), css.unavailableLink)}
</span>
</div>
</>}
@@ -33,7 +33,6 @@ export const en = {
quotaDescription: 'DeepSeek Harness cannot start a new task with this account when no balance is available. Would you like to top up? You can also top up later in Settings → Account.',
quotaTopUp: 'Top up',
bonusNoticeTitle: 'Bonus credited',
bonusEmpty: 'No bonus available',
} as const
/** Account locale keys. */
export type AccountKey = keyof typeof en
@@ -69,5 +68,4 @@ export const zh: Record<AccountKey, string> = {
quotaDescription: '没有可用额度时,DeepSeek Harness 无法开始新的任务,是否前往充值?或者可以稍后前往 设置 → 账号与余额 进行充值。',
quotaTopUp: '去充值',
bonusNoticeTitle: '赠金已到账',
bonusEmpty: '暂无可用赠金',
}
@@ -30,10 +30,10 @@ export const onboardingCopy = {
onboardingBack: '上一步',
onboardingSkip: '跳过',
onboardingSkipTitle: '跳过设置?',
onboardingSkipDescription: '你可以随时前往 个人中心 → 通用设置 中调整工作过程、性能与用量展示方式或开启代码工作工具。',
onboardingSkipDescription: '你可以随时前往 设置 → 通用设置 中调整工作过程、性能与用量展示方式或开启代码工作工具。',
onboardingKeepSetting: '继续设置',
onboardingNoCreditTitle: '暂时跳过充值?',
onboardingNoCreditDescription: '没有可用额度时,DeepSeek Harness 将无法开始新的任务。你可以稍后前往 个人中心 → 账号与余额 进行充值。',
onboardingNoCreditDescription: '没有可用额度时,DeepSeek Harness 将无法开始新的任务。你可以稍后前往 设置 → 账号与余额 进行充值。',
onboardingUnderstood: '我知道了',
onboardingGoTopUp: '前往充值',
onboardingSaveFailed: '未能保存设置,请重试。',
@@ -73,10 +73,10 @@ export const onboardingEnglishCopy: Record<keyof typeof onboardingCopy, string>
onboardingBack: 'Back',
onboardingSkip: 'Skip',
onboardingSkipTitle: 'Skip setup?',
onboardingSkipDescription: 'You can change how progress, performance, and usage are displayed, or enable Coding Tools, anytime in Profile → General Settings.',
onboardingSkipDescription: 'You can change how progress, performance, and usage are displayed, or enable Coding Tools, anytime in Settings → General.',
onboardingKeepSetting: 'Continue setup',
onboardingNoCreditTitle: 'Skip adding credits?',
onboardingNoCreditDescription: 'DeepSeek Harness can’t start new tasks without credits. You can add them later in Profile → Accounts.',
onboardingNoCreditDescription: 'DeepSeek Harness can’t start new tasks without credits. You can add them later in Settings → Account.',
onboardingUnderstood: 'Got it',
onboardingGoTopUp: 'Add credits',
onboardingSaveFailed: 'Could not save settings. Try again.',
@@ -13,6 +13,7 @@ import type { BonusNotice } from '../src/client/bonus-notices.ts'
import type { AccountMenuProps } from '../src/client/AccountMenu.tsx'
import type {} from '../src/client/index.ts'
import { en, zh, type AccountKey } from '../src/client/locales.ts'
import css from '../src/client/AccountSection.module.css'
afterEach(() => { cleanup(); vi.unstubAllGlobals() })
@@ -441,18 +442,19 @@ it.each([en, zh])('renders positive bonus wallets separately from recharge balan
})
expect(screen.getByText(copy.balance).parentElement!.textContent).toBe(`${copy.balance}¥209.00$20.07`)
expect(screen.getByText(copy.bonusBalance).parentElement!.textContent).toBe(`${copy.bonusBalance}¥5.00<$0.01`)
expect(screen.getByRole('region').querySelectorAll(`.${css.divider}`)).toHaveLength(2)
await expect(`${screen.getByRole('region').textContent}\n`)
.toMatchFileSnapshot(`./expected/bonus-${copy === en ? 'en' : 'zh'}.txt`)
})
it.each([[], [{ currency: 'CNY' as const, balance: '0.00' }, { currency: 'USD' as const, balance: '-1.00' }]].map(bonusWallets => ({ bonusWallets })))(
'keeps the bonus row without inventing credit for zero or negative wallets', ({ bonusWallets }) => {
'omits the bonus row for zero or negative wallets', ({ bonusWallets }) => {
mount({ status: 'credential-stored', attempt: null }, en, {
balance: { status: 'ready', value: [{ currency: 'CNY', balance: '0' }], bonusWallets },
})
// The row itself stays and states the absence.
expect(screen.getByText(en.bonusBalance)).toBeTruthy()
expect(screen.getByText(en.bonusEmpty)).toBeTruthy()
expect(screen.queryByText(en.bonusBalance)).toBeNull()
// The divider above the bonus row goes with it.
expect(screen.getByRole('region').querySelectorAll(`.${css.divider}`)).toHaveLength(1)
expect(screen.getByText('¥0.00')).toBeTruthy()
expect(screen.queryByText('¥-1.00')).toBeNull()
},
@@ -1 +1 @@
Harness Mock (TEST ONLY)138****0000More account informationTopped-up balance¥1,234.56<$0.01Granted balanceNo bonus availableMoreView usageTop up
Harness Mock (TEST ONLY)138****0000More account informationTopped-up balance¥1,234.56<$0.01MoreView usageTop up
@@ -1 +1 @@
Harness Mock (TEST ONLY)138****0000更多账号信息充值余额¥1,234.56<$0.01赠金余额暂无可用赠金更多查询用量充值
Harness Mock (TEST ONLY)138****0000更多账号信息充值余额¥1,234.56<$0.01更多查询用量充值