feat: 统一管理端多语言、配置与票据/结算页面重构

This commit is contained in:
2026-05-20 16:27:06 +08:00
parent 37b13278ef
commit 08a11a1589
81 changed files with 2059 additions and 490 deletions

View File

@@ -14,6 +14,17 @@
"saveAccountFailed": "Failed to save account",
"deleteSuccess": "Deleted {{name}}",
"deleteFailed": "Delete failed",
"roleLoadFailed": "Failed to load role list",
"roleListTitle": "Role Management",
"createRole": "Create role",
"roleCreateSuccess": "Created role {{name}}",
"roleUpdateSuccess": "Updated role {{name}}",
"roleSaveFailed": "Failed to save role",
"roleDeleteSuccess": "Deleted role {{name}}",
"roleDeleteFailed": "Failed to delete role",
"rolePermissionSaveSuccess": "Role permissions updated",
"rolePermissionSaveFailed": "Failed to save role permissions",
"roleFormRequired": "Role name and slug are required",
"allPermissions": "All permissions",
"saveRoleSuccess": "Updated roles for {{name}}",
"saveRoleFailed": "Failed to save roles",
@@ -36,6 +47,10 @@
"enabled": "Enabled",
"disabled": "Disabled"
},
"roleType": {
"system": "System",
"custom": "Custom"
},
"actions": {
"permissions": "Assign roles",
"edit": "Edit",
@@ -43,6 +58,18 @@
"cancel": "Cancel",
"save": "Save"
},
"roleTable": {
"name": "Role",
"slug": "Role Code",
"type": "Type",
"status": "Status",
"users": "Users",
"permissions": "Permission count",
"actions": "Actions"
},
"roleActions": {
"permissions": "Permissions"
},
"permissionDialog": {
"title": "Assign roles",
"rolesTitle": "Roles",
@@ -51,6 +78,18 @@
"selectedRoles": "Selected roles:",
"saveRoles": "Save roles"
},
"rolePermissionDialog": {
"title": "Role Permissions"
},
"roleDialog": {
"createTitle": "Create Role",
"editTitle": "Edit Role",
"description": "Roles group backend function permissions and are then assigned to admin accounts.",
"slug": "Role code",
"name": "Role name",
"descriptionLabel": "Role description",
"status": "Status"
},
"accountDialog": {
"createTitle": "Create admin",
"editTitle": "Edit account",
@@ -75,5 +114,60 @@
"rowActionTitle": "Delete this admin",
"confirmTitle": "Confirm deletion",
"confirmDescription": "Delete admin {{name}}? This action cannot be undone."
},
"roleDelete": {
"confirmTitle": "Delete Role",
"confirmDescription": "Delete role {{name}}?"
},
"permissionGroups": {
"all": "All Permissions",
"dashboard": "Dashboard",
"admin_users": "Admin Users",
"admin_roles": "Role Management",
"players": "Players",
"wallet": "Wallet",
"draws": "Draws",
"config": "Configuration",
"risk": "Risk",
"settlement": "Settlement",
"jackpot": "Jackpot",
"reconcile": "Reconcile",
"tickets": "Tickets",
"reports": "Reports",
"audit": "Audit Logs",
"settings": "Settings"
},
"permissionNames": {
"prd.admin_user.manage": "Admin Users · Manage",
"prd.admin_role.manage": "Role Management · Manage",
"prd.users.manage": "Players · Manage",
"prd.users.view_finance": "Players · View Finance",
"prd.users.view_cs": "Players · View Customer Service Cases",
"prd.player_freeze.manage": "Freeze/Unfreeze Player · Manage",
"prd.wallet_reconcile.manage": "Wallet Reconcile · Manage",
"prd.wallet_reconcile.view": "Wallet Reconcile · View",
"prd.wallet_reconcile.view_cs": "Wallet Reconcile · Customer Service View",
"prd.wallet_adjust.manage": "Adjustment/Reversal · Manage",
"prd.draw_result.manage": "Draw Results Entry · Manage",
"prd.draw_result.view": "Draw Results · View",
"prd.draw_reopen.manage": "Draw Reopen · Manage",
"prd.play_switch.manage": "Play Switches · Manage",
"prd.odds.manage": "Odds Configuration · Manage",
"prd.risk_cap.manage": "Risk Caps · Manage",
"prd.risk_cap.view": "Risk Caps · View",
"prd.rebate.manage": "Commission/Rebate · Manage",
"prd.rebate.view": "Commission/Rebate · View",
"prd.jackpot.manage": "Jackpot Configuration · Manage",
"prd.jackpot.view": "Jackpot Configuration · View",
"prd.payout.manage": "Payout Confirmation · Manage",
"prd.payout.review": "Payout Confirmation · Review",
"prd.payout.view": "Payout Confirmation · View",
"prd.report.all": "Reports · All",
"prd.report.risk": "Reports · Risk",
"prd.report.finance": "Reports · Finance",
"prd.report.player": "Reports · Single Player",
"prd.audit.all": "Audit Logs · All",
"prd.audit.self": "Audit Logs · Related to Self",
"prd.audit.finance": "Audit Logs · Finance Related"
}
}

