Files
thebet365/apps/player/src/i18n/en-US.ts
Mars f9343b00af feat(player/admin/api): 站内邮箱、在线状态、员工菜单权限与内容管理增强
API:
- 新增 player-messages 域:充值审核通过/拒绝、Banner/公告推广消息,支持多语言模板
- 新增 presence 域:Redis 心跳在线状态,管理端可查询在线玩家数
- User 表增加 visible_menus 字段;新增 player_messages 表及迁移
- 充值审核通过/拒绝时按系统配置自动写入玩家站内消息
- 管理端新增 GET /deposit-orders/pending-count、GET /presence/online-count
- 玩家端新增消息 CRUD、presence/ping、home 返回 inbox 开关配置
- 员工管理支持 visibleMenus 配置与删除保护(不能删自己/最后超管)
- SystemConfig 增加 inbox 功能开关及各类通知开关

Admin:
- 员工管理:按角色默认菜单 + 可勾选可见菜单项
- ManageLayout:按 visibleMenus 过滤侧栏;充值待审数量角标轮询
- Contents:富文本编辑器、图片字段组件重构
- DashboardPlayers:展示在线玩家数;AdminPlayerStatusCell 在线状态列
- 多页面 i18n 与权限细节调整

Player:
- 站内邮箱中心(InboxHub):消息列表/详情、未读角标、一键已读/删除
- 公告列表与详情页;走马灯可跳转详情
- 客服 Modal 改为 Panel,与邮箱 Hub 整合
- 充值状态轮询通知;presence 心跳;BetSlip 清空二次确认
- HomeView 今日赛事板块;FootballView 等体验优化

Shared: 新增 CANNOT_DELETE_SELF、STAFF_NOT_FOUND、MESSAGE_NOT_FOUND 等错误码
Docs: 玩家端缺失功能分析文档
Chore: 移除 .agents/skills 设计类 skill 文件
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-17 17:51:10 +08:00

