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

667 lines
39 KiB
Dart
Raw Permalink Normal View History

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 }