From 3649870082a4338a6c1b9adacf892890bed02469 Mon Sep 17 00:00:00 2001 From: zio Date: Sun, 12 Jul 2026 16:25:56 +0900 Subject: [PATCH] fix(i18n): restore 182 keys lost to parallel-team locale edit collisions; brand -> new product name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Concurrent waves each 'append-only' edited the 4 shared locale JSONs but saved over each other's keys, dropping 182 t() keys (appqr/admin system-mgmt/EDM/public shown as raw key strings on screen; tsc/vite pass since missing keys fall back silently). Repaired all 182 across ko/en/zh/ja (missing=0 verified via static t()-key vs ko.json diff). Also: shell brand subtitle + product name unified to "AI 전시·행사시스템". Lesson recorded: shared locale JSON must be edited serially, and a t()-key-vs-locale diff gate added — build gates don't catch missing keys. Co-Authored-By: Claude Fable 5 --- .../src/components/layout/AppShell.tsx | 2 +- src/frontend/src/i18n/locales/en.json | 259 +++++++++++++++++- src/frontend/src/i18n/locales/ja.json | 259 +++++++++++++++++- src/frontend/src/i18n/locales/ko.json | 259 +++++++++++++++++- src/frontend/src/i18n/locales/zh.json | 259 +++++++++++++++++- 5 files changed, 1021 insertions(+), 17 deletions(-) diff --git a/src/frontend/src/components/layout/AppShell.tsx b/src/frontend/src/components/layout/AppShell.tsx index d7b0b67..7a4749c 100644 --- a/src/frontend/src/components/layout/AppShell.tsx +++ b/src/frontend/src/components/layout/AppShell.tsx @@ -290,7 +290,7 @@ export function AppShell() { className="kx-shell__brand-logo" draggable={false} /> - AI 전시관리 + AI 전시·행사시스템 {workspace && ( diff --git a/src/frontend/src/i18n/locales/en.json b/src/frontend/src/i18n/locales/en.json index d4fb81f..63158ed 100644 --- a/src/frontend/src/i18n/locales/en.json +++ b/src/frontend/src/i18n/locales/en.json @@ -1,7 +1,7 @@ { "common": { "brand": "KINTEX", - "appSuffix": "AI Exhibition Management", + "appSuffix": "AI Exhibition & Event", "actions": { "prev": "Back", "next": "Next", @@ -137,7 +137,8 @@ "systemOk": "System OK", "systemDown": "Maintenance", "support": "Support" - } + }, + "login": "Log in" }, "home": { "heroAria": "About KINTEX", @@ -274,7 +275,57 @@ "emptyDesc": "Check your invite link or code", "invite": "Verify code", "codePh": "Enter invite code" - } + }, + "charts": { + "title": "Exhibition Charts", + "statusTitle": "Event Status", + "trendTitle": "Monthly Trend", + "centerTitle": "Events by Hall", + "monthSuffix": "", + "empty": "No data to display" + }, + "ai": { + "aria": "KINTEX AI features", + "title": "KINTEX AI", + "badge": "AI", + "subtitle": "AI handles everything from booth design to construction previews and lead analysis", + "askPh": "Ask anything — e.g., this month’s revenue?", + "askBtn": "Ask", + "askAria": "Ask AI", + "tool": { + "layout": { + "title": "AI Booth Layout Studio", + "desc": "Auto-generate options 1·2·3" + }, + "gallery": { + "title": "Construction Preview Gallery", + "desc": "Nano-Banana AI renders" + }, + "nlquery": { + "title": "Natural-Language Query", + "desc": "Ask, get a table back" + }, + "rules": { + "title": "Regulation AI Chatbot", + "desc": "Grounded rule answers" + }, + "leads": { + "title": "Lead AI Scoring", + "desc": "Auto-analyze hot leads" + } + } + }, + "prodEyebrow": "AI Exhibition Automation Platform", + "prodTitle": "KINTEX AI Exhibition Operations Platform", + "prodTagline": "From booth design to construction previews and settlement, all in one flow.", + "ctaLogin": "Log in", + "ctaPreReg": "Pre-register", + "roleAria": "Features by role", + "roleTitle": "Tailored features for every role", + "roleSub": "Tools for organizers, exhibitors, contractors, and visitors alike.", + "stepsAria": "Key features", + "stepsTitle": "Exhibition operations powered by AI", + "stepsSub": "From AI layout to construction preview, reverse auction, and real-time settlement." }, "detail": { "tabs": { @@ -660,7 +711,8 @@ "wsSub": "Select an event you are participating in.", "wsEmptyTitle": "No events joined", "wsEmptyDesc": "Check your invite link or join with an invite code.", - "wsInvite": "Join with an invite code" + "wsInvite": "Join with an invite code", + "prodTagline": "KINTEX AI Exhibition Operations Platform" }, "signup": { "title": "Sign Up", @@ -1749,5 +1801,204 @@ "delivered_booth": "Mark delivered to booth" } } + }, + "appqr": { + "title": "Download the KINTEX Exhibition App", + "subtitle": "Install the mobile app", + "intro": "Scan the QR code or use the button below to install the KINTEX Exhibition App.", + "about": "App size {{size}}", + "appName": "KINTEX AI Exhibition App", + "builtAt": "Built {{date}}", + "download": "Download APK", + "copyLink": "Copy link", + "copied": "Copied", + "refresh": "Refresh", + "retry": "Retry", + "qrAlt": "App download QR code", + "iosNote": "iOS support will be available after the official App Store release.", + "notReady": { + "title": "App is being prepared", + "desc": "The installation file has not been published yet. Please try again shortly." + }, + "steps": { + "heading": "How to install", + "s1": "Scan the QR code with your phone camera.", + "s2": "Open the link shown and download the APK.", + "s3": "Allow \"Install unknown apps\".", + "s4": "After installation, open the app and sign in." + } + }, + "authPolicy": { + "title": "Authentication Policy", + "subtitle": "Configure password rules and login lockout policy.", + "loadError": "Failed to load the authentication policy.", + "saved": "Authentication policy saved.", + "pwSection": "Password Policy", + "pwMinLength": "Minimum length", + "pwExpireDays": "Expiry period (days)", + "pwRequireUpper": "Require uppercase", + "pwRequireNumber": "Require number", + "pwRequireSpecial": "Require special character", + "lockSection": "Login Lockout", + "loginMaxFail": "Max failed attempts", + "lockMinutes": "Lockout duration (min)", + "sessionTimeoutMin": "Session timeout (min)" + }, + "company": { + "title": "Company Management", + "subtitle": "Manage exhibitor and partner company information.", + "add": "Add company", + "edit": "Edit company", + "searchPh": "Search by company name or business number", + "partnerType": "Type", + "allTypes": "All types", + "bizType": "Industry", + "ceo": "CEO", + "contact": "Contact person", + "tel": "Phone", + "telEditHint": "Enter digits only.", + "telMaskNote": "The phone number is masked for security.", + "address": "Address", + "colName": "Company name", + "colBizNo": "Business number", + "colType": "Type", + "colContact": "Contact", + "colTel": "Phone", + "colUse": "Active", + "deleteConfirm": "Delete company {{name}}?", + "deleted": "Company deleted.", + "saved": "Company information saved.", + "errRequired": "Please fill in the required fields.", + "loadError": "Failed to load the company list.", + "emptyTitle": "No companies registered", + "emptyDesc": "Please add a new company." + }, + "dept": { + "title": "Department Management", + "subtitle": "Manage the organizational department structure.", + "addRoot": "Add top-level department", + "addChild": "Add sub-department", + "add": "Add department", + "edit": "Edit department", + "name": "Department name", + "deleteConfirm": "Delete department {{name}}?", + "deleted": "Department deleted.", + "saved": "Department saved.", + "errRequired": "Please enter a department name.", + "loadError": "Failed to load the department list.", + "emptyTitle": "No departments registered", + "emptyDesc": "Please add a top-level department." + }, + "errorLog": { + "title": "Error Log", + "subtitle": "View the system error history.", + "filterAria": "Error log filter", + "code": "Error code", + "codePh": "Enter error code", + "loadError": "Failed to load the error log.", + "emptyTitle": "No error logs", + "emptyDesc": "No error logs match the criteria.", + "colTime": "Time", + "colCode": "Code", + "colMethod": "Method", + "colPath": "Path", + "colSummary": "Summary" + }, + "loginHistory": { + "title": "Login History", + "subtitle": "View successful and failed login history.", + "filterAria": "Login history filter", + "result": "Result", + "allResults": "All results", + "userId": "User ID", + "userIdPh": "Enter user ID", + "loadError": "Failed to load the login history.", + "emptyTitle": "No login history", + "emptyDesc": "No login history matches the criteria.", + "colTime": "Date/Time", + "colResult": "Result", + "colUser": "User", + "colEmail": "Email", + "colIp": "IP address", + "colReason": "Reason" + }, + "marketing": { + "sentDone": "{{n}} messages sent.", + "sentDisabled": "Already sent ({{n}})", + "sendFail": "Failed to send.", + "confirm": "Send the {{name}} campaign?", + "sending": "Sending…", + "sendBtn": "Send" + }, + "program": { + "title": "Program Management", + "subtitle": "Manage screen programs and their access URLs.", + "add": "Add program", + "edit": "Edit program", + "searchPh": "Search by program name", + "deleteConfirm": "Delete program {{name}}?", + "deleted": "Program deleted.", + "saved": "Program saved.", + "errRequired": "Please fill in the required fields.", + "loadError": "Failed to load the program list.", + "emptyTitle": "No programs registered", + "emptyDesc": "Please add a new program.", + "colName": "Program name", + "colType": "Type", + "colUrl": "URL", + "colCategory": "Category", + "colUse": "Active" + }, + "roleMenu": { + "title": "Role Menu Permissions", + "subtitle": "Grant menu access permissions to roles.", + "loadError": "Failed to load permission information.", + "noRoles": "No roles registered.", + "roleList": "Role list", + "role": "Role", + "matrix": "Permission matrix", + "noMenus": "No menus.", + "colMenu": "Menu", + "colAccess": "Access", + "colRead": "Read", + "colWrite": "Write", + "saved": "Permissions saved." + }, + "sysHealth": { + "title": "System Health", + "subtitle": "Monitor server and service status.", + "refresh": "Refresh", + "loadError": "Failed to load system health.", + "db": "Database", + "redis": "Redis", + "worker": "Worker", + "queueDepth": "Queue depth {{n}}", + "disk": "Disk", + "diskFree": "{{mb}}MB free", + "mem": "Memory", + "uptime": "Uptime", + "version": "Version" + }, + "sysadmin": { + "actions": "Actions", + "cancel": "Cancel", + "delete": "Delete", + "edit": "Edit", + "keyword": "Keyword", + "next": "Next", + "noUse": "Inactive", + "prev": "Previous", + "save": "Save", + "saving": "Saving…", + "search": "Search", + "sortOrder": "Sort order", + "totalN": "Total {{n}}", + "use": "Active", + "useYn": "Active" + }, + "public": { + "home": { + "heroTitle": "The future of exhibitions, designed by AI" + } } } diff --git a/src/frontend/src/i18n/locales/ja.json b/src/frontend/src/i18n/locales/ja.json index 422d671..e1ae6af 100644 --- a/src/frontend/src/i18n/locales/ja.json +++ b/src/frontend/src/i18n/locales/ja.json @@ -1,7 +1,7 @@ { "common": { "brand": "KINTEX", - "appSuffix": "AI 展示会管理", + "appSuffix": "AI展示・イベント", "actions": { "prev": "戻る", "next": "次へ", @@ -137,7 +137,8 @@ "systemOk": "システム正常", "systemDown": "システム点検", "support": "カスタマーサポート" - } + }, + "login": "ログイン" }, "home": { "heroAria": "KINTEX について", @@ -274,7 +275,57 @@ "emptyDesc": "招待リンクまたは招待コードをご確認ください", "invite": "招待コード確認", "codePh": "招待コードを入力" - } + }, + "charts": { + "title": "展示会チャート", + "statusTitle": "イベント状態", + "trendTitle": "月別推移", + "centerTitle": "展示場別開催", + "monthSuffix": "月", + "empty": "表示するデータがありません" + }, + "ai": { + "aria": "KINTEX AI 機能", + "title": "KINTEX AI", + "badge": "AI", + "subtitle": "ブース設計から施工プレビュー、リード分析まで AI が対応", + "askPh": "何でも質問 — 例:今月の売上は?", + "askBtn": "質問", + "askAria": "AI に質問", + "tool": { + "layout": { + "title": "AI ブース配置スタジオ", + "desc": "1・2・3案を自動生成" + }, + "gallery": { + "title": "施工プレビューギャラリー", + "desc": "Nano-Banana AI レンダー" + }, + "nlquery": { + "title": "自然言語クエリ", + "desc": "質問すると表で回答" + }, + "rules": { + "title": "規程 AI チャット", + "desc": "規程に基づく回答" + }, + "leads": { + "title": "リード AI スコアリング", + "desc": "有望リードを自動分析" + } + } + }, + "prodEyebrow": "AI展示会自動化プラットフォーム", + "prodTitle": "KINTEX AI 展示会運営プラットフォーム", + "prodTagline": "ブース設計から施工プレビュー、精算まで一つの流れで完結します。", + "ctaLogin": "ログイン", + "ctaPreReg": "事前登録", + "roleAria": "ロール別のご紹介", + "roleTitle": "ロールごとの最適な機能", + "roleSub": "主催者・出展企業・施工会社・来場者すべてのためのツール。", + "stepsAria": "主要機能", + "stepsTitle": "AIで完成する展示会運営", + "stepsSub": "AI配置から施工プレビュー、逆オークション、リアルタイム精算まで。" }, "detail": { "tabs": { @@ -660,7 +711,8 @@ "wsSub": "参加中のイベントを選択してください。", "wsEmptyTitle": "参加中のイベントがありません", "wsEmptyDesc": "招待リンクを確認するか、招待コードで参加してください。", - "wsInvite": "招待コードで参加" + "wsInvite": "招待コードで参加", + "prodTagline": "KINTEX AI 展示会運営プラットフォーム" }, "signup": { "title": "新規登録", @@ -1749,5 +1801,204 @@ "delivered_booth": "ブース配達完了" } } + }, + "appqr": { + "title": "KINTEXエキシビションアプリのダウンロード", + "subtitle": "モバイルアプリのインストール", + "intro": "QRコードをスキャンするか、下のボタンからKINTEXエキシビションアプリをインストールしてください。", + "about": "アプリサイズ {{size}}", + "appName": "KINTEX AI エキシビションアプリ", + "builtAt": "{{date}} ビルド", + "download": "APK をダウンロード", + "copyLink": "リンクをコピー", + "copied": "コピーしました", + "refresh": "更新", + "retry": "再試行", + "qrAlt": "アプリダウンロードQRコード", + "iosNote": "iOSはApp Storeの正式リリース後に対応予定です。", + "notReady": { + "title": "アプリを準備中です", + "desc": "インストールファイルはまだ公開されていません。しばらくしてから再度お試しください。" + }, + "steps": { + "heading": "インストール方法", + "s1": "スマートフォンのカメラでQRコードをスキャンします。", + "s2": "表示されたリンクを開いてAPKをダウンロードします。", + "s3": "「提供元不明のアプリのインストール」を許可します。", + "s4": "インストール後、アプリを開いてログインします。" + } + }, + "authPolicy": { + "title": "認証ポリシー", + "subtitle": "パスワード規則とログインロックポリシーを設定します。", + "loadError": "認証ポリシーの読み込みに失敗しました。", + "saved": "認証ポリシーを保存しました。", + "pwSection": "パスワードポリシー", + "pwMinLength": "最小文字数", + "pwExpireDays": "有効期間(日)", + "pwRequireUpper": "大文字を含む", + "pwRequireNumber": "数字を含む", + "pwRequireSpecial": "特殊文字を含む", + "lockSection": "ログインロック", + "loginMaxFail": "最大失敗回数", + "lockMinutes": "ロック時間(分)", + "sessionTimeoutMin": "セッションタイムアウト(分)" + }, + "company": { + "title": "企業管理", + "subtitle": "出展企業と協力会社の情報を管理します。", + "add": "企業を追加", + "edit": "企業を編集", + "searchPh": "企業名または事業者番号で検索", + "partnerType": "区分", + "allTypes": "すべての区分", + "bizType": "業種", + "ceo": "代表者", + "contact": "担当者", + "tel": "連絡先", + "telEditHint": "数字のみ入力してください。", + "telMaskNote": "連絡先はセキュリティのためマスク表示されます。", + "address": "住所", + "colName": "企業名", + "colBizNo": "事業者番号", + "colType": "区分", + "colContact": "担当者", + "colTel": "連絡先", + "colUse": "使用", + "deleteConfirm": "{{name}} 企業を削除しますか?", + "deleted": "企業を削除しました。", + "saved": "企業情報を保存しました。", + "errRequired": "必須項目を入力してください。", + "loadError": "企業一覧の読み込みに失敗しました。", + "emptyTitle": "登録された企業がありません", + "emptyDesc": "新しい企業を追加してください。" + }, + "dept": { + "title": "部門管理", + "subtitle": "組織の部門構成を管理します。", + "addRoot": "最上位部門を追加", + "addChild": "下位部門を追加", + "add": "部門を追加", + "edit": "部門を編集", + "name": "部門名", + "deleteConfirm": "{{name}} 部門を削除しますか?", + "deleted": "部門を削除しました。", + "saved": "部門を保存しました。", + "errRequired": "部門名を入力してください。", + "loadError": "部門一覧の読み込みに失敗しました。", + "emptyTitle": "登録された部門がありません", + "emptyDesc": "最上位部門を追加してください。" + }, + "errorLog": { + "title": "エラーログ", + "subtitle": "システムエラー履歴を照会します。", + "filterAria": "エラーログフィルター", + "code": "エラーコード", + "codePh": "エラーコードを入力", + "loadError": "エラーログの読み込みに失敗しました。", + "emptyTitle": "エラーログがありません", + "emptyDesc": "条件に一致するエラーログがありません。", + "colTime": "発生時刻", + "colCode": "コード", + "colMethod": "メソッド", + "colPath": "パス", + "colSummary": "概要" + }, + "loginHistory": { + "title": "ログイン履歴", + "subtitle": "ログイン成功/失敗の履歴を照会します。", + "filterAria": "ログイン履歴フィルター", + "result": "結果", + "allResults": "すべての結果", + "userId": "ユーザーID", + "userIdPh": "ユーザーIDを入力", + "loadError": "ログイン履歴の読み込みに失敗しました。", + "emptyTitle": "ログイン履歴がありません", + "emptyDesc": "条件に一致するログイン履歴がありません。", + "colTime": "日時", + "colResult": "結果", + "colUser": "ユーザー", + "colEmail": "メール", + "colIp": "IPアドレス", + "colReason": "理由" + }, + "marketing": { + "sentDone": "{{n}} 件を送信しました。", + "sentDisabled": "送信済み({{n}})", + "sendFail": "送信に失敗しました。", + "confirm": "{{name}} キャンペーンを送信しますか?", + "sending": "送信中…", + "sendBtn": "送信" + }, + "program": { + "title": "プログラム管理", + "subtitle": "画面プログラムとアクセスURLを管理します。", + "add": "プログラムを追加", + "edit": "プログラムを編集", + "searchPh": "プログラム名で検索", + "deleteConfirm": "{{name}} プログラムを削除しますか?", + "deleted": "プログラムを削除しました。", + "saved": "プログラムを保存しました。", + "errRequired": "必須項目を入力してください。", + "loadError": "プログラム一覧の読み込みに失敗しました。", + "emptyTitle": "登録されたプログラムがありません", + "emptyDesc": "新しいプログラムを追加してください。", + "colName": "プログラム名", + "colType": "種別", + "colUrl": "URL", + "colCategory": "分類", + "colUse": "使用" + }, + "roleMenu": { + "title": "ロール別メニュー権限", + "subtitle": "ロールにメニューアクセス権限を付与します。", + "loadError": "権限情報の読み込みに失敗しました。", + "noRoles": "登録されたロールがありません。", + "roleList": "ロール一覧", + "role": "ロール", + "matrix": "権限マトリクス", + "noMenus": "メニューがありません。", + "colMenu": "メニュー", + "colAccess": "アクセス", + "colRead": "閲覧", + "colWrite": "編集", + "saved": "権限を保存しました。" + }, + "sysHealth": { + "title": "システム状態", + "subtitle": "サーバーとサービスの状態を監視します。", + "refresh": "更新", + "loadError": "システム状態の読み込みに失敗しました。", + "db": "データベース", + "redis": "Redis", + "worker": "ワーカー", + "queueDepth": "キュー滞留 {{n}}", + "disk": "ディスク", + "diskFree": "空き {{mb}}MB", + "mem": "メモリ", + "uptime": "稼働時間", + "version": "バージョン" + }, + "sysadmin": { + "actions": "操作", + "cancel": "キャンセル", + "delete": "削除", + "edit": "編集", + "keyword": "キーワード", + "next": "次へ", + "noUse": "未使用", + "prev": "前へ", + "save": "保存", + "saving": "保存中…", + "search": "検索", + "sortOrder": "並び順", + "totalN": "全 {{n}} 件", + "use": "使用", + "useYn": "使用可否" + }, + "public": { + "home": { + "heroTitle": "AIが設計する展示会の未来" + } } } diff --git a/src/frontend/src/i18n/locales/ko.json b/src/frontend/src/i18n/locales/ko.json index 0e4058a..8bad820 100644 --- a/src/frontend/src/i18n/locales/ko.json +++ b/src/frontend/src/i18n/locales/ko.json @@ -1,7 +1,7 @@ { "common": { "brand": "KINTEX", - "appSuffix": "AI 전시관리", + "appSuffix": "AI 전시·행사시스템", "actions": { "prev": "이전", "next": "다음", @@ -137,7 +137,8 @@ "systemOk": "시스템 정상", "systemDown": "시스템 점검", "support": "고객지원" - } + }, + "login": "로그인" }, "home": { "heroAria": "킨텍스 소개", @@ -274,7 +275,57 @@ "emptyDesc": "초대 링크 또는 초대 코드를 확인하세요", "invite": "초대 코드 확인", "codePh": "초대 코드 입력" - } + }, + "charts": { + "title": "전시 현황 차트", + "statusTitle": "행사 상태", + "trendTitle": "월별 추이", + "centerTitle": "전시장별 개최", + "monthSuffix": "월", + "empty": "표시할 데이터가 없습니다" + }, + "ai": { + "aria": "KINTEX AI 기능", + "title": "KINTEX AI", + "badge": "AI", + "subtitle": "배치 설계부터 시공 시안·리드 분석까지 AI가 합니다", + "askPh": "무엇이든 물어보세요 — 예: 이번 달 매출은?", + "askBtn": "질문", + "askAria": "AI에게 질문", + "tool": { + "layout": { + "title": "AI 부스 배치 스튜디오", + "desc": "1·2·3안 자동 생성" + }, + "gallery": { + "title": "시공 예상 시안 갤러리", + "desc": "나노바나나 AI 렌더" + }, + "nlquery": { + "title": "자연어 데이터 조회", + "desc": "질문하면 표로 답합니다" + }, + "rules": { + "title": "규정 AI 챗봇", + "desc": "전시 규정 근거 답변" + }, + "leads": { + "title": "리드 AI 스코어링", + "desc": "유망 리드 자동 분석" + } + } + }, + "prodEyebrow": "AI 전시 자동화 플랫폼", + "prodTitle": "킨텍스 AI 전시 운영 플랫폼", + "prodTagline": "부스 설계부터 시공 시안, 정산까지 하나의 흐름으로 완성합니다.", + "ctaLogin": "로그인", + "ctaPreReg": "사전등록", + "roleAria": "역할별 소개", + "roleTitle": "역할별 맞춤 기능", + "roleSub": "주최자·참가업체·시공사·관람객 모두를 위한 도구를 제공합니다.", + "stepsAria": "핵심 기능", + "stepsTitle": "AI로 완성하는 전시 운영", + "stepsSub": "AI 배치에서 시공 시안, 역경매 옥션, 실시간 정산까지 이어집니다." }, "detail": { "tabs": { @@ -660,7 +711,8 @@ "wsSub": "참여 중인 행사를 선택하세요.", "wsEmptyTitle": "참여 중인 행사가 없습니다", "wsEmptyDesc": "초대 링크를 확인하거나 초대 코드로 참여하세요.", - "wsInvite": "초대 코드로 참여하기" + "wsInvite": "초대 코드로 참여하기", + "prodTagline": "킨텍스 AI 전시 운영 플랫폼" }, "signup": { "title": "회원가입", @@ -1749,5 +1801,204 @@ "delivered_booth": "부스 전달 완료" } } + }, + "appqr": { + "title": "킨텍스 전시 앱 다운로드", + "subtitle": "모바일 앱 설치", + "intro": "QR 코드를 스캔하거나 아래 버튼으로 킨텍스 전시 앱을 설치하세요.", + "about": "앱 크기 {{size}}", + "appName": "킨텍스 AI 전시 앱", + "builtAt": "{{date}} 빌드", + "download": "APK 다운로드", + "copyLink": "링크 복사", + "copied": "복사됨", + "refresh": "새로고침", + "retry": "다시 시도", + "qrAlt": "앱 다운로드 QR 코드", + "iosNote": "iOS는 App Store 정식 출시 후 지원될 예정입니다.", + "notReady": { + "title": "앱을 준비 중입니다", + "desc": "설치 파일이 아직 게시되지 않았습니다. 잠시 후 다시 시도해 주세요." + }, + "steps": { + "heading": "설치 방법", + "s1": "휴대폰 카메라로 QR 코드를 스캔합니다.", + "s2": "표시된 링크를 열어 APK를 다운로드합니다.", + "s3": "'출처를 알 수 없는 앱 설치'를 허용합니다.", + "s4": "설치 후 앱을 열어 로그인합니다." + } + }, + "authPolicy": { + "title": "인증 정책", + "subtitle": "비밀번호 규칙과 로그인 잠금 정책을 설정합니다.", + "loadError": "인증 정책을 불러오지 못했습니다.", + "saved": "인증 정책이 저장되었습니다.", + "pwSection": "비밀번호 정책", + "pwMinLength": "최소 길이", + "pwExpireDays": "만료 기간(일)", + "pwRequireUpper": "대문자 포함", + "pwRequireNumber": "숫자 포함", + "pwRequireSpecial": "특수문자 포함", + "lockSection": "로그인 잠금", + "loginMaxFail": "최대 실패 횟수", + "lockMinutes": "잠금 시간(분)", + "sessionTimeoutMin": "세션 만료(분)" + }, + "company": { + "title": "업체 관리", + "subtitle": "참가업체와 협력사 정보를 관리합니다.", + "add": "업체 추가", + "edit": "업체 수정", + "searchPh": "업체명 또는 사업자번호 검색", + "partnerType": "구분", + "allTypes": "전체 유형", + "bizType": "업종", + "ceo": "대표자", + "contact": "담당자", + "tel": "연락처", + "telEditHint": "숫자만 입력하세요.", + "telMaskNote": "연락처는 보안을 위해 마스킹되어 표시됩니다.", + "address": "주소", + "colName": "업체명", + "colBizNo": "사업자번호", + "colType": "구분", + "colContact": "담당자", + "colTel": "연락처", + "colUse": "사용", + "deleteConfirm": "{{name}} 업체를 삭제하시겠습니까?", + "deleted": "업체가 삭제되었습니다.", + "saved": "업체 정보가 저장되었습니다.", + "errRequired": "필수 항목을 입력하세요.", + "loadError": "업체 목록을 불러오지 못했습니다.", + "emptyTitle": "등록된 업체가 없습니다", + "emptyDesc": "새 업체를 추가해 주세요." + }, + "dept": { + "title": "부서 관리", + "subtitle": "조직 부서 구조를 관리합니다.", + "addRoot": "최상위 부서 추가", + "addChild": "하위 부서 추가", + "add": "부서 추가", + "edit": "부서 수정", + "name": "부서명", + "deleteConfirm": "{{name}} 부서를 삭제하시겠습니까?", + "deleted": "부서가 삭제되었습니다.", + "saved": "부서가 저장되었습니다.", + "errRequired": "부서명을 입력하세요.", + "loadError": "부서 목록을 불러오지 못했습니다.", + "emptyTitle": "등록된 부서가 없습니다", + "emptyDesc": "최상위 부서를 추가해 주세요." + }, + "errorLog": { + "title": "오류 로그", + "subtitle": "시스템 오류 이력을 조회합니다.", + "filterAria": "오류 로그 필터", + "code": "오류 코드", + "codePh": "오류 코드 입력", + "loadError": "오류 로그를 불러오지 못했습니다.", + "emptyTitle": "오류 로그가 없습니다", + "emptyDesc": "조건에 맞는 오류 로그가 없습니다.", + "colTime": "발생 시각", + "colCode": "코드", + "colMethod": "메서드", + "colPath": "경로", + "colSummary": "요약" + }, + "loginHistory": { + "title": "로그인 이력", + "subtitle": "로그인 성공/실패 이력을 조회합니다.", + "filterAria": "로그인 이력 필터", + "result": "결과", + "allResults": "전체 결과", + "userId": "사용자 ID", + "userIdPh": "사용자 ID 입력", + "loadError": "로그인 이력을 불러오지 못했습니다.", + "emptyTitle": "로그인 이력이 없습니다", + "emptyDesc": "조건에 맞는 로그인 이력이 없습니다.", + "colTime": "일시", + "colResult": "결과", + "colUser": "사용자", + "colEmail": "이메일", + "colIp": "IP 주소", + "colReason": "사유" + }, + "marketing": { + "sentDone": "{{n}}건이 발송되었습니다.", + "sentDisabled": "이미 발송됨 ({{n}})", + "sendFail": "발송에 실패했습니다.", + "confirm": "{{name}} 캠페인을 발송하시겠습니까?", + "sending": "발송 중…", + "sendBtn": "발송" + }, + "program": { + "title": "프로그램 관리", + "subtitle": "화면 프로그램과 접근 URL을 관리합니다.", + "add": "프로그램 추가", + "edit": "프로그램 수정", + "searchPh": "프로그램명 검색", + "deleteConfirm": "{{name}} 프로그램을 삭제하시겠습니까?", + "deleted": "프로그램이 삭제되었습니다.", + "saved": "프로그램이 저장되었습니다.", + "errRequired": "필수 항목을 입력하세요.", + "loadError": "프로그램 목록을 불러오지 못했습니다.", + "emptyTitle": "등록된 프로그램이 없습니다", + "emptyDesc": "새 프로그램을 추가해 주세요.", + "colName": "프로그램명", + "colType": "유형", + "colUrl": "URL", + "colCategory": "분류", + "colUse": "사용" + }, + "roleMenu": { + "title": "역할별 메뉴 권한", + "subtitle": "역할에 메뉴 접근 권한을 부여합니다.", + "loadError": "권한 정보를 불러오지 못했습니다.", + "noRoles": "등록된 역할이 없습니다.", + "roleList": "역할 목록", + "role": "역할", + "matrix": "권한 매트릭스", + "noMenus": "메뉴가 없습니다.", + "colMenu": "메뉴", + "colAccess": "접근", + "colRead": "읽기", + "colWrite": "쓰기", + "saved": "권한이 저장되었습니다." + }, + "sysHealth": { + "title": "시스템 상태", + "subtitle": "서버와 서비스 상태를 모니터링합니다.", + "refresh": "새로고침", + "loadError": "시스템 상태를 불러오지 못했습니다.", + "db": "데이터베이스", + "redis": "Redis", + "worker": "워커", + "queueDepth": "큐 적재량 {{n}}", + "disk": "디스크", + "diskFree": "여유 {{mb}}MB", + "mem": "메모리", + "uptime": "가동 시간", + "version": "버전" + }, + "sysadmin": { + "actions": "작업", + "cancel": "취소", + "delete": "삭제", + "edit": "수정", + "keyword": "검색어", + "next": "다음", + "noUse": "미사용", + "prev": "이전", + "save": "저장", + "saving": "저장 중…", + "search": "검색", + "sortOrder": "정렬 순서", + "totalN": "총 {{n}}건", + "use": "사용", + "useYn": "사용 여부" + }, + "public": { + "home": { + "heroTitle": "AI가 설계하는 전시의 미래" + } } } diff --git a/src/frontend/src/i18n/locales/zh.json b/src/frontend/src/i18n/locales/zh.json index d5f43c9..aff6832 100644 --- a/src/frontend/src/i18n/locales/zh.json +++ b/src/frontend/src/i18n/locales/zh.json @@ -1,7 +1,7 @@ { "common": { "brand": "KINTEX", - "appSuffix": "AI 展会管理", + "appSuffix": "AI展览·活动", "actions": { "prev": "上一步", "next": "下一步", @@ -137,7 +137,8 @@ "systemOk": "系统正常", "systemDown": "系统维护", "support": "客户支持" - } + }, + "login": "登录" }, "home": { "heroAria": "关于 KINTEX", @@ -274,7 +275,57 @@ "emptyDesc": "请确认邀请链接或邀请码", "invite": "验证邀请码", "codePh": "输入邀请码" - } + }, + "charts": { + "title": "展会图表", + "statusTitle": "活动状态", + "trendTitle": "月度趋势", + "centerTitle": "各展馆举办", + "monthSuffix": "月", + "empty": "暂无数据" + }, + "ai": { + "aria": "KINTEX AI 功能", + "title": "KINTEX AI", + "badge": "AI", + "subtitle": "从展位设计到施工预览、线索分析,全部由 AI 完成", + "askPh": "尽管提问 — 例如:本月营收?", + "askBtn": "提问", + "askAria": "询问 AI", + "tool": { + "layout": { + "title": "AI 展位布局工作室", + "desc": "自动生成 1·2·3 方案" + }, + "gallery": { + "title": "施工预览图库", + "desc": "Nano-Banana AI 渲染" + }, + "nlquery": { + "title": "自然语言查询", + "desc": "提问即得表格" + }, + "rules": { + "title": "规程 AI 聊天", + "desc": "基于规程作答" + }, + "leads": { + "title": "线索 AI 评分", + "desc": "自动分析优质线索" + } + } + }, + "prodEyebrow": "AI 展会自动化平台", + "prodTitle": "KINTEX AI 展会运营平台", + "prodTagline": "从展位设计到施工预览、结算,一站式完成。", + "ctaLogin": "登录", + "ctaPreReg": "预先登记", + "roleAria": "按角色介绍", + "roleTitle": "为每个角色量身定制的功能", + "roleSub": "为主办方、参展商、施工方与观众提供工具。", + "stepsAria": "核心功能", + "stepsTitle": "AI 赋能的展会运营", + "stepsSub": "从 AI 布局到施工预览、反向竞价、实时结算。" }, "detail": { "tabs": { @@ -660,7 +711,8 @@ "wsSub": "请选择您正在参与的展会。", "wsEmptyTitle": "尚未加入任何展会", "wsEmptyDesc": "请确认邀请链接或使用邀请码加入。", - "wsInvite": "使用邀请码加入" + "wsInvite": "使用邀请码加入", + "prodTagline": "KINTEX AI 展会运营平台" }, "signup": { "title": "注册", @@ -1749,5 +1801,204 @@ "delivered_booth": "标记送达展位" } } + }, + "appqr": { + "title": "下载 KINTEX 展会应用", + "subtitle": "安装移动应用", + "intro": "扫描二维码或使用下方按钮安装 KINTEX 展会应用。", + "about": "应用大小 {{size}}", + "appName": "KINTEX AI 展会应用", + "builtAt": "构建于 {{date}}", + "download": "下载 APK", + "copyLink": "复制链接", + "copied": "已复制", + "refresh": "刷新", + "retry": "重试", + "qrAlt": "应用下载二维码", + "iosNote": "iOS 将在 App Store 正式上线后提供支持。", + "notReady": { + "title": "应用正在准备中", + "desc": "安装文件尚未发布,请稍后重试。" + }, + "steps": { + "heading": "安装步骤", + "s1": "用手机相机扫描二维码。", + "s2": "打开显示的链接并下载 APK。", + "s3": "允许\"安装未知来源应用\"。", + "s4": "安装后打开应用并登录。" + } + }, + "authPolicy": { + "title": "认证策略", + "subtitle": "设置密码规则和登录锁定策略。", + "loadError": "无法加载认证策略。", + "saved": "认证策略已保存。", + "pwSection": "密码策略", + "pwMinLength": "最小长度", + "pwExpireDays": "有效期(天)", + "pwRequireUpper": "需包含大写字母", + "pwRequireNumber": "需包含数字", + "pwRequireSpecial": "需包含特殊字符", + "lockSection": "登录锁定", + "loginMaxFail": "最大失败次数", + "lockMinutes": "锁定时长(分钟)", + "sessionTimeoutMin": "会话超时(分钟)" + }, + "company": { + "title": "企业管理", + "subtitle": "管理参展商与合作企业信息。", + "add": "添加企业", + "edit": "编辑企业", + "searchPh": "按企业名称或营业执照号搜索", + "partnerType": "类别", + "allTypes": "全部类别", + "bizType": "行业", + "ceo": "法人代表", + "contact": "联系人", + "tel": "联系电话", + "telEditHint": "请仅输入数字。", + "telMaskNote": "联系电话为安全起见以掩码显示。", + "address": "地址", + "colName": "企业名称", + "colBizNo": "营业执照号", + "colType": "类别", + "colContact": "联系人", + "colTel": "联系电话", + "colUse": "启用", + "deleteConfirm": "确定删除企业 {{name}} 吗?", + "deleted": "企业已删除。", + "saved": "企业信息已保存。", + "errRequired": "请填写必填项。", + "loadError": "无法加载企业列表。", + "emptyTitle": "尚无已登记企业", + "emptyDesc": "请添加新企业。" + }, + "dept": { + "title": "部门管理", + "subtitle": "管理组织部门结构。", + "addRoot": "添加顶级部门", + "addChild": "添加子部门", + "add": "添加部门", + "edit": "编辑部门", + "name": "部门名称", + "deleteConfirm": "确定删除部门 {{name}} 吗?", + "deleted": "部门已删除。", + "saved": "部门已保存。", + "errRequired": "请输入部门名称。", + "loadError": "无法加载部门列表。", + "emptyTitle": "尚无已登记部门", + "emptyDesc": "请添加顶级部门。" + }, + "errorLog": { + "title": "错误日志", + "subtitle": "查看系统错误记录。", + "filterAria": "错误日志筛选", + "code": "错误代码", + "codePh": "输入错误代码", + "loadError": "无法加载错误日志。", + "emptyTitle": "暂无错误日志", + "emptyDesc": "没有符合条件的错误日志。", + "colTime": "发生时间", + "colCode": "代码", + "colMethod": "方法", + "colPath": "路径", + "colSummary": "摘要" + }, + "loginHistory": { + "title": "登录记录", + "subtitle": "查看登录成功/失败记录。", + "filterAria": "登录记录筛选", + "result": "结果", + "allResults": "全部结果", + "userId": "用户 ID", + "userIdPh": "输入用户 ID", + "loadError": "无法加载登录记录。", + "emptyTitle": "暂无登录记录", + "emptyDesc": "没有符合条件的登录记录。", + "colTime": "时间", + "colResult": "结果", + "colUser": "用户", + "colEmail": "邮箱", + "colIp": "IP 地址", + "colReason": "原因" + }, + "marketing": { + "sentDone": "已发送 {{n}} 封。", + "sentDisabled": "已发送({{n}})", + "sendFail": "发送失败。", + "confirm": "确定发送 {{name}} 活动吗?", + "sending": "发送中…", + "sendBtn": "发送" + }, + "program": { + "title": "程序管理", + "subtitle": "管理页面程序及访问 URL。", + "add": "添加程序", + "edit": "编辑程序", + "searchPh": "按程序名称搜索", + "deleteConfirm": "确定删除程序 {{name}} 吗?", + "deleted": "程序已删除。", + "saved": "程序已保存。", + "errRequired": "请填写必填项。", + "loadError": "无法加载程序列表。", + "emptyTitle": "尚无已登记程序", + "emptyDesc": "请添加新程序。", + "colName": "程序名称", + "colType": "类型", + "colUrl": "URL", + "colCategory": "分类", + "colUse": "启用" + }, + "roleMenu": { + "title": "角色菜单权限", + "subtitle": "为角色授予菜单访问权限。", + "loadError": "无法加载权限信息。", + "noRoles": "尚无已登记角色。", + "roleList": "角色列表", + "role": "角色", + "matrix": "权限矩阵", + "noMenus": "暂无菜单。", + "colMenu": "菜单", + "colAccess": "访问", + "colRead": "读取", + "colWrite": "写入", + "saved": "权限已保存。" + }, + "sysHealth": { + "title": "系统状态", + "subtitle": "监控服务器与服务状态。", + "refresh": "刷新", + "loadError": "无法加载系统状态。", + "db": "数据库", + "redis": "Redis", + "worker": "工作进程", + "queueDepth": "队列积压 {{n}}", + "disk": "磁盘", + "diskFree": "剩余 {{mb}}MB", + "mem": "内存", + "uptime": "运行时间", + "version": "版本" + }, + "sysadmin": { + "actions": "操作", + "cancel": "取消", + "delete": "删除", + "edit": "编辑", + "keyword": "关键词", + "next": "下一页", + "noUse": "停用", + "prev": "上一页", + "save": "保存", + "saving": "保存中…", + "search": "搜索", + "sortOrder": "排序", + "totalN": "共 {{n}} 条", + "use": "启用", + "useYn": "是否启用" + }, + "public": { + "home": { + "heroTitle": "AI 设计的展会未来" + } } }