View File

@@ -46,6 +46,9 @@
"errors": {
"loadFailed": "Failed to load"
},
"table": {
"id": "ID"
},
"toolbar": {
"defaultAdmin": "Administrator",
"notifications": "Notifications",
@@ -57,6 +60,7 @@
"home": "Home",
"dashboard": "Dashboard",
"admin_users": "Admin Users",
"admin_roles": "Role Management",
"players": "Players",
"wallet": "Wallet",
"draws": "Draws",
@@ -65,7 +69,7 @@
"settlement": "Settlement",
"jackpot": "Jackpot",
"reconcile": "Reconcile",
"tickets": "Tickets",
"tickets": "Ticket list",
"reports": "Reports",
"audit": "Audit Logs",
"settings": "Settings"

View File

@@ -5,15 +5,14 @@
"sidebarTitle": "Operations configuration",
"groups": {
"betting": "Betting and display",
"risk_wallet": "Risk and funds"
"risk": "Risk control"
},
"items": {
"plays": "Play types and limits",
"odds": "Odds",
"rebate": "Commission / rebate",
"jackpot": "Jackpot pool",
"risk-cap": "Payout caps",
"wallet": "Wallet thresholds"
"risk-cap": "Payout caps"
}
},
"versionStatus": {
@@ -70,6 +69,31 @@
},
"discard": "Discard changes"
},
"system": {
"title": "Draw and settlement runtime settings",
"runtimeTitle": "Global runtime parameters",
"runtimeIntro1": "This area stores global system parameters that do not belong to play, odds, or risk-control versions. They directly affect wallet transfers, job switches, and runtime policy.",
"runtimeIntro2": "Play, odds, rebate, and cap management stay under operations configuration. System settings only carry cross-module runtime parameters to avoid overlapping responsibilities in admin.",
"description": "Controls review flow after RNG draw generation, cooldown duration, and automatic settlement behavior. These are global runtime policies and do not belong to versioned operations config.",
"loadFailed": "Failed to load system settings",
"saveSuccess": "System settings saved",
"saveFailed": "Failed to save system settings",
"fields": {
"manualReview": "Require manual review for draw results",
"cooldownMinutes": "Cooldown duration (minutes)",
"autoSettlement": "Run settlement automatically"
},
"hints": {
"manualReview": "When enabled, RNG draw results enter pending review and must be published manually in admin.",
"cooldownMinutes": "How long to wait after publishing before entering settling. Use 0 to settle immediately.",
"autoSettlement": "When disabled, tick will not run settlement automatically and admins must trigger it manually."
},
"states": {
"enabled": "Enabled",
"disabled": "Disabled"
},
"discard": "Discard changes"
},
"play": {
"batchGroups": {
"d2": "2D Global",
@@ -79,6 +103,164 @@
"position": "Position Plays",
"box": "Box Plays",
"jackpot": "Jackpot"
},
"validation": {
"minMaxInvalid": "{{playCode}}: min bet cannot exceed max bet"
},
"publishFailed": "Publish failed",
"createDraftSuccess": "Created draft v{{version}}",
"createDraftFailed": "Failed to create draft",
"ruleSavedLocal": "Rule text was saved into the local draft. Save the draft to persist it.",
"deleteFailed": "Delete failed",
"activeVersion": "Active version v{{version}}",
"readOnlyHint": "Limits and rules are read-only. Create a draft first.",
"batchSwitchesTitle": "Batch switches",
"batchSwitchesDesc": "Only updates the current draft. The player betting table refreshes after save and publish.",
"readOnlyDraftHint": "Current version is read-only. Create a draft first.",
"batchEnabledCount": "{{enabledCount}}/{{total}} enabled",
"noPlayTypes": "No play types",
"actions": {
"enable": "Enable",
"disable": "Disable",
"ruleText": "Rule text"
},
"table": {
"playCode": "Play code",
"category": "Category",
"status": "Status",
"displayName": "Display name",
"order": "Order",
"minBet": "Min bet",
"maxBet": "Max bet",
"actions": "Actions"
},
"states": {
"enabled": "Enabled",
"disabled": "Disabled",
"readOnly": "Read only"
},
"aria": {
"enablePlay": "Enable {{playCode}}"
},
"ruleDialog": {
"title": "Rule text (Chinese)",
"description": "Play {{playCode}}. Changes stay in the draft until you save and publish it.",
"fieldLabel": "rule_text_zh",
"apply": "Apply to draft"
}
},
"odds": {
"tabs": {
"all": "All"
},
"category": "Category",
"playType": "Play type",
"noPlayTypes": "No play types in this category.",
"sheetDescription": "Choose a version to view here. Non-draft versions can be rolled back into a new draft.",
"activeVersionPrefix": "Active version:",
"readOnlyHint": "This version is read-only. Create a draft before editing odds.",
"loadingDetails": "Loading details…",
"multiplier": "Multiplier x{{value}} · {{currency}}",
"missingScopeRow": "Missing {{scope}} row. Check seed or version data.",
"rebateRate": "Rebate rate (%)",
"rebateRateHint": "Writes rebate_rate to all prize scopes under this play type.",
"publishFailed": "Publish failed",
"createDraftSuccess": "Created draft v{{version}}",
"createDraftFailed": "Failed to create draft",
"rollbackSuccess": "Cloned v{{fromVersion}} into new draft v{{version}}",
"rollbackFailed": "Rollback failed",
"deleteFailed": "Delete failed",
"rollbackDialog": {
"title": "Confirm rollback",
"description": "A new draft will be cloned from version v{{version}}. The active version will not be overwritten directly.",
"confirm": "Confirm rollback"
},
"publishDialog": {
"title": "Publish odds version?",
"description": "New odds affect new tickets immediately. Existing successful tickets still settle by their saved odds snapshot.",
"confirm": "Confirm publish",
"columns": {
"prizeScope": "Prize scope",
"currentActive": "Current active",
"afterPublish": "After publish"
}
}
},
"rebate": {
"sheetDescription": "Rebate is stored in the odds draft version and shares the same version set as odds.",
"publishLabel": "Publish",
"publishSuccess": "Published odds version with rebate",
"publishFailed": "Publish failed",
"createDraftSuccess": "Created draft v{{version}}",
"createDraftFailed": "Failed to create draft",
"deleteFailed": "Delete failed",
"editingVersion": "Editing version v{{version}} · {{status}}",
"readOnlyHint": "Create a draft before editing rebate.",
"fields": {
"d2": "2D rebate rate (%)",
"d3": "3D rebate rate (%)",
"d4": "4D rebate rate (%)"
},
"winEnjoy": {
"label": "Apply rebate on winning tickets",
"description": "Placeholder field. It can later be aligned with risk and settlement rules and persisted."
},
"effectiveTime": "Effective time (current active odds version)"
},
"riskCap": {
"validation": {
"requireAtLeastOne": "At least one cap row is required",
"defaultGreaterThanZero": "Default cap amount must be greater than 0",
"numberMustBe4Digits": "Number must be 4 digits: {{number}}",
"enterValidCapAmount": "Enter a valid cap amount"
},
"publishFailed": "Publish failed",
"createDraftSuccess": "Created draft v{{version}}",
"createDraftFailed": "Failed to create draft",
"savedLocalDraft": "Saved into local draft. Save the draft to persist it.",
"deleteFailed": "Delete failed",
"effectiveAt": "Effective at: {{value}}",
"note": "Note: {{value}}",
"readOnlyHint": "Read only. Create a draft first.",
"readOnly": "Read only",
"defaultCap": {
"title": "Default cap",
"description": "Numbers without a special cap use this default cap template.",
"fieldLabel": "Cap amount (minor unit)"
},
"specialCaps": {
"title": "Special caps"
},
"loadingDetails": "Loading details…",
"noDetailRows": "No detail rows.",
"table": {
"number": "Number",
"capAmount": "Cap amount",
"used": "Used",
"remaining": "Remaining",
"soldOut": "Sold out",
"ratio": "Ratio",
"actions": "Actions"
},
"occupancy": {
"title": "All number occupancy",
"description": "Placeholder view: filters and exports still need ticket-summary integration. Data below still comes from the current draft list.",
"searchLabel": "Search number",
"searchPlaceholder": "e.g. 8888",
"filterPending": "Sold-out / high-risk preset filter is pending integration",
"exportPending": "CSV export is pending integration"
},
"actions": {
"update": "Update",
"addSpecialCap": "+ Add special cap",
"filterPresets": "Filter presets…",
"exportCsv": "Export CSV",
"close": "Close"
},
"syncDialog": {
"title": "Sync default cap",
"description": "The default cap template will be set to {{value}}. This only changes the draft. Save and publish after confirming.",
"confirm": "Confirm"
}
}
}