521 lines
19 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
export default {
common: {
pull_refresh: 'Pull to refresh',
release_refresh: 'Release to refresh',
refreshing: 'Refreshing…',
loading_more: 'Loading more…',
no_more: 'No more',
load_failed: 'Failed to load',
retry: 'Retry',
back_to_top: 'Back to top',
cancel: 'Cancel',
confirm: 'Confirm',
},
nav: { home: 'Home', bet: 'Bet', bet_history: 'History', wallet: 'Wallet', profile: 'Profile' },
home: {
hot_matches: 'Hot matches',
hot_tab: 'Hot',
upcoming_tab: 'Upcoming',
no_matches: 'No matches',
upcoming_empty: 'No matches kicking off in the next 3 days',
announcement_badge: 'Notice',
announcement_default:
'Welcome to TheBet365 · Football events are live · Bet responsibly',
banner_prev: 'Previous slide',
banner_next: 'Next slide',
banner_slide: 'Slide {n}',
banner_fallback: 'Banner',
},
announcements: {
title: 'Announcements',
detail_title: 'Announcement',
empty: 'No announcements yet',
not_found: 'This announcement is unavailable',
view_all: 'View all announcements',
type_notice: 'Notice',
type_ticker: 'Ticker',
type_banner: 'Banner',
related_link: 'Related link',
go_link: 'Go to page',
open_link: 'Open link',
back: 'Back',
},
search: {
placeholder: 'Search teams or leagues',
no_results: 'No matches found',
results_count: '{count} matches found',
hint: 'Enter a team or league to filter on the Bet page',
},
deposit_notify: {
approved_title: 'Deposit approved',
rejected_title: 'Deposit rejected',
view_history: 'View deposit history',
view_messages: 'Open inbox',
dismiss: 'Dismiss',
},
messages: {
title: 'Inbox',
detail_title: 'Message',
empty: 'No messages yet',
not_found: 'Message not found',
view_all: 'Back to inbox',
back: 'Back',
mark_all_read: 'Mark all read',
load_more: 'Load more',
delete: 'Delete',
delete_all: 'Delete all',
delete_confirm: 'Delete this message?',
delete_all_confirm: 'Delete all messages? This cannot be undone.',
banner_promo_view: 'View promotion',
content_promo_view: 'View details',
status_unread: 'Unread',
status_read: 'Read',
deposit_approved_title: 'Deposit approved',
deposit_rejected_title: 'Deposit rejected',
deposit_approved_body: 'Order {orderNo} approved. Requested {amount}, credited {approvedAmount}.',
deposit_rejected_body: 'Order {orderNo} ({amount}) was rejected. {reason}',
reject_reason: 'Rejection reason',
no_reason: 'No reason provided',
view_recharge_history: 'View recharge history',
unread_badge: '{count} unread',
open_inbox: 'Open inbox',
},
inbox_hub: {
title: 'Messages & Support',
tab_messages: 'Inbox',
tab_support: 'Support',
open: 'Open messages and support',
open_support: 'Open support',
},
history: {
league_default: 'Football',
stake: 'Stake',
return: 'Return',
est_return: 'Est. Return',
odds: 'Odds',
ft: 'FT',
ht: 'HT',
parlay_title: 'Parlay · {n} legs',
parlay_league: 'Parlay',
empty: 'No bets yet',
no_more: 'No more bets',
status_won: 'WON',
status_pending: 'PENDING',
status_lost: 'LOST',
status_push: 'PUSH',
back: 'Back',
not_found: 'Bet not found',
my_pick: 'My pick',
my_bets: 'My bets',
legs: 'Parlay legs',
summary: 'Summary',
bet_no: 'Bet ID',
awaiting_result: 'Awaiting result…',
filter_all: 'All',
filter_won: 'Won',
filter_lost: 'Lost',
filter_pending: 'Pending',
filter_push: 'Push',
stats_total: 'Total',
stats_won: 'Won',
stats_lost: 'Lost',
stats_pending: 'Pending',
stats_push: 'Push',
stats_stake: 'Total Stake',
stats_return: 'Total Return',
cashbacked: 'Cashbacked',
},
auth:
{ login: 'Login',
register: 'Create Account',
logout: 'Log out',
username: 'Username',
password: 'Password',
invite_code: 'Invitation Code',
optional: 'Optional',
captcha_placeholder: 'Code',
captcha_refresh: 'Click to refresh',
captcha_wrong: 'Incorrect captcha code',
slide_to_verify: 'Slide to verify',
click_to_verify: 'Click to verify',
verified: 'Verified',
login_required: 'Login Required',
login_hint: 'Log in to place bets and access more features',
go_login: 'Go to login',
go_register: 'No account? Register now',
have_account: 'Already have an account? Log in',
register_btn: 'Register',
registering: 'Registering…',
sending_sms: 'Sending…',
register_failed: 'Registration failed, please try again',
continue_browsing: 'Skip login',
username_placeholder: 'Enter username',
username_register_placeholder: '7-32 letters or digits',
username_required: 'Username is required',
username_format_invalid: 'Username must be 7-32 letters or digits',
login_account: 'Phone / Username',
login_by_phone: 'Log in with phone',
login_by_account: 'Log in with username',
login_account_placeholder: 'Phone number or username',
login_username_placeholder: 'Phone number or username',
confirm_password: 'Confirm password',
password_mismatch: 'Passwords do not match',
password_min_length: 'Password must be at least 8 characters',
password_placeholder: 'Enter password',
login_btn: 'Log In',
login_failed: 'Login failed, please try again',
phone: 'Phone',
phone_placeholder: 'Enter phone number',
phone_local_placeholder: 'Enter phone number',
phone_required: 'Phone number is required',
phone_invalid: 'Invalid phone number format',
phone_country_unsupported: 'This country or region is not supported',
sms_code: 'SMS Code',
sms_code_placeholder: '6-digit code',
sms_code_required: 'Please enter the SMS code',
sms_required: 'Please request an SMS code first',
send_sms: 'Get Code',
resend_sms: 'Retry in {sec}s',
country_search: 'Search country or code',
country_not_found: 'No matching country',
forgot_password: 'Forgot password?',
forgot_password_title: 'Reset password',
reset_password_btn: 'Reset password',
reset_success: 'Password reset. Please sign in with your new password. Contact your agent if you cannot log in.',
reset_failed: 'Reset failed. Please try again.',
phone_not_registered: 'This phone number is not registered',
back_to_login: 'Back to login',
},
support: {
short: 'Support',
title: 'Customer Support',
open: 'Open customer support',
close: 'Close',
connecting: 'Connecting to support...',
url_pending: 'Support URL is not configured yet.',
},
wallet: {
balance: 'Balance',
cash_balance: 'Cash Balance',
card_holder: 'Cardholder',
unsettled: 'Unsettled',
available: 'Available',
no_records: 'No records',
tx_deposit: 'Deposit',
tx_admin_deposit: 'Admin top-up',
tx_agent_deposit: 'Agent top-up',
tx_player_deposit: 'Self deposit',
tx_player_deposit_reversal: 'Deposit reversal',
tx_withdraw: 'Withdrawal',
tx_admin_withdraw: 'Admin withdraw',
tx_agent_withdraw: 'Agent withdraw',
tx_adjust: 'Manual Adjust',
tx_bet_freeze: 'Bet Frozen',
tx_bet_deduct: 'Bet Deducted',
tx_bet_win: 'Bet Payout',
tx_bet_lose: 'Bet Settled',
tx_bet_push: 'Bet Push',
tx_bet_refund: 'Bet Refund',
tx_bet_void: 'Bet Voided',
tx_cashback: 'Cashback credit',
tx_resettle: 'Resettlement',
summary_bet: 'Bet {betNo}',
remark_deposit_revoke: 'Revoked approved deposit {orderNo}',
remark_deposit_revoke_generic: 'Revoked approved deposit',
stats_income: 'Income',
stats_expense: 'Expense',
stats_net: 'Net',
stats_cashback: 'Cashback',
filter_all: 'All',
filter_deposit: 'Deposit',
filter_withdraw: 'Withdraw',
filter_bet: 'Bet',
filter_cashback: 'Cashback',
view_all: 'View all transactions',
detail_summary: 'Details',
detail_amount: 'Amount',
detail_balance_before: 'Balance Before',
detail_balance_after: 'Balance After',
detail_frozen_before: 'Frozen Before',
detail_frozen_after: 'Frozen After',
detail_reference: 'Reference',
detail_reference_type: 'Type',
detail_reference_id: 'Reference ID',
detail_remark: 'Remark',
detail_bet_link: 'View Bet',
detail_tx_id: 'Transaction ID',
detail_not_found: 'Transaction not found',
ref_bet: 'Bet',
ref_deposit: 'Deposit',
ref_withdraw: 'Withdraw',
view_cashbacks: 'Cashback details',
view_cashbacks_detail: 'View cashback details (period/rate)',
cashback_filter_hint: 'This list shows wallet credits; see cashback details for period and rate.',
ref_cashback: 'Cashback batch',
detail_cashback_link: 'View cashback details',
},
recharge: {
title: 'Recharge',
history: 'History',
history_title: 'Recharge History',
bank_transfer: 'Bank Transfer',
bank_name: 'Bank Name',
account_holder: 'Account Holder',
account_number: 'Account Number',
usdt_address: 'USDT Address',
amount_label: 'Amount',
amount_placeholder: 'Enter recharge amount',
screenshot_label: 'Upload Screenshot',
upload_hint: 'Click to upload (max 10MB original, compressed to within 1MB)',
compressing: 'Compressing',
submit: 'Submit',
submitting: 'Submitting',
submitted: 'Recharge Submitted',
pending_review: 'Admin is reviewing, please wait',
new_recharge: 'New Recharge',
no_methods: 'No payment methods available',
select_method: 'Please select a payment method',
enter_amount: 'Please enter the amount',
upload_screenshot: 'Please upload a screenshot',
submit_failed: 'Submit failed, please retry',
file_must_be_image: 'Please upload an image file',
file_too_large: 'Original file must be 10MB or less',
compress_failed: 'Could not compress the image to within 1MB. Try a smaller screenshot.',
status_pending: 'Processing',
status_approved: 'Approved',
status_rejected: 'Rejected',
no_orders: 'No recharge records',
credited: 'Credited',
reject_reason: 'Rejection reason',
apply_time: 'Apply time',
review_time: 'Review time',
remark: 'Remark',
audit_title: 'Review history',
audit_submitted: 'Submitted',
audit_approved: 'Approved',
audit_rejected: 'Rejected',
audit_revoked: 'Approval revoked',
audit_reopened: 'Reopened for review',
audit_by_player: 'Player',
audit_by_admin: 'Platform review',
audit_amount: 'Amount',
audit_credited: 'Credited amount',
audit_remark_label: 'Note',
audit_summary: 'Review history · {count} steps',
audit_toggle_show: 'Show review history',
audit_toggle_hide: 'Hide review history',
view_detail: 'View details',
order_detail: 'Order details',
reapply: 'Re-apply',
reapply_hint: 'You are resubmitting this order. Transfer again and upload a new screenshot.',
back_to_history: 'Back to history',
},
cashback: {
title: 'Cashback Details',
list_title: 'Payout details',
total_received: 'Total cashback',
record_count: '{n} record(s)',
period: 'Period',
effective_stake: 'Effective stake',
bet_count: '{n} bet(s)',
empty: 'No cashback records yet',
empty_hint: 'Cashback is issued by the platform after each settlement period.',
ledger_hint: 'Matches wallet entries under the Cashback filter; amounts are the same.',
},
bet: {
bet_slip: 'Bet Slip',
stake: 'Stake',
place_bet: 'Place Bet',
place_bet_short: 'Bet',
parlay: 'Parlay',
tab_matches: 'Matches',
tab_outright: 'Outright',
tab_today: 'Today',
tab_early: 'Early',
filter_status_all: 'All',
filter_status_open: 'Open',
filter_status_settled: 'Settled',
filter_leagues_all: 'All Leagues',
status_open: 'Open',
status_live: 'Live',
match_unit: 'matches',
show_open_only: 'Open only',
show_all_matches: 'Show all',
today: 'Today',
loading: 'Loading…',
no_matches: 'No matches',
outright_coming: 'Outright markets coming soon',
outright_enter_stake: 'Enter stake',
outright_balance: 'Balance',
outright_stake_amount: 'Stake',
outright_success: 'Bet placed',
outright_done: 'Done',
outright_bet_failed: 'Bet failed',
outright_insufficient: 'Insufficient balance',
stake_label: 'Stake',
stake_placeholder: 'Enter amount',
stake_max: 'Max',
placing: 'Placing…',
no_outright: 'No outright markets',
no_outright_hint: 'Sign in as a player. If empty, ask admin to publish outright events.',
outright_events_summary: '{events} outright events · {teams} teams',
outright_teams_count: '{n} teams',
outright_load_failed: 'Failed to load outright markets',
outright_player_only: 'Player login required',
outright_shown_count: '{shown} / {total} teams shown',
outright_load_more: 'Load more',
cancel: 'Cancel',
parlay_max_legs: 'Parlay allows up to 5 legs',
parlay_block_outright: 'Outright cannot be parlayed',
parlay_block_quarter: 'Quarter-ball HDP/O-U cannot be parlayed',
parlay_block_not_allowed: 'This market cannot be parlayed',
parlay_need_more: 'Select at least 2 legs for parlay',
market_status_suspended: 'Suspended',
market_status_closed: 'Closed',
back: 'Back',
refresh: 'Refresh',
download: 'Download',
reward_active: 'Reward active!',
market_closed: 'Not open',
match_phase_closed_pending: 'Closed pending',
match_phase_settled: 'Settled',
view_match: 'View match',
expand_market: 'Expand',
collapse_market: 'Collapse',
market_cs: 'Correct Score',
market_ht_cs: '1H Correct Score',
market_sh_cs: '2H Correct Score',
market_ft_handicap: 'FT Handicap',
market_ft_ou: 'FT O/U',
market_ft_1x2: 'FT 1X2',
market_ft_oe: 'FT Odd/Even',
market_ht_handicap: 'HT Handicap',
market_ht_ou: 'HT O/U',
market_ht_1x2: 'HT 1X2',
parlay_sel_home: 'H',
parlay_sel_away: 'A',
parlay_sel_draw: 'D',
parlay_sel_over: 'O',
parlay_sel_under: 'U',
parlay_sel_odd: 'Odd',
parlay_sel_even: 'Even',
cs_other_home: 'Home win (other score)',
cs_other_draw: 'Draw (other score)',
cs_other_away: 'Away win (other score)',
col_home: 'Home',
col_draw: 'Draw',
col_away: 'Away',
cs_stake_required: 'Select at least one score',
cs_confirm_title: 'Confirm correct score bets',
cs_confirm_count: '{n} bet(s)',
cs_confirm_total_stake: 'Total stake',
cs_place_success: 'Bet placed',
cs_place_failed: 'Bet failed',
kickoff_time: 'Kickoff: ',
result_stats_title: 'Match facts',
result_ht: 'HT',
result_ft: 'FT',
result_corners: 'Corners',
result_yellow_cards: 'Yellow',
result_red_cards: 'Red',
guide_title: 'How to bet',
guide_help_aria: 'Betting help',
guide_got_it: 'Got it',
guide_flow_normal: 'Handicap / O-U / 1X2 etc.',
guide_normal_1: 'All markets are shown by default',
guide_normal_2: 'Tap any odds to open the bet drawer',
guide_normal_3: 'Enter stake in the drawer, then place a single bet or add it to parlay',
guide_flow_cs: 'Correct score',
guide_cs_1: 'Tap the score you want in the score table',
guide_cs_2: 'The bet drawer opens so you can enter stake and submit',
guide_cs_3: 'Score picks are single bets and can also be added to parlay',
guide_flow_parlay: 'Parlay (25 legs)',
guide_parlay_1: 'Tap any odds to open the drawer, then tap Add to parlay to put the current selection into your parlay slip.',
guide_rules_link: 'Full rules: Profile → Betting Rules.',
mode_cs_tag: 'Bet here',
mode_slip_tag: 'Add to slip',
cs_confirm_btn: 'Confirm bet',
cs_confirm_cell: 'Place order',
cs_panel_hint: 'Enter stakes below, then tap Confirm bet above',
slip_panel_hint: 'Tap odds to add; use the bottom bar when done',
slip_pick_hint: 'Tap to add/remove from slip; gold border = selected',
picked_tag: 'Selected',
pick_added: 'Added to bet slip',
pick_removed: 'Removed from bet slip',
slip_bar_ready: '1 selection',
slip_bar_go: 'Bet slip',
cs_top_hint: '① Enter stake ② Tap Confirm bet above',
slip_empty_hint: 'Tap odds to open the bet drawer',
slip_remove: 'Remove',
slip_est_return: 'Est. max payout',
slip_parlay_odds: 'Combined odds {odds}',
slip_review_title: 'Review selection',
slip_balance: 'Account balance',
slip_tab_single: 'Single',
slip_tab_parlay: 'Parlay',
slip_parlay_empty_hint: 'Pick a selection, then tap Add to parlay',
slip_add_parlay: 'Add to parlay',
slip_parlay_only_hint: 'This market is parlay-only. Tap Add to parlay to bet.',
slip_parlay_same_match: 'Parlay selections cannot be from the same match. Remove the same-match leg first.',
slip_parlay_count: '{n} parlay leg(s)',
slip_total_stake: 'Total stake',
slip_currency: 'Amount',
slip_min: 'Min',
slip_min_error: 'Minimum stake is {amount}',
odds_changed: 'Odds have changed on some selections. Accept to continue.',
odds_suspended: 'Some selections are suspended or closed. Remove them to continue.',
accept_changes_place: 'Accept changes & place bet',
odds_was: 'Was',
odds_now: 'Now',
place_success: 'Bet placed',
place_failed: 'Bet failed',
},
profile: {
edit: 'Edit Profile',
language: 'Language',
avatar: 'Avatar',
avatar_change: 'Change avatar',
avatar_confirm: 'Confirm',
section_contact: 'Contact',
section_account: 'Account',
change_password: 'Change password',
show_password: 'Show',
hide_password: 'Hide',
password_unavailable: '••••••••',
password_unavailable_hint: 'Password not available; contact support to reset',
section_password: 'Change password (optional)',
avatar_hint: 'Choose from built-in player portraits',
avatar_search: 'Search player, position or country',
avatar_empty: 'No players found',
phone: 'Phone',
email: 'Email',
phone_placeholder: 'Phone number',
email_placeholder: 'Email address',
save: 'Save',
password_optional_hint: 'Leave password fields blank to keep current password',
old_password_placeholder: 'Leave blank to skip',
new_password_placeholder: 'Leave blank to skip',
confirm_password_placeholder: 'Leave blank to skip',
old_password: 'Current password',
new_password: 'New password',
confirm_password: 'Confirm password',
back: 'Back',
saved: 'Contact saved',
save_failed: 'Save failed',
password_changed: 'Password updated',
password_failed: 'Password change failed',
password_mismatch: 'Passwords do not match',
password_incomplete: 'Fill current, new and confirm password to change password',
username_placeholder: 'Login username',
username_readonly_hint: 'Username is managed by admin; contact support to change',
username_updated: 'Username updated',
password_disabled: 'Password change is disabled for this account; contact support',
rules_title: 'Betting Rules',
rules_p1: 'Football pre-match only in v1. No live betting, Cash Out, bet edits, or system parlays.',
rules_p2: 'Parlays: 25 legs, with at most one selection per match. Outright and quarter-ball HDP/O-U are excluded.',
rules_p3: 'Results use admin-entered half-time and full-time scores; payouts apply after settlement preview is confirmed.',
rules_p4: 'If this text conflicts with site notices, the latest notice and market rules prevail.',
rules_p5: 'How to bet: open any match, tap the ? icon on the top right.',
},
} as const;