feat(i18n): l10n codegen — strings.json 单源生成 6 份 strings_*.dart

② 单源 codegen 落地:
- strings.json 补全 lists 段(days7/featsFree/featsPro/featsTeam),
  之前 extraction 漏了 4 个 List<String> getter;现 246 getter+4 list+5 method×6 语。
- design/codegen/gen_l10n_dart.mjs:strings.json → strings_{zh,en,ja,ko,ru,es}.dart,
  getter 转义 \$、method 保留 $var 插值,dart format 定型(保证漂移闸零 diff)。
- app_text.dart 保持手写(enum/abstract 声明/AppLangMisc 逻辑),编译器强制 concrete⊆abstract 兜底。
- 往返无损:生成的 Dart 重新抽取 == strings.json 逐字节一致;flutter analyze 0 issue、flutter test 244 全绿。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A79VtQA1BwTuQN1ThpvYpo
This commit is contained in:
wangjia
2026-07-27 08:47:44 +08:00
parent 9ab550d398
commit f76e3cdffd
9 changed files with 662 additions and 372 deletions
+45 -52
View File
@@ -1,8 +1,7 @@
// strings_ko.dart — 한국어 문구 리소스 (단일 언어 표시)
// strings_ko.dart — 한국어文案(自动生成 · 勿手改)
//
// 금지어: 검열 우회·민감 표현. 목록은 design/CLAUDE.md §1 규칙 13 참조.
// 포지셔닝: 네트워크 가속 / 경험 최적화 + 프라이버시.
// 요금제 번호는 design/CLAUDE.md §7 을 따름.
// GENERATED by design/codegen/gen_l10n_dart.mjs from design/i18n/strings.json.
// 改文案:改 strings.json 后重跑 codegen;新增 key 需同步 app_text.dart 抽象声明。
import 'app_text.dart';
class StringsKo extends AppText {
@@ -27,7 +26,6 @@ class StringsKo extends AppText {
String get connectNow => '연결';
@override
String get secure => '보안';
@override
String get tabConnect => '연결';
@override
@@ -36,7 +34,6 @@ class StringsKo extends AppText {
String get tabStats => '통계';
@override
String get tabMe => '계정';
@override
String get currentNode => '현재 노드';
@override
@@ -45,7 +42,6 @@ class StringsKo extends AppText {
String get upload => '';
@override
String get latency => '지연';
@override
String get quotaToday => '오늘 남은 시간';
@override
@@ -65,20 +61,19 @@ class StringsKo extends AppText {
@override
String get watchAdMore => '광고 시청으로 시간 추가';
@override
String get quotaExhaustedNotice => '오늘 무료 시간을 모두 사용했습니다. 업그레이드하면 계속 연결할 수 있습니다.';
String get quotaExhaustedNotice =>
'오늘 무료 시간을 모두 사용했습니다. 업그레이드하면 계속 연결할 수 있습니다.';
@override
String get adPlaying => '광고 재생 중…';
@override
String adRewarded(int minutes) => '+$minutes분 추가됨';
@override
String get adFailed => '시간 추가에 실패했습니다. 다시 시도하세요';
@override
String get quotaDesktopTitle => '오늘 무료 시간을 모두 사용함';
@override
String get quotaDesktopBody => '모바일 앱에서 광고를 시청해 시간을 추가하거나, 업그레이드하여 무제한으로 이용하세요.';
String get quotaDesktopBody =>
'모바일 앱에서 광고를 시청해 시간을 추가하거나, 업그레이드하여 무제한으로 이용하세요.';
@override
String get gotIt => '확인';
@override
String get chooseNode => '서버 선택';
@override
@@ -86,8 +81,6 @@ class StringsKo extends AppText {
@override
String get smartSelect => '스마트 선택';
@override
String nodeSwitchTitle(String name) => '$name(으)로 전환할까요?';
@override
String get nodeSwitchBody => '현재 연결을 끊고 이 노드로 다시 연결합니다.';
@override
String get nodeSwitchConfirm => '전환';
@@ -101,7 +94,6 @@ class StringsKo extends AppText {
String get smartSub => '네트워크에 가장 적합한 노드를 선택합니다';
@override
String get recommended => '추천';
@override
String get statsTitle => '통계';
@override
@@ -113,8 +105,6 @@ class StringsKo extends AppText {
@override
String get weekTraffic => '이번 주 (GB)';
@override
List<String> get days7 => const ['', '', '', '', '', '', ''];
@override
String get byDevice => '기기별';
@override
String get noDeviceUsage => '아직 기기 사용 기록이 없습니다';
@@ -134,7 +124,6 @@ class StringsKo extends AppText {
String get chartTwoWeeks => '최근 2주';
@override
String get allDevices => '모든 기기';
@override
String get meTitle => '계정';
@override
@@ -186,9 +175,11 @@ class StringsKo extends AppText {
@override
String get devSave => '저장';
@override
String get devForceLogoutConfirm => '이 기기의 로그인 세션을 무효화합니다 — 오프라인으로 강제 종료되며 다시 로그인해야 합니다. 기기는 목록에 남아 있습니다.';
String get devForceLogoutConfirm =>
'이 기기의 로그인 세션을 무효화합니다 — 오프라인으로 강제 종료되며 다시 로그인해야 합니다. 기기는 목록에 남아 있습니다.';
@override
String get devClearLoginConfirm => '이 기기를 목록에서 완전히 삭제하고 로그인 세션과 데이터 전송 자격 증명을 무효화합니다. 다시 사용하려면 재로그인해야 합니다.';
String get devClearLoginConfirm =>
'이 기기를 목록에서 완전히 삭제하고 로그인 세션과 데이터 전송 자격 증명을 무효화합니다. 다시 사용하려면 재로그인해야 합니다.';
@override
String get devCancel => '취소';
@override
@@ -224,8 +215,6 @@ class StringsKo extends AppText {
@override
String get autoConnectSub => '실행 시 자동으로 연결';
@override
String autoConnectingTo(String name) => '$name(으)로 자동 연결 중…';
@override
String get smartRoute => '스마트 라우팅';
@override
String get smartRouteSub => '해외는 가속, 국내는 직접 연결';
@@ -238,8 +227,6 @@ class StringsKo extends AppText {
@override
String get webUserCenter => '사용자 센터 (웹)';
@override
String updateAvailableTitle(String version) => '새 버전 v$version 사용 가능';
@override
String get updateNotesFallback => '이번 업데이트에는 버그 수정과 안정성 개선이 포함되어 있습니다.';
@override
String get updateLater => '나중에';
@@ -249,7 +236,6 @@ class StringsKo extends AppText {
String get updateUpToDate => '최신 버전입니다';
@override
String get updateCheckFailed => '업데이트 확인에 실패했습니다. 잠시 후 다시 시도하세요';
@override
String get freePlan => '무료';
@override
@@ -266,20 +252,6 @@ class StringsKo extends AppText {
String get choose => '선택';
@override
String get mostPopular => '인기';
@override
List<String> get featsFree => const [
'기본 노드 1개',
'하루 10분',
'광고 시청 후 시작',
'가입 시 7일 무료 체험',
];
@override
List<String> get featsPro =>
const ['80개 이상 지역', '무제한 · 빠른 속도', '기기 5대', '스트리밍 최적화'];
@override
List<String> get featsTeam =>
const ['Pro의 모든 기능', '10인 좌석', '통합 결제', '우선 지원'];
@override
String get redeemTitle => '코드 등록 및 구매';
@override
@@ -298,12 +270,10 @@ class StringsKo extends AppText {
String get chStore => '셀프 스토어';
@override
String get chEmail => '이메일 지원';
@override
String get contactTitle => '문의하기';
@override
String get contactIntro =>
'도움이 필요하신가요? 아래 채널로 문의하세요 — 보통 몇 분 안에 답변드립니다.';
String get contactIntro => '도움이 필요하신가요? 아래 채널로 문의하세요 — 보통 몇 분 안에 답변드립니다.';
@override
String get contactEmail => '이메일 지원';
@override
@@ -314,7 +284,6 @@ class StringsKo extends AppText {
String get contactHoursTitle => '지원 시간';
@override
String get contactHours => '매일 9:00 24:00 (GMT+8)';
@override
String get authTagline => '빠르게 · 안정적으로 · 손쉽게';
@override
@@ -334,8 +303,6 @@ class StringsKo extends AppText {
@override
String get codeLabel => '인증 코드';
@override
String codeSentTo(String email) => '$email(으)로 코드를 보냈습니다';
@override
String get sendCode => '코드 전송';
@override
String get resend => '재전송';
@@ -349,7 +316,6 @@ class StringsKo extends AppText {
String get forgotPw => '비밀번호를 잊으셨나요?';
@override
String get tos => '계속하면 이용약관 및 개인정보 처리방침에 동의하는 것입니다';
@override
String get obSkip => '건너뛰기';
@override
@@ -370,8 +336,6 @@ class StringsKo extends AppText {
String get ob3Title => '설계부터 프라이버시';
@override
String get ob3Sub => '종단 간 암호화. 브라우징 기록을 전혀 저장하지 않습니다.';
// ── 购买 / 支付 ──
@override
String get purchaseTitle => '요금제 구매';
@override
@@ -434,8 +398,6 @@ class StringsKo extends AppText {
String get payUnsupportedRenderType => '지원되지 않습니다. 결제 방법을 변경하세요';
@override
String get payNoActiveOrder => '진행 중인 주문이 없습니다';
// ── 支付渠道 switch + 订单 ──
@override
String get payChannel => '결제 채널';
@override
@@ -474,8 +436,6 @@ class StringsKo extends AppText {
String get orderRebuy => '다시 구매';
@override
String get payMethodNezha => 'Nazhapay';
// ── 邀请 / 通知 / 设置分组 / 订单过期(Spec ②③占位) ──
@override
String get inviteEntry => '친구 초대하고 멤버십 받기';
@override
@@ -546,4 +506,37 @@ class StringsKo extends AppText {
String get promoBadge => '한정 특가';
@override
String get promoOriginalPrice => '정가';
@override
List<String> get days7 => const ['', '', '', '', '', '', ''];
@override
List<String> get featsFree => const [
'기본 노드 1개',
'하루 10분',
'광고 시청 후 시작',
'가입 시 7일 무료 체험',
];
@override
List<String> get featsPro => const [
'80개 이상 지역',
'무제한 · 빠른 속도',
'기기 5대',
'스트리밍 최적화',
];
@override
List<String> get featsTeam => const [
'Pro의 모든 기능',
'10인 좌석',
'통합 결제',
'우선 지원',
];
@override
String adRewarded(int minutes) => '+$minutes분 추가됨';
@override
String nodeSwitchTitle(String name) => '$name(으)로 전환할까요?';
@override
String autoConnectingTo(String name) => '$name(으)로 자동 연결 중…';
@override
String updateAvailableTitle(String version) => '새 버전 v$version 사용 가능';
@override
String codeSentTo(String email) => '$email(으)로 코드를 보냈습니다';
}