feat: 语言切换功能页面推进

This commit is contained in:
hzj 2026-04-27 17:20:07 +08:00
parent 63c97927a5
commit d19282ed78
28 changed files with 3156 additions and 618 deletions

View File

@ -5,6 +5,8 @@
- 本文件是“首页 > 主要路由 > 其他路由”中的主要路由唯一清单 - 本文件是“首页 > 主要路由 > 其他路由”中的主要路由唯一清单
- 本文件用于把 `src/permission.js``store.dispatch('user/getMenus')` 的接口返回结果整理成便于国际化领取、验收和运行检查的父子级路由清单 - 本文件用于把 `src/permission.js``store.dispatch('user/getMenus')` 的接口返回结果整理成便于国际化领取、验收和运行检查的父子级路由清单
- 需要查看主要路由的中文名、英文名、路由别名、路径、入口文件、完成状态时,统一以本文件为准 - 需要查看主要路由的中文名、英文名、路由别名、路径、入口文件、完成状态时,统一以本文件为准
- 本文件中的英文路由名必须与侧边栏实际语言包 `src/lang/messages/base/menu-en.js` 保持一致;如有差异,以 `menu-en.js` 为准同步文档
- 注意 `src/lang/messages/en.js` 顶层旧中文 key 会在运行时覆盖 `menu-en.js` 的同名 key统一路由英文名时需要同步检查并消除这类重复覆盖
- 本文件中的菜单层级不默认限制为“父级 > 子级”两层,若实际菜单存在三级结构,则按真实父链整理 - 本文件中的菜单层级不默认限制为“父级 > 子级”两层,若实际菜单存在三级结构,则按真实父链整理
- 路由是否记为独立菜单,先以原始接口返回为准;若入口页再直接引用同目录多个 `.vue` 文件,则这些文件记为页面内功能文件,不单独记成并列主路由 - 路由是否记为独立菜单,先以原始接口返回为准;若入口页再直接引用同目录多个 `.vue` 文件,则这些文件记为页面内功能文件,不单独记成并列主路由
- 后续所有线程领取新任务前,除了读取 `线程协作.md``翻译进度.md``翻译清单.md`,还应先读取本文件 - 后续所有线程领取新任务前,除了读取 `线程协作.md``翻译进度.md``翻译清单.md`,还应先读取本文件
@ -14,11 +16,13 @@
### 全线程统一优先级 ### 全线程统一优先级
- 适用于所有线程,不只线程三 - 适用于所有线程,不只线程三
- 统一领取优先级:`已完成 src/views 页面私有组件复查 > 首页 > 本文件中的主要路由页面` - 统一领取优先级:`首页 > 本文件中的主要路由页面`
- 在“已完成 `src/views` 页面私有组件复查”完成前,暂不继续领取新的未完成普通页面 - 已完成 `src/views` 页面私有组件复查是历史临时任务,当前已完成,不再作为领取优先级的一环
- 后续认领本文件中的页面时,仍必须核对该页面入口直接涉及的 `src/views/**` 页面内组件 / 私有组件,以及直接渲染的 `src/components/**` 公共组件,并在完成记录里写明私有组件状态与直接公共组件状态
- 只要首页或本文件中的主要路由页面还有未完成项,后续线程都应优先从这两部分中选择 - 只要首页或本文件中的主要路由页面还有未完成项,后续线程都应优先从这两部分中选择
- 本文件中的主要路由页面之间,具体先领哪一个页面仍可按原来的方式灵活分配,只要先读 md、先写认领、避免冲突 - 本文件中的主要路由页面之间,具体先领哪一个页面仍可按原来的方式灵活分配,只要先读 md、先写认领、避免冲突
- 自 2026-04-22 起,后续翻译范围只保留本文件中的主要路由页面及其直接涉及组件;其他路由页面不再继续纳入新增翻译任务 - 自 2026-04-22 起,后续翻译范围只保留本文件中的主要路由页面及其直接涉及组件;其他路由页面不再继续纳入新增翻译任务
- 自 2026-04-27 起,“直接涉及组件”包含页面直接渲染的 `src/components/**` 公共组件;公共组件影响范围较大时可单独认领,但必须在当前页面状态中写明待复核或已完成
### 首页 ### 首页
@ -53,16 +57,16 @@
### 当前进行中的主要路由 ### 当前进行中的主要路由
- 系统管理 / System Management - 当前无
- App系统 / App System
- 版本管理 / Version Management ### 当前跨已完成页面的公共组件联动复查
- 路由别名:`sugartime:version`
- 路径:`version/app/index` - 状态:待处理
- 进行中文件: - 已完成:`src/components/data/PropsRow/index.vue`线程一2026-04-27
- `src/views/version/app/index.vue` - 说明:已发现不止 `用户列表 / User List` 使用仍需复核的 `src/components/**` 公共组件;所有已完成主要路由页面都需要按 `docs/i18n/翻译清单.md` 中“对已完成主要路由页面做直接公共组件联动复查”清单逐项确认
- `src/views/version/app/app-version-edit.vue` - 优先建议:
- `src/views/version/app/app-update-content.vue` - 继续处理被多个已完成页面复用的公共组件,例如 `src/components/data/RoomDeatilsDrawer/index.vue`
- 状态:进行中(线程三) - 再处理高频业务弹窗 / 抽屉,例如用户列表直接渲染的流水、充值、扣除、违规记录等组件
### 当前接口返回的主要路由树(整理版) ### 当前接口返回的主要路由树(整理版)
@ -71,38 +75,52 @@
- 用户管理 / User Management - 用户管理 / User Management
- 路由别名:`sys:user:list` - 路由别名:`sys:user:list`
- 路径:`sys/user-manager/index` - 路径:`sys/user-manager/index`
- 状态:待处理 - 已完成文件:
- `src/views/sys/user-manager/index.vue`
- `src/views/sys/user-manager/edit-user.vue`
- 状态:已完成
- 角色管理 / Role Management - 角色管理 / Role Management
- 路由别名:`sys:role:list` - 路由别名:`sys:role:list`
- 路径:`sys/role-manager/index` - 路径:`sys/role-manager/index`
- 状态:待处理 - 已完成文件:
- `src/views/sys/role-manager/index.vue`
- `src/views/sys/role-manager/edit-role.vue`
- `src/views/sys/role-manager/authorize-role.vue`
- 状态:已完成
- 菜单管理 / Menu Management - 菜单管理 / Menu Management
- 路由别名:`sys:menu:list` - 路由别名:`sys:menu:list`
- 路径:`sys/menu-manager/index` - 路径:`sys/menu-manager/index`
- 状态:待处理 - 已完成文件:
- `src/views/sys/menu-manager/index.vue`
- `src/views/sys/menu-manager/menu-tree.vue`
- `src/views/sys/menu-manager/menu-edit.vue`
- 状态:已完成
- 资源管理 / Resource Management - 资源管理 / Resource Management
- 路由别名:`sys:resource:list` - 路由别名:`sys:resource:list`
- 路径:`sys/resources-manager/index` - 路径:`sys/resources-manager/index`
- 状态:待处理 - 已完成文件:
- `src/views/sys/resources-manager/index.vue`
- 状态:已完成
- App系统 / App System - App系统 / App System
- 路由别名:`app:sys:manager` - 路由别名:`app:sys:manager`
- 状态:部分完成 - 状态:部分完成
- 版本管理 / Version Management - 版本管理 / Version Management
- 路由别名:`sugartime:version` - 路由别名:`sugartime:version`
- 路径:`version/app/index` - 路径:`version/app/index`
- 进行中文件: - 已完成文件:
- `src/views/version/app/index.vue` - `src/views/version/app/index.vue`
- `src/views/version/app/app-version-edit.vue` - `src/views/version/app/app-version-edit.vue`
- `src/views/version/app/app-update-content.vue` - `src/views/version/app/app-update-content.vue`
- 状态:进行中(线程三) - 状态:已完成
- APP运行日志 / APP Runtime Logs - APP运行日志 / APP Runtime Logs
- 路由别名:`Breakdown` - 路由别名:`Breakdown`
- 路径:`log/breakdown/index` - 路径:`log/breakdown/index`
- 状态:待处理 - 状态:暂跳过,入口文件缺失,待确认
- IM通讯 / IM Communication - IM通讯 / IM Communication
- 路由别名:`ExternalIm` - 路由别名:`ExternalIm`
- 路径:`external/im` - 路径:`external/im`
- 状态:待处理 - 文件:`src/views/external/im.vue`
- 状态:已完成
- 请求黑名单 / Request Blacklist - 请求黑名单 / Request Blacklist
- 路由别名:`request:blacklist` - 路由别名:`request:blacklist`
- 路径:`sys/request-blacklist/index` - 路径:`sys/request-blacklist/index`
@ -115,30 +133,44 @@
- 路由别名:`AppUserList` - 路由别名:`AppUserList`
- 路径:`user/user-table/index` - 路径:`user/user-table/index`
- 文件:`src/views/user/user-table/index.vue` - 文件:`src/views/user/user-table/index.vue`
- 状态:已完成 - 状态:页面本体已完成,直接公共组件待联动复核
- 用户专属礼物制作 / User Custom Gift Creation - 备注:该页面直接渲染多个 `src/components/**` 弹窗、抽屉、流水与表单组件;后续按公共组件联动复查规则逐个确认展示中文
- 用户专属礼物制作 / Custom User Gift Creation
- 路由别名:`UserCustomGift` - 路由别名:`UserCustomGift`
- 路径:`user/custom-gift/index` - 路径:`user/custom-gift/index`
- 文件:`src/views/user/custom-gift/index.vue` - 文件:`src/views/user/custom-gift/index.vue`
- 状态:已完成 - 状态:已完成
- 封禁设备列表 / Banned Device List - 封禁设备列表 / Blocked Device List
- 路由别名:`ArchiveDevice` - 路由别名:`ArchiveDevice`
- 路径:`log/archive-device/index` - 路径:`log/archive-device/index`
- 状态:待处理 - 文件:`src/views/log/archive-device/index.vue`
- 状态:已完成
- 最新登记设备 / Latest Registered Devices - 最新登记设备 / Latest Registered Devices
- 路由别名:`UserDevice` - 路由别名:`UserDevice`
- 路径:`user/user-device/index` - 路径:`user/user-device/index`
- 状态:待处理 - 已完成文件:
- `src/views/user/user-device/index.vue`
- 状态:已完成
- 运营管理 / Operations Management - 运营管理 / Operations Management
- 路由别名:`OperationManager` - 路由别名:`OperationManager`
- 营收支出 / Revenue and Expenses - 营收支出 / Revenue and Expenses
- 路由别名:`AppRevenue` - 路由别名:`AppRevenue`
- 状态:待处理 - 状态:部分完成
- 消费商品订单 / Purchase Orders
- 路由别名:`GoldPurchasing`
- 路径:`order/candy/purchasing/index`
- 文件:`src/views/order/candy/purchasing/index.vue`
- 状态:已完成
- 金币收支记录 / Gold Transaction Records
- 路由别名:`CandyRunningWater`
- 路径:`order/candy/running-water/index`
- 文件:`src/views/order/candy/running-water/index.vue`
- 状态:已完成
- 数据配置 / Data Configuration - 数据配置 / Data Configuration
- 路由别名:`data:conf` - 路由别名:`data:conf`
- 状态:部分完成 - 状态:部分完成
- 参数配置 / Parameter Configuration - 参数配置 / Parameter Settings
- 路由别名:`SysConfigSetting` - 路由别名:`SysConfigSetting`
- 路径:`cnf/enums/manager/index` - 路径:`cnf/enums/manager/index`
- 状态:待处理 - 状态:待处理
@ -146,7 +178,7 @@
- 路由别名:`game:rule-config` - 路由别名:`game:rule-config`
- 路径:`game/lucky-gift/rule-config/index` - 路径:`game/lucky-gift/rule-config/index`
- 状态:待处理 - 状态:待处理
- 幸运礼物规格配置 / Lucky Gift Standard Configuration - 幸运礼物规格配置 / Lucky Gift Specification Configuration
- 路由别名:`game:standard-config` - 路由别名:`game:standard-config`
- 路径:`game/lucky-gift/standard-config/index` - 路径:`game/lucky-gift/standard-config/index`
- 状态:待处理 - 状态:待处理
@ -222,7 +254,7 @@
- `src/views/activity/template-cnf/template-editor/reward-array-editor.vue` - `src/views/activity/template-cnf/template-editor/reward-array-editor.vue`
- `src/views/activity/template-cnf/template-form/index.vue` - `src/views/activity/template-cnf/template-form/index.vue`
- 状态:已完成 - 状态:已完成
- 活动模版 / Activity Template - 活动模版 / Activity Templates
- 路由别名:`Activity:Template` - 路由别名:`Activity:Template`
- 路径:`activity/template-cnf/template-form/index` - 路径:`activity/template-cnf/template-form/index`
- 状态:已完成 - 状态:已完成
@ -239,7 +271,7 @@
- `src/views/message/push/push-log.vue` - `src/views/message/push/push-log.vue`
- `src/views/message/push/push-task.vue` - `src/views/message/push/push-task.vue`
- 状态:已完成 - 状态:已完成
- APP管理员 / App Administrator - APP管理员 / App Administrators
- 路由别名:`AdministratorTable` - 路由别名:`AdministratorTable`
- 路径:`user/app-manager/index` - 路径:`user/app-manager/index`
- 已完成文件: - 已完成文件:
@ -253,7 +285,7 @@
- 路径:`sys/notice-message/index` - 路径:`sys/notice-message/index`
- 文件:`src/views/sys/notice-message/index.vue` - 文件:`src/views/sys/notice-message/index.vue`
- 状态:已完成 - 状态:已完成
- 金币代理 / Gold Agent - 金币代理 / Gold Agents
- 路由别名:`UserFreight` - 路由别名:`UserFreight`
- 路径:`user/freight/index` - 路径:`user/freight/index`
- 已完成文件: - 已完成文件:
@ -263,7 +295,7 @@
- `src/views/user/freight/seller-info.vue` - `src/views/user/freight/seller-info.vue`
- `src/views/user/freight/freight-seller-running-water.vue` - `src/views/user/freight/freight-seller-running-water.vue`
- 状态:已完成 - 状态:已完成
- 申请靓号 / Special ID Application - 申请靓号 / Apply for Special ID
- 路由别名:`BeautifulNumberApply` - 路由别名:`BeautifulNumberApply`
- 路径:`user/beautiful-number-apply/index` - 路径:`user/beautiful-number-apply/index`
- 状态:待处理 - 状态:待处理
@ -278,7 +310,7 @@
- 路由别名:`CustomerService` - 路由别名:`CustomerService`
- 路径:`sys/customer-service/index` - 路径:`sys/customer-service/index`
- 状态:待处理 - 状态:待处理
- 金币余额榜 / Gold Balance Ranking - 金币余额榜 / Gold Balance Leaderboard
- 路由别名:`gold:balanc:top` - 路由别名:`gold:balanc:top`
- 路径:`user/gold-balance/index` - 路径:`user/gold-balance/index`
- 状态:待处理 - 状态:待处理
@ -293,7 +325,7 @@
- 用户银行 / User Bank - 用户银行 / User Bank
- 路由别名:`UserBankBalance` - 路由别名:`UserBankBalance`
- 状态:待处理 - 状态:待处理
- 用户工资钻石 / User Salary Diamond - 用户工资钻石 / User Salary Diamonds
- 路由别名:`UserSalaryDiamondBalance` - 路由别名:`UserSalaryDiamondBalance`
- 状态:待处理 - 状态:待处理
@ -313,7 +345,7 @@
- `src/views/room/profile/room-visitor-log.vue` - `src/views/room/profile/room-visitor-log.vue`
- `src/views/room/profile/user-drawer.vue` - `src/views/room/profile/user-drawer.vue`
- 状态:已完成 - 状态:已完成
- 置顶房间 / Featured Rooms - 置顶房间 / Pinned Rooms
- 路由别名:`room:set:top` - 路由别名:`room:set:top`
- 路径:`sys/set-top/index` - 路径:`sys/set-top/index`
- 状态:待处理 - 状态:待处理
@ -327,11 +359,19 @@
- 家族配置 / Family Configuration - 家族配置 / Family Configuration
- 路由别名:`FamilyConfig` - 路由别名:`FamilyConfig`
- 路径:`family/config/index` - 路径:`family/config/index`
- 状态:待处理 - 已完成文件:
- `src/views/family/config/index.vue`
- `src/views/family/config/config-level/index.vue`
- `src/views/family/config/config-create-role/index.vue`
- `src/views/family/config/config-weekly-reward/index.vue`
- 状态:已完成
- 家族列表 / Family List - 家族列表 / Family List
- 路由别名:`FamilyList` - 路由别名:`FamilyList`
- 路径:`family/list/index` - 路径:`family/list/index`
- 状态:待处理 - 已完成文件:
- `src/views/family/list/index.vue`
- `src/views/family/list/family-member.vue`
- 状态:已完成
- 审批管理 / Approval Management - 审批管理 / Approval Management
- 路由别名:`ApprovalManager` - 路由别名:`ApprovalManager`
@ -346,7 +386,7 @@
- `src/views/props/props-source-group/index.vue` - `src/views/props/props-source-group/index.vue`
- `src/views/props/props-source-group/form-edit.vue` - `src/views/props/props-source-group/form-edit.vue`
- 状态:已完成 - 状态:已完成
- 道具赠送 / Prop Delivery - 道具赠送 / Prop Gift
- 路由别名:`PropsSendTool` - 路由别名:`PropsSendTool`
- 路径:`props/props-send-tool/index` - 路径:`props/props-send-tool/index`
- 状态:待处理 - 状态:待处理
@ -414,21 +454,33 @@
### 当前已完成主要路由摘要 ### 当前已完成主要路由摘要
- 系统管理 / System Management - 系统管理 / System Management
- 用户管理 / User Management
- 角色管理 / Role Management
- 菜单管理 / Menu Management
- 资源管理 / Resource Management
- App系统 / App System - App系统 / App System
- 版本管理 / Version Management
- IM通讯 / IM Communication
- 请求黑名单 / Request Blacklist - 请求黑名单 / Request Blacklist
- 用户管理 / User Management - 用户管理 / User Management
- 用户列表 / User List - 用户列表 / User List页面本体已完成直接公共组件待联动复核
- 运营管理 / Operations Management - 用户专属礼物制作 / Custom User Gift Creation
- 封禁设备列表 / Blocked Device List
- 最新登记设备 / Latest Registered Devices
- 运营管理 / Operations Management
- 营收支出 / Revenue and Expenses
- 消费商品订单 / Purchase Orders
- 金币收支记录 / Gold Transaction Records
- 数据配置 / Data Configuration - 数据配置 / Data Configuration
- 国家管理 / Country Management - 国家管理 / Country Management
- IM账号管理 / IM Account Management - IM账号管理 / IM Account Management
- 活动配置 / Activity Configuration - 活动配置 / Activity Configuration
- 活动管理 / Activity Management - 活动管理 / Activity Management
- 活动模版 / Activity Template - 活动模版 / Activity Templates
- 消息推送 / Message Push - 消息推送 / Message Push
- APP管理员 / App Administrator - APP管理员 / App Administrators
- 系统公告管理 / System Notice Management - 系统公告管理 / System Notice Management
- 金币代理 / Gold Agent - 金币代理 / Gold Agents
- App启动页 / App Launch Page - App启动页 / App Launch Page
- 区域配置 / Region Configuration - 区域配置 / Region Configuration
- 语音房间 / Voice Rooms - 语音房间 / Voice Rooms
@ -440,32 +492,9 @@
- BD Lead / BD Lead - BD Lead / BD Lead
- 代理政策 / Agent Policy - 代理政策 / Agent Policy
- BD列表 / BD List - BD列表 / BD List
- 家族管理 / Family Management
### 已完成但未在当前主要路由菜单返回中命中的补充页面 - 家族配置 / Family Configuration
- 家族列表 / Family List
- 当前接口返回里未出现 `工具管理` 顶层菜单,以下已完成页面暂归为补充页面:
- `src/views/tools/redis/index.vue`
- `src/views/tools/upload/index.vue`
- `src/views/tools/other/index.vue`
- `src/views/tools/other/alias-method.vue`
- `src/views/tools/other/api-sign.vue`
- `src/views/tools/other/redis-ops.vue`
- `src/views/tools/other/token-parse.vue`
- `src/views/tools/other/user-cancel-and-restore.vue`
- `src/views/tools/other/user-room-region.vue`
- `src/views/tools/other/user-swap-user.vue`
- `src/views/tools/gold-analyze/index.vue`
- `src/views/tools/compensate-order/index.vue`
- `src/views/tools/websocket/index.vue`
- 抽奖概率配置 / Lottery Probability Settings
- 路由别名:`GameLottery`
- 路由来源:`src/router/index.js` 静态路由
- 路径:`game/lottery-config/index`
- 已完成文件:
- `src/views/game/lottery-config/index.vue`
- `src/views/game/lottery-config/form-edit.vue`
- `src/views/game/lottery-config/select-propsr-popover.vue`
- 状态:已完成
### 已部分完成但入口页仍需复核的主要路由 ### 已部分完成但入口页仍需复核的主要路由
@ -473,12 +502,12 @@
### 当前建议检查顺序 ### 当前建议检查顺序
1. 先处理“已完成 `src/views` 页面私有组件复查”任务 1. 首页 `Dashboard` 模块
2. 首页 `Dashboard` 模块 2. 本文件中“当前进行中的主要路由”:
3. 本文件中“当前进行中的主要路由”:
- 当前无 - 当前无
4. 本文件中“模块部分完成,入口页仍需复核”的页面: 3. 本文件中“模块部分完成,入口页仍需复核”的页面:
- 当前无 - 当前无
4. 本文件中其他待处理主要路由页面
## 主要路由 ## 主要路由

View File