View File

@@ -4,7 +4,7 @@
"loadFailed": "Failed to load",
"saveSuccess": "Saved",
"saveFailed": "Save failed",
"invalidDrawId": "Enter a valid draw ID",
"invalidDrawId": "Enter a valid draw number",
"manualBurstSuccess": "Jackpot burst triggered manually",
"manualBurstFailed": "Manual burst failed",
"noPoolData": "No pool data",
@@ -21,7 +21,7 @@
"enabled": "Enabled",
"saving": "Saving…",
"save": "Save",
"manualBurstDrawId": "Manual burst draw ID",
"manualBurstDrawId": "Manual burst draw number",
"manualBurstAmount": "Burst amount (empty for all)",
"processing": "Processing…",
"manualBurst": "Manual burst",
@@ -31,12 +31,22 @@
"apply": "Apply",
"payoutRecords": "Jackpot payout records",
"contributionRecords": "Jackpot contribution records",
"recordsPage": {
"title": "Jackpot records",
"description": "Payout records and pool contribution flows"
},
"subnavLabel": "Jackpot sub navigation",
"subnavPools": "Pool configuration",
"subnavRecords": "Records",
"payoutLoadFailed": "Failed to load payout records",
"contributionLoadFailed": "Failed to load contribution records",
"trigger": "Trigger",
"triggerTypes": {
"threshold": "Threshold reached",
"forced_gap": "Forced by draw gap",
"play_combo": "Triggered by play combo",
"manual": "Manual trigger"
},
"payoutAmount": "Payout amount",
"winnerCount": "Winner count",
"time": "Time",

