Files
CloudHome-Ops/lib/utils/i10n.dart

667 lines
39 KiB
Dart
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.

import 'package:flutter/widgets.dart';
import '../providers/locale_provider.dart';
/// 轻量级国际化助手。
///
/// 覆盖底部导航、首页、设备、门店、管理、设置、激活码、用户、公司介绍等
/// 高频界面文案。后续业务模块继续在此补充。
///
/// 用法:
/// ```dart
/// final t = AppLocalizations.of(context);
/// Text(t.home);
/// ```
class AppLocalizations {
AppLocalizations(this._locale);
final AppLocale _locale;
static AppLocalizations of(BuildContext context) {
final locale = Localizations.of<AppLocale>(context, AppLocale);
return AppLocalizations(locale ?? AppLocale.zh);
}
String _pick(String zh, String en) => _locale == AppLocale.en ? en : zh;
/// 当前是否为英文模式。
bool get isEnglish => _locale == AppLocale.en;
// ============ 底部导航 ============
String get home => _pick('首页', 'Home');
String get devices => _pick('设备', 'Devices');
String get stores => _pick('门店', 'Stores');
String get admin => _pick('管理', 'Admin');
String get profile => _pick('我的', 'Profile');
// ============ 设置 ============
String get orientationMode => _pick('显示方向', 'Display Orientation');
String get orientationSystem => _pick('跟随系统', 'System');
String get orientationPortrait => _pick('竖屏', 'Portrait');
String get orientationLandscape => _pick('横屏', 'Landscape');
// ============ 首页 ============
/// AppBar / 顶部栏大标题。
String get appTitle => _pick('云定制主页运营平台', '云定制主页运营平台');
/// 首页品牌横幅 / 登录页主标题。
String get appHeroTitle => _pick('云定制主页运营助手', '云定制主页运营助手');
/// 登录页副标题。
String get appSubtitle => _pick('Mobile Management', 'Mobile Management');
String get totalDevices => _pick('设备总数', 'Total Devices');
String get totalStores => _pick('门店总数', 'Total Stores');
String get onlineDevices => _pick('在线设备', 'Online Devices');
String get offlineDevices => _pick('离线设备', 'Offline Devices');
String get quickActions => _pick('快捷操作', 'Quick Actions');
String get systemManagement => _pick('系统管理', 'System Management');
String get mediaManagement => _pick('媒资管理', 'Media Management');
// ============ 通用 ============
String get loading => _pick('加载中…', 'Loading…');
String get retry => _pick('重试', 'Retry');
String get save => _pick('保存', 'Save');
String get cancel => _pick('取消', 'Cancel');
String get confirm => _pick('确认', 'Confirm');
String get reset => _pick('重置', 'Reset');
String get edit => _pick('编辑', 'Edit');
String get delete => _pick('删除', 'Delete');
String get add => _pick('新增', 'Add');
String get search => _pick('搜索', 'Search');
String get back => _pick('返回', 'Back');
String get yes => _pick('是', 'Yes');
String get no => _pick('否', 'No');
String get unknown => _pick('未知', 'Unknown');
String get none => _pick('无', 'None');
String get notGrouped => _pick('未分组', 'Not Grouped');
String get all => _pick('全部', 'All');
String get noData => _pick('暂无数据', 'No data');
String get noMoreData => _pick('没有更多数据', 'No more data');
String get saved => _pick('保存成功', 'Saved');
String get saveFailed => _pick('保存失败', 'Save failed');
String get deleted => _pick('删除成功', 'Deleted');
String get deleteFailed => _pick('删除失败', 'Delete failed');
String get copied => _pick('已复制', 'Copied');
String get pleaseSelect => _pick('请选择', 'Please select');
// ============ 设置页 ============
String get settings => _pick('设置', 'Settings');
String get themeMode => _pick('主题模式', 'Theme');
String get language => _pick('语言', 'Language');
String get changePassword => _pick('修改密码', 'Change Password');
String get about => _pick('关于', 'About');
String get logout => _pick('退出登录', 'Log Out');
String get account => _pick('账号', 'Account');
String get themeDark => _pick('深色', 'Dark');
String get themeLight => _pick('浅色', 'Light');
String get themeSystem => _pick('跟随系统', 'System');
String get passwordDialogTitle => _pick('修改登录密码', 'Change Login Password');
String get oldPassword => _pick('原密码', 'Old Password');
String get newPassword => _pick('新密码', 'New Password');
String get confirmNewPassword => _pick('确认新密码', 'Confirm New Password');
String get pleaseFillPassword =>
_pick('请填写原密码和新密码', 'Please fill in old and new passwords');
String get passwordsDoNotMatch =>
_pick('两次输入的新密码不一致', 'New passwords do not match');
String get passwordChangeSuccess =>
_pick('密码修改成功,请重新登录', 'Password changed, please log in again');
String passwordChangeFailed(String error) =>
_pick('修改失败:$error', 'Change failed: $error');
// ============ 管理页菜单 ============
String get deviceManagement => _pick('设备管理', 'Device Management');
String get activationCode => _pick('激活码', 'Activation Code');
String get deviceLimit => _pick('设备上限', 'Device Limit');
String get units => _pick('台', 'Units');
String get storeConfig => _pick('门店配置', 'Store Config');
String get userManagement => _pick('用户管理', 'User Management');
String get companyIntro => _pick('公司介绍', 'Company Intro');
// ============ 设备管理 ============
String get deviceList => _pick('设备列表', 'Device List');
String get deviceDetails => _pick('设备详情', 'Device Details');
String get searchDeviceHint => _pick('搜索设备MAC / 房号', 'Search MAC / room number');
String get searchModelHint => _pick('型号', 'Model');
String get scanQueryDevice => _pick('扫码查询设备', 'Scan to Query');
String get scanActivateDevice => _pick('扫码激活新设备', 'Scan to Activate');
String get scanBindDevice => _pick('扫码绑定设备', 'Scan to Bind');
String get scanTitleActivate => _pick('扫码激活新设备', 'Scan to Activate Device');
String get scanTitleBind => _pick('扫码绑定设备', 'Scan to Bind Device');
String get scanTitleQuery => _pick('扫码查询设备', 'Scan to Query Device');
String get scanHintActivate => _pick('将新设备二维码放入框内以激活',
'Place the new device QR code in the frame to activate');
String get scanHintBind => _pick('将二维码放入框内以绑定设备',
'Place the QR code in the frame to bind the device');
String get scanHintQuery => _pick('将设备二维码放入框内以查询',
'Place the device QR code in the frame to query');
String get cameraPermissionDenied => _pick('未获得相机权限', 'Camera permission denied');
String get cameraPermissionDeniedHint =>
_pick('请在系统设置中开启后重试',
'Please enable camera permission in system settings and try again');
String get cameraInitializing => _pick('正在初始化相机…', 'Initializing camera…');
String get cameraUnavailable => _pick('相机不可用', 'Camera unavailable');
String cameraOpenFailed(String code) =>
_pick('相机打开失败:$code', 'Failed to open camera: $code');
String get scanConfirmActivateTitle => _pick('确认激活设备', 'Confirm Device Activation');
String get scanConfirmBindTitle => _pick('确认绑定', 'Confirm Binding');
String scanConfirmContent(String storeName, String groupId, String payload) =>
_pick(
'将设备绑定到门店「$storeName」'
'${groupId.isNotEmpty ? ' / 分组 $groupId' : ''}?\n\n'
'二维码内容:$payload',
'Bind device to store "$storeName"'
'${groupId.isNotEmpty ? ' / Group $groupId' : ''}?\n\n'
'QR code content: $payload',
);
String get scanActivate => _pick('激活', 'Activate');
String get scanBind => _pick('绑定', 'Bind');
String get scanDeviceNotFound => _pick('未找到设备,请确认二维码内容',
'Device not found, please check the QR code content');
String get scanPayloadUnrecognized => _pick(
'无法识别该二维码,请扫描设备二维码或确认二维码内容',
'Unrecognized QR code. Please scan a device QR code');
String scanDeviceNotReady(String identifier) => _pick(
'未找到对应设备($identifier)。设备可能尚未联网或同步,请确认设备已开机联网、已激活并归属当前账号后重试',
'No matching device found ($identifier). The device may not be online or synced yet. Please confirm it is powered on, connected, activated and assigned to this account, then retry');
String scanQueryFailed(String error) =>
_pick('查询失败:$error', 'Query failed: $error');
String scanLoadStoresFailed(String error) =>
_pick('加载门店失败:$error', 'Failed to load stores: $error');
String get scanNoStores => _pick('暂无可选门店,请先在门店管理中创建',
'No stores available. Please create one in Store Management first');
String get scanSelectStoreTitle => _pick('选择目标门店', 'Select Target Store');
String get scanActivateSuccess => _pick('设备已激活', 'Device activated');
String get scanBindSuccess => _pick('设备已绑定', 'Device bound');
String get scanPayloadNoMac =>
_pick('未能从二维码中识别到 MAC 地址,请检查二维码内容',
'Could not find MAC address in QR code');
String scanLoadGroupsFailed(String error) =>
_pick('加载分组失败:$error', 'Failed to load groups: $error');
String scanNoGroups(String storeName) =>
_pick('门店「$storeName」暂无设备分组,请先在设备分组中创建',
'Store "$storeName" has no device groups. Please create one first');
String get scanSelectGroupTitle => _pick('选择目标分组', 'Select Target Group');
String scanBindFailed(String error) =>
_pick('绑定失败:$error', 'Binding failed: $error');
// ============ 扫码绑定表单(页面内表单) ============
String get scanGroupLabel => _pick('门店分组', 'Store Group');
String get scanStoreRequired => _pick('请先选择门店', 'Please select a store first');
String get scanGroupRequired => _pick('请选择门店分组', 'Please select a store group');
String get scanRoomRequired => _pick('请输入房号', 'Please enter room number');
String get scanRoomInvalid => _pick(
'房号格式不正确(仅限中英文、数字、连字符、斜杠,长度 1-20)',
'Invalid room number (letters/digits/hyphen/slash only, 1-20 chars)');
// 房号改为选填:标签与提示都标明「选填」,避免用户误以为必填。
String get roomNoOptional => _pick('房号(选填)', 'Room Number (optional)');
String get scanRoomHint => _pick('选填,如 801、A101、3楼', 'Optional, e.g. 801, A101, 3rd floor');
String get scanRescan => _pick('重新扫码', 'Scan Again');
String get scanFormInvalid =>
_pick('请完善门店与门店分组后再提交', 'Please complete store and store group');
String get scanFormDeviceTitle => _pick('已识别设备', 'Recognized Device');
String get sendCommand => _pick('下发指令', 'Send Command');
String get editGroup => _pick('修改分组', 'Edit Group');
String get macAddress => _pick('MAC 地址', 'MAC Address');
String get ipAddress => _pick('IP 地址', 'IP Address');
String get belongStore => _pick('所属门店', 'Store');
String get belongGroup => _pick('所属分组', 'Group');
String get roomNo => _pick('房号', 'Room No.');
String deviceModel(String model) => _pick('型号:$model', 'Model: $model');
String deviceSubtitleStore(String name) => _pick('门店:$name', 'Store: $name');
String deviceSubtitleMac(String mac) => _pick('MAC:$mac', 'MAC: $mac');
String deviceSubtitleRoom(String room) => _pick('房号:$room', 'Room: $room');
String get deviceSubtitleNotSet => _pick('未设置', 'Not set');
String get location => _pick('位置', 'Location');
String get operatingSystem => _pick('操作系统', 'OS');
String get uptime => _pick('运行时长', 'Uptime');
// ============ 设备详情区块 ============
String get basicInfo => _pick('基本信息', 'Basic Info');
String get configParams => _pick('配置参数', 'Config Params');
String get networkInfo => _pick('网络信息', 'Network Info');
String get runtimeData => _pick('运行时数据', 'Runtime Data');
String get deviceName => _pick('设备名称', 'Device Name');
String get deviceId => _pick('设备 ID', 'Device ID');
String get modelLabel => _pick('型号', 'Model');
String get deviceSnLabel => _pick('设备序列号', 'Device SN');
String get deviceUidLabel => _pick('设备 UID', 'Device UID');
String get lastActiveTime => _pick('最后活跃时间', 'Last Active Time');
String get minutesAgo => _pick('分钟前', 'min ago');
String get cpuUsage => _pick('CPU 使用率', 'CPU Usage');
String get memoryUsage => _pick('内存使用率', 'Memory Usage');
String get diskUsage => _pick('磁盘使用率', 'Disk Usage');
String get networkRxTx => _pick('网络(收/发)', 'Network (Rx/Tx)');
String get showRuntimeMetrics => _pick('显示运行指标', 'Show Runtime Metrics');
String get showRuntimeMetricsHint =>
_pick('开启后在设备详情页展示 CPU、内存、磁盘、网络指标',
'Show CPU, memory, disk and network metrics on device detail');
String deviceListLoadFailed(String error) =>
_pick('设备列表加载失败:$error', 'Failed to load device list: $error');
String get noMatchedDevices => _pick('没有匹配的设备', 'No matched devices');
String get allStores => _pick('全部门店', 'All Stores');
String get selectStore => _pick('选择门店', 'Select Store');
String get groupId => _pick('所属分组 ID', 'Group ID');
String get groupIdHint => _pick('填写设备分组标识,如 g-core',
'Enter device group identifier, e.g. g-core');
String get saveSuccess => _pick('已保存', 'Saved successfully');
String get groupListLoading => _pick('加载分组列表…', 'Loading groups…');
// ============ 设备状态 ============
String get statusOnline => _pick('在线', 'Online');
String get statusOffline => _pick('离线', 'Offline');
String get statusWarning => _pick('告警', 'Warning');
String get statusNormal => _pick('正常', 'Normal');
String get statusDisabled => _pick('禁用', 'Disabled');
String deviceStatusLabel(DeviceStatusKey status) {
switch (status) {
case DeviceStatusKey.online:
return statusOnline;
case DeviceStatusKey.offline:
return statusOffline;
case DeviceStatusKey.warning:
return statusWarning;
}
}
// ============ 指令下发 ============
String get sendCommandTitle => _pick('下发指令', 'Send Command');
String get sendOrgCommandTitle => _pick('下发门店指令', 'Send Store Command');
String get commandType => _pick('指令类型', 'Command Type');
String get commandConfirmTitle => _pick('确认下发', 'Confirm Send');
String commandConfirmContent(String label) =>
_pick('确定要向该设备下发「$label」指令吗?',
'Are you sure you want to send the "$label" command?');
String commandSent(String target, String label) =>
_pick('已向$target下发「$label」指令(后端已接收,不代表设备已执行)',
'Command "$label" sent to $target (accepted by server, not yet confirmed by device)');
String get commandSendFailed => _pick('指令下发失败', 'Failed to send command');
String get pleaseInput => _pick('请输入', 'Please enter');
String get volumeRangeHint => _pick('请输入 0~100 的整数音量',
'Please enter an integer volume between 0 and 100');
String get maxVolume => _pick('最大音量', 'Max Volume');
String get commandOfflineWarning =>
_pick('该设备当前离线(或心跳已超时),指令可能不会立即生效;设备重新上报心跳后才会执行。',
'This device is offline (or its heartbeat timed out). The command may not take effect immediately; it will run after the device reconnects.');
String get commandOfflineConfirm => _pick('仍然下发', 'Send Anyway');
String get commandMacMissing =>
_pick('该设备缺少 MAC 地址,无法按 MAC 下发指令,请改用门店批量下发。',
'This device has no MAC address, so a MAC-targeted command cannot be sent. Use store-level delivery instead.');
String deviceCommandLabel(String cmd) {
return _pick(
const {
'powerOff': '关机',
'reboot': '重启',
'screenshot': '截屏',
'themeUpdate': '主题更新',
'versionUpdate': '版本更新',
'marqueeUpdate': '滚动字幕更新',
'weatherUpdate': '更新天气信息',
'mediaZoneVol': '媒体区域音量',
'defaultVol': '默认音量',
'themeClear': '清除主题缓存',
'cacheClear': '清除缓存',
'storeExpire': '门店到期',
'storeDisable': '门店禁用',
'passwordUpdate': '修改设置密码',
'worldAd': '获取世界广告',
}[cmd] ??
cmd,
const {
'powerOff': 'Power Off',
'reboot': 'Reboot',
'screenshot': 'Screenshot',
'themeUpdate': 'Theme Update',
'versionUpdate': 'Version Update',
'marqueeUpdate': 'Marquee Update',
'weatherUpdate': 'Update Weather',
'mediaZoneVol': 'Media Zone Volume',
'defaultVol': 'Default Volume',
'themeClear': 'Clear Theme Cache',
'cacheClear': 'Clear Cache',
'storeExpire': 'Store Expired',
'storeDisable': 'Store Disabled',
'passwordUpdate': 'Change Settings Password',
'worldAd': 'Fetch World Ads',
}[cmd] ??
cmd,
);
}
String deviceCommandInputLabel(String cmd) {
if (cmd == 'passwordUpdate') return _pick('新密码', 'New Password');
return _pick('音量(0-100)', 'Volume (0-100)');
}
// ============ 门店管理 ============
String get storeManagement => _pick('门店管理', 'Store Management');
String get storeCommands => _pick('门店指令', 'Store Commands');
String get searchStoreHint => _pick('搜索门店名称', 'Search store name');
String get storeDeleteConfirmTitle => _pick('删除门店', 'Delete Store');
String storeDeleteConfirmContent(String name) =>
_pick('确定要删除门店「$name」吗?', 'Are you sure you want to delete store "$name"?');
String get storeDeleted => _pick('门店已删除', 'Store deleted');
String get loadFailed => _pick('加载失败', 'Load failed');
String get storeId => _pick('门店ID', 'Store ID');
String get address => _pick('地址', 'Address');
String get contactPhone => _pick('联系电话', 'Contact Phone');
String get expireTime => _pick('到期时间', 'Expire Time');
String get expired => _pick('已过期', 'Expired');
String get noExpireTime => _pick('无到期时间', 'No expire date');
String get createTime => _pick('创建时间', 'Create Time');
String get storeName => _pick('门店名称', 'Store Name');
String get storeNameRequired => _pick('请输入门店名称', 'Please enter store name');
String get region => _pick('所在地区', 'Region');
String get regionHint => _pick('请选择省 / 市 / 区', 'Please select province / city / district');
String get addressDetail => _pick('详细地址', 'Detailed Address');
String get addressDetailHint => _pick('街道 / 门牌号等', 'Street / house number');
String get interfaceConfig => _pick('界面配置', 'Interface Config');
String get themeSkin => _pick('主题皮肤', 'Theme Skin');
String get themeCurrent => _pick('当前', 'Current');
String get themeUnnamed => _pick('未命名主题', 'Unnamed Theme');
String get noInterfaceConfig => _pick('当前门店暂无设备分组主题',
'No device group themes for this store');
String get editStore => _pick('编辑门店', 'Edit Store');
String get addStore => _pick('新增门店', 'Add Store');
String get create => _pick('创建', 'Create');
String get sampleStore => _pick('示例门店', 'Sample Store');
String get parentOrg => _pick('所属组织', 'Parent Organization');
String get parentOrgRequired => _pick('请选择所属组织', 'Please select parent organization');
String get regionRequired => _pick('请选择所在地区', 'Please select region');
String get storeUpdatedPlaceholder => _pick('门店已更新(本地占位)',
'Store updated (local placeholder)');
String get storeCreatedPlaceholder => _pick('门店已创建(本地占位)',
'Store created (local placeholder)');
// ============ 激活码管理 ============
String get activationCodeManagement => _pick('激活码管理', 'Activation Code Management');
String get noStoreAvailable => _pick('暂无可选门店', 'No stores available');
String get pleaseSelectStoreFirst => _pick('请先选择门店', 'Please select a store first');
String get currentActivationCode => _pick('当前激活码', 'Current Activation Code');
String get noActivationCode => _pick('暂无激活码信息', 'No activation code info');
String get generateActivationCode => _pick('生成激活码', 'Generate Activation Code');
String get resetActivationCode => _pick('重置激活码', 'Reset Activation Code');
String get resetActivationCodeConfirm => _pick('重置后原激活码将失效,确定要继续吗?',
'The original code will become invalid after reset. Continue?');
String get activationCodeGenerated => _pick('激活码已生成', 'Activation code generated');
String get activationCodeReset => _pick('激活码已重置', 'Activation code reset');
String get generateFailed => _pick('生成失败', 'Generate failed');
String get resetFailed => _pick('重置失败', 'Reset failed');
String get activationCodeResetSuccess =>
_pick('激活码已重置', 'Activation code reset');
String activationCodeResetFailed(String error) =>
_pick('激活码重置失败:$error', 'Activation code reset failed: $error');
String get maxActivateCount => _pick('最大激活数', 'Max Activations');
String get activatedCount => _pick('已激活数', 'Activated Count');
String get copy => _pick('复制', 'Copy');
String get generate => _pick('生成', 'Generate');
String get activationCodeCopied => _pick('激活码已复制', 'Activation code copied');
String get generateActivationCodeHint => _pick(
'将为当前门店生成新的激活码,原有激活码将被替换。',
'A new activation code will be generated for this store, replacing the existing one.');
String activationCodeLoadFailed(String error) =>
_pick('激活码加载失败:$error', 'Failed to load activation code: $error');
String generateFailedWithError(String error) =>
_pick('生成失败:$error', 'Generate failed: $error');
String get activationCodeNoCodeHint => _pick('无激活码,请点击「生成激活码」',
'No activation code, please tap "Generate Activation Code"');
String get maxActivationCountLabel => _pick('最大激活次数', 'Max Activation Count');
String get maxActivationCountHint => _pick('该激活码最多可激活的设备数量',
'Maximum number of devices this code can activate');
String get positiveIntegerRequired => _pick('请输入大于 0 的整数',
'Please enter an integer greater than 0');
// 门店表单中的激活码/终端数
String get terminalCountLabel => _pick('终端数', 'Terminal Count');
String get terminalCountHint => _pick('该门店允许激活的终端数量', 'Number of terminals allowed');
String get maxTerminalCount => _pick('最大终端数', 'Max Terminals');
String get usedTerminalCount => _pick('已用终端数', 'Used Terminals');
String get createActivationCode => _pick('创建激活码', 'Create Activation Code');
String get activationCodeWillAutoGenerate => _pick('保存门店后将自动生成激活码',
'Activation code will be auto-generated after saving the store');
String get activeActivationCode => _pick('当前激活码', 'Current Activation Code');
String get noActiveActivationCode => _pick('暂无正在使用的激活码',
'No activation code currently in use');
String get activationCodeGenerateHint => _pick('每次点击仅生成一个对应激活码',
'Each tap generates one activation code');
String storeSavedActivationFailed(String error) =>
_pick('门店已保存,但激活码生成失败:$error',
'Store saved, but activation code generation failed: $error');
String storeListLoadFailed(String error) =>
_pick('门店列表加载失败:$error', 'Failed to load store list: $error');
// ============ 用户管理 ============
String get username => _pick('用户名', 'Username');
String get usernameRequired => _pick('请输入用户名', 'Please enter username');
String get email => _pick('邮箱', 'Email');
String get mobile => _pick('手机号', 'Mobile');
String get password => _pick('密码', 'Password');
String get passwordEditHint => _pick('不修改请留空', 'Leave blank to keep unchanged');
String get passwordRequired => _pick('请输入密码', 'Please enter password');
String get confirmPassword => _pick('确认密码', 'Confirm Password');
String get confirmPasswordHint => _pick('请再次输入密码', 'Please enter the password again');
String get confirmPasswordRequired => _pick('请输入确认密码', 'Please enter confirm password');
String get role => _pick('角色', 'Role');
String get roleRequired => _pick('请选择角色', 'Please select a role');
String get org => _pick('所属组织', 'Organization');
String get selectOrg => _pick('请选择所属组织', 'Please select an organization');
String get noOrgHint => _pick('暂无可选组织,保留原归属',
'No organizations available, keep original');
String get status => _pick('状态', 'Status');
String get unassigned => _pick('未分配', 'Unassigned');
String get searchUsernameHint => _pick('搜索用户名', 'Search username');
String get searchOrgHint => _pick('搜索组织名称', 'Search organization name');
String get noMatchingOrg => _pick('未找到匹配组织', 'No matching organization');
String get roleLabel => _pick('角色', 'Role');
String get orgLabel => _pick('所属组织', 'Organization');
String get currentAccountInfo => _pick('当前账号信息', 'Current Account Info');
String get passwordNotSaved => _pick('未保存', 'Not saved');
String get noSubordinateAccount =>
_pick('当前账号暂无下级账号', 'No subordinate accounts');
String get showPassword => _pick('显示密码', 'Show password');
String get hidePassword => _pick('隐藏密码', 'Hide password');
String get editUser => _pick('编辑用户', 'Edit User');
String get addUser => _pick('新增用户', 'Add User');
String get deleteUserConfirmTitle => _pick('确认删除', 'Confirm Delete');
String deleteUserConfirmContent(String name) =>
_pick('确定要删除用户「$name」吗?', 'Are you sure you want to delete user "$name"?');
String get rolesLoadFailed => _pick('角色列表加载失败', 'Failed to load roles');
// ============ 滚动字幕管理 ============
String get marqueeManagement => _pick('滚动字幕管理', 'Scrolling Subtitle Management');
String get addMarquee => _pick('新增滚动字幕', 'Add Scrolling Subtitle');
String get editMarquee => _pick('编辑滚动字幕', 'Edit Scrolling Subtitle');
String get marqueeContent => _pick('字幕内容', 'Subtitle Content');
String get marqueeContentRequired => _pick('请输入字幕内容', 'Please enter subtitle content');
String get marqueeSpeed => _pick('滚动速度', 'Scroll Speed');
String get marqueeSpeedHint => _pick('像素/秒,建议 30~120', 'pixels/sec, recommended 30-120');
String get marqueeSpeedInvalid => _pick('请选择滚动速度', 'Please select scroll speed');
String get marqueeFontSizeInvalid => _pick('请输入大于 0 的字体大小', 'Please enter a font size greater than 0');
String get marqueeSpeedSlow => _pick('慢', 'Slow');
String get marqueeSpeedSlower => _pick('较慢', 'Slower');
String get marqueeSpeedMedium => _pick('中', 'Medium');
String get marqueeSpeedFaster => _pick('较快', 'Faster');
String get marqueeSpeedFast => _pick('快', 'Fast');
String get marqueeGradeDanger => _pick('危险', 'Danger');
String get marqueeGradeUrgent => _pick('紧急', 'Urgent');
String get marqueeGradeNormal => _pick('普通', 'Normal');
String get targetStore => _pick('目标门店', 'Target Store');
String get filterByStore => _pick('按门店筛选', 'Filter by Store');
String get searchMarqueeHint => _pick('搜索字幕内容或门店', 'Search subtitle content or store');
String get noMarqueeData => _pick('暂无滚动字幕', 'No scrolling subtitles');
String get marqueeStatus => _pick('状态', 'Status');
String get marqueeStatusEnabled => _pick('启用', 'Enabled');
String get marqueeStatusDisabled => _pick('禁用', 'Disabled');
String get marqueeStatusPending => _pick('待下发', 'Pending');
String get marqueeStatusDispatched => _pick('已下发', 'Dispatched');
String get dispatch => _pick('下发', 'Dispatch');
String get cancelDispatch => _pick('取消下发', 'Cancel Dispatch');
String get marqueeDispatched => _pick('字幕已下发', 'Subtitle dispatched');
String get marqueeDispatchFailed => _pick('字幕下发失败', 'Failed to dispatch subtitle');
String get marqueeDispatchCancelled => _pick('已取消下发', 'Dispatch cancelled');
String get marqueeCancelFailed => _pick('取消下发失败', 'Failed to cancel dispatch');
String get marqueeFontColor => _pick('字体颜色', 'Font Color');
String get marqueeBackgroundColor => _pick('背景颜色', 'Background Color');
String get marqueeFontSize => _pick('字体大小', 'Font Size');
String get marqueeLevel => _pick('级别', 'Level');
String get marqueeStartTime => _pick('开始时间', 'Start Time');
String get marqueeEndTime => _pick('结束时间', 'End Time');
String get marqueeHour => _pick('时', 'Hour');
String get marqueeMinute => _pick('分', 'Minute');
String get marqueeSecond => _pick('秒', 'Second');
String get marqueeContentPreview => _pick('字幕内容', 'Subtitle Content');
// ============ 公司介绍 ============
String get introCategoryTitle => _pick('公司介绍', 'Company Intro');
String get introStoreFilter => _pick('门店名称', 'Store Name');
String get introAllStores => _pick('全部门店', 'All Stores');
String get introCategoryName => _pick('名称', 'Name');
String get introCategoryTypeCode => _pick('类型编码', 'Type Code');
String get introCategoryEdit => _pick('编辑大类', 'Edit Category');
String get introCategoryAdd => _pick('新增大类', 'Add Category');
String get introSubcategoryEdit => _pick('编辑小类', 'Edit Subcategory');
String get introSubcategoryAdd => _pick('新增小类', 'Add Subcategory');
String get introDetailEdit => _pick('编辑内容', 'Edit Content');
String get introDetailAdd => _pick('新增内容', 'Add Content');
String get introTitle => _pick('标题', 'Title');
String get introTitleRequired => _pick('请输入标题', 'Please enter the title');
String get introDescription => _pick('描述', 'Description');
String get introMediaType => _pick('媒体类型', 'Media Type');
String get introMediaUrl => _pick('媒体地址', 'Media URL');
String get introMediaUrlRequired =>
_pick('请上传或填写媒体地址', 'Please upload or enter the media URL');
String get introImage => _pick('图片', 'Image');
String get introVideo => _pick('视频', 'Video');
String get introTypeLabel => _pick('类型', 'Type');
String get introStoreLabel => _pick('门店', 'Store');
String get introFilterStores => _pick('筛选门店', 'Filter Stores');
String get introSelectStoresHint => _pick('可多选门店', 'Select multiple stores');
String get introCategoryStore => _pick('所属门店', 'Store');
String get introStoreRequired => _pick('请选择所属门店', 'Please select a store');
String get introCategoryNameRequired =>
_pick('请输入名称', 'Please enter the name');
String get introCategoryTypeRequired =>
_pick('请输入类型编码', 'Please enter the type code');
String get introCategoryTypeNoChinese =>
_pick('类型编码禁止包含中文', 'Type code must not contain Chinese characters');
String get introStoreLoadFailed =>
_pick('门店列表加载失败,请下拉刷新后重试', 'Failed to load stores, please refresh and retry');
String get introSortOrder => _pick('排序号', 'Sort Order');
String get introEnabled => _pick('启用', 'Enabled');
String get introDisabled => _pick('禁用', 'Disabled');
String get introUploadImage => _pick('上传图片', 'Upload Image');
String get introPickImage => _pick('选择图片', 'Pick Image');
String get introImagePreview => _pick('图片预览', 'Image Preview');
String get introUploading => _pick('上传中…', 'Uploading…');
String get introUploadFailed => _pick('图片上传失败', 'Image upload failed');
String get introInsertImage => _pick('插入图片', 'Insert Image');
String get introSubImageHint =>
_pick('图片不超过 300KB,建议分辨率 1920×1080', 'Image ≤ 300KB, suggested 1920×1080');
String get introDetailImageHint => _pick('图片不超过 3MB', 'Image ≤ 3MB');
String get introDetailVideoHint => _pick('视频不超过 30MB', 'Video ≤ 30MB');
String get introImageTypeInvalid =>
_pick('请上传 jpg、png、gif 或 webp 图片', 'Please upload jpg, png, gif or webp image');
String get introVideoTypeInvalid =>
_pick('请上传 mp4、webm、mov 或 m4v 视频', 'Please upload mp4, webm, mov or m4v video');
String get introFileTooLarge => _pick('文件大小超过限制', 'File exceeds the size limit');
// ============ 地区选择器 ============
String get selectProvince => _pick('选择省份', 'Select Province');
String get selectCity => _pick('选择城市', 'Select City');
String get selectDistrict => _pick('选择区县', 'Select District');
String get selectRegion => _pick('选择地区', 'Select Region');
String get previousLevel => _pick('上一级', 'Previous');
// ============ 运行时长 ============
String formatUptime(int seconds) {
final duration = Duration(seconds: seconds);
final days = duration.inDays;
final hours = duration.inHours % 24;
final minutes = duration.inMinutes % 60;
final parts = <String>[];
if (days > 0) parts.add('$days${_pick('天', 'd')}');
if (hours > 0) parts.add('$hours${_pick('小时', 'h')}');
if (minutes > 0 || parts.isEmpty) {
parts.add('$minutes${_pick('分', 'm')}');
}
return parts.join(' ');
}
// ============ 通用状态/操作(后置兼容) ============
String get noOrgId => _pick('该门店缺少组织 ID,无法下发指令',
'This store lacks an organization ID and cannot receive commands');
// ============ 通用删除确认 ============
String get confirmDelete => _pick('确认删除', 'Confirm Delete');
String deleteConfirmContent(String name) =>
_pick('确定要删除「$name」吗?', 'Are you sure you want to delete "$name"?');
// ============ 渠道商管理 ============
String get channelManagement => _pick('渠道商管理', 'Channel Management');
String get addChannel => _pick('新增渠道', 'Add Channel');
String get editChannel => _pick('编辑渠道商', 'Edit Channel');
String get addSubChannel => _pick('新增子级', 'Add Child');
String get channelName => _pick('名称', 'Name');
String get channelType => _pick('类型', 'Type');
String get channelSort => _pick('排序', 'Sort');
String get channelStatus => _pick('状态', 'Status');
String get channelContactPhone => _pick('联系电话', 'Contact Phone');
String get channelAddress => _pick('地址', 'Address');
String get channelOrgCode => _pick('组织编码', 'Org Code');
String get channelTypeChannel => _pick('渠道', 'Channel');
String get channelTypeAgent => _pick('代理', 'Agent');
String get channelEnabled => _pick('启用', 'Enabled');
String get channelDisabled => _pick('禁用', 'Disabled');
String get channelParent => _pick('上级', 'Parent');
String get channelNameRequired => _pick('请输入名称', 'Please enter a name');
String get searchChannelHint => _pick('搜索渠道/代理商名称', 'Search channel/agent name');
String get channelDetail => _pick('渠道详情', 'Channel Detail');
String get channelExpireTime => _pick('到期时间', 'Expire Time');
String get channelCannotDeleteWithChildren =>
_pick('存在子集时不允许删除', 'Cannot delete a node that has children');
String get channelFilterStatus => _pick('状态', 'Status');
String get channelSwipeToDelete => _pick('左滑删除', 'Swipe left to delete');
// ============ 渠道版本管理 ============
/// 渠道/代理节点下钻的 App 版本管理入口。
String get channelVersionManage => _pick('版本管理', 'Version');
String get versionName => _pick('版本名', 'Version Name');
String get versionCode => _pick('版本号', 'Version Code');
String get downloadUrlHint => _pick('下载地址', 'Download URL');
String get forceUpdate => _pick('强制更新', 'Force Update');
String get showPopup => _pick('弹窗提示', 'Popup');
String get forceUpdateYes => _pick('是', 'Yes');
String get forceUpdateNo => _pick('否', 'No');
String get addVersion => _pick('新增版本', 'Add Version');
String get editVersion => _pick('编辑版本', 'Edit Version');
String get versionNameRequired => _pick('请输入版本名', 'Please enter a version name');
String get versionCodeRequired =>
_pick('请输入正整数版本号', 'Please enter a positive integer version code');
String get versionUrlRequired => _pick('请输入下载地址', 'Please enter a download URL');
String get versionUrlInvalid =>
_pick('请输入以 http(s) 开头的下载地址', 'URL must start with http(s)');
String get versionDeleteConfirm => _pick(
'确定删除该版本配置?删除后可重新新增。',
'Delete this version config? You can add it again afterward.');
String get versionDeleted => _pick('版本已删除', 'Version deleted');
String get uploadFile => _pick('上传文件', 'Upload');
String get uploading => _pick('上传中…', 'Uploading…');
String get uploadSuccess => _pick('文件上传成功', 'Uploaded');
String get uploadFailed => _pick('文件上传失败', 'Upload failed');
String get pleaseSelectApk => _pick('请选择 .apk 文件', 'Please select an .apk file');
// ============ 版本更新 ============
String get checkUpdate => _pick('检查更新', 'Check Update');
String get updateAvailable => _pick('发现新版本', 'Update Available');
String get currentVersion => _pick('当前版本', 'Current');
String get latestVersion => _pick('最新版本', 'Latest');
String get downloadUrl => _pick('下载地址', 'Download');
String get updateNow => _pick('立即更新', 'Update Now');
String get updateLater => _pick('稍后', 'Later');
String get updateNoNew => _pick('已是最新版本', 'Already up to date');
String get updateOpenFailed => _pick('无法打开下载地址', 'Failed to open download link');
}
/// 设备状态键(避免在模型层引入 BuildContext)。
enum DeviceStatusKey { online, offline, warning }