feat(flutter): localize referral page + fix language auto-detection

- Add 27 new l10n keys (ARB + generated dart) for the referral screen,
  covering both Enterprise tab and personal circle tab strings
- Replace all hardcoded Chinese strings in referral_screen.dart with
  l10n calls (tab labels, section headers, status labels, rules, etc.)
- Fix language auto-detection: default to '' instead of 'en', and
  return null from localeProvider to follow device locale
- Fix 'Refer & Earn' vertical text: wrap trailing with Flexible in
  _SettingsRow on profile page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-03-08 00:51:25 -08:00
parent 8262d3f8e3
commit b2594317d7
10 changed files with 483 additions and 65 deletions

View File

@ -114,8 +114,10 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
icon: Icons.language,
iconBg: const Color(0xFF3B82F6),
title: l10n.languageLabel,
trailing: Text(l10n.languageZh,
style: TextStyle(color: subtitleColor, fontSize: 14)),
trailing: Text(
_languageDisplayLabel(settings.language, l10n),
style: TextStyle(color: subtitleColor, fontSize: 14),
),
),
],
),
@ -350,6 +352,17 @@ class _ProfilePageState extends ConsumerState<ProfilePage> {
);
}
// Helpers
String _languageDisplayLabel(String lang, AppLocalizations l10n) {
return switch (lang) {
'zh' => l10n.languageZh,
'zh_TW' => l10n.languageZhTW,
'en' => l10n.languageEn,
_ => l10n.languageAuto,
};
}
// Pickers
void _showThemePicker(ThemeMode current) {
@ -919,7 +932,7 @@ class _SettingsRow extends StatelessWidget {
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (trailing != null) trailing!,
if (trailing != null) Flexible(child: trailing!),
if (onTap != null) ...[
const SizedBox(width: 4),
Icon(Icons.chevron_right,

View File

@ -39,9 +39,9 @@ class ReferralScreen extends ConsumerWidget {
indicatorColor: AppColors.primary,
labelColor: AppColors.primary,
unselectedLabelColor: Colors.grey,
tabs: const [
Tab(text: '企业推荐'),
Tab(text: '我的圈子'),
tabs: [
Tab(text: l10n.referralTabTenant),
Tab(text: l10n.referralTabPersonal),
],
),
),
@ -66,10 +66,11 @@ class _TenantReferralTab extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final l10n = AppLocalizations.of(context);
final infoAsync = ref.watch(referralInfoProvider);
return infoAsync.when(
loading: () => const Center(child: CircularProgressIndicator()),
error: (e, _) => Center(child: Text('加载失败: $e')),
error: (e, _) => Center(child: Text('${l10n.loadFailed}: $e')),
data: (info) => ListView(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
children: [
@ -80,14 +81,14 @@ class _TenantReferralTab extends ConsumerWidget {
_RewardRulesCard(cardColor: cardColor),
const SizedBox(height: 20),
_SectionHeader(
title: '推荐记录',
title: l10n.referralRecordsSection,
onTap: () => Navigator.push(context,
MaterialPageRoute(builder: (_) => const _ReferralListPage())),
),
_ReferralPreviewList(cardColor: cardColor),
const SizedBox(height: 20),
_SectionHeader(
title: '待结算奖励',
title: l10n.pendingRewardsSection,
onTap: () => Navigator.push(context,
MaterialPageRoute(builder: (_) => const _RewardListPage())),
),
@ -109,10 +110,11 @@ class _PersonalCircleTab extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final l10n = AppLocalizations.of(context);
final infoAsync = ref.watch(userReferralInfoProvider);
return infoAsync.when(
loading: () => const Center(child: CircularProgressIndicator()),
error: (e, _) => Center(child: Text('加载失败: $e')),
error: (e, _) => Center(child: Text('${l10n.loadFailed}: $e')),
data: (info) => ListView(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
children: [
@ -123,14 +125,14 @@ class _PersonalCircleTab extends ConsumerWidget {
_CircleRulesCard(cardColor: cardColor),
const SizedBox(height: 20),
_SectionHeader(
title: '我的圈子成员',
title: l10n.myCircleMembersSection,
onTap: () => Navigator.push(context,
MaterialPageRoute(builder: (_) => const _CircleListPage())),
),
_CirclePreviewList(cardColor: cardColor),
const SizedBox(height: 20),
_SectionHeader(
title: '积分记录',
title: l10n.pointsHistorySection,
onTap: () => Navigator.push(context,
MaterialPageRoute(builder: (_) => const _PointsHistoryPage())),
),
@ -152,6 +154,7 @@ class _UserCodeCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context);
return Card(
color: cardColor,
elevation: 0,
@ -161,9 +164,9 @@ class _UserCodeCard extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'我的个人邀请码',
style: TextStyle(color: Colors.grey, fontSize: 13),
Text(
l10n.myPersonalInviteCode,
style: const TextStyle(color: Colors.grey, fontSize: 13),
),
const SizedBox(height: 8),
Row(
@ -181,7 +184,7 @@ class _UserCodeCard extends StatelessWidget {
),
IconButton(
icon: const Icon(Icons.copy, color: Color(0xFF7C3AED)),
tooltip: '复制邀请码',
tooltip: l10n.copyReferralCodeTooltip,
onPressed: () => _copy(context, info.code),
),
],
@ -192,7 +195,7 @@ class _UserCodeCard extends StatelessWidget {
Expanded(
child: OutlinedButton.icon(
icon: const Icon(Icons.link, size: 18),
label: const Text('复制邀请链接'),
label: Text(l10n.copyInviteLinkButton),
onPressed: () => _copy(context, info.shareUrl),
style: OutlinedButton.styleFrom(
foregroundColor: const Color(0xFF7C3AED),
@ -206,7 +209,7 @@ class _UserCodeCard extends StatelessWidget {
Expanded(
child: FilledButton.icon(
icon: const Icon(Icons.share, size: 18),
label: const Text('分享'),
label: Text(l10n.shareButton),
onPressed: () => _share(context, info),
style: FilledButton.styleFrom(
backgroundColor: const Color(0xFF7C3AED),
@ -224,11 +227,12 @@ class _UserCodeCard extends StatelessWidget {
}
void _copy(BuildContext context, String text) {
final l10n = AppLocalizations.of(context);
Clipboard.setData(ClipboardData(text: text));
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('已复制到剪贴板'),
duration: Duration(seconds: 2)),
SnackBar(
content: Text(l10n.copiedToClipboard),
duration: const Duration(seconds: 2)),
);
}
@ -249,6 +253,7 @@ class _PointsBalanceCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context);
return Card(
color: cardColor,
elevation: 0,
@ -258,34 +263,34 @@ class _PointsBalanceCard extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Row(
Row(
children: [
Icon(Icons.stars_rounded, color: Color(0xFFF59E0B), size: 20),
SizedBox(width: 6),
Text('积分余额',
const Icon(Icons.stars_rounded, color: Color(0xFFF59E0B), size: 20),
const SizedBox(width: 6),
Text(l10n.pointsBalanceTitle,
style:
TextStyle(fontWeight: FontWeight.w600, fontSize: 15)),
const TextStyle(fontWeight: FontWeight.w600, fontSize: 15)),
],
),
const SizedBox(height: 16),
Row(
children: [
_PointsStatItem(
label: '当前余额',
label: l10n.currentBalanceLabel,
value: '${info.pointsBalance}',
unit: 'pts',
color: const Color(0xFF7C3AED),
),
const SizedBox(width: 12),
_PointsStatItem(
label: '圈子成员',
label: l10n.circleMembersCountLabel,
value: '${info.circleSize}',
unit: '',
color: const Color(0xFF10B981),
),
const SizedBox(width: 12),
_PointsStatItem(
label: '累计获得',
label: l10n.totalEarnedLabel,
value: '${info.totalEarned}',
unit: 'pts',
color: const Color(0xFF6366F1),
@ -352,6 +357,7 @@ class _CircleRulesCard extends StatelessWidget {
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context);
return Card(
color: cardColor,
elevation: 0,
@ -361,51 +367,51 @@ class _CircleRulesCard extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Row(
Row(
children: [
Icon(Icons.people_alt_rounded,
const Icon(Icons.people_alt_rounded,
color: Color(0xFF7C3AED), size: 20),
SizedBox(width: 6),
Text('圈子奖励规则',
const SizedBox(width: 6),
Text(l10n.circleRewardRulesTitle,
style:
TextStyle(fontWeight: FontWeight.w600, fontSize: 15)),
const TextStyle(fontWeight: FontWeight.w600, fontSize: 15)),
],
),
const SizedBox(height: 12),
_RuleItem(
icon: Icons.card_giftcard_rounded,
color: const Color(0xFF7C3AED),
text: '新成员加入你的圈子,你和对方各获 200 积分欢迎礼',
text: l10n.circleRule1,
),
const SizedBox(height: 8),
_RuleItem(
icon: Icons.star_rounded,
color: const Color(0xFF6366F1),
text: '圈子成员订阅 Pro 时,你获 1500 pts对方获 500 pts',
text: l10n.circleRule2,
),
const SizedBox(height: 8),
_RuleItem(
icon: Icons.star_rounded,
color: const Color(0xFF7C3AED),
text: '圈子成员订阅 Enterprise 时,你获 5000 pts对方获 2000 pts',
text: l10n.circleRule3,
),
const SizedBox(height: 8),
_RuleItem(
icon: Icons.repeat_rounded,
color: const Color(0xFF10B981),
text: '每月续订时你持续获得付款额 10% 的积分,最长 12 个月',
text: l10n.circleRule4,
),
const SizedBox(height: 8),
_RuleItem(
icon: Icons.account_tree_rounded,
color: const Color(0xFFF59E0B),
text: '二级圈子续订,你获 5% 积分,最长 6 个月',
text: l10n.circleRule5,
),
const SizedBox(height: 8),
_RuleItem(
icon: Icons.redeem_rounded,
color: const Color(0xFF10B981),
text: '积分可兑换额外使用配额或解锁智能体',
text: l10n.circleRule6,
),
],
),
@ -422,6 +428,7 @@ class _CirclePreviewList extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final l10n = AppLocalizations.of(context);
final async = ref.watch(myCircleProvider);
return async.when(
loading: () => const SizedBox(
@ -429,7 +436,7 @@ class _CirclePreviewList extends ConsumerWidget {
error: (_, __) => const SizedBox.shrink(),
data: (result) {
if (result.items.isEmpty) {
return _EmptyCard(cardColor: cardColor, message: '暂无圈子成员,快去邀请好友吧!');
return _EmptyCard(cardColor: cardColor, message: l10n.noCircleMembersMessage);
}
final preview = result.items.take(3).toList();
return Card(
@ -453,16 +460,17 @@ class _CircleMemberTile extends StatelessWidget {
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context);
final statusColor = member.isActive
? const Color(0xFF10B981)
: member.status == 'EXPIRED'
? Colors.grey
: const Color(0xFFF59E0B);
final statusLabel = switch (member.status) {
'PENDING' => '待激活',
'ACTIVE' => '已激活',
'REWARDED' => '已奖励',
'EXPIRED' => '已过期',
'PENDING' => l10n.pendingPaymentStatus,
'ACTIVE' => l10n.activatedStatus,
'REWARDED' => l10n.rewardedStatus,
'EXPIRED' => l10n.expiredStatus,
_ => member.status,
};
final levelLabel = member.level == 1 ? 'L1' : 'L2';
@ -485,7 +493,7 @@ class _CircleMemberTile extends StatelessWidget {
style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500),
),
subtitle: Text(
'加入于 ${_formatDate(member.joinedAt)}',
'${l10n.joinedAtLabel} ${_formatDate(member.joinedAt)}',
style: const TextStyle(fontSize: 12),
),
trailing: Container(
@ -517,6 +525,7 @@ class _PointsPreviewList extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final l10n = AppLocalizations.of(context);
final async = ref.watch(myPointsProvider);
return async.when(
loading: () => const SizedBox(
@ -524,7 +533,7 @@ class _PointsPreviewList extends ConsumerWidget {
error: (_, __) => const SizedBox.shrink(),
data: (result) {
if (result.transactions.isEmpty) {
return _EmptyCard(cardColor: cardColor, message: '暂无积分记录');
return _EmptyCard(cardColor: cardColor, message: l10n.noPointsHistoryMessage);
}
final preview = result.transactions.take(3).toList();
return Card(
@ -589,14 +598,15 @@ class _CircleListPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final l10n = AppLocalizations.of(context);
final async = ref.watch(myCircleProvider);
return Scaffold(
appBar: AppBar(title: const Text('我的圈子')),
appBar: AppBar(title: Text(l10n.referralTabPersonal)),
body: async.when(
loading: () => const Center(child: CircularProgressIndicator()),
error: (e, _) => Center(child: Text('加载失败: $e')),
error: (e, _) => Center(child: Text('${l10n.loadFailed}: $e')),
data: (result) => result.items.isEmpty
? const Center(child: Text('暂无圈子成员'))
? Center(child: Text(l10n.noCircleMembersMessage))
: ListView.separated(
itemCount: result.items.length,
separatorBuilder: (_, __) => const Divider(height: 1),
@ -613,14 +623,15 @@ class _PointsHistoryPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final l10n = AppLocalizations.of(context);
final async = ref.watch(myPointsProvider);
return Scaffold(
appBar: AppBar(title: const Text('积分记录')),
appBar: AppBar(title: Text(l10n.pointsHistorySection)),
body: async.when(
loading: () => const Center(child: CircularProgressIndicator()),
error: (e, _) => Center(child: Text('加载失败: $e')),
error: (e, _) => Center(child: Text('${l10n.loadFailed}: $e')),
data: (result) => result.transactions.isEmpty
? const Center(child: Text('暂无积分记录'))
? Center(child: Text(l10n.noPointsHistoryMessage))
: ListView.separated(
itemCount: result.transactions.length,
separatorBuilder: (_, __) => const Divider(height: 1),
@ -862,25 +873,25 @@ class _RewardRulesCard extends StatelessWidget {
_RuleItem(
icon: Icons.star_rounded,
color: const Color(0xFF6366F1),
text: '推荐 Pro 套餐:你获得 \$15 积分,对方获得 \$5 积分',
text: l10n.proReferralReward,
),
const SizedBox(height: 8),
_RuleItem(
icon: Icons.star_rounded,
color: const Color(0xFF7C3AED),
text: '推荐 Enterprise 套餐:你获得 \$50 积分,对方获得 \$20 积分',
text: l10n.enterpriseReferralReward,
),
const SizedBox(height: 8),
_RuleItem(
icon: Icons.repeat_rounded,
color: const Color(0xFF10B981),
text: '对方续订后,你持续获得每月付款额 10% 的积分,最长 12 个月',
text: l10n.renewalBonusReward,
),
const SizedBox(height: 8),
_RuleItem(
icon: Icons.account_balance_wallet_outlined,
color: const Color(0xFFF59E0B),
text: '积分自动抵扣你的下期账单',
text: l10n.creditDeductionReward,
),
],
),
@ -919,13 +930,14 @@ class _SectionHeader extends StatelessWidget {
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context);
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(title,
style: const TextStyle(
fontWeight: FontWeight.w600, fontSize: 16)),
TextButton(onPressed: onTap, child: const Text('查看全部')),
TextButton(onPressed: onTap, child: Text(l10n.viewAllButton)),
],
);
}
@ -1132,7 +1144,7 @@ class _ReferralListPage extends ConsumerWidget {
appBar: AppBar(title: Text(l10n.referralRecordsSection)),
body: async.when(
loading: () => const Center(child: CircularProgressIndicator()),
error: (e, _) => Center(child: Text('加载失败: $e')),
error: (e, _) => Center(child: Text('${l10n.loadFailed}: $e')),
data: (result) => result.items.isEmpty
? Center(child: Text(l10n.noReferralsMessage))
: ListView.separated(
@ -1150,14 +1162,15 @@ class _RewardListPage extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final l10n = AppLocalizations.of(context);
final async = ref.watch(allRewardsProvider);
return Scaffold(
appBar: AppBar(title: const Text('奖励历史')),
appBar: AppBar(title: Text(l10n.rewardHistoryPageTitle)),
body: async.when(
loading: () => const Center(child: CircularProgressIndicator()),
error: (e, _) => Center(child: Text('加载失败: $e')),
error: (e, _) => Center(child: Text('${l10n.loadFailed}: $e')),
data: (result) => result.items.isEmpty
? const Center(child: Text('暂无奖励记录'))
? Center(child: Text(l10n.noRewardsHistoryMessage))
: ListView.separated(
itemCount: result.items.length,
separatorBuilder: (_, __) => const Divider(height: 1),

View File

@ -32,7 +32,7 @@ class SettingsDatasource {
hapticFeedback: _prefs.getBool(_keyHaptic) ?? true,
selectedTenantId: _prefs.getString(_keyTenantId),
selectedTenantName: _prefs.getString(_keyTenantName),
language: _prefs.getString(_keyLanguage) ?? 'en',
language: _prefs.getString(_keyLanguage) ?? '',
biometricEnabled: _prefs.getBool(_keyBiometric) ?? false,
ttsVoice: _prefs.getString(_keyTtsVoice) ?? 'coral',
ttsStyle: _prefs.getString(_keyTtsStyle) ?? '',

View File

@ -225,11 +225,13 @@ final notificationsEnabledProvider = Provider<bool>((ref) {
return ref.watch(settingsProvider).notificationsEnabled;
});
final localeProvider = Provider<Locale>((ref) {
/// Returns null when language is '' (auto/system), letting Flutter pick the device locale.
final localeProvider = Provider<Locale?>((ref) {
final lang = ref.watch(settingsProvider).language;
return switch (lang) {
'zh_TW' => const Locale('zh', 'TW'),
'zh' => const Locale('zh'),
'en' => const Locale('en'),
_ => const Locale('zh'),
_ => null, // '' or anything else follow device locale
};
});

View File

@ -299,6 +299,32 @@
"languageZh": "简体中文",
"languageZhTW": "繁體中文",
"languageEn": "English",
"languageAuto": "Auto (System)",
"referralTabTenant": "Enterprise",
"referralTabPersonal": "My Circle",
"loadFailed": "Load failed",
"myPersonalInviteCode": "My personal invite code",
"pointsBalanceTitle": "Points Balance",
"currentBalanceLabel": "Balance",
"circleMembersCountLabel": "Members",
"totalEarnedLabel": "Total Earned",
"circleRewardRulesTitle": "Circle Reward Rules",
"circleRule1": "New member joins your circle: both get 200 pts welcome gift",
"circleRule2": "Member subscribes Pro: you get 1500 pts, they get 500 pts",
"circleRule3": "Member subscribes Enterprise: you get 5000 pts, they get 2000 pts",
"circleRule4": "Earn 10% of their monthly payments for up to 12 months",
"circleRule5": "L2 circle renewals earn you 5% for up to 6 months",
"circleRule6": "Redeem points for usage quota or agent unlocks",
"myCircleMembersSection": "My Circle Members",
"pointsHistorySection": "Points History",
"noCircleMembersMessage": "No circle members yet. Invite friends!",
"noPointsHistoryMessage": "No points history",
"activatedStatus": "Activated",
"joinedAtLabel": "Joined",
"viewAllButton": "View all",
"rewardHistoryPageTitle": "Reward History",
"noRewardsHistoryMessage": "No rewards yet",
"creditDeductionReward": "Credits auto-deducted from your next bill",
"selectLanguageTitle": "Select Language",
"pushNotificationsLabel": "Push notifications",
"soundLabel": "Sound",

View File

@ -1503,6 +1503,84 @@ abstract class AppLocalizations {
/// **'English'**
String get languageEn;
/// No description provided for @languageAuto.
String get languageAuto;
/// No description provided for @referralTabTenant.
String get referralTabTenant;
/// No description provided for @referralTabPersonal.
String get referralTabPersonal;
/// No description provided for @loadFailed.
String get loadFailed;
/// No description provided for @myPersonalInviteCode.
String get myPersonalInviteCode;
/// No description provided for @pointsBalanceTitle.
String get pointsBalanceTitle;
/// No description provided for @currentBalanceLabel.
String get currentBalanceLabel;
/// No description provided for @circleMembersCountLabel.
String get circleMembersCountLabel;
/// No description provided for @totalEarnedLabel.
String get totalEarnedLabel;
/// No description provided for @circleRewardRulesTitle.
String get circleRewardRulesTitle;
/// No description provided for @circleRule1.
String get circleRule1;
/// No description provided for @circleRule2.
String get circleRule2;
/// No description provided for @circleRule3.
String get circleRule3;
/// No description provided for @circleRule4.
String get circleRule4;
/// No description provided for @circleRule5.
String get circleRule5;
/// No description provided for @circleRule6.
String get circleRule6;
/// No description provided for @myCircleMembersSection.
String get myCircleMembersSection;
/// No description provided for @pointsHistorySection.
String get pointsHistorySection;
/// No description provided for @noCircleMembersMessage.
String get noCircleMembersMessage;
/// No description provided for @noPointsHistoryMessage.
String get noPointsHistoryMessage;
/// No description provided for @activatedStatus.
String get activatedStatus;
/// No description provided for @joinedAtLabel.
String get joinedAtLabel;
/// No description provided for @viewAllButton.
String get viewAllButton;
/// No description provided for @rewardHistoryPageTitle.
String get rewardHistoryPageTitle;
/// No description provided for @noRewardsHistoryMessage.
String get noRewardsHistoryMessage;
/// No description provided for @creditDeductionReward.
String get creditDeductionReward;
/// No description provided for @selectLanguageTitle.
///
/// In zh, this message translates to:

View File

@ -755,6 +755,84 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get languageEn => 'English';
@override
String get languageAuto => 'Auto (System)';
@override
String get referralTabTenant => 'Enterprise';
@override
String get referralTabPersonal => 'My Circle';
@override
String get loadFailed => 'Load failed';
@override
String get myPersonalInviteCode => 'My personal invite code';
@override
String get pointsBalanceTitle => 'Points Balance';
@override
String get currentBalanceLabel => 'Balance';
@override
String get circleMembersCountLabel => 'Members';
@override
String get totalEarnedLabel => 'Total Earned';
@override
String get circleRewardRulesTitle => 'Circle Reward Rules';
@override
String get circleRule1 => 'New member joins your circle: both get 200 pts welcome gift';
@override
String get circleRule2 => 'Member subscribes Pro: you get 1500 pts, they get 500 pts';
@override
String get circleRule3 => 'Member subscribes Enterprise: you get 5000 pts, they get 2000 pts';
@override
String get circleRule4 => 'Earn 10% of their monthly payments for up to 12 months';
@override
String get circleRule5 => 'L2 circle renewals earn you 5% for up to 6 months';
@override
String get circleRule6 => 'Redeem points for usage quota or agent unlocks';
@override
String get myCircleMembersSection => 'My Circle Members';
@override
String get pointsHistorySection => 'Points History';
@override
String get noCircleMembersMessage => 'No circle members yet. Invite friends!';
@override
String get noPointsHistoryMessage => 'No points history';
@override
String get activatedStatus => 'Activated';
@override
String get joinedAtLabel => 'Joined';
@override
String get viewAllButton => 'View all';
@override
String get rewardHistoryPageTitle => 'Reward History';
@override
String get noRewardsHistoryMessage => 'No rewards yet';
@override
String get creditDeductionReward => 'Credits auto-deducted from your next bill';
@override
String get selectLanguageTitle => 'Select Language';

View File

@ -738,6 +738,84 @@ class AppLocalizationsZh extends AppLocalizations {
@override
String get languageEn => 'English';
@override
String get languageAuto => '自动(跟随系统)';
@override
String get referralTabTenant => '企业推荐';
@override
String get referralTabPersonal => '我的圈子';
@override
String get loadFailed => '加载失败';
@override
String get myPersonalInviteCode => '我的个人邀请码';
@override
String get pointsBalanceTitle => '积分余额';
@override
String get currentBalanceLabel => '当前余额';
@override
String get circleMembersCountLabel => '圈子成员';
@override
String get totalEarnedLabel => '累计获得';
@override
String get circleRewardRulesTitle => '圈子奖励规则';
@override
String get circleRule1 => '新成员加入你的圈子,你和对方各获 200 积分欢迎礼';
@override
String get circleRule2 => '圈子成员订阅 Pro 时,你获 1500 pts对方获 500 pts';
@override
String get circleRule3 => '圈子成员订阅 Enterprise 时,你获 5000 pts对方获 2000 pts';
@override
String get circleRule4 => '每月续订时你持续获得付款额 10% 的积分,最长 12 个月';
@override
String get circleRule5 => '二级圈子续订,你获 5% 积分,最长 6 个月';
@override
String get circleRule6 => '积分可兑换额外使用配额或解锁智能体';
@override
String get myCircleMembersSection => '我的圈子成员';
@override
String get pointsHistorySection => '积分记录';
@override
String get noCircleMembersMessage => '暂无圈子成员,快去邀请好友吧!';
@override
String get noPointsHistoryMessage => '暂无积分记录';
@override
String get activatedStatus => '已激活';
@override
String get joinedAtLabel => '加入于';
@override
String get viewAllButton => '查看全部';
@override
String get rewardHistoryPageTitle => '奖励历史';
@override
String get noRewardsHistoryMessage => '暂无奖励记录';
@override
String get creditDeductionReward => '积分自动抵扣你的下期账单';
@override
String get selectLanguageTitle => '选择语言';
@ -1243,6 +1321,84 @@ class AppLocalizationsZhTw extends AppLocalizationsZh {
@override
String get languageEn => 'English';
@override
String get languageAuto => '自動(跟隨系統)';
@override
String get referralTabTenant => '企業推薦';
@override
String get referralTabPersonal => '我的圈子';
@override
String get loadFailed => '加載失敗';
@override
String get myPersonalInviteCode => '我的個人邀請碼';
@override
String get pointsBalanceTitle => '積分餘額';
@override
String get currentBalanceLabel => '當前餘額';
@override
String get circleMembersCountLabel => '圈子成員';
@override
String get totalEarnedLabel => '累計獲得';
@override
String get circleRewardRulesTitle => '圈子獎勵規則';
@override
String get circleRule1 => '新成員加入你的圈子,你和對方各獲 200 積分歡迎禮';
@override
String get circleRule2 => '圈子成員訂閱 Pro 時,你獲 1500 pts對方獲 500 pts';
@override
String get circleRule3 => '圈子成員訂閱 Enterprise 時,你獲 5000 pts對方獲 2000 pts';
@override
String get circleRule4 => '每月續訂時你持續獲得付款額 10% 的積分,最長 12 個月';
@override
String get circleRule5 => '二級圈子續訂,你獲 5% 積分,最長 6 個月';
@override
String get circleRule6 => '積分可兌換額外使用配額或解鎖智能體';
@override
String get myCircleMembersSection => '我的圈子成員';
@override
String get pointsHistorySection => '積分記錄';
@override
String get noCircleMembersMessage => '暫無圈子成員,快去邀請好友吧!';
@override
String get noPointsHistoryMessage => '暫無積分記錄';
@override
String get activatedStatus => '已激活';
@override
String get joinedAtLabel => '加入於';
@override
String get viewAllButton => '查看全部';
@override
String get rewardHistoryPageTitle => '獎勵歷史';
@override
String get noRewardsHistoryMessage => '暫無獎勵記錄';
@override
String get creditDeductionReward => '積分自動抵扣下期賬單';
@override
String get selectLanguageTitle => '選擇語言';

View File

@ -299,6 +299,32 @@
"languageZh": "简体中文",
"languageZhTW": "繁體中文",
"languageEn": "English",
"languageAuto": "自动(跟随系统)",
"referralTabTenant": "企业推荐",
"referralTabPersonal": "我的圈子",
"loadFailed": "加载失败",
"myPersonalInviteCode": "我的个人邀请码",
"pointsBalanceTitle": "积分余额",
"currentBalanceLabel": "当前余额",
"circleMembersCountLabel": "圈子成员",
"totalEarnedLabel": "累计获得",
"circleRewardRulesTitle": "圈子奖励规则",
"circleRule1": "新成员加入你的圈子,你和对方各获 200 积分欢迎礼",
"circleRule2": "圈子成员订阅 Pro 时,你获 1500 pts对方获 500 pts",
"circleRule3": "圈子成员订阅 Enterprise 时,你获 5000 pts对方获 2000 pts",
"circleRule4": "每月续订时你持续获得付款额 10% 的积分,最长 12 个月",
"circleRule5": "二级圈子续订,你获 5% 积分,最长 6 个月",
"circleRule6": "积分可兑换额外使用配额或解锁智能体",
"myCircleMembersSection": "我的圈子成员",
"pointsHistorySection": "积分记录",
"noCircleMembersMessage": "暂无圈子成员,快去邀请好友吧!",
"noPointsHistoryMessage": "暂无积分记录",
"activatedStatus": "已激活",
"joinedAtLabel": "加入于",
"viewAllButton": "查看全部",
"rewardHistoryPageTitle": "奖励历史",
"noRewardsHistoryMessage": "暂无奖励记录",
"creditDeductionReward": "积分自动抵扣你的下期账单",
"selectLanguageTitle": "选择语言",
"pushNotificationsLabel": "推送通知",
"soundLabel": "提示音",

View File

@ -44,6 +44,32 @@
"languageZh": "簡體中文",
"languageZhTW": "繁體中文",
"languageEn": "English",
"languageAuto": "自動(跟隨系統)",
"referralTabTenant": "企業推薦",
"referralTabPersonal": "我的圈子",
"loadFailed": "加載失敗",
"myPersonalInviteCode": "我的個人邀請碼",
"pointsBalanceTitle": "積分餘額",
"currentBalanceLabel": "當前餘額",
"circleMembersCountLabel": "圈子成員",
"totalEarnedLabel": "累計獲得",
"circleRewardRulesTitle": "圈子獎勵規則",
"circleRule1": "新成員加入你的圈子,你和對方各獲 200 積分歡迎禮",
"circleRule2": "圈子成員訂閱 Pro 時,你獲 1500 pts對方獲 500 pts",
"circleRule3": "圈子成員訂閱 Enterprise 時,你獲 5000 pts對方獲 2000 pts",
"circleRule4": "每月續訂時你持續獲得付款額 10% 的積分,最長 12 個月",
"circleRule5": "二級圈子續訂,你獲 5% 積分,最長 6 個月",
"circleRule6": "積分可兌換額外使用配額或解鎖智能體",
"myCircleMembersSection": "我的圈子成員",
"pointsHistorySection": "積分記錄",
"noCircleMembersMessage": "暫無圈子成員,快去邀請好友吧!",
"noPointsHistoryMessage": "暫無積分記錄",
"activatedStatus": "已激活",
"joinedAtLabel": "加入於",
"viewAllButton": "查看全部",
"rewardHistoryPageTitle": "獎勵歷史",
"noRewardsHistoryMessage": "暫無獎勵記錄",
"creditDeductionReward": "積分自動抵扣下期賬單",
"selectLanguageTitle": "選擇語言",
"chatStartConversationPrompt": "開始與 我智能體 對話",