View File

@@ -18,6 +18,17 @@
"createdAt": "Created at",
"id": "ID",
"empty": "No data",
"formatOptions": {
"csv": "CSV",
"xlsx": "Excel"
},
"statusOptions": {
"pending": "Pending",
"queued": "Queued",
"running": "Running",
"completed": "Completed",
"failed": "Failed"
},
"reportTypes": {
"draw_profit_summary": "Draw profit summary",
"daily_profit_summary": "Daily profit summary",

View File

@@ -58,6 +58,7 @@
"matchedTier": "Matched tier",
"regularPayout": "Regular payout",
"loadingDetails": "Loading details…",
"invalidBatchId": "Invalid settlement batch number",
"statusOptions": {
"all": "All",
"running": "Running",
@@ -67,5 +68,10 @@
"paid": "Paid",
"completed": "Completed",
"failed": "Failed"
},
"reviewStatusOptions": {
"pending": "Pending review",
"approved": "Approved",
"rejected": "Rejected"
}
}

View File

@@ -1,19 +1,43 @@
{
"title": "Tickets",
"playerTicketQuery": "Player ticket query",
"playerId": "Player ID",
"invalidPlayerId": "Enter a valid player ID",
"drawNoOptional": "Draw no. (optional)",
"title": "Ticket list",
"playerTicketQuery": "Ticket query",
"playerId": "Player ID / account",
"invalidPlayerId": "Enter a valid player ID or account",
"playerIdPlaceholder": "Leave blank for all tickets; enter player ID or account",
"drawNoOptional": "Draw number (optional)",
"drawNoPlaceholder": "For example 20260520-001",
"numberKeyword": "Number / ticket / order",
"numberKeywordPlaceholder": "Search by number, ticket no. or order no.",
"placedDateRange": "Placed date range",
"query": "Query",
"resetFilters": "Reset filters",
"refreshCurrentPage": "Refresh current page",
"loadFailed": "Failed to load",
"ticketNo": "Ticket no.",
"player": "Player",
"orderNo": "Order no.",
"drawNo": "Draw no.",
"playCode": "Play",
"number": "Number",
"betAmount": "Bet amount",
"actualDeduct": "Actual deduct",
"status": "Status",
"failReason": "Fail reason",
"winAmount": "Win amount"
"winAmount": "Win amount",
"placedAt": "Placed at",
"updatedAt": "Updated at",
"statusFilterLabel": "Status filter",
"statusHint": "Multiple selection supported. Leave empty for all statuses.",
"statusSelectedCount": "{{count}} selected",
"statusOptions": {
"all": "All",
"pending_confirm": "Pending confirmation",
"partial_pending_confirm": "Partially pending confirmation",
"success": "Bet placed",
"failed": "Bet failed",
"pending_payout": "Pending payout",
"settled_win": "Settled win",
"settled_lose": "Settled loss"
},
"allTickets": "All tickets"
}