@ -30,19 +30,26 @@
- `docs/i18n/主要路由.md` - `docs/i18n/主要路由.md`
- 每次准备领取新任务前,都要重新读取一次以上 3 份协作文档 + `docs/i18n/主要路由.md`,先确认最新认领状态已经落盘,避免两个线程在 md 尚未更新时重复认领同一文件 - 每次准备领取新任务前,都要重新读取一次以上 3 份协作文档 + `docs/i18n/主要路由.md`,先确认最新认领状态已经落盘,避免两个线程在 md 尚未更新时重复认领同一文件
- 所有线程统一领取优先级: - 所有线程统一领取优先级:
- 已完成 `src/views` 页面私有组件复查任务
- 首页 `Dashboard` - 首页 `Dashboard`
- `docs/i18n/主要路由.md` 中列出的主要路由页面 - `docs/i18n/主要路由.md` 中列出的主要路由页面
- 临时规则补充: - 已完成 `src/views` 页面私有组件复查是历史临时任务,当前已完成,不再作为领取优先级的一环
- 在“已完成 `src/views` 页面私有组件复查任务”完成前,暂不继续领取新的未完成普通页面 - 后续领取页面时仍必须检查该页面直接涉及的 `src/views/**` 私有组件与 `src/components/**` 公共组件:
- 这里的“私有组件”仅指 `src/views/**` 目录下、随页面一同渲染或由页面局部引用的组件,不包含公共组件目录 `src/components/**` - 读取入口页 import / 局部注册 / tab / 动态组件 / 抽屉 / 弹窗
- 自 2026-04-22 起,后续任务范围只保留“主要路由页面 + 这些页面直接涉及的页面内组件/私有组件”;非主要路由页面不再继续补翻 - 核对同目录与子目录可见 `.vue` 文件是否会被该页面渲染
- 如果属于当前主要路由页面直接涉及的页面内组件、私有组件或公共组件,随页面一并处理或明确写入待处理原因
- 完成记录必须写明页面私有组件状态与直接公共组件状态
- 这里的“私有组件”仅指 `src/views/**` 目录下、随页面一同渲染或由页面局部引用的组件
- 这里的“直接公共组件”指当前主要路由页面通过 `import`、局部注册、全局注册标签或模板直接渲染的 `src/components/**` 组件;这类组件不再默认排到最后统一处理
- 如果直接公共组件为多页面共享且影响范围较大,可以单独认领为公共组件任务,但必须在当前页面完成记录和 `翻译清单.md` 中写明“公共组件待复核/已完成/暂跳过原因”
- 自 2026-04-22 起,后续任务范围只保留“主要路由页面 + 这些页面直接涉及的页面内组件/私有组件/公共组件”;非主要路由页面不再继续补翻
- 当首页或 `主要路由.md` 中仍有未完成页面时,不应优先领取其他普通路由页面 - 当首页或 `主要路由.md` 中仍有未完成页面时,不应优先领取其他普通路由页面
- `主要路由.md` 中具体先领取哪一个页面,仍可按原来的灵活方式分配,只要遵守“不重复认领、不与其他线程冲突” - `主要路由.md` 中具体先领取哪一个页面,仍可按原来的灵活方式分配,只要遵守“不重复认领、不与其他线程冲突”
- 每次正式认领任务时,必须先把认领结果写入 md再开始修改源码不要先改代码、后补文档 - 每次正式认领任务时,必须先把认领结果写入 md再开始修改源码不要先改代码、后补文档
- 写入认领记录前,要先检查 3 份协作文档 + `docs/i18n/主要路由.md` 是否已有其他线程认领同一任务;写入完成后,要立刻再读一次同样的文档集合,确认没有新的冲突后再开工 - 写入认领记录前,要先检查 3 份协作文档 + `docs/i18n/主要路由.md` 是否已有其他线程认领同一任务;写入完成后,要立刻再读一次同样的文档集合,确认没有新的冲突后再开工
- 每个线程一次只认领明确的一组文件,避免交叉编辑 - 每个线程一次只认领明确的一组文件,避免交叉编辑
- 只翻译展示文本,不修改功能逻辑、接口参数、路由路径、权限码、后端依赖值 - 只翻译展示文本,不修改功能逻辑、接口参数、路由路径、权限码、后端依赖值
- md 中记录的英文路由名必须与侧边栏实际语言包 `src/lang/messages/base/menu-en.js` 保持一致;如果和历史文档不一致,以 `menu-en.js` 为准同步 md
- 侧边栏最终运行时会通过 `src/lang/messages/en.js` 合并语言对象;如果 `messages/en.js` 顶层存在同名中文 key会覆盖 `menu-en.js` 中的菜单译名,因此统一路由英文名时必须同时检查这两个文件
- 如果文本依赖接口返回且当前无法可靠推断,先跳过,并记录到 `docs/i18n/翻译清单.md` - 如果文本依赖接口返回且当前无法可靠推断,先跳过,并记录到 `docs/i18n/翻译清单.md`
- 每完成一轮修改后,必须同步更新: - 每完成一轮修改后,必须同步更新:
- `docs/i18n/翻译进度.md` - `docs/i18n/翻译进度.md`
@ -56,6 +63,12 @@
- `已随页面同步完成` - `已随页面同步完成`
- `历史已完成,已复核通过` - `历史已完成,已复核通过`
- `历史已完成,但仍待复核` - `历史已完成,但仍待复核`
- 自 2026-04-27 起,`src/views` 页面标记“已完成”时,还必须单独记录该页面直接公共组件状态:
- `无直接公共组件`
- `已随页面同步完成`
- `已单独完成`
- `仍待复核`
- `暂跳过,需写明原因`
## 新线程启动速记 ## 新线程启动速记
@ -75,6 +88,7 @@
- 认领页面时,不要只看 `index.vue`。如果同目录还有页面私有子组件或抽屉组件,也要顺手扫描一遍是否仍有中文展示文案,例如: - 认领页面时,不要只看 `index.vue`。如果同目录还有页面私有子组件或抽屉组件,也要顺手扫描一遍是否仍有中文展示文案,例如:
- `src/views/team/diamond-policy/props-form-edit.vue` - `src/views/team/diamond-policy/props-form-edit.vue`
- 历史上已经标记“已完成”的 `src/views` 页面,也不能默认其私有组件已完成;如果当时 md 只登记了入口页,后续必须补做一次目录级复核,并把组件状态补回 `翻译进度.md` - 历史上已经标记“已完成”的 `src/views` 页面,也不能默认其私有组件已完成;如果当时 md 只登记了入口页,后续必须补做一次目录级复核,并把组件状态补回 `翻译进度.md`
- 历史上已经标记“已完成”的 `src/views` 页面,也不能默认其直接引用的公共组件已完成;如果页面 import 了 `src/components/**` 弹窗、抽屉、详情、流水、表单等可见组件,后续必须补做公共组件联动复核,并把状态补回 `翻译进度.md``翻译清单.md`
- 如果是“模块入口页 + tab/component 动态切换子页”结构,不能只按当前先看到的 1-2 个子页面认领;必须先把同一模块下所有会被入口页渲染到界面的子页面一起盘清 - 如果是“模块入口页 + tab/component 动态切换子页”结构,不能只按当前先看到的 1-2 个子页面认领;必须先把同一模块下所有会被入口页渲染到界面的子页面一起盘清
- 如果页面里的私有子组件和现有模块语义一致,优先复用已有 key 体系,避免重复造轮子。本轮已验证可复用的 key 范围: - 如果页面里的私有子组件和现有模块语义一致,优先复用已有 key 体系,避免重复造轮子。本轮已验证可复用的 key 范围:
- `pages.propsSourceGroupForm` - `pages.propsSourceGroupForm`
@ -133,16 +147,20 @@
- 哪个可见文件被暂时排除 - 哪个可见文件被暂时排除
- 为什么排除 - 为什么排除
- 下一个线程建议接手哪个文件 - 下一个线程建议接手哪个文件
6. 开工前,至少对“本次认领模块目录”执行一次递归中文扫描,确认没有漏掉同目录可见文件 6. 同步列出入口页直接 import / 局部注册 / 全局标签渲染的 `src/components/**` 公共组件
7. 完成后,必须再次对整个模块目录做递归中文扫描,而不是只扫本轮实际修改过的单个文件 7. 对直接公共组件执行中文扫描;如果同轮不处理,必须写入“公共组件待复核”清单
8. 开工前,至少对“本次认领模块目录”执行一次递归中文扫描,确认没有漏掉同目录可见文件
9. 完成后,必须再次对整个模块目录与本轮纳入的直接公共组件做中文扫描,而不是只扫本轮实际修改过的单个文件
最低检查清单: 最低检查清单:
- 是否读取了入口页 - 是否读取了入口页
- 是否读取了模块目录文件列表 - 是否读取了模块目录文件列表
- 是否核对了入口页里所有可见 tab / 动态组件 / 局部组件 - 是否核对了入口页里所有可见 tab / 动态组件 / 局部组件
- 是否核对了入口页直接渲染的 `src/components/**` 公共组件
- 是否把故意跳过的可见文件写入 `翻译清单.md` - 是否把故意跳过的可见文件写入 `翻译清单.md`
- 是否在完成后对整个模块目录重新扫描 - 是否在完成后对整个模块目录重新扫描
- 是否在完成后对本轮纳入的直接公共组件重新扫描
本轮复盘案例: 本轮复盘案例:
@ -159,13 +177,559 @@
| 线程 | 当前状态 | 认领范围 | 说明 | | 线程 | 当前状态 | 认领范围 | 说明 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| 线程一 | 进行中 | `src/views/family/config` | 2026-04-22 已认领 `家族配置 / Family Configuration` 模块:`index.vue` + `config-level/index.vue` + `config-create-role/index.vue` + `config-weekly-reward/index.vue` | | 线程一 | 进行中 | `src/components/data/RoomDeatilsDrawer/index.vue` | 2026-04-27 认领公共组件联动复查:处理房间详情抽屉组件展示文本 |
| 线程二 | 进行中 | `src/views/game/ludo/index.vue` | 2026-04-22 已按规则重新读取协作文档与语言文件,现认领 Ludo 对局页面国际化、中文残留扫描、构建验证与 md 同步 | | 线程二 | 待分配 | 未认领 | 2026-04-27 已完成 `src/views/sys/menu-manager/index.vue` 系统管理 / 菜单管理页面国际化、中文残留扫描、构建验证与 md 同步 |
| 线程三 | 进行中 | `src/views/version/app/index.vue` | 2026-04-22 已按规则重新读取协作文档、主路由清单与语言文件,现认领 `版本管理 / Version Management` 模块:`index.vue` + `app-version-edit.vue` + `app-update-content.vue` | | 线程三 | 待分配 | 未认领 | 2026-04-27 已完成 `src/views/sys/role-manager` 系统管理 / 角色管理页面国际化,本轮结束后切回待分配 |
| 线程四 | 待分配 | 未认领 | 避免和其他线程同时编辑同一语言模块 | | 线程四 | 待分配 | 未认领 | 避免和其他线程同时编辑同一语言模块 |
## 最新认领记录 ## 最新认领记录
- 2026-04-27
- 线程一已新认领:`src/components/data/RoomDeatilsDrawer/index.vue`
- 任务类型:已完成主要路由页面的直接公共组件联动复查
- 关联页面包括:
- `src/views/game/ludo/index.vue`
- `src/views/room/profile/index.vue`
- 认领范围包括:
- 组件内静态展示文本翻译
- 必要的页面级语言 key 补充或复用
- 中文残留扫描、语言文件语法检查、构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 与本文件同步更新
- 不包含:
- 接口参数
- 路由路径
- 权限码
- 后端依赖值
- 2026-04-27
- 线程一已完成:`src/components/data/PropsRow/index.vue`
- 任务类型:已完成主要路由页面的直接公共组件联动复查
- 完成范围包括:
- “永久”展示文本国际化
- 新增 `pages.propsRow.word.permanent`
- 中文残留扫描
- 语言文件语法检查
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 与本文件同步更新
- 补充说明:
- `item.remark`、数量、天数、道具类型、图片地址与接口返回资源数据保持原样
- 组件剩余中文仅为注释“道具券 / 荣誉活动”,不属于可见展示文案
- `npm run build:prod` 已通过,当前仍保留项目既有 `17` 条 warning未新增阻塞错误
- 线程一本轮完成后切回待分配
- 2026-04-27
- 线程一已新认领:`src/components/data/PropsRow/index.vue`
- 任务类型:已完成主要路由页面的直接公共组件联动复查
- 关联页面包括:
- `src/views/activity/template-cnf/activity-rank-reward.vue`
- `src/views/activity/template-cnf/reward-edit.vue`
- `src/views/game/egg/egg-lottery-record/index.vue`
- `src/views/game/lottery-config/index.vue`
- `src/views/props/props-source-group/index.vue`
- `src/views/team/diamond-policy/index.vue`
- `src/views/team/policy/index.vue`
- 认领范围包括:
- 组件内静态展示文本翻译
- 必要的页面级语言 key 补充或复用
- 中文残留扫描、语言文件语法检查、构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md` 与本文件同步更新
- 不包含:
- 接口参数
- 路由路径
- 权限码
- 后端依赖值
- 2026-04-27
- 线程一已补充全量回扫结论:不止 `用户列表 / User List` 使用需复核的公共组件
- 已执行初扫:
- 扫描 `docs/i18n/翻译清单.md` 已完成文件平铺清单中的 `src/views/**/*.vue`
- 提取页面直接 `import "@/components/**"` 的公共组件
- 对解析到的公共组件执行中文命中扫描
- 已写入:
- `docs/i18n/翻译清单.md`:新增“已完成页面 -> 直接公共组件”待复核清单
- `docs/i18n/翻译进度.md`:记录全量回扫结论与优先建议
- `docs/i18n/主要路由.md`:记录当前跨已完成页面的公共组件联动复查
- 后续建议:
- 优先认领复用度高的公共组件,例如 `src/components/data/PropsRow/index.vue`
- 再认领用户列表直接渲染的高频业务弹窗 / 抽屉组件
- 2026-04-27
- 线程一已同步规则调整:主要路由页面完成标准新增“直接公共组件状态”
- 调整原因:
- 已发现 `用户列表 / User List` 页面本体和部分公共组件曾分开处理,旧规则只强调 `src/views/**` 私有组件,容易漏掉页面直接渲染的 `src/components/**` 公共组件
- 新规则:
- 后续认领主要路由页面时,必须同步核对页面本体、`src/views/**` 私有组件、直接渲染的 `src/components/**` 公共组件
- 公共组件影响范围较大时可单独认领,但必须在当前页面记录中写明“已完成 / 待复核 / 暂跳过原因”
- 已写入:
- `docs/i18n/线程协作.md`
- `docs/i18n/翻译清单.md`
- `docs/i18n/翻译进度.md`
- `docs/i18n/主要路由.md`
- 2026-04-27
- 线程一已完成:`src/views/order/candy/running-water/index.vue`
- 对应主要路由:运营管理 / Operations Management -> 营收支出 / Revenue and Expenses -> 金币收支记录 / Gold Transaction Records
- 完成范围包括:
- 筛选区系统、类型、来源、用户 ID、Trace ID、ID、日期范围、分页数量、搜索按钮国际化
- 表格列头、收支类型、加载更多按钮、时间范围提示、跨年限制提示、全部加载完成提示国际化
- 新增 `pages.goldRunningWater`
- 对 `currencyOrigins` 的来源名称做展示层翻译映射,保留原 value 与接口参数不变
- 中文残留扫描
- 语言文件语法检查
- 构建验证
- 页面私有组件状态:
- `src/views/order/candy/running-water/index.vue`:目录当前仅包含 `index.vue`,无页面私有组件,已完成
- 补充说明:
- 未修改查询参数、接口字段、路由路径、权限码、枚举提交值、分页逻辑或后端返回流水数据
- `currencyOrigins``value` 保持原样,仅通过展示层 key 映射翻译来源名称
- 后端返回的用户、备注、Trace ID、记录 ID、时间、金币数值等动态数据保持原样
- `npm run build:prod` 已通过,仍为项目既有 `17` 条 warning未新增阻塞错误
- 线程一本轮完成后切回待分配
- 2026-04-27
- 线程一已新认领:`src/views/order/candy/running-water/index.vue`
- 对应主要路由:运营管理 / Operations Management -> 营收支出 / Revenue and Expenses -> 金币收支记录 / Gold Transaction Records
- 认领前置检查:
- 已重读 `docs/i18n/线程协作.md`
- 已重读 `docs/i18n/翻译进度.md`
- 已重读 `docs/i18n/翻译清单.md`
- 已重读 `docs/i18n/主要路由.md`
- 已读取 `src/lang/messages/pages/en.js``src/lang/messages/pages/zh.js`
- 补充说明:
- 已核对 `src/views/order/candy/running-water` 目录当前仅包含 `index.vue`
- 本轮只处理页面可见静态文案,不修改查询参数、接口字段、枚举提交值或后端返回的流水来源名称
- 2026-04-27
- 线程一已完成:`src/views/order/candy/purchasing/index.vue`
- 对应主要路由:运营管理 / Operations Management -> 营收支出 / Revenue and Expenses -> 消费商品订单 / Purchase Orders
- 完成范围包括:
- 筛选区 placeholder、日期范围、搜索/导出按钮、用户总充值提示国际化
- 表格列头、朋友标记、状态展示、购买/修改时间前缀、详情按钮国际化
- 导出条件抽屉标题、表单标签、placeholder、关闭/导出按钮、校验提示与导出状态提示国际化
- 新增 `pages.purchaseOrders`
- 中文残留扫描
- 语言文件语法检查
- 构建验证
- 页面私有组件状态:
- `src/views/order/candy/purchasing/index.vue`:目录当前仅包含 `index.vue`,无页面私有组件,已完成
- 补充说明:
- 未修改接口参数、路由路径、权限码、订单状态提交值、导出参数、导出文件名、查询/导出逻辑
- `orderStatus.value` 保持 `COMPLETE` / `REIMBURSE` 原样,仅在展示层通过 value 映射翻译
- 后端返回的商品描述、第三方订单号、系统来源等数据保持原样
- 注释掉的 `label="事件"` 保留原样,不属于可见展示文案
- `npm run build:prod` 已通过,仍为项目既有 `17` 条 warning未新增阻塞错误
- 线程一本轮完成后切回待分配
- 2026-04-27
- 线程一已新认领:`src/views/order/candy/purchasing/index.vue`
- 对应主要路由:运营管理 / Operations Management -> 营收支出 / Revenue and Expenses -> 消费商品订单 / Purchase Orders
- 认领前置检查:
- 已重读 `docs/i18n/线程协作.md`
- 已重读 `docs/i18n/翻译进度.md`
- 已重读 `docs/i18n/翻译清单.md`
- 已重读 `docs/i18n/主要路由.md`
- 已读取 `src/lang/messages/pages/en.js``src/lang/messages/pages/zh.js`
- 补充说明:
- `营收支出` 为父级菜单,本地无单独入口文件;本轮认领其下第一个实际子路由 `order/candy/purchasing/index`
- 已核对 `src/views/order/candy/purchasing` 目录当前仅包含 `index.vue`
- 2026-04-27
- 线程一已完成:`src/views/external/im.vue`
- 对应主要路由:系统管理 / System Management -> App系统 / App System -> IM通讯 / IM Communication
- 完成范围包括:
- 已读取并复核 `src/views/external/im.vue`
- 已确认该页面当前仅渲染外部 IM iframe无中文静态展示文本、按钮、表单、表格或提示文案
- 已执行中文残留扫描
- 已核对 `src/views/external` 目录;`app_doc_interface.vue` 不属于接口返回主路由 `external/im`,本轮不纳入
- 页面私有组件状态:
- `src/views/external/im.vue`:无页面私有组件,已完成
- 补充说明:
- 未修改源码、接口、路由路径、权限码或 iframe 地址
- 本轮仅同步 md 状态;因源码无改动,未执行构建
- 线程一本轮完成后切回待分配
- 2026-04-27
- 线程一已新认领:`src/views/external/im.vue`
- 对应主要路由:系统管理 / System Management -> App系统 / App System -> IM通讯 / IM Communication
- 认领前置检查:
- 已重读 `docs/i18n/线程协作.md`
- 已重读 `docs/i18n/翻译进度.md`
- 已重读 `docs/i18n/翻译清单.md`
- 已重读 `docs/i18n/主要路由.md`
- 已读取 `src/lang/messages/pages/en.js``src/lang/messages/pages/zh.js`
- 补充说明:
- 按主要路由顺序先检查 APP运行日志 / APP Runtime Logs但本地未发现 `src/views/log/breakdown` 入口文件,且全项目仅发现相关 API 方法,未发现对应视图文件;本轮先标记为入口文件缺失,暂跳过待确认
- `src/views/external` 目录当前包含 `im.vue``app_doc_interface.vue`,本轮仅认领接口返回主路由 `external/im` 对应的 `im.vue`
- 2026-04-27
- 线程一已完成:`src/views/sys/resources-manager/index.vue`
- 对应主要路由:系统管理 / System Management -> 资源管理 / Resource Management
- 完成范围包括:
- 筛选区 placeholder、搜索/刷新资源按钮、表格列头、本地授权类型展示国际化
- 新增 `pages.sysResourcesManager`
- 中文残留扫描
- 语言文件语法检查
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 同步更新
- 页面私有组件状态:
- `src/views/sys/resources-manager/index.vue`:目录当前仅包含 `index.vue`,无页面私有组件,已完成
- 补充说明:
- 未修改接口参数、路由路径、权限码、请求方式实际值、授权类型提交值、资源列表查询/刷新逻辑
- 后端返回的资源名称、映射路径与权限标识按原值展示
- 授权类型仅在展示层通过 `value` 映射翻译,提交值 `1` / `2` / `3` 保持原样
- `src/views/sys/resources-manager/*.vue` 当前无中文残留
- `src/lang/messages/pages/en.js``src/lang/messages/pages/zh.js` 语法校验通过
- `npm run build:prod` 已通过,仍为项目既有 `17` 条 warning未新增阻塞错误
- 线程一本轮完成后切回待分配
- 2026-04-27
- 线程二已完成:`src/views/sys/menu-manager/index.vue`
- 同步完成:
- `src/views/sys/menu-manager/menu-tree.vue`
- `src/views/sys/menu-manager/menu-edit.vue`
- 完成范围包括:
- 菜单树按钮、筛选 placeholder、当前选中节点提示、节点操作按钮、删除确认与取消提示国际化
- 菜单编辑表单标签、placeholder、按钮、校验提示、事件标题与本地菜单类型/状态展示国际化
- 新增 `pages.sysMenuManager`
- 目录级中文残留扫描
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 同步更新
- 页面私有组件状态:
- `src/views/sys/menu-manager/index.vue`:已随页面同步完成;`menu-tree.vue``menu-edit.vue` 为入口页直接引用的页面内功能文件,已同步完成
- 补充说明:
- 未修改接口参数、路由路径、权限码、菜单类型/状态提交值
- 后端返回的菜单名称、资源名称与权限数据保持原样
- `src/views/sys/menu-manager/*.vue` 当前无中文残留
- 直接执行 `npm run build:prod` 构建通过,当前仍保留项目既有 `17` 条 warning未新增阻塞错误
- 线程二本轮完成后切回待分配
- 2026-04-27
- 线程三已完成:`src/views/sys/role-manager/index.vue`
- 同步完成:
- `src/views/sys/role-manager/edit-role.vue`
- `src/views/sys/role-manager/authorize-role.vue`
- 对应主要路由:系统管理 / System Management -> 角色管理 / Role Management
- 完成范围包括:
- 列表筛选区、搜索/添加按钮、表格列头、操作按钮、删除确认与取消提示国际化
- 角色编辑抽屉标题、表单标签、placeholder、按钮与校验提示国际化
- 菜单授权抽屉标题、按钮与加载文案国际化
- 新增 `pages.sysRoleManager`
- 移除未使用的旧本地 `roles` / `accountStatus` 数据
- 目录级中文残留扫描
- 语言对象轻量语法检查
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 同步更新
- 页面私有组件状态:
- `src/views/sys/role-manager/edit-role.vue`:已随页面同步完成
- `src/views/sys/role-manager/authorize-role.vue`:已随页面同步完成
- 补充说明:
- 未修改接口参数、路由路径、权限码、后端返回的角色、菜单与权限数据,以及新增、编辑、授权、删除和分页逻辑
- `src/views/sys/role-manager/*.vue` 当前无中文残留
- `npm run build:prod` 已通过,仍为项目既有 `17` 条 warning未新增阻塞错误
- 线程三本轮完成后切回待分配
- 2026-04-27
- 线程一已新认领:`src/views/sys/resources-manager/index.vue`
- 对应主要路由:系统管理 / System Management -> 资源管理 / Resource Management
- 领取前动作:
- 已重新读取 `docs/i18n/线程协作.md`
- 已重新读取 `docs/i18n/翻译进度.md`
- 已重新读取 `docs/i18n/翻译清单.md`
- 已重新读取 `docs/i18n/主要路由.md`
- 已重新读取 `src/lang/messages/pages/en.js`
- 已重新读取 `src/lang/messages/pages/zh.js`
- 已发现线程二当前认领 `src/views/sys/menu-manager/index.vue`,线程三当前认领 `src/views/sys/role-manager/index.vue`,线程一已避开上述任务
- 已核对 `src/views/sys/resources-manager` 目录当前仅包含 `index.vue`,无页面私有组件
- 已确认当前无其他线程认领 `src/views/sys/resources-manager/index.vue`,本轮不与其他线程冲突
- 认领范围包括:
- 筛选区 placeholder、搜索/刷新资源按钮、表格列头、本地授权类型展示国际化
- 新增或复用 `pages.sysResourcesManager` 页面级 key
- 目录级中文残留扫描
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 同步更新
- 不包含:
- 接口参数
- 路由路径
- 权限码
- 请求方式实际值
- 授权类型提交值
- 后端返回的资源名称、映射路径与权限标识数据
- 2026-04-27
- 线程二已新认领:`src/views/sys/menu-manager/index.vue`
- 同步纳入范围:
- `src/views/sys/menu-manager/menu-tree.vue`
- `src/views/sys/menu-manager/menu-edit.vue`
- 对应主要路由:系统管理 / System Management -> 菜单管理 / Menu Management
- 领取前动作:
- 已重新读取 `docs/i18n/线程协作.md`
- 已重新读取 `docs/i18n/翻译进度.md`
- 已重新读取 `docs/i18n/翻译清单.md`
- 已重新读取 `docs/i18n/主要路由.md`
- 已重新读取 `src/lang/messages/pages/en.js`
- 已重新读取 `src/lang/messages/pages/zh.js`
- 已发现线程三当前认领 `src/views/sys/role-manager/index.vue`,线程二已避开该任务
- 已核对 `src/views/sys/menu-manager/index.vue` 入口直接引用 `menu-tree.vue``menu-edit.vue`,本轮一并处理
- 已确认当前无其他线程认领 `src/views/sys/menu-manager` 目录文件,本轮不与其他线程冲突
- 认领范围包括:
- 菜单树按钮、筛选 placeholder、当前选中节点提示、节点操作按钮、删除确认与取消提示国际化
- 菜单编辑表单标签、placeholder、按钮、校验提示、事件标题与本地菜单类型/状态展示国际化
- 新增或复用 `pages.sysMenuManager` 页面级 key
- 目录级中文残留扫描
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 同步更新
- 不包含:
- 接口参数
- 路由路径
- 权限码
- 菜单类型/状态提交值
- 后端返回的菜单名称、资源名称与权限数据
- 2026-04-27
- 线程三已新认领:`src/views/sys/role-manager/index.vue`
- 同步纳入范围:
- `src/views/sys/role-manager/edit-role.vue`
- `src/views/sys/role-manager/authorize-role.vue`
- 对应主要路由:系统管理 / System Management -> 角色管理 / Role Management
- 领取前动作:
- 已重新读取 `docs/i18n/线程协作.md`
- 已重新读取 `docs/i18n/翻译进度.md`
- 已重新读取 `docs/i18n/翻译清单.md`
- 已重新读取 `docs/i18n/主要路由.md`
- 已重新读取 `src/lang/messages/pages/en.js`
- 已重新读取 `src/lang/messages/pages/zh.js`
- 已核对 `src/views/sys/role-manager/index.vue` 入口直接引用 `edit-role.vue``authorize-role.vue`,本轮一并处理
- 已确认当前主要路由进行中为空,其他线程均待分配,本轮不与其他线程冲突
- 认领范围包括:
- 列表筛选区、搜索/添加按钮、表格列头、操作按钮、删除确认与取消提示国际化
- 角色编辑抽屉标题、表单标签、placeholder、按钮与校验提示国际化
- 菜单授权抽屉标题、按钮与加载文案国际化
- 新增或复用 `pages.sysRoleManager` 页面级 key
- 目录级中文残留扫描
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 同步更新
- 不包含:
- 接口参数
- 路由路径
- 权限码
- 后端返回的角色、菜单与权限数据
- 2026-04-27
- 线程二已完成:`src/views/sys/user-manager/index.vue`
- 同步完成:
- `src/views/sys/user-manager/edit-user.vue`
- 完成范围包括:
- 筛选区 placeholder、搜索/添加按钮、表格列头、状态展示、操作按钮、重置密码确认弹窗与取消提示国际化
- 编辑用户抽屉标题、表单标签、placeholder、按钮与校验提示国际化
- 新增 `pages.sysUserManager`
- 目录级中文残留扫描
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 同步更新
- 页面私有组件状态:
- `src/views/sys/user-manager/edit-user.vue`:已随页面同步完成
- 补充说明:
- 未修改接口参数、路由路径、权限码、用户状态实际值 `0` / `1`
- 接口返回的角色名称、用户账号、昵称、电话、邮箱等动态数据保持原样
- 查询、创建、修改、启停用户与重置密码逻辑保持原样
- `src/views/sys/user-manager/*.vue` 当前无中文残留
- 直接执行 `npm run build:prod` 构建通过,当前仍保留项目既有 `17` 条 warning未新增阻塞错误
- 线程二本轮完成后切回待分配
- 2026-04-27
- 线程三已完成:`src/views/user/user-device/index.vue`
- 对应主要路由:用户管理 / User Management -> 最新登记设备 / Latest Registered Devices
- 完成范围包括:
- 筛选区 placeholder、日期范围、搜索按钮、表格列头、加载文案与复制按钮国际化
- 新增 `pages.userDevice`
- 中文残留扫描
- 语言对象轻量语法检查
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 同步更新
- 页面私有组件状态:
- `src/views/user/user-device/index.vue`:无同目录页面私有组件,已完成
- 补充说明:
- 未修改接口参数、路由路径、权限码、设备号、系统来源 value、动态用户/设备数据、复制、查询与分页逻辑
- `src/views/user/user-device/index.vue` 当前无中文残留
- `npm run build:prod` 已通过,仍为项目既有 `17` 条 warning未新增阻塞错误
- 线程三本轮完成后切回待分配
- 2026-04-27
- 线程二已新认领:`src/views/sys/user-manager/index.vue`
- 同步纳入范围:
- `src/views/sys/user-manager/edit-user.vue`
- 领取前动作:
- 已重新读取 `docs/i18n/线程协作.md`
- 已重新读取 `docs/i18n/翻译进度.md`
- 已重新读取 `docs/i18n/翻译清单.md`
- 已重新读取 `docs/i18n/主要路由.md`
- 已重新读取 `src/lang/messages/pages/en.js`
- 已重新读取 `src/lang/messages/pages/zh.js`
- 已确认线程三当前认领 `src/views/user/user-device/index.vue`,本轮文件范围不冲突
- 已核对 `src/views/sys/user-manager` 目录包含 `index.vue` 与入口直接引用的 `edit-user.vue`
- 认领范围包括:
- 筛选区 placeholder、搜索/添加按钮、表格列头、状态展示、操作按钮、重置密码确认弹窗与取消提示国际化
- 编辑用户抽屉标题、表单标签、placeholder、按钮与校验提示国际化
- 新增或复用 `pages.sysUserManager` 页面级 key
- 目录级中文残留扫描
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 同步更新
- 不包括:
- 接口参数
- 路由路径
- 权限码
- 用户状态实际值 `0` / `1`
- 接口返回的角色名称、用户账号、昵称、电话、邮箱等动态数据
- 查询、创建、修改、启停用户与重置密码逻辑
- 2026-04-27
- 线程三已新认领:`src/views/user/user-device/index.vue`
- 对应主要路由:用户管理 / User Management -> 最新登记设备 / Latest Registered Devices
- 领取前动作:
- 已重新读取 `docs/i18n/线程协作.md`
- 已重新读取 `docs/i18n/翻译进度.md`
- 已重新读取 `docs/i18n/翻译清单.md`
- 已重新读取 `docs/i18n/主要路由.md`
- 已重新读取 `src/lang/messages/pages/en.js`
- 已重新读取 `src/lang/messages/pages/zh.js`
- 已核对 `src/views/user/user-device` 目录当前仅包含 `index.vue`,无同目录页面私有组件
- 已确认当前主要路由进行中为空,本轮不与其他线程冲突
- 认领范围包括:
- `src/views/user/user-device/index.vue`
- 筛选区 placeholder、日期范围、搜索按钮、表格列头、复制按钮与本地提示国际化
- 新增或复用 `pages.userDevice` 页面级 key
- 中文残留扫描
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 同步更新
- 不包含:
- 接口参数
- 路由路径
- 权限码
- 后端依赖值
- 2026-04-27
- 线程一已完成:`src/views/log/archive-device/index.vue`
- 完成范围包括:
- 筛选区 placeholder、搜索按钮、表格列头、删除操作与本地删除成功提示国际化
- 新增 `pages.archiveDevice`
- 中文残留扫描
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 同步更新
- 页面私有组件状态:
- `src/views/log/archive-device/index.vue`:无私有组件,已完成
- 补充说明:
- 未修改接口参数、路由路径、系统来源 value、设备号、动态列表数据与删除/查询逻辑
- `src/views/log/archive-device/index.vue` 当前无中文残留
- `src/lang/messages/pages/en.js``src/lang/messages/pages/zh.js` 语法校验通过
- 直接执行 `npm run build:prod` 构建通过,当前仍保留项目既有 `17` 条 warning未新增阻塞错误
- 线程一本轮完成后切回待分配
- 2026-04-27
- 线程三已完成:`src/views/version/app/index.vue`
- 同步完成:
- `src/views/version/app/app-version-edit.vue`
- `src/views/version/app/app-update-content.vue`
- 完成范围包括:
- 版本管理列表筛选区、表格列头、布尔状态展示、App 类型展示、操作菜单、复制提示、删除确认与服务强更确认国际化
- 版本编辑弹窗标题、表单标签、placeholder、按钮与校验提示国际化
- 更新描述弹窗标题、表格列头、语言展示、表单标签、placeholder、按钮、校验提示、删除确认与删除成功提示国际化
- 新增 `pages.appVersionManager`
- 目录级中文残留扫描
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 同步更新
- 页面私有组件状态:
- `src/views/version/app/app-version-edit.vue`:已随页面同步完成
- `src/views/version/app/app-update-content.vue`:已随页面同步完成
- 补充说明:
- 未改动接口参数、路由路径、平台 / 渠道 / 语言 / appType 等提交值、版本号/构建号/下载链接/描述内容等动态数据,以及新增、编辑、删除、服务强更与分页逻辑
- 目录级中文残留仅剩注释和注释掉的旧表单片段,不属于可见展示文案
- `npm run build:prod` 已通过,仍为项目既有 warning
- 线程三本轮完成后切回待分配
- 2026-04-27
- 线程二已完成:`src/views/game/ludo/index.vue`
- 完成范围包括:
- 筛选区 placeholder、搜索按钮、表格列头、玩家弹窗标题、按钮、分页提示、确认弹窗与本地状态/事件展示映射国际化
- 新增 `pages.gameLudo`
- 中文残留扫描
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md` 同步更新
- 页面私有组件状态:
- `src/views/game/ludo/index.vue`:无私有组件,已完成
- 补充说明:
- 本轮不修改接口参数、`RUN``HISTORY``WAIT``PROGRESS``END``BACK_DISBAND` 等状态值
- `permissionsSysOriginPlatforms``SearchRoomInput`、接口返回的动态数据、解散对局、加载更多与查询逻辑保持原样
- `src/views/game/ludo/index.vue` 当前无中文残留
- 直接执行 `npm run build:prod` 构建通过,当前仍保留项目既有 `22` 条 warning未新增阻塞错误
- 线程二本轮完成后切回待分配,暂不继续认领新任务
- 2026-04-27
- 线程一已新认领:`src/views/log/archive-device/index.vue`
- 领取前动作:
- 已重新读取 `docs/i18n/线程协作.md`
- 已重新读取 `docs/i18n/翻译进度.md`
- 已重新读取 `docs/i18n/翻译清单.md`
- 已重新读取 `docs/i18n/主要路由.md`
- 已重新读取 `src/lang/messages/pages/en.js`
- 已重新读取 `src/lang/messages/pages/zh.js`
- 已确认线程二当前认领 `src/views/game/ludo/index.vue`、线程三当前认领 `src/views/version/app/index.vue`,本轮不与其他线程冲突
- 已核对 `src/views/log/archive-device` 目录当前仅包含 `index.vue`,无页面私有组件
- 范围说明:
- 处理筛选区 placeholder、搜索按钮、表格列头、删除操作与本地删除成功提示国际化
- 不修改接口参数、路由路径、系统来源 value、设备号、动态列表数据与删除/查询逻辑
- 2026-04-27
- 线程一已完成:`src/views/family/list` 家族列表模块
- 完成范围包括:
- `src/views/family/list/index.vue`
- `src/views/family/list/family-member.vue`
- 筛选区、表格列头、操作按钮、成员弹窗、确认弹窗、本地提示、家族等级和成员角色本地展示映射国际化
- 新增 `pages.familyList`
- 中文残留扫描
- 构建验证
- 保持不变:
- 接口参数、路由路径、家族等级 key、成员角色 value、动态用户/家族数据与删除/移除逻辑
- 验证结果:
- `src/views/family/list/*.vue` 当前无中文残留
- `src/lang/messages/pages/en.js``src/lang/messages/pages/zh.js` 语法校验通过
- 直接执行 `npm run build:prod` 构建通过,当前为项目既有 `17` 条 warning未新增阻塞错误
- 线程一本轮完成后切回待分配
- 2026-04-27
- 线程一已新认领:`src/views/family/list/index.vue`
- 同步纳入范围:
- `src/views/family/list/family-member.vue`
- 领取前动作:
- 已重新读取 `docs/i18n/线程协作.md`
- 已重新读取 `docs/i18n/翻译进度.md`
- 已重新读取 `docs/i18n/翻译清单.md`
- 已重新读取 `docs/i18n/主要路由.md`
- 已重新读取 `src/lang/messages/pages/en.js`
- 已重新读取 `src/lang/messages/pages/zh.js`
- 已确认线程二当前认领 `src/views/game/ludo/index.vue`、线程三当前认领 `src/views/version/app/index.vue`,本轮不与其他线程冲突
- 已核对 `src/views/family/list/index.vue` 入口直接引用 `family-member.vue`,本轮一并处理
- 范围说明:
- 处理筛选区、表格列头、操作按钮、成员弹窗、确认弹窗、本地提示和等级/角色本地展示映射国际化
- 不修改接口参数、路由路径、家族等级 key、成员角色 value、动态用户/家族数据与删除/移除逻辑
- 2026-04-27
- 线程一已完成:`src/views/family/config` 家族配置模块
- 完成范围包括:
- `src/views/family/config/index.vue`
- `src/views/family/config/config-level/index.vue`
- `src/views/family/config/config-create-role/index.vue`
- `src/views/family/config/config-weekly-reward/index.vue`
- 入口页 tab 标题、3 个可见子页的按钮、表格列头、表单标签、placeholder、弹窗标题、提醒文案、校验提示与本地成功提示国际化
- 新增 `pages.familyConfig`
- 中文残留扫描
- 构建验证
- `docs/i18n/翻译进度.md``docs/i18n/翻译清单.md``docs/i18n/主要路由.md` 同步更新
- 补充说明:
- 本轮不修改接口参数、平台枚举值、等级 key、类型 value、资源 ID、接口返回的资源名称 / 徽章名称 / 礼物名称,以及新增、修改、查询逻辑
- 等级名称与等级类型仅做页面展示层本地映射,提交值仍使用原 `value`
- `src/views/family/config/**/*.vue` 当前无中文残留
- 直接执行 `npm run build:prod` 构建通过,当前为项目既有 `17` 条 warning未新增阻塞错误
- 线程一本轮完成后切回待分配
- 2026-04-22 - 2026-04-22
- 线程三已新认领:`src/views/version/app/index.vue` - 线程三已新认领:`src/views/version/app/index.vue`
- 同步纳入范围: - 同步纳入范围:
@ -2375,16 +2939,17 @@
## 强烈建议的执行顺序 ## 强烈建议的执行顺序
1. 新线程启动后,先读取 3 份协作文档 + `docs/i18n/主要路由.md` 1. 新线程启动后,先读取 3 份协作文档 + `docs/i18n/主要路由.md`
2. 先检查“已完成 `src/views` 页面私有组件复查任务”是否仍有待处理目录;若有,优先从这批目录中认领 2. `首页 Dashboard > docs/i18n/主要路由.md` 的顺序领取任务
3. 每次准备领取新任务前,再读取一次同样的文档集合,确认认领状态已更新到文档 3. 每次准备领取新任务前,再读取一次同样的文档集合,确认认领状态已更新到文档
4. 确认无人认领后,先在 md 中写明自己认领的文件 4. 确认无人认领后,先在 md 中写明自己认领的文件
5. 写完认领记录后,立刻再读取一次同样的文档集合,确认没有其他线程同时写入冲突 5. 认领页面时同步核对入口 import、局部注册、tab、动态组件、抽屉、弹窗与同目录私有组件范围
6. 确认认领信息已落盘后,再改自己认领范围内的页面、组件和对应翻译 key 6. 写完认领记录后,立刻再读取一次同样的文档集合,确认没有其他线程同时写入冲突
7. 如果需要新增公共 key优先使用已有命名体系避免同义重复 key 7. 确认认领信息已落盘后,再改自己认领范围内的页面、组件和对应翻译 key
8. 修改完成后先本地构建验证 8. 如果需要新增公共 key优先使用已有命名体系避免同义重复 key
9. 把结果同步写入 `翻译进度.md``翻译清单.md` 9. 修改完成后先本地构建验证
10. 在线程认领表里把状态改为“已完成”或“阻塞” 10. 把结果同步写入 `翻译进度.md``翻译清单.md`
11. 后续不要再新认领非主要路由页面;已经处理过的非主要路由保持现状即可 11. 在线程认领表里把状态改为“已完成”或“阻塞”
12. 后续不要再新认领非主要路由页面;已经处理过的非主要路由保持现状即可
## 线程之间如何“保持联系” ## 线程之间如何“保持联系”

View File

@ -24,12 +24,12 @@
- 读取 md 或源码时使用:`Get-Content -Raw -Encoding UTF8 <path>` - 读取 md 或源码时使用:`Get-Content -Raw -Encoding UTF8 <path>`
- 领取任务前先重读 3 份协作文档 + `docs/i18n/主要路由.md`,再决定是否写入新的认领记录 - 领取任务前先重读 3 份协作文档 + `docs/i18n/主要路由.md`,再决定是否写入新的认领记录
- 领取任务的推荐顺序:重读 3 份协作文档 + `docs/i18n/主要路由.md` -> 确认无人认领 -> 先写 md -> 再读同样的文档集合复查 -> 开始改代码 - 领取任务的推荐顺序:重读 3 份协作文档 + `docs/i18n/主要路由.md` -> 确认无人认领 -> 先写 md -> 再读同样的文档集合复查 -> 开始改代码
- 所有线程统一领取优先级:`首页 > docs/i18n/主要路由.md > 其他路由` - 所有线程统一领取优先级:`首页 > docs/i18n/主要路由.md`
- 只要首页或 `docs/i18n/主要路由.md` 中页面仍未完成,就不要跳到其他普通路由 - 只要首页或 `docs/i18n/主要路由.md` 中页面仍未完成,就不要跳到其他普通路由
- 读取最新语言文件,避免覆盖别人新增的 key - 读取最新语言文件,避免覆盖别人新增的 key
- `src/lang/messages/pages/en.js` - `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js` - `src/lang/messages/pages/zh.js`
- 扫描认领页面是否存在同目录私有子组件、抽屉、弹窗表单;如果有,一并检查中文展示文案 - 扫描认领页面是否存在入口 import、局部注册、tab、动态组件、同目录私有子组件、抽屉、弹窗表单;如果有,一并检查中文展示文案并在完成记录里写明私有组件状态
- 构建验证使用:`npm run build:prod` - 构建验证使用:`npm run build:prod`
- 单文件快速扫中文可用:`Select-String -Path <file> -Pattern '[\u4e00-\u9fa5]' -Encoding UTF8` - 单文件快速扫中文可用:`Select-String -Path <file> -Pattern '[\u4e00-\u9fa5]' -Encoding UTF8`
@ -56,7 +56,8 @@
- 不改路由路径 - 不改路由路径
- 不改权限码 - 不改权限码
- 不改后端依赖值 - 不改后端依赖值
- 认领优先级遵守:`首页 > docs/i18n/主要路由.md > 其他路由` - 认领优先级遵守:`首页 > docs/i18n/主要路由.md`
- 认领页面时同步检查该页面直接涉及的 `src/views/**` 页面内组件 / 私有组件
- 如果文本依赖接口返回且当前无法推断,先跳过,并把阻塞写入 md - 如果文本依赖接口返回且当前无法推断,先跳过,并把阻塞写入 md
- 领取任务后,先把认领信息写入 md确认无冲突后再开始改源码 - 领取任务后,先把认领信息写入 md确认无冲突后再开始改源码
- 完成后同步更新: - 完成后同步更新:

View File

@ -4,6 +4,8 @@
- 本文件只负责维护文件级待办、进行中、已完成与当前认领状态 - 本文件只负责维护文件级待办、进行中、已完成与当前认领状态
- 需要看主要路由的完整父子级结构、路由别名、路径和入口文件时,统一查看 `docs/i18n/主要路由.md` - 需要看主要路由的完整父子级结构、路由别名、路径和入口文件时,统一查看 `docs/i18n/主要路由.md`
- 文档中的英文路由名需要与侧边栏实际语言包 `src/lang/messages/base/menu-en.js` 保持一致;如有差异,以 `menu-en.js` 为准
- 注意 `src/lang/messages/en.js` 顶层旧中文 key 会在运行时覆盖 `menu-en.js` 的同名 key统一路由英文名时需要同步检查并消除这类重复覆盖
- 需要看阶段成果、构建验证与时间线时,统一查看 `docs/i18n/翻译进度.md` - 需要看阶段成果、构建验证与时间线时,统一查看 `docs/i18n/翻译进度.md`
- 状态说明: - 状态说明:
- `已完成` - `已完成`
@ -14,9 +16,10 @@
### 翻译范围 ### 翻译范围
- 后续任务范围只限 `docs/i18n/主要路由.md` 中列出的主要路由页面,以及这些页面直接涉及到的页面内组件 / 私有组件 - 后续任务范围只限 `docs/i18n/主要路由.md` 中列出的主要路由页面,以及这些页面直接涉及到的页面内组件 / 私有组件 / 直接公共组件
- 已经处理过的其他非主要路由页面保持现状,不回滚,也不再继续扩展翻译 - 已经处理过的其他非主要路由页面保持现状,不回滚,也不再继续扩展翻译
- 主要路由范围内,路由、导航、页面标题、选项、按钮、表单标签、表格列名、提示文案、空态文案等都属于处理范围 - 主要路由范围内,路由、导航、页面标题、选项、按钮、表单标签、表格列名、提示文案、空态文案等都属于处理范围
- 当前主要路由页面直接渲染的 `src/components/**` 公共组件也属于处理范围;如果公共组件影响范围较大,可以单独认领,但不能从页面完成标准中消失
### 禁止改动项 ### 禁止改动项
@ -51,8 +54,9 @@
## 领取优先级 ## 领取优先级
- 适用于所有线程,不只线程三 - 适用于所有线程,不只线程三
- 统一领取优先级:`已完成 src/views 页面私有组件复查 > 首页 > docs/i18n/主要路由.md` - 统一领取优先级:`首页 > docs/i18n/主要路由.md`
- 在“已完成 `src/views` 页面私有组件复查”完成前,暂不继续领取新的未完成普通页面 - 已完成 `src/views` 页面私有组件复查是历史临时任务,当前已完成,不再作为领取优先级的一环
- 后续认领页面时仍必须检查该页面直接涉及的 `src/views/**` 页面内组件 / 私有组件,以及直接渲染的 `src/components/**` 公共组件,并在完成记录里写明私有组件状态与直接公共组件状态
- 只要首页或 `主要路由.md` 中页面仍未完成,后续线程都应优先从这两部分中选择任务 - 只要首页或 `主要路由.md` 中页面仍未完成,后续线程都应优先从这两部分中选择任务
- `主要路由.md` 中具体优先领取哪个页面,仍可按原来的协作方式灵活分配,只要先读 md、先写认领、避免冲突 - `主要路由.md` 中具体优先领取哪个页面,仍可按原来的协作方式灵活分配,只要先读 md、先写认领、避免冲突
@ -63,23 +67,34 @@
- 详细父子级结构、路由别名、路径与入口文件统一见 `docs/i18n/主要路由.md` - 详细父子级结构、路由别名、路径与入口文件统一见 `docs/i18n/主要路由.md`
- 以下索引已按 `docs/i18n/主要路由.md` 当前父子级顺序同步更新 - 以下索引已按 `docs/i18n/主要路由.md` 当前父子级顺序同步更新
- 系统管理 / System Management - 系统管理 / System Management
- 用户管理 / User Management
- 角色管理 / Role Management
- 菜单管理 / Menu Management
- 资源管理 / Resource Management
- App系统 / App System - App系统 / App System
- 版本管理 / Version Management
- IM通讯 / IM Communication
- 请求黑名单 / Request Blacklist - 请求黑名单 / Request Blacklist
- 用户管理 / User Management - 用户管理 / User Management
- 用户列表 / User List - 用户列表 / User List页面本体已完成直接公共组件待联动复核
- 用户专属礼物制作 / User Custom Gift Creation - 用户专属礼物制作 / Custom User Gift Creation
- 封禁设备列表 / Blocked Device List
- 最新登记设备 / Latest Registered Devices
- 运营管理 / Operations Management - 运营管理 / Operations Management
- 营收支出 / Revenue and Expenses
- 消费商品订单 / Purchase Orders
- 金币收支记录 / Gold Transaction Records
- 数据配置 / Data Configuration - 数据配置 / Data Configuration
- 国家管理 / Country Management - 国家管理 / Country Management
- IM账号管理 / IM Account Management - IM账号管理 / IM Account Management
- 活动配置 / Activity Configuration - 活动配置 / Activity Configuration
- 活动管理 / Activity Management - 活动管理 / Activity Management
- 活动模版 / Activity Template - 活动模版 / Activity Templates
- 消息推送 / Message Push - 消息推送 / Message Push
- APP管理员 / App Administrator - APP管理员 / App Administrators
- App启动页 / App Launch Page - App启动页 / App Launch Page
- 系统公告管理 / System Notice Management - 系统公告管理 / System Notice Management
- 金币代理 / Gold Agent - 金币代理 / Gold Agents
- 区域配置 / Region Configuration - 区域配置 / Region Configuration
- 语音房间 / Voice Rooms - 语音房间 / Voice Rooms
- 房间资料列表 / Room Profile List - 房间资料列表 / Room Profile List
@ -90,14 +105,9 @@
- BD Lead / BD Lead - BD Lead / BD Lead
- 代理政策 / Agent Policy - 代理政策 / Agent Policy
- BD列表 / BD List - BD列表 / BD List
- 补充页面 - 家族管理 / Family Management
- Redis缓存管理 / Redis Cache Management - 家族配置 / Family Configuration
- 文件上传 / File Upload - 家族列表 / Family List
- 小工具 / Utilities
- 金币分析 / Gold Analysis
- 订单补偿 / Order Compensation
- WebSocket调试 / WebSocket Tool
- 抽奖概率配置 / Lottery Probability Settings
### 已完成文件平铺清单 ### 已完成文件平铺清单
@ -107,6 +117,9 @@
- `src/views/tools/gold-analyze/index.vue` - `src/views/tools/gold-analyze/index.vue`
- `src/views/tools/websocket/index.vue` - `src/views/tools/websocket/index.vue`
- `src/views/sys/request-blacklist/index.vue` - `src/views/sys/request-blacklist/index.vue`
- `src/views/version/app/index.vue`
- `src/views/version/app/app-version-edit.vue`
- `src/views/version/app/app-update-content.vue`
- `src/components/Breadcrumb/index.vue` - `src/components/Breadcrumb/index.vue`
- `src/components/HeaderSearch/index.vue` - `src/components/HeaderSearch/index.vue`
- `src/components/SizeSelect/index.vue` - `src/components/SizeSelect/index.vue`
@ -150,6 +163,20 @@
- `src/views/message/push/push-task.vue` - `src/views/message/push/push-task.vue`
- `src/views/user/user-table/index.vue` - `src/views/user/user-table/index.vue`
- `src/views/user/custom-gift/index.vue` - `src/views/user/custom-gift/index.vue`
- `src/views/log/archive-device/index.vue`
- `src/views/user/user-device/index.vue`
- `src/views/sys/user-manager/index.vue`
- `src/views/sys/user-manager/edit-user.vue`
- `src/views/sys/role-manager/index.vue`
- `src/views/sys/role-manager/edit-role.vue`
- `src/views/sys/role-manager/authorize-role.vue`
- `src/views/sys/menu-manager/index.vue`
- `src/views/sys/menu-manager/menu-tree.vue`
- `src/views/sys/menu-manager/menu-edit.vue`
- `src/views/sys/resources-manager/index.vue`
- `src/views/external/im.vue`
- `src/views/order/candy/purchasing/index.vue`
- `src/views/order/candy/running-water/index.vue`
- `src/components/data/UserInfo/BaseInfo/index.vue` - `src/components/data/UserInfo/BaseInfo/index.vue`
- `src/views/room/profile/index.vue` - `src/views/room/profile/index.vue`
- `src/views/room/profile/room-active-charts.vue` - `src/views/room/profile/room-active-charts.vue`
@ -235,6 +262,12 @@
- `src/views/user/app-manager/administrator/auth.vue` - `src/views/user/app-manager/administrator/auth.vue`
- `src/views/user/app-manager/administrator-auth-resource/index.vue` - `src/views/user/app-manager/administrator-auth-resource/index.vue`
- `src/views/user/im-account-manager/index.vue` - `src/views/user/im-account-manager/index.vue`
- `src/views/family/config/index.vue`
- `src/views/family/config/config-level/index.vue`
- `src/views/family/config/config-create-role/index.vue`
- `src/views/family/config/config-weekly-reward/index.vue`
- `src/views/family/list/index.vue`
- `src/views/family/list/family-member.vue`
- `src/views/sys/notice-message/index.vue` - `src/views/sys/notice-message/index.vue`
- `src/views/sys/start-page/index.vue` - `src/views/sys/start-page/index.vue`
- `src/views/sys/start-page/form-edit.vue` - `src/views/sys/start-page/form-edit.vue`
@ -248,45 +281,73 @@
- `src/views/tools/other/user-cancel-and-restore.vue` - `src/views/tools/other/user-cancel-and-restore.vue`
- `src/views/tools/other/user-room-region.vue` - `src/views/tools/other/user-room-region.vue`
- `src/views/tools/other/user-swap-user.vue` - `src/views/tools/other/user-swap-user.vue`
- `src/views/game/ludo/index.vue`
- `src/components/data/PropsRow/index.vue`
- 表格展示适配:表头自动换行 + 默认最小宽度补齐 - 表格展示适配:表头自动换行 + 默认最小宽度补齐
- 表格展示适配:表头 `.cell` 高度自适应 + 纵向居中修正 - 表格展示适配:表头 `.cell` 高度自适应 + 纵向居中修正
- 表单展示适配:标题纵向居中 - 表单展示适配:标题纵向居中
## 进行中 ## 进行中
- `src/views/game/ludo/index.vue`
- 状态:进行中(线程二)
- 范围:筛选区 placeholder、搜索按钮、表格列头、玩家弹窗标题、按钮、分页提示、确认弹窗与本地状态/事件展示映射国际化;不改接口参数、状态值、动态数据与解散查询逻辑
- `src/views/family/config/index.vue`
- 状态:进行中(线程一)
- 同步范围:`src/views/family/config/config-level/index.vue``src/views/family/config/config-create-role/index.vue``src/views/family/config/config-weekly-reward/index.vue`
- 范围:入口页 tab 标题、3 个可见子页的按钮、表格列头、表单标签、placeholder、弹窗标题、提醒文案与校验提示国际化不改接口参数、平台 value、等级 key、类型 value、动态资源名称与业务逻辑
- `src/views/version/app/index.vue`
- 状态:进行中(线程三)
- 同步范围:`src/views/version/app/app-version-edit.vue``src/views/version/app/app-update-content.vue`
- 范围筛选区、表格列头、状态展示、操作菜单、弹窗标题、表单标签、placeholder、按钮、校验提示、确认弹窗与本地提示国际化不改接口参数、路由路径、平台/渠道/语言/appType 等提交值、动态版本数据与业务逻辑
- 临时任务:已完成 `src/views` 页面私有组件复查 - 临时任务:已完成 `src/views` 页面私有组件复查
- 状态:进行中 - 状态:已完成;当前无可领取明确剩余目录,不再作为后续领取优先级的一环
- 范围说明: - 范围说明:
- 只检查 `src/views/**` 下已经标记“已完成”的页面目录 - 只检查 `src/views/**` 下已经标记“已完成”的页面目录
- 只复查页面私有组件,不包含公共组件目录 `src/components/**` - 这是历史临时任务,只复查页面私有组件,不包含公共组件目录 `src/components/**`
- 后续页面完成记录需要额外写明“私有组件状态” - 公共组件联动复查已从 2026-04-27 起作为新的独立临时任务记录在下方
- 当前优先复核目录: - 后续不再单独领取该临时任务;认领主路由页面时,随页面检查其直接涉及的页面内组件 / 私有组件,并在完成记录里写明“私有组件状态”
- 暂无明确剩余目录;领取前需重新读取本文件与 `docs/i18n/主要路由.md` 后确认 - 当前已发现但尚未补齐到已完成记录的私有组件:当前无
- 当前已发现但尚未补齐到已完成记录的私有组件:
- 当前无
- 当前明确排除: - 当前明确排除:
- `src/views/message/push/push-text-store.vue` - `src/views/message/push/push-text-store.vue`
- 原因:当前未纳入入口渲染链,继续按既有排除项处理 - 原因:当前未纳入入口渲染链,继续按既有排除项处理
- `src/views/props/props-source-group/select-propsr-popover.vue` - `src/views/props/props-source-group/select-propsr-popover.vue`
- 原因:当前未被入口页或 `form-edit.vue` 引用,继续按既有排除项处理 - 原因:当前未被入口页或 `form-edit.vue` 引用,继续按既有排除项处理
- 临时任务:对已完成主要路由页面做直接公共组件联动复查
- 状态:待处理
- 规则说明:
- 对已经标记“已完成”的主要路由页面,补充检查入口页直接渲染的 `src/components/**` 公共组件
- 如果公共组件已完成,补回完成记录;如果仍有中文展示文本,按公共组件任务单独认领或随页面补齐
- 如果中文属于注释、提交内容、接口返回数据或后端依赖值,必须写入保留原因
- 2026-04-27 初扫范围:
- 扫描 `### 已完成文件平铺清单` 中已完成的 `src/views/**/*.vue`
- 提取这些页面直接 `import "@/components/**"` 的公共组件
- 对解析到的组件执行中文命中扫描
- 本轮已完成公共组件:
- `src/components/data/PropsRow/index.vue`
- 完成线程:线程一
- 关联页面:活动管理、砸金蛋记录、抽奖概率配置、资源组配置、代理钻石政策、代理政策等已完成页面
- 说明:组件内可见“永久”已国际化;剩余中文仅为注释,不属于可见展示文案
- 当前扫描到仍需复核的“已完成页面 -> 直接公共组件”:
- `src/views/activity/template-cnf/form-edit.vue` -> `src/components/data/GiftSelect/index.vue`(中文命中 3
- `src/views/activity/template-cnf/reward-edit.vue` -> `src/components/data/AssociatedResources/index.vue`(中文命中 9
- `src/views/cnf/lottery/select-prize.vue` -> `src/components/data/PropsSourceSelectPopover/index.vue`(中文命中 2
- `src/views/game/egg/egg-lottery-cnf/index.vue` -> `src/components/data/PropsSourceSelectDrawer/index.vue`(中文命中 16
- `src/views/game/ludo/index.vue` -> `src/components/data/RoomDeatilsDrawer/index.vue`(中文命中 1
- `src/views/room/profile/index.vue` -> `src/components/data/RoomDeatilsDrawer/index.vue`(中文命中 1
- `src/views/sys/menu-manager/menu-edit.vue` -> `src/components/IconsPanel/index.vue`(中文命中 2
- `src/views/user/im-account-manager/index.vue` -> `src/components/data/Gender/index.vue`(中文命中 1
- `src/views/user/user-table/index.vue` -> `src/components/data/AccountHanle/index.vue`(中文命中 1历史保留默认“警告”属于提交内容
- `src/views/user/user-table/index.vue` -> `src/components/data/AddOtherRecharge/index.vue`(中文命中 17
- `src/views/user/user-table/index.vue` -> `src/components/data/AddOtherRechargeDialog/index.vue`(中文命中 6
- `src/views/user/user-table/index.vue` -> `src/components/data/DiamondRunningWaterDialog/index.vue`(中文命中 8
- `src/views/user/user-table/index.vue` -> `src/components/data/DiamondSalaryRunningWaterDialog/index.vue`(中文命中 8
- `src/views/user/user-table/index.vue` -> `src/components/data/EditDiamondCoinDeductionForm/index.vue`(中文命中 9
- `src/views/user/user-table/index.vue` -> `src/components/data/EditUserGameCouponRewardForm/index.vue`(中文命中 12
- `src/views/user/user-table/index.vue` -> `src/components/data/EditUserGoldCoinDeductionForm/index.vue`(中文命中 9
- `src/views/user/user-table/index.vue` -> `src/components/data/EditUserGoldCoinRewardForm/index.vue`(中文命中 7历史已处理需确认是否仅剩注释
- `src/views/user/user-table/index.vue` -> `src/components/data/GoldRunningWaterDialog/index.vue`(中文命中 18
- `src/views/user/user-table/index.vue` -> `src/components/data/IpDeviceHandle/index.vue`(中文命中 7
- `src/views/user/user-table/index.vue` -> `src/components/data/UserAccountStatusLogDrawer/index.vue`(中文命中 8
- `src/views/user/user-table/index.vue` -> `src/components/data/UserRegistrationOverviewCharts/dialog.vue`(中文命中 1
- `src/views/user/user-table/index.vue` -> `src/components/data/UserVideoViolationTableDialog/index.vue`(中文命中 5
- 当前未列入“仍需复核”的直接公共组件:
- 直接组件文件不存在或未解析到本地 `.vue` 文件
- 扫描无中文命中
- 已在历史记录中完成且当前无中文命中
## 优先待处理 ## 优先待处理
- 已完成 `src/views` 页面目录中的私有组件复查任务
- 主要路由中已部分完成、但仍需继续收口的入口页 - 主要路由中已部分完成、但仍需继续收口的入口页
- 主要路由中的其他页面 - 主要路由中的其他页面
- 统一参考 `docs/i18n/主要路由.md` - 统一参考 `docs/i18n/主要路由.md`
@ -324,6 +385,12 @@
- `src/components/data/UserInfo/AccountStatusLatestLog/index.vue`:已完成(线程二) - `src/components/data/UserInfo/AccountStatusLatestLog/index.vue`:已完成(线程二)
## 本轮保留项 ## 本轮保留项
- `src/views/log/breakdown/index.vue`
- 当前保留为待确认
- 原因:主要路由接口返回 APP运行日志 / APP Runtime Logs路径为 `log/breakdown/index`,但本地未发现 `src/views/log/breakdown` 入口文件;全项目仅发现相关 API 方法,未发现对应视图文件
- `src/views/order/candy/purchasing/index.vue`
- 当前保留注释掉的 `label="事件"` 原样
- 原因:该表格列已被注释,不属于可见展示文案
- `src/views/cnf/lottery/index.vue` - `src/views/cnf/lottery/index.vue`
- 当前保留注释“扩展属性”原样 - 当前保留注释“扩展属性”原样
- 原因:该内容仅为代码注释,不属于可见展示文案;`select-prize.vue` 已完成奖品选择弹窗私有组件复查 - 原因:该内容仅为代码注释,不属于可见展示文案;`select-prize.vue` 已完成奖品选择弹窗私有组件复查

View File

@ -4,20 +4,24 @@
- 本文件只负责记录全局进展、阶段成果、构建验证结果与下一步目标 - 本文件只负责记录全局进展、阶段成果、构建验证结果与下一步目标
- 主要路由的完整父子级结构、路由别名、路径、入口文件与主路由优先级,以 `docs/i18n/主要路由.md` 为准 - 主要路由的完整父子级结构、路由别名、路径、入口文件与主路由优先级,以 `docs/i18n/主要路由.md` 为准
- 文档中的英文路由名需要与侧边栏实际语言包 `src/lang/messages/base/menu-en.js` 保持一致;如有差异,以 `menu-en.js` 为准
- 注意 `src/lang/messages/en.js` 顶层旧中文 key 会在运行时覆盖 `menu-en.js` 的同名 key统一路由英文名时需要同步检查并消除这类重复覆盖
- 文件级待办、进行中、已完成与认领状态,以 `docs/i18n/翻译清单.md` 为准 - 文件级待办、进行中、已完成与认领状态,以 `docs/i18n/翻译清单.md` 为准
- 协作规则、读 md 顺序、认领要求与交接规范,以 `docs/i18n/线程协作.md` 为准 - 协作规则、读 md 顺序、认领要求与交接规范,以 `docs/i18n/线程协作.md` 为准
## 当前目标 ## 当前目标
- 后续只对 `docs/i18n/主要路由.md` 中的主要路由页面及其直接涉及组件继续做国际化 - 后续只对 `docs/i18n/主要路由.md` 中的主要路由页面及其直接涉及组件继续做国际化
- 主要路由页面的完成标准包含页面本体、`src/views/**` 页面内组件 / 私有组件,以及该页面直接渲染的 `src/components/**` 公共组件
- 已经处理过的其他非主要路由页面保持现状,不回滚,也不再继续扩展 - 已经处理过的其他非主要路由页面保持现状,不回滚,也不再继续扩展
- 当前先支持 `en``zh` - 当前先支持 `en``zh`
- 后续如果增加 `bn``ar``tr` 等语言,优先复用现有键名体系 - 后续如果增加 `bn``ar``tr` 等语言,优先复用现有键名体系
## 任务优先级 ## 任务优先级
- 全线程统一优先级:`已完成 src/views 页面私有组件复查 > 首页 > docs/i18n/主要路由.md` - 全线程统一优先级:`首页 > docs/i18n/主要路由.md`
- 在“已完成 `src/views` 页面私有组件复查”完成前,暂不继续领取新的未完成普通页面 - 已完成 `src/views` 页面私有组件复查是历史临时任务,当前已完成,不再作为领取优先级的一环
- 后续认领页面时仍必须检查该页面直接涉及的 `src/views/**` 页面内组件 / 私有组件,以及直接渲染的 `src/components/**` 公共组件,并在完成记录里写明私有组件状态与直接公共组件状态
- 只要首页 `Dashboard` 模块或 `主要路由.md` 中页面仍未完成,后续线程领取新任务时都应优先从这两部分中选择 - 只要首页 `Dashboard` 模块或 `主要路由.md` 中页面仍未完成,后续线程领取新任务时都应优先从这两部分中选择
- `主要路由.md` 中具体先领哪个页面仍可灵活分配,但不得跳过首页整体优先级 - `主要路由.md` 中具体先领哪个页面仍可灵活分配,但不得跳过首页整体优先级
@ -48,22 +52,32 @@
- 以下摘要已按 `docs/i18n/主要路由.md` 当前父子级顺序同步更新 - 以下摘要已按 `docs/i18n/主要路由.md` 当前父子级顺序同步更新
- 已完成主路由摘要: - 已完成主路由摘要:
- 系统管理 / System Management - 系统管理 / System Management
- 用户管理 / User Management
- 角色管理 / Role Management
- 菜单管理 / Menu Management
- App系统 / App System - App系统 / App System
- 版本管理 / Version Management
- IM通讯 / IM Communication
- 请求黑名单 / Request Blacklist - 请求黑名单 / Request Blacklist
- 用户管理 / User Management - 用户管理 / User Management
- 用户列表 / User List - 用户列表 / User List页面本体已完成直接公共组件待联动复核
- 封禁设备列表 / Blocked Device List
- 最新登记设备 / Latest Registered Devices
- 运营管理 / Operations Management - 运营管理 / Operations Management
- 营收支出 / Revenue and Expenses
- 消费商品订单 / Purchase Orders
- 金币收支记录 / Gold Transaction Records
- 数据配置 / Data Configuration - 数据配置 / Data Configuration
- 国家管理 / Country Management - 国家管理 / Country Management
- IM账号管理 / IM Account Management - IM账号管理 / IM Account Management
- 活动配置 / Activity Configuration - 活动配置 / Activity Configuration
- 活动管理 / Activity Management - 活动管理 / Activity Management
- 活动模版 / Activity Template - 活动模版 / Activity Templates
- 消息推送 / Message Push - 消息推送 / Message Push
- APP管理员 / App Administrator - APP管理员 / App Administrators
- App启动页 / App Launch Page - App启动页 / App Launch Page
- 系统公告管理 / System Notice Management - 系统公告管理 / System Notice Management
- 金币代理 / Gold Agent - 金币代理 / Gold Agents
- 区域配置 / Region Configuration - 区域配置 / Region Configuration
- 语音房间 / Voice Rooms - 语音房间 / Voice Rooms
- 房间资料列表 / Room Profile List - 房间资料列表 / Room Profile List
@ -74,14 +88,9 @@
- BD Lead / BD Lead - BD Lead / BD Lead
- 代理政策 / Agent Policy - 代理政策 / Agent Policy
- BD列表 / BD List - BD列表 / BD List
- 已完成但未在当前主要路由菜单返回中命中的补充页面: - 家族管理 / Family Management
- Redis缓存管理 / Redis Cache Management - 家族配置 / Family Configuration
- 文件上传 / File Upload - 家族列表 / Family List
- 小工具 / Utilities
- 金币分析 / Gold Analysis
- 订单补偿 / Order Compensation
- WebSocket调试 / WebSocket Tool
- 抽奖概率配置 / Lottery Probability Settings
### 基础能力 ### 基础能力
- 已接入项目国际化基础能力 - 已接入项目国际化基础能力
@ -108,6 +117,257 @@
## 本轮新增进展 ## 本轮新增进展
### 2026-04-27
- 已调整协作规则:
- 说明:主要路由页面完成标准从“页面本体 + `src/views/**` 私有组件”扩展为“页面本体 + `src/views/**` 私有组件 + 页面直接渲染的 `src/components/**` 公共组件”
- 后续如果公共组件影响范围较大,可以单独认领为公共组件任务,但必须在当前页面完成记录和 `docs/i18n/翻译清单.md` 中写明公共组件状态,不能默认排到最后或漏记
- 已同步更新 `docs/i18n/线程协作.md``docs/i18n/翻译清单.md`
- 已新增临时复查任务:
- 对已完成主要路由页面做直接公共组件联动复查
- 说明:不是只有 `用户列表 / User List` 需要补查;所有已完成主要路由页面都需要回扫直接渲染的 `src/components/**` 公共组件
- 已对 `docs/i18n/翻译清单.md` 的已完成 `src/views/**/*.vue` 执行初扫,筛出仍有中文命中的直接公共组件并写入 `docs/i18n/翻译清单.md`
- 初扫命中的页面范围包括活动模板、抽奖配置、砸金蛋、Ludo、房间资料、菜单管理、主播政策、IM账号管理、用户列表等
- 后续建议优先按“公共组件复用度”认领,例如 `PropsRow``RoomDeatilsDrawer` 这类被多个已完成页面引用的组件优先处理
- 已完成公共组件联动复查:
- `src/components/data/PropsRow/index.vue`
- 说明:已完成多个已完成主路由页面直接复用的 PropsRow 组件可见“永久”文本国际化;`item.remark`、数量、天数、道具类型、图片地址与接口返回资源数据保持原样
- 已补充页面级语言 key
- `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js`
- 新增范围:`pages.propsRow.word.permanent`
- 已完成验证:
- `src/components/data/PropsRow/index.vue` 中文残留扫描完成,剩余中文仅为注释“道具券 / 荣誉活动”,不属于可见展示文案
- `src/lang/messages/pages/en.js``src/lang/messages/pages/zh.js` 语法校验通过
- `npm run build:prod` 构建通过
- 说明:当前仍保留项目既有 `17` 条 warning未因本轮 `PropsRow` 国际化改动新增阻塞错误
- 已完成页面:
- `src/views/order/candy/running-water/index.vue`
- 说明:已完成运营管理 / 营收支出 / 金币收支记录页面筛选区系统、类型、来源、用户 ID、Trace ID、ID、日期范围、分页数量、搜索按钮、表格列头、收支类型展示、加载更多按钮、时间范围提示、跨年限制提示与全部加载完成提示国际化接口参数、路由路径、权限码、分页逻辑、查询逻辑、枚举提交值与后端返回流水数据保持原样
- 页面私有组件状态:
- `src/views/order/candy/running-water/index.vue`:目录当前仅包含 `index.vue`,无页面私有组件,已完成
- 已补充页面级语言 key
- `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js`
- 新增范围:`pages.goldRunningWater`
- 已补充来源名称展示映射:
- `src/lang/messages/en.js`
- 说明:为 `currencyOrigins` 中的中文来源名补充英文顶层映射;原 `value`、接口参数和查询逻辑不变
- 已完成模块级复核:
- `src/views/order/candy/running-water/*.vue`
- 说明已执行目录级中文残留扫描当前未发现剩余中文可见文本后端返回的用户、备注、Trace ID、记录 ID、时间与金币数值等动态数据按原值展示
- 已完成验证:
- `src/lang/messages/pages/en.js``src/lang/messages/pages/zh.js` 语法校验通过
- `currencyOrigins` 英文映射缺失检查通过
- `npm run build:prod` 构建通过
- 说明:当前仍保留项目既有 `17` 条 warning未因本轮 `order/candy/running-water` 国际化改动新增阻塞错误
- 已完成页面:
- `src/views/order/candy/purchasing/index.vue`
- 说明:已完成运营管理 / 营收支出 / 消费商品订单页面筛选区、日期范围、搜索/导出按钮、用户总充值提示、表格列头、朋友标记、状态展示、购买/修改时间前缀、详情按钮、导出条件抽屉标题、表单标签、placeholder、关闭/导出按钮、校验提示与导出状态提示国际化;接口参数、路由路径、权限码、订单状态提交值、导出参数、导出文件名、查询/导出逻辑保持原样
- 页面私有组件状态:
- `src/views/order/candy/purchasing/index.vue`:目录当前仅包含 `index.vue`,无页面私有组件,已完成
- 已补充页面级语言 key
- `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js`
- 新增范围:`pages.purchaseOrders`
- 已完成模块级复核:
- `src/views/order/candy/purchasing/*.vue`
- 说明:已执行目录级中文残留扫描;仅剩注释掉的 `label="事件"`,不属于可见展示文案,已在清单保留项中记录
- 已完成验证:
- `src/lang/messages/pages/en.js``src/lang/messages/pages/zh.js` 语法校验通过
- `npm run build:prod` 构建通过
- 说明:当前仍保留项目既有 `17` 条 warning未因本轮 `order/candy/purchasing` 国际化改动新增阻塞错误
- 已完成页面:
- `src/views/external/im.vue`
- 说明:已完成系统管理 / App系统 / IM通讯页面复核该页面当前仅渲染外部 IM iframe无中文静态展示文本、按钮、表单、表格或提示文案接口参数、路由路径、权限码、iframe 地址与 resize 逻辑保持原样
- 页面私有组件状态:
- `src/views/external/im.vue`:无页面私有组件,已完成
- 已完成模块级复核:
- `src/views/external/im.vue`
- 说明:已执行中文残留扫描,当前未发现剩余中文可见文本;同目录 `app_doc_interface.vue` 不属于接口返回主路由 `external/im`,本轮不纳入
- 本轮保留 / 待确认:
- APP运行日志 / APP Runtime Logs主要路由接口返回路径为 `log/breakdown/index`,但本地未发现 `src/views/log/breakdown` 入口文件;全项目仅发现相关 API 方法,未发现对应视图文件,已在清单中标记为入口文件缺失,暂跳过待确认
- 验证说明:
- 本轮未修改源码,仅同步 md 状态;因源码无改动,未执行构建
- 已完成页面:
- `src/views/sys/resources-manager/index.vue`
- 说明:已完成系统管理 / 资源管理页面筛选区 placeholder、搜索/刷新资源按钮、表格列头、本地授权类型展示国际化;接口参数、路由路径、权限码、请求方式实际值、授权类型提交值、资源列表查询/刷新逻辑保持原样
- 页面私有组件状态:
- `src/views/sys/resources-manager/index.vue`:目录当前仅包含 `index.vue`,无页面私有组件,已完成
- 已补充页面级语言 key
- `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js`
- 新增范围:`pages.sysResourcesManager`
- 已完成模块级复核:
- `src/views/sys/resources-manager/*.vue`
- 说明:已执行目录级中文残留扫描,当前未发现剩余中文可见文本
- 已完成验证:
- `src/lang/messages/pages/en.js``src/lang/messages/pages/zh.js` 语法校验通过
- `npm run build:prod` 构建通过
- 说明:当前仍保留项目既有 `17` 条 warning未因本轮 `sys/resources-manager` 国际化改动新增阻塞错误
- 已完成页面:
- `src/views/sys/menu-manager/index.vue`
- `src/views/sys/menu-manager/menu-tree.vue`
- `src/views/sys/menu-manager/menu-edit.vue`
- 说明:已完成系统管理 / 菜单管理页面的菜单树按钮、筛选 placeholder、当前选中节点提示、节点操作按钮、删除确认与取消提示以及菜单编辑表单标签、placeholder、按钮、校验提示、事件标题与本地菜单类型/状态展示国际化;接口参数、路由路径、权限码、菜单类型/状态提交值、后端返回菜单名称、资源名称与权限数据保持原样
- 页面私有组件状态:
- `src/views/sys/menu-manager/index.vue`:已随页面同步完成;`menu-tree.vue``menu-edit.vue` 为入口页直接引用的页面内功能文件,已同步完成
- 已补充页面级语言 key
- `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js`
- 新增范围:`pages.sysMenuManager`
- 已完成模块级复核:
- `src/views/sys/menu-manager/*.vue`
- 说明:已执行目录级中文残留扫描;当前未发现剩余中文可见文本
- 已完成验证:
- 直接执行 `npm run build:prod` 构建通过
- 说明:当前仍保留项目既有 `17` 条 warning未因本轮 `sys/menu-manager` 国际化改动新增阻塞错误
- 已完成页面:
- `src/views/sys/role-manager/index.vue`
- `src/views/sys/role-manager/edit-role.vue`
- `src/views/sys/role-manager/authorize-role.vue`
- 说明:已完成系统管理 / 角色管理页面列表筛选区、搜索/添加按钮、表格列头、操作按钮、删除确认与取消提示、角色编辑抽屉标题、表单标签、placeholder、按钮、校验提示、菜单授权抽屉标题、按钮与加载文案国际化接口参数、路由路径、权限码、后端返回的角色、菜单与权限数据以及新增、编辑、授权、删除和分页逻辑保持原样
- 页面私有组件状态:
- `src/views/sys/role-manager/index.vue`:已随页面同步完成;`edit-role.vue``authorize-role.vue` 为入口页直接引用的页面内功能文件,已同步完成
- 已补充页面级语言 key
- `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js`
- 新增范围:`pages.sysRoleManager`
- 已完成模块级复核:
- `src/views/sys/role-manager/*.vue`
- 说明:已执行目录级中文残留扫描;当前未发现剩余中文可见文本
- 已完成验证:
- 语言对象轻量语法检查通过
- 直接执行 `npm run build:prod` 构建通过
- 说明:当前仍保留项目既有 `17` 条 warning未因本轮 `sys/role-manager` 国际化改动新增阻塞错误
- 已完成页面:
- `src/views/sys/user-manager/index.vue`
- `src/views/sys/user-manager/edit-user.vue`
- 说明:已完成系统管理 / 用户管理页面筛选区 placeholder、搜索/添加按钮、表格列头、状态展示、操作按钮、重置密码确认弹窗、取消提示、编辑用户抽屉标题、表单标签、placeholder、按钮与校验提示国际化接口参数、路由路径、权限码、用户状态实际值 `0` / `1`、接口返回角色/用户动态数据与业务逻辑保持原样
- 页面私有组件状态:
- `src/views/sys/user-manager/index.vue`:已随页面同步完成;`edit-user.vue` 为入口页直接引用的编辑用户抽屉,已同步完成
- 已补充页面级语言 key
- `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js`
- 新增范围:`pages.sysUserManager`
- 已完成模块级复核:
- `src/views/sys/user-manager/*.vue`
- 说明:已执行目录级中文残留扫描;当前未发现剩余中文可见文本
- 已完成验证:
- 直接执行 `npm run build:prod` 构建通过
- 说明:当前仍保留项目既有 `17` 条 warning未因本轮 `sys/user-manager` 国际化改动新增阻塞错误
- 已完成页面:
- `src/views/user/user-device/index.vue`
- 说明:已完成最新登记设备页面筛选区 placeholder、日期范围、搜索按钮、表格列头、加载文案与复制按钮国际化接口参数、路由路径、权限码、设备号、系统来源 value、动态用户/设备数据、复制、查询与分页逻辑保持原样
- 页面私有组件状态:
- `src/views/user/user-device/index.vue`:无同目录页面私有组件,已完成
- 已补充页面级语言 key
- `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js`
- 新增范围:`pages.userDevice`
- 已完成模块级复核:
- `src/views/user/user-device/*.vue`
- 说明:已执行目录级中文残留扫描;当前未发现剩余中文可见文本
- 已完成验证:
- 语言对象轻量语法检查通过
- 直接执行 `npm run build:prod` 构建通过
- 说明:当前仍保留项目既有 `17` 条 warning未因本轮 `user-device` 国际化改动新增阻塞错误
- 已完成页面:
- `src/views/log/archive-device/index.vue`
- 说明:已完成封禁设备列表筛选区 placeholder、搜索按钮、表格列头、删除操作与本地删除成功提示国际化接口参数、路由路径、系统来源 value、设备号、动态列表数据与删除/查询逻辑保持原样
- 页面私有组件状态:
- `src/views/log/archive-device/index.vue`:无私有组件,已完成
- 已补充页面级语言 key
- `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js`
- 新增范围:`pages.archiveDevice`
- 已完成模块级复核:
- `src/views/log/archive-device/*.vue`
- 说明:已执行目录级中文残留扫描;当前未发现剩余中文可见文本
- 已完成验证:
- `src/lang/messages/pages/en.js``src/lang/messages/pages/zh.js` 语法校验通过
- 直接执行 `npm run build:prod` 构建通过
- 说明:当前仍保留项目既有 `17` 条 warning未因本轮 `archive-device` 国际化改动新增阻塞错误
- 已完成页面:
- `src/views/version/app/index.vue`
- 说明已完成版本管理列表筛选区、表格列头、布尔状态展示、App 类型展示、操作菜单、复制提示、删除确认与服务强更确认国际化;接口参数、路由路径、平台 / 渠道 / 语言 / appType 等提交值、版本号/构建号/下载链接/描述内容等动态数据,以及新增、编辑、删除、服务强更与分页逻辑保持原样
- 页面私有组件状态:
- `src/views/version/app/app-version-edit.vue`:已随页面同步完成
- `src/views/version/app/app-update-content.vue`:已随页面同步完成
- 已补充页面级语言 key
- `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js`
- 新增范围:`pages.appVersionManager`
- 已完成模块级复核:
- `src/views/version/app/*.vue`
- 说明:已执行目录级中文残留扫描;当前残留中文仅为注释和注释掉的旧表单片段,不属于可见展示文案
- 已完成构建验证:
- `npm run build:prod` 已通过
- 当前仍保留项目既有 warning本轮无新增阻塞错误
- 已完成页面:
- `src/views/game/ludo/index.vue`
- 说明:已完成 Ludo 对局页面筛选区 placeholder、搜索按钮、表格列头、玩家弹窗标题、按钮、分页提示、确认弹窗与本地状态/事件展示映射国际化;接口参数、`RUN``HISTORY``WAIT``PROGRESS``END``BACK_DISBAND` 等状态值、动态房间/玩家数据与解散、加载更多、查询逻辑保持原样
- 页面私有组件状态:
- `src/views/game/ludo/index.vue`:无私有组件,已完成
- 已补充页面级语言 key
- `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js`
- 新增范围:`pages.gameLudo`
- 已完成模块级复核:
- `src/views/game/ludo/index.vue`
- 说明:已执行中文残留扫描;当前未发现剩余中文可见文本
- 已完成验证:
- 直接执行 `npm run build:prod` 构建通过
- 说明:当前仍保留项目既有 `22` 条 warning未因本轮 `game/ludo` 国际化改动新增阻塞错误
- 已完成页面:
- `src/views/family/list/index.vue`
- `src/views/family/list/family-member.vue`
- 说明:已完成家族列表筛选区、日期范围、表格列头、操作按钮、成员弹窗、确认弹窗、本地提示、家族等级与成员角色本地展示映射国际化;接口参数、路由路径、家族等级 key、成员角色 value、动态用户/家族数据与删除/移除逻辑保持原样
- 页面私有组件状态:
- `src/views/family/list/index.vue`:已随页面同步完成;`family-member.vue` 为入口页直接引用的成员弹窗功能文件,已同步完成
- 已补充页面级语言 key
- `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js`
- 新增范围:`pages.familyList`
- 已完成模块级复核:
- `src/views/family/list/*.vue`
- 说明:已执行目录级中文残留扫描;当前未发现剩余中文可见文本
- 已完成验证:
- `src/lang/messages/pages/en.js``src/lang/messages/pages/zh.js` 语法校验通过
- 直接执行 `npm run build:prod` 构建通过
- 说明:当前仍保留项目既有 `17` 条 warning未因本轮 `family/list` 国际化改动新增阻塞错误
- 已完成页面:
- `src/views/family/config/index.vue`
- `src/views/family/config/config-level/index.vue`
- `src/views/family/config/config-create-role/index.vue`
- `src/views/family/config/config-weekly-reward/index.vue`
- 说明:已完成家族配置入口页 tab、家族等级配置、创建家族规则、创建每周奖励规则的按钮、表格列头、表单标签、placeholder、弹窗标题、提醒文案、校验提示与本地成功提示国际化接口参数、平台枚举值、等级 key、类型 value、资源 ID、动态资源名称与业务逻辑保持原样
- 页面私有组件状态:
- `src/views/family/config/index.vue`:已随页面同步完成;`config-level/index.vue``config-create-role/index.vue``config-weekly-reward/index.vue` 均为入口页直接渲染的页面内功能文件,已同步完成
- 已补充页面级语言 key
- `src/lang/messages/pages/en.js`
- `src/lang/messages/pages/zh.js`
- 新增范围:`pages.familyConfig`
- 已完成模块级复核:
- `src/views/family/config/**/*.vue`
- 说明:已执行目录级中文残留扫描;当前未发现剩余中文可见文本
- 已完成验证:
- 直接执行 `npm run build:prod` 构建通过
- 说明:当前仍保留项目既有 `17` 条 warning未因本轮 `family/config` 国际化改动新增阻塞错误
### 2026-04-22 ### 2026-04-22
- 已完成页面: - 已完成页面:
@ -1052,15 +1312,16 @@
## 当前进行中 ## 当前进行中
- 历史已完成 `src/views` 页面私有组件复查任务当前优先于新页面认领 - 历史临时任务“已完成 `src/views` 页面私有组件复查”已完成,当前无明确剩余目录;后续不再作为领取优先级检查项
- 下一步目标: - 下一步目标:
- 先补查已标记完成页面目录中的私有组件,并把组件状态补写入进度文档 - 继续按 `docs/i18n/主要路由.md` 领取下一个未完成主路由页面
- 完成该临时任务后,只继续按 `docs/i18n/主要路由.md` 领取下一个未完成主路由页面 - 每个新完成页面必须同步检查直接涉及的页面内组件 / 私有组件 / 直接公共组件,并写明页面私有组件状态与直接公共组件状态
- 已完成主要路由页面需要补做直接公共组件联动复查,优先处理 `PropsRow``RoomDeatilsDrawer`、用户列表直接弹窗/抽屉等复用或高频组件
- 非主要路由页面后续不再继续扩展翻译 - 非主要路由页面后续不再继续扩展翻译
- 当前认领线程: - 当前认领线程:
- 线程一:进行中 `src/views/family/config/index.vue`;已完成认领前文档复读、语言文件复读、入口 import 核对、目录文件核对与模块中文扫描,准备进入页面国际化改动 - 线程一:待分配,当前未认领新任务;已完成 `src/components/data/PropsRow/index.vue` 公共组件联动复查、中文残留扫描、语言文件语法检查和构建验证
- 线程二:进行中 `src/views/game/ludo/index.vue`;已完成认领前文档复读、语言文件复读、目录核对与页面中文扫描,准备进入页面国际化改动 - 线程二:待分配,当前未认领新任务;已完成 `src/views/sys/menu-manager/index.vue``menu-tree.vue``menu-edit.vue` 系统管理 / 菜单管理页面国际化、中文残留扫描和构建验证
- 线程三:进行中 `src/views/version/app/index.vue`;已完成认领前文档复读、语言文件复读、目录核对与模块中文扫描,准备进入页面国际化改动 - 线程三:待分配,当前未认领新任务;已完成 `src/views/sys/role-manager/index.vue``edit-role.vue``authorize-role.vue` 系统管理 / 角色管理页面国际化、中文残留扫描和构建验证
## 扫描概况 ## 扫描概况

View File

@ -182,7 +182,7 @@ export default {
const val = item[format.field]; const val = item[format.field];
if (format.forever === true && val <= 0) { if (format.forever === true && val <= 0) {
return "永久"; return this.$t("pages.propsRow.word.permanent");
} }
return `${format.prefix}${val}${format.suffix}`; return `${format.prefix}${val}${format.suffix}`;

340
src/icons/svg/atyou.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 181 KiB

View File

@ -11,7 +11,7 @@ export default {
'团队钻石政策': 'Team Diamond Policy', '团队钻石政策': 'Team Diamond Policy',
'团队列表': 'Team List', '团队列表': 'Team List',
'成员列表': 'Members', '成员列表': 'Members',
'账单列表': 'Bills', '账单列表': 'Bill List',
'成员工作': 'Member Work', '成员工作': 'Member Work',
'成员审核日志': 'Member Review Logs', '成员审核日志': 'Member Review Logs',
'动态管理': 'Dynamic Management', '动态管理': 'Dynamic Management',
@ -20,15 +20,15 @@ export default {
'用户动态': 'User Posts', '用户动态': 'User Posts',
'黑名单': 'Blacklist', '黑名单': 'Blacklist',
'家族管理': 'Family Management', '家族管理': 'Family Management',
'家族配置': 'Family Settings', '家族配置': 'Family Configuration',
'家族列表': 'Family List', '家族列表': 'Family List',
'宠物管理': 'Pet Management', '宠物管理': 'Pet Management',
'宠物喂养记录': 'Pet Feeding Records', '宠物喂养记录': 'Pet Feeding Records',
'豆子账户': 'Bean Account', '豆子账户': 'Bean Account',
'豆子流水': 'Bean Transactions', '豆子流水': 'Bean Transactions',
'宠物池': 'Pet Pool', '宠物池': 'Pet Pool',
'道具管理': 'Props Management', '道具管理': 'Prop Management',
'道具赠送': 'Props Gift', '道具赠送': 'Prop Gift',
'资源配置': 'Resource Configuration', '资源配置': 'Resource Configuration',
'道具资源组配置': 'Prop Resource Group Settings', '道具资源组配置': 'Prop Resource Group Settings',
'活动道具规则配置': 'Activity Prop Rule Settings', '活动道具规则配置': 'Activity Prop Rule Settings',
@ -53,14 +53,14 @@ export default {
'封禁设备': 'Blocked Devices', '封禁设备': 'Blocked Devices',
'表情管理': 'Emoji Management', '表情管理': 'Emoji Management',
'系统管理': 'System Management', '系统管理': 'System Management',
'区域配置': 'Region Settings', '区域配置': 'Region Configuration',
'用户管理': 'User Management', '用户管理': 'User Management',
'角色管理': 'Role Management', '角色管理': 'Role Management',
'菜单管理': 'Menu Management', '菜单管理': 'Menu Management',
'资源管理': 'Resource Management', '资源管理': 'Resource Management',
'统计管理': 'Statistics', '统计管理': 'Statistics',
'数据大屏': 'Data Dashboard', '数据大屏': 'Data Dashboard',
'运营管理': 'Operations', '运营管理': 'Operations Management',
'代理活动': 'Agent Activities', '代理活动': 'Agent Activities',
'金币余额': 'Gold Balance', '金币余额': 'Gold Balance',
'自动发放工资凭据': 'Automatic Payroll Vouchers', '自动发放工资凭据': 'Automatic Payroll Vouchers',
@ -76,9 +76,9 @@ export default {
'邀请用户日志': 'Invite User Logs', '邀请用户日志': 'Invite User Logs',
'活动配置': 'Activity Configuration', '活动配置': 'Activity Configuration',
'活动模版': 'Activity Templates', '活动模版': 'Activity Templates',
'用户友谊卡配置': 'User Friendship Card Settings', '用户友谊卡配置': 'User Friendship Card Configuration',
'邀请用户配置': 'Invite User Settings', '邀请用户配置': 'Invite User Configuration',
'用户观看广告配置': 'User Ad View Settings', '用户观看广告配置': 'User Ad View Configuration',
'Ludo飞行棋': 'Ludo', 'Ludo飞行棋': 'Ludo',
'置顶房间': 'Pinned Rooms', '置顶房间': 'Pinned Rooms',
'热门房间': 'Popular Rooms', '热门房间': 'Popular Rooms',
@ -101,7 +101,7 @@ export default {
'小工具': 'Utilities', '小工具': 'Utilities',
'异常订单': 'Abnormal Orders', '异常订单': 'Abnormal Orders',
'货运代理流水': 'Freight Agent Transactions', '货运代理流水': 'Freight Agent Transactions',
'高产用户列表': 'High Output Users', '高产用户列表': 'High Output User List',
'金币收支记录': 'Gold Transaction Records', '金币收支记录': 'Gold Transaction Records',
'内部操作金币': 'Internal Gold Operations', '内部操作金币': 'Internal Gold Operations',
'游戏券收支记录': 'Game Coupon Transaction Records', '游戏券收支记录': 'Game Coupon Transaction Records',
@ -112,7 +112,7 @@ export default {
'抽奖概率配置': 'Lottery Probability Settings', '抽奖概率配置': 'Lottery Probability Settings',
'徽章配置管理': 'Badge Configuration Management', '徽章配置管理': 'Badge Configuration Management',
'靓号池管理': 'Special ID Pool Management', '靓号池管理': 'Special ID Pool Management',
'礼物赠送记录': 'Gift Giving Records', '礼物赠送记录': 'Gift Sending Records',
'房间贡献余额': 'Room Contribution Balance', '房间贡献余额': 'Room Contribution Balance',
'消息推送': 'Message Push', '消息推送': 'Message Push',
'在线房间': 'Online Rooms', '在线房间': 'Online Rooms',
@ -129,12 +129,12 @@ export default {
'购买麦位类型流水': 'Mic Slot Purchase Transactions', '购买麦位类型流水': 'Mic Slot Purchase Transactions',
'红包发送列表': 'Red Packet Sends', '红包发送列表': 'Red Packet Sends',
'用户活动领奖记录': 'User Activity Reward Records', '用户活动领奖记录': 'User Activity Reward Records',
'幸运礼物规则配置': 'Lucky Gift Rule Settings', '幸运礼物规则配置': 'Lucky Gift Rule Configuration',
'幸运礼物规格配置': 'Lucky Gift Specification Settings', '幸运礼物规格配置': 'Lucky Gift Specification Configuration',
'幸运礼物送礼记录': 'Lucky Gift Sending Records', '幸运礼物送礼记录': 'Lucky Gift Sending Records',
'LuckyBox抽奖记录': 'LuckyBox Draw Records', 'LuckyBox抽奖记录': 'LuckyBox Draw Records',
'摩天轮游戏每日数据': 'Ferris Wheel Daily Data', '摩天轮游戏每日数据': 'Ferris Wheel Daily Data',
'摩天轮任务配置': 'Ferris Wheel Task Settings', '摩天轮任务配置': 'Ferris Wheel Task Configuration',
'砸金蛋记录': 'Golden Egg Smash Records', '砸金蛋记录': 'Golden Egg Smash Records',
'炸金花': 'Teen Patti', '炸金花': 'Teen Patti',
'用户申请靓号记录': 'User Special ID Applications', '用户申请靓号记录': 'User Special ID Applications',
@ -155,8 +155,8 @@ export default {
'违规历史记录': 'Violation History', '违规历史记录': 'Violation History',
'家族头像审批': 'Family Avatar Approval', '家族头像审批': 'Family Avatar Approval',
'动态内容审批': 'Post Content Approval', '动态内容审批': 'Post Content Approval',
'动态举报审批': 'Post Report Approval', '动态举报审批': 'Post Report Review',
'用户银行卡审批': 'User Bank Card Approval', '用户银行卡审批': 'User Bank Card Review',
'语言': 'Language', '语言': 'Language',
English: 'English', English: 'English',
'中文': 'Chinese', '中文': 'Chinese',
@ -261,6 +261,123 @@ export default {
'系统补偿': 'System Compensation', '系统补偿': 'System Compensation',
'系统扣除': 'System Deduction', '系统扣除': 'System Deduction',
'创建银行账户': 'Create Bank Account', '创建银行账户': 'Create Bank Account',
'发送喇叭': 'Send Trumpet',
'用户退款': 'User Refund',
'每周特殊关系卡片奖励': 'Weekly Special Relationship Card Reward',
'每周游戏任务奖励': 'Weekly Game Task Reward',
'超限制发动态支付金币': 'Gold Paid for Exceeding Post Limit',
'购买表情包': 'Buy Emoji Pack',
'炸金花游戏 ': 'Teen Patti Game',
'sud游戏退款平局': 'SUD Game Draw Refund',
'sud游戏退款': 'SUD Game Refund',
'sud游戏获胜奖励': 'SUD Game Win Reward',
'用户特殊关系卡退款': 'User Special Relationship Card Refund',
'赠送用户特殊关系卡': 'Gift User Special Relationship Card',
'幸运礼物金币奖励': 'Lucky Gift Gold Reward',
'邀请用户奖励': 'Invite User Reward',
'LUDO游戏退款': 'LUDO Game Refund',
'幸运彩票押注': 'Lucky Lottery Bet',
'累计充值抽奖': 'Cumulative Recharge Lottery',
'幸运礼物抽奖': 'Lucky Gift Lottery',
'每日签到抽奖': 'Daily Check-in Lottery',
'游戏王奖励': 'Game King Reward',
'每周王后': 'Weekly Queen',
'每周国王': 'Weekly King',
'烧烤机游戏': 'BBQ Machine Game',
'水果机游戏': 'Slot Machine Game',
'砸金蛋': 'Golden Egg Smash',
'宠物转盘抽奖': 'Pet Wheel Lottery',
'宠物奖励': 'Pet Reward',
'激活宠物': 'Activate Pet',
'帮助他人喂养': 'Help Others Feed Pets',
'喂养宠物': 'Feed Pet',
'房间PK奖励': 'Room PK Reward',
'cp礼物互赠消耗': 'CP Gift Exchange Cost',
'赠送道具主题-金币': 'Gift Prop Theme - Gold',
'购买主题-赠送': 'Buy Theme - Gift',
'购买主题-金币': 'Buy Theme - Gold',
'开通VIP': 'Activate VIP',
'盖房子消费': 'Build House Cost',
'钻石兑换金币': 'Exchange Diamonds for Gold',
'首次充值': 'First Recharge',
'家族每周宝箱奖励领取': 'Claim Family Weekly Chest Reward',
'使用金币创建家族': 'Create Family with Gold',
'用户首次充值奖励': 'User First Recharge Reward',
'接收礼物': 'Receive Gift',
'红包退款': 'Red Packet Refund',
'领取红包奖励': 'Claim Red Packet Reward',
'发送红包': 'Send Red Packet',
'红包用户个人退款': 'Personal Red Packet Refund',
'领取用户个人红包奖励': 'Claim Personal Red Packet Reward',
'发送用户个人红包': 'Send Personal Red Packet',
'邀请的用户首次充值奖励': 'Invited User First Recharge Reward',
'邀请用户注册奖励': 'Invite User Registration Reward',
'朋友赠送金币': 'Friend Gifted Gold',
'购买金币': 'Buy Gold',
'礼包': 'Gift Pack',
'游戏抽成': 'Game Commission',
'游戏胜利': 'Game Win',
'游戏退还': 'Game Refund',
'签到获取奖励': 'Check-in Reward',
'房间奖励提取': 'Room Reward Withdrawal',
'WEB端购买': 'Web Purchase',
'周星': 'Weekly Star',
'房间奖励': 'Room Reward',
'累计充值奖励': 'Cumulative Recharge Reward',
'爆水晶游戏': 'Crystal Burst Game',
'CP奖励': 'CP Reward',
'每日任务': 'Daily Task',
'LUDO退款': 'LUDO Refund',
'LUDO胜利': 'LUDO Victory',
'Lucky Box & 幸运抽奖': 'Lucky Box & Lucky Lottery',
'CP组建': 'CP Formation',
'购买隐身浏览道具': 'Buy Invisible Browsing Prop',
'购买房间锁': 'Buy Room Lock',
'赠送装扮-金币': 'Gift Outfit - Gold',
'赠送车辆-金币': 'Gift Vehicle - Gold',
'赠送聊天气泡-金币': 'Gift Chat Bubble - Gold',
'赠送头像框-金币': 'Gift Avatar Frame - Gold',
'购买装扮-金币': 'Buy Outfit - Gold',
'购买车辆-金币': 'Buy Vehicle - Gold',
'购买聊天气泡-金币': 'Buy Chat Bubble - Gold',
'购买头像框-金币': 'Buy Avatar Frame - Gold',
'赠送贵族VIP-金币': 'Gift Noble VIP - Gold',
'购买贵族vip-金币': 'Buy Noble VIP - Gold',
'赠送靓号-金币': 'Gift Special ID - Gold',
'购买靓号-金币': 'Buy Special ID - Gold',
'LUDO游戏': 'LUDO Game',
'转盘游戏': 'Wheel Game',
'烧烤游戏': 'BBQ Game',
'水果游戏': 'Fruit Game',
'加入房间': 'Join Room',
'自定义主题': 'Custom Theme',
'赠送礼物': 'Send Gift',
'活动奖励': 'Activity Reward',
'后台管理发送-APP': 'Admin Sent - APP',
'Hkys第三方游戏': 'Hkys Third-party Game',
'房间贡献活动奖励': 'Room Contribution Activity Reward',
'后台发送金币': 'Admin Sent Gold',
'后台扣除金币': 'Admin Deducted Gold',
'代理的主播数量满足奖励': 'Agent Host Count Target Reward',
'代理名下主播累计月积分奖励': 'Agent Hosts Monthly Points Reward',
'主播月积分奖励': 'Host Monthly Points Reward',
'主播日积分奖励': 'Host Daily Points Reward',
'幸运摩天轮下注-自研': 'Lucky Ferris Wheel Bet - Self-developed',
'幸运摩天轮奖励-自研': 'Lucky Ferris Wheel Reward - Self-developed',
'KTV游戏每周榜单奖励': 'KTV Weekly Ranking Reward',
'代理活动奖励-周': 'Agent Activity Reward - Weekly',
'代理活动奖励-月': 'Agent Activity Reward - Monthly',
'消耗活动': 'Consumption Activity',
'房间粉丝人气票': 'Room Fan Popularity Votes',
'目标兑换金币': 'Target Exchange Gold',
'主播申请解约': 'Host Termination Request',
'主播取消申请解约': 'Host Canceled Termination Request',
'购买红包封面': 'Buy Red Packet Cover',
'赠送红包封面': 'Gift Red Packet Cover',
'CP空间祝福': 'CP Space Blessing',
'发送家族群聊红包': 'Send Family Group Red Packet',
'领取家族群聊红包': 'Claim Family Group Red Packet',
'家族群聊红包退款': 'Family Group Red Packet Refund',
'手机号码': 'Mobile Number', '手机号码': 'Mobile Number',
'谷歌': 'Google', '谷歌': 'Google',
'礼物': 'Gift', '礼物': 'Gift',

View File

@ -2692,6 +2692,11 @@ export default {
}, },
loading: 'Loading' loading: 'Loading'
}, },
propsRow: {
word: {
permanent: 'Permanent'
}
},
propsSourceGroupForm: { propsSourceGroupForm: {
dialog: { dialog: {
title: '{action} ({sysOrigin})' title: '{action} ({sysOrigin})'
@ -3015,6 +3020,532 @@ export default {
} }
} }
}, },
familyConfig: {
loading: 'Loading',
tabs: {
level: 'Family Level Configuration',
createRule: 'Family Creation Rule',
weeklyReward: 'Weekly Reward Rule'
},
filter: {
system: 'System'
},
table: {
system: 'System',
level: 'Level',
levelExp: 'Level Experience',
maxMember: 'Max Members',
maxManager: 'Max Managers',
sort: 'Sort',
actions: 'Actions',
createdAt: 'Created At',
minWealthLevel: 'Minimum Wealth Level',
createCost: 'Family Creation Cost',
goalExp: 'Required Contribution',
rewardCandy: 'Reward Candy'
},
form: {
system: 'System',
levelKey: 'Level Key',
avatarFrame: 'Avatar Frame',
badge: 'Badge',
gift: 'Gift',
background: 'Background Image',
contribution: 'Contribution',
managerCount: 'Managers',
memberCount: 'Members',
sortCareful: 'Sort (Careful)',
levelType: 'Level Type',
wealthLevel: 'Wealth Level',
createCost: 'Creation Cost',
taskContribution: 'Task Contribution',
rewardCandy: 'Reward Candy',
sort: 'Sort'
},
placeholder: {
system: 'System',
levelKey: 'Level Key',
avatarFrame: 'Avatar Frame',
badge: 'Badge',
gift: 'Gift',
levelSort: 'Lower numbers represent lower levels. Please keep the order accurate.',
levelType: 'Level Type',
rewardSort: 'Lower numbers mean fewer rewards'
},
action: {
search: 'Search',
add: 'Add',
edit: 'Edit',
save: 'Save',
cancel: 'Cancel'
},
alert: {
title: 'Notice',
singleCreateRule: 'Each system can have only one family creation rule.',
weeklyRewardLimit: 'Each system can have only three family weekly reward rules.'
},
dialog: {
addLevel: 'Add Family Level',
editLevel: 'Edit Family Level',
addCreateRule: 'Add Creation Rule',
editCreateRule: 'Edit Creation Rule',
addRewardRule: 'Add Family Reward Rule',
editRewardRule: 'Edit Family Reward Rule'
},
validation: {
selectSystem: 'Please select a system',
selectLevelKey: 'Please select a level key',
selectLevelBadge: 'Please select a level badge',
enterContribution: 'Please enter the contribution value',
enterMaxMember: 'Please enter the max member count',
enterMaxManager: 'Please enter the max manager count',
enterSort: 'Please enter the sort order',
selectLevelType: 'Please select a level type',
enterCost: 'Please enter the cost',
enterWealthLevel: 'Please enter the wealth level',
enterRewardCandy: 'Please enter the reward candy amount',
enterTaskContribution: 'Please enter the task contribution value',
enterRewardSort: 'Please enter the reward sort order'
},
levelKey: {
BLACK_IRON: 'Black Iron',
BRONZE_I: 'Bronze 1',
BRONZE_II: 'Bronze 2',
BRONZE_III: 'Bronze 3',
BRONZE_IIII: 'Bronze 4',
BRONZE_IIIII: 'Bronze 5',
SILVER_I: 'Silver 1',
SILVER_II: 'Silver 2',
SILVER_III: 'Silver 3',
SILVER_IIII: 'Silver 4',
SILVER_IIIII: 'Silver 5',
GOLD_I: 'Gold 1',
GOLD_II: 'Gold 2',
GOLD_III: 'Gold 3',
GOLD_IIII: 'Gold 4',
GOLD_IIIII: 'Gold 5',
PLATINUM_I: 'Platinum 1',
PLATINUM_II: 'Platinum 2',
PLATINUM_III: 'Platinum 3',
PLATINUM_IIII: 'Platinum 4',
PLATINUM_IIIII: 'Platinum 5'
},
levelType: {
BLACK_IRON: 'Black Iron',
BRONZE: 'Bronze',
SILVER: 'Silver',
GOLD: 'Gold',
PLATINUM: 'Platinum'
},
message: {
success: 'Successful'
}
},
familyList: {
loading: 'Loading',
filter: {
system: 'System',
userId: 'User ID',
familyAccount: 'Family Account'
},
dateRange: {
separator: 'To',
start: 'Start Date',
end: 'End Date'
},
table: {
system: 'Source System',
owner: 'Family Owner',
familyAccount: 'Family Account',
familyAvatar: 'Family Avatar',
familyName: 'Family Name',
memberCount: 'Members',
familyLevel: 'Family Level',
totalContribution: 'Total Contribution',
createdAt: 'Created At',
actions: 'Actions'
},
action: {
search: 'Search',
memberList: 'Member List',
disbandFamily: 'Disband Family',
remove: 'Remove'
},
memberDialog: {
title: 'Family Members',
table: {
avatar: 'Avatar',
nickname: 'Nickname',
role: 'Role',
joinedAt: 'Joined Family At'
}
},
role: {
ADMIN: 'Family Owner',
MANAGE: 'Manager',
MEMBER: 'Member'
},
confirm: {
disbandFamily: 'This cannot be restored after deletion. Are you sure you want to delete this family?',
removeMember: 'Are you sure you want to remove this member?',
title: 'Prompt',
confirm: 'Confirm',
cancel: 'Cancel'
},
message: {
disbanding: 'Deleting. Please wait for the result.',
disbandSuccess: 'Deleted successfully',
processing: 'Processing. Please wait for the result.',
removeSuccess: 'Removed successfully'
}
},
archiveDevice: {
loading: 'Loading',
filter: {
system: 'System',
deviceNo: 'Device No.'
},
table: {
deviceNo: 'Device No.',
createdAt: 'Created At',
actions: 'Actions'
},
action: {
search: 'Search',
delete: 'Delete'
},
message: {
deleteSuccess: 'Deleted successfully'
}
},
sysUserManager: {
loading: 'Loading',
filter: {
account: 'Account',
nickname: 'Nickname',
status: 'Status'
},
table: {
account: 'Account',
nickname: 'Nickname',
role: 'Role',
phone: 'Phone',
email: 'Email',
createdAt: 'Created At',
status: 'Status',
actions: 'Actions'
},
status: {
normal: 'Normal',
disabled: 'Disabled'
},
action: {
search: 'Search',
add: 'Add',
edit: 'Edit',
resetPassword: 'Reset Password',
cancel: 'Cancel',
submit: 'Submit'
},
drawer: {
create: 'Create',
edit: 'Edit'
},
form: {
account: 'Account',
nickname: 'Nickname',
phone: 'Phone',
email: 'Email',
role: 'Role'
},
placeholder: {
account: 'Please enter the login account',
nickname: 'Please enter the user nickname',
phone: 'Please enter the phone number',
email: 'Please enter the email address',
role: 'Please select a role'
},
validation: {
accountRequired: 'Username is required',
nicknameRequired: 'User nickname is required',
roleRequired: 'Role is required'
},
confirm: {
resetPassword: 'Are you sure you want to reset "{nickname}" login password?',
title: 'Prompt',
confirm: 'Confirm',
cancel: 'Cancel'
},
message: {
cancelled: 'Operation cancelled'
}
},
sysRoleManager: {
loading: 'Loading',
filter: {
roleName: 'Role Name'
},
table: {
role: 'Role',
remark: 'Remarks',
createdAt: 'Created At',
updatedAt: 'Updated At',
actions: 'Actions'
},
action: {
search: 'Search',
add: 'Add',
authorizeMenu: 'Menu Authorization',
edit: 'Edit',
delete: 'Delete',
cancel: 'Cancel',
submit: 'Submit'
},
drawer: {
create: 'Create',
edit: 'Edit',
authorize: 'Role Authorization'
},
form: {
roleName: 'Role Name',
remark: 'Remarks'
},
placeholder: {
roleName: 'Please enter the role name',
remark: 'Please enter remarks'
},
validation: {
roleNameRequired: 'Role name is required',
remarkMax: 'Remarks must be within 100 characters'
},
confirm: {
deleteRole: 'This role will be permanently deleted. Continue?',
title: 'Prompt',
confirm: 'Confirm',
cancel: 'Cancel'
},
message: {
cancelled: 'Deletion cancelled'
}
},
sysResourcesManager: {
loading: 'Loading',
filter: {
resourceName: 'Resource Name',
method: 'Request Method',
authType: 'Permission Type'
},
table: {
resourceName: 'Resource Name',
method: 'Request Method',
mapping: 'Mapping Path',
authType: 'Authorization Type',
perm: 'Permission Key',
updatedAt: 'Updated At'
},
authTypes: {
loginRequired: 'Login Required',
noAuthRequired: 'No Auth Required',
authRequired: 'Authorization Required'
},
action: {
search: 'Search',
refreshResources: 'Refresh Resources'
}
},
sysMenuManager: {
form: {
currentEvent: 'Current Event',
menuName: 'Menu Name',
permissionName: 'Permission Name',
menuType: 'Menu Type',
menuIcon: 'Menu Icon',
menuStatus: 'Menu Status',
sortWeight: 'Sort Weight',
menuPath: 'Menu Path',
menuRouter: 'Menu Router',
relatedResources: 'Related Resources'
},
placeholder: {
menuName: 'Please enter the menu name',
permissionName: 'Please enter the permission name',
sortWeight: 'Please enter the sort weight',
menuPath: 'Please enter the menu path',
menuRouter: 'Please enter the menu route',
relatedResources: 'Please select resources',
filterKeyword: 'Enter keywords to filter'
},
menuType: {
directory: 'Directory',
menu: 'Menu',
button: 'Button'
},
status: {
normal: 'Normal',
disabled: 'Disabled'
},
event: {
addChild: 'Add child node to "{name}"',
updateNode: 'Edit "{name}" node',
addRoot: 'Add root node',
invalid: 'Invalid event'
},
tree: {
addRootMenu: 'Add Root Menu',
refreshMenu: 'Refresh Menu',
expandFirstLevel: 'Expand First Level',
expandAll: 'Expand All',
collapseAll: 'Collapse All',
selectedNode: 'Current selected node: {name}',
rootNode: 'Root Node'
},
action: {
add: 'Add',
edit: 'Edit',
delete: 'Delete',
selectIcon: 'Select Icon',
submit: 'Submit'
},
validation: {
menuNameRequired: 'Menu name is required',
menuTypeRequired: 'Menu type is required',
menuStatusRequired: 'Menu status is required'
},
confirm: {
deleteMessage: 'This action will permanently delete the menu. Continue?',
title: 'Prompt',
confirm: 'Confirm',
cancel: 'Cancel'
},
message: {
cancelled: 'Deletion cancelled'
}
},
purchaseOrders: {
filter: {
system: 'System',
sourcePlatform: 'Source Platform',
status: 'Status',
userId: 'User ID',
orderId: 'Order ID',
to: 'To',
startDate: 'Start Date',
endDate: 'End Date'
},
summary: {
userTotalRecharge: 'Total recharge for this user: {total}'
},
table: {
environment: 'Environment',
platformChannel: 'Platform Channel',
buyer: 'Buyer',
amount: 'Amount',
description: 'Description',
status: 'Status',
thirdPartyId: 'Third-party ID',
purchaseTime: 'Purchase Time',
actions: 'Actions'
},
word: {
friend: 'Friend',
purchase: 'Purchased',
update: 'Updated'
},
action: {
search: 'Search',
export: 'Export',
details: 'Details',
close: 'Close'
},
export: {
title: 'Export Conditions',
month: 'Month',
selectMonth: 'Select month'
},
orderStatus: {
COMPLETE: 'Completed',
REIMBURSE: 'Refunded'
},
validation: {
requiredField: 'Required field cannot be empty'
},
message: {
exporting: 'Export is in progress, please wait.',
downloadFailed: 'Download failed.'
}
},
goldRunningWater: {
filter: {
system: 'System',
type: 'Type',
origin: 'Please enter or select content',
userId: 'User ID',
trackId: 'Trace ID',
recordId: 'Record ID',
to: 'To',
startDate: 'Start Date',
endDate: 'End Date',
pageSize: 'Page Size',
pageSizeValue: '{size}/page'
},
table: {
system: 'System',
user: 'User',
type: 'Type',
goldAmount: 'Gold Amount',
balance: 'Balance',
source: 'Source',
createdAt: 'Created At'
},
type: {
income: 'Income',
expense: 'Expense',
unknown: 'Unknown'
},
word: {
tag: 'Tag'
},
action: {
search: 'Search',
loadMore: 'Load More'
},
message: {
recentYearOnly: 'Note: Only data from the last 1 year can be viewed.',
loadedAll: 'All data loaded',
selectTimeRange: 'Please select a time range.',
crossYearNotAllowed: 'Cross-year queries are not allowed.'
}
},
userDevice: {
loading: 'Loading',
filter: {
system: 'System',
userId: 'User ID',
deviceNo: 'Device No.'
},
dateRange: {
separator: 'To',
start: 'Registration Start Date',
end: 'Registration End Date'
},
table: {
system: 'System',
user: 'User',
registerCount: 'Registration Count',
latestLoginIp: 'Latest Login IP',
deviceNo: 'Device No.',
requestPlatform: 'Request Platform',
phoneModel: 'Phone Model',
operatingSystem: 'Operating System',
appVersion: 'App Version',
createdAt: 'Created At',
updatedAt: 'Updated At'
},
action: {
search: 'Search',
copy: 'Click to Copy'
}
},
regionConfig: { regionConfig: {
filter: { filter: {
system: 'System', system: 'System',

View File

@ -2689,6 +2689,11 @@ export default {
}, },
loading: '加载中' loading: '加载中'
}, },
propsRow: {
word: {
permanent: '永久'
}
},
propsSourceGroupForm: { propsSourceGroupForm: {
dialog: { dialog: {
title: '{action}{sysOrigin}' title: '{action}{sysOrigin}'
@ -3012,6 +3017,532 @@ export default {
} }
} }
}, },
familyConfig: {
loading: '加载中',
tabs: {
level: '家族等级配置',
createRule: '创建家族规则',
weeklyReward: '创建每周奖励规则'
},
filter: {
system: '系统'
},
table: {
system: '系统',
level: '等级',
levelExp: '等级经验值',
maxMember: '最大成员数',
maxManager: '最大管理员数',
sort: '顺序',
actions: '操作',
createdAt: '创建时间',
minWealthLevel: '最低财富等级',
createCost: '创建家族支付糖果',
goalExp: '任务所需贡献值',
rewardCandy: '奖励糖果数'
},
form: {
system: '系统',
levelKey: '等级Key',
avatarFrame: '头像框',
badge: '徽章',
gift: '礼物',
background: '背景图',
contribution: '贡献值',
managerCount: '管理员数',
memberCount: '成员数',
sortCareful: '顺序(慎重)',
levelType: '等级类型',
wealthLevel: '财富等级',
createCost: '创建费用',
taskContribution: '任务贡献值',
rewardCandy: '奖励糖果数',
sort: '顺序'
},
placeholder: {
system: '系统',
levelKey: '等级Key',
avatarFrame: '头像框',
badge: '徽章',
gift: '礼物',
levelSort: '等级越低数字越小,顺序务必正确',
levelType: '等级类型',
rewardSort: '数字越小奖励越少'
},
action: {
search: '搜索',
add: '添加',
edit: '修改',
save: '保存',
cancel: '取消'
},
alert: {
title: '注意',
singleCreateRule: '一个系统只能有一条创建家族规则!',
weeklyRewardLimit: '一个系统只能有三条家族每周奖励规则!'
},
dialog: {
addLevel: '新增家族等级',
editLevel: '修改家族等级',
addCreateRule: '新增创建规则',
editCreateRule: '修改创建规则',
addRewardRule: '新增家族奖励规则',
editRewardRule: '修改家族奖励规则'
},
validation: {
selectSystem: '请选择系统',
selectLevelKey: '请选择等级Key',
selectLevelBadge: '请选择等级徽章',
enterContribution: '贡献值必须填写',
enterMaxMember: '最大成员数必须填写',
enterMaxManager: '最大管理员数必须填写',
enterSort: '序号必须填写',
selectLevelType: '请选择等级类型',
enterCost: '请输入消费金额',
enterWealthLevel: '请输入财富等级',
enterRewardCandy: '请输入奖励糖果数',
enterTaskContribution: '请输入任务贡献值',
enterRewardSort: '请输入奖励顺序'
},
levelKey: {
BLACK_IRON: '黑铁',
BRONZE_I: '青铜1',
BRONZE_II: '青铜2',
BRONZE_III: '青铜3',
BRONZE_IIII: '青铜4',
BRONZE_IIIII: '青铜5',
SILVER_I: '白银1',
SILVER_II: '白银2',
SILVER_III: '白银3',
SILVER_IIII: '白银4',
SILVER_IIIII: '白银5',
GOLD_I: '黄金1',
GOLD_II: '黄金2',
GOLD_III: '黄金3',
GOLD_IIII: '黄金4',
GOLD_IIIII: '黄金5',
PLATINUM_I: '铂金1',
PLATINUM_II: '铂金2',
PLATINUM_III: '铂金3',
PLATINUM_IIII: '铂金4',
PLATINUM_IIIII: '铂金5'
},
levelType: {
BLACK_IRON: '黑铁',
BRONZE: '青铜',
SILVER: '白银',
GOLD: '黄金',
PLATINUM: '铂金'
},
message: {
success: '成功'
}
},
familyList: {
loading: '加载中',
filter: {
system: '系统',
userId: '用户ID',
familyAccount: '家族账号'
},
dateRange: {
separator: '至',
start: '开始日期',
end: '结束日期'
},
table: {
system: '来源系统',
owner: '族长',
familyAccount: '家族账号',
familyAvatar: '家族头像',
familyName: '家族名称',
memberCount: '成员数',
familyLevel: '家族等级',
totalContribution: '总贡献值',
createdAt: '创建时间',
actions: '操作'
},
action: {
search: '搜索',
memberList: '成员列表',
disbandFamily: '解散家族',
remove: '移除'
},
memberDialog: {
title: '家族成员',
table: {
avatar: '头像',
nickname: '昵称',
role: '角色',
joinedAt: '加入家族时间'
}
},
role: {
ADMIN: '族长',
MANAGE: '管理员',
MEMBER: '成员'
},
confirm: {
disbandFamily: '【删除后不可复原】!! 确定删除该家族吗?',
removeMember: '确定移除该成员吗?',
title: '提示',
confirm: '确定',
cancel: '取消'
},
message: {
disbanding: '删除中,请等待结果',
disbandSuccess: '成功删除',
processing: '处理中,请等待结果',
removeSuccess: '成功移除'
}
},
archiveDevice: {
loading: '加载中',
filter: {
system: '系统',
deviceNo: '设备号'
},
table: {
deviceNo: '设备号',
createdAt: '创建时间',
actions: '操作'
},
action: {
search: '搜索',
delete: '删除'
},
message: {
deleteSuccess: '删除成功'
}
},
sysUserManager: {
loading: '加载中',
filter: {
account: '账号',
nickname: '昵称',
status: '状态'
},
table: {
account: '账号',
nickname: '昵称',
role: '角色',
phone: '手机号码',
email: '邮箱',
createdAt: '创建时间',
status: '状态',
actions: '操作'
},
status: {
normal: '正常',
disabled: '禁用'
},
action: {
search: '搜索',
add: '添加',
edit: '修改',
resetPassword: '重置密码',
cancel: '取消',
submit: '提交'
},
drawer: {
create: '创建',
edit: '修改'
},
form: {
account: '账号',
nickname: '昵称',
phone: '电话',
email: '邮箱',
role: '角色'
},
placeholder: {
account: '请输入登录账号',
nickname: '请输入用户昵称',
phone: '请输入手机号码',
email: '请输入电子邮箱',
role: '请选择角色'
},
validation: {
accountRequired: '用户名必填',
nicknameRequired: '用户昵称必填',
roleRequired: '角色必填'
},
confirm: {
resetPassword: '是否确认重置 "{nickname}" 登陆密码?',
title: '提示',
confirm: '确定',
cancel: '取消'
},
message: {
cancelled: '已取消操作'
}
},
sysRoleManager: {
loading: '加载中',
filter: {
roleName: '角色名称'
},
table: {
role: '角色',
remark: '备注',
createdAt: '创建时间',
updatedAt: '修改时间',
actions: '操作'
},
action: {
search: '搜索',
add: '添加',
authorizeMenu: '菜单授权',
edit: '修改',
delete: '删除',
cancel: '取消',
submit: '提交'
},
drawer: {
create: '创建',
edit: '修改',
authorize: '角色授权'
},
form: {
roleName: '角色名',
remark: '备注'
},
placeholder: {
roleName: '请输入角色名',
remark: '请输入备注'
},
validation: {
roleNameRequired: '角色名必填',
remarkMax: '备注必须在100字符以内'
},
confirm: {
deleteRole: '此操作将永久删除该角色,是否继续?',
title: '提示',
confirm: '确定',
cancel: '取消'
},
message: {
cancelled: '已取消删除'
}
},
sysResourcesManager: {
loading: '加载中',
filter: {
resourceName: '资源名',
method: '请求方式',
authType: '权限类型'
},
table: {
resourceName: '资源名称',
method: '请求方式',
mapping: '映射路径',
authType: '授权类型',
perm: '权限标识',
updatedAt: '修改时间'
},
authTypes: {
loginRequired: '需要登录',
noAuthRequired: '无需鉴权',
authRequired: '需要鉴权'
},
action: {
search: '搜索',
refreshResources: '刷新资源'
}
},
sysMenuManager: {
form: {
currentEvent: '当前事件',
menuName: '菜单名称',
permissionName: '权限名称',
menuType: '菜单类型',
menuIcon: '菜单图标',
menuStatus: '菜单状态',
sortWeight: '顺序权重',
menuPath: '菜单路径',
menuRouter: '菜单路由',
relatedResources: '对应资源'
},
placeholder: {
menuName: '请输入菜单名称',
permissionName: '请输入权限名称',
sortWeight: '请输入顺序权重',
menuPath: '请输入菜单路径',
menuRouter: '请输入菜单路由',
relatedResources: '请选择资源',
filterKeyword: '输入关键字进行过滤'
},
menuType: {
directory: '目录',
menu: '菜单',
button: '按钮'
},
status: {
normal: '正常',
disabled: '禁用'
},
event: {
addChild: '向“{name}”添加子节点',
updateNode: '修改“{name}”节点',
addRoot: '添加根节点',
invalid: '错误的事件'
},
tree: {
addRootMenu: '添加一级菜单',
refreshMenu: '刷新菜单',
expandFirstLevel: '展开一级',
expandAll: '全部展开',
collapseAll: '全部收起',
selectedNode: '当前选中节点:{name}',
rootNode: '根节点'
},
action: {
add: '添加',
edit: '修改',
delete: '删除',
selectIcon: '选择图标',
submit: '提交'
},
validation: {
menuNameRequired: '菜单名称必填',
menuTypeRequired: '菜单类型必填',
menuStatusRequired: '菜单状态必填'
},
confirm: {
deleteMessage: '此操作将永久删除菜单,是否继续?',
title: '提示',
confirm: '确定',
cancel: '取消'
},
message: {
cancelled: '已取消删除'
}
},
purchaseOrders: {
filter: {
system: '系统',
sourcePlatform: '来源平台',
status: '状态',
userId: '用户ID',
orderId: '订单ID',
to: '至',
startDate: '开始日期',
endDate: '结束日期'
},
summary: {
userTotalRecharge: '该用户总充值:{total}'
},
table: {
environment: '环境',
platformChannel: '平台渠道',
buyer: '购买人',
amount: '金额',
description: '描述',
status: '状态',
thirdPartyId: '第三方ID',
purchaseTime: '购买时间',
actions: '操作'
},
word: {
friend: '朋友',
purchase: '购买',
update: '修改'
},
action: {
search: '搜索',
export: '导出',
details: '详情',
close: '关闭'
},
export: {
title: '导出条件',
month: '月份',
selectMonth: '选择月'
},
orderStatus: {
COMPLETE: '已完成',
REIMBURSE: '已退款'
},
validation: {
requiredField: '必填字段不可为空'
},
message: {
exporting: '正在执行导出,请稍等',
downloadFailed: '下载失败'
}
},
goldRunningWater: {
filter: {
system: '系统',
type: '类型',
origin: '请输入或选择内容',
userId: '用户ID',
trackId: '跟踪ID',
recordId: '记录ID',
to: '至',
startDate: '开始日期',
endDate: '结束日期',
pageSize: '每页条数',
pageSizeValue: '{size}条/页'
},
table: {
system: '系统',
user: '用户',
type: '类型',
goldAmount: '金币数',
balance: '余额',
source: '来源',
createdAt: '创建时间'
},
type: {
income: '收入',
expense: '支出',
unknown: '未知'
},
word: {
tag: '标签'
},
action: {
search: '搜索',
loadMore: '加载更多'
},
message: {
recentYearOnly: '注意可查看数据为最近1年内的数据',
loadedAll: '已加载全部',
selectTimeRange: '请选择时间范围',
crossYearNotAllowed: '不允许跨年查询'
}
},
userDevice: {
loading: '加载中',
filter: {
system: '系统',
userId: '用户ID',
deviceNo: '设备号'
},
dateRange: {
separator: '至',
start: '注册开始日期',
end: '注册结束日期'
},
table: {
system: '系统',
user: '用户',
registerCount: '注册数量',
latestLoginIp: '最近登录IP',
deviceNo: '设备号',
requestPlatform: '请求平台',
phoneModel: '手机型号',
operatingSystem: '操作系统',
appVersion: 'App版本',
createdAt: '创建时间',
updatedAt: '修改时间'
},
action: {
search: '搜索',
copy: '点击复制'
}
},
regionConfig: { regionConfig: {
filter: { filter: {
system: '系统', system: '系统',

View File

@ -8,38 +8,38 @@
icon="el-icon-edit" icon="el-icon-edit"
@click="handleCreate" @click="handleCreate"
> >
添加 {{ $t('pages.familyConfig.action.add') }}
</el-button> </el-button>
</div> </div>
<el-alert <el-alert
title="注意" :title="$t('pages.familyConfig.alert.title')"
type="warning" type="warning"
:closable="false" :closable="false"
> >
一个系统只能有一条创建家族规则! {{ $t('pages.familyConfig.alert.singleCreateRule') }}
</el-alert> </el-alert>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="list" :data="list"
element-loading-text="Loading" :element-loading-text="$t('pages.familyConfig.loading')"
fit fit
highlight-current-row highlight-current-row
> >
<el-table-column prop="sysOrigin" label="系统" align="center"> <el-table-column prop="sysOrigin" :label="$t('pages.familyConfig.table.system')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<sys-origin-icon :icon="scope.row.sysOrigin" :desc="scope.row.sysOrigin" /> <sys-origin-icon :icon="scope.row.sysOrigin" :desc="scope.row.sysOrigin" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="userWealthLevel" label="最低财富等级" align="center" /> <el-table-column prop="userWealthLevel" :label="$t('pages.familyConfig.table.minWealthLevel')" align="center" />
<el-table-column prop="payCandy" label="创建家族支付糖果" align="center" /> <el-table-column prop="payCandy" :label="$t('pages.familyConfig.table.createCost')" align="center" />
<el-table-column fixed="right" label="操作" align="center"> <el-table-column fixed="right" :label="$t('pages.familyConfig.table.actions')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<div> <div>
<el-button type="text" @click.native="handlUpdate(scope.row)">修改</el-button> <el-button type="text" @click.native="handlUpdate(scope.row)">{{ $t('pages.familyConfig.action.edit') }}</el-button>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center"> <el-table-column prop="createTime" :label="$t('pages.familyConfig.table.createdAt')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.createTime | dateFormat }} {{ scope.row.createTime | dateFormat }}
</template> </template>
@ -55,7 +55,7 @@
/> />
<el-dialog <el-dialog
:title="textOptTitle" :title="$t(textOptTitle)"
:visible.sync="formVisible" :visible.sync="formVisible"
:modal-append-to-body="true" :modal-append-to-body="true"
:append-to-body="true" :append-to-body="true"
@ -64,14 +64,14 @@
width="400px" width="400px"
> >
<div v-loading="submitLoading"> <div v-loading="submitLoading">
<el-form ref="form" :model="form" label-width="110px" :rules="rules"> <el-form ref="form" :model="form" label-width="140px" :rules="rules">
<el-form-item <el-form-item
label="系统" :label="$t('pages.familyConfig.form.system')"
prop="sysOrigin" prop="sysOrigin"
> >
<el-select <el-select
v-model="form.sysOrigin" v-model="form.sysOrigin"
placeholder="系统" :placeholder="$t('pages.familyConfig.placeholder.system')"
style="width:100%;" style="width:100%;"
class="filter-item" class="filter-item"
> >
@ -87,15 +87,15 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="财富等级" prop="userWealthLevel"> <el-form-item :label="$t('pages.familyConfig.form.wealthLevel')" prop="userWealthLevel">
<el-input v-model.trim="form.userWealthLevel" type="number" /> <el-input v-model.trim="form.userWealthLevel" type="number" />
</el-form-item> </el-form-item>
<el-form-item label="创建费用" prop="payCandy"> <el-form-item :label="$t('pages.familyConfig.form.createCost')" prop="payCandy">
<el-input v-model.trim="form.payCandy" type="number" /> <el-input v-model.trim="form.payCandy" type="number" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="submitForm()">保存</el-button> <el-button type="primary" @click="submitForm()">{{ $t('pages.familyConfig.action.save') }}</el-button>
<el-button @click="handleClose()">取消</el-button> <el-button @click="handleClose()">{{ $t('pages.familyConfig.action.cancel') }}</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -135,21 +135,23 @@ export default {
sysOrigin: '' sysOrigin: ''
}, },
listLoading: true, listLoading: true,
searchLoading: false, searchLoading: false
rules: {
sysOrigin: [
{ required: true, message: '请选择系统', trigger: 'blur' }
],
payCandy: [
{ required: true, message: '请输入消费金额', trigger: 'blur' }
],
userWealthLevel: [
{ required: true, message: '请输入财富等级', trigger: 'blur' }
]
}
} }
}, },
computed: { computed: {
rules() {
return {
sysOrigin: [
{ required: true, message: this.$t('pages.familyConfig.validation.selectSystem'), trigger: 'blur' }
],
payCandy: [
{ required: true, message: this.$t('pages.familyConfig.validation.enterCost'), trigger: 'blur' }
],
userWealthLevel: [
{ required: true, message: this.$t('pages.familyConfig.validation.enterWealthLevel'), trigger: 'blur' }
]
}
},
...mapGetters(['permissionsSysOriginPlatforms']) ...mapGetters(['permissionsSysOriginPlatforms'])
}, },
created() { created() {
@ -176,12 +178,12 @@ export default {
this.renderData(true) this.renderData(true)
}, },
handleCreate() { handleCreate() {
this.textOptTitle = '新增创建规则' this.textOptTitle = 'pages.familyConfig.dialog.addCreateRule'
this.formVisible = true this.formVisible = true
this.form = getFormData() this.form = getFormData()
}, },
handlUpdate(row) { handlUpdate(row) {
this.textOptTitle = '修改创建规则' this.textOptTitle = 'pages.familyConfig.dialog.editCreateRule'
this.formVisible = true this.formVisible = true
this.form = Object.assign(this.form, row) this.form = Object.assign(this.form, row)
}, },
@ -194,7 +196,7 @@ export default {
}, },
querySearch(queryString, cb) { querySearch(queryString, cb) {
var results = queryString ? this.restaurants.filter(this.createFilter(queryString)) : this.restaurants var results = queryString ? this.restaurants.filter(this.createFilter(queryString)) : this.restaurants
// callback // Return the suggestion list through the callback.
cb(results) cb(results)
}, },
createFilter(queryString) { createFilter(queryString) {
@ -226,7 +228,7 @@ export default {
}, },
renderDataSuccess() { renderDataSuccess() {
this.$message({ this.$message({
message: 'Successful', message: this.$t('pages.familyConfig.message.success'),
type: 'success' type: 'success'
}) })
this.renderData() this.renderData()

View File

@ -4,7 +4,7 @@
<div class="filter-container"> <div class="filter-container">
<el-select <el-select
v-model="listQuery.sysOrigin" v-model="listQuery.sysOrigin"
placeholder="系统" :placeholder="$t('pages.familyConfig.filter.system')"
style="width: 120px" style="width: 120px"
class="filter-item" class="filter-item"
@change="handleSearch" @change="handleSearch"
@ -26,7 +26,7 @@
icon="el-icon-search" icon="el-icon-search"
@click="handleSearch" @click="handleSearch"
> >
搜索 {{ $t('pages.familyConfig.action.search') }}
</el-button> </el-button>
<el-button <el-button
@ -35,40 +35,40 @@
icon="el-icon-edit" icon="el-icon-edit"
@click="handleCreate" @click="handleCreate"
> >
添加 {{ $t('pages.familyConfig.action.add') }}
</el-button> </el-button>
</div> </div>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="list" :data="list"
element-loading-text="Loading" :element-loading-text="$t('pages.familyConfig.loading')"
fit fit
highlight-current-row highlight-current-row
> >
<el-table-column prop="sysOrigin" label="系统" align="center"> <el-table-column prop="sysOrigin" :label="$t('pages.familyConfig.table.system')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<sys-origin-icon :icon="scope.row.sysOrigin" :desc="scope.row.sysOrigin" /> <sys-origin-icon :icon="scope.row.sysOrigin" :desc="scope.row.sysOrigin" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="levelKey" label="等级" align="center"> <el-table-column prop="levelKey" :label="$t('pages.familyConfig.table.level')" align="center">
<template scope="scope"> <template scope="scope">
<span v-for="(levelKey, index) in familyLevelKeys" :key="index"> <span v-for="(levelKey, index) in familyLevelKeyOptions" :key="index">
<span v-if="levelKey.value == scope.row.levelKey">{{ levelKey.name }}</span> <span v-if="levelKey.value == scope.row.levelKey">{{ levelKey.name }}</span>
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="levelExp" label="等级经验值" align="center" /> <el-table-column prop="levelExp" :label="$t('pages.familyConfig.table.levelExp')" align="center" />
<el-table-column prop="maxMember" label="最大成员数" align="center" /> <el-table-column prop="maxMember" :label="$t('pages.familyConfig.table.maxMember')" align="center" />
<el-table-column prop="maxManager" label="最大管理员数" align="center" /> <el-table-column prop="maxManager" :label="$t('pages.familyConfig.table.maxManager')" align="center" />
<el-table-column prop="sort" label="顺序" align="center" /> <el-table-column prop="sort" :label="$t('pages.familyConfig.table.sort')" align="center" />
<el-table-column fixed="right" label="操作" align="center"> <el-table-column fixed="right" :label="$t('pages.familyConfig.table.actions')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<div> <div>
<el-button type="text" @click.native="handlUpdate(scope.row)">修改</el-button> <el-button type="text" @click.native="handlUpdate(scope.row)">{{ $t('pages.familyConfig.action.edit') }}</el-button>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center"> <el-table-column prop="createTime" :label="$t('pages.familyConfig.table.createdAt')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.createTime | dateFormat }} {{ scope.row.createTime | dateFormat }}
</template> </template>
@ -84,7 +84,7 @@
/> />
<el-dialog <el-dialog
:title="textOptTitle" :title="$t(textOptTitle)"
:visible.sync="formVisible" :visible.sync="formVisible"
:modal-append-to-body="true" :modal-append-to-body="true"
:append-to-body="true" :append-to-body="true"
@ -93,14 +93,14 @@
width="450px" width="450px"
> >
<div v-loading="submitLoading"> <div v-loading="submitLoading">
<el-form ref="form" :model="form" label-width="110px" :rules="rules"> <el-form ref="form" :model="form" label-width="140px" :rules="rules">
<el-form-item <el-form-item
label="系统" :label="$t('pages.familyConfig.form.system')"
prop="sysOrigin" prop="sysOrigin"
> >
<el-select <el-select
v-model="form.sysOrigin" v-model="form.sysOrigin"
placeholder="系统" :placeholder="$t('pages.familyConfig.placeholder.system')"
style="width:100%;" style="width:100%;"
class="filter-item" class="filter-item"
@change="changeSysOrigin" @change="changeSysOrigin"
@ -119,17 +119,17 @@
</el-form-item> </el-form-item>
<el-form-item <el-form-item
v-if="!form.id" v-if="!form.id"
label="等级Key" :label="$t('pages.familyConfig.form.levelKey')"
prop="levelKey" prop="levelKey"
> >
<el-select <el-select
v-model="form.levelKey" v-model="form.levelKey"
placeholder="等级Key" :placeholder="$t('pages.familyConfig.placeholder.levelKey')"
style="width:100%;" style="width:100%;"
class="filter-item" class="filter-item"
> >
<el-option <el-option
v-for="(item, index) in familyLevelKeys" v-for="(item, index) in familyLevelKeyOptions"
:key="index" :key="index"
:label="item.name" :label="item.name"
:value="item.value" :value="item.value"
@ -140,10 +140,10 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="avatarFrameId" label="头像框"> <el-form-item prop="avatarFrameId" :label="$t('pages.familyConfig.form.avatarFrame')">
<el-select <el-select
v-model="form.avatarFrameId" v-model="form.avatarFrameId"
placeholder="头像框" :placeholder="$t('pages.familyConfig.placeholder.avatarFrame')"
style="width:100%;" style="width:100%;"
class="filter-item" class="filter-item"
> >
@ -158,10 +158,10 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="badgeId" label="徽章"> <el-form-item prop="badgeId" :label="$t('pages.familyConfig.form.badge')">
<el-select <el-select
v-model="form.badgeId" v-model="form.badgeId"
placeholder="徽章" :placeholder="$t('pages.familyConfig.placeholder.badge')"
style="width:100%;" style="width:100%;"
class="filter-item" class="filter-item"
> >
@ -173,10 +173,10 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item prop="giftId" label="礼物"> <el-form-item prop="giftId" :label="$t('pages.familyConfig.form.gift')">
<el-select <el-select
v-model="form.giftId" v-model="form.giftId"
placeholder="礼物" :placeholder="$t('pages.familyConfig.placeholder.gift')"
style="width:100%;" style="width:100%;"
class="filter-item" class="filter-item"
> >
@ -190,7 +190,7 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="背景图" prop="levelBackgroundPicture"> <el-form-item :label="$t('pages.familyConfig.form.background')" prop="levelBackgroundPicture">
<el-upload <el-upload
:disabled="coverUploadLoading" :disabled="coverUploadLoading"
:class="{'upload-but-hide': !isShowCoverUpload}" :class="{'upload-but-hide': !isShowCoverUpload}"
@ -206,30 +206,30 @@
</el-upload> </el-upload>
</el-form-item> </el-form-item>
<el-form-item label="贡献值" prop="levelExp"> <el-form-item :label="$t('pages.familyConfig.form.contribution')" prop="levelExp">
<el-input v-model.trim="form.levelExp" type="number" /> <el-input v-model.trim="form.levelExp" type="number" />
</el-form-item> </el-form-item>
<el-form-item label="管理员数" prop="maxManager"> <el-form-item :label="$t('pages.familyConfig.form.managerCount')" prop="maxManager">
<el-input v-model.trim="form.maxManager" type="number" /> <el-input v-model.trim="form.maxManager" type="number" />
</el-form-item> </el-form-item>
<el-form-item label="成员数" prop="maxMember"> <el-form-item :label="$t('pages.familyConfig.form.memberCount')" prop="maxMember">
<el-input v-model.trim="form.maxMember" type="number" /> <el-input v-model.trim="form.maxMember" type="number" />
</el-form-item> </el-form-item>
<el-form-item label="顺序(慎重)" prop="sort"> <el-form-item :label="$t('pages.familyConfig.form.sortCareful')" prop="sort">
<el-input v-model.trim="form.sort" type="number" :placeholder="'等级越低数字越小,顺序务必正确'" /> <el-input v-model.trim="form.sort" type="number" :placeholder="$t('pages.familyConfig.placeholder.levelSort')" />
</el-form-item> </el-form-item>
<el-form-item <el-form-item
label="等级类型" :label="$t('pages.familyConfig.form.levelType')"
prop="levelType" prop="levelType"
> >
<el-select <el-select
v-model="form.levelType" v-model="form.levelType"
placeholder="等级类型" :placeholder="$t('pages.familyConfig.placeholder.levelType')"
style="width:100%;" style="width:100%;"
class="filter-item" class="filter-item"
> >
<el-option <el-option
v-for="(item, index) in familyTypes" v-for="(item, index) in familyTypeOptions"
:key="index" :key="index"
:label="item.name" :label="item.name"
:value="item.value" :value="item.value"
@ -241,8 +241,8 @@
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="submitForm()">保存</el-button> <el-button type="primary" @click="submitForm()">{{ $t('pages.familyConfig.action.save') }}</el-button>
<el-button @click="handleClose()">取消</el-button> <el-button @click="handleClose()">{{ $t('pages.familyConfig.action.cancel') }}</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -283,8 +283,6 @@ export default {
}, },
data() { data() {
return { return {
familyTypes,
familyLevelKeys,
thisRow: {}, thisRow: {},
coverFileList: [], coverFileList: [],
level: 0, level: 0,
@ -302,38 +300,52 @@ export default {
}, },
listLoading: true, listLoading: true,
searchLoading: false, searchLoading: false,
rules: {
sysOrigin: [
{ required: true, message: '请选择系统', trigger: 'blur' }
],
levelKey: [
{ required: true, message: '请选择等级Key', trigger: 'blur' }
],
badgeId: [
{ required: true, message: '请选择等级徽章', trigger: 'blur' }
],
levelExp: [
{ required: true, message: '贡献值必须填写', trigger: 'blur' }
],
maxMember: [
{ required: true, message: '最大成员数必须填写', trigger: 'blur' }
],
maxManager: [
{ required: true, message: '最大管理员数必须填写', trigger: 'blur' }
],
sort: [
{ required: true, message: '序号必须填写', trigger: 'blur' }
],
levelType: [
{ required: true, message: '请选择等级类型', trigger: 'blur' }
]
},
avatarFrameList: [], avatarFrameList: [],
badgeList: [], badgeList: [],
giftList: [] giftList: []
} }
}, },
computed: { computed: {
rules() {
return {
sysOrigin: [
{ required: true, message: this.$t('pages.familyConfig.validation.selectSystem'), trigger: 'blur' }
],
levelKey: [
{ required: true, message: this.$t('pages.familyConfig.validation.selectLevelKey'), trigger: 'blur' }
],
badgeId: [
{ required: true, message: this.$t('pages.familyConfig.validation.selectLevelBadge'), trigger: 'blur' }
],
levelExp: [
{ required: true, message: this.$t('pages.familyConfig.validation.enterContribution'), trigger: 'blur' }
],
maxMember: [
{ required: true, message: this.$t('pages.familyConfig.validation.enterMaxMember'), trigger: 'blur' }
],
maxManager: [
{ required: true, message: this.$t('pages.familyConfig.validation.enterMaxManager'), trigger: 'blur' }
],
sort: [
{ required: true, message: this.$t('pages.familyConfig.validation.enterSort'), trigger: 'blur' }
],
levelType: [
{ required: true, message: this.$t('pages.familyConfig.validation.selectLevelType'), trigger: 'blur' }
]
}
},
familyLevelKeyOptions() {
return familyLevelKeys.map(item => ({
...item,
name: this.$t(`pages.familyConfig.levelKey.${item.value}`)
}))
},
familyTypeOptions() {
return familyTypes.map(item => ({
...item,
name: this.$t(`pages.familyConfig.levelType.${item.value}`)
}))
},
isShowCoverUpload() { isShowCoverUpload() {
return !this.form.levelBackgroundPicture return !this.form.levelBackgroundPicture
}, },
@ -386,14 +398,14 @@ export default {
this.renderData(true) this.renderData(true)
}, },
handleCreate() { handleCreate() {
this.textOptTitle = '新增家族等级' this.textOptTitle = 'pages.familyConfig.dialog.addLevel'
this.formVisible = true this.formVisible = true
this.form = getFormData() this.form = getFormData()
this.coverFileList = [] this.coverFileList = []
this.getBadgeList() this.getBadgeList()
}, },
handlUpdate(row) { handlUpdate(row) {
this.textOptTitle = '修改家族等级' this.textOptTitle = 'pages.familyConfig.dialog.editLevel'
this.formVisible = true this.formVisible = true
this.form = Object.assign(this.form, row) this.form = Object.assign(this.form, row)
this.coverFileList = getElementUiUploadFile(this.form.levelBackgroundPicture) this.coverFileList = getElementUiUploadFile(this.form.levelBackgroundPicture)
@ -414,7 +426,7 @@ export default {
}, },
querySearch(queryString, cb) { querySearch(queryString, cb) {
var results = queryString ? this.restaurants.filter(this.createFilter(queryString)) : this.restaurants var results = queryString ? this.restaurants.filter(this.createFilter(queryString)) : this.restaurants
// callback // Return the suggestion list through the callback.
cb(results) cb(results)
}, },
createFilter(queryString) { createFilter(queryString) {
@ -474,7 +486,7 @@ export default {
}, },
renderDataSuccess() { renderDataSuccess() {
this.$message({ this.$message({
message: 'Successful', message: this.$t('pages.familyConfig.message.success'),
type: 'success' type: 'success'
}) })
this.renderData() this.renderData()

View File

@ -8,39 +8,39 @@
icon="el-icon-edit" icon="el-icon-edit"
@click="handleCreate" @click="handleCreate"
> >
添加 {{ $t('pages.familyConfig.action.add') }}
</el-button> </el-button>
</div> </div>
<el-alert <el-alert
title="注意" :title="$t('pages.familyConfig.alert.title')"
type="warning" type="warning"
:closable="false" :closable="false"
> >
一个系统只能有三条家族每周奖励规则! {{ $t('pages.familyConfig.alert.weeklyRewardLimit') }}
</el-alert> </el-alert>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="list" :data="list"
element-loading-text="Loading" :element-loading-text="$t('pages.familyConfig.loading')"
fit fit
highlight-current-row highlight-current-row
> >
<el-table-column prop="sysOrigin" label="系统" align="center"> <el-table-column prop="sysOrigin" :label="$t('pages.familyConfig.table.system')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<sys-origin-icon :icon="scope.row.sysOrigin" :desc="scope.row.sysOrigin" /> <sys-origin-icon :icon="scope.row.sysOrigin" :desc="scope.row.sysOrigin" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="goalExp" label="任务所需贡献值" align="center" /> <el-table-column prop="goalExp" :label="$t('pages.familyConfig.table.goalExp')" align="center" />
<el-table-column prop="rewardQuantity" label="奖励糖果数" align="center" /> <el-table-column prop="rewardQuantity" :label="$t('pages.familyConfig.table.rewardCandy')" align="center" />
<el-table-column prop="sort" label="顺序" align="center" /> <el-table-column prop="sort" :label="$t('pages.familyConfig.table.sort')" align="center" />
<el-table-column fixed="right" label="操作" align="center"> <el-table-column fixed="right" :label="$t('pages.familyConfig.table.actions')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<div> <div>
<el-button type="text" @click.native="handlUpdate(scope.row)">修改</el-button> <el-button type="text" @click.native="handlUpdate(scope.row)">{{ $t('pages.familyConfig.action.edit') }}</el-button>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" label="创建时间" align="center"> <el-table-column prop="createTime" :label="$t('pages.familyConfig.table.createdAt')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.createTime | dateFormat }} {{ scope.row.createTime | dateFormat }}
</template> </template>
@ -56,7 +56,7 @@
/> />
<el-dialog <el-dialog
:title="textOptTitle" :title="$t(textOptTitle)"
:visible.sync="formVisible" :visible.sync="formVisible"
:modal-append-to-body="true" :modal-append-to-body="true"
:append-to-body="true" :append-to-body="true"
@ -65,15 +65,15 @@
width="400px" width="400px"
> >
<div v-loading="submitLoading"> <div v-loading="submitLoading">
<el-form ref="form" :model="form" label-width="110px" :rules="rules"> <el-form ref="form" :model="form" label-width="140px" :rules="rules">
<el-form-item <el-form-item
v-if="form.id === ''" v-if="form.id === ''"
label="系统" :label="$t('pages.familyConfig.form.system')"
prop="sysOrigin" prop="sysOrigin"
> >
<el-select <el-select
v-model="form.sysOrigin" v-model="form.sysOrigin"
placeholder="系统" :placeholder="$t('pages.familyConfig.placeholder.system')"
style="width:100%;" style="width:100%;"
class="filter-item" class="filter-item"
> >
@ -89,18 +89,18 @@
</el-option> </el-option>
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="任务贡献值" prop="goalExp"> <el-form-item :label="$t('pages.familyConfig.form.taskContribution')" prop="goalExp">
<el-input v-model.trim="form.goalExp" type="number" /> <el-input v-model.trim="form.goalExp" type="number" />
</el-form-item> </el-form-item>
<el-form-item label="奖励糖果数" prop="rewardQuantity"> <el-form-item :label="$t('pages.familyConfig.form.rewardCandy')" prop="rewardQuantity">
<el-input v-model.trim="form.rewardQuantity" type="number" /> <el-input v-model.trim="form.rewardQuantity" type="number" />
</el-form-item> </el-form-item>
<el-form-item label="顺序" prop="sort"> <el-form-item :label="$t('pages.familyConfig.form.sort')" prop="sort">
<el-input v-model.trim="form.sort" placeholder="数字越小奖励越少" type="number" /> <el-input v-model.trim="form.sort" :placeholder="$t('pages.familyConfig.placeholder.rewardSort')" type="number" />
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="submitForm()">保存</el-button> <el-button type="primary" @click="submitForm()">{{ $t('pages.familyConfig.action.save') }}</el-button>
<el-button @click="handleClose()">取消</el-button> <el-button @click="handleClose()">{{ $t('pages.familyConfig.action.cancel') }}</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@ -143,24 +143,26 @@ export default {
sysOrigin: '' sysOrigin: ''
}, },
listLoading: true, listLoading: true,
searchLoading: false, searchLoading: false
rules: {
sysOrigin: [
{ required: true, message: '请选择系统', trigger: 'blur' }
],
rewardQuantity: [
{ required: true, message: '请输入奖励糖果数', trigger: 'blur' }
],
goalExp: [
{ required: true, message: '请输入任务贡献值', trigger: 'blur' }
],
sort: [
{ required: true, message: '请输入奖励顺序', trigger: 'blur' }
]
}
} }
}, },
computed: { computed: {
rules() {
return {
sysOrigin: [
{ required: true, message: this.$t('pages.familyConfig.validation.selectSystem'), trigger: 'blur' }
],
rewardQuantity: [
{ required: true, message: this.$t('pages.familyConfig.validation.enterRewardCandy'), trigger: 'blur' }
],
goalExp: [
{ required: true, message: this.$t('pages.familyConfig.validation.enterTaskContribution'), trigger: 'blur' }
],
sort: [
{ required: true, message: this.$t('pages.familyConfig.validation.enterRewardSort'), trigger: 'blur' }
]
}
},
...mapGetters(['permissionsSysOriginPlatforms']) ...mapGetters(['permissionsSysOriginPlatforms'])
}, },
created() { created() {
@ -187,12 +189,12 @@ export default {
this.renderData(true) this.renderData(true)
}, },
handleCreate() { handleCreate() {
this.textOptTitle = '新增家族奖励规则' this.textOptTitle = 'pages.familyConfig.dialog.addRewardRule'
this.formVisible = true this.formVisible = true
this.form = getFormData() this.form = getFormData()
}, },
handlUpdate(row) { handlUpdate(row) {
this.textOptTitle = '修改家族奖励规则' this.textOptTitle = 'pages.familyConfig.dialog.editRewardRule'
this.formVisible = true this.formVisible = true
this.form = Object.assign(this.form, row) this.form = Object.assign(this.form, row)
}, },
@ -205,7 +207,7 @@ export default {
}, },
querySearch(queryString, cb) { querySearch(queryString, cb) {
var results = queryString ? this.restaurants.filter(this.createFilter(queryString)) : this.restaurants var results = queryString ? this.restaurants.filter(this.createFilter(queryString)) : this.restaurants
// callback // Return the suggestion list through the callback.
cb(results) cb(results)
}, },
createFilter(queryString) { createFilter(queryString) {
@ -237,7 +239,7 @@ export default {
}, },
renderDataSuccess() { renderDataSuccess() {
this.$message({ this.$message({
message: 'Successful', message: this.$t('pages.familyConfig.message.success'),
type: 'success' type: 'success'
}) })
this.renderData() this.renderData()

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<el-tabs v-model="activeName"> <el-tabs v-model="activeName">
<el-tab-pane v-for="item in tables" :key="item.name" :label="item.title" :name="item.component" /> <el-tab-pane v-for="item in tables" :key="item.component" :label="$t(item.titleKey)" :name="item.component" />
<component :is="activeName" /> <component :is="activeName" />
</el-tabs> </el-tabs>
</div> </div>
@ -18,13 +18,13 @@ export default {
activeName: 'ConfigLevel', activeName: 'ConfigLevel',
tables: [ tables: [
{ {
title: '家族等级配置', titleKey: 'pages.familyConfig.tabs.level',
component: 'ConfigLevel' component: 'ConfigLevel'
}, { }, {
title: '创建家族规则', titleKey: 'pages.familyConfig.tabs.createRule',
component: 'ConfigCreateRole' component: 'ConfigCreateRole'
}, { }, {
title: '创建每周奖励规则', titleKey: 'pages.familyConfig.tabs.weeklyReward',
component: 'ConfigRewardRole' component: 'ConfigRewardRole'
} }
] ]

View File

@ -1,6 +1,6 @@
<template> <template>
<el-dialog <el-dialog
title="家族成员" :title="$t('pages.familyList.memberDialog.title')"
:visible="true" :visible="true"
:modal-append-to-body="true" :modal-append-to-body="true"
:append-to-body="true" :append-to-body="true"
@ -12,7 +12,7 @@
<div class="app-container"> <div class="app-container">
<div class="filter-container"> <div class="filter-container">
<div class="filter-item"> <div class="filter-item">
<account-input v-model="listQuery.userId" placeholder="用户ID" /> <account-input v-model="listQuery.userId" :placeholder="$t('pages.familyList.filter.userId')" />
</div> </div>
<el-button <el-button
class="filter-item" class="filter-item"
@ -21,19 +21,19 @@
:disabled="searchDisabled" :disabled="searchDisabled"
@click="handleSearch" @click="handleSearch"
> >
搜索 {{ $t('pages.familyList.action.search') }}
</el-button> </el-button>
</div> </div>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="list" :data="list"
:before-close="handleClose" :before-close="handleClose"
element-loading-text="Loading" :element-loading-text="$t('pages.familyList.loading')"
fit fit
highlight-current-row highlight-current-row
max-height="350px" max-height="350px"
> >
<el-table-column label="头像" align="center" width="150"> <el-table-column :label="$t('pages.familyList.memberDialog.table.avatar')" align="center" width="150">
<template slot-scope="scope"> <template slot-scope="scope">
<avatar :url="scope.row.userBaseInfo.userAvatar" :gender="scope.row.userSex" /> <avatar :url="scope.row.userBaseInfo.userAvatar" :gender="scope.row.userSex" />
<div <div
@ -44,7 +44,7 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="昵称" align="center"> <el-table-column :label="$t('pages.familyList.memberDialog.table.nickname')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<div <div
style="width:100%;overflow: hidden;text-overflow:ellipsis;white-space: nowrap;" style="width:100%;overflow: hidden;text-overflow:ellipsis;white-space: nowrap;"
@ -54,21 +54,21 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="角色" align="center"> <el-table-column :label="$t('pages.familyList.memberDialog.table.role')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<span v-for="(item, index) in familyRoles" :key="index"> <span v-for="(item, index) in familyRoleOptions" :key="index">
<span v-if="item.value == scope.row.memberRole">{{ item.name }}</span> <span v-if="item.value == scope.row.memberRole">{{ item.name }}</span>
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="createTime" label="加入家族时间" align="center"> <el-table-column prop="createTime" :label="$t('pages.familyList.memberDialog.table.joinedAt')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.createTime | dateFormat }} {{ scope.row.createTime | dateFormat }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column fixed="right" label="操作" align="center" width="120"> <el-table-column fixed="right" :label="$t('pages.familyList.table.actions')" align="center" width="120">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click.native="removeMember(scope.row)">移除</el-button> <el-button type="text" @click.native="removeMember(scope.row)">{{ $t('pages.familyList.action.remove') }}</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -116,8 +116,15 @@ export default {
listLoading: false, listLoading: false,
searchDisabled: false, searchDisabled: false,
userDeatilsDrawerVisible: false, userDeatilsDrawerVisible: false,
thatSelectedUserId: '', thatSelectedUserId: ''
familyRoles }
},
computed: {
familyRoleOptions() {
return familyRoles.map(item => ({
...item,
name: this.$t(`pages.familyList.role.${item.value}`)
}))
} }
}, },
watch: { watch: {
@ -155,18 +162,20 @@ export default {
}, },
removeMember(item) { removeMember(item) {
const that = this const that = this
that.$confirm('确定移除该成员吗?', '提示', { that.$confirm(this.$t('pages.familyList.confirm.removeMember'), this.$t('pages.familyList.confirm.title'), {
type: 'warning' type: 'warning',
confirmButtonText: this.$t('pages.familyList.confirm.confirm'),
cancelButtonText: this.$t('pages.familyList.confirm.cancel')
}).then(() => { }).then(() => {
that.$message({ that.$message({
message: '处理中,请等待结果', message: this.$t('pages.familyList.message.processing'),
type: 'warning' type: 'warning'
}) })
that.listLoading = true that.listLoading = true
removeFamilyMember(item.familyId, item.id).then((res) => { removeFamilyMember(item.familyId, item.id).then((res) => {
that.listLoading = false that.listLoading = false
that.$message({ that.$message({
message: '成功移除', message: this.$t('pages.familyList.message.removeSuccess'),
type: 'success' type: 'success'
}) })
that.renderData() that.renderData()

View File

@ -3,7 +3,7 @@
<div class="filter-container"> <div class="filter-container">
<el-select <el-select
v-model="listQuery.sysOrigin" v-model="listQuery.sysOrigin"
placeholder="系统" :placeholder="$t('pages.familyList.filter.system')"
style="width: 120px" style="width: 120px"
class="filter-item" class="filter-item"
@change="handleSearch" @change="handleSearch"
@ -26,12 +26,12 @@
<account-input <account-input
v-model="listQuery.userId" v-model="listQuery.userId"
:sys-origin="listQuery.sysOrigin" :sys-origin="listQuery.sysOrigin"
placeholder="用户ID" :placeholder="$t('pages.familyList.filter.userId')"
/> />
</div> </div>
<el-input <el-input
v-model.trim="listQuery.familyAccount" v-model.trim="listQuery.familyAccount"
placeholder="家族账号" :placeholder="$t('pages.familyList.filter.familyAccount')"
style="width: 200px;" style="width: 200px;"
class="filter-item" class="filter-item"
/> />
@ -41,9 +41,9 @@
value-format="timestamp" value-format="timestamp"
type="datetimerange" type="datetimerange"
:picker-options="pickerOptions" :picker-options="pickerOptions"
range-separator="" :range-separator="$t('pages.familyList.dateRange.separator')"
start-placeholder="开始日期" :start-placeholder="$t('pages.familyList.dateRange.start')"
end-placeholder="结束日期" :end-placeholder="$t('pages.familyList.dateRange.end')"
/> />
</div> </div>
<el-button <el-button
@ -53,17 +53,17 @@
:disabled="searchDisabled" :disabled="searchDisabled"
@click="handleSearch" @click="handleSearch"
> >
搜索 {{ $t('pages.familyList.action.search') }}
</el-button> </el-button>
</div> </div>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="list" :data="list"
element-loading-text="Loading" :element-loading-text="$t('pages.familyList.loading')"
fit fit
highlight-current-row highlight-current-row
> >
<el-table-column prop="sysOrigin" label="来源系统" align="center"> <el-table-column prop="sysOrigin" :label="$t('pages.familyList.table.system')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<sys-origin-icon <sys-origin-icon
:icon="scope.row.sysOrigin" :icon="scope.row.sysOrigin"
@ -71,7 +71,7 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="族长" align="center"> <el-table-column :label="$t('pages.familyList.table.owner')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-link <el-link
v-if="scope.row.userBaseInfo.id" v-if="scope.row.userBaseInfo.id"
@ -82,25 +82,25 @@
</el-link> </el-link>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="家族账号" prop="familyAccount" align="center" /> <el-table-column :label="$t('pages.familyList.table.familyAccount')" prop="familyAccount" align="center" />
<el-table-column label="家族头像" align="center" width="150"> <el-table-column :label="$t('pages.familyList.table.familyAvatar')" align="center" width="150">
<template slot-scope="scope"> <template slot-scope="scope">
<avatar :url="scope.row.familyAvatar" /> <avatar :url="scope.row.familyAvatar" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="家族名称" prop="familyName" align="center" /> <el-table-column :label="$t('pages.familyList.table.familyName')" prop="familyName" align="center" />
<el-table-column label="成员数" prop="memberCount" align="center" /> <el-table-column :label="$t('pages.familyList.table.memberCount')" prop="memberCount" align="center" />
<el-table-column label="家族等级" align="center"> <el-table-column :label="$t('pages.familyList.table.familyLevel')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<span v-for="(item, index) in familyLevelKeys" :key="index"> <span v-for="(item, index) in familyLevelKeyOptions" :key="index">
<span v-if="item.value == scope.row.levelKey">{{ item.name }}</span> <span v-if="item.value == scope.row.levelKey">{{ item.name }}</span>
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="总贡献值" prop="familyExp" align="center" /> <el-table-column :label="$t('pages.familyList.table.totalContribution')" prop="familyExp" align="center" />
<el-table-column <el-table-column
prop="createTime" prop="createTime"
label="创建时间" :label="$t('pages.familyList.table.createdAt')"
width="200" width="200"
align="center" align="center"
> >
@ -108,16 +108,16 @@
{{ scope.row.createTime | dateFormat }} {{ scope.row.createTime | dateFormat }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column fixed="right" label="操作" align="center"> <el-table-column fixed="right" :label="$t('pages.familyList.table.actions')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
type="text" type="text"
@click.native="handleFamilyMember(scope.row)" @click.native="handleFamilyMember(scope.row)"
>成员列表</el-button> >{{ $t('pages.familyList.action.memberList') }}</el-button>
<el-button <el-button
type="text" type="text"
@click.native="delFamilyData(scope.row)" @click.native="delFamilyData(scope.row)"
>解散家族</el-button> >{{ $t('pages.familyList.action.disbandFamily') }}</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -163,7 +163,6 @@ export default {
thatSelectedUserId: '', thatSelectedUserId: '',
familyMemberDialogVisible: false, familyMemberDialogVisible: false,
thatSelectedFamilyId: '', thatSelectedFamilyId: '',
familyLevelKeys,
list: [], list: [],
total: 0, total: 0,
rangeDate: [], rangeDate: [],
@ -181,7 +180,13 @@ export default {
} }
}, },
computed: { computed: {
...mapGetters(['permissionsSysOriginPlatforms']) ...mapGetters(['permissionsSysOriginPlatforms']),
familyLevelKeyOptions() {
return familyLevelKeys.map(item => ({
...item,
name: this.$t(`pages.familyConfig.levelKey.${item.value}`)
}))
}
}, },
watch: { watch: {
rangeDate: { rangeDate: {
@ -236,12 +241,14 @@ export default {
delFamilyData(item) { delFamilyData(item) {
const that = this const that = this
that that
.$confirm('【删除后不可复原】!! 确定删除该家族吗?', '提示', { .$confirm(this.$t('pages.familyList.confirm.disbandFamily'), this.$t('pages.familyList.confirm.title'), {
type: 'warning' type: 'warning',
confirmButtonText: this.$t('pages.familyList.confirm.confirm'),
cancelButtonText: this.$t('pages.familyList.confirm.cancel')
}) })
.then(() => { .then(() => {
that.$message({ that.$message({
message: '删除中,请等待结果', message: this.$t('pages.familyList.message.disbanding'),
type: 'warning' type: 'warning'
}) })
that.listLoading = true that.listLoading = true
@ -249,7 +256,7 @@ export default {
.then(res => { .then(res => {
that.listLoading = false that.listLoading = false
that.$message({ that.$message({
message: '成功删除', message: this.$t('pages.familyList.message.disbandSuccess'),
type: 'success' type: 'success'
}) })
that.renderData() that.renderData()

View File

@ -3,7 +3,7 @@
<div class="filter-container"> <div class="filter-container">
<el-select <el-select
v-model="listQuery.sysOrigin" v-model="listQuery.sysOrigin"
placeholder="系统" :placeholder="$t('pages.archiveDevice.filter.system')"
style="width: 120px" style="width: 120px"
class="filter-item" class="filter-item"
@change="handleSearch" @change="handleSearch"
@ -20,7 +20,7 @@
</el-select> </el-select>
<el-input <el-input
v-model.trim="listQuery.deviceNo" v-model.trim="listQuery.deviceNo"
placeholder="设备号" :placeholder="$t('pages.archiveDevice.filter.deviceNo')"
style="width: 200px;" style="width: 200px;"
clearable clearable
class="filter-item" class="filter-item"
@ -31,25 +31,25 @@
icon="el-icon-search" icon="el-icon-search"
@click="handleSearch" @click="handleSearch"
> >
搜索 {{ $t('pages.archiveDevice.action.search') }}
</el-button> </el-button>
</div> </div>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="list" :data="list"
element-loading-text="Loading" :element-loading-text="$t('pages.archiveDevice.loading')"
fit fit
highlight-current-row highlight-current-row
> >
<el-table-column prop="deviceNo" label="设备号" align="center" /> <el-table-column prop="deviceNo" :label="$t('pages.archiveDevice.table.deviceNo')" align="center" />
<el-table-column prop="createTime" label="创建时间" align="center"> <el-table-column prop="createTime" :label="$t('pages.archiveDevice.table.createdAt')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.createTime | dateFormat }} {{ scope.row.createTime | dateFormat }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column fixed="right" label="操作" align="center" width="200"> <el-table-column fixed="right" :label="$t('pages.archiveDevice.table.actions')" align="center" width="200">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="text" @click.native="handleDelDevice(scope.row)">删除</el-button> <el-button type="text" @click.native="handleDelDevice(scope.row)">{{ $t('pages.archiveDevice.action.delete') }}</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -120,7 +120,7 @@ export default {
delDevice(row.id) delDevice(row.id)
.then(res => { .then(res => {
this.$message({ this.$message({
message: '删除成功', message: this.$t('pages.archiveDevice.message.deleteSuccess'),
type: 'success' type: 'success'
}) })
this.renderData(true) this.renderData(true)

View File

@ -3,7 +3,7 @@
<div class="filter-container"> <div class="filter-container">
<el-select <el-select
v-model="sysOrigins" v-model="sysOrigins"
placeholder="系统" :placeholder="$t('pages.purchaseOrders.filter.system')"
style="width: 200px" style="width: 200px"
class="filter-item" class="filter-item"
multiple multiple
@ -25,7 +25,7 @@
</el-select> </el-select>
<el-select <el-select
v-model="listQuery.platform" v-model="listQuery.platform"
placeholder="来源平台" :placeholder="$t('pages.purchaseOrders.filter.sourcePlatform')"
clearable clearable
style="width: 120px" style="width: 120px"
class="filter-item" class="filter-item"
@ -40,14 +40,14 @@
</el-select> </el-select>
<el-select <el-select
v-model="listQuery.status" v-model="listQuery.status"
placeholder="状态" :placeholder="$t('pages.purchaseOrders.filter.status')"
clearable clearable
style="width: 120px" style="width: 120px"
class="filter-item" class="filter-item"
@change="handleSearch" @change="handleSearch"
> >
<el-option <el-option
v-for="item in orderStatus" v-for="item in localizedOrderStatus"
:key="item.value" :key="item.value"
:label="item.name" :label="item.name"
:value="item.value" :value="item.value"
@ -59,13 +59,13 @@
:sys-origin=" :sys-origin="
sysOrigins && sysOrigins.length === 1 ? sysOrigins[0] : '' sysOrigins && sysOrigins.length === 1 ? sysOrigins[0] : ''
" "
placeholder="用户ID" :placeholder="$t('pages.purchaseOrders.filter.userId')"
/> />
</div> </div>
<div class="filter-item"> <div class="filter-item">
<el-input <el-input
v-model.trim="listQuery.orderId" v-model.trim="listQuery.orderId"
placeholder="订单id" :placeholder="$t('pages.purchaseOrders.filter.orderId')"
style="width: 200px;" style="width: 200px;"
/> />
</div> </div>
@ -75,9 +75,9 @@
value-format="timestamp" value-format="timestamp"
type="datetimerange" type="datetimerange"
:picker-options="pickerOptions" :picker-options="pickerOptions"
range-separator="" :range-separator="$t('pages.purchaseOrders.filter.to')"
start-placeholder="开始日期" :start-placeholder="$t('pages.purchaseOrders.filter.startDate')"
end-placeholder="结束日期" :end-placeholder="$t('pages.purchaseOrders.filter.endDate')"
/> />
</div> </div>
<el-button <el-button
@ -87,7 +87,7 @@
:disabled="searchDisabled" :disabled="searchDisabled"
@click="handleSearch" @click="handleSearch"
> >
搜索 {{ $t('pages.purchaseOrders.action.search') }}
</el-button> </el-button>
<el-button <el-button
v-if="buttonPermissions.includes('user:table:purchasing:export')" v-if="buttonPermissions.includes('user:table:purchasing:export')"
@ -96,13 +96,13 @@
icon="el-icon-download" icon="el-icon-download"
@click="exprotOrder" @click="exprotOrder"
> >
导出 {{ $t('pages.purchaseOrders.action.export') }}
</el-button> </el-button>
</div> </div>
<el-alert v-show="isShowUserTotal" type="success" :closable="false"> <el-alert v-show="isShowUserTotal" type="success" :closable="false">
<span <span
style="font-size: .25rem; color: #54c988;" style="font-size: .25rem; color: #54c988;"
>该用户总充值: {{ userTotal }}</span> >{{ $t('pages.purchaseOrders.summary.userTotalRecharge', { total: userTotal }) }}</span>
</el-alert> </el-alert>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
@ -112,7 +112,7 @@
highlight-current-row highlight-current-row
> >
<el-table-column type="index" width="50" label="No" /> <el-table-column type="index" width="50" label="No" />
<el-table-column prop="orderPurchase.evn" label="环境" align="center" width="80"> <el-table-column prop="orderPurchase.evn" :label="$t('pages.purchaseOrders.table.environment')" align="center" width="80">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.orderPurchase.evn === 'PROD'" type="success">{{ <el-tag v-if="scope.row.orderPurchase.evn === 'PROD'" type="success">{{
scope.row.orderPurchase.evn scope.row.orderPurchase.evn
@ -125,7 +125,7 @@
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="platform" prop="platform"
label="平台渠道" :label="$t('pages.purchaseOrders.table.platformChannel')"
min-width="120" min-width="120"
align="center" align="center"
> >
@ -147,7 +147,7 @@
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column prop="expandTypeName" label="事件" align="center" min-width="80" /> --> <!-- <el-table-column prop="expandTypeName" label="事件" align="center" min-width="80" /> -->
<el-table-column label="购买人" align="center" min-width="200"> <el-table-column :label="$t('pages.purchaseOrders.table.buyer')" align="center" min-width="200">
<template slot-scope="scope"> <template slot-scope="scope">
<div> <div>
<user-table-exhibit <user-table-exhibit
@ -161,59 +161,59 @@
size="mini" size="mini"
:user-profile="scope.row.friendBaseInfo" :user-profile="scope.row.friendBaseInfo"
:query-details="true" :query-details="true"
tag-name="朋友" :tag-name="$t('pages.purchaseOrders.word.friend')"
/> />
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="金额" align="center" min-width="80"> <el-table-column :label="$t('pages.purchaseOrders.table.amount')" align="center" min-width="80">
<template slot-scope="scope"> <template slot-scope="scope">
<div>{{ scope.row.orderPurchase.unitPrice }}</div> <div>{{ scope.row.orderPurchase.unitPrice }}</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="orderPurchase.productDescription" prop="orderPurchase.productDescription"
label="描述" :label="$t('pages.purchaseOrders.table.description')"
align="center" align="center"
min-width="200" min-width="200"
/> />
<el-table-column <el-table-column
prop="statusName" prop="statusName"
label="状态" :label="$t('pages.purchaseOrders.table.status')"
align="center" align="center"
min-width="100" min-width="100"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<el-tag v-if="scope.row.orderPurchase.status === 'REIMBURSE'" type="danger">{{ <el-tag v-if="scope.row.orderPurchase.status === 'REIMBURSE'" type="danger">{{
scope.row.statusName getOrderStatusName(scope.row.orderPurchase.status, scope.row.statusName)
}}</el-tag> }}</el-tag>
<el-tag v-else type="success">{{ scope.row.statusName }}</el-tag> <el-tag v-else type="success">{{ getOrderStatusName(scope.row.orderPurchase.status, scope.row.statusName) }}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="orderPurchase.orderId" prop="orderPurchase.orderId"
label="第三方ID" :label="$t('pages.purchaseOrders.table.thirdPartyId')"
align="center" align="center"
min-width="200" min-width="200"
/> />
<el-table-column <el-table-column
prop="orderPurchase.purchaseDateMs" prop="orderPurchase.purchaseDateMs"
label="购买时间" :label="$t('pages.purchaseOrders.table.purchaseTime')"
align="center" align="center"
width="200" width="200"
> >
<template slot-scope="scope"> <template slot-scope="scope">
<div>购买: {{ scope.row.orderPurchase.purchaseDateMs | dateFormat }}</div> <div>{{ $t('pages.purchaseOrders.word.purchase') }}: {{ scope.row.orderPurchase.purchaseDateMs | dateFormat }}</div>
<div>修改: {{ scope.row.orderPurchase.updateTime | dateFormat }}</div> <div>{{ $t('pages.purchaseOrders.word.update') }}: {{ scope.row.orderPurchase.updateTime | dateFormat }}</div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column fixed="right" label="操作" align="center" width="50"> <el-table-column fixed="right" :label="$t('pages.purchaseOrders.table.actions')" align="center" width="80">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
type="text" type="text"
@click="clickQueryDetails(scope.row)" @click="clickQueryDetails(scope.row)"
>详情</el-button> >{{ $t('pages.purchaseOrders.action.details') }}</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -239,7 +239,7 @@
/> />
<el-drawer <el-drawer
title="导出条件" :title="$t('pages.purchaseOrders.export.title')"
:visible="exportConditionVisible" :visible="exportConditionVisible"
:before-close="exportConditionClose" :before-close="exportConditionClose"
:close-on-press-escape="false" :close-on-press-escape="false"
@ -257,10 +257,10 @@
label-position="left" label-position="left"
label-width="70px" label-width="70px"
> >
<el-form-item label="系统" prop="sysOrigins"> <el-form-item :label="$t('pages.purchaseOrders.filter.system')" prop="sysOrigins">
<el-select <el-select
v-model="exportQuery.sysOrigins" v-model="exportQuery.sysOrigins"
placeholder="系统" :placeholder="$t('pages.purchaseOrders.filter.system')"
class="filter-item" class="filter-item"
multiple multiple
collapse-tags collapse-tags
@ -284,25 +284,25 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="月份" prop="monthDate"> <el-form-item :label="$t('pages.purchaseOrders.export.month')" prop="monthDate">
<el-date-picker <el-date-picker
v-model="exportQuery.monthDate" v-model="exportQuery.monthDate"
type="month" type="month"
value-format="yyyyMM" value-format="yyyyMM"
placeholder="选择月" :placeholder="$t('pages.purchaseOrders.export.selectMonth')"
style="width: 100%;" style="width: 100%;"
/> />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div class="drawer-footer"> <div class="drawer-footer">
<el-button @click="exportConditionClose()">关闭</el-button> <el-button @click="exportConditionClose()">{{ $t('pages.purchaseOrders.action.close') }}</el-button>
<el-button <el-button
type="primary" type="primary"
:disabled="exportLoading" :disabled="exportLoading"
:loading="exportLoading" :loading="exportLoading"
@click="exportConditionSubmit()" @click="exportConditionSubmit()"
>导出</el-button> >{{ $t('pages.purchaseOrders.action.export') }}</el-button>
</div> </div>
</div> </div>
</el-drawer> </el-drawer>
@ -327,7 +327,11 @@ export default {
components: { Pagination, PlatformSvgIcon, InAppPurchaseDetails }, components: { Pagination, PlatformSvgIcon, InAppPurchaseDetails },
data() { data() {
const commonRules = [ const commonRules = [
{ required: true, message: '必填字段不可为空', trigger: 'blur' } {
required: true,
message: this.$t('pages.purchaseOrders.validation.requiredField'),
trigger: 'blur'
}
] ]
return { return {
exportLoading: false, exportLoading: false,
@ -397,6 +401,12 @@ export default {
) )
) || [] ) || []
) )
},
localizedOrderStatus() {
return this.orderStatus.map(item => ({
...item,
name: this.getOrderStatusName(item.value, item.name)
}))
} }
}, },
watch: { watch: {
@ -463,7 +473,7 @@ export default {
}, },
exportConditionClose() { exportConditionClose() {
if (this.exportLoading) { if (this.exportLoading) {
this.$opsMessage.warn('正在执行导出, 请稍等~') this.$opsMessage.warn(this.$t('pages.purchaseOrders.message.exporting'))
return return
} }
this.exportConditionVisible = false this.exportConditionVisible = false
@ -490,9 +500,14 @@ export default {
}) })
.catch(er => { .catch(er => {
that.exportLoading = false that.exportLoading = false
this.$opsMessage.fail('下载失败!') this.$opsMessage.fail(this.$t('pages.purchaseOrders.message.downloadFailed'))
}) })
}) })
},
getOrderStatusName(status, fallback) {
const key = `pages.purchaseOrders.orderStatus.${status}`
const text = this.$t(key)
return text === key ? fallback : text
} }
} }
} }

View File

@ -3,7 +3,7 @@
<div class="filter-container"> <div class="filter-container">
<el-select <el-select
v-model="sysOrigins" v-model="sysOrigins"
placeholder="系统" :placeholder="$t('pages.goldRunningWater.filter.system')"
style="width: 200px" style="width: 200px"
class="filter-item" class="filter-item"
multiple multiple
@ -21,14 +21,14 @@
</el-select> </el-select>
<el-select <el-select
v-model="listQuery.type" v-model="listQuery.type"
placeholder="类型" :placeholder="$t('pages.goldRunningWater.filter.type')"
clearable clearable
style="width: 120px" style="width: 120px"
class="filter-item" class="filter-item"
@change="handleSearch" @change="handleSearch"
> >
<el-option <el-option
v-for="item in candyPurchasingTypes" v-for="item in localizedCandyPurchasingTypes"
:key="item.value" :key="item.value"
:label="item.name" :label="item.name"
:value="item.value" :value="item.value"
@ -39,7 +39,7 @@
v-model="listQuery.origin" v-model="listQuery.origin"
popper-class="my-autocomplete" popper-class="my-autocomplete"
:fetch-suggestions="querySearch" :fetch-suggestions="querySearch"
placeholder="请输入或选择内容" :placeholder="$t('pages.goldRunningWater.filter.origin')"
clearable clearable
@select="handleSelect" @select="handleSelect"
@clear="handleSelect" @clear="handleSelect"
@ -49,24 +49,24 @@
class="el-icon-edit el-input__icon" class="el-icon-edit el-input__icon"
/> />
<template slot-scope="{ item }"> <template slot-scope="{ item }">
<span :label="item.name">{{ item.name }}</span> <span :label="getCurrencyOriginName(item)">{{ getCurrencyOriginName(item) }}</span>
<div :key="item.value" :value="item.value" style="font-size:12px; color:#d8d0d0">{{ item.value }}</div> <div :key="item.value" :value="item.value" style="font-size:12px; color:#d8d0d0">{{ item.value }}</div>
</template> </template>
</el-autocomplete> </el-autocomplete>
</div> </div>
<div class="filter-item"> <div class="filter-item">
<account-input v-model="listQuery.userId" :sys-origin="sysOrigins && sysOrigins.length === 1? sysOrigins[0] : ''" placeholder="用户ID" /> <account-input v-model="listQuery.userId" :sys-origin="sysOrigins && sysOrigins.length === 1? sysOrigins[0] : ''" :placeholder="$t('pages.goldRunningWater.filter.userId')" />
</div> </div>
<el-input <el-input
v-model.trim="listQuery.trackId" v-model.trim="listQuery.trackId"
placeholder="跟踪ID" :placeholder="$t('pages.goldRunningWater.filter.trackId')"
style="width: 200px;" style="width: 200px;"
class="filter-item" class="filter-item"
/> />
<el-input <el-input
v-model.trim="listQuery.id" v-model.trim="listQuery.id"
v-number v-number
placeholder="记录ID" :placeholder="$t('pages.goldRunningWater.filter.recordId')"
style="width: 200px;" style="width: 200px;"
class="filter-item" class="filter-item"
/> />
@ -76,15 +76,15 @@
value-format="timestamp" value-format="timestamp"
type="datetimerange" type="datetimerange"
:picker-options="pickerOptions" :picker-options="pickerOptions"
range-separator="" :range-separator="$t('pages.goldRunningWater.filter.to')"
start-placeholder="开始日期" :start-placeholder="$t('pages.goldRunningWater.filter.startDate')"
end-placeholder="结束日期" :end-placeholder="$t('pages.goldRunningWater.filter.endDate')"
:clearable="false" :clearable="false"
/> />
</div> </div>
<el-select <el-select
v-model="listQuery.limit" v-model="listQuery.limit"
placeholder="类型" :placeholder="$t('pages.goldRunningWater.filter.pageSize')"
style="width: 120px" style="width: 120px"
class="filter-item" class="filter-item"
@change="handleSearch" @change="handleSearch"
@ -92,7 +92,7 @@
<el-option <el-option
v-for="(val) in limits" v-for="(val) in limits"
:key="val" :key="val"
:label="val+'条/页'" :label="$t('pages.goldRunningWater.filter.pageSizeValue', { size: val })"
:value="val" :value="val"
/> />
</el-select> </el-select>
@ -103,11 +103,11 @@
:disabled="listLoading" :disabled="listLoading"
@click="handleSearch" @click="handleSearch"
> >
搜索 {{ $t('pages.goldRunningWater.action.search') }}
</el-button> </el-button>
</div> </div>
<el-alert type="warning" :closable="false"> <el-alert type="warning" :closable="false">
注意: 可查看数据为最近1年内的数据 {{ $t('pages.goldRunningWater.message.recentYearOnly') }}
</el-alert> </el-alert>
<el-table <el-table
:data="list" :data="list"
@ -116,26 +116,26 @@
highlight-current-row highlight-current-row
> >
<el-table-column type="index" width="50" label="No" /> <el-table-column type="index" width="50" label="No" />
<el-table-column prop="sysOrigin" label="系统" align="center" min-width="80"> <el-table-column prop="sysOrigin" :label="$t('pages.goldRunningWater.table.system')" align="center" min-width="80">
<template slot-scope="scope"> <template slot-scope="scope">
<sys-origin-icon :icon="scope.row.runningWater.sysOrigin" :desc="scope.row.runningWater.sysOrigin" /> <sys-origin-icon :icon="scope.row.runningWater.sysOrigin" :desc="scope.row.runningWater.sysOrigin" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="用户" align="center" min-width="200"> <el-table-column :label="$t('pages.goldRunningWater.table.user')" align="center" min-width="200">
<template slot-scope="scope"> <template slot-scope="scope">
<user-table-exhibit :user-profile="scope.row.userProfile" :query-details="true" :tag-name="scope.row.backOperationName" /> <user-table-exhibit :user-profile="scope.row.userProfile" :query-details="true" :tag-name="scope.row.backOperationName" />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="类型" align="center" min-width="80"> <el-table-column :label="$t('pages.goldRunningWater.table.type')" align="center" min-width="80">
<template slot-scope="scope"> <template slot-scope="scope">
<div> <div>
<span v-if="scope.row.runningWater.type === 0">收入</span> <span v-if="scope.row.runningWater.type === 0">{{ $t('pages.goldRunningWater.type.income') }}</span>
<span v-else-if="scope.row.runningWater.type === 1">支出</span> <span v-else-if="scope.row.runningWater.type === 1">{{ $t('pages.goldRunningWater.type.expense') }}</span>
<span v-else>未知</span> <span v-else>{{ $t('pages.goldRunningWater.type.unknown') }}</span>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="糖果数" align="center" min-width="80"> <el-table-column :label="$t('pages.goldRunningWater.table.goldAmount')" align="center" min-width="80">
<template slot-scope="scope"> <template slot-scope="scope">
<div> <div>
<span v-if="scope.row.runningWater.type === 0" class="font-danger">+{{ scope.row.runningWater.quantity }}</span> <span v-if="scope.row.runningWater.type === 0" class="font-danger">+{{ scope.row.runningWater.quantity }}</span>
@ -144,10 +144,10 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="runningWater.balance" label="余额" align="center" /> <el-table-column prop="runningWater.balance" :label="$t('pages.goldRunningWater.table.balance')" align="center" />
<el-table-column label="来源" prop="runningWater.originName" align="center" show-overflow-tooltip min-width="300"> <el-table-column :label="$t('pages.goldRunningWater.table.source')" prop="runningWater.originName" align="center" show-overflow-tooltip min-width="300">
<template slot-scope="scope"> <template slot-scope="scope">
<el-tooltip class="item" effect="dark" :content="'标签:' + scope.row.runningWater.origin"> <el-tooltip class="item" effect="dark" :content="$t('pages.goldRunningWater.word.tag') + ': ' + scope.row.runningWater.origin">
<div> <div>
{{ scope.row.runningWater.originName }} {{ scope.row.runningWater.originName }}
<span v-if="scope.row.runningWater.remark">({{ scope.row.runningWater.remark }})</span> <span v-if="scope.row.runningWater.remark">({{ scope.row.runningWater.remark }})</span>
@ -155,7 +155,7 @@
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="runningWater.createTime" label="创建时间" width="200" align="center"> <el-table-column prop="runningWater.createTime" :label="$t('pages.goldRunningWater.table.createdAt')" width="200" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<div> <div>
{{ scope.row.runningWater.createTime | dateFormat('yyyy-MM-dd HH:mm:ss') }} {{ scope.row.runningWater.createTime | dateFormat('yyyy-MM-dd HH:mm:ss') }}
@ -165,8 +165,8 @@
</el-table> </el-table>
<div style="text-align: center; margin-top:20px;"> <div style="text-align: center; margin-top:20px;">
<el-button v-if="!notMore " size="mini" :disabled="listLoading" :loading="listLoading" @click="clickLoadMore">加载更多</el-button> <el-button v-if="!notMore " size="mini" :disabled="listLoading" :loading="listLoading" @click="clickLoadMore">{{ $t('pages.goldRunningWater.action.loadMore') }}</el-button>
<span v-else>已加载全部</span> <span v-else>{{ $t('pages.goldRunningWater.message.loadedAll') }}</span>
</div> </div>
</div> </div>
</template> </template>
@ -227,7 +227,13 @@ export default {
} }
}, },
computed: { computed: {
...mapGetters(['permissionsSysOriginPlatformAlls']) ...mapGetters(['permissionsSysOriginPlatformAlls']),
localizedCandyPurchasingTypes() {
return this.candyPurchasingTypes.map(item => ({
...item,
name: this.getRunningWaterTypeName(item.value, item.name)
}))
}
}, },
watch: { watch: {
rangeDate: { rangeDate: {
@ -301,14 +307,14 @@ export default {
} }
if (!that.listQuery.startTime || !that.listQuery.endTime) { if (!that.listQuery.startTime || !that.listQuery.endTime) {
that.$opsMessage.warn('请选择时间范围~') that.$opsMessage.warn(that.$t('pages.goldRunningWater.message.selectTimeRange'))
return return
} }
const startYear = new Date(that.listQuery.startTime).getFullYear() const startYear = new Date(that.listQuery.startTime).getFullYear()
const endYear = new Date(that.listQuery.endTime).getFullYear() const endYear = new Date(that.listQuery.endTime).getFullYear()
if (startYear !== endYear) { if (startYear !== endYear) {
that.$opsMessage.warn('不允许跨年查询!') that.$opsMessage.warn(that.$t('pages.goldRunningWater.message.crossYearNotAllowed'))
return return
} }
@ -352,7 +358,12 @@ export default {
}, },
createFilter(queryString) { createFilter(queryString) {
return (restaurant) => { return (restaurant) => {
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) >= 0) || (restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) >= 0) const keyword = queryString.toLowerCase()
return (
restaurant.value.toLowerCase().indexOf(keyword) >= 0 ||
restaurant.name.toLowerCase().indexOf(keyword) >= 0 ||
this.getCurrencyOriginName(restaurant).toLowerCase().indexOf(keyword) >= 0
)
} }
}, },
handleSelect(item) { handleSelect(item) {
@ -360,6 +371,22 @@ export default {
}, },
clickLoadMore() { clickLoadMore() {
this.renderData() this.renderData()
},
getRunningWaterTypeName(type, fallback) {
const keyMap = {
0: 'income',
1: 'expense'
}
const key = keyMap[type]
if (!key) {
return fallback
}
const text = this.$t(`pages.goldRunningWater.type.${key}`)
return text === `pages.goldRunningWater.type.${key}` ? fallback : text
},
getCurrencyOriginName(item) {
const text = this.$t(item.name)
return text === item.name ? item.name : text
} }
} }
} }

View File

@ -1,29 +1,29 @@
<template> <template>
<div class="meun-edit"> <div class="meun-edit">
<el-form ref="dataForm" v-loading="formLoading" :model="formData" :rules="rules" label-width="80px"> <el-form ref="dataForm" v-loading="formLoading" :model="formData" :rules="rules" label-width="80px">
<el-form-item label="当前事件"> <el-form-item :label="$t('pages.sysMenuManager.form.currentEvent')">
<el-tag>{{ eventName }}</el-tag> <el-tag>{{ eventName }}</el-tag>
</el-form-item> </el-form-item>
<el-form-item label="菜单名称" prop="menuName"> <el-form-item :label="$t('pages.sysMenuManager.form.menuName')" prop="menuName">
<el-input <el-input
v-model.trim="formData.menuName" v-model.trim="formData.menuName"
placeholder="请输入菜单名称" :placeholder="$t('pages.sysMenuManager.placeholder.menuName')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="权限名称" prop="alias"> <el-form-item :label="$t('pages.sysMenuManager.form.permissionName')" prop="alias">
<el-input <el-input
v-model.trim="formData.alias" v-model.trim="formData.alias"
placeholder="请输入权限名称" :placeholder="$t('pages.sysMenuManager.placeholder.permissionName')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="菜单类型" prop="menuType"> <el-form-item :label="$t('pages.sysMenuManager.form.menuType')" prop="menuType">
<el-radio-group v-model="formData.menuType"> <el-radio-group v-model="formData.menuType">
<el-radio :label="1">目录</el-radio> <el-radio :label="1">{{ $t('pages.sysMenuManager.menuType.directory') }}</el-radio>
<el-radio :label="2">菜单</el-radio> <el-radio :label="2">{{ $t('pages.sysMenuManager.menuType.menu') }}</el-radio>
<el-radio :label="3">按钮</el-radio> <el-radio :label="3">{{ $t('pages.sysMenuManager.menuType.button') }}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="菜单图标"> <el-form-item :label="$t('pages.sysMenuManager.form.menuIcon')">
<el-input v-model="formData.icon" placeholder="icon code" disabled> <el-input v-model="formData.icon" placeholder="icon code" disabled>
<template v-if="formData.icon" slot="prepend"> <template v-if="formData.icon" slot="prepend">
<svg-icon :icon-class="formData.icon" style="font-size:20px;" /> <svg-icon :icon-class="formData.icon" style="font-size:20px;" />
@ -32,41 +32,41 @@
slot="append" slot="append"
icon="el-icon-help" icon="el-icon-help"
@click="iconsVisible = true;" @click="iconsVisible = true;"
>选择图标</el-button> >{{ $t('pages.sysMenuManager.action.selectIcon') }}</el-button>
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item label="菜单状态" prop="status"> <el-form-item :label="$t('pages.sysMenuManager.form.menuStatus')" prop="status">
<el-radio-group v-model="formData.status"> <el-radio-group v-model="formData.status">
<el-radio :label="0">正常</el-radio> <el-radio :label="0">{{ $t('pages.sysMenuManager.status.normal') }}</el-radio>
<el-radio :label="1">禁用</el-radio> <el-radio :label="1">{{ $t('pages.sysMenuManager.status.disabled') }}</el-radio>
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
<el-form-item label="顺序权重"> <el-form-item :label="$t('pages.sysMenuManager.form.sortWeight')">
<el-input <el-input
v-model="formData.sort" v-model="formData.sort"
v-number v-number
placeholder="请输入顺序权重" :placeholder="$t('pages.sysMenuManager.placeholder.sortWeight')"
/> />
</el-form-item> </el-form-item>
<el-form-item v-if="isMenuTypeToMenu" label="菜单路径" prop="path"> <el-form-item v-if="isMenuTypeToMenu" :label="$t('pages.sysMenuManager.form.menuPath')" prop="path">
<el-input <el-input
v-model.trim="formData.path" v-model.trim="formData.path"
placeholder="请输入菜单路径" :placeholder="$t('pages.sysMenuManager.placeholder.menuPath')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="菜单路由" prop="router"> <el-form-item :label="$t('pages.sysMenuManager.form.menuRouter')" prop="router">
<el-input <el-input
v-model.trim="formData.router" v-model.trim="formData.router"
placeholder="请输入菜单路由" :placeholder="$t('pages.sysMenuManager.placeholder.menuRouter')"
/> />
</el-form-item> </el-form-item>
<el-form-item v-if="isMenuTypeToMenu" label="对应资源"> <el-form-item v-if="isMenuTypeToMenu" :label="$t('pages.sysMenuManager.form.relatedResources')">
<el-select <el-select
v-model="formData.resourceIds" v-model="formData.resourceIds"
multiple multiple
style="width:100%" style="width:100%"
class="filter-item" class="filter-item"
placeholder="请选择角色" :placeholder="$t('pages.sysMenuManager.placeholder.relatedResources')"
> >
<el-option <el-option
v-for="item in resources" v-for="item in resources"
@ -77,7 +77,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" :loading="submitLoading" @click="handleSubmit">提交</el-button> <el-button type="primary" :loading="submitLoading" @click="handleSubmit">{{ $t('pages.sysMenuManager.action.submit') }}</el-button>
</el-form-item> </el-form-item>
</el-form> </el-form>
<iconsPanel <iconsPanel
@ -115,9 +115,9 @@ export default {
default: null default: null
}, },
/** /**
* addRoot: 添加根节点 * addRoot: add root node
* addChildren添加子节点 * addChildren: add child node
* updateNode: 更新节点 * updateNode: update node
*/ */
event: { event: {
type: String, type: String,
@ -130,11 +130,6 @@ export default {
submitLoading: false, submitLoading: false,
iconsVisible: false, iconsVisible: false,
formData: defaultFormData(), formData: defaultFormData(),
rules: {
menuName: [{ required: true, message: '菜单名称必填', trigger: 'blur' }],
menuType: [{ required: true, message: '菜单类型必填', trigger: 'blur' }],
status: [{ required: true, message: '菜单状态必填', trigger: 'blur' }]
},
resources: [] resources: []
} }
}, },
@ -153,16 +148,23 @@ export default {
}, },
eventName() { eventName() {
if (this.isAdd) { if (this.isAdd) {
return `向 ”${this.nodeData.menuName}“ 添加子节点` return this.$t('pages.sysMenuManager.event.addChild', { name: this.nodeData.menuName })
} }
if (this.isUpdate) { if (this.isUpdate) {
return `修改 ”${this.nodeData.menuName}“ 节点` return this.$t('pages.sysMenuManager.event.updateNode', { name: this.nodeData.menuName })
} }
if (this.isAddRoot) { if (this.isAddRoot) {
return '添加根节点' return this.$t('pages.sysMenuManager.event.addRoot')
}
return this.$t('pages.sysMenuManager.event.invalid')
},
rules() {
return {
menuName: [{ required: true, message: this.$t('pages.sysMenuManager.validation.menuNameRequired'), trigger: 'blur' }],
menuType: [{ required: true, message: this.$t('pages.sysMenuManager.validation.menuTypeRequired'), trigger: 'blur' }],
status: [{ required: true, message: this.$t('pages.sysMenuManager.validation.menuStatusRequired'), trigger: 'blur' }]
} }
return '错误的事件'
} }
}, },
watch: { watch: {

View File

@ -5,16 +5,16 @@
size="mini" size="mini"
type="primary" type="primary"
@click="addMenu()" @click="addMenu()"
>添加一级菜单</el-button> >{{ $t('pages.sysMenuManager.tree.addRootMenu') }}</el-button>
<el-button size="mini" @click="restTree()">刷新菜单</el-button> <el-button size="mini" @click="restTree()">{{ $t('pages.sysMenuManager.tree.refreshMenu') }}</el-button>
<el-button <el-button
size="mini" size="mini"
@click="expandFirstNodeTree()" @click="expandFirstNodeTree()"
>展开一级</el-button> >{{ $t('pages.sysMenuManager.tree.expandFirstLevel') }}</el-button>
<el-button size="mini" @click="expandTree(true)">全部展开</el-button> <el-button size="mini" @click="expandTree(true)">{{ $t('pages.sysMenuManager.tree.expandAll') }}</el-button>
<el-button size="mini" @click="expandTree(false)">全部收起</el-button> <el-button size="mini" @click="expandTree(false)">{{ $t('pages.sysMenuManager.tree.collapseAll') }}</el-button>
</div> </div>
<el-alert <el-alert
class="operation" class="operation"
@ -27,7 +27,7 @@
v-model="filterText" v-model="filterText"
class="operation" class="operation"
size="small" size="small"
placeholder="输入关键字进行过滤" :placeholder="$t('pages.sysMenuManager.placeholder.filterKeyword')"
/> />
<el-tree <el-tree
ref="tree" ref="tree"
@ -55,8 +55,7 @@ export default {
menus: [], menus: [],
menusList: [], menusList: [],
filterText: '', filterText: '',
alertDescription: '当前选中节点:', activeNodeName: '',
firstNodeDesc: '根节点',
formData: { formData: {
id: '', id: '',
menuName: '', menuName: '',
@ -73,9 +72,16 @@ export default {
} }
}, },
created() { created() {
this.appendTost(this.firstNodeDesc) this.appendTost('')
this.renderTreeData() this.renderTreeData()
}, },
computed: {
alertDescription() {
return this.$t('pages.sysMenuManager.tree.selectedNode', {
name: this.activeNodeName || this.$t('pages.sysMenuManager.tree.rootNode')
})
}
},
methods: { methods: {
renderTreeData() { renderTreeData() {
const that = this const that = this
@ -129,7 +135,7 @@ export default {
handlerRenderContent(h, { node, data, store }) { handlerRenderContent(h, { node, data, store }) {
let tag = '' let tag = ''
if (data.status === 1) { if (data.status === 1) {
tag = <el-tag size='mini' type='warning' effect='plain'>禁用</el-tag> tag = <el-tag size='mini' type='warning' effect='plain'>{this.$t('pages.sysMenuManager.status.disabled')}</el-tag>
} }
return ( return (
<span class='custom-tree-node'> <span class='custom-tree-node'>
@ -140,21 +146,21 @@ export default {
type='text' type='text'
on-click={($event) => this.updateTree($event, data)} on-click={($event) => this.updateTree($event, data)}
> >
修改 {this.$t('pages.sysMenuManager.action.edit')}
</el-button> </el-button>
<el-button <el-button
size='mini' size='mini'
type='text' type='text'
on-click={($event) => this.appendTree($event, data)} on-click={($event) => this.appendTree($event, data)}
> >
添加 {this.$t('pages.sysMenuManager.action.add')}
</el-button> </el-button>
<el-button <el-button
size='mini' size='mini'
type='text' type='text'
on-click={($event) => this.removeTree($event, node, data)} on-click={($event) => this.removeTree($event, node, data)}
> >
删除 {this.$t('pages.sysMenuManager.action.delete')}
</el-button> </el-button>
</span> </span>
</span> </span>
@ -164,7 +170,7 @@ export default {
this.appendTost(data.menuName) this.appendTost(data.menuName)
}, },
appendTost(text) { appendTost(text) {
this.alertDescription = `当前选中节点:${text}` this.activeNodeName = text
}, },
handlerExpanded(list, isExpand) { handlerExpanded(list, isExpand) {
const that = this const that = this
@ -201,9 +207,9 @@ export default {
// event.stopPropagation() // event.stopPropagation()
this.$emit('removeNode', deepClone(data)) this.$emit('removeNode', deepClone(data))
const that = this const that = this
that.$confirm('此操作将永删除, 是否继续?', '提示', { that.$confirm(this.$t('pages.sysMenuManager.confirm.deleteMessage'), this.$t('pages.sysMenuManager.confirm.title'), {
confirmButtonText: '确定', confirmButtonText: this.$t('pages.sysMenuManager.confirm.confirm'),
cancelButtonText: '取消', cancelButtonText: this.$t('pages.sysMenuManager.confirm.cancel'),
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
delMenu(data.id).then(res => { delMenu(data.id).then(res => {
@ -212,7 +218,7 @@ export default {
}).catch(() => { }).catch(() => {
that.$message({ that.$message({
type: 'info', type: 'info',
message: '已取消删除' message: this.$t('pages.sysMenuManager.message.cancelled')
}) })
}) })
}, },
@ -229,7 +235,7 @@ export default {
} }
}, },
addMenu() { addMenu() {
this.appendTost(this.firstNodeDesc) this.appendTost('')
this.$emit('addRootNode') this.$emit('addRootNode')
} }
} }

View File

@ -3,15 +3,15 @@
<div class="filter-container"> <div class="filter-container">
<el-input <el-input
v-model="listQuery.resourceName" v-model="listQuery.resourceName"
placeholder="资源名" :placeholder="$t('pages.sysResourcesManager.filter.resourceName')"
style="width: 200px;" style="width: 200px;"
class="filter-item" class="filter-item"
/> />
<el-select v-model="listQuery.method" placeholder="请求方式" clearable style="width: 120px" class="filter-item"> <el-select v-model="listQuery.method" :placeholder="$t('pages.sysResourcesManager.filter.method')" clearable style="width: 120px" class="filter-item">
<el-option v-for="item in requestTypes" :key="item" :label="item" :value="item" /> <el-option v-for="item in requestTypes" :key="item" :label="item" :value="item" />
</el-select> </el-select>
<el-select v-model="listQuery.authType" placeholder=" 权限类型" clearable style="width: 120px" class="filter-item"> <el-select v-model="listQuery.authType" :placeholder="$t('pages.sysResourcesManager.filter.authType')" clearable style="width: 120px" class="filter-item">
<el-option v-for="(item,index) in grantTypes" :key="index" :label="item.name" :value="item.value" /> <el-option v-for="(item,index) in grantTypes" :key="index" :label="$t(item.nameKey)" :value="item.value" />
</el-select> </el-select>
<el-button <el-button
class="filter-item" class="filter-item"
@ -20,7 +20,7 @@
:disabled="listLoading" :disabled="listLoading"
@click="handleSearch" @click="handleSearch"
> >
搜索 {{ $t('pages.sysResourcesManager.action.search') }}
</el-button> </el-button>
<el-button <el-button
class="filter-item" class="filter-item"
@ -31,23 +31,27 @@
:disabled="resetResourcesLoading" :disabled="resetResourcesLoading"
@click="handleResetResouces" @click="handleResetResouces"
> >
刷新资源 {{ $t('pages.sysResourcesManager.action.refreshResources') }}
</el-button> </el-button>
</div> </div>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="list" :data="list"
element-loading-text="Loading" :element-loading-text="$t('pages.sysResourcesManager.loading')"
fit fit
highlight-current-row highlight-current-row
> >
<el-table-column prop="id" label="ID" align="center" width="95" /> <el-table-column prop="id" label="ID" align="center" width="95" />
<el-table-column prop="resourceName" label="资源名称" align="center" /> <el-table-column prop="resourceName" :label="$t('pages.sysResourcesManager.table.resourceName')" align="center" />
<el-table-column prop="method" label="请求方式" align="center" /> <el-table-column prop="method" :label="$t('pages.sysResourcesManager.table.method')" align="center" />
<el-table-column prop="mapping" label="映射路径" align="center" /> <el-table-column prop="mapping" :label="$t('pages.sysResourcesManager.table.mapping')" align="center" />
<el-table-column prop="authType" label="授权类型" align="center" /> <el-table-column prop="authType" :label="$t('pages.sysResourcesManager.table.authType')" align="center">
<el-table-column prop="perm" label="权限标识" align="center" /> <template slot-scope="scope">
<el-table-column prop="updateTime" label="修改时间" width="200" align="center"> {{ getAuthTypeLabel(scope.row.authType) }}
</template>
</el-table-column>
<el-table-column prop="perm" :label="$t('pages.sysResourcesManager.table.perm')" align="center" />
<el-table-column prop="updateTime" :label="$t('pages.sysResourcesManager.table.updatedAt')" width="200" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.createTime | dateFormat }} {{ scope.row.createTime | dateFormat }}
</template> </template>
@ -75,7 +79,11 @@ export default {
return { return {
resetResourcesLoading: false, resetResourcesLoading: false,
requestTypes: ['GET', 'POST', 'PUT', 'DELETE'], requestTypes: ['GET', 'POST', 'PUT', 'DELETE'],
grantTypes: [{ value: '1', name: '需要登录' }, { value: '2', name: '无需鉴权' }, { value: '3', name: '需要鉴权' }], grantTypes: [
{ value: '1', nameKey: 'pages.sysResourcesManager.authTypes.loginRequired' },
{ value: '2', nameKey: 'pages.sysResourcesManager.authTypes.noAuthRequired' },
{ value: '3', nameKey: 'pages.sysResourcesManager.authTypes.authRequired' }
],
list: [], list: [],
total: 0, total: 0,
listQuery: { listQuery: {
@ -108,6 +116,10 @@ export default {
handleSearch() { handleSearch() {
this.renderData(true) this.renderData(true)
}, },
getAuthTypeLabel(authType) {
const matchedType = this.grantTypes.find(item => String(item.value) === String(authType))
return matchedType ? this.$t(matchedType.nameKey) : authType
},
handleResetResouces() { handleResetResouces() {
const that = this const that = this
that.resetResourcesLoading = true that.resetResourcesLoading = true

View File

@ -2,7 +2,7 @@
<div class="authorize-role"> <div class="authorize-role">
<el-drawer <el-drawer
title="角色授权" :title="$t('pages.sysRoleManager.drawer.authorize')"
:visible="true" :visible="true"
:before-close="handleClose" :before-close="handleClose"
:close-on-press-escape="false" :close-on-press-escape="false"
@ -16,6 +16,7 @@
<el-tree <el-tree
ref="tree" ref="tree"
v-loading="treeLoading" v-loading="treeLoading"
:element-loading-text="$t('pages.sysRoleManager.loading')"
:data="menus" :data="menus"
:expand-on-click-node="false" :expand-on-click-node="false"
node-key="id" node-key="id"
@ -25,8 +26,8 @@
</div> </div>
<div class="drawer-footer"> <div class="drawer-footer">
<el-button @click="handleClose"> 取消 </el-button> <el-button @click="handleClose">{{ $t('pages.sysRoleManager.action.cancel') }}</el-button>
<el-button type="primary" :loading="submitLoading" :disabled="submitLoading" @click="handleSubmit">提交</el-button> <el-button type="primary" :loading="submitLoading" :disabled="submitLoading" @click="handleSubmit">{{ $t('pages.sysRoleManager.action.submit') }}</el-button>
</div> </div>
</div> </div>
</el-drawer> </el-drawer>

View File

@ -18,24 +18,24 @@
label-position="right" label-position="right"
label-width="70px" label-width="70px"
> >
<el-form-item label="角色名" prop="roleName"> <el-form-item :label="$t('pages.sysRoleManager.form.roleName')" prop="roleName">
<el-input v-model.trim="formData.roleName" placeholder="请输入角色名" /> <el-input v-model.trim="formData.roleName" :placeholder="$t('pages.sysRoleManager.placeholder.roleName')" />
</el-form-item> </el-form-item>
<el-form-item label="备注" prop="remark"> <el-form-item :label="$t('pages.sysRoleManager.form.remark')" prop="remark">
<el-input <el-input
v-model.trim="formData.remark" v-model.trim="formData.remark"
rows="6" rows="6"
resize="none" resize="none"
type="textarea" type="textarea"
placeholder="请输入备注" :placeholder="$t('pages.sysRoleManager.placeholder.remark')"
/> />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<div class="drawer-footer"> <div class="drawer-footer">
<el-button @click="handleClose"> <el-button @click="handleClose">
取消 {{ $t('pages.sysRoleManager.action.cancel') }}
</el-button> </el-button>
<el-button <el-button
:loading="submitLoading" :loading="submitLoading"
@ -43,7 +43,7 @@
type="primary" type="primary"
@click="handleSubmit" @click="handleSubmit"
> >
提交 {{ $t('pages.sysRoleManager.action.submit') }}
</el-button> </el-button>
</div> </div>
</el-drawer> </el-drawer>
@ -62,13 +62,12 @@ export default {
data() { data() {
const validateRemark = (rule, value, callback) => { const validateRemark = (rule, value, callback) => {
if (value && value.length > 100) { if (value && value.length > 100) {
callback(new Error('max 100 character')) callback(new Error(this.$t('pages.sysRoleManager.validation.remarkMax')))
} else { } else {
callback() callback()
} }
} }
return { return {
roles: ['超级管理员', '管理员'],
formData: { formData: {
id: '', id: '',
remark: '', remark: '',
@ -76,9 +75,9 @@ export default {
}, },
rules: { rules: {
roleName: [ roleName: [
{ required: true, message: '角色名必填', trigger: 'change' } { required: true, message: this.$t('pages.sysRoleManager.validation.roleNameRequired'), trigger: 'change' }
], ],
remark: [{ required: false, message: '备注必须在100字符以内', trigger: 'blur', validator: validateRemark }] remark: [{ required: false, message: this.$t('pages.sysRoleManager.validation.remarkMax'), trigger: 'blur', validator: validateRemark }]
}, },
submitLoading: false submitLoading: false
} }
@ -88,7 +87,7 @@ export default {
return this.updateData === null return this.updateData === null
}, },
title() { title() {
return this.isAdd ? '创建' : '修改' return this.isAdd ? this.$t('pages.sysRoleManager.drawer.create') : this.$t('pages.sysRoleManager.drawer.edit')
} }
}, },
watch: { watch: {

View File

@ -3,7 +3,7 @@
<div class="filter-container"> <div class="filter-container">
<el-input <el-input
v-model="listQuery.roleName" v-model="listQuery.roleName"
placeholder="角色名称" :placeholder="$t('pages.sysRoleManager.filter.roleName')"
style="width: 200px;" style="width: 200px;"
class="filter-item" class="filter-item"
/> />
@ -14,7 +14,7 @@
:disabled="listLoading" :disabled="listLoading"
@click="handleSearch" @click="handleSearch"
> >
搜索 {{ $t('pages.sysRoleManager.action.search') }}
</el-button> </el-button>
<el-button <el-button
class="filter-item" class="filter-item"
@ -23,23 +23,23 @@
icon="el-icon-edit" icon="el-icon-edit"
@click="handleCreate" @click="handleCreate"
> >
添加 {{ $t('pages.sysRoleManager.action.add') }}
</el-button> </el-button>
</div> </div>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="list" :data="list"
element-loading-text="Loading" :element-loading-text="$t('pages.sysRoleManager.loading')"
fit fit
highlight-current-row highlight-current-row
@cell-mouse-enter="handleMouseEnter" @cell-mouse-enter="handleMouseEnter"
> >
<el-table-column prop="id" label="ID" align="center" /> <el-table-column prop="id" label="ID" align="center" />
<el-table-column prop="roleName" label="角色" align="center" /> <el-table-column prop="roleName" :label="$t('pages.sysRoleManager.table.role')" align="center" />
<el-table-column prop="remark" label="备注" align="center" /> <el-table-column prop="remark" :label="$t('pages.sysRoleManager.table.remark')" align="center" />
<el-table-column <el-table-column
prop="createTime" prop="createTime"
label="创建时间" :label="$t('pages.sysRoleManager.table.createdAt')"
width="200" width="200"
align="center" align="center"
> >
@ -49,7 +49,7 @@
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="updateTime" prop="updateTime"
label="修改时间" :label="$t('pages.sysRoleManager.table.updatedAt')"
width="200" width="200"
align="center" align="center"
> >
@ -57,19 +57,19 @@
{{ scope.row.updateTime | dateFormat }} {{ scope.row.updateTime | dateFormat }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column fixed="right" label="操作" align="center" width="180"> <el-table-column fixed="right" :label="$t('pages.sysRoleManager.table.actions')" align="center" width="180">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
type="text" type="text"
size="small" size="small"
@click="handlerGrant(scope.row)" @click="handlerGrant(scope.row)"
>菜单授权</el-button> >{{ $t('pages.sysRoleManager.action.authorizeMenu') }}</el-button>
<el-button <el-button
type="text" type="text"
size="small" size="small"
@click="handleUpdateClick(scope.row)" @click="handleUpdateClick(scope.row)"
>修改</el-button> >{{ $t('pages.sysRoleManager.action.edit') }}</el-button>
<el-button type="text" size="small" @click="clickDelRole(scope.row.id)">删除</el-button> <el-button type="text" size="small" @click="clickDelRole(scope.row.id)">{{ $t('pages.sysRoleManager.action.delete') }}</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -115,7 +115,6 @@ export default {
dialogGrantVisible: false, dialogGrantVisible: false,
grantSubmitLoading: false, grantSubmitLoading: false,
menuIds: [], menuIds: [],
roles: ['超级管理员', '管理员'],
list: [], list: [],
total: 0, total: 0,
listQuery: { listQuery: {
@ -123,10 +122,6 @@ export default {
limit: 20, limit: 20,
roleName: '' roleName: ''
}, },
accountStatus: [
{ value: 0, name: '正常' },
{ value: 1, name: '禁用' }
],
listLoading: false listLoading: false
} }
}, },
@ -178,9 +173,9 @@ export default {
}, },
clickDelRole(id) { clickDelRole(id) {
const that = this const that = this
that.$confirm('此操作将永删除, 是否继续?', '提示', { that.$confirm(that.$t('pages.sysRoleManager.confirm.deleteRole'), that.$t('pages.sysRoleManager.confirm.title'), {
confirmButtonText: '确定', confirmButtonText: that.$t('pages.sysRoleManager.confirm.confirm'),
cancelButtonText: '取消', cancelButtonText: that.$t('pages.sysRoleManager.confirm.cancel'),
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
delRole(id).then(res => { delRole(id).then(res => {
@ -190,7 +185,7 @@ export default {
}).catch(() => { }).catch(() => {
that.$message({ that.$message({
type: 'info', type: 'info',
message: '已取消删除' message: that.$t('pages.sysRoleManager.message.cancelled')
}) })
}) })
}, },

View File

@ -17,47 +17,47 @@
label-position="right" label-position="right"
label-width="70px" label-width="70px"
> >
<el-form-item label="账号" prop="loginName"> <el-form-item :label="$t('pages.sysUserManager.form.account')" prop="loginName">
<div v-if="isAdd"> <div v-if="isAdd">
<el-input <el-input
v-model.trim="formData.loginName" v-model.trim="formData.loginName"
placeholder="请输入登录账号" :placeholder="$t('pages.sysUserManager.placeholder.account')"
/> />
</div> </div>
<div v-else>{{ formData.loginName }}</div> <div v-else>{{ formData.loginName }}</div>
</el-form-item> </el-form-item>
<el-form-item label="昵称" prop="nickname"> <el-form-item :label="$t('pages.sysUserManager.form.nickname')" prop="nickname">
<el-input <el-input
v-model.trim="formData.nickname" v-model.trim="formData.nickname"
placeholder="请输入用户昵称" :placeholder="$t('pages.sysUserManager.placeholder.nickname')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="电话" prop="phone"> <el-form-item :label="$t('pages.sysUserManager.form.phone')" prop="phone">
<el-input <el-input
v-model="formData.phone" v-model="formData.phone"
v-number v-number
placeholder="请输入手机号码" :placeholder="$t('pages.sysUserManager.placeholder.phone')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="邮箱" prop="email"> <el-form-item :label="$t('pages.sysUserManager.form.email')" prop="email">
<el-input <el-input
v-model.trim="formData.email" v-model.trim="formData.email"
placeholder="请输入电子邮箱" :placeholder="$t('pages.sysUserManager.placeholder.email')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="角色" prop="roleIds"> <el-form-item :label="$t('pages.sysUserManager.form.role')" prop="roleIds">
<!--multiple 取消角色多选支持--> <!-- multiple: keep role multi-select support disabled if product needs it later -->
<el-select <el-select
v-model="formData.roleIds" v-model="formData.roleIds"
v-loading="roleLoading" v-loading="roleLoading"
style="width:100%" style="width:100%"
class="filter-item" class="filter-item"
multiple multiple
placeholder="请选择角色" :placeholder="$t('pages.sysUserManager.placeholder.role')"
> >
<el-option <el-option
v-for="item in roles" v-for="item in roles"
@ -71,14 +71,14 @@
<div class="drawer-footer"> <div class="drawer-footer">
<el-button @click="handleClose"> <el-button @click="handleClose">
取消 {{ $t('pages.sysUserManager.action.cancel') }}
</el-button> </el-button>
<el-button <el-button
type="primary" type="primary"
:loading="submitLoading" :loading="submitLoading"
@click="handleSubmit" @click="handleSubmit"
> >
提交 {{ $t('pages.sysUserManager.action.submit') }}
</el-button> </el-button>
</div> </div>
</div> </div>
@ -106,19 +106,6 @@ export default {
phone: '', phone: '',
email: '', email: '',
roleIds: [] roleIds: []
},
rules: {
loginName: [
{ required: true, message: '用户名必填', trigger: 'blur' }
],
nickname: [
{
required: true,
message: '用户昵称必填',
trigger: 'blur'
}
],
roleIds: [{ required: true, message: '角色必填', trigger: 'blur' }]
} }
} }
}, },
@ -127,7 +114,26 @@ export default {
return this.updateData === null return this.updateData === null
}, },
title() { title() {
return this.isAdd ? '创建' : '修改' return this.isAdd
? this.$t('pages.sysUserManager.drawer.create')
: this.$t('pages.sysUserManager.drawer.edit')
},
rules() {
return {
loginName: [
{ required: true, message: this.$t('pages.sysUserManager.validation.accountRequired'), trigger: 'blur' }
],
nickname: [
{
required: true,
message: this.$t('pages.sysUserManager.validation.nicknameRequired'),
trigger: 'blur'
}
],
roleIds: [
{ required: true, message: this.$t('pages.sysUserManager.validation.roleRequired'), trigger: 'blur' }
]
}
} }
}, },
watch: { watch: {

View File

@ -3,27 +3,27 @@
<div class="filter-container"> <div class="filter-container">
<el-input <el-input
v-model="listQuery.loginName" v-model="listQuery.loginName"
placeholder="账号" :placeholder="$t('pages.sysUserManager.filter.account')"
style="width: 200px;" style="width: 200px;"
class="filter-item" class="filter-item"
/> />
<el-input <el-input
v-model="listQuery.nickname" v-model="listQuery.nickname"
placeholder="昵称" :placeholder="$t('pages.sysUserManager.filter.nickname')"
style="width: 200px;" style="width: 200px;"
class="filter-item" class="filter-item"
/> />
<el-select <el-select
v-model="listQuery.status" v-model="listQuery.status"
placeholder="状态" :placeholder="$t('pages.sysUserManager.filter.status')"
clearable clearable
style="width: 90px" style="width: 90px"
class="filter-item" class="filter-item"
> >
<el-option <el-option
v-for="item in accountStatus" v-for="item in accountStatusOptions"
:key="item.value" :key="item.value"
:label="item.name" :label="item.label"
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
@ -34,7 +34,7 @@
:disabled="listLoading" :disabled="listLoading"
@click="handleSearch" @click="handleSearch"
> >
搜索 {{ $t('pages.sysUserManager.action.search') }}
</el-button> </el-button>
<el-button <el-button
class="filter-item" class="filter-item"
@ -43,36 +43,36 @@
icon="el-icon-edit" icon="el-icon-edit"
@click="clickCreateUser" @click="clickCreateUser"
> >
添加 {{ $t('pages.sysUserManager.action.add') }}
</el-button> </el-button>
</div> </div>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="list" :data="list"
element-loading-text="Loading" :element-loading-text="$t('pages.sysUserManager.loading')"
fit fit
highlight-current-row highlight-current-row
@cell-mouse-enter="handleMouseEnter" @cell-mouse-enter="handleMouseEnter"
> >
<el-table-column prop="id" label="ID" align="center" /> <el-table-column prop="id" label="ID" align="center" />
<el-table-column prop="loginName" label="账号" align="center" /> <el-table-column prop="loginName" :label="$t('pages.sysUserManager.table.account')" align="center" />
<el-table-column prop="nickname" label="昵称" align="center" /> <el-table-column prop="nickname" :label="$t('pages.sysUserManager.table.nickname')" align="center" />
<el-table-column prop="nickname" label="角色" align="center"> <el-table-column prop="nickname" :label="$t('pages.sysUserManager.table.role')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.userRoles | joinRolesFilter }} {{ scope.row.userRoles | joinRolesFilter }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="phone" prop="phone"
label="手机号码" :label="$t('pages.sysUserManager.table.phone')"
width="110" width="110"
align="center" align="center"
/> />
<el-table-column prop="email" label="邮箱" width="110" align="center" /> <el-table-column prop="email" :label="$t('pages.sysUserManager.table.email')" width="110" align="center" />
<el-table-column <el-table-column
prop="createTime" prop="createTime"
label="创建时间" :label="$t('pages.sysUserManager.table.createdAt')"
width="200" width="200"
align="center" align="center"
> >
@ -81,26 +81,26 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="nickname" label="状态" align="center"> <el-table-column prop="nickname" :label="$t('pages.sysUserManager.table.status')" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch <el-switch
v-model="scope.row.status" v-model="scope.row.status"
:active-value="0" :active-value="0"
:inactive-value="1" :inactive-value="1"
active-text="正常" :active-text="$t('pages.sysUserManager.status.normal')"
inactive-text="禁用" :inactive-text="$t('pages.sysUserManager.status.disabled')"
@change="clickSwitchChange(scope.row)" @change="clickSwitchChange(scope.row)"
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column fixed="right" label="操作" align="center" width="150"> <el-table-column fixed="right" :label="$t('pages.sysUserManager.table.actions')" align="center" width="150">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
type="text" type="text"
size="small" size="small"
@click="clickUpdateClick(scope.row)" @click="clickUpdateClick(scope.row)"
>修改</el-button> >{{ $t('pages.sysUserManager.action.edit') }}</el-button>
<el-button type="text" size="small" @click="clickRestPwd(scope.row)">重置密码</el-button> <el-button type="text" size="small" @click="clickRestPwd(scope.row)">{{ $t('pages.sysUserManager.action.resetPassword') }}</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -142,7 +142,6 @@ export default {
return { return {
editUserVisible: false, editUserVisible: false,
activeRow: null, activeRow: null,
roles: ['超级管理员', '管理员'],
list: [], list: [],
total: 0, total: 0,
listQuery: { listQuery: {
@ -152,16 +151,18 @@ export default {
nickname: '', nickname: '',
status: '' status: ''
}, },
accountStatus: [
{ value: 0, name: '正常' },
{ value: 1, name: '禁用' }
],
listLoading: false listLoading: false
} }
}, },
computed: { computed: {
thisActiveRow() { thisActiveRow() {
return this.activeRow ? Object.assign({}, this.activeRow) : null return this.activeRow ? Object.assign({}, this.activeRow) : null
},
accountStatusOptions() {
return [
{ value: 0, label: this.$t('pages.sysUserManager.status.normal') },
{ value: 1, label: this.$t('pages.sysUserManager.status.disabled') }
]
} }
}, },
created() { created() {
@ -206,16 +207,16 @@ export default {
}) })
}, },
clickRestPwd(row) { clickRestPwd(row) {
this.$confirm(`是否确认重置 "${row.nickname}" 登陆密码?`, '提示', { this.$confirm(this.$t('pages.sysUserManager.confirm.resetPassword', { nickname: row.nickname }), this.$t('pages.sysUserManager.confirm.title'), {
confirmButtonText: '确定', confirmButtonText: this.$t('pages.sysUserManager.confirm.confirm'),
cancelButtonText: '取消', cancelButtonText: this.$t('pages.sysUserManager.confirm.cancel'),
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
restPassword(row.id).then(res => { restPassword(row.id).then(res => {
this.$opsMessage.success() this.$opsMessage.success()
}) })
}).catch(() => { }).catch(() => {
this.$opsMessage.info('已取消删除') this.$opsMessage.info(this.$t('pages.sysUserManager.message.cancelled'))
}) })
}, },
handleMouseEnter(row) { handleMouseEnter(row) {

View File

@ -3,7 +3,7 @@
<div class="filter-container"> <div class="filter-container">
<el-select <el-select
v-model="listQuery.sysOrigin" v-model="listQuery.sysOrigin"
placeholder="归属系统" :placeholder="$t('pages.userDevice.filter.system')"
style="width: 120px" style="width: 120px"
class="filter-item" class="filter-item"
@change="handleSearch" @change="handleSearch"
@ -26,11 +26,11 @@
v-model="listQuery.userId" v-model="listQuery.userId"
:sys-origin="listQuery.sysOrigin" :sys-origin="listQuery.sysOrigin"
class="filter-item" class="filter-item"
placeholder="用户ID" :placeholder="$t('pages.userDevice.filter.userId')"
/> />
<el-input <el-input
v-model.trim="listQuery.imei" v-model.trim="listQuery.imei"
placeholder="设备号" :placeholder="$t('pages.userDevice.filter.deviceNo')"
style="width: 200px;" style="width: 200px;"
class="filter-item" class="filter-item"
/> />
@ -40,9 +40,9 @@
value-format="timestamp" value-format="timestamp"
type="datetimerange" type="datetimerange"
:picker-options="pickerOptions" :picker-options="pickerOptions"
range-separator="" :range-separator="$t('pages.userDevice.dateRange.separator')"
start-placeholder="注册开始日期" :start-placeholder="$t('pages.userDevice.dateRange.start')"
end-placeholder="注册结束日期" :end-placeholder="$t('pages.userDevice.dateRange.end')"
/> />
</div> </div>
<el-button <el-button
@ -52,18 +52,18 @@
:disabled="searchDisabled" :disabled="searchDisabled"
@click="handleSearch" @click="handleSearch"
> >
搜索 {{ $t('pages.userDevice.action.search') }}
</el-button> </el-button>
</div> </div>
<el-table <el-table
v-loading="listLoading" v-loading="listLoading"
:data="list" :data="list"
element-loading-text="Loading" :element-loading-text="$t('pages.userDevice.loading')"
fit fit
highlight-current-row highlight-current-row
> >
<el-table-column prop="id" label="ID" align="center" width="200" /> <el-table-column prop="id" label="ID" align="center" width="200" />
<el-table-column prop="sysOrigin" label="系统" align="center" min-width="50"> <el-table-column prop="sysOrigin" :label="$t('pages.userDevice.table.system')" align="center" min-width="50">
<template slot-scope="scope"> <template slot-scope="scope">
<sys-origin-icon <sys-origin-icon
:icon="scope.row.sysOrigin" :icon="scope.row.sysOrigin"
@ -71,7 +71,7 @@
/> />
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="用户" align="center" min-width="200"> <el-table-column :label="$t('pages.userDevice.table.user')" align="center" min-width="200">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
v-if="scope.row.userId" v-if="scope.row.userId"
@ -80,26 +80,26 @@
>{{ scope.row.userNickname }}</el-button> >{{ scope.row.userNickname }}</el-button>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="registerNumber" label="注册数量" align="center" min-width="80" /> <el-table-column prop="registerNumber" :label="$t('pages.userDevice.table.registerCount')" align="center" min-width="80" />
<el-table-column prop="ip" label="最近登录IP" align="center" min-width="200" /> <el-table-column prop="ip" :label="$t('pages.userDevice.table.latestLoginIp')" align="center" min-width="200" />
<el-table-column prop="imei" label="设备号" align="center" min-width="80"> <el-table-column prop="imei" :label="$t('pages.userDevice.table.deviceNo')" align="center" min-width="80">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
type="text" type="text"
@click="copyContent(scope.row.imei)" @click="copyContent(scope.row.imei)"
>点击复制</el-button> >{{ $t('pages.userDevice.action.copy') }}</el-button>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="requestClient" label="请求平台" align="center" min-width="80" /> <el-table-column prop="requestClient" :label="$t('pages.userDevice.table.requestPlatform')" align="center" min-width="80" />
<el-table-column prop="phoneModel" label="手机型号" align="center" min-width="80" /> <el-table-column prop="phoneModel" :label="$t('pages.userDevice.table.phoneModel')" align="center" min-width="80" />
<el-table-column prop="phoneSysVersion" label="操作系统" align="center" min-width="80" /> <el-table-column prop="phoneSysVersion" :label="$t('pages.userDevice.table.operatingSystem')" align="center" min-width="80" />
<el-table-column prop="appVersion" label="App版本" align="center" min-width="80" /> <el-table-column prop="appVersion" :label="$t('pages.userDevice.table.appVersion')" align="center" min-width="80" />
<el-table-column prop="createTime" label="创建时间" align="center" width="200"> <el-table-column prop="createTime" :label="$t('pages.userDevice.table.createdAt')" align="center" width="200">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.createTime | dateFormat }} {{ scope.row.createTime | dateFormat }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="updateTime" label="修改时间" align="center" width="200"> <el-table-column prop="updateTime" :label="$t('pages.userDevice.table.updatedAt')" align="center" width="200">
<template slot-scope="scope"> <template slot-scope="scope">
{{ scope.row.updateTime | dateFormat }} {{ scope.row.updateTime | dateFormat }}
</template> </template>