feat: 语言切换功能
This commit is contained in:
parent
ca86f075dd
commit
e7a2073e00
@ -5,7 +5,9 @@ VUE_APP_BASE_API = '/console'
|
||||
VUE_CLI_BABEL_TRANSPILE_MODULES = true
|
||||
|
||||
# application base url
|
||||
VUE_APP_BASE_URL ='https://consoletest.azizichat.com'
|
||||
# VUE_APP_BASE_URL ='https://consoletest.azizichat.com'
|
||||
VUE_APP_BASE_URL ='https://console.atuchat.com'
|
||||
# VUE_APP_BASE_URL = 'https://console.likeichat.com'
|
||||
|
||||
# oss
|
||||
VUE_APP_OSS_BUCKET = 'tkm-likei'
|
||||
|
||||
BIN
build-egg-thread1.log
Normal file
BIN
build-egg-thread1.log
Normal file
Binary file not shown.
190
docs/UI橙色主题与交互顺序调整记录.md
Normal file
190
docs/UI橙色主题与交互顺序调整记录.md
Normal file
@ -0,0 +1,190 @@
|
||||
# UI 橙色主题与交互顺序调整记录
|
||||
|
||||
## 1. 变更背景
|
||||
|
||||
本次调整目标:
|
||||
|
||||
- 将项目整体视觉风格从原有偏冷色风格调整为偏橙色风格,主色以 `#FF9326`、`#FEB219` 为核心。
|
||||
- 取消暗夜模式,仅保留常规亮色展示。
|
||||
- 允许调整按钮样式、圆角、阴影、表单项顺序、搜索项顺序、静态多选/下拉选项顺序。
|
||||
- 明确不调整权限点、业务逻辑、接口行为、路由配置。
|
||||
|
||||
本次所有改动均以 UI 层和静态展示层为边界。
|
||||
|
||||
## 2. 整体视觉风格调整
|
||||
|
||||
### 2.1 主色与基础风格
|
||||
|
||||
已将项目主视觉切换为橙色系,重点调整包括:
|
||||
|
||||
- 主按钮、默认按钮、文本按钮颜色统一为橙色主题。
|
||||
- 输入框、选择器、日期组件的聚焦态边框和阴影改为橙色高亮。
|
||||
- 弹窗、抽屉、卡片、表格等容器统一增加暖色边框、圆角和阴影。
|
||||
- 顶栏、侧边栏、Logo 区域统一为暖色风格。
|
||||
|
||||
重点样式文件:
|
||||
|
||||
- `src/styles/element-ui.scss`
|
||||
- `src/styles/variables.scss`
|
||||
- `src/styles/index.scss`
|
||||
- `src/styles/sidebar.scss`
|
||||
- `src/styles/element-variables.scss`
|
||||
|
||||
### 2.2 按钮与弹窗按钮视觉顺序
|
||||
|
||||
已统一主按钮视觉优先级,使确认类按钮更突出。
|
||||
其中弹窗/抽屉底部操作区通过样式顺序优化为主按钮优先展示,但未改动原始点击逻辑。
|
||||
|
||||
## 3. 暗夜模式取消
|
||||
|
||||
已取消暗夜模式入口及暗夜切换能力,处理方式如下:
|
||||
|
||||
- `src/utils/theme.js`
|
||||
- `getTheme()` 固定返回 `normal`
|
||||
- `setTheme()` 固定写入 `normal`
|
||||
- `checkSwitchTheme()` 固定清除根节点暗色类名
|
||||
- `src/layout/components/index.js`
|
||||
- 导航栏导出切换为 `NavbarLight.vue`
|
||||
- `src/layout/components/NavbarLight.vue`
|
||||
- 新增简化版导航栏
|
||||
- 移除主题切换相关入口,仅保留常用功能
|
||||
|
||||
说明:
|
||||
|
||||
- 原有权限逻辑、导航逻辑未修改。
|
||||
- 该处理方式属于 UI 层收口,不影响业务行为。
|
||||
|
||||
## 4. 搜索区与表单项顺序调整
|
||||
|
||||
针对页面内搜索区、过滤区、表单项的展示顺序做了纯 UI 层重排,主要通过模板顺序和样式 `order` 控制完成,不改查询参数结构和业务逻辑。
|
||||
|
||||
已调整的典型页面:
|
||||
|
||||
- `src/views/user/user-table/index.vue`
|
||||
- `src/views/user/user-table-role/index.vue`
|
||||
- `src/views/user/freight/index.vue`
|
||||
- `src/views/version/app/index.vue`
|
||||
|
||||
调整方向包括:
|
||||
|
||||
- 系统、国家、账号、设备、状态、性别、注册来源、来源平台、日期区间等筛选项顺序重新整理。
|
||||
- 搜索按钮、概览按钮、条件展开开关等操作项顺序重新排列。
|
||||
- 保证搜索区主流程更靠前,次级条件靠后。
|
||||
|
||||
## 5. 静态选项顺序调整
|
||||
|
||||
仅对前端文件内写死的选项顺序进行了整理;接口返回的列表未做改动。
|
||||
|
||||
### 5.1 公共输入组件
|
||||
|
||||
- `src/components/data/AccountInput/index.vue`
|
||||
- 类型顺序由原来的“长 ID / 短 ID”调整为“短 ID / 长 ID”
|
||||
- `src/components/data/SearchRoomInput/index.vue`
|
||||
- 类型顺序由原来的“长 ID / 短 ID”调整为“短 ID / 长 ID”
|
||||
|
||||
### 5.2 静态常量
|
||||
|
||||
- `src/constant/origin.js`
|
||||
- 注册来源顺序调整
|
||||
- 来源平台顺序调整
|
||||
- App 平台顺序调整
|
||||
- `src/constant/type.js`
|
||||
- `platformOrigins` 平台顺序调整为 Android 优先
|
||||
|
||||
说明:
|
||||
|
||||
- 仅变更静态数组的前端展示顺序。
|
||||
- 未变更任何接口字段含义或后端约定。
|
||||
|
||||
## 6. 侧边栏折叠态图标居中修复
|
||||
|
||||
在橙色样式改造后,发现侧边栏收起状态下图标未居中。
|
||||
原因是旧实现依赖固定 `margin-left` 偏移,无法适配新的侧边栏宽度、内边距和圆角布局。
|
||||
|
||||
处理方式:
|
||||
|
||||
- 修改 `src/styles/sidebar.scss`
|
||||
- 将折叠菜单项和子菜单标题改为 `flex` 居中
|
||||
- 清除折叠态图标的额外左边距
|
||||
|
||||
修复结果:
|
||||
|
||||
- 侧边栏收起后图标可在中轴线上正常居中显示
|
||||
- 不影响菜单高亮、路由跳转和交互逻辑
|
||||
|
||||
## 7. 弹窗被遮罩层覆盖问题修复
|
||||
|
||||
发现类似以下统计类弹窗:
|
||||
|
||||
```vue
|
||||
<user-registration-overview-charts-dialog
|
||||
v-if="UserRegistrationOverviewChartsDialogVisible"
|
||||
@close="UserRegistrationOverviewChartsDialogVisible = false"
|
||||
/>
|
||||
```
|
||||
|
||||
存在“弹窗本体在遮罩层下方、展示不全且无法点击”的问题。
|
||||
|
||||
### 7.1 原因
|
||||
|
||||
- 遮罩层默认挂载到 `body`
|
||||
- 弹窗本体未挂载到 `body`
|
||||
- 页面内容容器存在局部层叠上下文和 `overflow: hidden`
|
||||
- 最终导致遮罩层在外层,而弹窗仍在页面容器内部,被裁切或压住
|
||||
|
||||
### 7.2 修复方式
|
||||
|
||||
已为以下同类弹窗补充:
|
||||
|
||||
- `:modal-append-to-body="true"`
|
||||
- `:append-to-body="true"`
|
||||
|
||||
已处理文件:
|
||||
|
||||
- `src/components/data/UserRegistrationOverviewCharts/dialog.vue`
|
||||
- `src/components/data/PropsSalesOverviewCharts/dialog.vue`
|
||||
|
||||
### 7.3 修复结果
|
||||
|
||||
- 弹窗与遮罩层处于同一挂载层级
|
||||
- 弹窗可完整显示并可正常交互
|
||||
- 不影响弹窗内部业务逻辑
|
||||
|
||||
## 8. 验证情况
|
||||
|
||||
本次样式主改造完成后,已执行生产构建校验:
|
||||
|
||||
```powershell
|
||||
$env:NODE_OPTIONS='--openssl-legacy-provider'; npm run build:prod
|
||||
```
|
||||
|
||||
结果:
|
||||
|
||||
- 构建通过
|
||||
- 存在若干项目原有 warning
|
||||
- 这些 warning 主要为旧代码中的导出提示、样式顺序提示、Sass 旧 API 提示,不属于本次 UI 改造新增问题
|
||||
|
||||
说明:
|
||||
|
||||
- 后续对侧边栏折叠图标、统计弹窗挂载层级的修复属于局部样式修正,本记录未逐次重复构建
|
||||
|
||||
## 9. 变更边界说明
|
||||
|
||||
本次调整明确未涉及以下内容:
|
||||
|
||||
- 权限点
|
||||
- 功能逻辑
|
||||
- 接口行为
|
||||
- 路由结构
|
||||
- 后端字段定义
|
||||
|
||||
本次属于前端 UI 视觉统一、静态交互顺序整理与样式问题修复。
|
||||
|
||||
## 10. 建议后续项
|
||||
|
||||
如后续继续做 UI 收口,可优先补充以下内容:
|
||||
|
||||
- 继续逐页排查页面内写死的下拉、多选、单选顺序
|
||||
- 统一所有统计类、详情类弹窗的 `append-to-body` 规范
|
||||
- 继续检查折叠侧边栏下的图标、文字、tooltip 对齐一致性
|
||||
- 对全站弹窗、抽屉、表格筛选区形成统一样式规范文档
|
||||
533
docs/i18n/主要路由.md
Normal file
533
docs/i18n/主要路由.md
Normal file
@ -0,0 +1,533 @@
|
||||
## 路由摘要
|
||||
|
||||
### 文档定位
|
||||
|
||||
- 本文件是“首页 > 主要路由 > 其他路由”中的主要路由唯一清单
|
||||
- 本文件用于把 `src/permission.js` 中 `store.dispatch('user/getMenus')` 的接口返回结果整理成便于国际化领取、验收和运行检查的父子级路由清单
|
||||
- 需要查看主要路由的中文名、英文名、路由别名、路径、入口文件、完成状态时,统一以本文件为准
|
||||
- 本文件中的菜单层级不默认限制为“父级 > 子级”两层,若实际菜单存在三级结构,则按真实父链整理
|
||||
- 后续所有线程领取新任务前,除了读取 `线程协作.md`、`翻译进度.md`、`翻译清单.md`,还应先读取本文件
|
||||
- 其他文档不再重复维护完整主路由树,最多保留摘要并引用本文件
|
||||
- 下方保留原始接口返回,顶部摘要用于实际执行
|
||||
|
||||
### 全线程统一优先级
|
||||
|
||||
- 适用于所有线程,不只线程三
|
||||
- 统一领取优先级:`已完成 src/views 页面私有组件复查 > 首页 > 本文件中的主要路由页面 > 其他路由页面`
|
||||
- 在“已完成 `src/views` 页面私有组件复查”完成前,暂不继续领取新的未完成普通页面
|
||||
- 只要首页或本文件中的主要路由页面还有未完成项,后续线程都应优先从这两部分中选择
|
||||
- 本文件中的主要路由页面之间,具体先领哪一个页面仍可按原来的方式灵活分配,只要先读 md、先写认领、避免冲突
|
||||
- 只有当首页和本文件中的主要路由页面全部处理完成后,才进入其他路由页面
|
||||
|
||||
### 首页
|
||||
|
||||
- 路由名:`Dashboard`
|
||||
- 路径:`/dashboard`
|
||||
- 路由来源:`src/router/index.js`
|
||||
- 入口文件:`src/views/dashboard/index.vue`
|
||||
- 当前状态:`已完成`
|
||||
|
||||
首页模块建议按同一轮检查的文件范围:
|
||||
|
||||
- `src/views/dashboard/index.vue`
|
||||
- `src/views/dashboard/dashboard.vue`
|
||||
- `src/views/dashboard/dashboard-charts/index.vue`
|
||||
- `src/views/dashboard/quick-link/index.vue`
|
||||
- `src/views/dashboard/introduction/index.vue`
|
||||
- `src/views/dashboard/introduction/user-account-info/index.vue`
|
||||
- `src/views/dashboard/introduction/user-navigation/index.vue`
|
||||
- `src/views/dashboard/introduction/waiting-processing/index.vue`
|
||||
- `src/views/dashboard/components/active-index/index.vue`
|
||||
- `src/views/dashboard/components/daily-currency/index.vue`
|
||||
- `src/views/dashboard/components/daily-currency-gold/index.vue`
|
||||
- `src/views/dashboard/components/daily-purchase/index.vue`
|
||||
- `src/views/dashboard/components/daily-register-user/index.vue`
|
||||
- `src/views/dashboard/components/monthly-purchase/index.vue`
|
||||
- `src/views/dashboard/components/user-daily-currency-gold-top/index.vue`
|
||||
- `src/views/dashboard/components/user-daily-currency-recharge-top/index.vue`
|
||||
|
||||
### 当前与国际化进度直接相关的主要路由
|
||||
|
||||
以下顺序按父级/子级路由整理,方便运行项目时逐项检查。
|
||||
|
||||
### 当前进行中的主要路由
|
||||
|
||||
- 当前无
|
||||
|
||||
### 已完成主要路由总览
|
||||
|
||||
- 用户管理 / User Management
|
||||
- 路由别名:`AppUserManager`
|
||||
- 用户列表 / User List
|
||||
- 路由别名:`AppUserList`
|
||||
- 路径:`user/user-table/index`
|
||||
- 文件:`src/views/user/user-table/index.vue`
|
||||
- 状态:已完成
|
||||
- 运营管理 / Operations Management
|
||||
- 路由别名:`OperationManager`
|
||||
- 数据配置 / Data Configuration
|
||||
- 路由别名:`data:conf`
|
||||
- 转盘抽奖品配置 / Spin Wheel Prize Configuration
|
||||
- 路由别名:`cnf:lottery`
|
||||
- 路径:`cnf/lottery/index`
|
||||
- 文件:`src/views/cnf/lottery/index.vue`
|
||||
- 状态:已完成
|
||||
- 国家管理 / Country Management
|
||||
- 路由别名:`SysCountryCode`
|
||||
- 路径:`sys/country-code/index`
|
||||
- 文件:`src/views/sys/country-code/index.vue`
|
||||
- 状态:已完成
|
||||
- 活动配置 / Activity Configuration
|
||||
- 路由别名:`Activity:Config`
|
||||
- 活动管理 / Activity Management
|
||||
- 路由别名:`Activity:Manager`
|
||||
- 路径:`activity/template-cnf/index`
|
||||
- 文件:`src/views/activity/template-cnf/index.vue`
|
||||
- 状态:已完成
|
||||
- 消息推送 / Message Push (需要重新检查)
|
||||
- 路由别名:`MessageManagerPush`
|
||||
- 路径:`message/push/index`
|
||||
- 已完成文件:
|
||||
- `src/views/message/push/index.vue`
|
||||
- `src/views/message/push/new-push-form.vue`
|
||||
- `src/views/message/push/push-log.vue`
|
||||
- `src/views/message/push/push-task.vue`
|
||||
- 状态:已完成
|
||||
- 运营日志 / Operations Logs
|
||||
- 路由别名:`operation:log`
|
||||
- 砸金蛋记录 / Golden Egg Smash Records
|
||||
- 路由别名:`GameEgg`
|
||||
- 路径:`game/egg/index`
|
||||
- 已完成文件:
|
||||
- `src/views/game/egg/index.vue`
|
||||
- `src/views/game/egg/egg-exchange-record/index.vue`
|
||||
- `src/views/game/egg/egg-lottery-record/index.vue`
|
||||
- `src/views/game/egg/egg-lottery-cnf/index.vue`
|
||||
- 状态:已完成
|
||||
- APP管理员 / App Administrator
|
||||
- 路由别名:`AdministratorTable`
|
||||
- 路径:`user/app-manager/index`
|
||||
- 已完成文件:
|
||||
- `src/views/user/app-manager/index.vue`
|
||||
- `src/views/user/app-manager/administrator/index.vue`
|
||||
- `src/views/user/app-manager/administrator/auth.vue`
|
||||
- `src/views/user/app-manager/administrator-auth-resource/index.vue`
|
||||
- 状态:已完成
|
||||
- App启动页 / App Launch Page
|
||||
- 路由别名:`StartPage`
|
||||
- 路径:`sys/start/page`
|
||||
- 已完成文件:
|
||||
- `src/views/sys/start-page/index.vue`
|
||||
- `src/views/sys/start-page/form-edit.vue`
|
||||
- 状态:已完成
|
||||
- 系统公告管理 / System Notice Management
|
||||
- 路由别名:`NoticeMessage`
|
||||
- 路径:`sys/notice-message/index`
|
||||
- 文件:`src/views/sys/notice-message/index.vue`
|
||||
- 状态:已完成
|
||||
- 语音房间 / Voice Rooms
|
||||
- 路由别名:`VoiceRoom`
|
||||
- 房间资料列表 / Room Profile List
|
||||
- 路由别名:`ProfileRoom`
|
||||
- 路径:`room/profile/index`
|
||||
- 文件:`src/views/room/profile/index.vue`
|
||||
- 状态:已完成
|
||||
- 道具管理 / Prop Management
|
||||
- 路由别名:`PropsManager`
|
||||
- 资源组配置 / Resource Group Configuration
|
||||
- 路由别名:`PropsActivitySourceGroup`
|
||||
- 路径:`props/props-source-group/index`
|
||||
- 已完成文件:
|
||||
- `src/views/props/props-source-group/index.vue`
|
||||
- `src/views/props/props-source-group/form-edit.vue`
|
||||
- 状态:已完成
|
||||
- 系统工具 / System Tools
|
||||
- 路由别名:`ToolsManager`
|
||||
- Redis缓存管理 / Redis Cache Management
|
||||
- 路由别名:`RedisManager`
|
||||
- 路径:`/redis`
|
||||
- 文件:`src/views/tools/redis/index.vue`
|
||||
- 状态:已完成
|
||||
- 文件上传 / File Upload
|
||||
- 路由别名:`upload:file`
|
||||
- 路径:`/upload/file`
|
||||
- 文件:`src/views/tools/upload/index.vue`
|
||||
- 状态:已完成
|
||||
- 主播中心 / Broadcaster Center
|
||||
- 路由别名:`team:manaber`
|
||||
- 代理钻石政策 / Agent Diamond Policy
|
||||
- 路由别名:`TeamDiamondPolicyManager`
|
||||
- 路径:`team/diamond-policy/index`
|
||||
- 文件:`src/views/team/diamond-policy/index.vue`
|
||||
- 状态:已完成
|
||||
- 代理政策 / Agent Policy
|
||||
- 路由别名:`TeamPolicyManager`
|
||||
- 路径:`team/policy/index`
|
||||
- 文件:`src/views/team/policy/index.vue`
|
||||
- 状态:已完成
|
||||
- BD列表 / BD List
|
||||
- 路由别名:`BusinessDevelopment`
|
||||
- 路径:`team/business-development/index`
|
||||
- 文件:`src/views/team/business-development/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`
|
||||
- 状态:已完成
|
||||
|
||||
### 已部分完成但入口页仍需复核的主要路由
|
||||
|
||||
- 当前无
|
||||
|
||||
### 当前建议检查顺序
|
||||
|
||||
1. 先处理“已完成 `src/views` 页面私有组件复查”任务
|
||||
2. 首页 `Dashboard` 模块
|
||||
3. 本文件中“当前进行中的主要路由”:
|
||||
- 当前无
|
||||
4. 本文件中“模块部分完成,入口页仍需复核”的页面:
|
||||
- 当前无
|
||||
5. 本文件之外的其他路由页面
|
||||
|
||||
## 原始接口返回(保留)
|
||||
|
||||
{
|
||||
"time": "1776417483715",
|
||||
"status": true,
|
||||
"errorCode": 0,
|
||||
"body": {
|
||||
"id": "160",
|
||||
"theme": "normal",
|
||||
"recentPreviews": [
|
||||
{
|
||||
"reqTraceId": "GL-99fc25be00b9e5b70891628f3615fe89",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.20.94",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776417455831,
|
||||
"id": "sys:role:list",
|
||||
"type": "SYSTEM",
|
||||
"name": "角色管理",
|
||||
"link": "/system/manager/role",
|
||||
"createTime": 1776417455831
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-4bdfb064bb5ba9936cc50ae6871d8094",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.12.49",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776417451877,
|
||||
"id": "sys:user:list",
|
||||
"type": "SYSTEM",
|
||||
"name": "用户管理",
|
||||
"link": "/system/manager/user",
|
||||
"createTime": 1776417451878
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-5eea9989c975401d54c22eefce0def90",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.20.94",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776333417531,
|
||||
"id": "RegionConfig",
|
||||
"type": "SYSTEM",
|
||||
"name": "区域配置",
|
||||
"link": "/operation/manager/region/config",
|
||||
"createTime": 1776333417531
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-0517a95d554779799e8899bffb75347b",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.20.94",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776332452114,
|
||||
"id": "GameEgg",
|
||||
"type": "SYSTEM",
|
||||
"name": "砸金蛋记录",
|
||||
"link": "/operation/manager/log/running_water/game/egg",
|
||||
"createTime": 1776332452114
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-4c500d97fe3f6aa2e777c170e880bc31",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.12.49",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776313451145,
|
||||
"id": "AppUserList",
|
||||
"type": "SYSTEM",
|
||||
"name": "用户列表",
|
||||
"link": "/app/user/manager/user/table",
|
||||
"createTime": 1776313451145
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-9eff89dc13f92cee8e476013e475b232",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.20.94",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776245058763,
|
||||
"id": "TeamPolicyManager",
|
||||
"type": "SYSTEM",
|
||||
"name": "代理政策",
|
||||
"link": "/team/team-policy",
|
||||
"createTime": 1776245058764
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-dd55810a0797b1bd4288ebc6b7916f75",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.12.49",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776243303511,
|
||||
"id": "team:member",
|
||||
"type": "SYSTEM",
|
||||
"name": "主播成员",
|
||||
"link": "/team/team/member",
|
||||
"createTime": 1776243303511
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-e41e534ef606191c784532ecefa38008",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.12.49",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776243294447,
|
||||
"id": "BusinessDevelopment",
|
||||
"type": "SYSTEM",
|
||||
"name": "BD列表",
|
||||
"link": "/team/business-development",
|
||||
"createTime": 1776243294447
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-bae2f36d15f77bdb3e738dc58e1bc800",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.20.94",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776242391890,
|
||||
"id": "game:config",
|
||||
"type": "SYSTEM",
|
||||
"name": "游戏列表",
|
||||
"link": "/operation/manager/data_cnf/game-config",
|
||||
"createTime": 1776242391890
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-022908aeb3ee33038d10981b0940fc26",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.12.49",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776158503061,
|
||||
"id": "team:bdleader:work",
|
||||
"type": "SYSTEM",
|
||||
"name": "BDLeader工作",
|
||||
"link": "/team/bd-leader-work",
|
||||
"createTime": 1776158503061
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-7759554caea3846c5fca82c1478c28b3",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.12.49",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776074669162,
|
||||
"id": "UserCustomGift",
|
||||
"type": "SYSTEM",
|
||||
"name": "用户专属礼物制作",
|
||||
"link": "/app/user/manager/user_custom_gift",
|
||||
"createTime": 1776074669162
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-9b16acbbd3ad6ac088740c1a30c564d1",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.20.94",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776074206583,
|
||||
"id": "sys:resource:list",
|
||||
"type": "SYSTEM",
|
||||
"name": "资源管理",
|
||||
"link": "/system/manager/resource",
|
||||
"createTime": 1776074206583
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-d5e278dc379b183c02d52378775b1ad8",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.20.94",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776074206154,
|
||||
"id": "sys:menu:list",
|
||||
"type": "SYSTEM",
|
||||
"name": "菜单管理",
|
||||
"link": "/system/manager/menu",
|
||||
"createTime": 1776074206154
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-f010314eafd3755510be60829bd7f5f8",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.20.94",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776070694764,
|
||||
"id": "upload:file",
|
||||
"type": "SYSTEM",
|
||||
"name": "文件上传",
|
||||
"link": "/system/manager/tools/manager/upload/file",
|
||||
"createTime": 1776070694764
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-d305c7808e7665680e6f420c51f85be8",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.20.94",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776070692971,
|
||||
"id": "tools:other",
|
||||
"type": "SYSTEM",
|
||||
"name": "小工具",
|
||||
"link": "/system/manager/tools/manager/tools",
|
||||
"createTime": 1776070692971
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-bfba1c4b6dddf7ca0e8afeb0567be6cb",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.12.49",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776070689919,
|
||||
"id": "toot:gold:analyze",
|
||||
"type": "SYSTEM",
|
||||
"name": "金币分析",
|
||||
"link": "/system/manager/tools/manager/gold-analyze",
|
||||
"createTime": 1776070689919
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-9c6d5a4d2d0e240cdfa4f729d43b9fa8",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.20.94",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776070685881,
|
||||
"id": "OrderCompensate",
|
||||
"type": "SYSTEM",
|
||||
"name": "订单补偿",
|
||||
"link": "/system/manager/tools/manager/order/compensate",
|
||||
"createTime": 1776070685882
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-f579fc5751d9d6867e1a703e7529ce18",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.20.94",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776070684510,
|
||||
"id": "RedisManager",
|
||||
"type": "SYSTEM",
|
||||
"name": "Redis缓存管理",
|
||||
"link": "/system/manager/tools/manager/redis",
|
||||
"createTime": 1776070684511
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-dd1b84facd843153dd62aefea9fc01d4",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.20.94",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776070681380,
|
||||
"id": "request:blacklist",
|
||||
"type": "SYSTEM",
|
||||
"name": "请求黑名单",
|
||||
"link": "/system/manager/app/sys/request-blacklist",
|
||||
"createTime": 1776070681380
|
||||
},
|
||||
{
|
||||
"reqTraceId": "GL-2765d45daac6092185f983e42cc5c156",
|
||||
"reqUserId": "160",
|
||||
"reqLanguage": "en",
|
||||
"reqZoneId": "UTC",
|
||||
"reqIp": "10.0.12.49",
|
||||
"reqClient": "OPS",
|
||||
"reqApi": "/console/dashboard/previews",
|
||||
"reqApiVersion": "v2",
|
||||
"reqTime": 1776070679538,
|
||||
"id": "ExternalIm",
|
||||
"type": "SYSTEM",
|
||||
"name": "IM通讯",
|
||||
"link": "/system/manager/app/sys/external/im",
|
||||
"createTime": 1776070679539
|
||||
}
|
||||
],
|
||||
"customNavigations": []
|
||||
}
|
||||
}
|
||||
1622
docs/i18n/线程协作.md
Normal file
1622
docs/i18n/线程协作.md
Normal file
File diff suppressed because it is too large
Load Diff
78
docs/i18n/线程模板.md
Normal file
78
docs/i18n/线程模板.md
Normal file
@ -0,0 +1,78 @@
|
||||
# 线程模板
|
||||
|
||||
## 使用方式
|
||||
|
||||
- 新开一个并行线程时,把下面内容复制到线程首条消息里,并把“线程名”和“认领文件”替换掉
|
||||
- 新线程开始前,先读取:
|
||||
- `docs/i18n/线程协作.md`
|
||||
- `docs/i18n/翻译进度.md`
|
||||
- `docs/i18n/翻译清单.md`
|
||||
- `docs/i18n/主要路由.md`
|
||||
- 每次准备领取新任务前,也要重新读取以上 3 份协作文档 + `docs/i18n/主要路由.md`,确认其他线程的认领状态已经写入文档,避免重复领取
|
||||
- 每次领取任务时,先更新 md 认领记录,再开始改源码;不要先改代码再补文档
|
||||
- 写入认领记录前和写完后,都要再检查一次以上 3 份协作文档 + `docs/i18n/主要路由.md`,确认没有线程冲突
|
||||
|
||||
## 文档定位
|
||||
|
||||
- 本文件只负责给新线程提供启动清单与首条消息模板
|
||||
- 协作规则本体以 `docs/i18n/线程协作.md` 为准
|
||||
- 主要路由结构与优先核查页面以 `docs/i18n/主要路由.md` 为准
|
||||
- 进度时间线与文件级状态分别以 `docs/i18n/翻译进度.md`、`docs/i18n/翻译清单.md` 为准
|
||||
|
||||
## 启动前补充检查
|
||||
|
||||
- 读取 md 或源码时使用:`Get-Content -Raw -Encoding UTF8 <path>`
|
||||
- 领取任务前先重读 3 份协作文档 + `docs/i18n/主要路由.md`,再决定是否写入新的认领记录
|
||||
- 领取任务的推荐顺序:重读 3 份协作文档 + `docs/i18n/主要路由.md` -> 确认无人认领 -> 先写 md -> 再读同样的文档集合复查 -> 开始改代码
|
||||
- 所有线程统一领取优先级:`首页 > docs/i18n/主要路由.md > 其他路由`
|
||||
- 只要首页或 `docs/i18n/主要路由.md` 中页面仍未完成,就不要跳到其他普通路由
|
||||
- 读取最新语言文件,避免覆盖别人新增的 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 扫描认领页面是否存在同目录私有子组件、抽屉、弹窗表单;如果有,一并检查中文展示文案
|
||||
- 构建验证使用:`npm run build:prod`
|
||||
- 单文件快速扫中文可用:`Select-String -Path <file> -Pattern '[\u4e00-\u9fa5]' -Encoding UTF8`
|
||||
|
||||
## 推荐首条消息模板
|
||||
|
||||
你是国际化翻译协作中的【线程X】。
|
||||
|
||||
请先读取以下文件并基于其内容继续工作:
|
||||
|
||||
- `docs/i18n/线程协作.md`
|
||||
- `docs/i18n/翻译进度.md`
|
||||
- `docs/i18n/翻译清单.md`
|
||||
- `docs/i18n/主要路由.md`
|
||||
|
||||
本线程当前认领文件:
|
||||
|
||||
- `待填写文件路径`
|
||||
|
||||
执行要求:
|
||||
|
||||
- 只翻译展示文本
|
||||
- 不改功能逻辑
|
||||
- 不改接口参数
|
||||
- 不改路由路径
|
||||
- 不改权限码
|
||||
- 不改后端依赖值
|
||||
- 认领优先级遵守:`首页 > docs/i18n/主要路由.md > 其他路由`
|
||||
- 如果文本依赖接口返回且当前无法推断,先跳过,并把阻塞写入 md
|
||||
- 领取任务后,先把认领信息写入 md,确认无冲突后再开始改源码
|
||||
- 完成后同步更新:
|
||||
- `docs/i18n/翻译进度.md`
|
||||
- `docs/i18n/翻译清单.md`
|
||||
|
||||
完成后输出:
|
||||
|
||||
- 已完成文件
|
||||
- 新增语言 key 范围
|
||||
- 未处理阻塞项
|
||||
- 是否已更新 md
|
||||
|
||||
## 已沉淀的复用经验
|
||||
|
||||
- 页面内资源组/奖励配置类抽屉,优先查看是否可复用 `pages.propsSourceGroupForm`
|
||||
- 如果 PowerShell 直接读取出现乱码,优先怀疑读取编码,不要急着判断文件损坏
|
||||
- 如果 `npm run build` 失败,先检查 `package.json`,本项目应改用 `npm run build:prod`
|
||||
- 多线程认领时,写 md 比改源码优先级更高;认领前后都要复查 3 份协作文档 + `docs/i18n/主要路由.md`,确认没有撞任务
|
||||
312
docs/i18n/翻译清单.md
Normal file
312
docs/i18n/翻译清单.md
Normal file
@ -0,0 +1,312 @@
|
||||
# 国际化翻译清单
|
||||
|
||||
## 文档定位
|
||||
|
||||
- 本文件只负责维护文件级待办、进行中、已完成与当前认领状态
|
||||
- 需要看主要路由的完整父子级结构、路由别名、路径和入口文件时,统一查看 `docs/i18n/主要路由.md`
|
||||
- 需要看阶段成果、构建验证与时间线时,统一查看 `docs/i18n/翻译进度.md`
|
||||
- 状态说明:
|
||||
- `已完成`
|
||||
- `进行中`
|
||||
- `待处理`
|
||||
|
||||
## 你的要求
|
||||
|
||||
### 翻译范围
|
||||
|
||||
- 扫描项目中的中文展示文本
|
||||
- 只要不是涉及接口参数的内容,都要做翻译
|
||||
- 路由、导航、页面标题、选项、按钮、表单标签、表格列名、提示文案、空态文案等都属于处理范围
|
||||
|
||||
### 禁止改动项
|
||||
|
||||
- 不要改功能逻辑
|
||||
- 不要改接口参数
|
||||
- 不要改路由路径
|
||||
- 不要改权限码
|
||||
- 不要改接口依赖的状态值、枚举值、提交值
|
||||
- 不要把后端依赖的数据值翻译掉
|
||||
|
||||
### 文档维护要求
|
||||
|
||||
- 进度和清单文档统一放在 `docs/i18n/`
|
||||
- 文档统一使用中文
|
||||
- 后续每一轮翻译都要实时更新这些文档,避免上下文丢失
|
||||
- 每轮源码翻译完成后,至少同步更新以下两份核心文档:
|
||||
- `docs/i18n/翻译进度.md`
|
||||
- `docs/i18n/翻译清单.md`
|
||||
- 协作规则或主路由优先级发生变化时,再同步维护:
|
||||
- `docs/i18n/线程协作.md`
|
||||
- `docs/i18n/主要路由.md`
|
||||
|
||||
### 展示适配要求
|
||||
|
||||
- 英文等较长文案要兼顾展示宽度,不只做字面翻译
|
||||
- 表单标签宽度不足时允许自动换行,必要时补充更宽的公共样式
|
||||
- 表单标签需要保持纵向居中,避免宽度调整后标题贴边
|
||||
- 表格列标题宽度不足时允许自动换行,避免英文单词被截断
|
||||
- 没有设置 `min-width` 的普通表格列,需要补全局默认最小宽度
|
||||
- 个别列仍不足时,再按页面单独调整
|
||||
|
||||
## 领取优先级
|
||||
|
||||
- 适用于所有线程,不只线程三
|
||||
- 统一领取优先级:`已完成 src/views 页面私有组件复查 > 首页 > docs/i18n/主要路由.md > 其他路由`
|
||||
- 在“已完成 `src/views` 页面私有组件复查”完成前,暂不继续领取新的未完成普通页面
|
||||
- 只要首页或 `主要路由.md` 中页面仍未完成,后续线程都应优先从这两部分中选择任务
|
||||
- `主要路由.md` 中具体优先领取哪个页面,仍可按原来的协作方式灵活分配,只要先读 md、先写认领、避免冲突
|
||||
|
||||
## 已完成
|
||||
|
||||
### 已完成主要路由索引
|
||||
|
||||
- 详细父子级结构、路由别名、路径与入口文件统一见 `docs/i18n/主要路由.md`
|
||||
- 以下索引已按 `docs/i18n/主要路由.md` 当前父子级顺序同步更新
|
||||
- 用户管理 / User Management
|
||||
- 用户列表 / User List
|
||||
- 运营管理 / Operations Management
|
||||
- 数据配置 / Data Configuration
|
||||
- 转盘抽奖品配置 / Spin Wheel Prize Configuration
|
||||
- 国家管理 / Country Management
|
||||
- 活动配置 / Activity Configuration
|
||||
- 活动管理 / Activity Management
|
||||
- 消息推送 / Message Push
|
||||
- 运营日志 / Operations Logs
|
||||
- 砸金蛋记录 / Golden Egg Smash Records
|
||||
- APP管理员 / App Administrator
|
||||
- App启动页 / App Launch Page
|
||||
- 系统公告管理 / System Notice Management
|
||||
- 语音房间 / Voice Rooms
|
||||
- 房间资料列表 / Room Profile List
|
||||
- 道具管理 / Prop Management
|
||||
- 资源组配置 / Resource Group Configuration
|
||||
- 系统工具 / System Tools
|
||||
- Redis缓存管理 / Redis Cache Management
|
||||
- 文件上传 / File Upload
|
||||
- 主播中心 / Broadcaster Center
|
||||
- 代理钻石政策 / Agent Diamond Policy
|
||||
- 代理政策 / Agent Policy
|
||||
- BD列表 / BD List
|
||||
- 补充页面
|
||||
- 抽奖概率配置 / Lottery Probability Settings
|
||||
|
||||
### 已完成文件平铺清单
|
||||
|
||||
- `src/views/login/index.vue`
|
||||
- `src/components/Breadcrumb/index.vue`
|
||||
- `src/components/HeaderSearch/index.vue`
|
||||
- `src/components/SizeSelect/index.vue`
|
||||
- `src/components/data/RestPassword/index.vue`
|
||||
- `src/layout/components/NavbarLight.vue`
|
||||
- `src/layout/components/Sidebar/Item.vue`
|
||||
- `src/utils/get-page-title.js`
|
||||
- `src/permission.js`
|
||||
- `src/utils/ops-message.js`
|
||||
- `src/views/dashboard/introduction/waiting-processing/index.vue`
|
||||
- `src/views/dashboard/index.vue`
|
||||
- `src/views/dashboard/dashboard.vue`
|
||||
- `src/views/dashboard/dashboard-charts/index.vue`
|
||||
- `src/views/dashboard/quick-link/index.vue`
|
||||
- `src/views/dashboard/introduction/user-account-info/index.vue`
|
||||
- `src/views/dashboard/introduction/user-navigation/index.vue`
|
||||
- `src/views/dashboard/components/active-index/index.vue`
|
||||
- `src/views/dashboard/components/daily-currency/index.vue`
|
||||
- `src/views/dashboard/components/daily-currency/line-graph-charts.vue`
|
||||
- `src/views/dashboard/components/daily-currency-gold/index.vue`
|
||||
- `src/views/dashboard/components/daily-currency-gold/line-graph-charts.vue`
|
||||
- `src/views/dashboard/components/daily-currency-gold-origin-top/index.vue`
|
||||
- `src/views/dashboard/components/daily-currency-gold-origin-top/bar-graph-charts.vue`
|
||||
- `src/views/dashboard/components/daily-purchase/index.vue`
|
||||
- `src/views/dashboard/components/daily-purchase/line-graph-charts-general.vue`
|
||||
- `src/views/dashboard/components/daily-purchase/line-graph-charts.vue`
|
||||
- `src/views/dashboard/components/daily-register-user/index.vue`
|
||||
- `src/views/dashboard/components/daily-register-user/line-graph-charts.vue`
|
||||
- `src/views/dashboard/components/monthly-purchase/index.vue`
|
||||
- `src/views/dashboard/components/monthly-purchase/line-graph-charts.vue`
|
||||
- `src/views/dashboard/components/user-daily-currency-gold-top/index.vue`
|
||||
- `src/views/dashboard/components/user-daily-currency-gold-top/bar-graph-charts.vue`
|
||||
- `src/views/dashboard/components/user-daily-currency-recharge-top/index.vue`
|
||||
- `src/views/dashboard/components/user-daily-currency-recharge-top/bar-graph-charts.vue`
|
||||
- `src/components/data/PropsSalesOverviewCharts/index.vue`
|
||||
- `src/components/data/PropsSalesOverviewCharts/dialog.vue`
|
||||
- `src/components/data/PropsSalesOverviewCharts/bar-graph-charts.vue`
|
||||
- `src/views/message/push/index.vue`
|
||||
- `src/views/message/push/new-push-form.vue`
|
||||
- `src/views/message/push/push-log.vue`
|
||||
- `src/views/message/push/push-task.vue`
|
||||
- `src/views/user/user-table/index.vue`
|
||||
- `src/components/data/UserInfo/BaseInfo/index.vue`
|
||||
- `src/views/room/profile/index.vue`
|
||||
- `src/views/team/policy/index.vue`
|
||||
- `src/views/props/props-source-group/form-edit.vue`
|
||||
- `src/views/cnf/lottery/index.vue`
|
||||
- `src/views/activity/template-cnf/index.vue`
|
||||
- `src/views/team/business-development/index.vue`
|
||||
- `src/views/team/diamond-policy/index.vue`
|
||||
- `src/components/data/AccountHanle/index.vue`
|
||||
- `src/views/sys/region-config/region/index.vue`
|
||||
- `src/components/data/RoomInfo/index.vue`
|
||||
- `src/components/data/UserAuthForm/index.vue`
|
||||
- `src/components/data/InappPurchaseApple/index.vue`(已核查,无需重复修改)
|
||||
- `src/components/data/InAppPurchaseDetails/index.vue`
|
||||
- `src/components/data/InappPurchaseGoogle/index.vue`
|
||||
- `src/components/data/UserInfo/BankCardDrawer/index.vue`
|
||||
- `src/components/data/UserInfo/BaseInfo/AssociatedDeviceTimeline.vue`
|
||||
- `src/components/data/UserInfo/AccountStatusLatestLog/index.vue`
|
||||
- `src/components/data/UserInfo/UserTableExhibit/index.vue`
|
||||
- `src/components/data/SearchRoomInput/index.vue`
|
||||
- `src/components/data/GiftHistoryDetailsDrawer/index.vue`
|
||||
- `src/components/data/EditUserForm/index.vue`
|
||||
- `src/components/data/EditUserGoldCoinRewardForm/index.vue`
|
||||
- `src/components/data/EditUserDiamondRewardForm/index.vue`
|
||||
- `src/views/game/lucky-box/standard-config/gift-details.vue`
|
||||
- `src/views/game/lucky-box/standard-config/index.vue`
|
||||
- `src/views/game/lucky-box/standard-config/edit.vue`
|
||||
- `src/views/game/lucky-box/standard-config/probability.vue`
|
||||
- `src/views/game/lucky-box/award-config/index.vue`
|
||||
- `src/views/game/lucky-box/award-config/edit.vue`
|
||||
- `src/views/game/lucky-box/award-config/details.vue`
|
||||
- `src/views/game/lucky-box/bounty-config/index.vue`
|
||||
- `src/views/game/lucky-box/bounty-config/edit.vue`
|
||||
- `src/views/game/lucky-box/bounty-config/details.vue`
|
||||
- `src/views/game/lucky-box/fortune-config/index.vue`(已复核完成;目录实际仅存在该文件)
|
||||
- `src/views/game/egg/index.vue`
|
||||
- `src/views/game/egg/egg-exchange-record/index.vue`
|
||||
- `src/views/game/egg/egg-lottery-record/index.vue`
|
||||
- `src/views/game/egg/egg-lottery-cnf/index.vue`
|
||||
- `src/views/game/lottery-config/form-edit.vue`
|
||||
- `src/views/game/lottery-config/select-propsr-popover.vue`
|
||||
- `src/views/game/lottery-config/index.vue`
|
||||
- `src/components/data/AccountInput/index.vue`
|
||||
- `src/components/data/EditUserGameCouponDeductionForm/index.vue`
|
||||
- `src/views/user/freight/index.vue`
|
||||
- `src/views/user/freight/form-edit.vue`
|
||||
- `src/views/user/freight/running-water.vue`
|
||||
- `src/views/user/freight/seller-info.vue`
|
||||
- `src/views/user/freight/freight-seller-running-water.vue`
|
||||
- `src/views/sys/region-config/index.vue`
|
||||
- `src/views/sys/region-config/assist/index.vue`
|
||||
- `src/views/props/props-source-group/index.vue`
|
||||
- `src/views/sys/country-code/index.vue`
|
||||
- `src/views/user/app-manager/index.vue`
|
||||
- `src/views/user/app-manager/administrator/index.vue`
|
||||
- `src/views/user/app-manager/administrator/auth.vue`
|
||||
- `src/views/user/app-manager/administrator-auth-resource/index.vue`
|
||||
- `src/views/sys/notice-message/index.vue`
|
||||
- `src/views/sys/start-page/index.vue`
|
||||
- `src/views/sys/start-page/form-edit.vue`
|
||||
- `src/views/tools/redis/index.vue`
|
||||
- `src/views/tools/upload/index.vue`
|
||||
- 表格展示适配:表头自动换行 + 默认最小宽度补齐
|
||||
- 表格展示适配:表头 `.cell` 高度自适应 + 纵向居中修正
|
||||
- 表单展示适配:标题纵向居中
|
||||
|
||||
## 进行中
|
||||
|
||||
- 临时任务:已完成 `src/views` 页面私有组件复查
|
||||
- 状态:进行中
|
||||
- 范围说明:
|
||||
- 只检查 `src/views/**` 下已经标记“已完成”的页面目录
|
||||
- 只复查页面私有组件,不包含公共组件目录 `src/components/**`
|
||||
- 后续页面完成记录需要额外写明“私有组件状态”
|
||||
- 当前优先复核目录:
|
||||
- `src/views/team/policy`
|
||||
- `src/views/team/diamond-policy`
|
||||
- `src/views/team/business-development`
|
||||
- `src/views/room/profile`
|
||||
- `src/views/activity/template-cnf`
|
||||
- `src/views/cnf/lottery`
|
||||
- 当前已发现但尚未补齐到已完成记录的私有组件:
|
||||
- `src/views/team/policy/props-form-edit.vue`
|
||||
- `src/views/team/diamond-policy/props-form-edit.vue`
|
||||
- `src/views/team/business-development/add-bd.vue`
|
||||
- `src/views/team/business-development/auth.vue`
|
||||
- `src/views/team/business-development/bind-bd-leader.vue`
|
||||
- `src/views/team/business-development/bind-team.vue`
|
||||
- `src/views/team/business-development/team-member.vue`
|
||||
- `src/views/room/profile/room-active-charts.vue`
|
||||
- `src/views/room/profile/room-operation-log.vue`
|
||||
- `src/views/room/profile/room-visitor-log.vue`
|
||||
- `src/views/room/profile/user-drawer.vue`
|
||||
- `src/views/activity/template-cnf/activity-rank.vue`
|
||||
- `src/views/activity/template-cnf/activity-rank-reward.vue`
|
||||
- `src/views/activity/template-cnf/form-edit.vue`
|
||||
- `src/views/activity/template-cnf/reward-edit.vue`
|
||||
- `src/views/activity/template-cnf/template-editor/attr-editor.vue`
|
||||
- `src/views/activity/template-cnf/template-editor/index.vue`
|
||||
- `src/views/activity/template-cnf/template-editor/lang-text-editor.vue`
|
||||
- `src/views/activity/template-cnf/template-editor/page-editor.vue`
|
||||
- `src/views/activity/template-cnf/template-editor/props-card.vue`
|
||||
- `src/views/activity/template-cnf/template-editor/reward-array-editor.vue`
|
||||
- `src/views/activity/template-cnf/template-form/index.vue`
|
||||
- `src/views/cnf/lottery/select-prize.vue`
|
||||
- 当前明确排除:
|
||||
- `src/views/message/push/push-text-store.vue`
|
||||
- 原因:当前未纳入入口渲染链,继续按既有排除项处理
|
||||
- `src/views/props/props-source-group/select-propsr-popover.vue`
|
||||
- 原因:当前未被入口页或 `form-edit.vue` 引用,继续按既有排除项处理
|
||||
|
||||
## 优先待处理
|
||||
|
||||
- 已完成 `src/views` 页面目录中的私有组件复查任务
|
||||
- 主要路由中已部分完成、但仍需继续收口的入口页
|
||||
- 主要路由中的其他页面
|
||||
- 统一参考 `docs/i18n/主要路由.md`
|
||||
- 当首页与本文件中的“优先待处理”完成后,再继续处理 `主要路由.md` 中剩余未完成页面
|
||||
|
||||
## 第一批高优先级页面
|
||||
|
||||
- `src/views/user/user-table/index.vue`:已完成
|
||||
- `src/views/room/profile/index.vue`:已完成
|
||||
- `src/views/team/policy/index.vue`:已完成
|
||||
- `src/views/message/push/index.vue`:已完成(线程二;同步收口 `new-push-form.vue`、`push-log.vue` 与 `push-task.vue`)
|
||||
- `src/views/message/push/push-task.vue`:已完成
|
||||
- `src/components/data/UserInfo/BaseInfo/index.vue`:已完成
|
||||
|
||||
## 第二批高优先级页面
|
||||
|
||||
- `src/views/props/props-source-group/form-edit.vue`:已完成静态文案,接口返回名称待补数据
|
||||
- `src/views/cnf/lottery/index.vue`:已完成
|
||||
- `src/views/activity/template-cnf/index.vue`:已完成
|
||||
- `src/views/team/business-development/index.vue`:已完成
|
||||
- `src/views/sys/region-config/region/index.vue`:已完成(线程一)
|
||||
- `src/views/team/diamond-policy/index.vue`:已完成(线程二)
|
||||
- `src/views/game/lottery-config/form-edit.vue`:已完成(线程二)
|
||||
- `src/views/game/lottery-config/index.vue`:已完成(线程二)
|
||||
|
||||
## 高优先级组件
|
||||
|
||||
- `src/components/data/AccountHanle/index.vue`:已完成(线程二)
|
||||
- `src/components/data/InappPurchaseApple/index.vue`:已核查完成(线程一)
|
||||
- `src/components/data/InAppPurchaseDetails/index.vue`:已完成(线程二)
|
||||
- `src/components/data/InappPurchaseGoogle/index.vue`:已完成(线程一)
|
||||
- `src/components/data/RoomInfo/index.vue`:已完成(线程三)
|
||||
- `src/components/data/UserInfo/BankCardDrawer/index.vue`:已完成(线程三)
|
||||
- `src/components/data/UserAuthForm/index.vue`:已完成(线程三)
|
||||
- `src/components/data/UserInfo/AccountStatusLatestLog/index.vue`:已完成(线程二)
|
||||
|
||||
## 本轮保留项
|
||||
- `src/components/data/AccountHanle/index.vue`
|
||||
- 默认“警告”描述文案保留中文
|
||||
- 原因:该内容会直接写入提交表单并发给后端,不按纯展示文案处理
|
||||
- `src/components/data/RoomInfo/index.vue`
|
||||
- 注释掉的“装饰道具”代码块仍保留中文
|
||||
- 原因:当前不渲染,不属于可见展示文案;领取任务前已按新规则重读 3 份协作文档 + `docs/i18n/主要路由.md` 后再认领
|
||||
- `src/views/props/props-source-group/select-propsr-popover.vue`
|
||||
- 当前保留原样
|
||||
- 原因:已核对 `src/views/props/props-source-group/index.vue` 的入口 import 列表与模块目录文件列表;该文件当前未被入口页或 `form-edit.vue` 引用,不属于本轮入口渲染链
|
||||
- `src/views/props/props-source-group/form-edit.vue`
|
||||
- 仍保留接口返回名称类文本与注释类中文
|
||||
- 原因:接口返回的 `badgeName`、`pItem.name`、资源名称等需依赖样例数据判断是否可安全翻译;注释不属于可见展示文案
|
||||
- `src/views/user/app-manager/**/*.vue`
|
||||
- 当前保留注释“去除校验”和注释掉的“管理房间”代码块原样
|
||||
- 原因:均不属于可见展示文案;接口返回的 `resourceName` 等后端资源名称保持原样,不做翻译
|
||||
- `src/views/sys/notice-message/index.vue`
|
||||
- 当前保留字段行尾注释与“删除”注释原样
|
||||
- 原因:均不属于可见展示文案;`permissionsSysOriginPlatforms` 的 `item.label` 作为公共系统来源数据,本轮未改其值
|
||||
|
||||
## 需持续关注
|
||||
|
||||
- 历史语言文件中的旧键名和新语义键并存
|
||||
- 页面中文较多的文件需要分批推进,避免一次性改动过大
|
||||
- 优先处理高频页面、公共组件、用户详情类抽屉和配置类页面
|
||||
837
docs/i18n/翻译进度.md
Normal file
837
docs/i18n/翻译进度.md
Normal file
@ -0,0 +1,837 @@
|
||||
# 国际化翻译进度
|
||||
|
||||
## 文档定位
|
||||
|
||||
- 本文件只负责记录全局进展、阶段成果、构建验证结果与下一步目标
|
||||
- 主要路由的完整父子级结构、路由别名、路径、入口文件与主路由优先级,以 `docs/i18n/主要路由.md` 为准
|
||||
- 文件级待办、进行中、已完成与认领状态,以 `docs/i18n/翻译清单.md` 为准
|
||||
- 协作规则、读 md 顺序、认领要求与交接规范,以 `docs/i18n/线程协作.md` 为准
|
||||
|
||||
## 当前目标
|
||||
|
||||
- 将项目页面中出现的中文展示文本逐步接入国际化
|
||||
- 当前先支持 `en` 和 `zh`
|
||||
- 后续如果增加 `bn`、`ar`、`tr` 等语言,优先复用现有键名体系
|
||||
|
||||
## 任务优先级
|
||||
|
||||
- 全线程统一优先级:`已完成 src/views 页面私有组件复查 > 首页 > docs/i18n/主要路由.md > 其他路由`
|
||||
- 在“已完成 `src/views` 页面私有组件复查”完成前,暂不继续领取新的未完成普通页面
|
||||
- 只要首页 `Dashboard` 模块或 `主要路由.md` 中页面仍未完成,后续线程领取新任务时都应优先从这两部分中选择
|
||||
- `主要路由.md` 中具体先领哪个页面仍可灵活分配,但不得跳过首页整体优先级
|
||||
|
||||
## 必须遵守的约束
|
||||
|
||||
- 只翻译展示文本
|
||||
- 不修改功能逻辑
|
||||
- 不修改接口参数
|
||||
- 不修改路由路径
|
||||
- 不修改权限码
|
||||
- 不修改后端依赖的枚举值、状态值、别名值、提交值
|
||||
- 凡是会传给接口、或依赖后端匹配的值,一律保持原样
|
||||
- 已经本来就是英文的展示文本,不强制改动
|
||||
|
||||
## 展示适配要求
|
||||
|
||||
- 英文等较长展示文案需要考虑布局适配
|
||||
- 表单标签在宽度不足时允许自动换行,并可按页面需要补充更宽的标签样式
|
||||
- 表格列表列标题在宽度不足时允许自动换行,不再截断单词
|
||||
- 对未设置 `min-width` 的普通表格列补全局默认最小宽度,先保证大部分标题至少能展示完整单词
|
||||
- 个别仍然宽度不足的列,后续再按页面逐项微调
|
||||
|
||||
## 已完成
|
||||
|
||||
### 主要路由完成摘要
|
||||
|
||||
- 详细父子级结构、路由别名、路径与验收入口统一见 `docs/i18n/主要路由.md`
|
||||
- 以下摘要已按 `docs/i18n/主要路由.md` 当前父子级顺序同步更新
|
||||
- 已完成主路由摘要:
|
||||
- 用户管理 / User Management
|
||||
- 用户列表 / User List
|
||||
- 运营管理 / Operations Management
|
||||
- 数据配置 / Data Configuration
|
||||
- 转盘抽奖品配置 / Spin Wheel Prize Configuration
|
||||
- 国家管理 / Country Management
|
||||
- 活动配置 / Activity Configuration
|
||||
- 活动管理 / Activity Management
|
||||
- 消息推送 / Message Push
|
||||
- 运营日志 / Operations Logs
|
||||
- 砸金蛋记录 / Golden Egg Smash Records
|
||||
- APP管理员 / App Administrator
|
||||
- App启动页 / App Launch Page
|
||||
- 系统公告管理 / System Notice Management
|
||||
- 语音房间 / Voice Rooms
|
||||
- 房间资料列表 / Room Profile List
|
||||
- 道具管理 / Prop Management
|
||||
- 资源组配置 / Resource Group Configuration
|
||||
- 系统工具 / System Tools
|
||||
- Redis缓存管理 / Redis Cache Management
|
||||
- 文件上传 / File Upload
|
||||
- 主播中心 / Broadcaster Center
|
||||
- 代理钻石政策 / Agent Diamond Policy
|
||||
- 代理政策 / Agent Policy
|
||||
- BD列表 / BD List
|
||||
- 已完成但未在当前主要路由菜单返回中命中的补充页面:
|
||||
- 抽奖概率配置 / Lottery Probability Settings
|
||||
### 基础能力
|
||||
|
||||
- 已接入项目国际化基础能力
|
||||
- 已使用 Vuex 存储当前语言
|
||||
- 已接入 Element UI 语言包切换
|
||||
- 已支持基于时区的默认语言识别
|
||||
- 未匹配到现有语言类型时,默认回退到英文
|
||||
|
||||
### 导航与通用区域
|
||||
|
||||
- 已增加导航栏语言切换入口
|
||||
- 已增加头像下拉中的语言切换入口
|
||||
- 已支持侧边栏路由标题翻译
|
||||
- 已调整侧边栏宽度、自动换行和图标居中表现
|
||||
|
||||
### 其他已处理内容
|
||||
|
||||
- 已移除 `src/views/dashboard/introduction/waiting-processing/index.vue` 中“每日一文”相关展示数据
|
||||
- 已保留系统时间展示
|
||||
- 已将默认语言检测与浏览器时区关联
|
||||
- 已将语言切换结果持久化
|
||||
- 刷新后优先使用用户上次选择的语言
|
||||
- 只有首次没有持久化记录时,才使用默认语言判断逻辑
|
||||
|
||||
## 本轮新增进展
|
||||
|
||||
### 2026-04-20
|
||||
|
||||
- 已完成页面:
|
||||
- `src/views/tools/upload/index.vue`
|
||||
- 说明:已完成上传方式开关、拖拽上传提示、失败状态与超限提示国际化;接口参数、文件上传逻辑、路由路径与后端依赖值保持原样
|
||||
- 页面私有组件状态:
|
||||
- `src/views/tools/upload/index.vue`:无私有组件,已完成
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.uploadFile`
|
||||
- 已完成模块级复核:
|
||||
- `src/views/tools/upload/index.vue`
|
||||
- 说明:已执行中文残留扫描;当前未发现剩余中文可见文本
|
||||
- 已完成构建验证:
|
||||
- 直接执行 `npm run build:prod` 构建通过
|
||||
- 说明:当前仍保留项目原有 `22` 条 warning,未因本轮 `tools/upload` 国际化改动新增阻塞错误
|
||||
- 已完成页面:
|
||||
- `src/views/sys/start-page/index.vue`
|
||||
- 说明:已完成筛选区 placeholder、状态下拉、活动类型展示映射、表格列头、按钮、删除确认与成功提示国际化;接口参数、状态值、路由路径与系统来源数据保持原样
|
||||
- 已处理页面私有子组件:
|
||||
- `src/views/sys/start-page/form-edit.vue`
|
||||
- 说明:已完成弹窗标题、表单标签、placeholder、保存/取消按钮、必填校验提示与活动类型展示映射国际化;提交字段、上传逻辑与接口调用保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.startPage`
|
||||
- 已完成模块级复核:
|
||||
- `src/views/sys/start-page/**/*.vue`
|
||||
- 说明:已执行递归中文残留扫描;当前残余中文仅保留在模板注释与“删除”代码注释中
|
||||
- 已完成构建验证:
|
||||
- 直接执行 `npm run build:prod` 构建通过
|
||||
- 说明:当前仍保留项目原有 `22` 条 warning,未因本轮 `sys/start-page` 国际化改动新增阻塞错误
|
||||
- 已完成页面:
|
||||
- `src/views/tools/redis/index.vue`
|
||||
- 说明:已完成入口快捷标签、空态文案、打卡缓存查询弹窗标题/按钮/校验提示国际化;接口方法名、缓存查询 key、路由路径与返回数据结构保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.redisTools`
|
||||
- 已完成模块级复核:
|
||||
- `src/views/tools/redis/index.vue`
|
||||
- 说明:已执行中文残留扫描;当前未发现剩余中文可见文本
|
||||
- 已完成构建验证:
|
||||
- 首次直接执行 `npm run build:prod` 触发 `ERR_OSSL_EVP_UNSUPPORTED`
|
||||
- 改用 `$env:NODE_OPTIONS='--openssl-legacy-provider'; npm run build:prod` 后构建通过
|
||||
- 说明:当前仍保留项目原有 `22` 条 warning,未因本轮 `tools/redis` 国际化改动新增阻塞错误
|
||||
- 已完成页面:
|
||||
- `src/views/sys/notice-message/index.vue`
|
||||
- 说明:已完成筛选区、表格列头、类型文案、按钮、发布/上架确认提示、成功提示、弹窗标题、表单标签、placeholder 与校验提示国际化;接口参数、状态值、类型值、路由路径与公共系统来源数据保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.noticeMessage`
|
||||
- 已完成模块级复核:
|
||||
- `src/views/sys/notice-message/**/*.vue`
|
||||
- 说明:已执行递归中文残留扫描;当前残余中文仅保留在字段行尾注释与“删除”注释中
|
||||
- 已完成构建验证:
|
||||
- 首次直接执行 `npm run build:prod` 触发 `ERR_OSSL_EVP_UNSUPPORTED`
|
||||
- 改用 `$env:NODE_OPTIONS='--openssl-legacy-provider'; npm run build:prod` 后构建通过
|
||||
- 说明:当前仍保留项目原有 `22` 条 warning,未因本轮 `sys/notice-message` 国际化改动新增阻塞错误
|
||||
- 已完成页面:
|
||||
- `src/views/user/app-manager/index.vue`
|
||||
- 说明:已完成入口页 tab 标题国际化,并按模块级检查方案一并收口两个可见子页与权限设置弹窗;接口参数、角色值、分组值、路由路径与后端资源名称保持原样
|
||||
- 已处理页面私有子组件:
|
||||
- `src/views/user/app-manager/administrator/index.vue`
|
||||
- `src/views/user/app-manager/administrator/auth.vue`
|
||||
- `src/views/user/app-manager/administrator-auth-resource/index.vue`
|
||||
- 说明:已完成筛选区、表格列头、状态文案、按钮、弹窗标题、表单标签、确认提示、校验提示与本地角色/分组映射国际化;接口返回的 `resourceName` 等后端数据未做翻译
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.appManager`
|
||||
- 已完成模块级复核:
|
||||
- `src/views/user/app-manager/**/*.vue`
|
||||
- 说明:已执行递归中文残留扫描;当前残余中文仅保留在注释“去除校验”与注释掉的“管理房间”代码块中
|
||||
- 已完成构建验证:
|
||||
- 首次直接执行 `npm run build:prod` 触发 `ERR_OSSL_EVP_UNSUPPORTED`
|
||||
- 改用 `$env:NODE_OPTIONS='--openssl-legacy-provider'; npm run build:prod` 后构建通过
|
||||
- 说明:当前仍保留项目原有 `22` 条 warning,未因本轮 `user/app-manager` 国际化改动新增阻塞错误
|
||||
- 已完成页面:
|
||||
- `src/views/sys/country-code/index.vue`
|
||||
- 说明:已完成筛选区 placeholder、表格列头、状态文案、弹窗标题、表单标签、按钮、上传按钮与校验提示国际化;接口参数、提交字段、路由路径与后端依赖值保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.countryCode`
|
||||
- 已完成模块级复核:
|
||||
- `src/views/sys/country-code/index.vue`
|
||||
- 说明:已执行中文残留扫描;当前残余中文仅保留在注释中
|
||||
- 已完成构建验证:
|
||||
- 直接使用 `$env:NODE_OPTIONS='--openssl-legacy-provider'; npm run build:prod` 构建通过
|
||||
- 说明:当前仍保留项目原有 `22` 条 warning,包含项目既有 `getAddressUrl` 导出缺失 warning,未因本轮 `sys/country-code` 国际化改动新增阻塞性错误
|
||||
- 已完成页面:
|
||||
- `src/views/props/props-source-group/index.vue`
|
||||
- 说明:已完成入口页筛选区 placeholder、搜索与添加按钮、表格列头、时间展示、编辑按钮与 loading 文案国际化;接口查询参数、分页结构、上下架开关值与弹窗逻辑保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.propsSourceGroup`
|
||||
- 复用范围:`common.search`、`pages.propsSourceGroupForm`
|
||||
- 已完成模块级复核:
|
||||
- `src/views/props/props-source-group/index.vue`
|
||||
- `src/views/props/props-source-group/form-edit.vue`
|
||||
- 说明:已对 `src/views/props/props-source-group/**/*.vue` 执行递归中文扫描;当前 `index.vue` 残余中文仅在注释中,`form-edit.vue` 残余主要为注释与接口返回名称类文本,`select-propsr-popover.vue` 当前未接入入口渲染链
|
||||
- 已完成构建验证:
|
||||
- 首次直接执行 `npm run build:prod` 触发 `ERR_OSSL_EVP_UNSUPPORTED`
|
||||
- 改用 `$env:NODE_OPTIONS='--openssl-legacy-provider'; npm run build:prod` 后构建通过
|
||||
- 说明:当前仍保留项目原有 `22` 条 warning,未因本轮 `props-source-group/index.vue` 国际化改动新增阻塞错误
|
||||
- 已新增临时任务规则:
|
||||
- 暂停继续领取新的未完成普通页面
|
||||
- 先检查 `src/views` 下所有已标记完成页面的私有组件是否已完成国际化
|
||||
- 后续页面完成记录必须额外写明“页面私有组件状态”
|
||||
- 已形成首批历史页面私有组件复核队列:
|
||||
- `src/views/team/policy/props-form-edit.vue`
|
||||
- `src/views/team/diamond-policy/props-form-edit.vue`
|
||||
- `src/views/team/business-development/add-bd.vue`
|
||||
- `src/views/team/business-development/auth.vue`
|
||||
- `src/views/team/business-development/bind-bd-leader.vue`
|
||||
- `src/views/team/business-development/bind-team.vue`
|
||||
- `src/views/team/business-development/team-member.vue`
|
||||
- `src/views/room/profile/room-active-charts.vue`
|
||||
- `src/views/room/profile/room-operation-log.vue`
|
||||
- `src/views/room/profile/room-visitor-log.vue`
|
||||
- `src/views/room/profile/user-drawer.vue`
|
||||
- `src/views/activity/template-cnf/activity-rank.vue`
|
||||
- `src/views/activity/template-cnf/activity-rank-reward.vue`
|
||||
- `src/views/activity/template-cnf/form-edit.vue`
|
||||
- `src/views/activity/template-cnf/reward-edit.vue`
|
||||
- `src/views/activity/template-cnf/template-editor/attr-editor.vue`
|
||||
- `src/views/activity/template-cnf/template-editor/index.vue`
|
||||
- `src/views/activity/template-cnf/template-editor/lang-text-editor.vue`
|
||||
- `src/views/activity/template-cnf/template-editor/page-editor.vue`
|
||||
- `src/views/activity/template-cnf/template-editor/props-card.vue`
|
||||
- `src/views/activity/template-cnf/template-editor/reward-array-editor.vue`
|
||||
- `src/views/activity/template-cnf/template-form/index.vue`
|
||||
- `src/views/cnf/lottery/select-prize.vue`
|
||||
|
||||
### 2026-04-17
|
||||
|
||||
- 已完成首页模块:
|
||||
- `src/views/dashboard/index.vue`
|
||||
- `src/views/dashboard/dashboard.vue`
|
||||
- `src/views/dashboard/dashboard-charts/index.vue`
|
||||
- `src/views/dashboard/quick-link/index.vue`
|
||||
- `src/views/dashboard/introduction/user-account-info/index.vue`
|
||||
- `src/views/dashboard/introduction/user-navigation/index.vue`
|
||||
- `src/views/dashboard/introduction/waiting-processing/index.vue`
|
||||
- `src/views/dashboard/components/active-index/index.vue`
|
||||
- `src/views/dashboard/components/daily-currency/index.vue`
|
||||
- `src/views/dashboard/components/daily-currency/line-graph-charts.vue`
|
||||
- `src/views/dashboard/components/daily-currency-gold/index.vue`
|
||||
- `src/views/dashboard/components/daily-currency-gold/line-graph-charts.vue`
|
||||
- `src/views/dashboard/components/daily-currency-gold-origin-top/index.vue`
|
||||
- `src/views/dashboard/components/daily-currency-gold-origin-top/bar-graph-charts.vue`
|
||||
- `src/views/dashboard/components/daily-purchase/index.vue`
|
||||
- `src/views/dashboard/components/daily-purchase/line-graph-charts-general.vue`
|
||||
- `src/views/dashboard/components/daily-purchase/line-graph-charts.vue`
|
||||
- `src/views/dashboard/components/daily-register-user/index.vue`
|
||||
- `src/views/dashboard/components/daily-register-user/line-graph-charts.vue`
|
||||
- `src/views/dashboard/components/monthly-purchase/index.vue`
|
||||
- `src/views/dashboard/components/monthly-purchase/line-graph-charts.vue`
|
||||
- `src/views/dashboard/components/user-daily-currency-gold-top/index.vue`
|
||||
- `src/views/dashboard/components/user-daily-currency-gold-top/bar-graph-charts.vue`
|
||||
- `src/views/dashboard/components/user-daily-currency-recharge-top/index.vue`
|
||||
- `src/views/dashboard/components/user-daily-currency-recharge-top/bar-graph-charts.vue`
|
||||
- `src/components/data/PropsSalesOverviewCharts/index.vue`
|
||||
- `src/components/data/PropsSalesOverviewCharts/dialog.vue`
|
||||
- `src/components/data/PropsSalesOverviewCharts/bar-graph-charts.vue`
|
||||
- 说明:已完成首页入口、概览卡片、图表 tab、图表 legend/tooltip、快捷入口与首页直接依赖销售总览组件的国际化收口,并补齐运行时语言切换所需的首页响应式联动
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.dashboard`
|
||||
- 已完成模块级复核:
|
||||
- `src/views/dashboard/**/*`
|
||||
- `src/components/data/PropsSalesOverviewCharts/**/*`
|
||||
- 说明:模块内静态中文展示文案残留扫描结果为 0
|
||||
- 已完成构建验证:
|
||||
- `npm run build:prod`
|
||||
- 说明:本轮首页 i18n 改动编译通过,仍保留项目既有 `22` 条 warning,未新增阻塞错误
|
||||
- 已完成页面:
|
||||
- `src/views/message/push/index.vue`
|
||||
- `src/views/message/push/new-push-form.vue`
|
||||
- `src/views/message/push/push-log.vue`
|
||||
- `src/views/message/push/push-task.vue`
|
||||
- 说明:已完成消息推送入口页 tab、新建 Push 表单与 Push 日志页的可见静态文案国际化,并补齐 `push-task.vue` 中遗留成功提示;未改动接口参数、路由路径、权限码与后端依赖值
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.messagePush`、`pages.messagePushLog`
|
||||
- 扩展范围:`pages.messagePushTask`
|
||||
- 已完成模块级复核:
|
||||
- `src/views/message/push/index.vue`
|
||||
- `src/views/message/push/new-push-form.vue`
|
||||
- `src/views/message/push/push-log.vue`
|
||||
- `src/views/message/push/push-task.vue`
|
||||
- 说明:已执行中文残留扫描,当前残余中文仅保留在注释中;`push-text-store.vue` 仍未被入口页渲染,已在协作文档中标记为排除项
|
||||
- 已完成构建验证:
|
||||
- `npm run build:prod`
|
||||
- 说明:构建通过,当前仍保留项目原有 `22` 条 warning,未因本轮 `message/push` i18n 改动新增阻塞性错误
|
||||
- 已完成页面:
|
||||
- `src/views/user/freight/index.vue`
|
||||
- `src/views/user/freight/form-edit.vue`
|
||||
- `src/views/user/freight/running-water.vue`
|
||||
- `src/views/user/freight/seller-info.vue`
|
||||
- `src/views/user/freight/freight-seller-running-water.vue`
|
||||
- 说明:已完成用户货运模块列表页、编辑页、流水页与卖家相关弹窗中的静态展示文案国际化;仅对展示层做本地化映射,未改动后端依赖提交值、接口参数、路由路径与业务逻辑
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.userFreight`
|
||||
- 已完成模块级复核:
|
||||
- `src/views/user/freight/**/*.vue`
|
||||
- 说明:已执行递归中文扫描;当前残余中文仅保留在注释、后端依赖提交值或当前非可见数据结构中
|
||||
- 已完成构建验证:
|
||||
- `npm run build:prod`
|
||||
- 说明:构建通过,当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已完成页面:
|
||||
- `src/views/sys/region-config/index.vue`
|
||||
- `src/views/sys/region-config/assist/index.vue`
|
||||
- 说明:已完成区域配置入口页 tab 标题与辅助配置页可见静态文案国际化;`region/index.vue` 沿用既有国际化结果,本轮完成入口联动收口;未改动接口参数、路由路径、权限码与后端依赖值
|
||||
- 已扩展页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 扩展范围:`pages.regionConfig.tabs`、`pages.regionConfig.assist`
|
||||
- 已完成模块级复核:
|
||||
- `src/views/sys/region-config/index.vue`
|
||||
- `src/views/sys/region-config/assist/index.vue`
|
||||
- 说明:已执行中文残留扫描;当前残余中文仅保留在注释中
|
||||
- 已完成构建验证:
|
||||
- `npm run build:prod`
|
||||
- 说明:构建通过,当前仍保留项目原有 `22` 条 warning,未因本轮 `sys/region-config` i18n 改动新增阻塞性错误
|
||||
- 已处理组件:
|
||||
- `src/components/data/EditUserDiamondRewardForm/index.vue`
|
||||
- 说明:已完成钻石奖励弹窗标题、字段标签、placeholder、按钮与校验提示国际化;`userId`、`quantity`、`remarks` 提交字段与接口调用保持原样,表单标签“钻石”复用 `pages.propsSourceGroupForm.resourceType.diamond`
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.editUserDiamondRewardForm`
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/EditUserDiamondRewardForm/index.vue` 国际化改动编译通过
|
||||
- 2026-04-17 当前环境直接执行 `npm run build:prod` 已通过,当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已处理组件:
|
||||
- `src/components/data/EditUserGameCouponDeductionForm/index.vue`
|
||||
- 说明:已完成扣除用户游戏券弹窗标题、表单标签、placeholder、按钮与校验提示国际化;接口参数、提交数量与备注内容保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.editUserGameCouponDeductionForm`
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/EditUserGameCouponDeductionForm/index.vue` 国际化改动编译通过
|
||||
- 2026-04-17 当前环境直接执行 `npm run build:prod` 已通过,当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已沉淀线程经验到文档:
|
||||
- 2026-04-17 当前 Node 环境下,`$env:NODE_OPTIONS='--openssl-legacy-provider'` 会直接报 `--openssl-legacy-provider is not allowed in NODE_OPTIONS`
|
||||
- 后续构建验证优先直接执行 `npm run build:prod`
|
||||
|
||||
### 2026-04-16
|
||||
|
||||
- 已补领页面:
|
||||
- `src/views/game/egg/egg-lottery-cnf/index.vue`
|
||||
- 说明:线程一已按最新协作规则重新读取 3 份 md 与语言文件,并已把此前遗漏的 Egg 配置页正式登记为本轮进行中任务;后续将只处理可见静态展示文本,不改接口参数与页面逻辑
|
||||
- 已完成页面:
|
||||
- `src/views/game/egg/index.vue`
|
||||
- `src/views/game/egg/egg-exchange-record/index.vue`
|
||||
- `src/views/game/egg/egg-lottery-record/index.vue`
|
||||
- `src/views/game/egg/egg-lottery-cnf/index.vue`
|
||||
- 说明:线程一已完成 Egg 模块入口页、兑换记录页、抽奖记录页与配置页的静态展示文本国际化收口;配置页补充了筛选区、按钮、表格列头、占位文案、奖品类型下拉、校验提示与确认弹窗翻译,并新增 `pages.eggLotteryCnf`
|
||||
- 已完成模块级复核:
|
||||
- `src/views/game/egg/**/*.vue`
|
||||
- 说明:已按“模块级最优检查方案”对 Egg 模块做递归中文扫描,当前未发现剩余中文可见文本
|
||||
- 已完成构建验证:
|
||||
- `npm run build:prod`
|
||||
- 说明:本轮直接执行构建已通过,仍保留项目既有 `22` 条 warning,未新增阻塞错误
|
||||
- 发现检查缺口:
|
||||
- `src/views/game/egg/egg-lottery-cnf/index.vue`
|
||||
- 说明:该文件与 `src/views/game/egg/index.vue` 同属一个可见 tab 模块,上一轮线程一虽然在认领记录中写了“暂未纳入本次范围”,但没有把它同步登记为“可见但待处理文件”,也没有按模块目录做完整核对;这说明此前的目录级检查还不够严谨
|
||||
- 已补充协作规范:
|
||||
- `docs/i18n/线程协作.md`
|
||||
- 新增“模块级最优检查方案”
|
||||
- 目的:后续认领 `views` 模块时,先核对入口页 import、tab、动态组件与模块目录文件列表,避免再次漏掉像 `egg-lottery-cnf/index.vue` 这样的同级可见页面
|
||||
- 已完成页面:
|
||||
- `src/views/game/lucky-box/fortune-config/index.vue`
|
||||
- 说明:已完成 `fortune-config` 页面静态展示文本国际化复核;本轮确认目录实际仅存在 `index.vue`,协作文档里提到的 `edit.vue`、`details.vue` 并不存在,无需继续查找或翻译
|
||||
- 已复核页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 复核范围:`pages.luckyBoxFortuneConfig`
|
||||
- 说明:中英文语言项已齐备,`index.vue` 中无剩余中文展示文本
|
||||
- 已完成构建验证:
|
||||
- 首次直接执行 `npm run build:prod` 因当前 Node/OpenSSL 组合触发 `ERR_OSSL_EVP_UNSUPPORTED`
|
||||
- 改用 `$env:NODE_OPTIONS='--openssl-legacy-provider'; npm run build:prod` 后构建通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 fortune-config 收口新增阻塞错误
|
||||
- 已同步修正文档:
|
||||
- `docs/i18n/线程协作.md`
|
||||
- `docs/i18n/翻译清单.md`
|
||||
- `docs/i18n/翻译进度.md`
|
||||
- 说明:已移除对不存在的 `src/views/game/lucky-box/fortune-config/edit.vue`、`src/views/game/lucky-box/fortune-config/details.vue` 的错误引用,避免后续线程误判任务范围
|
||||
|
||||
### 2026-04-15
|
||||
|
||||
- 已处理组件:
|
||||
- `src/components/data/AccountInput/index.vue`
|
||||
- 说明:已完成账号输入组件中类型选择 placeholder、类型选项和平台选择 placeholder 的国际化;账号输入值、平台值与外部传入参数保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.accountInput`
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/AccountInput/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已处理组件:
|
||||
- `src/components/data/InappPurchaseGoogle/index.vue`
|
||||
- 说明:已完成弹窗标题、购买记录、Google 订阅单据、状态文案、复制按钮、空内容提示与 tooltip 的国际化;订阅令牌、json 内容、订单状态与接口返回值保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.inappPurchaseGoogle`
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/InappPurchaseGoogle/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已处理组件:
|
||||
- `src/components/data/InAppPurchaseDetails/index.vue`
|
||||
- 说明:已完成抽屉标题、订单信息区、状态流转、商品信息、元数据、事件通知和状态映射的国际化;`createNickname`、`productDescriptor`、商品名称/内容/描述、原因、事件类型与通知数据保持接口返回原值
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.inAppPurchaseDetails`
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/InAppPurchaseDetails/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已完成核查组件:
|
||||
- `src/components/data/InappPurchaseApple/index.vue`
|
||||
- 说明:当前组件已接入 `pages.inappPurchaseApple`,源码中未发现剩余中文展示文本,本轮无需重复修改源码
|
||||
- 已处理组件:
|
||||
- `src/components/data/UserAuthForm/index.vue`
|
||||
- 说明:已完成抽屉标题、卡片标题、手机号绑定按钮、已绑定状态、placeholder、校验提示、确认弹窗与成功提示的国际化;认证类型列表中的 `item.type` 与手机号数据保持接口返回原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.userAuthForm`
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/UserAuthForm/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已处理组件:
|
||||
- `src/components/data/RoomInfo/index.vue`
|
||||
- 说明:已完成折叠面板标题、基础资料字段、状态标签、布尔展示文案、设置信息字段、徽章 tooltip 文案的国际化;房间公告内容、国家码、平台值与接口返回数据保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.roomInfo`
|
||||
- 保留项:
|
||||
- `src/components/data/RoomInfo/index.vue`
|
||||
- 内容:注释掉的“装饰道具”代码块中的中文
|
||||
- 原因:该代码块当前不渲染,不属于可见展示文案,按协作规范不作为本轮必翻项处理
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/RoomInfo/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已完成页面:
|
||||
- `src/views/sys/region-config/region/index.vue`
|
||||
- 说明:已完成筛选区、表格列头、操作菜单、抽屉标题、表单标签、placeholder、钱包设置、确认弹窗与校验提示的国际化;接口参数、区域编码字段、提交结构与元数据 key 保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.regionConfig`
|
||||
- 已完成构建验证:
|
||||
- `src/views/sys/region-config/region/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已处理组件:
|
||||
- `src/components/data/AccountHanle/index.vue`
|
||||
- 说明:已完成弹窗标题、表单标签、处罚分组名、处罚选项名、天数选项、按钮、校验提示与翻译失败提示文案国际化;处罚值、提交字段和默认警告内容保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.accountHandle`
|
||||
- 阻塞/保留项:
|
||||
- `src/components/data/AccountHanle/index.vue`
|
||||
- 内容:默认“警告”描述文案
|
||||
- 原因:该文本会直接写入提交表单并发送给后端,属于提交内容,不按纯展示文案处理
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/AccountHanle/index.vue` 国际化改动编译通过
|
||||
- 已完成页面:
|
||||
- `src/views/team/diamond-policy/index.vue`
|
||||
- 说明:已完成筛选区、政策菜单、表格列头、编辑区、历史抽屉、校验提示与确认弹窗翻译;接口参数、政策类型值、提交结构和删除/发布逻辑保持原样
|
||||
- 已处理页面私有子组件:
|
||||
- `src/views/team/diamond-policy/props-form-edit.vue`
|
||||
- 说明:已完成抽屉内静态展示文案翻译,并复用现有 `pages.propsSourceGroupForm` key,避免重复新增同义 key
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.teamDiamondPolicy`
|
||||
- 已完成构建验证:
|
||||
- `src/views/team/diamond-policy/index.vue` 国际化改动编译通过
|
||||
- `src/views/team/diamond-policy/props-form-edit.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已完成页面:
|
||||
- `src/views/game/lottery-config/form-edit.vue`
|
||||
- 说明:已完成弹窗标题、游戏类型、奖励列表、添加配置区、按钮、placeholder、校验提示与概率提示的国际化;`lotteryGameTypes` 的共享常量值未改动,仅在页面展示层对 `EGG` 做了本地映射翻译
|
||||
- 已处理页面私有子组件:
|
||||
- `src/views/game/lottery-config/select-propsr-popover.vue`
|
||||
- 说明:已完成弹出层标题、类型名称标签与选择按钮国际化
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.gameLotteryConfigForm`
|
||||
- 复用范围:`pages.propsSourceGroupForm.resourceType`、`pages.propsSourceGroupForm.validation`
|
||||
- 保留项:
|
||||
- `src/views/game/lottery-config/form-edit.vue`
|
||||
- 内容:`specialIdTypes`、`pItem.name`、`badgeName` 等动态或接口返回内容
|
||||
- 原因:这类文本不属于静态展示文案,本轮按原值展示
|
||||
- 已完成构建验证:
|
||||
- `src/views/game/lottery-config/form-edit.vue` 国际化改动编译通过
|
||||
- `src/views/game/lottery-config/select-propsr-popover.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已完成页面:
|
||||
- `src/views/game/lottery-config/index.vue`
|
||||
- 说明:已完成筛选区 placeholder、搜索/添加按钮、游戏类型列、道具列、时间列、编辑按钮与游戏类型展示映射国际化;接口查询参数、分页结构和编辑逻辑保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.gameLotteryConfig`
|
||||
- 保留项:
|
||||
- `src/views/game/lottery-config/index.vue`
|
||||
- 内容:注释掉的“上/下架”筛选块中的中文
|
||||
- 原因:该区块当前不渲染,不属于可见展示文案
|
||||
- 已完成构建验证:
|
||||
- `src/views/game/lottery-config/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已沉淀线程经验到文档:
|
||||
- 新线程读取源码与 md 时统一使用 UTF-8 显式编码
|
||||
- 每次领取新任务前都要重新读取 `docs/i18n/线程协作.md`、`docs/i18n/翻译进度.md`、`docs/i18n/翻译清单.md` 与 `docs/i18n/主要路由.md`,确认认领状态已经写入 md 后再决定是否领取
|
||||
- 每次认领任务时,必须先更新 md 再开始改源码;写入认领记录前后都要复查 3 份协作文档 + `docs/i18n/主要路由.md`,确认没有线程冲突
|
||||
- 构建验证统一使用 `npm run build:prod`
|
||||
- 同目录私有子组件需和页面一起扫描,避免“主页面已翻、抽屉仍是中文”
|
||||
|
||||
### 2026-04-14
|
||||
|
||||
- 已建立页面级翻译文件目录:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 已将页面级翻译模块接入:
|
||||
- `src/lang/messages/en.js`
|
||||
- `src/lang/messages/zh.js`
|
||||
- 已完成页面:
|
||||
- `src/views/message/push/push-task.vue`
|
||||
- 说明:仅替换展示文本,接口值如 `OFFICIAL_MESSAGE_NOTICE`、语言值 `ar/tr/en`、状态值等保持不变
|
||||
- `src/views/user/user-table/index.vue`
|
||||
- 说明:已完成页面可见文案翻译,接口查询字段、权限码、提交值和路由逻辑未改动
|
||||
- 已处理组件:
|
||||
- `src/components/data/UserInfo/BaseInfo/index.vue`
|
||||
- 当前状态:已完成展示文本翻译,剩余中文仅存在注释中
|
||||
- 已完成页面:
|
||||
- `src/views/room/profile/index.vue`
|
||||
- 说明:已完成筛选区、表格、操作菜单、弹窗、表单校验文案和下拉展示项翻译;接口参数、事件值、角色值、审批状态值保持原样
|
||||
- 已完成页面:
|
||||
- `src/views/team/policy/index.vue`
|
||||
- 说明:已完成筛选区、政策列表、编辑区、历史政策抽屉、确认提示与状态文案翻译;政策类型值、查询参数、发布状态字段等后端依赖值保持原样
|
||||
- 已完成可见静态文案:
|
||||
- `src/views/props/props-source-group/form-edit.vue`
|
||||
- 说明:已完成抽屉标题、表单标签、按钮、占位文案、校验提示、奖励摘要和本地资源类型名称翻译
|
||||
- 待补接口样例:
|
||||
- 奖励列表中的 `badgeName`
|
||||
- 资源选择项中的 `pItem.name`
|
||||
- 接口返回的礼物 / 徽章 / 表情包 / 通用资源名称
|
||||
- 处理策略:这类文本依赖接口返回,当前先保留原样,等待你后续提供接口返回数据后再逐项补齐
|
||||
- 已完成页面:
|
||||
- `src/views/cnf/lottery/index.vue`
|
||||
- 说明:已完成配置页中的卡片标题、表单标签、按钮、弹窗提示、默认奖品文案和默认配置区翻译;仅处理展示文案,抽奖配置结构、接口提交体和字段值保持原样
|
||||
- 已完成页面:
|
||||
- `src/views/activity/template-cnf/index.vue`
|
||||
- 说明:已完成筛选区、帮助说明、表格列标题、状态标签、操作菜单、加载文案与确认弹窗翻译;活动状态值、权限码、接口查询参数和路由跳转参数保持原样
|
||||
- 已完成页面:
|
||||
- `src/views/team/business-development/index.vue`
|
||||
- 说明:已完成筛选区、表格列头、操作菜单、无权限提示、复制结果提示与删除确认弹窗翻译;权限码、接口查询参数、分页参数和操作逻辑保持原样
|
||||
- 已补充并固定文档目录:
|
||||
- `docs/i18n/翻译进度.md`
|
||||
- `docs/i18n/翻译清单.md`
|
||||
- 后续翻译时需要同步更新的文档:
|
||||
- `docs/i18n/翻译进度.md`
|
||||
- `docs/i18n/翻译清单.md`
|
||||
- 已将你的约束写入文档并作为后续执行规则:
|
||||
- 只翻译展示文本
|
||||
- 不修改功能逻辑
|
||||
- 不修改接口参数
|
||||
- 不修改路由路径
|
||||
- 不修改权限码
|
||||
- 不修改后端依赖值
|
||||
- 已补充国际化表单适配样式:
|
||||
- 为英文等较长标题增加可复用的表单标签宽度和自动换行方案
|
||||
- 已补充表单标题纵向居中,避免标签宽度加大后文字贴上边
|
||||
- 当前已接入页面:
|
||||
- `src/views/message/push/push-task.vue`
|
||||
- `src/views/room/profile/index.vue`
|
||||
- 公共样式位置:
|
||||
- `src/styles/element-ui.scss`
|
||||
- 已完成表格展示适配方案:
|
||||
- 表头标题支持自动换行,避免英文标题被直接截断
|
||||
- 未设置 `min-width` 的普通 `el-table-column` 增加全局默认最小宽度
|
||||
- 已修正表头 `.cell` 高度自适应与纵向居中,避免 `th` 足够高但标题文本仍贴边
|
||||
- 相关入口位置:
|
||||
- `src/styles/element-ui.scss`
|
||||
- `src/main.js`
|
||||
- 已完成两次构建验证:
|
||||
- 语言切换持久化改动编译通过
|
||||
- `src/views/room/profile/index.vue` 国际化改动编译通过
|
||||
- `src/views/team/policy/index.vue` 国际化改动编译通过
|
||||
- `src/views/props/props-source-group/form-edit.vue` 静态文案国际化改动编译通过
|
||||
- `src/views/cnf/lottery/index.vue` 国际化改动编译通过
|
||||
- `src/views/activity/template-cnf/index.vue` 国际化改动编译通过
|
||||
- `src/views/team/business-development/index.vue` 国际化改动编译通过
|
||||
- 表格标题自动换行与默认最小宽度适配编译通过
|
||||
- 表格标题 `.cell` 高度自适应与纵向居中修正编译通过
|
||||
- 表单标题纵向居中适配编译通过
|
||||
- 已处理组件:
|
||||
- `src/components/data/UserInfo/BankCardDrawer/index.vue`
|
||||
- 说明:已完成抽屉标题、卡片标签、审核状态、使用状态、操作按钮、表单标签、placeholder、校验提示与确认弹窗国际化;`cardType` 与银行卡类型枚举值保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.bankCardDrawer`
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/UserInfo/BankCardDrawer/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已处理页面:
|
||||
- `src/views/game/lucky-box/standard-config/gift-details.vue`
|
||||
- 说明:已完成列表弹窗、表格列头、操作按钮、提示文案、表单标签、placeholder、校验提示与礼物类型展示映射的国际化;礼物类型实际值、接口参数与页面逻辑保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.luckyBoxGiftDetails`
|
||||
- 已完成构建验证:
|
||||
- `src/views/game/lucky-box/standard-config/gift-details.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已完成页面:
|
||||
- `src/views/game/lucky-box/standard-config/index.vue`
|
||||
- 说明:已完成筛选区、表格列头、类型标签、操作按钮、删除确认与成功提示的国际化;列表筛选值、状态布尔值与接口逻辑保持原样
|
||||
- 已处理页面私有子组件:
|
||||
- `src/views/game/lucky-box/standard-config/edit.vue`
|
||||
- `src/views/game/lucky-box/standard-config/probability.vue`
|
||||
- 说明:已完成编辑弹窗与概率配置弹窗中的标题、表单标签、placeholder、校验提示、说明提示、保存确认与错误提示国际化;概率数值、礼物关联值与接口参数保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.luckyBoxStandardConfig`
|
||||
- 已完成构建验证:
|
||||
- `src/views/game/lucky-box/standard-config/index.vue` 国际化改动编译通过
|
||||
- `src/views/game/lucky-box/standard-config/edit.vue` 国际化改动编译通过
|
||||
- `src/views/game/lucky-box/standard-config/probability.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已处理组件:
|
||||
- `src/components/data/UserInfo/BaseInfo/AssociatedDeviceTimeline.vue`
|
||||
- 说明:已完成语言、时区、IP、客户端、设备信息、Push 信息与注册时间等标签国际化;`item.latestDevice.*` 与 `item.userProfile.createTime` 等动态数据保持原样
|
||||
- 语言 key 处理:
|
||||
- 本轮复用 `pages.userBaseInfo.labels`
|
||||
- 本轮复用 `pages.userBaseInfo.words.activeIp`
|
||||
- 无需新增页面级语言 key
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/UserInfo/BaseInfo/AssociatedDeviceTimeline.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已处理组件:
|
||||
- `src/components/data/UserInfo/AccountStatusLatestLog/index.vue`
|
||||
- 说明:已完成最新账号处理日志标签文案国际化;`item.approvalUserName`、`item.statusName` 与 `item.createTime` 保持动态原值展示
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.accountStatusLatestLog`
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/UserInfo/AccountStatusLatestLog/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已处理组件:
|
||||
- `src/components/data/UserInfo/UserTableExhibit/index.vue`
|
||||
- 说明:已完成特殊 ID 账号展示后缀国际化;直接复用 `pages.userBaseInfo.labels.specialIdSuffix`,未新增页面级语言 key
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/UserInfo/UserTableExhibit/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已处理组件:
|
||||
- `src/components/data/SearchRoomInput/index.vue`
|
||||
- 说明:已完成房间 ID 输入框 placeholder、类型选择、搜索结果弹窗与失败提示国际化;房间数据与接口返回内容保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.searchRoomInput`
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/SearchRoomInput/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已处理组件:
|
||||
- `src/components/data/GiftHistoryDetailsDrawer/index.vue`
|
||||
- 说明:已完成抽屉标题、发送人/房间、礼物信息快照、接收用户标签、日志事件与单据 ID 按钮国际化;礼物值、房间资料、日志内容与接口返回数据保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.giftHistoryDetailsDrawer`
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/GiftHistoryDetailsDrawer/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已处理组件:
|
||||
- `src/components/data/EditUserForm/index.vue`
|
||||
- 说明:已完成用户编辑抽屉标题、昵称/性别表单项、出生日期 placeholder、关闭/提交按钮与校验提示国际化;国家选择与接口返回数据保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.editUserForm`
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/EditUserForm/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已处理组件:
|
||||
- `src/components/data/EditUserGoldCoinRewardForm/index.vue`
|
||||
- 说明:已完成金币奖励弹窗标题、表单标签、placeholder、按钮与校验提示国际化;`currencyRewardReasons` 的提交值与备注拼接内容保持原样,仅在页面展示层做奖励类型本地映射翻译
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.editUserGoldCoinRewardForm`
|
||||
- 保留项:
|
||||
- `src/components/data/EditUserGoldCoinRewardForm/index.vue`
|
||||
- 内容:模板注释中的中文
|
||||
- 原因:该部分不渲染,不属于可见展示文案
|
||||
- 已完成构建验证:
|
||||
- `src/components/data/EditUserGoldCoinRewardForm/index.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已完成页面:
|
||||
- `src/views/game/lucky-box/award-config/index.vue`
|
||||
- 说明:已完成筛选区、表格列头、类型标签、操作按钮、删除确认与成功提示的国际化;列表筛选值与接口逻辑保持原样
|
||||
- 已处理页面私有子组件:
|
||||
- `src/views/game/lucky-box/award-config/edit.vue`
|
||||
- `src/views/game/lucky-box/award-config/details.vue`
|
||||
- 说明:已完成编辑弹窗与奖励配置弹窗中的标题、表单标签、placeholder、校验提示、按钮与本地常量类型映射国际化;资源值、目标次数、接口参数与逻辑保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.luckyBoxAwardConfig`
|
||||
- 已完成构建验证:
|
||||
- `src/views/game/lucky-box/award-config/index.vue` 国际化改动编译通过
|
||||
- `src/views/game/lucky-box/award-config/edit.vue` 国际化改动编译通过
|
||||
- `src/views/game/lucky-box/award-config/details.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
- 已完成页面:
|
||||
- `src/views/game/lucky-box/bounty-config/index.vue`
|
||||
- 说明:已完成筛选区、表格列头、类型标签、操作按钮、删除确认与成功提示的国际化;`DAILY`、`WEEKLY` 等实际值与接口逻辑保持原样
|
||||
- 已处理页面私有子组件:
|
||||
- `src/views/game/lucky-box/bounty-config/edit.vue`
|
||||
- `src/views/game/lucky-box/bounty-config/details.vue`
|
||||
- 说明:已完成编辑弹窗与道具配置弹窗中的标题、表单标签、placeholder、校验提示、按钮、礼物类型/道具类型本地映射国际化;资源值、提交字段、接口参数与逻辑保持原样
|
||||
- 已补充页面级语言 key:
|
||||
- `src/lang/messages/pages/en.js`
|
||||
- `src/lang/messages/pages/zh.js`
|
||||
- 新增范围:`pages.luckyBoxBountyConfig`
|
||||
- 已完成构建验证:
|
||||
- `src/views/game/lucky-box/bounty-config/index.vue` 国际化改动编译通过
|
||||
- `src/views/game/lucky-box/bounty-config/edit.vue` 国际化改动编译通过
|
||||
- `src/views/game/lucky-box/bounty-config/details.vue` 国际化改动编译通过
|
||||
- 当前仍保留项目原有 `22` 条 warning,未因本轮 i18n 改动新增阻塞性错误
|
||||
|
||||
## 当前进行中
|
||||
|
||||
- 历史已完成 `src/views` 页面私有组件复查任务当前优先于新页面认领
|
||||
- 下一步目标:
|
||||
- 先补查已标记完成页面目录中的私有组件,并把组件状态补写入进度文档
|
||||
- 完成该临时任务后,再继续按 `docs/i18n/主要路由.md` 领取下一个未完成主路由页面
|
||||
- 当前认领线程:
|
||||
- 线程一:当前无进行中任务;已完成 `src/views/sys/start-page/index.vue` 与 `src/views/sys/start-page/form-edit.vue`,并已完成构建验证与 md 同步
|
||||
- 线程二:当前无进行中任务;已完成 `src/views/message/push/index.vue`、`src/views/message/push/new-push-form.vue`、`src/views/message/push/push-log.vue`、`src/views/message/push/push-task.vue`,并已完成构建验证与 md 同步
|
||||
- 线程三:当前无进行中任务;已完成 `src/views/tools/upload/index.vue`,后续与其他线程一样优先处理历史已完成页面私有组件复查
|
||||
|
||||
## 扫描概况
|
||||
|
||||
### views 目录
|
||||
|
||||
- `src/views` 中命中中文展示文本总数:`9165`
|
||||
- `src/views` 中涉及文件数:`430`
|
||||
|
||||
#### 中文密度较高的页面
|
||||
|
||||
- `src/views/user/user-table/index.vue`:158
|
||||
- `src/views/props/props-source-group/form-edit.vue`:140
|
||||
- `src/views/cnf/lottery/index.vue`:133
|
||||
- `src/views/room/profile/index.vue`:128
|
||||
- `src/views/team/policy/index.vue`:125
|
||||
- `src/views/activity/template-cnf/index.vue`:90
|
||||
- `src/views/team/business-development/index.vue`:89
|
||||
- `src/views/sys/region-config/region/index.vue`:已完成
|
||||
- `src/views/team/diamond-policy/index.vue`:已完成
|
||||
- `src/views/game/lottery-config/form-edit.vue`:已完成
|
||||
|
||||
### components 目录
|
||||
|
||||
- `src/components` 中命中中文展示文本总数:`752`
|
||||
- `src/components` 中涉及文件数:`57`
|
||||
|
||||
#### 中文密度较高的组件
|
||||
|
||||
- `src/components/data/UserInfo/BaseInfo/index.vue`:79
|
||||
- `src/components/data/InappPurchaseApple/index.vue`:54
|
||||
- `src/components/data/AccountHanle/index.vue`:已完成
|
||||
- `src/components/data/InAppPurchaseDetails/index.vue`:45
|
||||
- `src/components/data/InappPurchaseGoogle/index.vue`:40
|
||||
- `src/components/data/RoomInfo/index.vue`:39
|
||||
- `src/components/data/UserInfo/BankCardDrawer/index.vue`:33
|
||||
- `src/components/data/UserAuthForm/index.vue`:32
|
||||
|
||||
## 建议执行顺序
|
||||
|
||||
### 第一批
|
||||
|
||||
- `src/views/user/user-table/index.vue`
|
||||
- `src/components/data/UserInfo/BaseInfo/index.vue`
|
||||
- `src/views/room/profile/index.vue`
|
||||
- `src/views/message/push/push-task.vue`
|
||||
- `src/views/team/policy/index.vue`
|
||||
|
||||
### 第二批
|
||||
|
||||
- `src/views/props/props-source-group/form-edit.vue`
|
||||
- `src/views/cnf/lottery/index.vue`
|
||||
- `src/views/activity/template-cnf/index.vue`
|
||||
- `src/views/team/business-development/index.vue`
|
||||
- `src/views/sys/region-config/region/index.vue`(已完成)
|
||||
- `src/views/team/diamond-policy/index.vue`
|
||||
- `src/views/game/lottery-config/form-edit.vue`(已完成)
|
||||
|
||||
### 第三批
|
||||
|
||||
- `src/components/data/AccountHanle/index.vue`
|
||||
- `src/components/data/InappPurchaseApple/index.vue`
|
||||
- `src/components/data/InAppPurchaseDetails/index.vue`
|
||||
- `src/components/data/InappPurchaseGoogle/index.vue`
|
||||
- `src/components/data/RoomInfo/index.vue`
|
||||
|
||||
## 备注
|
||||
|
||||
- 终端里部分文件曾出现乱码展示,已确认源码本身为 UTF-8,后续按 UTF-8 读取和修改
|
||||
- 在 PowerShell 中建议显式使用:`Get-Content -Raw -Encoding UTF8 <path>`
|
||||
- 部分旧语言文件中存在历史遗留键值写法混用问题,后续会逐步收口,但不影响当前继续翻译页面
|
||||
- 路由 / 菜单翻译与页面展示文案翻译分开处理,避免相互影响
|
||||
- 校验提示、按钮、标签、空态、对话框标题属于安全翻译区
|
||||
- 类似 `PASS`、`NOT_PASS`、`OFFICIAL_MESSAGE_NOTICE`、`NORMAL`、`FREEZE` 这类后端依赖值必须保持原样
|
||||
- 本项目构建验证命令为:`npm run build:prod`
|
||||
212
docs/问题排查记录-权限平台与开发服务地址.md
Normal file
212
docs/问题排查记录-权限平台与开发服务地址.md
Normal file
@ -0,0 +1,212 @@
|
||||
# 问题排查记录:权限平台默认值与开发服务 Network 地址
|
||||
|
||||
## 记录时间
|
||||
|
||||
- 2026-04
|
||||
|
||||
## 背景
|
||||
|
||||
本次排查涉及两个独立但连续出现的问题:
|
||||
|
||||
1. 页面初始化时,`this.permissionsSysOriginPlatforms[0]` 偶发拿不到,导致默认平台没有赋值,后续 `renderData(true)` 不执行。
|
||||
2. 本地执行 `npm run dev` 后,控制台一直显示 `Network: unavailable`,但同机器的其他项目可以正常显示类似 `http://192.168.0.115:5173/` 的局域网访问地址。
|
||||
|
||||
---
|
||||
|
||||
## 一、权限平台默认值偶发为空
|
||||
|
||||
### 现象
|
||||
|
||||
页面中存在如下初始化逻辑:
|
||||
|
||||
```js
|
||||
const querySystem = this.permissionsSysOriginPlatforms[0];
|
||||
if (!querySystem) {
|
||||
return;
|
||||
}
|
||||
that.listQuery.sysOrigins = [querySystem.value];
|
||||
that.renderData(true);
|
||||
```
|
||||
|
||||
当 `this.permissionsSysOriginPlatforms[0]` 为空时,页面会直接返回,默认查询条件与首屏数据都不会初始化。
|
||||
|
||||
### 结论
|
||||
|
||||
`permissionsSysOriginPlatforms` 不是接口直接返回的平台数组,而是:
|
||||
|
||||
1. 按钮权限接口先返回权限别名列表。
|
||||
2. 前端再用本地写死的 `sysOriginPlatforms` 常量进行过滤。
|
||||
3. 过滤结果再写入 Vuex,页面最终通过 getter 读取。
|
||||
|
||||
也就是说:
|
||||
|
||||
- 平台候选项来源于前端常量。
|
||||
- 当前用户能拿到哪些平台,取决于按钮权限接口返回的权限别名。
|
||||
|
||||
### 关键代码链路
|
||||
|
||||
- 页面读取位置:`src/views/user/user-table/index.vue`
|
||||
- getter 映射位置:`src/store/getters.js`
|
||||
- Vuex 组装位置:`src/store/modules/user.js`
|
||||
- 平台常量定义:`src/constant/origin.js`
|
||||
- 按钮权限接口:`src/api/ops-system.js`
|
||||
|
||||
### 根因
|
||||
|
||||
根因是时序问题,不是页面本地代码本身写错:
|
||||
|
||||
1. 路由守卫中会调用 `store.dispatch('user/buttonPermissions')`。
|
||||
2. 但原逻辑没有 `await` 这个异步请求。
|
||||
3. 页面已经进入并执行 `created()` 时,权限数据可能还没回填到 Vuex。
|
||||
4. 于是 `this.permissionsSysOriginPlatforms[0]` 偶发为空。
|
||||
|
||||
另外还有一个补充前提:
|
||||
|
||||
- 当前前端常量里只有 `ATYOU` 一个系统平台,并且依赖权限 `query:atyou`。
|
||||
- 如果接口没有返回这个权限,过滤后数组本身也会为空。
|
||||
|
||||
### 已做处理
|
||||
|
||||
已在 `src/permission.js` 中将:
|
||||
|
||||
```js
|
||||
store.dispatch('user/buttonPermissions')
|
||||
```
|
||||
|
||||
修改为:
|
||||
|
||||
```js
|
||||
await store.dispatch('user/buttonPermissions')
|
||||
```
|
||||
|
||||
### 处理结果
|
||||
|
||||
调整后,路由放行前会先等待按钮权限加载完成,页面 `created()` 再读取 `permissionsSysOriginPlatforms` 时,不会再因为异步竞争导致首项为空。
|
||||
|
||||
### 后续建议
|
||||
|
||||
- 若后续仍出现空数组,需要优先检查接口返回是否包含 `query:atyou`。
|
||||
- 如果页面还需要进一步增强健壮性,可以在页面侧增加 watcher 或兜底默认逻辑,但当前首先应保证路由阶段权限已完成回填。
|
||||
|
||||
---
|
||||
|
||||
## 二、开发服务 `Network: unavailable`
|
||||
|
||||
### 现象
|
||||
|
||||
执行 `npm run dev` 后输出类似:
|
||||
|
||||
```txt
|
||||
App running at:
|
||||
- Local: http://localhost:9528
|
||||
- Network: unavailable
|
||||
```
|
||||
|
||||
但同一台机器上的其他项目可以正常显示局域网访问地址。
|
||||
|
||||
### 初步排查结论
|
||||
|
||||
这不是项目无法启动,也不是没有局域网 IP,而是 Vue CLI 选错了网卡。
|
||||
|
||||
通过系统网络信息确认:
|
||||
|
||||
- 当前机器存在可用私网地址:`192.168.0.115`
|
||||
- 同时还存在一个虚拟网卡地址:`26.26.26.1`
|
||||
|
||||
### 根因
|
||||
|
||||
项目使用的是较老版本的 `@vue/cli-service 3.6.0`。
|
||||
|
||||
该版本在生成 `Network` 地址时,会在内部调用 `address.ip()` 取一个 IPv4 地址,然后只接受以下私网地址范围:
|
||||
|
||||
- `10.x.x.x`
|
||||
- `172.16.x.x` 到 `172.31.x.x`
|
||||
- `192.168.x.x`
|
||||
|
||||
如果拿到的不是私网地址,就会直接将 `Network` 显示为 `unavailable`。
|
||||
|
||||
本次机器环境中,Vue CLI 优先拿到的是虚拟网卡 `26.26.26.1`,由于它不属于私网范围,因此被直接丢弃,最终控制台显示 `Network: unavailable`。
|
||||
|
||||
### 关键代码位置
|
||||
|
||||
- 输出逻辑:`node_modules/@vue/cli-service/lib/commands/serve.js`
|
||||
- 局域网地址选择逻辑:`node_modules/@vue/cli-service/lib/util/prepareURLs.js`
|
||||
|
||||
### 已尝试处理
|
||||
|
||||
#### 第一步
|
||||
|
||||
先在 `vue.config.js` 中增加:
|
||||
|
||||
```js
|
||||
host: '0.0.0.0'
|
||||
```
|
||||
|
||||
目的:
|
||||
|
||||
- 让 dev server 监听所有网卡,而不是只监听本机回环地址。
|
||||
|
||||
结果:
|
||||
|
||||
- 监听范围已放开。
|
||||
- 但 `Network` 仍然显示 `unavailable`。
|
||||
- 说明问题不在监听地址,而在 Vue CLI 的网卡识别逻辑。
|
||||
|
||||
#### 第二步
|
||||
|
||||
在 `vue.config.js` 中新增自定义 LAN IP 选择逻辑,替代 Vue CLI 默认的“随便取一个 IPv4”的方式。
|
||||
|
||||
处理思路:
|
||||
|
||||
1. 使用 `os.networkInterfaces()` 枚举网卡。
|
||||
2. 只保留私网 IPv4。
|
||||
3. 优先选择 `WLAN / Wi-Fi / Ethernet / 以太网` 这类常见真实网卡。
|
||||
4. 排除 `TAP / VPN / Virtual / VMware / Hyper-V / Docker / vEthernet` 等虚拟网卡。
|
||||
5. 将最终结果写入 `devServer.public`。
|
||||
|
||||
### 当前配置结果
|
||||
|
||||
`vue.config.js` 已调整为:
|
||||
|
||||
- `host: '0.0.0.0'`
|
||||
- `public: lanIp ? \`${lanIp}:${port}\` : undefined`
|
||||
|
||||
并增加了自动识别私网地址的辅助函数。
|
||||
|
||||
### 处理结果
|
||||
|
||||
此修改的目的不是单纯让服务“能访问”,而是:
|
||||
|
||||
1. 明确让服务监听所有网卡。
|
||||
2. 明确告诉旧版 Vue CLI 应该向外公布哪个局域网地址。
|
||||
3. 避免其误选虚拟网卡后把 Network 判成 unavailable。
|
||||
|
||||
### 备用方案
|
||||
|
||||
如果后续本机 IP 变化,或当前网络环境特殊,也可以临时手动指定:
|
||||
|
||||
```powershell
|
||||
$env:DEV_SERVER_PUBLIC_IP='192.168.0.115'
|
||||
npm run dev
|
||||
```
|
||||
|
||||
或:
|
||||
|
||||
```powershell
|
||||
npm run dev -- --public 192.168.0.115:9528
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 本次涉及的改动文件
|
||||
|
||||
- `src/permission.js`
|
||||
- `vue.config.js`
|
||||
- `docs/问题排查记录-权限平台与开发服务地址.md`
|
||||
|
||||
## 本次经验总结
|
||||
|
||||
1. 页面里出现“偶发空值”时,优先检查数据来源是不是异步回填,而不是只盯页面局部逻辑。
|
||||
2. `permissionsSysOriginPlatforms` 这类字段要区分“候选项来源”和“最终权限结果来源”。
|
||||
3. 老版本 Vue CLI 对网卡选择并不稳定,机器上存在 VPN、TAP、虚拟网卡时,`Network: unavailable` 往往是地址识别问题,不代表 dev server 本身不可用。
|
||||
4. 对局域网访问有明确需求的项目,最好显式配置 `devServer.host` 与 `devServer.public`,不要完全依赖工具链自动推断。
|
||||
@ -4,8 +4,8 @@
|
||||
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
|
||||
<!-- <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
|
||||
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a> -->
|
||||
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
|
||||
<a v-else>{{ item.meta.title }}</a>
|
||||
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ translateTitle(item.meta.title) }}</span>
|
||||
<a v-else>{{ translateTitle(item.meta.title) }}</a>
|
||||
</el-breadcrumb-item>
|
||||
</transition-group>
|
||||
</el-breadcrumb>
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
<script>
|
||||
import pathToRegexp from 'path-to-regexp'
|
||||
import { translateRouteTitle } from '@/lang'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@ -35,7 +36,7 @@ export default {
|
||||
const first = matched[0]
|
||||
|
||||
if (!this.isDashboard(first)) {
|
||||
matched = [{ path: '/dashboard', meta: { title: 'Dashboard' }}].concat(matched)
|
||||
matched = [{ path: '/dashboard', meta: { title: 'nav.home' }}].concat(matched)
|
||||
}
|
||||
|
||||
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
|
||||
@ -47,6 +48,9 @@ export default {
|
||||
}
|
||||
return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
|
||||
},
|
||||
translateTitle(title) {
|
||||
return translateRouteTitle(title)
|
||||
},
|
||||
pathCompile(path) {
|
||||
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
|
||||
const { params } = this.$route
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
filterable
|
||||
default-first-option
|
||||
remote
|
||||
placeholder="Search"
|
||||
:placeholder="$t('common.search')"
|
||||
class="header-search-select"
|
||||
@change="change"
|
||||
>
|
||||
@ -22,6 +22,7 @@
|
||||
// make search results more in line with expectations
|
||||
import Fuse from 'fuse.js'
|
||||
import path from 'path'
|
||||
import { translateRouteTitle } from '@/lang'
|
||||
|
||||
export default {
|
||||
name: 'HeaderSearch',
|
||||
@ -35,6 +36,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
language() {
|
||||
return this.$store.getters.language
|
||||
},
|
||||
routes() {
|
||||
return this.$store.getters.routers
|
||||
}
|
||||
@ -46,6 +50,9 @@ export default {
|
||||
searchPool(list) {
|
||||
this.initFuse(this.filterTitleGtLevelExcludeDashboard(list, 1))
|
||||
},
|
||||
language() {
|
||||
this.searchPool = this.generateRoutes(this.routes)
|
||||
},
|
||||
show(value) {
|
||||
if (value) {
|
||||
document.body.addEventListener('click', this.close)
|
||||
@ -119,7 +126,7 @@ export default {
|
||||
}
|
||||
|
||||
if (router.meta && router.meta.title) {
|
||||
data.title = [...data.title, router.meta.title]
|
||||
data.title = [...data.title, translateRouteTitle(router.meta.title)]
|
||||
|
||||
if (router.redirect !== 'noRedirect') {
|
||||
// only push the routes with title
|
||||
|
||||
96
src/components/LanguageSwitch/index.vue
Normal file
96
src/components/LanguageSwitch/index.vue
Normal file
@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<el-dropdown class="language-switch" :trigger="trigger" @command="handleCommand">
|
||||
<span class="language-trigger">
|
||||
<i v-if="showIcon" class="el-icon-s-flag" />
|
||||
<span class="label">{{ currentLabel }}</span>
|
||||
<i class="el-icon-arrow-down el-icon--right" />
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item
|
||||
v-for="item in languageOptions"
|
||||
:key="item.value"
|
||||
:command="item.value"
|
||||
:disabled="item.value === locale"
|
||||
>
|
||||
<span>{{ item.nativeLabel || item.label }}</span>
|
||||
<i v-if="item.value === locale" class="el-icon-check option-check" />
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getLocaleOptions } from '@/lang'
|
||||
|
||||
export default {
|
||||
name: 'LanguageSwitch',
|
||||
props: {
|
||||
trigger: {
|
||||
type: String,
|
||||
default: 'hover'
|
||||
},
|
||||
showIcon: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
computedLegacy: {
|
||||
locale() {
|
||||
return this.$store.getters.language
|
||||
},
|
||||
languageOptions() {
|
||||
return [
|
||||
{ value: 'en', label: 'English' },
|
||||
{ value: 'zh', label: '中文' }
|
||||
]
|
||||
},
|
||||
currentLabel() {
|
||||
return this.locale === 'zh' ? '中文' : 'English'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
locale() {
|
||||
return this.$store.getters.language
|
||||
},
|
||||
languageOptions() {
|
||||
return getLocaleOptions()
|
||||
},
|
||||
currentOption() {
|
||||
return this.languageOptions.find(item => item.value === this.locale) || this.languageOptions[0] || {}
|
||||
},
|
||||
currentLabel() {
|
||||
return this.currentOption.nativeLabel || this.currentOption.label || this.locale
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleCommand(locale) {
|
||||
this.$setLocale(locale)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.language-switch {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
|
||||
.language-trigger {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
color: #7A5C3F;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.label {
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.option-check {
|
||||
margin-left: 8px;
|
||||
color: #FF9326;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,12 +1,11 @@
|
||||
<template>
|
||||
<template>
|
||||
<el-dropdown trigger="click" @command="handleSetSize">
|
||||
<div>
|
||||
<svg-icon class-name="size-icon" icon-class="size" />
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item v-for="item of sizeOptions" :key="item.value" :disabled="size===item.value" :command="item.value">
|
||||
{{
|
||||
item.label }}
|
||||
{{ item.label }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
@ -14,17 +13,15 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
sizeOptions: [
|
||||
{ label: '默认(Default)', value: 'default' },
|
||||
{ label: '中等(Medium)', value: 'medium' },
|
||||
{ label: '小的(Small)', value: 'small' },
|
||||
{ label: '迷你(Mini)', value: 'mini' }
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
sizeOptions() {
|
||||
return [
|
||||
{ label: this.$t('size.default'), value: 'default' },
|
||||
{ label: this.$t('size.medium'), value: 'medium' },
|
||||
{ label: this.$t('size.small'), value: 'small' },
|
||||
{ label: this.$t('size.mini'), value: 'mini' }
|
||||
]
|
||||
},
|
||||
size() {
|
||||
return this.$store.getters.size
|
||||
}
|
||||
@ -35,7 +32,7 @@ export default {
|
||||
this.$store.dispatch('app/setSize', size)
|
||||
this.refreshView()
|
||||
this.$message({
|
||||
message: 'Switch Size Success',
|
||||
message: this.$t('size.switchSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
},
|
||||
@ -43,6 +40,5 @@ export default {
|
||||
this.$router.go(0)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
title="账号处理"
|
||||
:title="$t('pages.accountHandle.dialog.title')"
|
||||
:visible="true"
|
||||
width="30%"
|
||||
:before-close="handleClose"
|
||||
@ -9,13 +9,13 @@
|
||||
ref="form"
|
||||
v-loading="loading"
|
||||
:model="form"
|
||||
:rules="formRules"
|
||||
:rules="localizedFormRules"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item v-loading="loadingAccountStatus" label="当前状态">
|
||||
<el-form-item v-loading="loadingAccountStatus" :label="$t('pages.accountHandle.form.currentStatus')">
|
||||
{{ thisAccountStatus.value }}
|
||||
</el-form-item>
|
||||
<el-form-item label="处理状态" prop="accountStatusEnum">
|
||||
<el-form-item :label="$t('pages.accountHandle.form.handleStatus')" prop="accountStatusEnum">
|
||||
<el-select
|
||||
v-model="form.accountStatusEnum"
|
||||
:disabled="accountStatusTypes.length <= 0"
|
||||
@ -38,45 +38,33 @@
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="form.accountStatusEnum === 'FREEZE'"
|
||||
label="冻结天数"
|
||||
:label="$t('pages.accountHandle.form.freezeDays')"
|
||||
prop="days"
|
||||
>
|
||||
<el-select v-model="form.days">
|
||||
<el-option label="1天" value="1" />
|
||||
<el-option label="2天" value="2" />
|
||||
<el-option label="3天" value="3" />
|
||||
<el-option label="4天" value="4" />
|
||||
<el-option label="5天" value="5" />
|
||||
<el-option label="6天" value="6" />
|
||||
<el-option label="7天" value="7" />
|
||||
<el-option label="8天" value="8" />
|
||||
<el-option label="9天" value="9" />
|
||||
<el-option label="10天" value="10" />
|
||||
<el-option label="15天" value="15" />
|
||||
<el-option label="30天" value="30" />
|
||||
<el-option
|
||||
v-for="item in dayOptions"
|
||||
:key="`freeze-${item.value}`"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="form.accountStatusEnum === 'ARCHIVE'"
|
||||
label="天数"
|
||||
:label="$t('pages.accountHandle.form.days')"
|
||||
prop="days"
|
||||
>
|
||||
<el-select v-model="form.days">
|
||||
<el-option label="1天" value="1" />
|
||||
<el-option label="2天" value="2" />
|
||||
<el-option label="3天" value="3" />
|
||||
<el-option label="4天" value="4" />
|
||||
<el-option label="5天" value="5" />
|
||||
<el-option label="6天" value="6" />
|
||||
<el-option label="7天" value="7" />
|
||||
<el-option label="8天" value="8" />
|
||||
<el-option label="9天" value="9" />
|
||||
<el-option label="10天" value="10" />
|
||||
<el-option label="15天" value="15" />
|
||||
<el-option label="30天" value="30" />
|
||||
<el-option
|
||||
v-for="item in dayOptions"
|
||||
:key="`archive-${item.value}`"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="description">
|
||||
<el-form-item :label="$t('pages.accountHandle.form.remarks')" prop="description">
|
||||
<el-input
|
||||
v-model.trim="form.description"
|
||||
type="textarea"
|
||||
@ -88,14 +76,14 @@
|
||||
type="text"
|
||||
:disabled="disabledTranslate"
|
||||
@click="clickTranslate"
|
||||
>点击翻译</el-button
|
||||
>{{ $t('pages.accountHandle.action.translate') }}</el-button
|
||||
>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="form.descriptionTranslate" label="译文">
|
||||
<el-form-item v-if="form.descriptionTranslate" :label="$t('pages.accountHandle.form.translation')">
|
||||
<el-input v-model="form.descriptionTranslate" type="textarea" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="submit()">提交</el-button>
|
||||
<el-button type="primary" @click="submit()">{{ $t('pages.accountHandle.action.submit') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-dialog>
|
||||
@ -120,9 +108,6 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const commonRules = [
|
||||
{ required: true, message: "必填字段不可为空", trigger: "blur" }
|
||||
];
|
||||
return {
|
||||
loadingTranslate: false,
|
||||
loadingAccountStatus: true,
|
||||
@ -131,21 +116,21 @@ export default {
|
||||
loading: false,
|
||||
accountStatusGroup: [
|
||||
{
|
||||
name: "执行处罚",
|
||||
nameKey: "executePunishment",
|
||||
options: [
|
||||
{ value: "WARNING", name: "警告" },
|
||||
{ value: "FREEZE", name: "冻结" },
|
||||
{ value: "ARCHIVE", name: "封禁" },
|
||||
{ value: "ARCHIVE1DAY", name: "封禁1天" },
|
||||
{ value: "ARCHIVE_DEVICE", name: "封禁+设备" }
|
||||
{ value: "WARNING", nameKey: "warning" },
|
||||
{ value: "FREEZE", nameKey: "freeze" },
|
||||
{ value: "ARCHIVE", nameKey: "archive" },
|
||||
{ value: "ARCHIVE1DAY", nameKey: "archive1Day" },
|
||||
{ value: "ARCHIVE_DEVICE", nameKey: "archiveDevice" }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "解除处罚",
|
||||
nameKey: "releasePunishment",
|
||||
options: [
|
||||
{ value: "UNTIE_ACOOUNT", name: "账号解封" },
|
||||
{ value: "UNTIE_DEVICE", name: "设备解封" },
|
||||
{ value: "UNTIE_DEVICE_AND_ACCOUNT", name: "设备+账号解封" }
|
||||
{ value: "UNTIE_ACOOUNT", nameKey: "untieAccount" },
|
||||
{ value: "UNTIE_DEVICE", nameKey: "untieDevice" },
|
||||
{ value: "UNTIE_DEVICE_AND_ACCOUNT", nameKey: "untieDeviceAndAccount" }
|
||||
]
|
||||
}
|
||||
],
|
||||
@ -156,26 +141,42 @@ export default {
|
||||
descriptionTranslate: "",
|
||||
beApprovalUserId: ""
|
||||
},
|
||||
formRules: {
|
||||
description: commonRules,
|
||||
days: commonRules,
|
||||
accountStatusEnum: commonRules
|
||||
},
|
||||
accountStatusTypes: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["buttonPermissions"]),
|
||||
localizedFormRules() {
|
||||
const commonRules = [this.getRequiredRule()];
|
||||
return {
|
||||
description: commonRules,
|
||||
days: commonRules,
|
||||
accountStatusEnum: commonRules
|
||||
};
|
||||
},
|
||||
dayOptions() {
|
||||
return ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "15", "30"].map(
|
||||
value => ({
|
||||
value,
|
||||
label: this.getDayLabel(value)
|
||||
})
|
||||
);
|
||||
},
|
||||
accountStatus() {
|
||||
const that = this;
|
||||
const result = [];
|
||||
that.accountStatusTypes = [];
|
||||
that.accountStatusGroup.forEach(row => {
|
||||
const newRow = deepClone(row);
|
||||
newRow.name = that.$t(`pages.accountHandle.group.${row.nameKey}`);
|
||||
result.push(newRow);
|
||||
newRow.options = [];
|
||||
row.options.forEach(item => {
|
||||
if (that.buttonPermissions.includes(`user:account:${item.value}`)) {
|
||||
newRow.options.push(item);
|
||||
newRow.options.push({
|
||||
...item,
|
||||
name: that.$t(`pages.accountHandle.status.${item.nameKey}`)
|
||||
});
|
||||
that.accountStatusTypes.push(item);
|
||||
}
|
||||
});
|
||||
@ -194,6 +195,21 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getRequiredRule() {
|
||||
return {
|
||||
required: true,
|
||||
message: this.$t("pages.accountHandle.validation.requiredField"),
|
||||
trigger: "blur"
|
||||
};
|
||||
},
|
||||
getDayLabel(day) {
|
||||
return this.$t(
|
||||
Number(day) === 1
|
||||
? "pages.accountHandle.word.daySingle"
|
||||
: "pages.accountHandle.word.dayPlural",
|
||||
{ days: day }
|
||||
);
|
||||
},
|
||||
loadAccountStatus(userId) {
|
||||
const that = this;
|
||||
that.loadingAccountStatus = true;
|
||||
@ -263,11 +279,11 @@ export default {
|
||||
that.loadingTranslate = false;
|
||||
that.form.descriptionTranslate = res.body;
|
||||
if (res.status === 3001) {
|
||||
that.$opsMessage.fail("相同语言");
|
||||
that.$opsMessage.fail(this.$t("pages.accountHandle.message.sameLanguage"));
|
||||
return;
|
||||
}
|
||||
if (res.status === 3003) {
|
||||
that.$opsMessage.fail("没有找到合适的语言");
|
||||
that.$opsMessage.fail(this.$t("pages.accountHandle.message.noSuitableLanguage"));
|
||||
return;
|
||||
}
|
||||
that.disabledTranslate = true;
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="user-input">
|
||||
<el-input v-model.trim="inputValue" clearable :disabled="!sysOriginVal" :placeholder="placeholder" class="input-with-select" @input="handleInput">
|
||||
<el-select slot="prepend" v-model="selectType" placeholder="类型" :disabled="!sysOriginVal" @change="selectTypeChange">
|
||||
<el-option label="短ID" value="SHORT" />
|
||||
<el-option label="长ID" value="LONG" />
|
||||
<el-select slot="prepend" v-model="selectType" :placeholder="$t('pages.accountInput.placeholder.type')" :disabled="!sysOriginVal" @change="selectTypeChange">
|
||||
<el-option :label="$t('pages.accountInput.option.shortId')" value="SHORT" />
|
||||
<el-option :label="$t('pages.accountInput.option.longId')" value="LONG" />
|
||||
</el-select>
|
||||
|
||||
<el-select v-if="showSysOriginTypeSelect && selectType !== 'LONG' && permissionsSysOriginPlatforms.length > 0" slot="append" v-model="sysOriginType" placeholder="平台" @change="sysOriginTypeChange">
|
||||
<el-select v-if="showSysOriginTypeSelect && selectType !== 'LONG' && permissionsSysOriginPlatforms.length > 0" slot="append" v-model="sysOriginType" :placeholder="$t('pages.accountInput.placeholder.platform')" @change="sysOriginTypeChange">
|
||||
<el-option
|
||||
v-for="item in permissionsSysOriginPlatforms"
|
||||
:key="item.value"
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="edit-user-gold-coin-deduction-form">
|
||||
<el-dialog
|
||||
title="奖励用户钻石"
|
||||
:title="$t('pages.editUserDiamondRewardForm.dialog.title')"
|
||||
:visible="true"
|
||||
width="450px"
|
||||
:before-close="handleClose"
|
||||
@ -15,31 +15,31 @@
|
||||
label-width="70px"
|
||||
style="width: 300px; margin-left:50px;"
|
||||
>
|
||||
<el-form-item label="钻石" prop="candy">
|
||||
<el-form-item :label="$t('pages.propsSourceGroupForm.resourceType.diamond')" prop="candy">
|
||||
<el-input
|
||||
v-model.trim="formData.candy"
|
||||
placeholder="需要奖励的钻石数量"
|
||||
:placeholder="$t('pages.editUserDiamondRewardForm.placeholder.diamondQuantity')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-form-item :label="$t('pages.editUserDiamondRewardForm.form.remarks')" prop="remarks">
|
||||
<el-input
|
||||
v-model.trim="formData.remarks"
|
||||
placeholder="奖励钻石的原因"
|
||||
:placeholder="$t('pages.editUserDiamondRewardForm.placeholder.reason')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="handleClose()">
|
||||
取消
|
||||
{{ $t('pages.editUserDiamondRewardForm.action.cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-loading="listLoading"
|
||||
type="primary"
|
||||
@click="handleSubmit()"
|
||||
>
|
||||
提交
|
||||
{{ $t('pages.editUserDiamondRewardForm.action.submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
@ -64,12 +64,12 @@ export default {
|
||||
candy: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入金额',
|
||||
message: this.$t('pages.propsSourceGroupForm.validation.requiredField'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
pattern: /^\d{1,7}(\.\d{0,2})?$/,
|
||||
message: 'double范围0~9999999小数最多两位',
|
||||
message: this.$t('pages.editUserDiamondRewardForm.validation.amountRange'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="edit-user-form">
|
||||
<el-drawer
|
||||
title="编辑用户"
|
||||
:title="$t('pages.editUserForm.dialog.title')"
|
||||
:visible="true"
|
||||
:before-close="handleClose"
|
||||
:close-on-press-escape="false"
|
||||
@ -20,38 +20,38 @@
|
||||
label-position="left"
|
||||
label-width="70px"
|
||||
>
|
||||
<el-form-item label="昵称" prop="userNickname">
|
||||
<el-form-item :label="$t('pages.editUserForm.form.nickname')" prop="userNickname">
|
||||
<el-input
|
||||
v-model.trim="formData.userNickname"
|
||||
placeholder="请输入用户昵称"
|
||||
:placeholder="$t('pages.editUserForm.placeholder.nickname')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="性别" prop="userSex">
|
||||
<el-form-item :label="$t('pages.editUserForm.form.gender')" prop="userSex">
|
||||
<el-select
|
||||
v-model="formData.userSex"
|
||||
placeholder="请选择性别"
|
||||
:placeholder="$t('pages.editUserForm.placeholder.gender')"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in genders"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:label="getGenderLabel(item.value)"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item :label="'年龄'" prop="email">
|
||||
<el-form-item :label="$t('pages.userBaseInfo.labels.age')" prop="email">
|
||||
<el-date-picker
|
||||
v-model="formAgeDate"
|
||||
style="width: 100%;"
|
||||
type="date"
|
||||
placeholder="选择出生日期"
|
||||
:placeholder="$t('pages.editUserForm.placeholder.birthDate')"
|
||||
value-format="yyyy-MM-dd"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="'国家'" prop="email">
|
||||
<el-form-item :label="$t('pages.userBaseInfo.labels.country')" prop="email">
|
||||
<contry-select
|
||||
v-if="formData.countryId"
|
||||
v-model="formData.countryId"
|
||||
@ -61,8 +61,8 @@
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="drawer-footer">
|
||||
<el-button @click="handleClose()">关闭</el-button>
|
||||
<el-button type="primary" @click="handleSubmit()">提交</el-button>
|
||||
<el-button @click="handleClose()">{{ $t('pages.editUserForm.action.close') }}</el-button>
|
||||
<el-button type="primary" @click="handleSubmit()">{{ $t('pages.editUserForm.action.submit') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
@ -91,11 +91,15 @@ export default {
|
||||
userNickname: [
|
||||
{
|
||||
required: true,
|
||||
message: '用户昵称必填',
|
||||
message: this.$t('pages.editUserForm.validation.nicknameRequired'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
],
|
||||
userSex: [{ required: true, message: '性别必填', trigger: 'blur' }]
|
||||
userSex: [{
|
||||
required: true,
|
||||
message: this.$t('pages.editUserForm.validation.genderRequired'),
|
||||
trigger: 'blur'
|
||||
}]
|
||||
},
|
||||
formData: {
|
||||
userNickname: '',
|
||||
@ -135,6 +139,11 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getGenderLabel(value) {
|
||||
return value === 0
|
||||
? this.$t('pages.userBaseInfo.words.female')
|
||||
: this.$t('pages.userBaseInfo.words.male')
|
||||
},
|
||||
renderData() {
|
||||
const that = this
|
||||
that.listLoading = true
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="edit-user-gold-coin-deduction-form">
|
||||
<el-dialog
|
||||
title="扣除用户游戏券"
|
||||
:title="$t('pages.editUserGameCouponDeductionForm.dialog.title')"
|
||||
:visible="true"
|
||||
width="450px"
|
||||
:before-close="handleClose"
|
||||
@ -15,31 +15,31 @@
|
||||
label-width="70px"
|
||||
style="width: 300px; margin-left:50px;"
|
||||
>
|
||||
<el-form-item label="游戏券" prop="coupon">
|
||||
<el-form-item :label="$t('pages.editUserGameCouponDeductionForm.form.gameCoupon')" prop="coupon">
|
||||
<el-input
|
||||
v-model.trim="formData.coupon"
|
||||
placeholder="需要扣除的游戏券数量"
|
||||
:placeholder="$t('pages.editUserGameCouponDeductionForm.placeholder.gameCouponQuantity')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-form-item :label="$t('pages.editUserGameCouponDeductionForm.form.remarks')" prop="remarks">
|
||||
<el-input
|
||||
v-model.trim="formData.remarks"
|
||||
placeholder="扣除游戏券的原因"
|
||||
:placeholder="$t('pages.editUserGameCouponDeductionForm.placeholder.remarks')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="handleClose()">
|
||||
取消
|
||||
{{ $t('pages.editUserGameCouponDeductionForm.action.cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-loading="listLoading"
|
||||
type="primary"
|
||||
@click="handleSubmit()"
|
||||
>
|
||||
提交
|
||||
{{ $t('pages.editUserGameCouponDeductionForm.action.submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
@ -64,12 +64,12 @@ export default {
|
||||
coupon: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入金额',
|
||||
message: this.$t('pages.editUserGameCouponDeductionForm.validation.enterAmount'),
|
||||
trigger: 'blur'
|
||||
},
|
||||
{
|
||||
pattern: /^\d{1,7}(\.\d{0,2})?$/,
|
||||
message: 'double范围0~9999999小数最多两位',
|
||||
message: this.$t('pages.editUserGameCouponDeductionForm.validation.amountRange'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="edit-user-gold-coin-reward-form">
|
||||
<el-dialog
|
||||
title="奖励用户金币"
|
||||
:title="$t('pages.editUserGoldCoinRewardForm.dialog.title')"
|
||||
:visible="true"
|
||||
width="450px"
|
||||
:before-close="handleClose"
|
||||
@ -16,41 +16,47 @@
|
||||
style="width: 300px; margin-left:50px;"
|
||||
>
|
||||
<!-- 类型选择 下拉框 -->
|
||||
<el-form-item label="类型" prop="rewardType">
|
||||
<el-form-item :label="$t('pages.editUserGoldCoinRewardForm.form.type')" prop="rewardType">
|
||||
<el-select
|
||||
v-model="formData.rewardType"
|
||||
placeholder="请选择"
|
||||
:placeholder="$t('pages.editUserGoldCoinRewardForm.placeholder.select')"
|
||||
style="width: 100%;"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in currencyRewardReasons"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:label="getRewardTypeLabel(item.value)"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 金币数量 输入框 -->
|
||||
<el-form-item label="金币" prop="candy">
|
||||
<el-form-item :label="$t('pages.userBaseInfo.labels.gold')" prop="candy">
|
||||
<el-input
|
||||
v-model.trim="formData.candy"
|
||||
placeholder="需要奖励的金币数量"
|
||||
:placeholder="$t('pages.editUserGoldCoinRewardForm.placeholder.goldQuantity')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 美金 输入框 -->
|
||||
<el-form-item
|
||||
v-if="formData.rewardType == 3 || formData.rewardType == 4"
|
||||
label="美金"
|
||||
:label="$t('pages.editUserGoldCoinRewardForm.form.usd')"
|
||||
prop="usdCandy"
|
||||
>
|
||||
<el-input v-model.trim="formData.usdCandy" placeholder="美金数量" />
|
||||
<el-input
|
||||
v-model.trim="formData.usdCandy"
|
||||
:placeholder="$t('pages.editUserGoldCoinRewardForm.placeholder.usdQuantity')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 备注 输入框 -->
|
||||
<el-form-item label="备注" prop="remarks">
|
||||
<el-input v-model.trim="formData.remarks" placeholder="奖励备注" />
|
||||
<el-form-item :label="$t('pages.editUserGoldCoinRewardForm.form.remarks')" prop="remarks">
|
||||
<el-input
|
||||
v-model.trim="formData.remarks"
|
||||
:placeholder="$t('pages.editUserGoldCoinRewardForm.placeholder.remarks')"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
@ -58,7 +64,7 @@
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<!-- 取消按钮 -->
|
||||
<el-button @click="handleClose()">
|
||||
取消
|
||||
{{ $t('pages.editUserGoldCoinRewardForm.action.cancel') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 提交按钮 -->
|
||||
@ -67,7 +73,7 @@
|
||||
type="primary"
|
||||
@click="handleSubmit()"
|
||||
>
|
||||
提交
|
||||
{{ $t('pages.editUserGoldCoinRewardForm.action.submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
@ -94,26 +100,26 @@ export default {
|
||||
candy: [
|
||||
{
|
||||
required: true,
|
||||
message: "必填字段不可为空",
|
||||
message: this.$t("pages.propsSourceGroupForm.validation.requiredField"),
|
||||
trigger: "blur"
|
||||
},
|
||||
{
|
||||
pattern: /^\d{1,7}(\.\d{0,2})?$/,
|
||||
message: "double范围0~9999999小数最多两位",
|
||||
message: this.$t("pages.editUserGoldCoinRewardForm.validation.goldRange"),
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
rewardType: [
|
||||
{
|
||||
required: true,
|
||||
message: "必填字段不可为空",
|
||||
message: this.$t("pages.propsSourceGroupForm.validation.requiredField"),
|
||||
trigger: "blur"
|
||||
}
|
||||
],
|
||||
usdCandy: [
|
||||
{
|
||||
required: true,
|
||||
message: "必填字段不可为空",
|
||||
message: this.$t("pages.propsSourceGroupForm.validation.requiredField"),
|
||||
trigger: "blur"
|
||||
}
|
||||
]
|
||||
@ -127,6 +133,16 @@ export default {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
getRewardTypeLabel(value) {
|
||||
const keyMap = {
|
||||
1: "reward",
|
||||
2: "internal",
|
||||
3: "salary",
|
||||
4: "recharge",
|
||||
5: "other"
|
||||
};
|
||||
return this.$t(`pages.editUserGoldCoinRewardForm.rewardType.${keyMap[value]}`);
|
||||
},
|
||||
handleSubmit() {
|
||||
const that = this;
|
||||
that.$refs.dataForm.validate(valid => {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="gift-history-drawer">
|
||||
<el-drawer
|
||||
title="详情"
|
||||
:title="$t('pages.giftHistoryDetailsDrawer.dialog.title')"
|
||||
:visible="true"
|
||||
:before-close="handleClose"
|
||||
:close-on-press-escape="false"
|
||||
@ -12,12 +12,12 @@
|
||||
>
|
||||
<div class="gift-history-content">
|
||||
<div class="blockquote">
|
||||
发送人
|
||||
{{ $t('pages.giftHistoryDetailsDrawer.section.sender') }}
|
||||
<el-tag
|
||||
v-if="row.anchor === true"
|
||||
type="danger"
|
||||
size="mini"
|
||||
>主播</el-tag>
|
||||
>{{ $t('pages.userBaseInfo.labels.anchor') }}</el-tag>
|
||||
</div>
|
||||
<div class="content">
|
||||
<user-table-exhibit
|
||||
@ -25,7 +25,7 @@
|
||||
:query-details="true"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="row.roomProfile" class="blockquote">发送房间</div>
|
||||
<div v-if="row.roomProfile" class="blockquote">{{ $t('pages.giftHistoryDetailsDrawer.section.senderRoom') }}</div>
|
||||
<div v-if="row.roomProfile" class="content">
|
||||
<div class="flex-l" style="padding-bottom: 10px;">
|
||||
<div class="room-avatar">
|
||||
@ -53,13 +53,13 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="row.roomProfile" class="blockquote">信息快照</div>
|
||||
<div v-if="row.roomProfile" class="blockquote">{{ $t('pages.giftHistoryDetailsDrawer.section.snapshot') }}</div>
|
||||
<div class="content gift-text">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="12">礼物ID: {{ row.giftId }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.giftHistoryDetailsDrawer.label.giftId') }}: {{ row.giftId }}</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>礼物封面:
|
||||
>{{ $t('pages.giftHistoryDetailsDrawer.label.giftCover') }}:
|
||||
<el-image
|
||||
style="width: 30px; height: 30px"
|
||||
:src="row.giftCover"
|
||||
@ -69,36 +69,36 @@
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>礼物货币: {{ row.giftValue.currencyType }}</el-col>
|
||||
<el-col :span="12">礼物类型: {{ row.giftValue.giftType }}</el-col>
|
||||
<el-col :span="12">礼物单价: {{ row.giftValue.unitPrice }}</el-col>
|
||||
<el-col :span="12">礼物价值: {{ row.giftValue.giftValue }}</el-col>
|
||||
>{{ $t('pages.giftHistoryDetailsDrawer.label.giftCurrency') }}: {{ row.giftValue.currencyType }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.giftHistoryDetailsDrawer.label.giftType') }}: {{ row.giftValue.giftType }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.giftHistoryDetailsDrawer.label.giftUnitPrice') }}: {{ row.giftValue.unitPrice }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.giftHistoryDetailsDrawer.label.giftValue') }}: {{ row.giftValue.giftValue }}</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>实际价值: {{ row.giftValue.actualAmount }}</el-col>
|
||||
>{{ $t('pages.giftHistoryDetailsDrawer.label.actualAmount') }}: {{ row.giftValue.actualAmount }}</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>发送数量: {{ row.giftValue.quantity }} 个</el-col>
|
||||
>{{ $t('pages.giftHistoryDetailsDrawer.label.sendQuantity') }}: {{ row.giftValue.quantity }} {{ $t('pages.giftHistoryDetailsDrawer.word.countUnit') }}</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>接收用户: {{ row.giftValue.userSize }} 人</el-col>
|
||||
>{{ $t('pages.giftHistoryDetailsDrawer.label.acceptUsers') }}: {{ row.giftValue.userSize }} {{ $t('pages.giftHistoryDetailsDrawer.word.peopleUnit') }}</el-col>
|
||||
<!-- 这两个字段已移除(percentage&selfPercentage), 2023/4月份可移除-->
|
||||
<el-col
|
||||
v-if="row.giftValue.percentage"
|
||||
:span="12"
|
||||
>接收概率: {{ row.giftValue.percentage * 100 }}%</el-col>
|
||||
>{{ $t('pages.giftHistoryDetailsDrawer.label.acceptProbability') }}: {{ row.giftValue.percentage * 100 }}%</el-col>
|
||||
<el-col
|
||||
v-if="row.giftValue.selfPercentage"
|
||||
:span="12"
|
||||
>自己接收概率: {{ row.giftValue.selfPercentage * 100 }}%</el-col>
|
||||
>{{ $t('pages.giftHistoryDetailsDrawer.label.selfAcceptProbability') }}: {{ row.giftValue.selfPercentage * 100 }}%</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>背包: {{ row.giftValue.bag ? "Yes" : "No" }}</el-col>
|
||||
<el-col :span="12">跟踪ID: {{ row.trackId }}</el-col>
|
||||
<el-col :span="12">请求平台: {{ row.requestPlatform }}</el-col>
|
||||
>{{ $t('pages.giftHistoryDetailsDrawer.label.bag') }}: {{ row.giftValue.bag ? $t('pages.userBaseInfo.words.yes') : $t('pages.userBaseInfo.words.no') }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.giftHistoryDetailsDrawer.label.trackId') }}: {{ row.trackId }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.giftHistoryDetailsDrawer.label.requestPlatform') }}: {{ row.requestPlatform }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="blockquote">接收用户</div>
|
||||
<div class="blockquote">{{ $t('pages.giftHistoryDetailsDrawer.section.receivers') }}</div>
|
||||
<div class="content">
|
||||
<div
|
||||
v-for="(item, index) in row.acceptUsers"
|
||||
@ -114,15 +114,15 @@
|
||||
v-if="item.anchor === true"
|
||||
type="danger"
|
||||
size="mini"
|
||||
>主播</el-tag>
|
||||
>{{ $t('pages.userBaseInfo.labels.anchor') }}</el-tag>
|
||||
<el-tag
|
||||
v-if="item.anchor === true"
|
||||
size="mini"
|
||||
>接收目标:{{ item.targetAmount }}</el-tag>
|
||||
<el-tag size="mini">接收金额:{{ item.acceptAmount }}</el-tag>
|
||||
>{{ $t('pages.giftHistoryDetailsDrawer.label.acceptTarget') }}: {{ item.targetAmount }}</el-tag>
|
||||
<el-tag size="mini">{{ $t('pages.giftHistoryDetailsDrawer.label.acceptAmount') }}: {{ item.acceptAmount }}</el-tag>
|
||||
<el-tag
|
||||
size="mini"
|
||||
>接收概率:
|
||||
>{{ $t('pages.giftHistoryDetailsDrawer.label.acceptProbability') }}:
|
||||
{{
|
||||
(item.acceptUserId !== row.userId
|
||||
? item.percentage
|
||||
@ -131,23 +131,23 @@
|
||||
<el-tag
|
||||
v-if="item.region"
|
||||
size="mini"
|
||||
>区域(发-接): {{ item.region
|
||||
>{{ $t('pages.giftHistoryDetailsDrawer.label.regionFlow') }}: {{ item.region
|
||||
}}<span
|
||||
v-if="item.hasOwnProperty('regionEq')"
|
||||
>、{{ item.regionEq ? "Yes" : "No" }}</span></el-tag>
|
||||
>、{{ item.regionEq ? $t('pages.userBaseInfo.words.yes') : $t('pages.userBaseInfo.words.no') }}</span></el-tag>
|
||||
<el-tag
|
||||
v-if="item.hasOwnProperty('countTargetAmount')"
|
||||
size="mini"
|
||||
>统计状态: {{ item.countTargetAmount ? "Yes" : "No" }}</el-tag>
|
||||
>{{ $t('pages.giftHistoryDetailsDrawer.label.countStatus') }}: {{ item.countTargetAmount ? $t('pages.userBaseInfo.words.yes') : $t('pages.userBaseInfo.words.no') }}</el-tag>
|
||||
<el-button
|
||||
type="text"
|
||||
size="mini"
|
||||
@click="clickCopyReceiptId(item)"
|
||||
><i class="el-icon-document-copy" />单据ID</el-button>
|
||||
><i class="el-icon-document-copy" />{{ $t('pages.giftHistoryDetailsDrawer.action.receiptId') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="blockquote">日志事件</div>
|
||||
<div class="blockquote">{{ $t('pages.giftHistoryDetailsDrawer.section.logEvents') }}</div>
|
||||
<div class="content">
|
||||
<el-timeline>
|
||||
<el-timeline-item
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="in-app-purchase-details-drawer">
|
||||
<el-drawer
|
||||
title="详情"
|
||||
:title="$t('pages.inAppPurchaseDetails.dialog.title')"
|
||||
:visible="true"
|
||||
:before-close="handleClose"
|
||||
:close-on-press-escape="false"
|
||||
@ -12,65 +12,65 @@
|
||||
>
|
||||
<div v-if="order" v-loading="orderLoading" class="in-app-purchase-details-content">
|
||||
<div v-if="orderIsNull" style="text-align: center;">
|
||||
没有更多信息
|
||||
{{ $t("pages.inAppPurchaseDetails.message.noMoreInfo") }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-if="order.acceptUserProfile" class="order-row">
|
||||
<div class="blockquote">接收用户</div>
|
||||
<div class="blockquote">{{ $t("pages.inAppPurchaseDetails.section.acceptUser") }}</div>
|
||||
<div class="content">
|
||||
<user-table-exhibit :user-profile="order.acceptUserProfile" :query-details="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="order.createUserProfile" class="order-row">
|
||||
<div class="blockquote">创建用户</div>
|
||||
<div class="blockquote">{{ $t("pages.inAppPurchaseDetails.section.createUser") }}</div>
|
||||
<div class="content">
|
||||
<user-table-exhibit :user-profile="order.createUserProfile" :query-details="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="order.createNickname" class="order-row">
|
||||
<div class="blockquote">创建用户</div>
|
||||
<div class="blockquote">{{ $t("pages.inAppPurchaseDetails.section.createUser") }}</div>
|
||||
<div class="content" style="margin-bottom: 10px;">
|
||||
{{ order.createNickname }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="order.details" class="order-row">
|
||||
<div class="blockquote">订单信息</div>
|
||||
<div class="blockquote">{{ $t("pages.inAppPurchaseDetails.section.orderInfo") }}</div>
|
||||
<div class="content">
|
||||
<div class="order-info flex-b flex-wrap">
|
||||
<div class="order-info-col">环境:
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.environment') }}:
|
||||
<el-tag v-if="order.details.env === 'PROD'" type="success" size="mini">{{ order.details.env }}</el-tag>
|
||||
<el-tag v-else-if="order.details.env === 'TEST'" type="warning" size="mini">{{ order.details.env }}</el-tag>
|
||||
<el-tag v-else type="danger" size="mini">{{ order.details.env }}</el-tag>
|
||||
</div>
|
||||
<div class="order-info-col">类型: {{ orderReceiptTypeMap[order.details.receiptType] }}</div>
|
||||
<div class="order-info-col">状态:
|
||||
<el-tag :type=" orderStatusMap[order.details.status].tagType" size="mini">{{ orderStatusMap[order.details.status].label }}</el-tag>
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.type') }}: {{ orderReceiptTypeMap[order.details.receiptType] }}</div>
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.status') }}:
|
||||
<el-tag :type="orderStatusMap[order.details.status].tagType" size="mini">{{ orderStatusMap[order.details.status].label }}</el-tag>
|
||||
</div>
|
||||
<div class="order-info-col">ID: {{ order.details.id }}</div>
|
||||
<div class="order-info-col">跟踪ID: {{ order.details.trackId }}</div>
|
||||
<div v-if="order.details.subscribeId" class="order-info-col">订阅ID: {{ order.details.subscribeId }}</div>
|
||||
<div class="order-info-col" :span="24">订单ID: {{ order.details.orderId }}</div>
|
||||
<div class="order-info-col">平台渠道:
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.id') }}: {{ order.details.id }}</div>
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.trackId') }}: {{ order.details.trackId }}</div>
|
||||
<div v-if="order.details.subscribeId" class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.subscribeId') }}: {{ order.details.subscribeId }}</div>
|
||||
<div class="order-info-col" :span="24">{{ $t('pages.inAppPurchaseDetails.label.orderId') }}: {{ order.details.orderId }}</div>
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.platformChannel') }}:
|
||||
<sys-origin-icon size="20px" :icon="order.details.sysOrigin" :desc="order.details.sysOrigin" />
|
||||
<platform-svg-icon size="20px" :icon="order.details.factory.platform" />
|
||||
<platform-svg-icon size="20px" :icon="order.details.factory.factoryCode" />
|
||||
</div>
|
||||
<div class="order-info-col">国家编号: {{ order.details.countryCode }}</div>
|
||||
<div class="order-info-col">货币类型: {{ order.details.currency }}</div>
|
||||
<div class="order-info-col">金额: {{ order.details.amount }} {{ order.details.currency }}</div>
|
||||
<div class="order-info-col">美元: {{ order.details.amountUsd }} USD</div>
|
||||
<div class="order-info-col">免费试用: {{ order.details.trialPeriod === true ? 'Yes' :'No' }}</div>
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.countryCode') }}: {{ order.details.countryCode }}</div>
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.currency') }}: {{ order.details.currency }}</div>
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.amount') }}: {{ order.details.amount }} {{ order.details.currency }}</div>
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.usd') }}: {{ order.details.amountUsd }} USD</div>
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.freeTrial') }}: {{ order.details.trialPeriod === true ? $t('pages.inAppPurchaseDetails.word.yes') : $t('pages.inAppPurchaseDetails.word.no') }}</div>
|
||||
|
||||
<div v-if="order.details.reason" class="order-info-col">原因: {{ order.details.reason }}</div>
|
||||
<div class="order-info-col">购买时间: {{ order.details.purchaseDateMs }}</div>
|
||||
<div class="order-info-col">创建时间: {{ order.details.createTime }}</div>
|
||||
<div class="order-info-col">修改时间: {{ order.details.updateTime }}</div>
|
||||
<div class="order-info-col">锁版本: {{ order.details.version }}</div>
|
||||
<div v-if="order.details.reason" class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.reason') }}: {{ order.details.reason }}</div>
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.purchaseTime') }}: {{ order.details.purchaseDateMs }}</div>
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.createdAt') }}: {{ order.details.createTime }}</div>
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.updatedAt') }}: {{ order.details.updateTime }}</div>
|
||||
<div class="order-info-col">{{ $t('pages.inAppPurchaseDetails.label.version') }}: {{ order.details.version }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="order.details && order.details.statusSteps && order.details.statusSteps.length>0" class="order-row">
|
||||
<div class="blockquote">状态流转</div>
|
||||
<div class="blockquote">{{ $t('pages.inAppPurchaseDetails.section.statusFlow') }}</div>
|
||||
<div class="content">
|
||||
<el-steps align-center :space="200" :active="order.details.statusSteps.length" finish-status="success" style="margin: 10px 0px;">
|
||||
<el-step v-for="(item, index) in order.details.statusSteps" :key="index" :title="orderStatusMap[item.status].label" :description="item.createTime" />
|
||||
@ -78,7 +78,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="order.details && order.details.products && order.details.products.length > 0" class="order-row">
|
||||
<div class="blockquote">商品信息</div>
|
||||
<div class="blockquote">{{ $t('pages.inAppPurchaseDetails.section.productInfo') }}</div>
|
||||
<div class="content">
|
||||
<div class="product-card">
|
||||
<div v-if="order.details.productDescriptor" class="prodcut-desc">
|
||||
@ -91,13 +91,13 @@
|
||||
</div>
|
||||
<div class="product-info">
|
||||
<el-row>
|
||||
<el-col :span="12">ID: {{ item.id }}</el-col>
|
||||
<el-col :span="12">名称: {{ item.name }}</el-col>
|
||||
<el-col :span="12">编号: {{ item.code }}</el-col>
|
||||
<el-col :span="12">内容: {{ item.content }}</el-col>
|
||||
<el-col :span="12">金额: {{ item.amountUsd }} USD</el-col>
|
||||
<el-col :span="12">数量: {{ item.quantity }}</el-col>
|
||||
<el-col :span="24">描述: {{ item.describe }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.inAppPurchaseDetails.label.id') }}: {{ item.id }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.inAppPurchaseDetails.label.name') }}: {{ item.name }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.inAppPurchaseDetails.label.code') }}: {{ item.code }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.inAppPurchaseDetails.label.content') }}: {{ item.content }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.inAppPurchaseDetails.label.amount') }}: {{ item.amountUsd }} USD</el-col>
|
||||
<el-col :span="12">{{ $t('pages.inAppPurchaseDetails.label.quantity') }}: {{ item.quantity }}</el-col>
|
||||
<el-col :span="24">{{ $t('pages.inAppPurchaseDetails.label.description') }}: {{ item.describe }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
@ -106,21 +106,21 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="order.details && order.details.metadata && Object.keys(order.details.metadata).length > 0" class="order-row">
|
||||
<div class="blockquote">元数据</div>
|
||||
<div class="blockquote">{{ $t('pages.inAppPurchaseDetails.section.metadata') }}</div>
|
||||
<div class="content">
|
||||
<el-table
|
||||
:data="metadataList"
|
||||
element-loading-text="Loading"
|
||||
:element-loading-text="$t('pages.inAppPurchaseDetails.message.loading')"
|
||||
fit
|
||||
highlight-current-row
|
||||
>
|
||||
<el-table-column prop="key" label="字段" align="center" />
|
||||
<el-table-column prop="value" label="值" align="center" />
|
||||
<el-table-column prop="key" :label="$t('pages.inAppPurchaseDetails.label.field')" align="center" />
|
||||
<el-table-column prop="value" :label="$t('pages.inAppPurchaseDetails.label.value')" align="center" />
|
||||
</el-table>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="order.details && order.details.payNotices" class="order-row">
|
||||
<div class="blockquote">事件通知</div>
|
||||
<div class="blockquote">{{ $t('pages.inAppPurchaseDetails.section.eventNotice') }}</div>
|
||||
<div class="content">
|
||||
<el-timeline :reverse="true">
|
||||
<el-timeline-item
|
||||
@ -130,8 +130,8 @@
|
||||
:timestamp="item.createTime"
|
||||
>
|
||||
<div class="event-info">
|
||||
<div class="event-info-item">事件ID: {{ item.eventId }}</div>
|
||||
<div class="event-info-item">事件类型: {{ item.noticeType }}</div>
|
||||
<div class="event-info-item">{{ $t('pages.inAppPurchaseDetails.label.eventId') }}: {{ item.eventId }}</div>
|
||||
<div class="event-info-item">{{ $t('pages.inAppPurchaseDetails.label.eventType') }}: {{ item.noticeType }}</div>
|
||||
</div>
|
||||
<div class="request-data">
|
||||
<json-editor v-model="item.noticeData" :read-only="true" />
|
||||
@ -163,40 +163,48 @@ export default {
|
||||
return {
|
||||
orderLoading: false,
|
||||
order: {},
|
||||
orderIsNull: false,
|
||||
orderReceiptTypeMap: {
|
||||
'PAYMENT': '付款',
|
||||
'RECEIPT': '收款'
|
||||
},
|
||||
orderStatusMap: {
|
||||
'CREATE': {
|
||||
label: '创建',
|
||||
tagType: ''
|
||||
},
|
||||
'SUCCESS': {
|
||||
label: '成功',
|
||||
tagType: 'success'
|
||||
},
|
||||
'FAIL': {
|
||||
label: '失败',
|
||||
tagType: 'danger'
|
||||
},
|
||||
'CANCEL': {
|
||||
label: '取消',
|
||||
tagType: 'info'
|
||||
},
|
||||
'HANG': {
|
||||
label: '挂起',
|
||||
tagType: 'warning'
|
||||
},
|
||||
'REFUND': {
|
||||
label: '退款',
|
||||
tagType: 'danger'
|
||||
}
|
||||
}
|
||||
orderIsNull: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
orderReceiptTypeMap() {
|
||||
const locale = this.$i18n.locale
|
||||
void locale
|
||||
return {
|
||||
PAYMENT: this.$t('pages.inAppPurchaseDetails.receiptType.payment'),
|
||||
RECEIPT: this.$t('pages.inAppPurchaseDetails.receiptType.receipt')
|
||||
}
|
||||
},
|
||||
orderStatusMap() {
|
||||
const locale = this.$i18n.locale
|
||||
void locale
|
||||
return {
|
||||
CREATE: {
|
||||
label: this.$t('pages.inAppPurchaseDetails.status.create'),
|
||||
tagType: ''
|
||||
},
|
||||
SUCCESS: {
|
||||
label: this.$t('pages.inAppPurchaseDetails.status.success'),
|
||||
tagType: 'success'
|
||||
},
|
||||
FAIL: {
|
||||
label: this.$t('pages.inAppPurchaseDetails.status.fail'),
|
||||
tagType: 'danger'
|
||||
},
|
||||
CANCEL: {
|
||||
label: this.$t('pages.inAppPurchaseDetails.status.cancel'),
|
||||
tagType: 'info'
|
||||
},
|
||||
HANG: {
|
||||
label: this.$t('pages.inAppPurchaseDetails.status.hang'),
|
||||
tagType: 'warning'
|
||||
},
|
||||
REFUND: {
|
||||
label: this.$t('pages.inAppPurchaseDetails.status.refund'),
|
||||
tagType: 'danger'
|
||||
}
|
||||
}
|
||||
},
|
||||
metadataList() {
|
||||
if (!this.order.details || !this.order.details.metadata) {
|
||||
return []
|
||||
@ -213,7 +221,7 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
orderId: {
|
||||
handler(newVal) {
|
||||
handler() {
|
||||
this.loadInAppPurchase()
|
||||
},
|
||||
immediate: true
|
||||
@ -230,7 +238,7 @@ export default {
|
||||
that.orderLoading = false
|
||||
that.order = res.body || {}
|
||||
that.orderIsNull = !(that.order && that.order.details && that.order.details.id)
|
||||
}).catch(er => {
|
||||
}).catch(() => {
|
||||
that.orderLoading = false
|
||||
})
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<el-dialog
|
||||
v-loading="loading"
|
||||
title="Apple 内购订阅"
|
||||
:title="$t('pages.inappPurchaseApple.dialog.title')"
|
||||
:visible="true"
|
||||
width="60%"
|
||||
:before-close="handleClose"
|
||||
@ -11,70 +11,70 @@
|
||||
<div class="sub-block">
|
||||
<el-timeline :hide-timestamp="true">
|
||||
<el-timeline-item :type="reimburseDot">
|
||||
<h3>购买记录(站内)</h3>
|
||||
<h3>{{ $t('pages.inappPurchaseApple.section.purchaseRecord') }}</h3>
|
||||
<el-card>
|
||||
<div class="typesetting">
|
||||
<div class="line">
|
||||
<div class="label">环境:{{ purchaseHistory.evn }}</div>
|
||||
<div class="label">原事务ID:{{ purchaseHistory.originalOrderId }}</div>
|
||||
<div class="label">过期时间:{{ purchaseHistory.expiresDateMs }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.environment') }}:{{ purchaseHistory.evn }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.originalTransactionId') }}:{{ purchaseHistory.originalOrderId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.expireTime') }}:{{ purchaseHistory.expiresDateMs }}</div>
|
||||
</div>
|
||||
|
||||
<div class="line">
|
||||
<div class="label">来源平台:{{ purchaseHistory.platform }}</div>
|
||||
<div class="label">事务ID:{{ purchaseHistory.orderId }}</div>
|
||||
<div class="label">购买时间:{{ purchaseHistory.purchaseDateMs }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.sourcePlatform') }}:{{ purchaseHistory.platform }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.transactionId') }}:{{ purchaseHistory.orderId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.purchaseTime') }}:{{ purchaseHistory.purchaseDateMs }}</div>
|
||||
</div>
|
||||
|
||||
<div class="line">
|
||||
<div class="label">购买事件:{{ purchaseHistory.event }}</div>
|
||||
<div class="label">单价:{{ purchaseHistory.unitPrice }} ({{ purchaseHistory.unit }})</div>
|
||||
<div class="label">创建时间:{{ purchaseHistory.createTime }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.purchaseEvent') }}:{{ purchaseHistory.event }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.unitPrice') }}:{{ purchaseHistory.unitPrice }} ({{ purchaseHistory.unit }})</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.createdAt') }}:{{ purchaseHistory.createTime }}</div>
|
||||
</div>
|
||||
|
||||
<div class="line">
|
||||
<div class="label">站内产品ID:{{ purchaseHistory.purchaseProductId }}</div>
|
||||
<div class="label">订单状态:{{ purchaseHistory.status }}</div>
|
||||
<div class="label">修改时间:{{ purchaseHistory.updateTime }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.internalProductId') }}:{{ purchaseHistory.purchaseProductId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.orderStatus') }}:{{ purchaseHistory.status }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.updatedAt') }}:{{ purchaseHistory.updateTime }}</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="label">APPLE产品ID:{{ purchaseHistory.productId }}</div>
|
||||
<div class="label">产品类型:{{ purchaseHistory.productType }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.appleProductId') }}:{{ purchaseHistory.productId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.productType') }}:{{ purchaseHistory.productType }}</div>
|
||||
<div class="label" />
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
<el-timeline-item>
|
||||
<h3>等待续费订阅(Apple)</h3>
|
||||
<h3>{{ $t('pages.inappPurchaseApple.section.pendingRenewal') }}</h3>
|
||||
<el-card>
|
||||
<div class="typesetting">
|
||||
<div class="line">
|
||||
<div class="label">原事务ID:{{ pendingRenewalInfo.originalTransactionId }}</div>
|
||||
<div class="label">产品ID:{{ pendingRenewalInfo.productId }}</div>
|
||||
<div class="label">自动续费产品ID:{{ pendingRenewalInfo.autoRenewProductId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.originalTransactionId') }}:{{ pendingRenewalInfo.originalTransactionId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.productId') }}:{{ pendingRenewalInfo.productId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.autoRenewProductId') }}:{{ pendingRenewalInfo.autoRenewProductId }}</div>
|
||||
</div>
|
||||
|
||||
<div class="line">
|
||||
<div class="label">自动续费状态:{{ autoRenewStatusName }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.autoRenewStatus') }}:{{ autoRenewStatusName }}</div>
|
||||
<div class="label">
|
||||
努力续费中:{{ inBillingRetryPeriodName }}
|
||||
<el-tooltip class="item" effect="dark" content="可能由于计费周期问题,Apple正在努力尝试自动订阅中">
|
||||
{{ $t('pages.inappPurchaseApple.label.inBillingRetryPeriod') }}:{{ inBillingRetryPeriodName }}
|
||||
<el-tooltip class="item" effect="dark" :content="$t('pages.inappPurchaseApple.tooltip.retryPeriod')">
|
||||
<i class="el-icon-question" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="label">续订宽限到期时间:{{ pendingRenewalInfo.gracePeriodExpiresDateMs }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.gracePeriodExpiresAt') }}:{{ pendingRenewalInfo.gracePeriodExpiresDateMs }}</div>
|
||||
</div>
|
||||
|
||||
<div class="line">
|
||||
<div class="label">订阅过期原因:{{ pendingRenewalInfo.expirationIntent }}
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.expirationReason') }}:{{ pendingRenewalInfo.expirationIntent }}
|
||||
<el-tooltip class="item" effect="dark">
|
||||
<div slot="content">
|
||||
<p>1.客户自愿取消订阅</p>
|
||||
<p>2.帐单错误;例如,客户的付款信息不再有效</p>
|
||||
<p>3.客户不同意最近涨价</p>
|
||||
<p>4.产品更新时无法购买</p>
|
||||
<p>5.未知错误</p>
|
||||
<p>{{ $t('pages.inappPurchaseApple.tooltip.expirationReason1') }}</p>
|
||||
<p>{{ $t('pages.inappPurchaseApple.tooltip.expirationReason2') }}</p>
|
||||
<p>{{ $t('pages.inappPurchaseApple.tooltip.expirationReason3') }}</p>
|
||||
<p>{{ $t('pages.inappPurchaseApple.tooltip.expirationReason4') }}</p>
|
||||
<p>{{ $t('pages.inappPurchaseApple.tooltip.expirationReason5') }}</p>
|
||||
</div>
|
||||
<i class="el-icon-question" />
|
||||
</el-tooltip>
|
||||
@ -84,58 +84,58 @@
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
<el-timeline-item>
|
||||
<h3>单据信息(Apple)</h3>
|
||||
<h3>{{ $t('pages.inappPurchaseApple.section.receiptInfo') }}</h3>
|
||||
<el-card>
|
||||
<div class="typesetting">
|
||||
<div class="line">
|
||||
<div class="label">取消时间:{{ latestReceipt.cancellationDateMs }}
|
||||
<el-tooltip class="item" effect="dark" content="此字段仅适用于已退款的交易。">
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.cancellationTime') }}:{{ latestReceipt.cancellationDateMs }}
|
||||
<el-tooltip class="item" effect="dark" :content="$t('pages.inappPurchaseApple.tooltip.cancellationTime')">
|
||||
<i class="el-icon-question" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="label">产品ID:{{ latestReceipt.productId }}</div>
|
||||
<div class="label">到期时间:{{ latestReceipt.expiresDateMs }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.productId') }}:{{ latestReceipt.productId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.expireTime') }}:{{ latestReceipt.expiresDateMs }}</div>
|
||||
</div>
|
||||
|
||||
<div class="line">
|
||||
<div class="label">取消原因:{{ latestReceipt.cancellationReason }}
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.cancellationReason') }}:{{ latestReceipt.cancellationReason }}
|
||||
<el-tooltip class="item" effect="dark">
|
||||
<div slot="content">
|
||||
<p> 0) 表示交易因其他原因被取消;例如,如果客户是意外购买的。</p>
|
||||
<p> 1) 表示客户因应用程序中的实际或感知问题而取消了交易。</p>
|
||||
<p>{{ $t('pages.inappPurchaseApple.tooltip.cancellationReason0') }}</p>
|
||||
<p>{{ $t('pages.inappPurchaseApple.tooltip.cancellationReason1') }}</p>
|
||||
</div>
|
||||
<i class="el-icon-question" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="label">原事务ID:{{ latestReceipt.transactionId }}</div>
|
||||
<div class="label">原购买时间:{{ dateFormat(latestReceipt.originalPurchaseDateMs) }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.originalTransactionId') }}:{{ latestReceipt.transactionId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.originalPurchaseTime') }}:{{ dateFormat(latestReceipt.originalPurchaseDateMs) }}</div>
|
||||
</div>
|
||||
|
||||
<div class="line">
|
||||
<div class="label">所属订阅组:{{ latestReceipt.subscriptionGroupIdentifier }}</div>
|
||||
<div class="label">事务ID:{{ latestReceipt.transactionId }}</div>
|
||||
<div class="label">购买时间:{{ latestReceipt.purchaseDateMs }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.subscriptionGroup') }}:{{ latestReceipt.subscriptionGroupIdentifier }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.transactionId') }}:{{ latestReceipt.transactionId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.purchaseTime') }}:{{ latestReceipt.purchaseDateMs }}</div>
|
||||
</div>
|
||||
|
||||
<div class="line">
|
||||
<div class="label">网格列ID:{{ latestReceipt.webOrderLineItemId }}</div>
|
||||
<div class="label">创建时间:{{ latestReceipt.createTime }}</div>
|
||||
<div class="label">修改时间:{{ latestReceipt.updateTime }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.webOrderLineItemId') }}:{{ latestReceipt.webOrderLineItemId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.createdAt') }}:{{ latestReceipt.createTime }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.updatedAt') }}:{{ latestReceipt.updateTime }}</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="label">免费试用:{{ latestReceipt.trialPeriod === true ? '是' : '否' }}</div>
|
||||
<div class="label"><el-button type="text" @click="openUrl('status')">收据状态</el-button>:{{ latestReceipt.status }}
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.trialPeriod') }}:{{ latestReceipt.trialPeriod === true ? $t('pages.inappPurchaseApple.word.yes') : $t('pages.inappPurchaseApple.word.no') }}</div>
|
||||
<div class="label"><el-button type="text" @click="openUrl('status')">{{ $t('pages.inappPurchaseApple.action.receiptStatus') }}</el-button>:{{ latestReceipt.status }}
|
||||
<el-tooltip class="item" effect="dark">
|
||||
<div slot="content">
|
||||
<p> 如果收据有效,则为0;如果有错误,则为状态码。 </p>
|
||||
<p> 状态代码反映了整个应用收据的状态。</p>
|
||||
<p> 点击标题查看详细信息</p>
|
||||
<p>{{ $t('pages.inappPurchaseApple.tooltip.receiptStatus1') }}</p>
|
||||
<p>{{ $t('pages.inappPurchaseApple.tooltip.receiptStatus2') }}</p>
|
||||
<p>{{ $t('pages.inappPurchaseApple.tooltip.receiptStatus3') }}</p>
|
||||
</div>
|
||||
<i class="el-icon-question" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="label">Base64单据:<el-button type="text" @click="copyReceipt($event)">点击复制</el-button></div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseApple.label.base64Receipt') }}:<el-button type="text" @click="copyReceipt($event)">{{ $t('pages.inappPurchaseApple.action.copy') }}</el-button></div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
@ -164,7 +164,9 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
inBillingRetryPeriodName() {
|
||||
return this.apple.pendingRenewalInfo && this.apple.pendingRenewalInfo.inBillingRetryPeriod === true ? '是' : '否'
|
||||
return this.apple.pendingRenewalInfo && this.apple.pendingRenewalInfo.inBillingRetryPeriod === true
|
||||
? this.$t('pages.inappPurchaseApple.word.yes')
|
||||
: this.$t('pages.inappPurchaseApple.word.no')
|
||||
},
|
||||
purchaseHistory() {
|
||||
return this.apple.purchaseHistory || {}
|
||||
@ -179,7 +181,9 @@ export default {
|
||||
return this.latestReceipt && this.apple.cancellationDateMs ? 'danger' : ''
|
||||
},
|
||||
autoRenewStatusName() {
|
||||
return this.pendingRenewalInfo.autoRenewStatus === true ? '订阅中' : '已取消'
|
||||
return this.pendingRenewalInfo.autoRenewStatus === true
|
||||
? this.$t('pages.inappPurchaseApple.word.subscribing')
|
||||
: this.$t('pages.inappPurchaseApple.word.cancelled')
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<el-dialog
|
||||
v-loading="loading"
|
||||
title="Google 内购订阅"
|
||||
:title="$t('pages.inappPurchaseGoogle.dialog.title')"
|
||||
:visible="true"
|
||||
width="60%"
|
||||
:before-close="handleClose"
|
||||
@ -11,75 +11,75 @@
|
||||
<div class="sub-block">
|
||||
<el-timeline :hide-timestamp="true">
|
||||
<el-timeline-item :type="reimburseDot">
|
||||
<h3>购买记录(站内)</h3>
|
||||
<h3>{{ $t('pages.inappPurchaseGoogle.section.purchaseRecord') }}</h3>
|
||||
<el-card>
|
||||
<div class="typesetting">
|
||||
<div class="line">
|
||||
<div class="label">环境:{{ purchaseHistory.evn }}</div>
|
||||
<div class="label">原事务ID:{{ purchaseHistory.originalOrderId }}</div>
|
||||
<div class="label">过期时间:{{ purchaseHistory.expiresDateMs }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.environment') }}:{{ purchaseHistory.evn }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.originalTransactionId') }}:{{ purchaseHistory.originalOrderId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.expireTime') }}:{{ purchaseHistory.expiresDateMs }}</div>
|
||||
</div>
|
||||
|
||||
<div class="line">
|
||||
<div class="label">来源平台:{{ purchaseHistory.platform }}</div>
|
||||
<div class="label">事务ID:{{ purchaseHistory.orderId }}</div>
|
||||
<div class="label">购买时间:{{ purchaseHistory.purchaseDateMs }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.sourcePlatform') }}:{{ purchaseHistory.platform }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.transactionId') }}:{{ purchaseHistory.orderId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.purchaseTime') }}:{{ purchaseHistory.purchaseDateMs }}</div>
|
||||
</div>
|
||||
|
||||
<div class="line">
|
||||
<div class="label">购买事件:{{ purchaseHistory.event }}</div>
|
||||
<div class="label">单价:{{ purchaseHistory.unitPrice }} ({{ purchaseHistory.unit }})</div>
|
||||
<div class="label">创建时间:{{ purchaseHistory.createTime }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.purchaseEvent') }}:{{ purchaseHistory.event }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.unitPrice') }}:{{ purchaseHistory.unitPrice }} ({{ purchaseHistory.unit }})</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.createdAt') }}:{{ purchaseHistory.createTime }}</div>
|
||||
</div>
|
||||
|
||||
<div class="line">
|
||||
<div class="label">站内产品ID:{{ purchaseHistory.purchaseProductId }}</div>
|
||||
<div class="label">订单状态:{{ purchaseHistory.status }}</div>
|
||||
<div class="label">修改时间:{{ purchaseHistory.updateTime }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.internalProductId') }}:{{ purchaseHistory.purchaseProductId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.orderStatus') }}:{{ purchaseHistory.status }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.updatedAt') }}:{{ purchaseHistory.updateTime }}</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="label">APPLE产品ID:{{ purchaseHistory.productId }}</div>
|
||||
<div class="label">产品类型:{{ purchaseHistory.productType }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.productId') }}:{{ purchaseHistory.productId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.productType') }}:{{ purchaseHistory.productType }}</div>
|
||||
<div class="label" />
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-timeline-item>
|
||||
<el-timeline-item v-if="google.latestSubscription">
|
||||
<h3>订阅单据(Google)</h3>
|
||||
<h3>{{ $t('pages.inappPurchaseGoogle.section.subscriptionReceipt') }}</h3>
|
||||
<el-card>
|
||||
<div class="typesetting">
|
||||
<div class="line">
|
||||
<div class="label">授予订阅的时间:{{ dateFormat(latestSubscription.startTimeMillis) }}</div>
|
||||
<div class="label">自动续费状态:{{ autoRenewStatusName }}</div>
|
||||
<div class="label">订单ID:{{ latestSubscription.orderId }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.subscriptionGrantedAt') }}:{{ dateFormat(latestSubscription.startTimeMillis) }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.autoRenewStatus') }}:{{ autoRenewStatusName }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.orderId') }}:{{ latestSubscription.orderId }}</div>
|
||||
</div>
|
||||
|
||||
<div class="line">
|
||||
<div class="label">订阅到期的时间:{{ dateFormat(latestSubscription.expiryTimeMillis) }} </div>
|
||||
<div class="label">订阅的购买类型:{{ latestSubscription.purchaseType }}</div>
|
||||
<div class="label">付款状:{{ latestSubscriptionPaymentStateName }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.subscriptionExpireAt') }}:{{ dateFormat(latestSubscription.expiryTimeMillis) }} </div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.subscriptionPurchaseType') }}:{{ latestSubscription.purchaseType }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.paymentState') }}:{{ latestSubscriptionPaymentStateName }}</div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="label">创建时间:{{ latestSubscription.createTime }}</div>
|
||||
<div class="label">付款国家CODE:{{ latestSubscription.countryCode }}</div>
|
||||
<div class="label">令牌:<el-button type="text" @click="copyReceipt(latestSubscription.linkedPurchaseToken)">点击复制</el-button></div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.createdAt') }}:{{ latestSubscription.createTime }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.paymentCountryCode') }}:{{ latestSubscription.countryCode }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.token') }}:<el-button type="text" @click="copyReceipt(latestSubscription.linkedPurchaseToken)">{{ $t('pages.inappPurchaseGoogle.action.copy') }}</el-button></div>
|
||||
</div>
|
||||
<div class="line">
|
||||
<div class="label">修改时间:{{ latestSubscription.updateTime }}</div>
|
||||
<div class="label">订阅被取消:{{ latestSubscription.cancelReason }}
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.updatedAt') }}:{{ latestSubscription.updateTime }}</div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.subscriptionCancelled') }}:{{ latestSubscription.cancelReason }}
|
||||
<el-tooltip class="item" effect="dark">
|
||||
<div slot="content">
|
||||
<p>0.用户取消了订阅</p>
|
||||
<p>1.例如由于计费问题,系统取消了订阅</p>
|
||||
<p>2.用新订阅替换了订阅</p>
|
||||
<p>3.开发者取消了订阅</p>
|
||||
<p>{{ $t('pages.inappPurchaseGoogle.tooltip.cancelReason0') }}</p>
|
||||
<p>{{ $t('pages.inappPurchaseGoogle.tooltip.cancelReason1') }}</p>
|
||||
<p>{{ $t('pages.inappPurchaseGoogle.tooltip.cancelReason2') }}</p>
|
||||
<p>{{ $t('pages.inappPurchaseGoogle.tooltip.cancelReason3') }}</p>
|
||||
</div>
|
||||
<i class="el-icon-question" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
<div class="label">json结构:<el-button type="text" @click="copyReceipt(latestSubscription.lastJson)">点击复制</el-button></div>
|
||||
<div class="label">{{ $t('pages.inappPurchaseGoogle.label.jsonStructure') }}:<el-button type="text" @click="copyReceipt(latestSubscription.lastJson)">{{ $t('pages.inappPurchaseGoogle.action.copy') }}</el-button></div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
@ -120,22 +120,24 @@ export default {
|
||||
return this.latestReceipt && this.google.cancellationDateMs ? 'danger' : ''
|
||||
},
|
||||
autoRenewStatusName() {
|
||||
return this.latestSubscription.autoRenewing === true ? '订阅中' : '已取消'
|
||||
return this.latestSubscription.autoRenewing === true
|
||||
? this.$t('pages.inappPurchaseGoogle.word.subscribing')
|
||||
: this.$t('pages.inappPurchaseGoogle.word.cancelled')
|
||||
},
|
||||
latestSubscriptionPaymentStateName() {
|
||||
if (this.latestSubscription.paymentState === 0) {
|
||||
return '待付款'
|
||||
return this.$t('pages.inappPurchaseGoogle.paymentState.pending')
|
||||
}
|
||||
if (this.latestSubscription.paymentState === 1) {
|
||||
return '收到付款'
|
||||
return this.$t('pages.inappPurchaseGoogle.paymentState.received')
|
||||
}
|
||||
if (this.latestSubscription.paymentState === 2) {
|
||||
return '免费试用'
|
||||
return this.$t('pages.inappPurchaseGoogle.paymentState.freeTrial')
|
||||
}
|
||||
if (this.latestSubscription.paymentState === 3) {
|
||||
return '待推迟的升级/降级'
|
||||
return this.$t('pages.inappPurchaseGoogle.paymentState.deferredUpgradeDowngrade')
|
||||
}
|
||||
return '异常'
|
||||
return this.$t('pages.inappPurchaseGoogle.paymentState.abnormal')
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@ -154,7 +156,7 @@ export default {
|
||||
},
|
||||
copyReceipt(content) {
|
||||
if (!content) {
|
||||
this.$opsMessage.info('内容为空')
|
||||
this.$opsMessage.info(this.$t('pages.inappPurchaseGoogle.message.emptyContent'))
|
||||
return
|
||||
}
|
||||
copyText(content).then(() => {
|
||||
@ -179,11 +181,14 @@ export default {
|
||||
line-height: 30px;
|
||||
.line {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.label {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space: nowrap;
|
||||
flex: 1 1 260px;
|
||||
min-width: 0;
|
||||
padding-right: 12px;
|
||||
white-space: normal;
|
||||
word-break: break-word;
|
||||
line-height: 1.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
<template>
|
||||
<div class="register-logout-count-charts">
|
||||
<div id="charts" ref="charts" :style="'width: 100%;height:'+ height +';'" />
|
||||
<div id="charts" ref="charts" :style="'width: 100%;height:' + height + ';'" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { copyText } from '@/utils'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
height: {
|
||||
@ -22,50 +24,43 @@ export default {
|
||||
charts: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['language'])
|
||||
},
|
||||
watch: {
|
||||
chartsData: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
handler() {
|
||||
if (this.charts) {
|
||||
this.charts.clear()
|
||||
this.renderCharts()
|
||||
}
|
||||
}
|
||||
},
|
||||
language() {
|
||||
if (this.charts) {
|
||||
this.charts.clear()
|
||||
this.renderCharts()
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
mounted() {
|
||||
const that = this
|
||||
that.$nextTick(() => {
|
||||
that.charts = that.$echarts.init(that.$refs.charts)
|
||||
that.renderCharts()
|
||||
this.$nextTick(() => {
|
||||
this.charts = this.$echarts.init(this.$refs.charts)
|
||||
this.renderCharts()
|
||||
window.addEventListener('resize', () => {
|
||||
that.charts.resize()
|
||||
this.charts.resize()
|
||||
})
|
||||
that.charts.on('click', param => {
|
||||
this.charts.on('click', param => {
|
||||
copyText(param.name).then(() => {
|
||||
this.$opsMessage.success()
|
||||
}).catch(er => {
|
||||
}).catch(() => {
|
||||
this.$opsMessage.fail()
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
newSeries(name, data) {
|
||||
return {
|
||||
name,
|
||||
type: 'bar',
|
||||
stack: name,
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data,
|
||||
areaStyle: {},
|
||||
barWidth: 40
|
||||
}
|
||||
},
|
||||
newRich(imageUrl) {
|
||||
return {
|
||||
height: 40,
|
||||
@ -76,7 +71,6 @@ export default {
|
||||
}
|
||||
},
|
||||
proccessData() {
|
||||
const that = this
|
||||
const charts = {
|
||||
xAxisData: [],
|
||||
seriesData: [],
|
||||
@ -87,20 +81,22 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (that.chartsData.length > 0) {
|
||||
that.chartsData.forEach(item => {
|
||||
if (this.chartsData.length > 0) {
|
||||
this.chartsData.forEach(item => {
|
||||
const propsSource = item.propsSource
|
||||
charts.xAxisData.push(propsSource.id)
|
||||
charts.seriesData.push([propsSource.id, item.saleQuantity || 0])
|
||||
charts.richData[propsSource.id] = that.newRich(propsSource.cover)
|
||||
charts.richData[propsSource.id] = this.newRich(propsSource.cover)
|
||||
})
|
||||
}
|
||||
return charts
|
||||
},
|
||||
renderCharts() {
|
||||
const that = this
|
||||
const proccessChartsData = that.proccessData()
|
||||
that.charts.setOption({
|
||||
if (!this.charts) {
|
||||
return
|
||||
}
|
||||
const proccessChartsData = this.proccessData()
|
||||
this.charts.setOption({
|
||||
color: ['#66b3ff', '#ce90e8', '#ff9c6e', '#5cdbd3'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
@ -113,8 +109,8 @@ export default {
|
||||
shadowStyle: { color: 'rgba(200,200,200,0.2)' }
|
||||
}
|
||||
},
|
||||
formatter: function(val) {
|
||||
return `数量: ${val[0].data[1]}`
|
||||
formatter: val => {
|
||||
return this.$t('pages.dashboard.propsSalesOverview.quantity', { value: val[0].data[1] })
|
||||
}
|
||||
},
|
||||
legend: {
|
||||
@ -130,26 +126,24 @@ export default {
|
||||
borderColor: '#eee'
|
||||
},
|
||||
toolbox: { color: ['#1e90ff', '#1e90ff', '#1e90ff', '#1e90ff'], effectiveColor: '#ff4500' },
|
||||
xAxis: [
|
||||
{
|
||||
xAxis: [{
|
||||
show: true,
|
||||
type: 'category',
|
||||
data: proccessChartsData.xAxisData || [],
|
||||
splitArea: {
|
||||
show: true,
|
||||
type: 'category',
|
||||
data: proccessChartsData.xAxisData || [],
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
axisLabel: {
|
||||
interval: 0,
|
||||
formatter(value) {
|
||||
return '{' + value + '| }'
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
axisLabel: {
|
||||
interval: 0,
|
||||
formatter: function(value) {
|
||||
return '{' + value + '| }'
|
||||
},
|
||||
rich: proccessChartsData.richData || {}
|
||||
}
|
||||
rich: proccessChartsData.richData || {}
|
||||
}
|
||||
],
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
axisTick: { show: true, length: 0 },
|
||||
@ -166,7 +160,6 @@ export default {
|
||||
areaStyle: {},
|
||||
barWidth: 40
|
||||
}
|
||||
|
||||
}, true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="props-config-edit">
|
||||
<el-dialog
|
||||
title="总揽销售报表"
|
||||
:title="$t('pages.dashboard.propsSalesOverview.dialogTitle')"
|
||||
:visible="true"
|
||||
:before-close="handleClose"
|
||||
:close-on-click-modal="false"
|
||||
@ -13,13 +13,12 @@
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import PropsSalesOverviewCharts from '@/components/data/PropsSalesOverviewCharts'
|
||||
|
||||
export default {
|
||||
components: { PropsSalesOverviewCharts },
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
handleClose() {
|
||||
this.$emit('close')
|
||||
@ -27,6 +26,6 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div class="sales-overview-charts">
|
||||
<div class="sales-overview-charts" :data-language="language">
|
||||
<div class="charts-body">
|
||||
<div class="filter-container">
|
||||
<el-select
|
||||
v-model="listQuery.sysOrigin"
|
||||
placeholder="系统"
|
||||
:placeholder="$t('pages.dashboard.propsSalesOverview.systemPlaceholder')"
|
||||
style="width: 120px"
|
||||
class="filter-item"
|
||||
@change="renderData"
|
||||
@ -19,9 +19,10 @@
|
||||
<span style="float: left;margin-left:10px">{{ item.label }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
|
||||
<el-select
|
||||
v-model="listQuery.dateType"
|
||||
placeholder="时间类型"
|
||||
:placeholder="$t('pages.dashboard.propsSalesOverview.dateTypePlaceholder')"
|
||||
style="width: 120px"
|
||||
class="filter-item"
|
||||
@change="changeDateType"
|
||||
@ -33,14 +34,15 @@
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
|
||||
<el-select
|
||||
v-model="listQuery.propsType"
|
||||
placeholder="道具类型"
|
||||
:placeholder="$t('pages.dashboard.propsSalesOverview.propsTypePlaceholder')"
|
||||
style="width: 120px"
|
||||
class="filter-item"
|
||||
@change="renderData"
|
||||
>
|
||||
<el-option v-for="item in propsTypes" :key="item.value" :label="item.name" :value="item.value" />
|
||||
<el-option v-for="item in localizedPropsTypes" :key="item.value" :label="item.name" :value="item.value" />
|
||||
</el-select>
|
||||
|
||||
<div class="filter-item">
|
||||
@ -49,29 +51,45 @@
|
||||
:clearable="false"
|
||||
:value-format="selectedDateType.dateValueFormat"
|
||||
:type="selectedDateType.dateType"
|
||||
placeholder="选择日期"
|
||||
:placeholder="$t('pages.dashboard.propsSalesOverview.datePlaceholder')"
|
||||
:editable="false"
|
||||
@change="renderData"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="filter-item">
|
||||
总额: {{ sale.total || '-' }}
|
||||
{{ $t('pages.dashboard.propsSalesOverview.totalLabel') }}: {{ sale.total || '-' }}
|
||||
</div>
|
||||
</div>
|
||||
<div v-loading="loading">
|
||||
<bar-graph-charts :charts-data="sale.propsSales" :height="height" />
|
||||
</div>
|
||||
|
||||
<div v-loading="loading">
|
||||
<bar-graph-charts :key="'props-sales-' + language" :charts-data="sale.propsSales" :height="height" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { getPropsSale } from '@/api/statistics'
|
||||
import { formatDate } from '@/utils'
|
||||
import { propsTypes } from '@/constant/type'
|
||||
import { mapGetters } from 'vuex'
|
||||
import BarGraphCharts from './bar-graph-charts'
|
||||
|
||||
const PROP_TYPE_KEY_MAP = {
|
||||
AVATAR_FRAME: 'avatarFrame',
|
||||
RIDE: 'ride',
|
||||
NOBLE_VIP: 'nobleVip',
|
||||
THEME: 'theme',
|
||||
LAYOUT: 'layout',
|
||||
CHAT_BUBBLE: 'chatBubble',
|
||||
FLOAT_PICTURE: 'floatPicture',
|
||||
FRAGMENTS: 'fragments',
|
||||
DATA_CARD: 'dataCard',
|
||||
SPECIAL_ID: 'specialId',
|
||||
CUSTOMIZE: 'customizeReadonly'
|
||||
}
|
||||
|
||||
export default {
|
||||
components: { BarGraphCharts },
|
||||
props: {
|
||||
@ -83,19 +101,19 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
propsTypes,
|
||||
rawPropsTypes: propsTypes,
|
||||
dateTypeMap: {
|
||||
'DAY': {
|
||||
DAY: {
|
||||
dateType: 'date',
|
||||
dateValueFormat: 'yyyyMMdd',
|
||||
defaultDate: formatDate(new Date(), 'yyyyMMdd')
|
||||
},
|
||||
'MONTH': {
|
||||
MONTH: {
|
||||
dateType: 'month',
|
||||
dateValueFormat: 'yyyyMM',
|
||||
defaultDate: formatDate(new Date(), 'yyyyMM')
|
||||
},
|
||||
'YEAR': {
|
||||
YEAR: {
|
||||
dateType: 'year',
|
||||
dateValueFormat: 'yyyy',
|
||||
defaultDate: formatDate(new Date(), 'yyyy')
|
||||
@ -108,17 +126,35 @@ export default {
|
||||
propsType: 'AVATAR_FRAME',
|
||||
date: ''
|
||||
},
|
||||
queryTypes: [
|
||||
{ label: '天', value: 'DAY' },
|
||||
{ label: '月', value: 'MONTH' },
|
||||
{ label: '年', value: 'YEAR' }
|
||||
],
|
||||
loading: false,
|
||||
sale: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permissionsSysOriginPlatforms'])
|
||||
...mapGetters(['permissionsSysOriginPlatforms', 'language']),
|
||||
queryTypes() {
|
||||
const language = this.language
|
||||
return [
|
||||
{ label: this.$t('pages.dashboard.propsSalesOverview.day'), value: 'DAY' },
|
||||
{ label: this.$t('pages.dashboard.propsSalesOverview.month'), value: 'MONTH' },
|
||||
{ label: this.$t('pages.dashboard.propsSalesOverview.year'), value: 'YEAR' }
|
||||
]
|
||||
},
|
||||
localizedPropsTypes() {
|
||||
const language = this.language
|
||||
return this.rawPropsTypes.map(item => {
|
||||
const key = PROP_TYPE_KEY_MAP[item.value]
|
||||
return {
|
||||
...item,
|
||||
name: key ? this.$t(`pages.dashboard.propsSalesOverview.propTypes.${key}`) : item.name
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
language() {
|
||||
this.selectedDateType = this.dateTypeMap[this.listQuery.dateType]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.selectedDateType = this.dateTypeMap[this.listQuery.dateType]
|
||||
@ -130,13 +166,12 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
renderData() {
|
||||
const that = this
|
||||
that.loading = true
|
||||
getPropsSale(that.listQuery).then(res => {
|
||||
that.loading = false
|
||||
that.sale = res.body || {}
|
||||
}).catch(er => {
|
||||
that.loading = false
|
||||
this.loading = true
|
||||
getPropsSale(this.listQuery).then(res => {
|
||||
this.loading = false
|
||||
this.sale = res.body || {}
|
||||
}).catch(() => {
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
changeDateType() {
|
||||
@ -147,6 +182,6 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<template>
|
||||
<el-drawer
|
||||
title="重置密码"
|
||||
:title="$t('password.title')"
|
||||
:visible="true"
|
||||
:before-close="clickClose"
|
||||
:close-on-press-escape="false"
|
||||
@ -9,56 +9,53 @@
|
||||
:append-to-body="true"
|
||||
custom-class="drawer-auto-layout"
|
||||
>
|
||||
|
||||
<div class="drawer-form">
|
||||
<el-form ref="dataForm" :model="formData" :rules="rules" label-width="80px">
|
||||
<el-form-item label="原始密码" prop="oldPassword">
|
||||
<el-form ref="dataForm" :model="formData" :rules="rules" label-width="120px">
|
||||
<el-form-item :label="$t('password.old')" prop="oldPassword">
|
||||
<el-input
|
||||
v-model.trim="formData.oldPassword"
|
||||
type="password"
|
||||
placeholder="请输入原始密码"
|
||||
:placeholder="$t('password.placeholderOld')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="newPassword">
|
||||
<el-form-item :label="$t('password.new')" prop="newPassword">
|
||||
<el-input
|
||||
v-model.trim="formData.newPassword"
|
||||
type="password"
|
||||
placeholder="请输入新密码"
|
||||
:placeholder="$t('password.placeholderNew')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="rePassword">
|
||||
<el-form-item :label="$t('password.confirm')" prop="rePassword">
|
||||
<el-input
|
||||
v-model.trim="formData.rePassword"
|
||||
type="password"
|
||||
placeholder="请输入确认密码"
|
||||
:placeholder="$t('password.placeholderConfirm')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
</el-form>
|
||||
</div>
|
||||
<div class="drawer-footer">
|
||||
<el-button @click="clickClose">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" :disabled="submitLoading" @click="clickSubmit">提交</el-button>
|
||||
<el-button @click="clickClose">{{ $t('common.cancel') }}</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" :disabled="submitLoading" @click="clickSubmit">{{ $t('common.submit') }}</el-button>
|
||||
</div>
|
||||
</el-drawer>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { resetPassword } from '@/api/ops-system'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
const passwordValid = (rule, value, callback) => {
|
||||
if (!value) {
|
||||
callback(new Error('必填字体不可为空'))
|
||||
callback(new Error(this.$t('password.required')))
|
||||
} else if (value.length < 4) {
|
||||
callback(new Error('密码不可小于4位'))
|
||||
callback(new Error(this.$t('password.invalidLength')))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
submitLoading: false,
|
||||
formData: {
|
||||
@ -75,34 +72,34 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
clickSubmit() {
|
||||
const that = this
|
||||
that.$refs.dataForm.validate(valid => {
|
||||
if (valid) {
|
||||
if (that.formData.newPassword !== that.formData.rePassword) {
|
||||
that.$opsMessage.fail('两次密码输入不一致')
|
||||
return false
|
||||
}
|
||||
that.submitLoading = true
|
||||
resetPassword(that.formData).then(res => {
|
||||
that.submitLoading = false
|
||||
that.$emit('success')
|
||||
that.$store.dispatch('user/resetToken').then(() => {
|
||||
// window.clearVuexAlong(true, true)
|
||||
location.reload()
|
||||
})
|
||||
}).catch(er => {
|
||||
that.submitLoading = false
|
||||
that.$emit('fial', er)
|
||||
})
|
||||
} else {
|
||||
console.error('error submit!!')
|
||||
this.$refs.dataForm.validate(valid => {
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (this.formData.newPassword !== this.formData.rePassword) {
|
||||
this.$opsMessage.fail(this.$t('password.mismatch'))
|
||||
return false
|
||||
}
|
||||
|
||||
this.submitLoading = true
|
||||
resetPassword(this.formData).then(() => {
|
||||
this.submitLoading = false
|
||||
this.$emit('success')
|
||||
this.$store.dispatch('user/resetToken').then(() => {
|
||||
location.reload()
|
||||
})
|
||||
}).catch(error => {
|
||||
this.submitLoading = false
|
||||
this.$emit('fail', error)
|
||||
})
|
||||
|
||||
return true
|
||||
})
|
||||
},
|
||||
clickClose() {
|
||||
if (this.submitLoading === true) {
|
||||
this.$opsMessage.warn('Processing submission!')
|
||||
if (this.submitLoading) {
|
||||
this.$opsMessage.warn(this.$t('password.processing'))
|
||||
return
|
||||
}
|
||||
this.$emit('close')
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
<el-collapse v-model="nActiveCollapseNames">
|
||||
<el-collapse-item title="" name="profileInfo">
|
||||
<template slot="title">
|
||||
<i class="el-icon-s-custom" /> 基本资料
|
||||
<i class="el-icon-s-custom" /> {{ $t('pages.roomInfo.section.profileInfo') }}
|
||||
</template>
|
||||
<div class="block-info">
|
||||
|
||||
@ -27,35 +27,35 @@
|
||||
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">房间ID:{{ roomDetails.id }}</el-col>
|
||||
<el-col :span="12">账号:{{ getAccountText() }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.roomId') }}:{{ roomDetails.id }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.account') }}:{{ getAccountText() }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">用户ID:{{ roomDetails.userId }}</el-col>
|
||||
<el-col :span="12" class="icon-item">国家:
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.userId') }}:{{ roomDetails.userId }}</el-col>
|
||||
<el-col :span="12" class="icon-item">{{ $t('pages.roomInfo.label.country') }}:
|
||||
<flag-icon class="flag-icon" :code="roomDetails.countryCode" :tooltip="roomDetails.countryName" size="28" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">状态:
|
||||
<el-tag v-if="roomDetails.event === 'AVAILABLE'" size="mini" type="success">正常</el-tag>
|
||||
<el-tag v-else-if="roomDetails.event === 'ID_CHANGE'" size="mini" type="info">ID变更</el-tag>
|
||||
<el-tag v-else-if="roomDetails.event === 'WAITING_CONFIRMED'" size="mini" type="warning">等待确认</el-tag>
|
||||
<el-tag v-else-if="roomDetails.event === 'CLOSE'" size="mini" type="danger">关闭</el-tag>
|
||||
<el-tag v-else size="mini" type="danger">未知</el-tag>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.status') }}:
|
||||
<el-tag v-if="roomDetails.event === 'AVAILABLE'" size="mini" type="success">{{ $t('pages.roomInfo.status.available') }}</el-tag>
|
||||
<el-tag v-else-if="roomDetails.event === 'ID_CHANGE'" size="mini" type="info">{{ $t('pages.roomInfo.status.idChange') }}</el-tag>
|
||||
<el-tag v-else-if="roomDetails.event === 'WAITING_CONFIRMED'" size="mini" type="warning">{{ $t('pages.roomInfo.status.waitingConfirmed') }}</el-tag>
|
||||
<el-tag v-else-if="roomDetails.event === 'CLOSE'" size="mini" type="danger">{{ $t('pages.roomInfo.status.close') }}</el-tag>
|
||||
<el-tag v-else size="mini" type="danger">{{ $t('pages.roomInfo.status.unknown') }}</el-tag>
|
||||
</el-col>
|
||||
<el-col :span="12">注销:
|
||||
{{ roomDetails.del ? 'Yes' : 'NO' }}
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.deleted') }}:
|
||||
{{ getYesNoText(roomDetails.del) }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12" class="icon-item">平台:
|
||||
<el-col :span="12" class="icon-item">{{ $t('pages.roomInfo.label.platform') }}:
|
||||
<div class="sys-icon">
|
||||
<sys-origin-icon :icon="userProfile.sysOriginChild || userProfile.originSys" :desc="userProfile.originSys || userProfile.sysOriginChild" />
|
||||
</div>
|
||||
@ -63,15 +63,15 @@
|
||||
</el-row>
|
||||
</div>
|
||||
<div>
|
||||
<div>公告:{{ roomDetails.roomDesc }}</div>
|
||||
<div>{{ $t('pages.roomInfo.label.notice') }}:{{ roomDetails.roomDesc }}</div>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
创建时间:{{ roomDetails.createTime }}
|
||||
{{ $t('pages.roomInfo.label.createdAt') }}:{{ roomDetails.createTime }}
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
修改时间:{{ roomDetails.updateTime }}
|
||||
{{ $t('pages.roomInfo.label.updatedAt') }}:{{ roomDetails.updateTime }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -79,42 +79,42 @@
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="" name="settingInfo">
|
||||
<template slot="title">
|
||||
<i class="el-icon-s-opportunity" /> 设置信息
|
||||
<i class="el-icon-s-opportunity" /> {{ $t('pages.roomInfo.section.settingInfo') }}
|
||||
</template>
|
||||
<div class="block-info">
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">房间密码:{{ roomDetails.setting.password ? roomDetails.setting.password : '无' }}</el-col>
|
||||
<el-col :span="12">加入成员金币:{{ roomDetails.setting.joinGolds || 0 }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.roomPassword') }}:{{ roomDetails.setting.password ? roomDetails.setting.password : $t('pages.roomInfo.word.none') }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.joinGolds') }}:{{ roomDetails.setting.joinGolds || 0 }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">成员人数:{{ roomDetails.counter.memberCount }}/{{ roomDetails.setting.maxMember }}</el-col>
|
||||
<el-col :span="12">管理员人数:{{ roomDetails.counter.adminCount }}/{{ roomDetails.setting.maxAdmin }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.memberCount') }}:{{ roomDetails.counter.memberCount }}/{{ roomDetails.setting.maxMember }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.adminCount') }}:{{ roomDetails.counter.adminCount }}/{{ roomDetails.setting.maxAdmin }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">麦克风权限:{{ roomDetails.setting.takeMicRole || '-' }}</el-col>
|
||||
<el-col :span="12">麦克风数量:{{ roomDetails.setting.mikeSize || '-' }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.takeMicRole') }}:{{ roomDetails.setting.takeMicRole || '-' }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.mikeSize') }}:{{ roomDetails.setting.mikeSize || '-' }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">游客上麦:{{ roomDetails.setting.touristMike ? '允许' : '不允许' }}</el-col>
|
||||
<el-col :span="12">游客发消息:{{ roomDetails.setting.touristMsg? '允许' : '不允许' }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.touristMike') }}:{{ getPermissionText(roomDetails.setting.touristMike) }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.touristMsg') }}:{{ getPermissionText(roomDetails.setting.touristMsg) }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">播放音乐:{{ roomDetails.setting.allowMusic ? '允许' : '不允许' }}</el-col>
|
||||
<el-col :span="12">管理员锁麦克风:{{ roomDetails.setting.adminLockSeat? '允许' : '不允许' }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.allowMusic') }}:{{ getPermissionText(roomDetails.setting.allowMusic) }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.adminLockSeat') }}:{{ getPermissionText(roomDetails.setting.adminLockSeat) }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">显示心动值:{{ roomDetails.setting.showHeartbeat ? '允许' : '不允许' }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.roomInfo.label.showHeartbeat') }}:{{ getPermissionText(roomDetails.setting.showHeartbeat) }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
@ -148,17 +148,17 @@
|
||||
</el-collapse-item> -->
|
||||
<el-collapse-item title="" name="badgeInfo">
|
||||
<template slot="title">
|
||||
<i class="el-icon-s-opportunity" /> 装饰徽章
|
||||
<i class="el-icon-s-opportunity" /> {{ $t('pages.roomInfo.section.badgeInfo') }}
|
||||
</template>
|
||||
<div class="block-info">
|
||||
<div v-if="roomDetails.useBadges && roomDetails.useBadges.length > 0" class="text-item flex-l">
|
||||
<el-tooltip v-for="(item, index) in roomDetails.useBadges" :key="index" class="item" effect="dark">
|
||||
<div slot="content">
|
||||
<div>ID:{{ item.id }}</div>
|
||||
<div>徽章名称:{{ item.badgeName }}</div>
|
||||
<div>徽章类型:{{ item.type }}</div>
|
||||
<div>徽章KEY:{{ item.badgeKey }}</div>
|
||||
<div>过期时间:{{ item.expireTime | dateFormat('yyyy-MM-dd HH:mm:ss') }}</div>
|
||||
<div>{{ $t('pages.roomInfo.label.badgeName') }}:{{ item.badgeName }}</div>
|
||||
<div>{{ $t('pages.roomInfo.label.badgeType') }}:{{ item.type }}</div>
|
||||
<div>{{ $t('pages.roomInfo.label.badgeKey') }}:{{ item.badgeKey }}</div>
|
||||
<div>{{ $t('pages.roomInfo.label.expireTime') }}:{{ item.expireTime | dateFormat('yyyy-MM-dd HH:mm:ss') }}</div>
|
||||
</div>
|
||||
<el-image
|
||||
style="width: 50px; height: 50px"
|
||||
@ -217,10 +217,21 @@ export default {
|
||||
handleClose() {
|
||||
this.$emit('close')
|
||||
},
|
||||
getPermissionText(value) {
|
||||
return this.$t(value ? 'pages.roomInfo.word.allow' : 'pages.roomInfo.word.notAllow')
|
||||
},
|
||||
getYesNoText(value) {
|
||||
return this.$t(value ? 'pages.roomInfo.word.yes' : 'pages.roomInfo.word.no')
|
||||
},
|
||||
getAccountText() {
|
||||
const account = this.userProfile.account
|
||||
if (this.userProfile.ownSpecialId && this.userProfile.ownSpecialId.account) {
|
||||
return `${account} / ${this.userProfile.ownSpecialId.account}靓`
|
||||
const specialAccount = this.userProfile.ownSpecialId && this.userProfile.ownSpecialId.account
|
||||
if (specialAccount) {
|
||||
return this.$t('pages.roomInfo.text.accountWithSpecial', {
|
||||
account,
|
||||
specialAccount,
|
||||
suffix: this.$t('pages.roomInfo.word.specialSuffix')
|
||||
})
|
||||
}
|
||||
return account
|
||||
},
|
||||
|
||||
@ -14,29 +14,29 @@
|
||||
success: roomProfile.id && roomProfile.id > 0,
|
||||
fail: (!roomProfile.id || roomProfile.id < 0) && failShow
|
||||
}"
|
||||
placeholder="请输入房间ID"
|
||||
:placeholder="$t('pages.searchRoomInput.placeholder.roomId')"
|
||||
class="input-with-select"
|
||||
@blur="clickSearch"
|
||||
>
|
||||
<el-select
|
||||
slot="prepend"
|
||||
v-model="selectType"
|
||||
placeholder="类型"
|
||||
:placeholder="$t('pages.searchRoomInput.placeholder.type')"
|
||||
@change="clickSearch"
|
||||
>
|
||||
<el-option label="短ID" value="SHORT_ID" />
|
||||
<el-option label="长ID" value="LONG_ID" />
|
||||
<el-option :label="$t('pages.searchRoomInput.option.shortId')" value="SHORT_ID" />
|
||||
<el-option :label="$t('pages.searchRoomInput.option.longId')" value="LONG_ID" />
|
||||
</el-select>
|
||||
</el-input>
|
||||
</el-tooltip>
|
||||
|
||||
<el-dialog
|
||||
title="房间搜索"
|
||||
:title="$t('pages.searchRoomInput.dialog.title')"
|
||||
:visible="visibleSelecteDialog"
|
||||
:before-close="handleClose"
|
||||
:append-to-body="true"
|
||||
>
|
||||
<span>找到多个结果, 请选择您期望</span>
|
||||
<span>{{ $t('pages.searchRoomInput.dialog.selectRoom') }}</span>
|
||||
<div class="select-room">
|
||||
<div
|
||||
v-for="(item, index) in roomProfiles"
|
||||
@ -57,7 +57,7 @@
|
||||
{{ item.roomName }}
|
||||
</div>
|
||||
<div class="selected-but">
|
||||
<el-button type="text" @click="clickSelected(item)">选择</el-button>
|
||||
<el-button type="text" @click="clickSelected(item)">{{ $t('pages.searchRoomInput.action.select') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -158,11 +158,11 @@ export default {
|
||||
return;
|
||||
}
|
||||
if (!/\d+/.test(that.content)) {
|
||||
that.failTipsContent("输入内容必须是正整数!");
|
||||
that.failTipsContent(this.$t("pages.searchRoomInput.message.contentMustBePositiveInteger"));
|
||||
return;
|
||||
}
|
||||
if (that.content.length < 1) {
|
||||
that.failTipsContent("输入账号必须>=1位数!");
|
||||
that.failTipsContent(this.$t("pages.searchRoomInput.message.contentLengthInvalid"));
|
||||
return;
|
||||
}
|
||||
if (
|
||||
@ -182,7 +182,7 @@ export default {
|
||||
that.loading = false;
|
||||
const result = res.body;
|
||||
if (!result) {
|
||||
that.failTipsContent("没有找到房间信息!");
|
||||
that.failTipsContent(this.$t("pages.searchRoomInput.message.roomNotFound"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -199,7 +199,7 @@ export default {
|
||||
}
|
||||
|
||||
if (result.length === 0) {
|
||||
that.failTipsContent("没有找到房间信息!");
|
||||
that.failTipsContent(this.$t("pages.searchRoomInput.message.roomNotFound"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -209,7 +209,7 @@ export default {
|
||||
.catch(er => {
|
||||
that.loading = false;
|
||||
console.error("clickSearch", er);
|
||||
that.failTipsContent("请求数据错误!");
|
||||
that.failTipsContent(this.$t("pages.searchRoomInput.message.requestFailed"));
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="bind-user-phone-form">
|
||||
<el-drawer
|
||||
title="认证信息"
|
||||
:title="$t('pages.userAuthForm.drawer.title')"
|
||||
:visible="true"
|
||||
:before-close="handleClose"
|
||||
:close-on-press-escape="false"
|
||||
@ -13,7 +13,7 @@
|
||||
<div v-loading="authLoading" class="user-auth-type" style="padding: 10px;">
|
||||
<el-card class="box-card" style="margin-top:0px;">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>已认证类型</span>
|
||||
<span>{{ $t('pages.userAuthForm.section.authenticatedTypes') }}</span>
|
||||
</div>
|
||||
<div class="text item" style="">
|
||||
<div
|
||||
@ -35,24 +35,24 @@
|
||||
</el-card>
|
||||
<el-card class="box-card" style="margin-top: 10px;">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>手机号绑定</span>
|
||||
<el-button v-if="!(userMobileAuth || {}).id" type="text" @click="handleCreate()">绑定</el-button>
|
||||
<span>{{ $t('pages.userAuthForm.section.phoneBinding') }}</span>
|
||||
<el-button v-if="!(userMobileAuth || {}).id" type="text" @click="handleCreate()">{{ $t('pages.userAuthForm.action.bind') }}</el-button>
|
||||
</div>
|
||||
<div v-if="(userMobileAuth || {}).id && editBoxVisible == false" class="text item">
|
||||
<div style="display: flex; align-items: center; justify-content: space-between;">
|
||||
<div>{{ userMobileAuth.phonePrefix }}-{{ userMobileAuth.phoneNumber }}</div>
|
||||
<div><el-tag type="success">已绑定</el-tag></div>
|
||||
<div><el-tag type="success">{{ $t('pages.userAuthForm.status.bound') }}</el-tag></div>
|
||||
<div>
|
||||
<el-button type="text" @click="handleUpdateMobileAuth()">换绑</el-button>
|
||||
<el-button type="text" @click="handleDelete()">删除</el-button>
|
||||
<el-button type="text" @click="handleUpdateMobileAuth()">{{ $t('pages.userAuthForm.action.rebind') }}</el-button>
|
||||
<el-button type="text" @click="handleDelete()">{{ $t('pages.userAuthForm.action.delete') }}</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="editBoxVisible" class="text item">
|
||||
<el-form
|
||||
<el-form
|
||||
ref="formData"
|
||||
v-loading="listLoading"
|
||||
:rules="rules"
|
||||
:rules="localizedRules"
|
||||
:model="formData"
|
||||
label-position="left"
|
||||
label-width="70px"
|
||||
@ -65,7 +65,7 @@
|
||||
<el-input
|
||||
v-model.trim="formData.phonePrefix"
|
||||
v-number
|
||||
placeholder="区号"
|
||||
:placeholder="$t('pages.userAuthForm.placeholder.phonePrefix')"
|
||||
maxlength="7"
|
||||
/>
|
||||
</el-form-item>
|
||||
@ -76,7 +76,7 @@
|
||||
<el-input
|
||||
v-model.trim="formData.phoneNumber"
|
||||
v-number
|
||||
placeholder="手机号"
|
||||
:placeholder="$t('pages.userAuthForm.placeholder.phoneNumber')"
|
||||
maxlength="20"
|
||||
/>
|
||||
</el-form-item>
|
||||
@ -85,18 +85,18 @@
|
||||
<el-form-item prop="pwd">
|
||||
<el-input
|
||||
v-model="formData.pwd"
|
||||
placeholder="密码"
|
||||
:placeholder="$t('pages.userAuthForm.placeholder.password')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<div style="text-align: center;">
|
||||
<el-button @click="handleCancel()">
|
||||
取消
|
||||
{{ $t('pages.userAuthForm.action.cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
@click="handleSubmit()"
|
||||
>
|
||||
提交
|
||||
{{ $t('pages.userAuthForm.action.submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
@ -104,20 +104,20 @@
|
||||
</el-card>
|
||||
<el-card class="box-card" style="margin-top: 10px;">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>账号密码登录次数</span>
|
||||
<el-button type="text" @click="initAccountLogin()">重置</el-button>
|
||||
<span>{{ $t('pages.userAuthForm.section.accountPasswordLoginCount') }}</span>
|
||||
<el-button type="text" @click="initAccountLogin()">{{ $t('pages.userAuthForm.action.reset') }}</el-button>
|
||||
<br>
|
||||
<span>账号登录</span>
|
||||
<el-button type="text" @click="deleteAccountLogin()">删除</el-button>
|
||||
<span>{{ $t('pages.userAuthForm.section.accountLogin') }}</span>
|
||||
<el-button type="text" @click="deleteAccountLogin()">{{ $t('pages.userAuthForm.action.delete') }}</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
<el-card class="box-card" style="margin-top: 10px;">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>支付密码错误次数</span>
|
||||
<el-button type="text" @click="initPayAuth()">重置</el-button>
|
||||
<span>{{ $t('pages.userAuthForm.section.payPasswordErrorCount') }}</span>
|
||||
<el-button type="text" @click="initPayAuth()">{{ $t('pages.userAuthForm.action.reset') }}</el-button>
|
||||
<br>
|
||||
<span>支付密码</span>
|
||||
<el-button type="text" @click="deletePayAuth()">删除</el-button>
|
||||
<span>{{ $t('pages.userAuthForm.section.payPassword') }}</span>
|
||||
<el-button type="text" @click="deletePayAuth()">{{ $t('pages.userAuthForm.action.delete') }}</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
@ -145,25 +145,25 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
function commonFormRules() {
|
||||
return [
|
||||
{ required: true, message: '必填字段', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
return {
|
||||
listLoading: false,
|
||||
authLoading: false,
|
||||
userAuthList: [],
|
||||
userMobileAuth: {},
|
||||
editBoxVisible: false,
|
||||
rules: {
|
||||
phonePrefix: commonFormRules(),
|
||||
phoneNumber: commonFormRules(),
|
||||
pwd: commonFormRules()
|
||||
},
|
||||
formData: getFormData()
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
localizedRules() {
|
||||
const commonRules = [this.getRequiredRule()]
|
||||
return {
|
||||
phonePrefix: commonRules,
|
||||
phoneNumber: commonRules,
|
||||
pwd: commonRules
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
userId: {
|
||||
handler(newVal) {
|
||||
@ -175,6 +175,13 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getRequiredRule() {
|
||||
return {
|
||||
required: true,
|
||||
message: this.$t('pages.userAuthForm.validation.requiredField'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
},
|
||||
renderData() {
|
||||
const that = this
|
||||
that.authLoading = true
|
||||
@ -189,13 +196,13 @@ export default {
|
||||
},
|
||||
handleDelete() {
|
||||
const that = this
|
||||
that.$confirm('确认删除吗?', '提示', {
|
||||
that.$confirm(that.$t('pages.userAuthForm.confirm.delete'), that.$t('pages.userAuthForm.confirm.title'), {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
that.listLoading = true
|
||||
deleteUserMobileAuth(that.userId).then((res) => {
|
||||
that.listLoading = false
|
||||
that.$message.success('删除成功')
|
||||
that.$message.success(that.$t('pages.userAuthForm.message.deleteSuccess'))
|
||||
that.$emit('success', {})
|
||||
that.renderData()
|
||||
that.handleCancel()
|
||||
@ -212,7 +219,7 @@ export default {
|
||||
return false
|
||||
}
|
||||
if (Number((that.formData.phonePrefix + '').substring(0, 1)) <= 0) {
|
||||
that.$message.error('区号不能以0开头')
|
||||
that.$message.error(that.$t('pages.userAuthForm.validation.phonePrefixCannotStartWithZero'))
|
||||
return
|
||||
}
|
||||
that.listLoading = true
|
||||
@ -234,13 +241,13 @@ export default {
|
||||
},
|
||||
initAccountLogin() {
|
||||
const that = this
|
||||
that.$confirm('确认重置吗?', '提示', {
|
||||
that.$confirm(that.$t('pages.userAuthForm.confirm.reset'), that.$t('pages.userAuthForm.confirm.title'), {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
that.listLoading = true
|
||||
initUserAccountLogin(that.userId).then((res) => {
|
||||
that.listLoading = false
|
||||
that.$message.success('重置成功')
|
||||
that.$message.success(that.$t('pages.userAuthForm.message.resetSuccess'))
|
||||
that.$emit('success', {})
|
||||
that.renderData()
|
||||
that.handleCancel()
|
||||
@ -251,13 +258,13 @@ export default {
|
||||
},
|
||||
deleteAccountLogin() {
|
||||
const that = this
|
||||
that.$confirm('确认删除吗?', '提示', {
|
||||
that.$confirm(that.$t('pages.userAuthForm.confirm.delete'), that.$t('pages.userAuthForm.confirm.title'), {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
that.listLoading = true
|
||||
deleteUserAccountLogin(that.userId).then((res) => {
|
||||
that.listLoading = false
|
||||
that.$message.success('删除成功')
|
||||
that.$message.success(that.$t('pages.userAuthForm.message.deleteSuccess'))
|
||||
that.$emit('success', {})
|
||||
that.renderData()
|
||||
that.handleCancel()
|
||||
@ -267,13 +274,13 @@ export default {
|
||||
},
|
||||
initPayAuth() {
|
||||
const that = this
|
||||
that.$confirm('确认重置吗?', '提示', {
|
||||
that.$confirm(that.$t('pages.userAuthForm.confirm.reset'), that.$t('pages.userAuthForm.confirm.title'), {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
that.listLoading = true
|
||||
initUserPayAuth(that.userId).then((res) => {
|
||||
that.listLoading = false
|
||||
that.$message.success('重置成功')
|
||||
that.$message.success(that.$t('pages.userAuthForm.message.resetSuccess'))
|
||||
that.$emit('success', {})
|
||||
that.renderData()
|
||||
that.handleCancel()
|
||||
@ -284,13 +291,13 @@ export default {
|
||||
},
|
||||
deletePayAuth() {
|
||||
const that = this
|
||||
that.$confirm('确认删除吗?', '提示', {
|
||||
that.$confirm(that.$t('pages.userAuthForm.confirm.delete'), that.$t('pages.userAuthForm.confirm.title'), {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
that.listLoading = true
|
||||
deleteUserPayAuth(that.userId).then((res) => {
|
||||
that.listLoading = false
|
||||
that.$message.success('删除成功')
|
||||
that.$message.success(that.$t('pages.userAuthForm.message.deleteSuccess'))
|
||||
that.$emit('success', {})
|
||||
that.renderData()
|
||||
that.handleCancel()
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
<!--账号处理日志列表-->
|
||||
<template>
|
||||
<div class="account-status-latest-log">
|
||||
<div
|
||||
@ -6,7 +5,12 @@
|
||||
:key="index"
|
||||
class="block"
|
||||
>
|
||||
<el-tag type="danger"> <strong>”{{ item.approvalUserName }}“</strong> 操作 <strong>“{{ item.statusName }}”</strong> {{ item.createTime }}</el-tag>
|
||||
<el-tag type="danger">
|
||||
<strong>”{{ item.approvalUserName }}“</strong>
|
||||
{{ $t('pages.accountStatusLatestLog.message.operated') }}
|
||||
<strong>“{{ item.statusName }}”</strong>
|
||||
{{ item.createTime }}
|
||||
</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="user-bank-card-list">
|
||||
<el-drawer
|
||||
title="银行卡列表"
|
||||
:title="$t('pages.bankCardDrawer.drawer.title')"
|
||||
:visible="true"
|
||||
:before-close="handleClose"
|
||||
:close-on-press-escape="false"
|
||||
@ -18,73 +18,73 @@
|
||||
style="margin: 10px;"
|
||||
@click="handleCreate"
|
||||
>
|
||||
新增
|
||||
{{ $t('pages.bankCardDrawer.action.create') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<div v-loading="listLoading">
|
||||
<el-row v-for="(item, index) in list" :key="index">
|
||||
<el-card style="margin: 10px;">
|
||||
<div>
|
||||
<el-tag effect="plain">卡号: {{ item.cardNo }}</el-tag>
|
||||
<el-tag effect="plain">收款人: {{ item.payee }}</el-tag>
|
||||
<el-tag effect="plain">银行: {{ item.cardName }}</el-tag>
|
||||
<el-tag effect="plain">{{ $t('pages.bankCardDrawer.label.cardNo') }}: {{ item.cardNo }}</el-tag>
|
||||
<el-tag effect="plain">{{ $t('pages.bankCardDrawer.label.payee') }}: {{ item.payee }}</el-tag>
|
||||
<el-tag effect="plain">{{ $t('pages.bankCardDrawer.label.bank') }}: {{ item.cardName }}</el-tag>
|
||||
<el-tag
|
||||
v-if="item.status === 'PENDING'"
|
||||
effect="plain"
|
||||
type="info"
|
||||
>审核状态: 待审核</el-tag>
|
||||
>{{ $t('pages.bankCardDrawer.label.auditStatus') }}: {{ $t('pages.bankCardDrawer.status.pending') }}</el-tag>
|
||||
<el-tag
|
||||
v-if="item.status === 'PASS'"
|
||||
effect="plain"
|
||||
type="success"
|
||||
>审核状态: 正常</el-tag>
|
||||
>{{ $t('pages.bankCardDrawer.label.auditStatus') }}: {{ $t('pages.bankCardDrawer.status.pass') }}</el-tag>
|
||||
<el-tag
|
||||
v-if="item.status === 'NOT_PASS'"
|
||||
effect="plain"
|
||||
type="danger"
|
||||
>审核状态: 驳回</el-tag>
|
||||
>{{ $t('pages.bankCardDrawer.label.auditStatus') }}: {{ $t('pages.bankCardDrawer.status.notPass') }}</el-tag>
|
||||
<el-tag
|
||||
v-if="item.use"
|
||||
effect="plain"
|
||||
type="success"
|
||||
>使用中: 是</el-tag>
|
||||
>{{ $t('pages.bankCardDrawer.label.inUse') }}: {{ $t('pages.bankCardDrawer.word.yes') }}</el-tag>
|
||||
<el-tag
|
||||
v-if="!item.use"
|
||||
effect="plain"
|
||||
type="info"
|
||||
>使用中: 否</el-tag>
|
||||
>{{ $t('pages.bankCardDrawer.label.inUse') }}: {{ $t('pages.bankCardDrawer.word.no') }}</el-tag>
|
||||
</div>
|
||||
<div class="bottom clearfix">
|
||||
<time class="time">创建时间:{{ item.createTime }}</time>
|
||||
<time class="time">{{ $t('pages.bankCardDrawer.label.createdAt') }}:{{ item.createTime }}</time>
|
||||
</div>
|
||||
<div class="clearfix">
|
||||
<el-button
|
||||
type="text"
|
||||
@click.native="handleUpdate(item)"
|
||||
>修改</el-button>
|
||||
>{{ $t('pages.bankCardDrawer.action.edit') }}</el-button>
|
||||
<el-button
|
||||
v-if="!item.use"
|
||||
type="text"
|
||||
@click.native="handleUse(item)"
|
||||
>使用</el-button>
|
||||
>{{ $t('pages.bankCardDrawer.action.use') }}</el-button>
|
||||
<el-button
|
||||
type="text"
|
||||
@click.native="handleDelete(item)"
|
||||
>删除</el-button>
|
||||
>{{ $t('pages.bankCardDrawer.action.delete') }}</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-dialog
|
||||
width="450px"
|
||||
:title="textOptTitle2"
|
||||
:title="formDialogTitle"
|
||||
:visible.sync="form2Visible"
|
||||
append-to-body
|
||||
>
|
||||
<div v-loading="submitLoading">
|
||||
<el-form
|
||||
ref="dataForm"
|
||||
:rules="rules"
|
||||
:rules="localizedRules"
|
||||
:model="dataForm"
|
||||
label-position="left"
|
||||
label-width="70px"
|
||||
@ -92,12 +92,12 @@
|
||||
>
|
||||
<el-form-item
|
||||
v-if="dataForm.id === ''"
|
||||
label="类型"
|
||||
:label="$t('pages.bankCardDrawer.form.cardType')"
|
||||
prop="cardType"
|
||||
>
|
||||
<el-select
|
||||
v-model="dataForm.cardType"
|
||||
placeholder="类型"
|
||||
:placeholder="$t('pages.bankCardDrawer.placeholder.cardType')"
|
||||
style="width: 120px"
|
||||
class="filter-item"
|
||||
@change="getBankCardTypeName(dataForm)"
|
||||
@ -113,33 +113,33 @@
|
||||
|
||||
<el-form-item
|
||||
v-if="dataForm.id === '' && dataForm.cardType === 'BANK'"
|
||||
label="银行"
|
||||
:label="$t('pages.bankCardDrawer.form.cardName')"
|
||||
prop="cardName"
|
||||
>
|
||||
<el-input
|
||||
v-model.trim="dataForm.cardName"
|
||||
placeholder="请输入银行(英文)名称"
|
||||
:placeholder="$t('pages.bankCardDrawer.placeholder.cardName')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="收款人" prop="payee">
|
||||
<el-input v-model.trim="dataForm.payee" placeholder="收款人" />
|
||||
<el-form-item :label="$t('pages.bankCardDrawer.form.payee')" prop="payee">
|
||||
<el-input v-model.trim="dataForm.payee" :placeholder="$t('pages.bankCardDrawer.placeholder.payee')" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="卡号" prop="cardNo">
|
||||
<el-input v-model.trim="dataForm.cardNo" placeholder="卡号" />
|
||||
<el-form-item :label="$t('pages.bankCardDrawer.form.cardNo')" prop="cardNo">
|
||||
<el-input v-model.trim="dataForm.cardNo" :placeholder="$t('pages.bankCardDrawer.placeholder.cardNo')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer" style="text-align: center;">
|
||||
<el-button @click="form2Visible = false">
|
||||
取消
|
||||
{{ $t('pages.bankCardDrawer.action.cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
v-loading="listLoading"
|
||||
type="primary"
|
||||
@click="handleSubmit()"
|
||||
>
|
||||
提交
|
||||
{{ $t('pages.bankCardDrawer.action.submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@ -182,17 +182,7 @@ export default {
|
||||
list: [],
|
||||
form2Visible: false,
|
||||
listLoading: false,
|
||||
textOptTitle2: '添加',
|
||||
rules: {
|
||||
cardType: [
|
||||
{ required: true, message: '请填写卡片类型', trigger: 'blur' }
|
||||
],
|
||||
payee: [{ required: true, message: '请填写收款人', trigger: 'blur' }],
|
||||
cardNo: [{ required: true, message: '请填写卡号', trigger: 'blur' }],
|
||||
cardName: [
|
||||
{ required: true, message: '请填写银行英语名称', trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
dialogMode: 'create',
|
||||
dataForm: {
|
||||
id: '',
|
||||
userId: '',
|
||||
@ -205,10 +195,30 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
localizedRules() {
|
||||
return {
|
||||
cardType: [this.getRequiredRule('pages.bankCardDrawer.validation.cardTypeRequired')],
|
||||
payee: [this.getRequiredRule('pages.bankCardDrawer.validation.payeeRequired')],
|
||||
cardNo: [this.getRequiredRule('pages.bankCardDrawer.validation.cardNoRequired')],
|
||||
cardName: [this.getRequiredRule('pages.bankCardDrawer.validation.cardNameRequired')]
|
||||
}
|
||||
},
|
||||
formDialogTitle() {
|
||||
return this.$t(`pages.bankCardDrawer.dialog.${this.dialogMode}`)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.renderData()
|
||||
},
|
||||
methods: {
|
||||
getRequiredRule(messageKey) {
|
||||
return {
|
||||
required: true,
|
||||
message: this.$t(messageKey),
|
||||
trigger: 'blur'
|
||||
}
|
||||
},
|
||||
renderData() {
|
||||
const that = this
|
||||
that.listLoading = true
|
||||
@ -262,7 +272,7 @@ export default {
|
||||
handleDelete(row) {
|
||||
const that = this
|
||||
that
|
||||
.$confirm('确认删除吗?', '提示', {
|
||||
.$confirm(this.$t('pages.bankCardDrawer.confirm.delete'), this.$t('pages.bankCardDrawer.confirm.title'), {
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
@ -282,7 +292,7 @@ export default {
|
||||
handleUse(row) {
|
||||
const that = this
|
||||
that
|
||||
.$confirm('确认使用该银行卡吗?', '提示', {
|
||||
.$confirm(this.$t('pages.bankCardDrawer.confirm.use'), this.$t('pages.bankCardDrawer.confirm.title'), {
|
||||
type: 'warning'
|
||||
})
|
||||
.then(() => {
|
||||
@ -303,12 +313,12 @@ export default {
|
||||
this.$emit('close')
|
||||
},
|
||||
handleCreate() {
|
||||
this.textOptTitle2 = '添加'
|
||||
this.dialogMode = 'create'
|
||||
this.form2Visible = true
|
||||
this.dataForm = getFormData()
|
||||
},
|
||||
handleUpdate(row) {
|
||||
this.textOptTitle2 = '修改'
|
||||
this.dialogMode = 'edit'
|
||||
this.form2Visible = true
|
||||
this.dataForm = Object.assign(this.dataForm, row)
|
||||
},
|
||||
|
||||
@ -17,16 +17,16 @@
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>语言:{{ item.latestDevice.language }}</el-col>
|
||||
<el-col :span="12">时区:{{ item.latestDevice.zoneId }}</el-col>
|
||||
>{{ $t('pages.userBaseInfo.labels.language') }}:{{ item.latestDevice.language }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.userBaseInfo.labels.timezone') }}:{{ item.latestDevice.zoneId }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">ip:{{ item.latestDevice.ip }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.userBaseInfo.words.activeIp') }}:{{ item.latestDevice.ip }}</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>客户端:{{ item.latestDevice.requestClient }}</el-col>
|
||||
>{{ $t('pages.userBaseInfo.labels.client') }}:{{ item.latestDevice.requestClient }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
@ -34,12 +34,12 @@
|
||||
<el-col
|
||||
:span="12"
|
||||
class="nowrap-ellipsis"
|
||||
>设备型号:<a :title="item.latestDevice.phoneModel">{{
|
||||
>{{ $t('pages.userBaseInfo.labels.deviceModel') }}:<a :title="item.latestDevice.phoneModel">{{
|
||||
item.latestDevice.phoneModel
|
||||
}}</a></el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>设备系统:{{ item.latestDevice.phoneSysVersion }}</el-col>
|
||||
>{{ $t('pages.userBaseInfo.labels.deviceSystem') }}:{{ item.latestDevice.phoneSysVersion }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
@ -47,10 +47,10 @@
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>编译版本:{{ item.latestDevice.buildVersion }}</el-col>
|
||||
>{{ $t('pages.userBaseInfo.labels.buildVersion') }}:{{ item.latestDevice.buildVersion }}</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>App版本:{{ item.latestDevice.appVersion }}</el-col>
|
||||
>{{ $t('pages.userBaseInfo.labels.appVersion') }}:{{ item.latestDevice.appVersion }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
@ -58,10 +58,10 @@
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>Push平台:{{ item.latestDevice.deviceType }}</el-col>
|
||||
>{{ $t('pages.userBaseInfo.labels.pushPlatform') }}:{{ item.latestDevice.deviceType }}</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>登记平台:{{ item.latestDevice.sysOrigin }}</el-col>
|
||||
>{{ $t('pages.userBaseInfo.labels.registerPlatformShort') }}:{{ item.latestDevice.sysOrigin }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
@ -70,7 +70,7 @@
|
||||
<el-col
|
||||
:span="24"
|
||||
class="nowrap-ellipsis"
|
||||
>Push设备:<a :title="item.latestDevice.deviceId">{{
|
||||
>{{ $t('pages.userBaseInfo.labels.pushDevice') }}:<a :title="item.latestDevice.deviceId">{{
|
||||
item.latestDevice.deviceId
|
||||
}}</a></el-col>
|
||||
</el-row>
|
||||
@ -80,7 +80,7 @@
|
||||
<el-col
|
||||
:span="24"
|
||||
class="nowrap-ellipsis"
|
||||
>imei ID:<a :title="item.latestDevice.imei">{{
|
||||
>{{ $t('pages.userBaseInfo.labels.imei') }}:<a :title="item.latestDevice.imei">{{
|
||||
item.latestDevice.imei
|
||||
}}</a></el-col>
|
||||
</el-row>
|
||||
@ -90,7 +90,7 @@
|
||||
<el-col
|
||||
:span="24"
|
||||
class="nowrap-ellipsis"
|
||||
>注册时间:<a
|
||||
>{{ $t('pages.userBaseInfo.labels.registerTime') }}:<a
|
||||
:title="item.userProfile.createTime | dateFormat"
|
||||
>{{ item.userProfile.createTime | dateFormat }}</a></el-col>
|
||||
</el-row>
|
||||
|
||||
@ -11,8 +11,8 @@
|
||||
<div class="content">
|
||||
<div class="text">
|
||||
{{ userBaseInfo.userNickname }}、
|
||||
<span v-if="userBaseInfo.userSex === 1">男</span>
|
||||
<span v-else> 女 </span>
|
||||
<span v-if="userBaseInfo.userSex === 1">{{ $t('pages.userBaseInfo.words.male') }}</span>
|
||||
<span v-else> {{ $t('pages.userBaseInfo.words.female') }} </span>
|
||||
</div>
|
||||
<div
|
||||
v-if="userRunProfile.wearBadge && userRunProfile.wearBadge.length > 0"
|
||||
@ -26,11 +26,11 @@
|
||||
>
|
||||
<div slot="content">
|
||||
<div>ID:{{ item.id }}</div>
|
||||
<div>徽章名称:{{ item.badgeName }}</div>
|
||||
<div>徽章类型:{{ item.type }}</div>
|
||||
<div>徽章KEY:{{ item.badgeKey }}</div>
|
||||
<div>{{ $t('pages.userBaseInfo.labels.badgeName') }}:{{ item.badgeName }}</div>
|
||||
<div>{{ $t('pages.userBaseInfo.labels.badgeType') }}:{{ item.type }}</div>
|
||||
<div>{{ $t('pages.userBaseInfo.labels.badgeKey') }}:{{ item.badgeKey }}</div>
|
||||
<div>
|
||||
过期时间:{{
|
||||
{{ $t('pages.userBaseInfo.labels.expireTime') }}:{{
|
||||
item.expireTime | dateFormat("yyyy-MM-dd HH:mm:ss")
|
||||
}}
|
||||
</div>
|
||||
@ -54,11 +54,11 @@
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item
|
||||
@click.native="queryUserRunProfile()"
|
||||
>查看运行数据
|
||||
>{{ $t('pages.userBaseInfo.actions.viewRuntimeData') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
@click.native="removeUserRunProfile()"
|
||||
>删除运行数据
|
||||
>{{ $t('pages.userBaseInfo.actions.deleteRuntimeData') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
@ -68,16 +68,16 @@
|
||||
<el-collapse v-model="nActiveCollapseNames" @change="collapseChange">
|
||||
<el-collapse-item title="" name="accountInfo">
|
||||
<template slot="title">
|
||||
<i class="el-icon-s-opportunity" /> 账户信息
|
||||
<i class="el-icon-s-opportunity" /> {{ $t('pages.userBaseInfo.sections.accountInfo') }}
|
||||
|
||||
<span
|
||||
v-if="userBaseInfo.del === true"
|
||||
>(已注销:{{ userBaseInfo.updateTime | dateFormat }})</span>
|
||||
>({{ $t('pages.userBaseInfo.labels.deletedAt') }}:{{ userBaseInfo.updateTime | dateFormat }})</span>
|
||||
<span v-else>
|
||||
({{ userBaseInfo.accountStatusName }}
|
||||
<span
|
||||
v-if="userBaseInfo.accountStatus === 'FREEZE'"
|
||||
>:{{ userBaseInfo.freezingTime | dateFormat }}</span>)
|
||||
> {{ $t('pages.userBaseInfo.labels.operationFrozenAt') }}:{{ userBaseInfo.freezingTime | dateFormat }}</span>)
|
||||
</span>
|
||||
|
||||
<!-- <i class="el-icon-s-opportunity" /> 认证信息
|
||||
@ -92,7 +92,7 @@
|
||||
size="38"
|
||||
/>
|
||||
<div class="tags">
|
||||
<el-tag>金币:{{ candy || 0 }}</el-tag>
|
||||
<el-tag>{{ $t('pages.userBaseInfo.labels.gold') }}:{{ candy || 0 }}</el-tag>
|
||||
|
||||
<!-- <el-tag>当前订阅:<a :title="notExpiredSubscriptionName">{{ notExpiredSubscriptionName }}</a> -->
|
||||
<!-- <span v-if="balance.vipEvent > 0">{{ balance.vipExpireTime }}</span> </el-tag>-->
|
||||
@ -111,7 +111,7 @@
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="" name="baseInfo">
|
||||
<template slot="title">
|
||||
<i class="el-icon-s-custom" /> 基本信息
|
||||
<i class="el-icon-s-custom" /> {{ $t('pages.userBaseInfo.sections.baseInfo') }}
|
||||
</template>
|
||||
<div class="block-info">
|
||||
<div class="text-item">
|
||||
@ -119,7 +119,7 @@
|
||||
<el-col :span="12">ID:{{ userBaseInfo.id }}</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>账号:{{ getAccountText(userBaseInfo) }}
|
||||
>{{ $t('pages.userBaseInfo.labels.account') }}:{{ getAccountText(userBaseInfo) }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -127,12 +127,12 @@
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>主播:{{ identity.anchor ? "Yes" : "No" }}
|
||||
>{{ $t('pages.userBaseInfo.labels.anchor') }}:{{ identity.anchor ? $t('pages.userBaseInfo.words.yes') : $t('pages.userBaseInfo.words.no') }}
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>主播代理:{{ identity.agent ? "Yes" : "No" }} / 货运代理:{{
|
||||
identity.freightAgent ? "Yes" : "No"
|
||||
>{{ $t('pages.userBaseInfo.labels.anchorAgent') }}:{{ identity.agent ? $t('pages.userBaseInfo.words.yes') : $t('pages.userBaseInfo.words.no') }} / {{ $t('pages.userBaseInfo.labels.freightAgent') }}:{{
|
||||
identity.freightAgent ? $t('pages.userBaseInfo.words.yes') : $t('pages.userBaseInfo.words.no')
|
||||
}}
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -141,18 +141,18 @@
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>BD:{{ identity.bd ? "Yes" : "No" }} / BD Leader:{{
|
||||
identity.bdLeader ? "Yes" : "No"
|
||||
>BD:{{ identity.bd ? $t('pages.userBaseInfo.words.yes') : $t('pages.userBaseInfo.words.no') }} / BD Leader:{{
|
||||
identity.bdLeader ? $t('pages.userBaseInfo.words.yes') : $t('pages.userBaseInfo.words.no')
|
||||
}}
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>等级Lv:
|
||||
>{{ $t('pages.userBaseInfo.labels.level') }}:
|
||||
<el-tag
|
||||
size="mini"
|
||||
>财富{{ userBaseInfo.wealthLevel }}
|
||||
>{{ $t('pages.userBaseInfo.labels.wealth') }}{{ userBaseInfo.wealthLevel }}
|
||||
</el-tag>
|
||||
<el-tag size="mini">魅力{{ userBaseInfo.charmLevel }}</el-tag>
|
||||
<el-tag size="mini">{{ $t('pages.userBaseInfo.labels.charm') }}{{ userBaseInfo.charmLevel }}</el-tag>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -160,43 +160,43 @@
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>生日:<span
|
||||
>{{ $t('pages.userBaseInfo.labels.birthday') }}:<span
|
||||
v-if="userBaseInfo.bornYear"
|
||||
>{{ userBaseInfo.bornYear }}-{{ userBaseInfo.bornMonth }}-{{
|
||||
userBaseInfo.bornDay
|
||||
}}</span></el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>年龄:<span
|
||||
>{{ $t('pages.userBaseInfo.labels.age') }}:<span
|
||||
v-if="userBaseInfo.age"
|
||||
>({{ userBaseInfo.age }})</span></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">国家:{{ userBaseInfo.countryName }}</el-col>
|
||||
<el-col :span="12">邮箱:{{ userRegisterInfo.email }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.userBaseInfo.labels.country') }}:{{ userBaseInfo.countryName }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.userBaseInfo.labels.email') }}:{{ userRegisterInfo.email }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>注册平台:
|
||||
>{{ $t('pages.userBaseInfo.labels.registerPlatform') }}:
|
||||
<platform-svg-icon
|
||||
size="20px"
|
||||
:icon="userRegisterInfo.originPlatform"
|
||||
:desc="'注册平台:' + userRegisterInfo.originPlatform"
|
||||
:desc="$t('pages.userBaseInfo.labels.registerPlatform') + ':' + userRegisterInfo.originPlatform"
|
||||
/>
|
||||
<platform-svg-icon
|
||||
size="20px"
|
||||
:icon="userRegisterInfo.authType"
|
||||
:desc="'注册方式:' + userRegisterInfo.authType"
|
||||
:desc="$t('pages.userBaseInfo.labels.registerMethod') + ':' + userRegisterInfo.authType"
|
||||
/>
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>手机型号:<a :title="userRegisterInfo.originPhoneModel">{{
|
||||
>{{ $t('pages.userBaseInfo.labels.phoneModel') }}:<a :title="userRegisterInfo.originPhoneModel">{{
|
||||
userRegisterInfo.originPhoneModel
|
||||
}}</a></el-col>
|
||||
</el-row>
|
||||
@ -206,12 +206,12 @@
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>账号类型:
|
||||
>{{ $t('pages.userBaseInfo.labels.accountType') }}:
|
||||
{{ userBaseInfo.userTypeName }}
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>注册时间:<a :title="userBaseInfo.createTime | dateFormat">{{
|
||||
>{{ $t('pages.userBaseInfo.labels.registerTime') }}:<a :title="userBaseInfo.createTime | dateFormat">{{
|
||||
userBaseInfo.createTime | dateFormat
|
||||
}}</a></el-col>
|
||||
</el-row>
|
||||
@ -220,7 +220,7 @@
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>来源系统:
|
||||
>{{ $t('pages.userBaseInfo.labels.sourceSystem') }}:
|
||||
<span
|
||||
v-if="
|
||||
!userBaseInfo.sysOriginChild ||
|
||||
@ -235,13 +235,13 @@
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>所属区域: {{ userBaseInfo.regionName }}
|
||||
>{{ $t('pages.userBaseInfo.labels.region') }}: {{ userBaseInfo.regionName }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div v-if="identity && identity.historyIdentity && identity.historyIdentity.length > 0" class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">历史身份: {{ identity.historyIdentity.join(",") }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.userBaseInfo.labels.historyIdentity') }}: {{ identity.historyIdentity.join(",") }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
@ -252,7 +252,7 @@
|
||||
:loading="authTypeLoading"
|
||||
type="text"
|
||||
@click="queryOpenId"
|
||||
>查看OPENID
|
||||
>{{ $t('pages.userBaseInfo.actions.viewOpenId') }}
|
||||
</el-button>
|
||||
<div v-else>
|
||||
<el-tooltip class="item" effect="dark">
|
||||
@ -260,7 +260,7 @@
|
||||
<div v-if="authType.openId">
|
||||
<p>{{ authType.openId }}</p>
|
||||
</div>
|
||||
<div v-else>Empty</div>
|
||||
<div v-else>{{ $t('pages.userBaseInfo.words.empty') }}</div>
|
||||
</div>
|
||||
<i
|
||||
style="cursor: pointer;"
|
||||
@ -281,7 +281,7 @@
|
||||
:loading="aTokenLoading"
|
||||
type="text"
|
||||
@click="queryAToken"
|
||||
>查看登录令牌
|
||||
>{{ $t('pages.userBaseInfo.actions.viewLoginToken') }}
|
||||
</el-button>
|
||||
<div v-else>
|
||||
<div>
|
||||
@ -290,10 +290,10 @@
|
||||
<el-tooltip class="item" effect="dark">
|
||||
<div slot="content">
|
||||
<div v-if="aToken.token">
|
||||
<p>点击可CopyToken</p>
|
||||
<p>{{ $t('pages.userBaseInfo.words.clickToCopyToken') }}</p>
|
||||
<p>AToken: {{ aToken.token }}</p>
|
||||
</div>
|
||||
<div v-else>未登录</div>
|
||||
<div v-else>{{ $t('pages.userBaseInfo.words.notLoggedIn') }}</div>
|
||||
</div>
|
||||
<i
|
||||
style="cursor: pointer;"
|
||||
@ -301,7 +301,7 @@
|
||||
@click="copyContent(aToken.token)"
|
||||
/>
|
||||
</el-tooltip>
|
||||
AToken:{{ aToken.token || "未登录" }}
|
||||
AToken:{{ aToken.token || $t('pages.userBaseInfo.words.notLoggedIn') }}
|
||||
</el-col>
|
||||
<el-col
|
||||
v-if="
|
||||
@ -320,7 +320,7 @@
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item
|
||||
@click.native="delToken()"
|
||||
>删除令牌
|
||||
>{{ $t('pages.userBaseInfo.actions.deleteToken') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
@click.native="
|
||||
@ -341,7 +341,7 @@
|
||||
</el-row>
|
||||
</div>
|
||||
<div v-if="userRegisterInfo.residentialAddress" class="text-item">
|
||||
居住地址:{{ userRegisterInfo.residentialAddress }}
|
||||
{{ $t('pages.userBaseInfo.labels.residentialAddress') }}:{{ userRegisterInfo.residentialAddress }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
@ -350,7 +350,7 @@
|
||||
"
|
||||
class="text-item flex-l"
|
||||
>
|
||||
佩戴道具:
|
||||
{{ $t('pages.userBaseInfo.labels.wearingProps') }}:
|
||||
<el-tooltip
|
||||
v-for="(item, index) in userRunProfile.useProps"
|
||||
:key="index"
|
||||
@ -360,12 +360,12 @@
|
||||
<div slot="content">
|
||||
<div v-if="item.propsResources">
|
||||
<div>ID:{{ item.propsResources.id }}</div>
|
||||
<div>道具类型:{{ item.propsResources.type }}</div>
|
||||
<div>道具编号:{{ item.propsResources.code }}</div>
|
||||
<div>道具名称:{{ item.propsResources.name }}</div>
|
||||
<div>{{ $t('pages.userBaseInfo.labels.propType') }}:{{ item.propsResources.type }}</div>
|
||||
<div>{{ $t('pages.userBaseInfo.labels.propCode') }}:{{ item.propsResources.code }}</div>
|
||||
<div>{{ $t('pages.userBaseInfo.labels.propName') }}:{{ item.propsResources.name }}</div>
|
||||
</div>
|
||||
<div>
|
||||
过期时间:{{
|
||||
{{ $t('pages.userBaseInfo.labels.expireTime') }}:{{
|
||||
item.expireTime | dateFormat("yyyy-MM-dd HH:mm:ss")
|
||||
}}
|
||||
</div>
|
||||
@ -383,7 +383,7 @@
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="" name="vipInfo">
|
||||
<template slot="title">
|
||||
<i class="el-icon-s-check" /> VIP权益
|
||||
<i class="el-icon-s-check" /> {{ $t('pages.userBaseInfo.sections.vipInfo') }}
|
||||
</template>
|
||||
<div v-loading="vipLoading" class="vip-info">
|
||||
<div class="blockquote-content block-info">
|
||||
@ -391,13 +391,13 @@
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>任意发言:
|
||||
{{ vipActualEquity.speak ? "Yes" : "No" }}
|
||||
>{{ $t('pages.userBaseInfo.labels.anySpeech') }}:
|
||||
{{ vipActualEquity.speak ? $t('pages.userBaseInfo.words.yes') : $t('pages.userBaseInfo.words.no') }}
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>防踢:
|
||||
{{ vipActualEquity.prohibitKick ? "Yes" : "No" }}
|
||||
>{{ $t('pages.userBaseInfo.labels.noKick') }}:
|
||||
{{ vipActualEquity.prohibitKick ? $t('pages.userBaseInfo.words.yes') : $t('pages.userBaseInfo.words.no') }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -405,13 +405,13 @@
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>任意上麦:
|
||||
{{ vipActualEquity.microphone ? "Yes" : "No" }}
|
||||
>{{ $t('pages.userBaseInfo.labels.anyMic') }}:
|
||||
{{ vipActualEquity.microphone ? $t('pages.userBaseInfo.words.yes') : $t('pages.userBaseInfo.words.no') }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<el-alert
|
||||
title="具备实际权益的VIP来源: 购买,朋友赠送,活动获得; 系统后台赠送则不存在VIP实际权益,所以会产生VIP5被踢出房间的情况."
|
||||
:title="$t('pages.userBaseInfo.messages.vipAlert')"
|
||||
type="warning"
|
||||
:closable="false"
|
||||
/>
|
||||
@ -428,15 +428,15 @@
|
||||
name="deviceInfo"
|
||||
>
|
||||
<template slot="title">
|
||||
<i class="el-icon-s-platform" /> 设备信息
|
||||
<i class="el-icon-s-platform" /> {{ $t('pages.userBaseInfo.sections.deviceInfo') }}
|
||||
</template>
|
||||
<div v-loading="deviceLoading" class="device-info">
|
||||
<div v-if="deviceFlash && !deviceInfo" class="text-center">
|
||||
没有设备信息
|
||||
{{ $t('pages.userBaseInfo.labels.noDeviceInfo') }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="blockquote">
|
||||
当前最新设备
|
||||
{{ $t('pages.userBaseInfo.labels.currentLatestDevice') }}
|
||||
</div>
|
||||
<div
|
||||
v-if="deviceInfo.latestDevice"
|
||||
@ -446,11 +446,11 @@
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>语言:{{ deviceInfo.latestDevice.language }}
|
||||
>{{ $t('pages.userBaseInfo.labels.language') }}:{{ deviceInfo.latestDevice.language }}
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>时区:{{ deviceInfo.latestDevice.zoneId }}
|
||||
>{{ $t('pages.userBaseInfo.labels.timezone') }}:{{ deviceInfo.latestDevice.zoneId }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -462,7 +462,7 @@
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>客户端:{{ deviceInfo.latestDevice.requestClient }}
|
||||
>{{ $t('pages.userBaseInfo.labels.client') }}:{{ deviceInfo.latestDevice.requestClient }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -471,12 +471,12 @@
|
||||
<el-col
|
||||
:span="12"
|
||||
class="nowrap-ellipsis"
|
||||
>设备型号:<a
|
||||
>{{ $t('pages.userBaseInfo.labels.deviceModel') }}:<a
|
||||
:title="deviceInfo.latestDevice.phoneModel"
|
||||
>{{ deviceInfo.latestDevice.phoneModel }}</a></el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>设备系统:{{ deviceInfo.latestDevice.phoneSysVersion }}
|
||||
>{{ $t('pages.userBaseInfo.labels.deviceSystem') }}:{{ deviceInfo.latestDevice.phoneSysVersion }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -485,11 +485,11 @@
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>编译版本:{{ deviceInfo.latestDevice.buildVersion }}
|
||||
>{{ $t('pages.userBaseInfo.labels.buildVersion') }}:{{ deviceInfo.latestDevice.buildVersion }}
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>App版本:{{ deviceInfo.latestDevice.appVersion }}
|
||||
>{{ $t('pages.userBaseInfo.labels.appVersion') }}:{{ deviceInfo.latestDevice.appVersion }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -498,11 +498,11 @@
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>Push平台:{{ deviceInfo.latestDevice.deviceType }}
|
||||
>{{ $t('pages.userBaseInfo.labels.pushPlatform') }}:{{ deviceInfo.latestDevice.deviceType }}
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>登记平台:{{ deviceInfo.latestDevice.sysOrigin }}
|
||||
>{{ $t('pages.userBaseInfo.labels.registerPlatformShort') }}:{{ deviceInfo.latestDevice.sysOrigin }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -512,7 +512,7 @@
|
||||
<el-col
|
||||
:span="24"
|
||||
class="nowrap-ellipsis"
|
||||
>Push设备:<a :title="deviceInfo.latestDevice.deviceId">{{
|
||||
>{{ $t('pages.userBaseInfo.labels.pushDevice') }}:<a :title="deviceInfo.latestDevice.deviceId">{{
|
||||
deviceInfo.latestDevice.deviceId
|
||||
}}</a></el-col>
|
||||
</el-row>
|
||||
@ -522,7 +522,7 @@
|
||||
<el-col
|
||||
:span="24"
|
||||
class="nowrap-ellipsis"
|
||||
>imei ID:<a :title="deviceInfo.latestDevice.imei">{{
|
||||
>{{ $t('pages.userBaseInfo.labels.imei') }}:<a :title="deviceInfo.latestDevice.imei">{{
|
||||
deviceInfo.latestDevice.imei
|
||||
}}</a></el-col>
|
||||
</el-row>
|
||||
@ -532,7 +532,7 @@
|
||||
<el-col
|
||||
:span="24"
|
||||
class="nowrap-ellipsis"
|
||||
>登记时间:<a
|
||||
>{{ $t('pages.userBaseInfo.labels.registerAt') }}:<a
|
||||
:title="deviceInfo.latestDevice.createTime | dateFormat"
|
||||
>{{
|
||||
deviceInfo.latestDevice.createTime | dateFormat
|
||||
@ -541,14 +541,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="text-center">
|
||||
当前用户没有登记设备信息
|
||||
{{ $t('pages.userBaseInfo.labels.noRegisteredDeviceInfo') }}
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="associatedDeviceNotEmpty || associatedIpNotEmpty"
|
||||
class="blockquote"
|
||||
>
|
||||
设备关联信息
|
||||
{{ $t('pages.userBaseInfo.labels.deviceAssociationInfo') }}
|
||||
</div>
|
||||
<div
|
||||
v-if="associatedDeviceNotEmpty || associatedIpNotEmpty"
|
||||
@ -557,7 +557,7 @@
|
||||
<el-tabs v-model="associatedDeviceTabActiveName">
|
||||
<el-tab-pane
|
||||
v-if="associatedDeviceNotEmpty"
|
||||
label="设备"
|
||||
:label="$t('pages.userBaseInfo.words.device')"
|
||||
name="associatedDevice"
|
||||
>
|
||||
<associated-device-timeline
|
||||
@ -580,50 +580,50 @@
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="" name="expendInfo">
|
||||
<template slot="title">
|
||||
<i class="el-icon-s-grid" /> 扩展信息
|
||||
<i class="el-icon-s-grid" /> {{ $t('pages.userBaseInfo.sections.expendInfo') }}
|
||||
</template>
|
||||
<div v-loading="expendLoading" class="expend-info">
|
||||
<div v-if="expendFlash && !expend.userId" class="text-center">
|
||||
没有找到Expend信息,数据异常请联系管理员!!!
|
||||
{{ $t('pages.userBaseInfo.labels.noExpendInfo') }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col :span="12">语言:{{ expend.language }}</el-col>
|
||||
<el-col :span="12">时区:{{ expend.lastZoneId }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.userBaseInfo.labels.language') }}:{{ expend.language }}</el-col>
|
||||
<el-col :span="12">{{ $t('pages.userBaseInfo.labels.timezone') }}:{{ expend.lastZoneId }}</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="text-item">
|
||||
<el-row>
|
||||
<el-col
|
||||
:span="12"
|
||||
>购买过:{{ expend.purchasing === true ? "是" : "否" }}
|
||||
>{{ $t('pages.userBaseInfo.labels.purchased') }}:{{ expend.purchasing === true ? $t('pages.userBaseInfo.words.purchasedYes') : $t('pages.userBaseInfo.words.purchasedNo') }}
|
||||
</el-col>
|
||||
<el-col
|
||||
:span="12"
|
||||
>活跃时间:{{ expend.lastActiveTime | dateFormat }}
|
||||
>{{ $t('pages.userBaseInfo.labels.activeTime') }}:{{ expend.lastActiveTime | dateFormat }}
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div v-if="expend.registerCountryCode" class="text-item">
|
||||
注册国家:{{ expend.registerCountryCode }}
|
||||
{{ $t('pages.userBaseInfo.labels.registerCountry') }}:{{ expend.registerCountryCode }}
|
||||
</div>
|
||||
<div v-if="expend.signature" class="text-item">
|
||||
个性签名:{{ expend.signature }}
|
||||
{{ $t('pages.userBaseInfo.labels.signature') }}:{{ expend.signature }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="" name="giftWall">
|
||||
<template slot="title">
|
||||
<i class="el-icon-s-cooperation" /> 礼物墙
|
||||
<i class="el-icon-s-cooperation" /> {{ $t('pages.userBaseInfo.sections.giftWall') }}
|
||||
</template>
|
||||
|
||||
<div
|
||||
v-if="giftWallsFlash && giftWalls.length <= 0"
|
||||
class="text-center"
|
||||
>
|
||||
没有礼物信息, 快去给他送点吧!
|
||||
{{ $t('pages.userBaseInfo.labels.noGiftInfo') }}
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="photo-wall">
|
||||
@ -647,7 +647,7 @@
|
||||
</div>
|
||||
|
||||
<el-dialog
|
||||
title="运行缓存数据"
|
||||
:title="$t('pages.userBaseInfo.sections.runtimeCacheData')"
|
||||
:visible.sync="userRunProfileVisible"
|
||||
:append-to-body="true"
|
||||
>
|
||||
@ -859,7 +859,7 @@ export default {
|
||||
}
|
||||
const account = baseInfo.account
|
||||
if (baseInfo.ownSpecialId && baseInfo.ownSpecialId.account) {
|
||||
return `${account} / ${baseInfo.ownSpecialId.account}靓`
|
||||
return `${account} / ${baseInfo.ownSpecialId.account}${this.$t('pages.userBaseInfo.labels.specialIdSuffix')}`
|
||||
}
|
||||
return account
|
||||
},
|
||||
|
||||
@ -105,7 +105,7 @@ export default {
|
||||
return 'error'
|
||||
}
|
||||
if (this.isSpecialId) {
|
||||
return `${this.userProfile.ownSpecialId.account}靓`
|
||||
return `${this.userProfile.ownSpecialId.account}${this.$t('pages.userBaseInfo.labels.specialIdSuffix')}`
|
||||
}
|
||||
return this.userProfile.account
|
||||
},
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { localizeCollection } from '@/lang'
|
||||
|
||||
/**
|
||||
* Element UI 组件属性管理
|
||||
* @auth pengliang
|
||||
@ -62,5 +64,8 @@ const pickerOptions = {
|
||||
}
|
||||
}]
|
||||
}
|
||||
|
||||
localizeCollection(pickerOptions)
|
||||
|
||||
export { pickerOptions }
|
||||
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import { localizeCollection } from '@/lang'
|
||||
|
||||
/**
|
||||
* 家族等级Key集合
|
||||
@ -40,6 +41,8 @@ const familyTypes = [
|
||||
{ value: 'PLATINUM', name: '铂金' }
|
||||
]
|
||||
|
||||
localizeCollection([familyLevelKeys, familyRoles, familyTypes])
|
||||
|
||||
export {
|
||||
familyLevelKeys,
|
||||
familyRoles,
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
// 注册来源
|
||||
import { localizeCollection } from '@/lang'
|
||||
|
||||
const registerOrigins = [
|
||||
{ value: "MOBILE", name: "手机号码" },
|
||||
{ value: "APPLE", name: "Apple" },
|
||||
@ -84,6 +86,20 @@ const badgeTypes = [
|
||||
{ value: "HONOR_ACTIVITY", name: "荣誉-活动" }
|
||||
];
|
||||
|
||||
localizeCollection([
|
||||
registerOrigins,
|
||||
originPlatforms,
|
||||
appPlatforms,
|
||||
deviceTypes,
|
||||
payPlatforms,
|
||||
sysPlatforms,
|
||||
sysOriginPlatforms,
|
||||
giftType,
|
||||
giftInfo,
|
||||
propsGiveTypes,
|
||||
badgeTypes
|
||||
])
|
||||
|
||||
export {
|
||||
badgeTypes,
|
||||
propsGiveTypes,
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { localizeCollection } from '@/lang'
|
||||
|
||||
/**
|
||||
* 团队相关类型定义.
|
||||
*/
|
||||
@ -131,6 +133,19 @@ const bdApprovalReasons = [
|
||||
{ value: 'ACCEPT_BD_INVITE', name: '接受成为BD邀请' }
|
||||
]
|
||||
|
||||
localizeCollection([
|
||||
teamStatus,
|
||||
contactTypes,
|
||||
bankCardType,
|
||||
teamMemberRoles,
|
||||
teamBillStatus,
|
||||
teamBillSettleTypes,
|
||||
teamApplicationProcessStatusList,
|
||||
teamReasons,
|
||||
teamApprovalReasons,
|
||||
bdApprovalReasons
|
||||
])
|
||||
|
||||
export {
|
||||
teamBillSettleTypeMap,
|
||||
teamBillSettleTypes,
|
||||
|
||||
249
src/lang/index.js
Normal file
249
src/lang/index.js
Normal file
@ -0,0 +1,249 @@
|
||||
import elementLocale from 'element-ui/lib/locale'
|
||||
import enElement from 'element-ui/lib/locale/lang/en'
|
||||
import zhElement from 'element-ui/lib/locale/lang/zh-CN'
|
||||
|
||||
const DEFAULT_LOCALE = 'en'
|
||||
const MESSAGE_FIELDS = ['name', 'label', 'title', 'help', 'msg', 'text', 'placeholder', 'content']
|
||||
const TIMEZONE_LOCALE_MAP = {
|
||||
zh: [
|
||||
'Asia/Shanghai',
|
||||
'Asia/Urumqi',
|
||||
'Asia/Chongqing',
|
||||
'Asia/Harbin',
|
||||
'Asia/Hong_Kong',
|
||||
'Asia/Macau',
|
||||
'Asia/Taipei'
|
||||
],
|
||||
bn: [
|
||||
'Asia/Dhaka'
|
||||
],
|
||||
tr: [
|
||||
'Europe/Istanbul'
|
||||
],
|
||||
ar: [
|
||||
'Asia/Riyadh',
|
||||
'Asia/Dubai',
|
||||
'Asia/Kuwait',
|
||||
'Asia/Qatar',
|
||||
'Asia/Bahrain',
|
||||
'Asia/Muscat',
|
||||
'Asia/Aden',
|
||||
'Asia/Baghdad',
|
||||
'Asia/Damascus',
|
||||
'Asia/Amman',
|
||||
'Asia/Beirut',
|
||||
'Asia/Jerusalem',
|
||||
'Africa/Cairo',
|
||||
'Africa/Tripoli',
|
||||
'Africa/Tunis',
|
||||
'Africa/Algiers',
|
||||
'Africa/Casablanca',
|
||||
'Africa/Khartoum'
|
||||
]
|
||||
}
|
||||
let activeStore = null
|
||||
const elementLocales = {
|
||||
en: enElement,
|
||||
zh: zhElement
|
||||
}
|
||||
const messageContext = require.context('./messages', false, /\.js$/)
|
||||
const messages = messageContext.keys().reduce((result, filePath) => {
|
||||
const locale = filePath.replace('./', '').replace(/\.js$/, '')
|
||||
const localeModule = messageContext(filePath)
|
||||
result[locale] = localeModule.default || localeModule
|
||||
return result
|
||||
}, {})
|
||||
const localeOptions = Object.keys(messages)
|
||||
.sort((left, right) => {
|
||||
if (left === DEFAULT_LOCALE) {
|
||||
return -1
|
||||
}
|
||||
if (right === DEFAULT_LOCALE) {
|
||||
return 1
|
||||
}
|
||||
return left.localeCompare(right)
|
||||
})
|
||||
.map(locale => {
|
||||
const meta = messages[locale] && messages[locale].meta ? messages[locale].meta : {}
|
||||
const fallbackLabel = locale.toUpperCase()
|
||||
return {
|
||||
value: locale,
|
||||
label: meta.label || fallbackLabel,
|
||||
nativeLabel: meta.nativeLabel || meta.label || fallbackLabel
|
||||
}
|
||||
})
|
||||
|
||||
function normalizeLocale(locale) {
|
||||
return Object.prototype.hasOwnProperty.call(messages, locale) ? locale : DEFAULT_LOCALE
|
||||
}
|
||||
|
||||
export function getLocaleOptions() {
|
||||
return localeOptions.slice()
|
||||
}
|
||||
|
||||
export function getCurrentTimeZone() {
|
||||
try {
|
||||
return new Intl.DateTimeFormat().resolvedOptions().timeZone || ''
|
||||
} catch (error) {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
export function detectLocaleByTimeZone(timeZone = getCurrentTimeZone()) {
|
||||
if (!timeZone) {
|
||||
return DEFAULT_LOCALE
|
||||
}
|
||||
|
||||
const matchedLocale = Object.keys(TIMEZONE_LOCALE_MAP).find(locale => {
|
||||
if (!Object.prototype.hasOwnProperty.call(messages, locale)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return TIMEZONE_LOCALE_MAP[locale].some(pattern => {
|
||||
return timeZone === pattern || timeZone.indexOf(`${pattern}/`) === 0
|
||||
})
|
||||
})
|
||||
|
||||
return normalizeLocale(matchedLocale || DEFAULT_LOCALE)
|
||||
}
|
||||
|
||||
function getMessage(locale, key) {
|
||||
if (!key || !messages[locale]) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const localeMessages = messages[locale]
|
||||
if (Object.prototype.hasOwnProperty.call(localeMessages, key)) {
|
||||
return localeMessages[key]
|
||||
}
|
||||
|
||||
return key.split('.').reduce((result, current) => {
|
||||
if (result == null) {
|
||||
return undefined
|
||||
}
|
||||
return result[current]
|
||||
}, localeMessages)
|
||||
}
|
||||
|
||||
export function getLocale() {
|
||||
if (!activeStore || !activeStore.state || !activeStore.state.app) {
|
||||
return DEFAULT_LOCALE
|
||||
}
|
||||
return normalizeLocale(activeStore.state.app.language)
|
||||
}
|
||||
|
||||
export function translate(key, params) {
|
||||
if (typeof key !== 'string' || key.length === 0) {
|
||||
return key
|
||||
}
|
||||
|
||||
const locale = getLocale()
|
||||
const localeText = getMessage(locale, key)
|
||||
let text = localeText
|
||||
|
||||
if (text == null) {
|
||||
if (locale === 'zh') {
|
||||
text = key
|
||||
} else {
|
||||
text = getMessage(DEFAULT_LOCALE, key)
|
||||
}
|
||||
}
|
||||
|
||||
if (text == null) {
|
||||
text = key
|
||||
}
|
||||
|
||||
if (!params || typeof text !== 'string') {
|
||||
return text
|
||||
}
|
||||
|
||||
return Object.keys(params).reduce((result, name) => {
|
||||
return result.replace(new RegExp(`\\{${name}\\}`, 'g'), params[name])
|
||||
}, text)
|
||||
}
|
||||
|
||||
export function translateRouteTitle(title) {
|
||||
return translate(title)
|
||||
}
|
||||
|
||||
function bindField(target, field) {
|
||||
if (!target || !Object.prototype.hasOwnProperty.call(target, field)) {
|
||||
return
|
||||
}
|
||||
|
||||
const descriptor = Object.getOwnPropertyDescriptor(target, field)
|
||||
if (!descriptor || descriptor.get || typeof descriptor.value !== 'string') {
|
||||
return
|
||||
}
|
||||
|
||||
const cacheKey = `__i18n_${field}`
|
||||
Object.defineProperty(target, cacheKey, {
|
||||
value: descriptor.value,
|
||||
enumerable: false,
|
||||
configurable: true,
|
||||
writable: true
|
||||
})
|
||||
|
||||
Object.defineProperty(target, field, {
|
||||
enumerable: true,
|
||||
configurable: true,
|
||||
get() {
|
||||
return translate(this[cacheKey])
|
||||
},
|
||||
set(value) {
|
||||
this[cacheKey] = value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function localizeCollection(collection, fields = MESSAGE_FIELDS, weakSet = new WeakSet()) {
|
||||
if (!collection || typeof collection !== 'object' || weakSet.has(collection)) {
|
||||
return collection
|
||||
}
|
||||
|
||||
weakSet.add(collection)
|
||||
|
||||
if (Array.isArray(collection)) {
|
||||
collection.forEach(item => localizeCollection(item, fields, weakSet))
|
||||
return collection
|
||||
}
|
||||
|
||||
fields.forEach(field => bindField(collection, field))
|
||||
|
||||
Object.keys(collection).forEach(key => {
|
||||
localizeCollection(collection[key], fields, weakSet)
|
||||
})
|
||||
|
||||
return collection
|
||||
}
|
||||
|
||||
export function setLocale(locale) {
|
||||
const nextLocale = normalizeLocale(locale)
|
||||
if (activeStore && activeStore.state && activeStore.state.app && activeStore.state.app.language !== nextLocale) {
|
||||
activeStore.dispatch('app/setLanguage', nextLocale)
|
||||
}
|
||||
elementLocale.use(elementLocales[nextLocale] || elementLocales[DEFAULT_LOCALE])
|
||||
return nextLocale
|
||||
}
|
||||
|
||||
export function attachStore(store) {
|
||||
activeStore = store
|
||||
}
|
||||
|
||||
const i18nPlugin = {
|
||||
install(Vue) {
|
||||
Vue.prototype.$t = function(key, params) {
|
||||
return translate(key, params)
|
||||
}
|
||||
Vue.prototype.$setLocale = function(locale) {
|
||||
return setLocale(locale)
|
||||
}
|
||||
Object.defineProperty(Vue.prototype, '$locale', {
|
||||
get() {
|
||||
return getLocale()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default i18nPlugin
|
||||
48
src/lang/messages/base/en.js
Normal file
48
src/lang/messages/base/en.js
Normal file
@ -0,0 +1,48 @@
|
||||
import menuMessages from './menu-en'
|
||||
|
||||
export default {
|
||||
meta: {
|
||||
label: 'English',
|
||||
nativeLabel: 'English'
|
||||
},
|
||||
nav: {
|
||||
home: 'Home'
|
||||
},
|
||||
common: {
|
||||
language: 'Language',
|
||||
search: 'Search',
|
||||
globalSize: 'Global Size',
|
||||
resetPassword: 'Reset Password',
|
||||
logout: 'Logout',
|
||||
cancel: 'Cancel',
|
||||
submit: 'Submit'
|
||||
},
|
||||
auth: {
|
||||
login: 'Login',
|
||||
username: 'Username',
|
||||
password: 'Password',
|
||||
invalidUsername: 'Please enter the correct user name',
|
||||
invalidPasswordLength: 'The password can not be less than 4 digits'
|
||||
},
|
||||
password: {
|
||||
title: 'Reset Password',
|
||||
old: 'Original Password',
|
||||
new: 'New Password',
|
||||
confirm: 'Confirm Password',
|
||||
placeholderOld: 'Please enter the original password',
|
||||
placeholderNew: 'Please enter the new password',
|
||||
placeholderConfirm: 'Please confirm the password',
|
||||
required: 'Required field cannot be empty',
|
||||
invalidLength: 'The password can not be less than 4 digits',
|
||||
mismatch: 'Passwords do not match',
|
||||
processing: 'Processing submission, please wait'
|
||||
},
|
||||
size: {
|
||||
default: 'Default',
|
||||
medium: 'Medium',
|
||||
small: 'Small',
|
||||
mini: 'Mini',
|
||||
switchSuccess: 'Switch Size Success'
|
||||
},
|
||||
...menuMessages
|
||||
}
|
||||
192
src/lang/messages/base/menu-en.js
Normal file
192
src/lang/messages/base/menu-en.js
Normal file
@ -0,0 +1,192 @@
|
||||
export default {
|
||||
'系统管理': 'System Management',
|
||||
'用户管理': 'User Management',
|
||||
'角色管理': 'Role Management',
|
||||
'菜单管理': 'Menu Management',
|
||||
'资源管理': 'Resource Management',
|
||||
'App系统': 'App System',
|
||||
'版本管理': 'Version Management',
|
||||
'APP运行日志': 'App Runtime Logs',
|
||||
'IM通讯': 'IM Communication',
|
||||
'请求黑名单': 'Request Blacklist',
|
||||
'工具管理': 'Tools Management',
|
||||
'Redis缓存管理': 'Redis Cache Management',
|
||||
'订单补偿': 'Order Compensation',
|
||||
'金币分析': 'Gold Analysis',
|
||||
'小工具': 'Utilities',
|
||||
'文件上传': 'File Upload',
|
||||
'Api请求日志': 'API Request Logs',
|
||||
'金币流水分析': 'Gold Transaction Analysis',
|
||||
'Socket测试': 'Socket Test',
|
||||
'金币流水图表': 'Gold Transaction Charts',
|
||||
'系统监控': 'System Monitor',
|
||||
'用户列表': 'User List',
|
||||
'用户专属礼物制作': 'Custom User Gift Creation',
|
||||
'封禁设备列表': 'Blocked Device List',
|
||||
'最新登记设备': 'Latest Registered Devices',
|
||||
'喇叭黑名单': 'Trumpet Blacklist',
|
||||
'用户充值黑名单': 'User Recharge Blacklist',
|
||||
'运营管理': 'Operations Management',
|
||||
'营收支出': 'Revenue and Expenses',
|
||||
'消费商品订单': 'Consumable Product Orders',
|
||||
'金币收支记录': 'Gold Transaction Records',
|
||||
'钻石流水列表': 'Diamond Transaction List',
|
||||
'积分收支记录': 'Points Transaction Records',
|
||||
'金币代理流水': 'Gold Agent Transactions',
|
||||
'钻石余额列表': 'Diamond Balance List',
|
||||
'高产用户列表': 'High Output User List',
|
||||
'Stripe订单': 'Stripe Orders',
|
||||
'异常订单': 'Abnormal Orders',
|
||||
'退款记录': 'Refund Records',
|
||||
'游戏券收支记录': 'Game Coupon Transaction Records',
|
||||
'收款单': 'Receipts',
|
||||
'订单详情': 'Order Details',
|
||||
'内部操作金币': 'Internal Gold Operations',
|
||||
'数据配置': 'Data Configuration',
|
||||
'参数配置': 'Parameter Settings',
|
||||
'幸运礼物规则配置': 'Lucky Gift Rule Configuration',
|
||||
'幸运礼物规格配置': 'Lucky Gift Specification Configuration',
|
||||
'用户观看广告配置': 'User Ad View Configuration',
|
||||
'礼物管理': 'Gift Management',
|
||||
'IM账号管理': 'IM Account Management',
|
||||
'Banner管理': 'Banner Management',
|
||||
'房间主题管理': 'Room Theme Management',
|
||||
'国家管理': 'Country Management',
|
||||
'徽章配置管理': 'Badge Configuration Management',
|
||||
'表情管理': 'Emoji Management',
|
||||
'转盘抽奖品配置': 'Spin Wheel Prize Configuration',
|
||||
'靓号管理': 'Special ID Management',
|
||||
'邀请用户配置': 'Invite User Configuration',
|
||||
'用户友谊卡配置': 'User Friendship Card Configuration',
|
||||
'游戏列表': 'Game List',
|
||||
'名人堂': 'Hall of Fame',
|
||||
'CP小屋配置': 'CP Cabin Configuration',
|
||||
'麦位类型管理': 'Mic Slot Type Management',
|
||||
'活动图片配置': 'Activity Image Configuration',
|
||||
'摩天轮任务配置': 'Ferris Wheel Task Configuration',
|
||||
'运营日志': 'Operations Logs',
|
||||
'礼物赠送记录': 'Gift Sending Records',
|
||||
'用户道具流水': 'User Prop Transactions',
|
||||
'红包发送记录': 'Red Packet Send Records',
|
||||
'退款扣除目标': 'Refund Deduction Targets',
|
||||
'房间支持活动': 'Room Support Activities',
|
||||
'代理活动历史': 'Agent Activity History',
|
||||
'现金邀请用户': 'Cash Invite Users',
|
||||
'邀请配置': 'Invite Configuration',
|
||||
'助力日志': 'Assistance Logs',
|
||||
'临时提现': 'Temporary Withdrawals',
|
||||
'红包邀新用户': 'Red Packet User Invitations',
|
||||
'转盘配置': 'Carousel Configuration',
|
||||
'邀新配置': 'Invite-New Configuration',
|
||||
'用户目标': 'User Targets',
|
||||
'开红包记录': 'Red Packet Opening Records',
|
||||
'抽奖日志': 'Draw Logs',
|
||||
'邀请用户': 'Invite Users',
|
||||
'幸运礼物送礼记录': 'Lucky Gift Sending Records',
|
||||
'注销日志': 'Logout Logs',
|
||||
'注销申请': 'Logout Requests',
|
||||
'活动领奖记录': 'Activity Reward Records',
|
||||
'用户签到': 'User Check-ins',
|
||||
'砸金蛋记录': 'Golden Egg Smash Records',
|
||||
'登录日志': 'Login Logs',
|
||||
'Ludo飞行棋': 'Ludo',
|
||||
'PK记录': 'PK Records',
|
||||
'CP申请日志': 'CP Application Logs',
|
||||
'世界杯': 'World Cup',
|
||||
'购买麦位记录': 'Mic Slot Purchase Records',
|
||||
'用户密码日志': 'User Password Logs',
|
||||
'内购配置': 'In-App Purchase Configuration',
|
||||
'渠道管理': 'Channel Management',
|
||||
'厂商管理': 'Provider Management',
|
||||
'区域关联支付国家': 'Region-Payment Country Relations',
|
||||
'开通支付国家': 'Enabled Payment Countries',
|
||||
'应用管理': 'Application Management',
|
||||
'Google/Apple-V2': 'Google/Apple V2',
|
||||
'活动配置': 'Activity Configuration',
|
||||
'活动管理': 'Activity Management',
|
||||
'活动模版': 'Activity Templates',
|
||||
'活动规则配置': 'Activity Rule Configuration',
|
||||
'KTV音乐': 'KTV Music',
|
||||
'音乐管理': 'Music Management',
|
||||
'礼物配置': 'Gift Configuration',
|
||||
'热门歌曲': 'Popular Songs',
|
||||
'点歌记录': 'Song Request Records',
|
||||
'消息推送': 'Message Push',
|
||||
'数据大屏': 'Data Dashboard',
|
||||
'APP管理员': 'App Administrators',
|
||||
'系统公告管理': 'System Notice Management',
|
||||
'金币代理': 'Gold Agents',
|
||||
'申请靓号': 'Apply for Special ID',
|
||||
'App启动页': 'App Launch Page',
|
||||
'客服列表': 'Customer Service List',
|
||||
'金币余额榜': 'Gold Balance Leaderboard',
|
||||
'区域配置': 'Region Configuration',
|
||||
'用户银行': 'User Bank',
|
||||
'目标兑换工资记录': 'Target Salary Exchange Records',
|
||||
'用户银行流水': 'User Bank Transactions',
|
||||
'用户银行账户': 'User Bank Accounts',
|
||||
'美金兑换金币记录': 'USD-to-Gold Exchange Records',
|
||||
'现金提现申请': 'Cash Withdrawal Applications',
|
||||
'自动支付工资凭据': 'Automatic Salary Payment Vouchers',
|
||||
'用户工资钻石': 'User Salary Diamonds',
|
||||
'用户工资钻石账户': 'User Salary Diamond Accounts',
|
||||
'用户工资钻石流水': 'User Salary Diamond Transactions',
|
||||
'钻石提现申请': 'Diamond Withdrawal Applications',
|
||||
'钻石兑换金币记录': 'Diamond-to-Gold Exchange Records',
|
||||
'语音房间': 'Voice Rooms',
|
||||
'在线房间': 'Online Rooms',
|
||||
'房间贡献余额': 'Room Contribution Balance',
|
||||
'房间资料列表': 'Room Profile List',
|
||||
'置顶房间': 'Pinned Rooms',
|
||||
'热门房间': 'Popular Rooms',
|
||||
'房间黑名单': 'Room Blacklist',
|
||||
'家族管理': 'Family Management',
|
||||
'家族配置': 'Family Configuration',
|
||||
'家族列表': 'Family List',
|
||||
'审批管理': 'Approval Management',
|
||||
'用户头像': 'User Avatar',
|
||||
'用户照片墙': 'User Photo Wall',
|
||||
'用户昵称': 'User Nickname',
|
||||
'举报信息': 'Reports',
|
||||
'意见反馈': 'Feedback',
|
||||
'用户个性签名': 'User Profile Signatures',
|
||||
'房间封面': 'Room Covers',
|
||||
'房间通知': 'Room Notices',
|
||||
'房间名称': 'Room Names',
|
||||
'违规历史记录': 'Violation History',
|
||||
'CP告白审核': 'CP Confession Review',
|
||||
'游戏白名单': 'Game Whitelist',
|
||||
'KYC身份审核': 'KYC Identity Review',
|
||||
'房间主题审批': 'Room Theme Approval',
|
||||
'家族资料审批': 'Family Profile Review',
|
||||
'动态内容审核': 'Post Content Review',
|
||||
'动态举报审批': 'Post Report Review',
|
||||
'喇叭审批': 'Trumpet Review',
|
||||
'用户银行卡审批': 'User Bank Card Review',
|
||||
'道具管理': 'Prop Management',
|
||||
'资源配置': 'Resource Configuration',
|
||||
'资源组配置': 'Resource Group Configuration',
|
||||
'道具赠送': 'Prop Gift',
|
||||
'道具商店': 'Prop Store',
|
||||
'宠物管理': 'Pet Management',
|
||||
'宠物池': 'Pet Pool',
|
||||
'豆子余额列表': 'Bean Balance List',
|
||||
'豆子流水': 'Bean Transactions',
|
||||
'宠物喂养记录': 'Pet Feeding Records',
|
||||
'动态管理': 'Dynamic Management',
|
||||
'标签': 'Tags',
|
||||
'动态配置': 'Post Configuration',
|
||||
'用户动态': 'User Posts',
|
||||
'动态黑名单': 'Post Blacklist',
|
||||
'主播中心': 'Broadcaster Center',
|
||||
'代理钻石政策': 'Agent Diamond Policy',
|
||||
'BD Lead': 'BD Lead',
|
||||
'代理政策': 'Agent Policy',
|
||||
'BD工作统计': 'BD Work Statistics',
|
||||
'BD列表': 'BD List',
|
||||
'代理列表': 'Agent List',
|
||||
'主播成员': 'Broadcaster Members',
|
||||
'账单列表': 'Bill List',
|
||||
'主播工作': 'Broadcaster Work',
|
||||
'成员审核日志': 'Member Review Logs'
|
||||
}
|
||||
45
src/lang/messages/base/zh.js
Normal file
45
src/lang/messages/base/zh.js
Normal file
@ -0,0 +1,45 @@
|
||||
export default {
|
||||
meta: {
|
||||
label: 'Chinese',
|
||||
nativeLabel: '\u4e2d\u6587'
|
||||
},
|
||||
nav: {
|
||||
home: '\u9996\u9875'
|
||||
},
|
||||
common: {
|
||||
language: '\u8bed\u8a00',
|
||||
search: '\u641c\u7d22',
|
||||
globalSize: '\u5168\u5c40\u5c3a\u5bf8',
|
||||
resetPassword: '\u4fee\u6539\u5bc6\u7801',
|
||||
logout: '\u9000\u51fa\u767b\u5f55',
|
||||
cancel: '\u53d6\u6d88',
|
||||
submit: '\u63d0\u4ea4'
|
||||
},
|
||||
auth: {
|
||||
login: '\u767b\u5f55',
|
||||
username: '\u7528\u6237\u540d',
|
||||
password: '\u5bc6\u7801',
|
||||
invalidUsername: '\u8bf7\u8f93\u5165\u6b63\u786e\u7684\u7528\u6237\u540d',
|
||||
invalidPasswordLength: '\u5bc6\u7801\u4e0d\u80fd\u5c11\u4e8e4\u4f4d'
|
||||
},
|
||||
password: {
|
||||
title: '\u91cd\u7f6e\u5bc6\u7801',
|
||||
old: '\u539f\u59cb\u5bc6\u7801',
|
||||
new: '\u65b0\u5bc6\u7801',
|
||||
confirm: '\u786e\u8ba4\u5bc6\u7801',
|
||||
placeholderOld: '\u8bf7\u8f93\u5165\u539f\u59cb\u5bc6\u7801',
|
||||
placeholderNew: '\u8bf7\u8f93\u5165\u65b0\u5bc6\u7801',
|
||||
placeholderConfirm: '\u8bf7\u8f93\u5165\u786e\u8ba4\u5bc6\u7801',
|
||||
required: '\u5fc5\u586b\u5b57\u6bb5\u4e0d\u80fd\u4e3a\u7a7a',
|
||||
invalidLength: '\u5bc6\u7801\u4e0d\u80fd\u5c11\u4e8e4\u4f4d',
|
||||
mismatch: '\u4e24\u6b21\u5bc6\u7801\u8f93\u5165\u4e0d\u4e00\u81f4',
|
||||
processing: '\u6b63\u5728\u5904\u7406\u63d0\u4ea4\uff0c\u8bf7\u7a0d\u5019'
|
||||
},
|
||||
size: {
|
||||
default: '\u9ed8\u8ba4',
|
||||
medium: '\u4e2d\u7b49',
|
||||
small: '\u5c0f',
|
||||
mini: '\u8ff7\u4f60',
|
||||
switchSuccess: '\u5207\u6362\u5c3a\u5bf8\u6210\u529f'
|
||||
}
|
||||
}
|
||||
306
src/lang/messages/en.js
Normal file
306
src/lang/messages/en.js
Normal file
@ -0,0 +1,306 @@
|
||||
import semantic from './base/en'
|
||||
import pageMessages from './pages/en'
|
||||
|
||||
export default {
|
||||
...semantic,
|
||||
...pageMessages,
|
||||
'首页': 'Home',
|
||||
'用户详情': 'User Details',
|
||||
'团队管理': 'Team Management',
|
||||
'团队政策': 'Team Policy',
|
||||
'团队钻石政策': 'Team Diamond Policy',
|
||||
'团队列表': 'Team List',
|
||||
'成员列表': 'Members',
|
||||
'账单列表': 'Bills',
|
||||
'成员工作': 'Member Work',
|
||||
'成员审核日志': 'Member Review Logs',
|
||||
'动态管理': 'Dynamic Management',
|
||||
'标签列表': 'Tag List',
|
||||
'权重配置': 'Weight Configuration',
|
||||
'用户动态': 'User Posts',
|
||||
'黑名单': 'Blacklist',
|
||||
'家族管理': 'Family Management',
|
||||
'家族配置': 'Family Settings',
|
||||
'家族列表': 'Family List',
|
||||
'宠物管理': 'Pet Management',
|
||||
'宠物喂养记录': 'Pet Feeding Records',
|
||||
'豆子账户': 'Bean Account',
|
||||
'豆子流水': 'Bean Transactions',
|
||||
'宠物池': 'Pet Pool',
|
||||
'道具管理': 'Props Management',
|
||||
'道具赠送': 'Props Gift',
|
||||
'资源配置': 'Resource Configuration',
|
||||
'道具资源组配置': 'Prop Resource Group Settings',
|
||||
'活动道具规则配置': 'Activity Prop Rule Settings',
|
||||
'道具商店': 'Prop Store',
|
||||
'工具管理': 'Tools',
|
||||
'请求黑名单': 'Request Blacklist',
|
||||
'金币分析': 'Gold Analysis',
|
||||
'Redis缓存管理': 'Redis Cache Management',
|
||||
'文件上传': 'File Upload',
|
||||
'Socket测试': 'Socket Test',
|
||||
'App系统管理': 'App System Management',
|
||||
'登陆日志': 'Login Logs',
|
||||
'房间黑名单': 'Room Blacklist',
|
||||
'请求日志': 'Request Logs',
|
||||
'靓号管理': 'Special ID Management',
|
||||
'文档管理': 'Document Management',
|
||||
'IM通讯': 'IM Communication',
|
||||
'版本管理': 'Version Management',
|
||||
'参数配置管理': 'Parameter Management',
|
||||
'参数配置': 'Parameter Settings',
|
||||
'内购产品配置V2': 'In-app Product Configuration V2',
|
||||
'封禁设备': 'Blocked Devices',
|
||||
'表情管理': 'Emoji Management',
|
||||
'系统管理': 'System Management',
|
||||
'区域配置': 'Region Settings',
|
||||
'用户管理': 'User Management',
|
||||
'角色管理': 'Role Management',
|
||||
'菜单管理': 'Menu Management',
|
||||
'资源管理': 'Resource Management',
|
||||
'统计管理': 'Statistics',
|
||||
'数据大屏': 'Data Dashboard',
|
||||
'运营管理': 'Operations',
|
||||
'代理活动': 'Agent Activities',
|
||||
'金币余额': 'Gold Balance',
|
||||
'自动发放工资凭据': 'Automatic Payroll Vouchers',
|
||||
'用户银行卡提现现金申请': 'User Bank Card Cash Withdrawal Requests',
|
||||
'用户银行卡提现钻石申请': 'User Bank Card Diamond Withdrawal Requests',
|
||||
'用户银行金币兑换申请': 'User Bank Gold Exchange Requests',
|
||||
'用户银行卡钻石兑换金币申请': 'User Bank Card Diamond-to-Gold Requests',
|
||||
'用户银行账户': 'User Bank Accounts',
|
||||
'用户银行流水': 'User Bank Transactions',
|
||||
'客服列表': 'Customer Service List',
|
||||
'CP申请': 'CP Applications',
|
||||
'PK记录': 'PK Records',
|
||||
'邀请用户日志': 'Invite User Logs',
|
||||
'活动配置': 'Activity Configuration',
|
||||
'活动模版': 'Activity Templates',
|
||||
'用户友谊卡配置': 'User Friendship Card Settings',
|
||||
'邀请用户配置': 'Invite User Settings',
|
||||
'用户观看广告配置': 'User Ad View Settings',
|
||||
'Ludo飞行棋': 'Ludo',
|
||||
'置顶房间': 'Pinned Rooms',
|
||||
'热门房间': 'Popular Rooms',
|
||||
'退款扣除目标': 'Refund Deduction Targets',
|
||||
'开通支付国家': 'Enabled Payment Countries',
|
||||
'支付区域关系': 'Payment Region Relations',
|
||||
'应用管理': 'Application Management',
|
||||
'支付厂商': 'Payment Providers',
|
||||
'支付渠道': 'Payment Channels',
|
||||
'抽奖品配置': 'Lottery Prize Settings',
|
||||
'货运代理': 'Freight Agent',
|
||||
'BD列表': 'BD List',
|
||||
'邀请用户奖励记录': 'Invite User Reward Records',
|
||||
'IM账号管理': 'IM Account Management',
|
||||
'用户签到': 'User Check-ins',
|
||||
'用户列表': 'User List',
|
||||
'用户最新设备列表': 'Latest User Devices',
|
||||
'APP管理员': 'App Administrators',
|
||||
'订单补偿': 'Order Compensation',
|
||||
'小工具': 'Utilities',
|
||||
'异常订单': 'Abnormal Orders',
|
||||
'货运代理流水': 'Freight Agent Transactions',
|
||||
'高产用户列表': 'High Output Users',
|
||||
'金币收支记录': 'Gold Transaction Records',
|
||||
'内部操作金币': 'Internal Gold Operations',
|
||||
'游戏券收支记录': 'Game Coupon Transaction Records',
|
||||
'积分收支记录': 'Points Transaction Records',
|
||||
'订单详情': 'Order Details',
|
||||
'退款记录': 'Refund Records',
|
||||
'礼物管理': 'Gift Management',
|
||||
'抽奖概率配置': 'Lottery Probability Settings',
|
||||
'徽章配置管理': 'Badge Configuration Management',
|
||||
'靓号池管理': 'Special ID Pool Management',
|
||||
'礼物赠送记录': 'Gift Giving Records',
|
||||
'房间贡献余额': 'Room Contribution Balance',
|
||||
'消息推送': 'Message Push',
|
||||
'在线房间': 'Online Rooms',
|
||||
'房间资料信息': 'Room Profile Information',
|
||||
'系统banner管理': 'System Banner Management',
|
||||
'麦位类型管理': 'Mic Slot Type Management',
|
||||
'游戏列表': 'Game List',
|
||||
'App启动页': 'App Launch Page',
|
||||
'系统公告管理': 'System Notice Management',
|
||||
'国家管理': 'Country Management',
|
||||
'用户道具流水': 'User Prop Transactions',
|
||||
'用户钻石余额列表': 'User Diamond Balances',
|
||||
'用户钻石流水列表': 'User Diamond Transactions',
|
||||
'购买麦位类型流水': 'Mic Slot Purchase Transactions',
|
||||
'红包发送列表': 'Red Packet Sends',
|
||||
'用户活动领奖记录': 'User Activity Reward Records',
|
||||
'幸运礼物规则配置': 'Lucky Gift Rule Settings',
|
||||
'幸运礼物规格配置': 'Lucky Gift Specification Settings',
|
||||
'幸运礼物送礼记录': 'Lucky Gift Sending Records',
|
||||
'LuckyBox抽奖记录': 'LuckyBox Draw Records',
|
||||
'摩天轮游戏每日数据': 'Ferris Wheel Daily Data',
|
||||
'摩天轮任务配置': 'Ferris Wheel Task Settings',
|
||||
'砸金蛋记录': 'Golden Egg Smash Records',
|
||||
'炸金花': 'Teen Patti',
|
||||
'用户申请靓号记录': 'User Special ID Applications',
|
||||
'自定义名人堂': 'Custom Hall of Fame',
|
||||
'喇叭列表': 'Trumpet List',
|
||||
'房间支持活动': 'Room Support Activities',
|
||||
'审批管理': 'Approval Management',
|
||||
'头像审核': 'Avatar Approval',
|
||||
'昵称审核': 'Nickname Approval',
|
||||
'照片墙审核': 'Photo Wall Approval',
|
||||
'房间封面审批': 'Room Cover Approval',
|
||||
'用户个性签名审批': 'User Profile Signature Approval',
|
||||
'房间通知审批': 'Room Notice Approval',
|
||||
'房间名称审批': 'Room Name Approval',
|
||||
'房间主题审批': 'Room Theme Approval',
|
||||
'举报管理': 'Report Management',
|
||||
'意见反馈': 'Feedback',
|
||||
'违规历史记录': 'Violation History',
|
||||
'家族头像审批': 'Family Avatar Approval',
|
||||
'动态内容审批': 'Post Content Approval',
|
||||
'动态举报审批': 'Post Report Approval',
|
||||
'用户银行卡审批': 'User Bank Card Approval',
|
||||
'语言': 'Language',
|
||||
English: 'English',
|
||||
'中文': 'Chinese',
|
||||
'切换主题': 'Change Theme',
|
||||
'选择主题': 'Select Theme',
|
||||
'正常模式': 'Light Mode',
|
||||
'暗黑模式': 'Dark Mode',
|
||||
'自动切换': 'Auto',
|
||||
'07:00~18:00 正常模式,19:00~06:00 进入暗黑模式': '07:00~18:00 uses light mode, 19:00~06:00 uses dark mode',
|
||||
'修改密码': 'Reset Password',
|
||||
'退出登录': 'Logout',
|
||||
Search: 'Search',
|
||||
'Global Size': 'Global Size',
|
||||
'默认': 'Default',
|
||||
'中等': 'Medium',
|
||||
'小': 'Small',
|
||||
'迷你': 'Mini',
|
||||
'切换尺寸成功': 'Switch Size Success',
|
||||
'重置密码': 'Reset Password',
|
||||
'原始密码': 'Original Password',
|
||||
'新密码': 'New Password',
|
||||
'确认密码': 'Confirm Password',
|
||||
'请输入原始密码': 'Please enter the original password',
|
||||
'请输入新密码': 'Please enter the new password',
|
||||
'请输入确认密码': 'Please confirm the password',
|
||||
'必填字段不能为空': 'Required field cannot be empty',
|
||||
'密码不能少于4位': 'The password can not be less than 4 digits',
|
||||
'两次密码输入不一致': 'Passwords do not match',
|
||||
'取消': 'Cancel',
|
||||
'提交': 'Submit',
|
||||
'正在处理提交,请稍候': 'Processing submission, please wait',
|
||||
Successful: 'Successful',
|
||||
Failed: 'Failed',
|
||||
Unknown: 'Unknown',
|
||||
Login: 'Login',
|
||||
Username: 'Username',
|
||||
Password: 'Password',
|
||||
'Please enter the correct user name': 'Please enter the correct user name',
|
||||
'The password can not be less than 4 digits': 'The password can not be less than 4 digits',
|
||||
'最近2小时': 'Last 2 Hours',
|
||||
'最近6小时': 'Last 6 Hours',
|
||||
'最近12小时': 'Last 12 Hours',
|
||||
'最近一天': 'Last 1 Day',
|
||||
'最近一周': 'Last 1 Week',
|
||||
'最近一个月': 'Last 1 Month',
|
||||
'最近三个月': 'Last 3 Months',
|
||||
'正常': 'Normal',
|
||||
'关闭': 'Closed',
|
||||
'等待确认': 'Pending Confirmation',
|
||||
'ID变更': 'ID Changed',
|
||||
'房主': 'Room Owner',
|
||||
'管理员': 'Admin',
|
||||
'成员': 'Member',
|
||||
'代理': 'Agent',
|
||||
'收入': 'Income',
|
||||
'支出': 'Expense',
|
||||
'未处理': 'Pending',
|
||||
'已处理': 'Processed',
|
||||
'已发布': 'Published',
|
||||
'未发布': 'Unpublished',
|
||||
'奖励': 'Reward',
|
||||
'内部': 'Internal',
|
||||
'工资': 'Salary',
|
||||
'充值': 'Recharge',
|
||||
'其他': 'Other',
|
||||
'违规': 'Violation',
|
||||
'多发': 'Overpayment',
|
||||
'已领取': 'Claimed',
|
||||
'未领取': 'Unclaimed',
|
||||
'推送': 'Push',
|
||||
'无': 'None',
|
||||
'会员': 'Member',
|
||||
'非会员': 'Non-member',
|
||||
'男': 'Male',
|
||||
'女': 'Female',
|
||||
'通过': 'Approved',
|
||||
'不通过': 'Rejected',
|
||||
'等待审核': 'Pending Review',
|
||||
'图文': 'Image and Text',
|
||||
'视频': 'Video',
|
||||
'收藏': 'Favorited',
|
||||
'未收藏': 'Not Favorited',
|
||||
'聊天消息': 'Chat Message',
|
||||
'系统招呼': 'System Greeting',
|
||||
'全部': 'All',
|
||||
'免费池': 'Free Pool',
|
||||
'女生池': 'Girls Pool',
|
||||
'女神池': 'Goddess Pool',
|
||||
'优质女性': 'Premium Female',
|
||||
'主播': 'Host',
|
||||
'普通女性': 'Regular Female',
|
||||
'主播与优质女性': 'Host and Premium Female',
|
||||
'男性会员': 'Male Member',
|
||||
'购买过糖果的男性': 'Male User Who Purchased Candy',
|
||||
'普通男性': 'Regular Male',
|
||||
'会员与购买过糖果男性': 'Member and Candy Buyer',
|
||||
'提现': 'Withdraw',
|
||||
'转账': 'Transfer',
|
||||
'转账金币': 'Transfer Gold',
|
||||
'接收转账': 'Receive Transfer',
|
||||
'兑换金币': 'Exchange Gold',
|
||||
'系统补偿': 'System Compensation',
|
||||
'系统扣除': 'System Deduction',
|
||||
'创建银行账户': 'Create Bank Account',
|
||||
'手机号码': 'Mobile Number',
|
||||
'谷歌': 'Google',
|
||||
'礼物': 'Gift',
|
||||
'道具': 'Props',
|
||||
'钻石': 'Diamond',
|
||||
'徽章': 'Badge',
|
||||
'用户-成就徽章': 'User - Achievement Badge',
|
||||
'用户-管理员': 'User - Administrator',
|
||||
'用户-活动徽章': 'User - Activity Badge',
|
||||
'荣誉-管理员': 'Honor - Administrator',
|
||||
'荣誉-活动': 'Honor - Activity',
|
||||
'黑铁': 'Black Iron',
|
||||
'青铜': 'Bronze',
|
||||
'白银': 'Silver',
|
||||
'黄金': 'Gold',
|
||||
'铂金': 'Platinum',
|
||||
'族长': 'Patriarch',
|
||||
'电子钱包': 'E-wallet',
|
||||
'银行卡': 'Bank Card',
|
||||
'银行卡转账': 'Bank Card Transfer',
|
||||
'线下非银网点': 'Offline Non-bank Outlets',
|
||||
'运营商计费': 'Carrier Billing',
|
||||
'网上银行': 'Online Banking',
|
||||
'快捷支付': 'Quick Payment',
|
||||
'延迟支付': 'Delayed Payment',
|
||||
'无密支付': 'Password-free Payment',
|
||||
'便利店': 'Convenience Store',
|
||||
'点卡支付': 'Point Card Payment',
|
||||
'超商条码': 'Supermarket Barcode',
|
||||
'行动/电话小额付': 'Mobile / Phone Payment',
|
||||
'实体ATM': 'Physical ATM',
|
||||
'ATM线上': 'ATM Online',
|
||||
'ATM线下': 'ATM Offline',
|
||||
'银行虚拟账号': 'Bank Virtual Account',
|
||||
'银行柜台': 'Bank Counter',
|
||||
'预付费卡': 'Prepaid Card',
|
||||
'西联汇款': 'Western Union',
|
||||
'转账汇款': 'Transfer',
|
||||
'刚刚': 'Just now',
|
||||
'分钟前': ' minutes ago',
|
||||
'小时前': ' hours ago',
|
||||
'1天前': '1 day ago'
|
||||
}
|
||||
2746
src/lang/messages/pages/en.js
Normal file
2746
src/lang/messages/pages/en.js
Normal file
File diff suppressed because it is too large
Load Diff
2745
src/lang/messages/pages/zh.js
Normal file
2745
src/lang/messages/pages/zh.js
Normal file
File diff suppressed because it is too large
Load Diff
45
src/lang/messages/zh.js
Normal file
45
src/lang/messages/zh.js
Normal file
@ -0,0 +1,45 @@
|
||||
import semantic from './base/zh'
|
||||
import pageMessages from './pages/zh'
|
||||
|
||||
export default {
|
||||
...semantic,
|
||||
...pageMessages,
|
||||
Language: '语言',
|
||||
English: 'English',
|
||||
Chinese: '中文',
|
||||
Search: '搜索',
|
||||
'Global Size': '全局尺寸',
|
||||
Default: '默认',
|
||||
Medium: '中等',
|
||||
Small: '小',
|
||||
Mini: '迷你',
|
||||
'Switch Size Success': '切换尺寸成功',
|
||||
Login: '登录',
|
||||
Username: '用户名',
|
||||
Password: '密码',
|
||||
'Please enter the correct user name': '请输入正确的用户名',
|
||||
'The password can not be less than 4 digits': '密码不能少于4位',
|
||||
'Change Theme': '切换主题',
|
||||
'Select Theme': '选择主题',
|
||||
'Light Mode': '正常模式',
|
||||
'Dark Mode': '暗黑模式',
|
||||
Auto: '自动切换',
|
||||
'07:00~18:00 uses light mode, 19:00~06:00 uses dark mode': '07:00~18:00 正常模式,19:00~06:00 进入暗黑模式',
|
||||
'Reset Password': '重置密码',
|
||||
'Original Password': '原始密码',
|
||||
'New Password': '新密码',
|
||||
'Confirm Password': '确认密码',
|
||||
'Please enter the original password': '请输入原始密码',
|
||||
'Please enter the new password': '请输入新密码',
|
||||
'Please confirm the password': '请输入确认密码',
|
||||
'Required field cannot be empty': '必填字段不能为空',
|
||||
'Passwords do not match': '两次密码输入不一致',
|
||||
Cancel: '取消',
|
||||
Submit: '提交',
|
||||
Logout: '退出登录',
|
||||
'Processing submission, please wait': '正在处理提交,请稍候',
|
||||
Successful: '成功',
|
||||
Failed: '失败',
|
||||
Unknown: '未知',
|
||||
Home: '首页'
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<div class="navbar">
|
||||
<hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
||||
|
||||
@ -10,9 +10,13 @@
|
||||
|
||||
<screenfull id="screenfull" class="right-menu-item hover-effect" />
|
||||
|
||||
<el-tooltip content="Global Size" effect="dark" placement="bottom">
|
||||
<el-tooltip :content="$t('common.globalSize')" effect="dark" placement="bottom">
|
||||
<size-select id="size-select" class="right-menu-item hover-effect" />
|
||||
</el-tooltip>
|
||||
|
||||
<div class="right-menu-item hover-effect language-entry">
|
||||
<language-switch />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-dropdown class="avatar-container" trigger="click">
|
||||
@ -21,8 +25,17 @@
|
||||
<i class="el-icon-caret-bottom" />
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown" class="user-dropdown">
|
||||
<el-dropdown-item @click.native="resetPwd">修改密码</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="logout">退出登录</el-dropdown-item>
|
||||
<el-dropdown-item disabled>{{ $t('common.language') }}</el-dropdown-item>
|
||||
<el-dropdown-item
|
||||
v-for="item in languageOptions"
|
||||
:key="item.value"
|
||||
:disabled="$locale === item.value"
|
||||
@click.native="changeLanguage(item.value)"
|
||||
>
|
||||
{{ item.nativeLabel || item.label }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item divided @click.native="resetPwd">{{ $t('common.resetPassword') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="logout">{{ $t('common.logout') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
@ -39,6 +52,8 @@ import RestPassword from '@/components/data/RestPassword'
|
||||
import Screenfull from '@/components/Screenfull'
|
||||
import SizeSelect from '@/components/SizeSelect'
|
||||
import Search from '@/components/HeaderSearch'
|
||||
import LanguageSwitch from '@/components/LanguageSwitch'
|
||||
import { getLocaleOptions } from '@/lang'
|
||||
import { extractColorByText } from '@/utils'
|
||||
|
||||
export default {
|
||||
@ -49,7 +64,8 @@ export default {
|
||||
RestPassword,
|
||||
Screenfull,
|
||||
SizeSelect,
|
||||
Search
|
||||
Search,
|
||||
LanguageSwitch
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@ -64,6 +80,9 @@ export default {
|
||||
'dashboard',
|
||||
'name'
|
||||
]),
|
||||
languageOptions() {
|
||||
return getLocaleOptions()
|
||||
},
|
||||
userAvatarColor() {
|
||||
return 'background-color:' + extractColorByText(this.name) + ';'
|
||||
},
|
||||
@ -78,6 +97,9 @@ export default {
|
||||
resetPwd() {
|
||||
this.resetPasswordVisible = true
|
||||
},
|
||||
changeLanguage(locale) {
|
||||
this.$setLocale(locale)
|
||||
},
|
||||
async logout() {
|
||||
this.$store.dispatch('user/resetToken').then(() => {
|
||||
location.reload()
|
||||
@ -142,6 +164,10 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.language-entry {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.avatar-container {
|
||||
margin-right: 30px;
|
||||
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
<script>
|
||||
import { translateRouteTitle } from '@/lang'
|
||||
|
||||
export default {
|
||||
name: 'MenuItem',
|
||||
functional: true,
|
||||
@ -15,13 +17,14 @@ export default {
|
||||
render(h, context) {
|
||||
const { icon, title } = context.props
|
||||
const vnodes = []
|
||||
const translatedTitle = title ? translateRouteTitle(title) : ''
|
||||
|
||||
if (icon) {
|
||||
vnodes.push(<svg-icon icon-class={icon}/>)
|
||||
vnodes.push(<svg-icon class='menu-icon' icon-class={icon}/>)
|
||||
}
|
||||
|
||||
if (title) {
|
||||
vnodes.push(<span slot='title'>{(title)}</span>)
|
||||
if (translatedTitle) {
|
||||
vnodes.push(<span class='menu-title' slot='title' attrs={{ title: translatedTitle }}>{translatedTitle}</span>)
|
||||
}
|
||||
return vnodes
|
||||
}
|
||||
|
||||
31
src/main.js
31
src/main.js
@ -2,17 +2,17 @@ import Vue from 'vue'
|
||||
import Cookies from 'js-cookie'
|
||||
import 'normalize.css/normalize.css' // A modern alternative to CSS resets
|
||||
|
||||
import ElementUI from 'element-ui'
|
||||
import ElementUI, { TableColumn } from 'element-ui'
|
||||
import '@/styles/theme/dark/index.css'
|
||||
import 'element-ui/lib/theme-chalk/index.css'
|
||||
import 'element-ui/lib/theme-chalk/display.css'
|
||||
import locale from 'element-ui/lib/locale/lang/zh-CN' // lang i18n
|
||||
|
||||
import '@/styles/index.scss' // global css
|
||||
|
||||
import App from './App'
|
||||
import store from './store'
|
||||
import router from './router'
|
||||
import i18nPlugin, { attachStore, setLocale } from './lang'
|
||||
import '@/directive'
|
||||
import '@/components-register'
|
||||
import '@/permission' // permission control
|
||||
@ -39,8 +39,31 @@ if (isMock()) {
|
||||
mockXHR()
|
||||
}
|
||||
|
||||
// set ElementUI lang to zh-CN
|
||||
Vue.use(ElementUI, { locale, size: Cookies.get('size') || 'medium' })
|
||||
// initialize ElementUI and runtime locale
|
||||
const DEFAULT_TABLE_COLUMN_MIN_WIDTH = 120
|
||||
|
||||
if (TableColumn && TableColumn.methods && !TableColumn.methods.__defaultMinWidthPatched__) {
|
||||
const originalSetColumnWidth = TableColumn.methods.setColumnWidth
|
||||
TableColumn.methods.setColumnWidth = function(column) {
|
||||
const nextColumn = originalSetColumnWidth.call(this, column)
|
||||
const hasExplicitWidth = this.width !== undefined && this.width !== null && this.width !== ''
|
||||
const hasExplicitMinWidth = this.minWidth !== undefined && this.minWidth !== null && this.minWidth !== ''
|
||||
const isSpecialType = ['selection', 'index', 'expand'].includes(nextColumn.type)
|
||||
|
||||
if (!hasExplicitWidth && !hasExplicitMinWidth && !isSpecialType && nextColumn.minWidth < DEFAULT_TABLE_COLUMN_MIN_WIDTH) {
|
||||
nextColumn.minWidth = DEFAULT_TABLE_COLUMN_MIN_WIDTH
|
||||
nextColumn.realWidth = nextColumn.width === undefined ? nextColumn.minWidth : nextColumn.width
|
||||
}
|
||||
|
||||
return nextColumn
|
||||
}
|
||||
TableColumn.methods.__defaultMinWidthPatched__ = true
|
||||
}
|
||||
|
||||
Vue.use(ElementUI, { size: Cookies.get('size') || 'medium' })
|
||||
Vue.use(i18nPlugin)
|
||||
attachStore(store)
|
||||
setLocale(store.getters.language || 'en')
|
||||
// 如果想要中文版 element-ui,按如下方式声明
|
||||
// Vue.use(ElementUI)
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import router from './router'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import { Message } from 'element-ui'
|
||||
import NProgress from 'nprogress' // progress bar
|
||||
@ -6,6 +6,7 @@ import 'nprogress/nprogress.css' // progress bar style
|
||||
import { getToken } from '@/utils/auth' // get token from cookie
|
||||
import { checkSwitchTheme } from '@/utils/theme'
|
||||
import getPageTitle from '@/utils/get-page-title'
|
||||
import { translate, translateRouteTitle } from '@/lang'
|
||||
NProgress.configure({ showSpinner: false }) // NProgress Configuration
|
||||
|
||||
const whiteList = ['/login'] // no redirect whitelist
|
||||
@ -15,7 +16,7 @@ router.beforeEach(async(to, from, next) => {
|
||||
NProgress.start()
|
||||
stackRouter.push()
|
||||
// set page title
|
||||
document.title = getPageTitle(to.meta.title)
|
||||
document.title = getPageTitle(translateRouteTitle(to.meta && to.meta.title))
|
||||
|
||||
// determine whether the user has logged in
|
||||
const hasToken = getToken()
|
||||
@ -32,7 +33,7 @@ router.beforeEach(async(to, from, next) => {
|
||||
store.dispatch('user/addNavigationRecentPreviews', {
|
||||
id: to.name || 'none',
|
||||
type: 'SYSTEM',
|
||||
name: to.meta.title || '未知',
|
||||
name: translateRouteTitle(to.meta && to.meta.title),
|
||||
link: to.fullPath
|
||||
})
|
||||
}
|
||||
@ -58,7 +59,7 @@ router.beforeEach(async(to, from, next) => {
|
||||
} catch (error) {
|
||||
// remove token and go to login page to re-login
|
||||
await store.dispatch('user/resetToken')
|
||||
Message.error(error || 'Has Error')
|
||||
Message.error(translate(error || 'Failed'))
|
||||
next(`/login?redirect=${to.path}`)
|
||||
NProgress.done()
|
||||
}
|
||||
@ -82,3 +83,4 @@ router.afterEach(() => {
|
||||
// finish progress bar
|
||||
NProgress.done()
|
||||
})
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
const getters = {
|
||||
sidebar: state => state.app.sidebar,
|
||||
size: state => state.app.size,
|
||||
language: state => state.app.language,
|
||||
device: state => state.app.device,
|
||||
token: state => state.user.token,
|
||||
avatar: state => state.user.avatar,
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
import Cookies from 'js-cookie'
|
||||
import { detectLocaleByTimeZone } from '@/lang'
|
||||
|
||||
const LANGUAGE_STORAGE_KEY = 'language'
|
||||
|
||||
const state = {
|
||||
sidebar: {
|
||||
@ -7,6 +10,7 @@ const state = {
|
||||
},
|
||||
device: 'desktop',
|
||||
size: Cookies.get('size') || 'medium',
|
||||
language: Cookies.get(LANGUAGE_STORAGE_KEY) || detectLocaleByTimeZone(),
|
||||
runTask: []
|
||||
}
|
||||
|
||||
@ -32,6 +36,10 @@ const mutations = {
|
||||
state.size = size
|
||||
Cookies.set('size', size)
|
||||
},
|
||||
SET_LANGUAGE: (state, language) => {
|
||||
state.language = language || 'en'
|
||||
Cookies.set(LANGUAGE_STORAGE_KEY, state.language)
|
||||
},
|
||||
PUSH_RUN_TASK: (state, runTask) => {
|
||||
if (!runTask) {
|
||||
return
|
||||
@ -74,6 +82,9 @@ const actions = {
|
||||
setSize({ commit }, size) {
|
||||
commit('SET_SIZE', size)
|
||||
},
|
||||
setLanguage({ commit }, language) {
|
||||
commit('SET_LANGUAGE', language)
|
||||
},
|
||||
pushRunTask({ commit }, runTask) {
|
||||
commit('PUSH_RUN_TASK', runTask)
|
||||
},
|
||||
|
||||
@ -67,6 +67,33 @@
|
||||
color:#6E5138;
|
||||
}
|
||||
|
||||
.el-table th.el-table__cell {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.el-table th.el-table__cell > .cell {
|
||||
white-space: normal !important;
|
||||
word-break: normal;
|
||||
overflow-wrap: normal;
|
||||
overflow: visible;
|
||||
text-overflow: clip;
|
||||
line-height: 1.35;
|
||||
height: auto !important;
|
||||
min-height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.el-table th.is-center > .cell {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.el-table th.is-right > .cell {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.el-table th.el-table__cell.is-leaf, .el-table td.el-table__cell {
|
||||
border-bottom: none !important;
|
||||
}
|
||||
@ -370,6 +397,50 @@
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.el-form.i18n-form {
|
||||
--i18n-form-label-width: 132px;
|
||||
|
||||
.el-form-item__label-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.el-form-item__label {
|
||||
width: var(--i18n-form-label-width) !important;
|
||||
min-height: 36px;
|
||||
white-space: normal;
|
||||
word-break: normal;
|
||||
overflow-wrap: break-word;
|
||||
line-height: 1.35;
|
||||
padding-right: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.el-form-item__content {
|
||||
margin-left: var(--i18n-form-label-width) !important;
|
||||
min-height: 36px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-form.i18n-form.i18n-form--wide {
|
||||
--i18n-form-label-width: 150px;
|
||||
}
|
||||
|
||||
.el-form.i18n-form.i18n-form--narrow {
|
||||
--i18n-form-label-width: 116px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.el-form.i18n-form,
|
||||
.el-form.i18n-form.i18n-form--wide,
|
||||
.el-form.i18n-form.i18n-form--narrow {
|
||||
--i18n-form-label-width: 116px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-backtop {
|
||||
background: linear-gradient(135deg, #FF9326 0%, #FEB219 100%);
|
||||
color: #FFFFFF;
|
||||
|
||||
@ -56,6 +56,7 @@
|
||||
|
||||
.svg-icon {
|
||||
margin-right: 16px;
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.el-menu {
|
||||
@ -68,12 +69,38 @@
|
||||
.el-menu-item,
|
||||
.el-submenu__title {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: 6px 12px;
|
||||
width: calc(100% - 24px) !important;
|
||||
min-height: 52px;
|
||||
height: auto !important;
|
||||
line-height: 1.4 !important;
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
border-radius: 14px;
|
||||
transition: all .2s ease;
|
||||
}
|
||||
|
||||
.el-submenu__title {
|
||||
padding-right: 44px !important;
|
||||
}
|
||||
|
||||
.el-submenu__icon-arrow {
|
||||
right: 16px !important;
|
||||
}
|
||||
|
||||
.menu-title {
|
||||
display: block;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
white-space: normal;
|
||||
word-break: normal;
|
||||
overflow-wrap: break-word;
|
||||
hyphens: auto;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.el-menu-item:hover,
|
||||
.el-submenu__title:hover {
|
||||
transform: translateX(2px);
|
||||
@ -146,6 +173,14 @@
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> .svg-icon,
|
||||
> .menu-icon {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.el-submenu {
|
||||
@ -156,6 +191,7 @@
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 52px;
|
||||
|
||||
.svg-icon {
|
||||
margin: 0;
|
||||
@ -164,6 +200,14 @@
|
||||
.el-submenu__icon-arrow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
> .svg-icon,
|
||||
> .menu-icon {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
margin: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ $menuHover: #372316;
|
||||
$subMenuBg: #1B120C;
|
||||
$subMenuHover: #422A19;
|
||||
|
||||
$sideBarWidth: 210px;
|
||||
$sideBarWidth: 246px;
|
||||
|
||||
// the :export directive is the magic sauce for webpack
|
||||
// https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
import defaultSettings from "@/settings";
|
||||
import { translateRouteTitle } from '@/lang'
|
||||
|
||||
const title = defaultSettings.title || "Aslan";
|
||||
|
||||
export default function getPageTitle(pageTitle) {
|
||||
if (pageTitle) {
|
||||
return `${pageTitle} - ${title}`;
|
||||
return `${translateRouteTitle(pageTitle)} - ${title}`;
|
||||
}
|
||||
return `${title}`;
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
* 2. 能快速统一的更管提示框样式
|
||||
*/
|
||||
import { Message } from 'element-ui'
|
||||
import { translate } from '@/lang'
|
||||
|
||||
/**
|
||||
* 提示消息.
|
||||
@ -12,28 +13,28 @@ import { Message } from 'element-ui'
|
||||
const opsMessage = {
|
||||
success: (text) => {
|
||||
Message({
|
||||
message: text || 'Successful',
|
||||
message: translate(text || 'Successful'),
|
||||
type: 'success',
|
||||
duration: 3 * 1000
|
||||
})
|
||||
},
|
||||
fail: (text) => {
|
||||
Message({
|
||||
message: text || 'Failed',
|
||||
message: translate(text || 'Failed'),
|
||||
type: 'error',
|
||||
duration: 3 * 1000
|
||||
})
|
||||
},
|
||||
warn: (text) => {
|
||||
Message({
|
||||
message: text,
|
||||
message: translate(text),
|
||||
type: 'warning',
|
||||
duration: 3 * 1000
|
||||
})
|
||||
},
|
||||
info: (text) => {
|
||||
Message({
|
||||
message: text,
|
||||
message: translate(text),
|
||||
type: 'info',
|
||||
duration: 3 * 1000
|
||||
})
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
<!-- 系统 -->
|
||||
<el-select
|
||||
v-model="listQuery.sysOrigin"
|
||||
placeholder="系统"
|
||||
:placeholder="$t('pages.activityTemplateManage.filter.system')"
|
||||
style="width: 120px"
|
||||
class="filter-item"
|
||||
@change="handleSearch"
|
||||
@ -27,19 +27,19 @@
|
||||
<!-- 状态 -->
|
||||
<el-select
|
||||
v-model="listQuery.showcase"
|
||||
placeholder="状态"
|
||||
:placeholder="$t('pages.activityTemplateManage.filter.status')"
|
||||
style="width: 120px"
|
||||
class="filter-item"
|
||||
clearable
|
||||
@change="handleSearch"
|
||||
>
|
||||
<el-option-group label="运行状态">
|
||||
<el-option label="已开始" :value="1" />
|
||||
<el-option label="已结束" :value="2" />
|
||||
<el-option-group :label="$t('pages.activityTemplateManage.group.runtimeStatus')">
|
||||
<el-option :label="$t('pages.activityTemplateManage.word.started')" :value="1" />
|
||||
<el-option :label="$t('pages.activityTemplateManage.word.ended')" :value="2" />
|
||||
</el-option-group>
|
||||
<el-option-group label="管理状态">
|
||||
<el-option label="上架" :value="3" />
|
||||
<el-option label="下架" :value="4" />
|
||||
<el-option-group :label="$t('pages.activityTemplateManage.group.managementStatus')">
|
||||
<el-option :label="$t('pages.activityTemplateManage.word.onShelf')" :value="3" />
|
||||
<el-option :label="$t('pages.activityTemplateManage.word.offShelf')" :value="4" />
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
|
||||
@ -47,7 +47,7 @@
|
||||
<el-input
|
||||
v-model.trim="listQuery.id"
|
||||
v-number
|
||||
placeholder="活动ID"
|
||||
:placeholder="$t('pages.activityTemplateManage.filter.activityId')"
|
||||
style="width: 200px;"
|
||||
class="filter-item"
|
||||
/>
|
||||
@ -56,7 +56,7 @@
|
||||
<el-input
|
||||
v-model.trim="listQuery.templateId"
|
||||
v-number
|
||||
placeholder="模版ID"
|
||||
:placeholder="$t('pages.activityTemplateManage.filter.templateId')"
|
||||
style="width: 200px;"
|
||||
class="filter-item"
|
||||
/>
|
||||
@ -68,7 +68,7 @@
|
||||
icon="el-icon-search"
|
||||
@click="handleSearch"
|
||||
>
|
||||
搜索
|
||||
{{ $t('pages.activityTemplateManage.action.search') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 新增按钮 -->
|
||||
@ -78,42 +78,38 @@
|
||||
icon="el-icon-edit"
|
||||
@click="clickCreate"
|
||||
>
|
||||
新增
|
||||
{{ $t('pages.activityTemplateManage.action.create') }}
|
||||
</el-button>
|
||||
|
||||
<!-- 帮助按钮 -->
|
||||
<el-popover title="操作手册" trigger="hover">
|
||||
<el-popover :title="$t('pages.activityTemplateManage.help.title')" trigger="hover">
|
||||
<div class="content">
|
||||
<div class="help">
|
||||
<strong>怎么创建一个活动?</strong>
|
||||
<p>1.在 “活动模版” 创建一个模版页面, 如果已创建可以直接使用</p>
|
||||
<p>2.在当前 “活动管理” 创建一个活动并关联 “活动模版”</p>
|
||||
<p>3.使用 “复制活动链接” 获得活动地址</p>
|
||||
<p>4.在 “Banner” 配置活动地址</p>
|
||||
<strong>活动排行榜计算规则?</strong>
|
||||
<p>1.活动处于上架状态</p>
|
||||
<strong>{{ $t('pages.activityTemplateManage.help.createTitle') }}</strong>
|
||||
<p>{{ $t('pages.activityTemplateManage.help.createStep1') }}</p>
|
||||
<p>{{ $t('pages.activityTemplateManage.help.createStep2') }}</p>
|
||||
<p>{{ $t('pages.activityTemplateManage.help.createStep3') }}</p>
|
||||
<p>{{ $t('pages.activityTemplateManage.help.createStep4') }}</p>
|
||||
<strong>{{ $t('pages.activityTemplateManage.help.rankTitle') }}</strong>
|
||||
<p>{{ $t('pages.activityTemplateManage.help.rankStep1') }}</p>
|
||||
<p>
|
||||
2.活动进行中: 系统当前时间 >= 开始时间 并且 系统当前时间 <=
|
||||
结束时间
|
||||
{{ $t('pages.activityTemplateManage.help.rankStep2') }}
|
||||
</p>
|
||||
<p>3.活动中包含礼物</p>
|
||||
<p>满足上面条件的情况下, 用户发送礼物触发</p>
|
||||
<strong>注意事项</strong>
|
||||
<p>{{ $t('pages.activityTemplateManage.help.rankStep3') }}</p>
|
||||
<p>{{ $t('pages.activityTemplateManage.help.rankStep4') }}</p>
|
||||
<strong>{{ $t('pages.activityTemplateManage.help.noticeTitle') }}</strong>
|
||||
<p>
|
||||
1.活动结束后不可用在次编辑, 如果需要重写激活请使用 “复制活动”
|
||||
重写创建一个新的活动
|
||||
{{ $t('pages.activityTemplateManage.help.noticeStep1') }}
|
||||
</p>
|
||||
<p>
|
||||
2.排行榜只能在活动进行中可查看, 活动结束后通过系统 “发送奖品”
|
||||
系统将缓存TOP20 或 通过 “奖品发送记录” 查看
|
||||
{{ $t('pages.activityTemplateManage.help.noticeStep2') }}
|
||||
</p>
|
||||
<p>
|
||||
3.一个 “活动模版” 如果被多个活动关联,
|
||||
修改模版所有关联活动将全部会改变
|
||||
{{ $t('pages.activityTemplateManage.help.noticeStep3') }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<span slot="reference"><i class="el-icon-info" />帮助</span>
|
||||
<span slot="reference"><i class="el-icon-info" />{{ $t('pages.activityTemplateManage.action.help') }}</span>
|
||||
</el-popover>
|
||||
</div>
|
||||
|
||||
@ -127,7 +123,7 @@
|
||||
>
|
||||
<!-- 关联模版 -->
|
||||
<el-table-column
|
||||
label="关联模版"
|
||||
:label="$t('pages.activityTemplateManage.table.relatedTemplate')"
|
||||
prop="templateName"
|
||||
align="center"
|
||||
min-width="200"
|
||||
@ -135,7 +131,7 @@
|
||||
|
||||
<!-- 备注 -->
|
||||
<el-table-column
|
||||
label="备注"
|
||||
:label="$t('pages.activityTemplateManage.table.remark')"
|
||||
prop="config.remark"
|
||||
align="center"
|
||||
min-width="200"
|
||||
@ -143,7 +139,7 @@
|
||||
|
||||
<!-- 状态 -->
|
||||
<el-table-column
|
||||
label="状态"
|
||||
:label="$t('pages.activityTemplateManage.table.status')"
|
||||
prop="config.startTime"
|
||||
align="center"
|
||||
min-width="200"
|
||||
@ -152,55 +148,55 @@
|
||||
<el-tag
|
||||
:type="scope.row.config.showcase === true ? 'primary' : 'danger'"
|
||||
>
|
||||
{{ scope.row.config.showcase === true ? "上架" : "下架" }}
|
||||
{{ scope.row.config.showcase === true ? $t("pages.activityTemplateManage.word.onShelf") : $t("pages.activityTemplateManage.word.offShelf") }}
|
||||
</el-tag>
|
||||
<el-tag v-if="scope.row.status === 0" type="info">未开始</el-tag>
|
||||
<el-tag v-if="scope.row.status === 1" type="success">已开始</el-tag>
|
||||
<el-tag v-if="scope.row.status === 2" type="warning">已结束</el-tag>
|
||||
<el-tag v-if="scope.row.status === 0" type="info">{{ $t('pages.activityTemplateManage.word.notStarted') }}</el-tag>
|
||||
<el-tag v-if="scope.row.status === 1" type="success">{{ $t('pages.activityTemplateManage.word.started') }}</el-tag>
|
||||
<el-tag v-if="scope.row.status === 2" type="warning">{{ $t('pages.activityTemplateManage.word.ended') }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 活动时间 -->
|
||||
<el-table-column
|
||||
label="活动时间"
|
||||
:label="$t('pages.activityTemplateManage.table.activityTime')"
|
||||
prop="config.startTime"
|
||||
align="center"
|
||||
min-width="200"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<div>开始: {{ scope.row.config.startTime | dateFormat }}</div>
|
||||
<div>结束: {{ scope.row.config.endTime | dateFormat }}</div>
|
||||
<div>{{ $t('pages.activityTemplateManage.label.start') }}: {{ scope.row.config.startTime | dateFormat }}</div>
|
||||
<div>{{ $t('pages.activityTemplateManage.label.end') }}: {{ scope.row.config.endTime | dateFormat }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 修改/创建人 -->
|
||||
<el-table-column
|
||||
label="修改/创建人"
|
||||
:label="$t('pages.activityTemplateManage.table.updatedCreatedBy')"
|
||||
prop="config.createTime"
|
||||
align="center"
|
||||
min-width="200"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<div>修改: {{ scope.row.updateUserName }}</div>
|
||||
<div>创建: {{ scope.row.createUserName }}</div>
|
||||
<div>{{ $t('pages.activityTemplateManage.label.update') }}: {{ scope.row.updateUserName }}</div>
|
||||
<div>{{ $t('pages.activityTemplateManage.label.create') }}: {{ scope.row.createUserName }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 修改/创建时间 -->
|
||||
<el-table-column
|
||||
label="修改/创建时间"
|
||||
:label="$t('pages.activityTemplateManage.table.updatedCreatedTime')"
|
||||
prop="config.createTime"
|
||||
align="center"
|
||||
min-width="200"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<div>修改: {{ scope.row.config.updateTime | dateFormat }}</div>
|
||||
<div>创建: {{ scope.row.config.createTime | dateFormat }}</div>
|
||||
<div>{{ $t('pages.activityTemplateManage.label.update') }}: {{ scope.row.config.updateTime | dateFormat }}</div>
|
||||
<div>{{ $t('pages.activityTemplateManage.label.create') }}: {{ scope.row.config.createTime | dateFormat }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
<el-table-column fixed="right" label="操作" align="center" width="80">
|
||||
<el-table-column fixed="right" :label="$t('pages.activityTemplateManage.table.actions')" align="center" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link">
|
||||
@ -210,7 +206,7 @@
|
||||
<!-- 未开始/已开始:编辑,已结束:查看 -->
|
||||
<el-dropdown-item @click.native="clickEdit(scope.row)">
|
||||
{{
|
||||
scope.row.status !== 2 ? "编辑" : "查看"
|
||||
scope.row.status !== 2 ? $t("pages.activityTemplateManage.action.edit") : $t("pages.activityTemplateManage.action.view")
|
||||
}}</el-dropdown-item
|
||||
>
|
||||
|
||||
@ -219,7 +215,7 @@
|
||||
v-if="scope.row.status !== 0"
|
||||
@click.native="clickRank(scope.row)"
|
||||
>
|
||||
排行榜
|
||||
{{ $t('pages.activityTemplateManage.action.ranking') }}
|
||||
</el-dropdown-item>
|
||||
|
||||
<!-- 未开始/已开始:编辑模版 -->
|
||||
@ -227,12 +223,12 @@
|
||||
v-if="scope.row.status !== 2"
|
||||
@click.native="clickEditTemplate(scope.row)"
|
||||
>
|
||||
编辑模版
|
||||
{{ $t('pages.activityTemplateManage.action.editTemplate') }}
|
||||
</el-dropdown-item>
|
||||
|
||||
<!-- 复制活动 -->
|
||||
<el-dropdown-item @click.native="clickCopyActivity(scope.row)">
|
||||
复制活动
|
||||
{{ $t('pages.activityTemplateManage.action.copyActivity') }}
|
||||
</el-dropdown-item>
|
||||
|
||||
<!-- 已结束:发送奖品 -->
|
||||
@ -242,8 +238,8 @@
|
||||
>
|
||||
{{
|
||||
scope.row.config.awardStatus === true
|
||||
? "奖品发送记录"
|
||||
: "发送奖品"
|
||||
? $t("pages.activityTemplateManage.action.rewardRecord")
|
||||
: $t("pages.activityTemplateManage.action.sendReward")
|
||||
}}
|
||||
</el-dropdown-item>
|
||||
|
||||
@ -251,19 +247,19 @@
|
||||
<el-dropdown-item
|
||||
@click.native="copyContent(scope.row.config.id)"
|
||||
>
|
||||
复制活动ID
|
||||
{{ $t('pages.activityTemplateManage.action.copyActivityId') }}
|
||||
</el-dropdown-item>
|
||||
|
||||
<!-- 复制模版ID -->
|
||||
<el-dropdown-item
|
||||
@click.native="copyContent(scope.row.config.templateId)"
|
||||
>
|
||||
复制模版ID
|
||||
{{ $t('pages.activityTemplateManage.action.copyTemplateId') }}
|
||||
</el-dropdown-item>
|
||||
|
||||
<!-- 复制活动链接 -->
|
||||
<el-dropdown-item @click.native="clickActivityLink(scope.row)">
|
||||
复制活动链接
|
||||
{{ $t('pages.activityTemplateManage.action.copyActivityLink') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
@ -273,14 +269,14 @@
|
||||
|
||||
<!-- 加载模块 -->
|
||||
<div v-if="listQuery.lastId" class="load-more">
|
||||
<span v-if="notData">已加载全部</span>
|
||||
<span v-if="notData">{{ $t('pages.activityTemplateManage.word.loadedAll') }}</span>
|
||||
<el-button
|
||||
v-else
|
||||
size="mini"
|
||||
:disabled="loadMoreLoading"
|
||||
:loading="loadMoreLoading"
|
||||
@click="clickLoadMore"
|
||||
>加载更多</el-button
|
||||
>{{ $t('pages.activityTemplateManage.action.loadMore') }}</el-button
|
||||
>
|
||||
</div>
|
||||
|
||||
@ -453,11 +449,11 @@ export default {
|
||||
const that = this;
|
||||
that
|
||||
.$confirm(
|
||||
"注意: 模版发生改变后相关引用都会同步发生变化, 是否继续?",
|
||||
"提示",
|
||||
that.$t("pages.activityTemplateManage.confirm.editTemplateMessage"),
|
||||
that.$t("pages.activityTemplateManage.confirm.title"),
|
||||
{
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
confirmButtonText: that.$t("pages.activityTemplateManage.action.confirm"),
|
||||
cancelButtonText: that.$t("pages.activityTemplateManage.action.cancel"),
|
||||
type: "warning"
|
||||
}
|
||||
)
|
||||
|
||||
@ -22,23 +22,23 @@
|
||||
<div v-for="(item,index) in form.prizes" :key="index" class="flex-l">
|
||||
<img :src="item.imgs[0].src" width="40" height="40">
|
||||
<div style="width: 40%;padding: 0px 5px;" class="font-info">
|
||||
库存: {{ item.unlimited ? '不限' : item.inStock }}
|
||||
{{ $t('pages.lotteryConfig.stock.stock') }}: {{ item.unlimited ? $t('pages.lotteryConfig.word.unlimited') : item.inStock }}
|
||||
</div>
|
||||
<div style="width: 40%;padding: 0px 5px;" class="font-danger">
|
||||
消耗: {{ item.consumeInStock || '0' }}
|
||||
{{ $t('pages.lotteryConfig.stock.consume') }}: {{ item.consumeInStock || '0' }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col class="lottery-conf" :md="6" :xs="24">
|
||||
<el-form ref="form" class="form" :model="form" label-width="100px">
|
||||
<el-form ref="form" class="form i18n-form i18n-form--wide" :model="form" label-width="140px">
|
||||
<div class="card bottom-line">
|
||||
<div class="title">属性</div>
|
||||
<div class="title">{{ $t('pages.lotteryConfig.section.attributes') }}</div>
|
||||
<div class="content">
|
||||
<el-form-item label="归属系统">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.system')">
|
||||
<el-select
|
||||
v-model="listQuery.sysOrigin"
|
||||
placeholder="系统"
|
||||
:placeholder="$t('pages.lotteryConfig.placeholder.system')"
|
||||
style="width: 100%"
|
||||
class="filter-item"
|
||||
@change="loadLotteryConf"
|
||||
@ -55,16 +55,16 @@
|
||||
</el-select>
|
||||
|
||||
</el-form-item>
|
||||
<el-form-item label="启动消费">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.startConsume')">
|
||||
<el-input v-model="form.startConsume" v-number />
|
||||
</el-form-item>
|
||||
<el-form-item label="抽奖类型">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.lotteryType')">
|
||||
<el-radio-group v-model="form.type">
|
||||
<el-radio :label="0">转盘</el-radio>
|
||||
<el-radio :label="1" :disabled="true">九宫格</el-radio>
|
||||
<el-radio :label="0">{{ $t('pages.lotteryConfig.word.wheel') }}</el-radio>
|
||||
<el-radio :label="1" :disabled="true">{{ $t('pages.lotteryConfig.word.gridNine') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="转盘直径">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.wheelDiameter')">
|
||||
<el-input v-model="form.diameter" @change="renderLuckyWheel" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
@ -72,48 +72,48 @@
|
||||
<div class="card bottom-line">
|
||||
<div class="title">
|
||||
<el-row>
|
||||
<el-col :span="21">背景</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addBlocks"><i class="el-icon-circle-plus" />添加</el-button></el-col>
|
||||
<el-col :span="21">{{ $t('pages.lotteryConfig.section.background') }}</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addBlocks"><i class="el-icon-circle-plus" />{{ $t('pages.lotteryConfig.action.add') }}</el-button></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-tabs v-model="blocksIndex" type="border-card" closable @tab-remove="removeBlocks">
|
||||
<el-tab-pane v-for="(item, index) in form.blocks" :key="index" :name="String(index)">
|
||||
<span slot="label">{{ index }}</span>
|
||||
<el-form-item label="内间距">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.padding')">
|
||||
<el-input v-model="item.padding" />
|
||||
</el-form-item>
|
||||
<el-form-item label="背景颜色">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.backgroundColor')">
|
||||
<el-color-picker v-model="item.background" />
|
||||
</el-form-item>
|
||||
|
||||
<div class="card">
|
||||
<div class="title">
|
||||
<el-row>
|
||||
<el-col :span="21">图片</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addBlocksImg(item)"><i class="el-icon-circle-plus" />添加</el-button></el-col>
|
||||
<el-col :span="21">{{ $t('pages.lotteryConfig.section.image') }}</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addBlocksImg(item)"><i class="el-icon-circle-plus" />{{ $t('pages.lotteryConfig.action.add') }}</el-button></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div :key="attributeIndex" class="content">
|
||||
<el-tabs v-if="item.imgs.length > 0" v-model="item.imageIndex" type="border-card" closable @tab-remove="index => removeImg(item, index)">
|
||||
<el-tab-pane v-for="(imgItem, imgIndex) in item.imgs" :key="imgIndex" :name="String(imgIndex)">
|
||||
<span slot="label">{{ imgIndex }}</span>
|
||||
<el-form-item label="图片链接">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.imageLink')">
|
||||
<el-input v-model="imgItem.src" />
|
||||
</el-form-item>
|
||||
<el-form-item label="顶部间距">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.topSpacing')">
|
||||
<el-input v-model="imgItem.top" />
|
||||
</el-form-item>
|
||||
<el-form-item label="图片宽">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.imageWidth')">
|
||||
<el-input v-model="imgItem.width" />
|
||||
</el-form-item>
|
||||
<el-form-item label="图片高">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.imageHeight')">
|
||||
<el-input v-model="imgItem.height" />
|
||||
</el-form-item>
|
||||
<el-form-item label="背景转动">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.backgroundRotate')">
|
||||
<el-radio-group v-model="imgItem.rotate">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
<el-radio :label="true">{{ $t('pages.lotteryConfig.word.yes') }}</el-radio>
|
||||
<el-radio :label="false">{{ $t('pages.lotteryConfig.word.no') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
@ -127,50 +127,50 @@
|
||||
<div class="card bottom-line">
|
||||
<div class="title">
|
||||
<el-row>
|
||||
<el-col :span="21">奖品</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addPrize"><i class="el-icon-circle-plus" />添加</el-button></el-col>
|
||||
<el-col :span="21">{{ $t('pages.lotteryConfig.section.prize') }}</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addPrize"><i class="el-icon-circle-plus" />{{ $t('pages.lotteryConfig.action.add') }}</el-button></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div :key="attributeIndex" class="content">
|
||||
<el-tabs v-model="prizesIndex" type="border-card" closable @tab-remove="removePrize">
|
||||
<el-tab-pane v-for="(item, index) in form.prizes" :key="index" :name="String(index)">
|
||||
<span slot="label">{{ index }}</span>
|
||||
<el-form-item label="奖品编号">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.prizeCode')">
|
||||
<el-input v-model="item.code" />
|
||||
</el-form-item>
|
||||
<el-form-item label="中奖概率">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.winProbability')">
|
||||
<el-input v-model="item.probability" />
|
||||
</el-form-item>
|
||||
<el-form-item label="库存数量">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.stockQuantity')">
|
||||
<el-col :span="4" style="text-align: center;">
|
||||
<el-checkbox v-model="item.unlimited">不限</el-checkbox>
|
||||
<el-checkbox v-model="item.unlimited">{{ $t('pages.lotteryConfig.word.unlimited') }}</el-checkbox>
|
||||
</el-col>
|
||||
<el-col v-if="!item.unlimited" :span="10" style="text-align: center;">
|
||||
库存: {{ item.inStock }}
|
||||
{{ $t('pages.lotteryConfig.stock.stock') }}: {{ item.inStock }}
|
||||
<i class="el-icon-edit cursor-pointer" style="color:#FF9326;" @click="clickInStockEdit(item)" />
|
||||
</el-col>
|
||||
<el-col v-if="!item.unlimited" :span="10" style="text-align: center;">
|
||||
消费: {{ item.consumeInStock }}
|
||||
{{ $t('pages.lotteryConfig.stock.consume') }}: {{ item.consumeInStock }}
|
||||
<i class="el-icon-refresh-left cursor-pointer" style="color:#FF9326;" @click="clickRestConsumeInStock(item)" />
|
||||
</el-col>
|
||||
<div v-if="item.inStock < item.consumeInStock" class="font-danger">
|
||||
”库存 < 消费“ 点击保存系统会清理消费数重新计算
|
||||
{{ $t('pages.lotteryConfig.message.stockLessThanConsume') }}
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="背景颜色">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.backgroundColor')">
|
||||
<el-color-picker v-model="item.background" @change="renderLuckyWheel()" />
|
||||
</el-form-item>
|
||||
<el-form-item label="奖品关联">
|
||||
<el-button type="text" @click="clickSelectPrize(item)"><i class="el-icon-circle-plus" />选择奖品</el-button>
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.prizeRelation')">
|
||||
<el-button type="text" @click="clickSelectPrize(item)"><i class="el-icon-circle-plus" />{{ $t('pages.lotteryConfig.action.selectPrize') }}</el-button>
|
||||
<div v-if="item.prize.content" class="select-prize flex-l">
|
||||
<img :src="item.prize.cover" width="100px" height="100px">
|
||||
<div class="content" style="padding:10px;color:#999999;">
|
||||
<div>内容: {{ item.prize.content }}</div>
|
||||
<div>数量: {{ item.prize.quantity }} {{ item.prize.unit }}</div>
|
||||
<div>{{ $t('pages.lotteryConfig.label.content') }}: {{ item.prize.content }}</div>
|
||||
<div>{{ $t('pages.lotteryConfig.label.quantity') }}: {{ item.prize.quantity }} {{ item.prize.unit }}</div>
|
||||
<div>
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
title="选择设置图片位置"
|
||||
:title="$t('pages.lotteryConfig.popover.selectImagePosition')"
|
||||
trigger="click"
|
||||
>
|
||||
<div class="content">
|
||||
@ -178,12 +178,12 @@
|
||||
{{ itemImgIndex }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button slot="reference" type="text">设置图片</el-button>
|
||||
<el-button slot="reference" type="text">{{ $t('pages.lotteryConfig.action.setImage') }}</el-button>
|
||||
</el-popover>
|
||||
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
title="选择设置文字"
|
||||
:title="$t('pages.lotteryConfig.popover.selectTextTarget')"
|
||||
trigger="click"
|
||||
>
|
||||
<div class="content">
|
||||
@ -191,7 +191,7 @@
|
||||
{{ itemFontIndex }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-button slot="reference" type="text">设置文字</el-button>
|
||||
<el-button slot="reference" type="text">{{ $t('pages.lotteryConfig.action.setText') }}</el-button>
|
||||
</el-popover>
|
||||
</div>
|
||||
</div>
|
||||
@ -200,30 +200,30 @@
|
||||
<div class="card">
|
||||
<div class="title">
|
||||
<el-row>
|
||||
<el-col :span="21">文字</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addFont(item)"><i class="el-icon-circle-plus" />添加</el-button></el-col>
|
||||
<el-col :span="21">{{ $t('pages.lotteryConfig.section.text') }}</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addFont(item)"><i class="el-icon-circle-plus" />{{ $t('pages.lotteryConfig.action.add') }}</el-button></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-tabs v-if="item.fonts.length > 0" v-model="item.fontIndex" type="border-card" closable @tab-remove="index => removeFont(item, index)">
|
||||
<el-tab-pane v-for="(fontItem, fontIndex) in item.fonts" :key="fontIndex" :name="String(fontIndex)">
|
||||
<span slot="label">{{ fontIndex }}</span>
|
||||
<el-form-item label="字体内容">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontContent')">
|
||||
<el-input v-model="fontItem.text" />
|
||||
</el-form-item>
|
||||
<el-form-item label="顶部间距">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.topSpacing')">
|
||||
<el-input v-model="fontItem.top" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体颜色">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontColor')">
|
||||
<el-color-picker v-model="fontItem.fontColor" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体大小">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontSize')">
|
||||
<el-input v-model="fontItem.fontSize" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体样式">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontStyle')">
|
||||
<el-input v-model="fontItem.fontStyle" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体粗细">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontWeight')">
|
||||
<el-select v-model="fontItem.fontWeight" style="width:100%;">
|
||||
<el-option
|
||||
v-for="val in fontWeights"
|
||||
@ -233,16 +233,16 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="字体行高">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.lineHeight')">
|
||||
<el-input v-model="fontItem.lineHeight" />
|
||||
</el-form-item>
|
||||
<el-form-item label="自动换行">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.wordWrap')">
|
||||
<el-radio-group v-model="fontItem.wordWrap">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
<el-radio :label="true">{{ $t('pages.lotteryConfig.word.yes') }}</el-radio>
|
||||
<el-radio :label="false">{{ $t('pages.lotteryConfig.word.no') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="换行宽度">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.wrapWidth')">
|
||||
<el-input v-model="fontItem.lengthLimit" />
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
@ -252,24 +252,24 @@
|
||||
<div class="card">
|
||||
<div class="title">
|
||||
<el-row>
|
||||
<el-col :span="21">图片</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addImg(item)"><i class="el-icon-circle-plus" />添加</el-button></el-col>
|
||||
<el-col :span="21">{{ $t('pages.lotteryConfig.section.image') }}</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addImg(item)"><i class="el-icon-circle-plus" />{{ $t('pages.lotteryConfig.action.add') }}</el-button></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-tabs v-if="item.imgs.length > 0" v-model="item.imageIndex" type="border-card" closable @tab-remove="index => removeImg(item, index)">
|
||||
<el-tab-pane v-for="(imgItem, imgIndex) in item.imgs" :key="imgIndex" :name="String(imgIndex)">
|
||||
<span slot="label">{{ imgIndex }}</span>
|
||||
<el-form-item label="图片链接">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.imageLink')">
|
||||
<el-input v-model="imgItem.src" />
|
||||
</el-form-item>
|
||||
<el-form-item label="顶部间距">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.topSpacing')">
|
||||
<el-input v-model="imgItem.top" />
|
||||
</el-form-item>
|
||||
<el-form-item label="图片宽">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.imageWidth')">
|
||||
<el-input v-model="imgItem.width" />
|
||||
</el-form-item>
|
||||
<el-form-item label="图片高">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.imageHeight')">
|
||||
<el-input v-model="imgItem.height" />
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
@ -284,53 +284,53 @@
|
||||
<div class="card bottom-line">
|
||||
<div class="title">
|
||||
<el-row>
|
||||
<el-col :span="21">按钮</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addButton"><i class="el-icon-circle-plus" />添加</el-button></el-col>
|
||||
<el-col :span="21">{{ $t('pages.lotteryConfig.section.button') }}</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addButton"><i class="el-icon-circle-plus" />{{ $t('pages.lotteryConfig.action.add') }}</el-button></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div :key="attributeIndex" class="content">
|
||||
<el-tabs v-model="buttonIndex" type="border-card" closable @tab-remove="removeButton">
|
||||
<el-tab-pane v-for="(item, index) in form.buttons" :key="index" :name="String(index)">
|
||||
<span slot="label">{{ index }}</span>
|
||||
<el-form-item label="按钮半径">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.buttonRadius')">
|
||||
<el-input v-model="item.radius" />
|
||||
</el-form-item>
|
||||
<el-form-item label="是否显示指针">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.showPointer')">
|
||||
<el-radio-group v-model="item.pointer">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
<el-radio :label="true">{{ $t('pages.lotteryConfig.word.yes') }}</el-radio>
|
||||
<el-radio :label="false">{{ $t('pages.lotteryConfig.word.no') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="背景颜色">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.backgroundColor')">
|
||||
<el-color-picker v-model="item.background" />
|
||||
</el-form-item>
|
||||
<div class="card">
|
||||
<div class="title">
|
||||
<el-row>
|
||||
<el-col :span="21">文字</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addFont(item)"><i class="el-icon-circle-plus" />添加</el-button></el-col>
|
||||
<el-col :span="21">{{ $t('pages.lotteryConfig.section.text') }}</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addFont(item)"><i class="el-icon-circle-plus" />{{ $t('pages.lotteryConfig.action.add') }}</el-button></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-tabs v-if="item.fonts.length > 0" v-model="item.fontIndex" type="border-card" closable @tab-remove="index => removeFont(item, index)">
|
||||
<el-tab-pane v-for="(fontItem, fontIndex) in item.fonts" :key="fontIndex" :name="String(fontIndex)">
|
||||
<span slot="label">{{ fontIndex }}</span>
|
||||
<el-form-item label="字体内容">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontContent')">
|
||||
<el-input v-model="fontItem.text" />
|
||||
</el-form-item>
|
||||
<el-form-item label="顶部间距">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.topSpacing')">
|
||||
<el-input v-model="fontItem.top" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体颜色">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontColor')">
|
||||
<el-color-picker v-model="fontItem.fontColor" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体大小">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontSize')">
|
||||
<el-input v-model="fontItem.fontSize" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体样式">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontStyle')">
|
||||
<el-input v-model="fontItem.fontStyle" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体粗细">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontWeight')">
|
||||
<el-select v-model="fontItem.fontWeight" style="width:100%;">
|
||||
<el-option
|
||||
v-for="val in fontWeights"
|
||||
@ -340,16 +340,16 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="字体行高">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.lineHeight')">
|
||||
<el-input v-model="fontItem.lineHeight" />
|
||||
</el-form-item>
|
||||
<el-form-item label="自动换行">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.wordWrap')">
|
||||
<el-radio-group v-model="fontItem.wordWrap">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
<el-radio :label="true">{{ $t('pages.lotteryConfig.word.yes') }}</el-radio>
|
||||
<el-radio :label="false">{{ $t('pages.lotteryConfig.word.no') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="换行宽度">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.wrapWidth')">
|
||||
<el-input v-model="fontItem.lengthLimit" />
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
@ -359,24 +359,24 @@
|
||||
<div class="card">
|
||||
<div class="title">
|
||||
<el-row>
|
||||
<el-col :span="21">图片</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addImg(item)"><i class="el-icon-circle-plus" />添加</el-button></el-col>
|
||||
<el-col :span="21">{{ $t('pages.lotteryConfig.section.image') }}</el-col>
|
||||
<el-col :span="3"><el-button type="text" @click="addImg(item)"><i class="el-icon-circle-plus" />{{ $t('pages.lotteryConfig.action.add') }}</el-button></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-tabs v-if="item.imgs.length > 0" v-model="item.imageIndex" type="border-card" closable @tab-remove="index => removeImg(item, index)">
|
||||
<el-tab-pane v-for="(imgItem, imgIndex) in item.imgs" :key="imgIndex" :name="String(imgIndex)">
|
||||
<span slot="label">{{ imgIndex }}</span>
|
||||
<el-form-item label="图片链接">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.imageLink')">
|
||||
<el-input v-model="imgItem.src" />
|
||||
</el-form-item>
|
||||
<el-form-item label="顶部间距">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.topSpacing')">
|
||||
<el-input v-model="imgItem.top" />
|
||||
</el-form-item>
|
||||
<el-form-item label="图片宽">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.imageWidth')">
|
||||
<el-input v-model="imgItem.width" />
|
||||
</el-form-item>
|
||||
<el-form-item label="图片高">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.imageHeight')">
|
||||
<el-input v-model="imgItem.height" />
|
||||
</el-form-item>
|
||||
</el-tab-pane>
|
||||
@ -388,44 +388,44 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="title">默认配置</div>
|
||||
<div class="title">{{ $t('pages.lotteryConfig.section.defaultConfig') }}</div>
|
||||
<div class="content">
|
||||
<el-form-item label="扇形间隙">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.gutter')">
|
||||
<el-input-number v-model="form.defaultConfig.gutter" :min="0" style="width:100%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="停止范围">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.stopRange')">
|
||||
<el-slider v-model="form.defaultConfig.stopRange" />
|
||||
</el-form-item>
|
||||
<el-form-item label="偏移角度">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.offsetDegree')">
|
||||
<el-input-number v-model="form.defaultConfig.offsetDegree" :min="0" style="width:100%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="速度">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.speed')">
|
||||
<el-input-number v-model="form.defaultConfig.speed" :min="0" style="width:100%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开始旋转时间">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.accelerationTime')">
|
||||
<el-input-number v-model="form.defaultConfig.accelerationTime" :min="0" style="width:100%;" />
|
||||
</el-form-item>
|
||||
<el-form-item label="缓慢停止时间">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.decelerationTime')">
|
||||
<el-input-number v-model="form.defaultConfig.decelerationTime" :min="0" style="width:100%;" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="title">默认样式</div>
|
||||
<div class="title">{{ $t('pages.lotteryConfig.section.defaultStyle') }}</div>
|
||||
<div class="content">
|
||||
<el-form-item label="背景颜色">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.backgroundColor')">
|
||||
<el-color-picker v-model="form.defaultStyle.background" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体颜色">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontColor')">
|
||||
<el-input v-model="form.defaultStyle.fontColor" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体大小">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontSize')">
|
||||
<el-input v-model="form.defaultStyle.fontSize" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体样式">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontStyle')">
|
||||
<el-input v-model="form.defaultStyle.fontStyle" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字体粗细">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.fontWeight')">
|
||||
<el-select v-model="form.defaultStyle.fontWeight" style="width:100%;">
|
||||
<el-option
|
||||
v-for="item in fontWeights"
|
||||
@ -435,26 +435,26 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="字体行高">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.lineHeight')">
|
||||
<el-input v-model="form.defaultStyle.lineHeight" />
|
||||
</el-form-item>
|
||||
<el-form-item label="自动换行">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.wordWrap')">
|
||||
<el-radio-group v-model="form.defaultStyle.wordWrap">
|
||||
<el-radio :label="true">是</el-radio>
|
||||
<el-radio :label="false">否</el-radio>
|
||||
<el-radio :label="true">{{ $t('pages.lotteryConfig.word.yes') }}</el-radio>
|
||||
<el-radio :label="false">{{ $t('pages.lotteryConfig.word.no') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="换行宽度">
|
||||
<el-form-item :label="$t('pages.lotteryConfig.form.wrapWidth')">
|
||||
<el-input v-model="form.defaultStyle.lengthLimit" />
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
</el-form>
|
||||
<div class="operation-but">
|
||||
<el-button :loading="formLoading" @click="loadLotteryConf">重置</el-button>
|
||||
<el-button @click="copyForm">复制</el-button>
|
||||
<el-button @click="importForm">导入</el-button>
|
||||
<el-button type="primary" :loading="formSubmitLoading" @click="clickSubmit">保存</el-button>
|
||||
<el-button :loading="formLoading" @click="loadLotteryConf">{{ $t('pages.lotteryConfig.action.reset') }}</el-button>
|
||||
<el-button @click="copyForm">{{ $t('pages.lotteryConfig.action.copy') }}</el-button>
|
||||
<el-button @click="importForm">{{ $t('pages.lotteryConfig.action.import') }}</el-button>
|
||||
<el-button type="primary" :loading="formSubmitLoading" @click="clickSubmit">{{ $t('pages.lotteryConfig.action.save') }}</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -571,7 +571,7 @@ export default {
|
||||
for (let index = 0; index < 6; index++) {
|
||||
const prize = this.getEmptyPrizeObj()
|
||||
prize.background = index % 2 === 0 ? '#f8d384' : '#f9e3bb'
|
||||
prize.fonts[0].text = index + 1 + ' 元红包'
|
||||
prize.fonts[0].text = this.$t('pages.lotteryConfig.defaultPrizeText', { index: index + 1 })
|
||||
form.prizes.push(prize)
|
||||
}
|
||||
return form
|
||||
@ -590,11 +590,15 @@ export default {
|
||||
},
|
||||
importForm() {
|
||||
const that = this
|
||||
that.$prompt('JSON配置信息', '导入配置', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
closeOnClickModal: false
|
||||
}).then(({ value }) => {
|
||||
that.$prompt(
|
||||
that.$t('pages.lotteryConfig.prompt.jsonConfig'),
|
||||
that.$t('pages.lotteryConfig.prompt.importConfig'),
|
||||
{
|
||||
confirmButtonText: that.$t('pages.lotteryConfig.action.confirm'),
|
||||
cancelButtonText: that.$t('pages.lotteryConfig.action.cancel'),
|
||||
closeOnClickModal: false
|
||||
}
|
||||
).then(({ value }) => {
|
||||
that.form = JSON.parse(value)
|
||||
that.renderLuckyWheel()
|
||||
}).catch(() => {
|
||||
@ -690,7 +694,7 @@ export default {
|
||||
},
|
||||
addBlocks() {
|
||||
if (this.form.blocks.length > 10) {
|
||||
this.$opsMessage.warn('有点多了,哥哥!')
|
||||
this.$opsMessage.warn(this.$t('pages.lotteryConfig.message.tooMany'))
|
||||
return
|
||||
}
|
||||
this.form.blocks.push({
|
||||
@ -703,7 +707,7 @@ export default {
|
||||
},
|
||||
removeBlocks(index) {
|
||||
if (this.form.blocks.length === 1) {
|
||||
this.$opsMessage.warn('求求你做个人,留下一个吧!')
|
||||
this.$opsMessage.warn(this.$t('pages.lotteryConfig.message.keepAtLeastOne'))
|
||||
return
|
||||
}
|
||||
this.form.blocks.splice(index, 1)
|
||||
@ -711,7 +715,7 @@ export default {
|
||||
},
|
||||
addPrize() {
|
||||
if (this.form.prizes.length > 10) {
|
||||
this.$opsMessage.warn('有点多了,哥哥!')
|
||||
this.$opsMessage.warn(this.$t('pages.lotteryConfig.message.tooMany'))
|
||||
return
|
||||
}
|
||||
const prize = this.getEmptyPrizeObj()
|
||||
@ -722,7 +726,7 @@ export default {
|
||||
},
|
||||
removePrize(index) {
|
||||
if (this.form.prizes.length === 1) {
|
||||
this.$opsMessage.warn('求求你做个人,留下一个吧!')
|
||||
this.$opsMessage.warn(this.$t('pages.lotteryConfig.message.keepAtLeastOne'))
|
||||
return
|
||||
}
|
||||
this.form.prizes.splice(index, 1)
|
||||
@ -730,7 +734,7 @@ export default {
|
||||
},
|
||||
addButton() {
|
||||
if (this.form.buttons.length > 10) {
|
||||
this.$opsMessage.warn('有点多了,哥哥!')
|
||||
this.$opsMessage.warn(this.$t('pages.lotteryConfig.message.tooMany'))
|
||||
return
|
||||
}
|
||||
this.form.buttons.push(this.getEmptyPrizeObj())
|
||||
@ -739,7 +743,7 @@ export default {
|
||||
},
|
||||
removeButton(index) {
|
||||
if (this.form.buttons.length === 1) {
|
||||
this.$opsMessage.warn('求求你做个人,留下一个吧!')
|
||||
this.$opsMessage.warn(this.$t('pages.lotteryConfig.message.keepAtLeastOne'))
|
||||
return
|
||||
}
|
||||
this.form.buttons.splice(index, 1)
|
||||
@ -747,7 +751,7 @@ export default {
|
||||
},
|
||||
addBlocksImg(item) {
|
||||
if (item.imgs.length > 10) {
|
||||
this.$opsMessage.warn('有点多了,哥哥!')
|
||||
this.$opsMessage.warn(this.$t('pages.lotteryConfig.message.tooMany'))
|
||||
return
|
||||
}
|
||||
item.imgs.push(this.getEmptyImageObj())
|
||||
@ -759,7 +763,7 @@ export default {
|
||||
},
|
||||
addImg(item) {
|
||||
if (item.imgs.length > 10) {
|
||||
this.$opsMessage.warn('有点多了,哥哥!')
|
||||
this.$opsMessage.warn(this.$t('pages.lotteryConfig.message.tooMany'))
|
||||
return
|
||||
}
|
||||
item.imgs.push(this.getEmptyBaseImageObj())
|
||||
@ -778,7 +782,7 @@ export default {
|
||||
},
|
||||
addFont(item, index) {
|
||||
if (item.fonts.length > 10) {
|
||||
this.$opsMessage.warn('有点多了,哥哥!')
|
||||
this.$opsMessage.warn(this.$t('pages.lotteryConfig.message.tooMany'))
|
||||
return
|
||||
}
|
||||
item.fonts.push(this.getEmptyFontObj())
|
||||
@ -811,36 +815,40 @@ export default {
|
||||
},
|
||||
clickInStockEdit(item) {
|
||||
const that = this
|
||||
that.$prompt('请输入库存数量', '库存编辑', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
inputPattern: /^\d+$/,
|
||||
inputErrorMessage: '请输入正整数',
|
||||
closeOnClickModal: false
|
||||
}).then(({ value }) => {
|
||||
that.$prompt(
|
||||
that.$t('pages.lotteryConfig.prompt.enterStock'),
|
||||
that.$t('pages.lotteryConfig.prompt.stockEdit'),
|
||||
{
|
||||
confirmButtonText: that.$t('pages.lotteryConfig.action.confirm'),
|
||||
cancelButtonText: that.$t('pages.lotteryConfig.action.cancel'),
|
||||
inputPattern: /^\d+$/,
|
||||
inputErrorMessage: that.$t('pages.lotteryConfig.validation.positiveInteger'),
|
||||
closeOnClickModal: false
|
||||
}
|
||||
).then(({ value }) => {
|
||||
item.inStock = value
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'info',
|
||||
message: '取消输入'
|
||||
message: this.$t('pages.lotteryConfig.message.inputCancelled')
|
||||
})
|
||||
})
|
||||
},
|
||||
clickRestConsumeInStock(item) {
|
||||
const that = this
|
||||
that.$confirm('是否重置消费库存', '重置', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
that.$confirm(that.$t('pages.lotteryConfig.confirm.resetConsumeStock'), that.$t('pages.lotteryConfig.action.reset'), {
|
||||
confirmButtonText: that.$t('pages.lotteryConfig.action.confirm'),
|
||||
cancelButtonText: that.$t('pages.lotteryConfig.action.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '重置成功!'
|
||||
message: this.$t('pages.lotteryConfig.message.resetSuccess')
|
||||
})
|
||||
}).catch(() => {
|
||||
this.$message({
|
||||
type: 'info',
|
||||
message: '已取消重置'
|
||||
message: this.$t('pages.lotteryConfig.message.resetCancelled')
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@ -1,21 +1,24 @@
|
||||
<template>
|
||||
<div v-loading="latestActiveListLoading" class="active-index">
|
||||
<div class="title">第三方活跃指标
|
||||
<div v-loading="latestActiveListLoading" class="active-index" :data-language="language">
|
||||
<div class="title">
|
||||
{{ $t('pages.dashboard.activeIndex.thirdPartyTitle') }}
|
||||
<span class="desc">All {{ latestActiveIndex.date || '-' }}</span>
|
||||
</div>
|
||||
<div class=" flex-l flex-wrap">
|
||||
<div class="flex-l flex-wrap">
|
||||
<div
|
||||
v-for="(item, index) in activeIndexs"
|
||||
:key="index"
|
||||
class="block-card"
|
||||
:class="{'block-card-selected': item.type === selectedIndex.data.type}"
|
||||
@click="clickQueryCharts('IM_ACTIVE',item)"
|
||||
:class="{ 'block-card-selected': item.type === selectedIndex.data.type }"
|
||||
@click="clickQueryCharts('IM_ACTIVE', item)"
|
||||
>
|
||||
<div class="block-card-title nowrap-ellipsis"><a :title="item.name">{{ item.name }}</a></div>
|
||||
<div class="cite">{{ latestActiveIndex.imActiveIndex ? latestActiveIndex.imActiveIndex[item.field] || '0' : '-' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title">自定义活跃指标
|
||||
|
||||
<div class="title">
|
||||
{{ $t('pages.dashboard.activeIndex.customTitle') }}
|
||||
<span class="desc">{{ latestActiveIndex.date || '-' }}</span>
|
||||
</div>
|
||||
<div class="flex-l flex-wrap">
|
||||
@ -23,28 +26,65 @@
|
||||
v-for="(item, index) in customizeIndexs"
|
||||
:key="index"
|
||||
class="block-card"
|
||||
|
||||
:class="{'block-card-selected': item.type === selectedIndex.data.type}"
|
||||
@click="clickQueryCharts('CUTOMIZE_ACTIVE',item)"
|
||||
:class="{ 'block-card-selected': item.type === selectedIndex.data.type }"
|
||||
@click="clickQueryCharts('CUTOMIZE_ACTIVE', item)"
|
||||
>
|
||||
<div class="block-card-title nowrap-ellipsis"><a :title="item.name">{{ item.name }}</a></div>
|
||||
<div class="cite">{{ latestActiveIndex.customizeActiveIndex ? latestActiveIndex.customizeActiveIndex[item.field] || '0' : '-' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="title">数据折线图
|
||||
|
||||
<div class="title">
|
||||
{{ $t('pages.dashboard.activeIndex.chartTitle') }}
|
||||
<span class="desc">{{ chartsData.title }}</span>
|
||||
</div>
|
||||
<div class="charts">
|
||||
<line-graph-charts :charts-data="chartsData" height="300px" />
|
||||
<line-graph-charts :key="'active-index-chart-' + language" :charts-data="chartsData" height="300px" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { formatDate } from '@/utils'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { listUserActiveIndex } from '@/api/statistics'
|
||||
import LineGraphCharts from './line-graph-charts'
|
||||
|
||||
const ACTIVE_INDEX_CONFIGS = [
|
||||
{ key: 'activeUsers', field: 'activeUserNum', type: 'ACTIVE_USER_NUM' },
|
||||
{ key: 'newRegistrations', field: 'registUserNumOneDay', type: 'REGIST_USER_NUM_ONE_DAY' },
|
||||
{ key: 'totalRegistrations', field: 'registUserNumTotal', type: 'REGIST_USER_NUM_TOTAL' },
|
||||
{ key: 'loginTimes', field: 'loginTimes', type: 'LOGIN_TIMES' },
|
||||
{ key: 'loginUsers', field: 'loginUserNum', type: 'LOGIN_USER_NUM' },
|
||||
{ key: 'upMessages', field: 'upMsgNum', type: 'UP_MSG_NUM' },
|
||||
{ key: 'sendMessageUsers', field: 'sendMsgUserNum', type: 'SEND_MSG_USER_NUM' },
|
||||
{ key: 'apnsMessages', field: 'apnsMsgNum', type: 'APNS_MSG_NUM' },
|
||||
{ key: 'c2cUpMessages', field: 'c2cUpMsgNum', type: 'C2C_UP_MSG_NUM' },
|
||||
{ key: 'c2cDownMessages', field: 'c2cDownMsgNum', type: 'C2C_DOWN_MSG_NUM' },
|
||||
{ key: 'c2cSendUsers', field: 'c2cSendMsgUserNum', type: 'C2C_SEND_MSG_USER_NUM' },
|
||||
{ key: 'c2cApnsMessages', field: 'c2cAPNSMsgNum', type: 'C2C_APNS_MSG_NUM' },
|
||||
{ key: 'maxOnlineUsers', field: 'maxOnlineNum', type: 'MAX_ONLINE_NUM' },
|
||||
{ key: 'downMessagesTotal', field: 'downMsgNum', type: 'FOWN_MSG_NUM' },
|
||||
{ key: 'chainIncrease', field: 'chainIncrease', type: 'CHAIN_INCREASE' },
|
||||
{ key: 'chainDecrease', field: 'chainDecrease', type: 'CHAIN_DECREASE' },
|
||||
{ key: 'groupUpMessages', field: 'groupUpMsgNum', type: 'GROUP_UP_MSG_NUM' },
|
||||
{ key: 'groupDownMessages', field: 'groupDownMsgNum', type: 'GROUP_DOWN_MSG_NUM' },
|
||||
{ key: 'groupSendUsers', field: 'groupSendMsgUserNum', type: 'GROUP_SEND_MSG_USER_NUM' },
|
||||
{ key: 'groupApnsMessages', field: 'groupAPNSMsgNum', type: 'GROUP_APNS_MSG_NUM' },
|
||||
{ key: 'groupSendCount', field: 'groupSendMsgGroupNum', type: 'GROUP_SEND_MSG_GROUP_NUM' },
|
||||
{ key: 'groupJoinTotal', field: 'groupJoinGroupTimes', type: 'GROUP_JOIN_GROUP_TIMES' },
|
||||
{ key: 'groupQuitTotal', field: 'groupQuitGroupTimes', type: 'GROUP_QUIT_GROUP_TIMES' },
|
||||
{ key: 'groupNewCount', field: 'groupNewGroupNum', type: 'GROUP_NEW_GROUP_NUM' },
|
||||
{ key: 'groupTotalCount', field: 'groupAllGroupNum', type: 'GROUP_ALL_GROUP_NUM' },
|
||||
{ key: 'groupDestroyCount', field: 'groupDestroyGroupNum', type: 'GROUP_DESTORY_GROUP_NUM' },
|
||||
{ key: 'callbackRequests', field: 'callbackReq', type: 'CALLBACK_REQ' },
|
||||
{ key: 'callbackResponses', field: 'callbackRsp', type: 'CALLBACK_RSP' }
|
||||
]
|
||||
|
||||
const CUSTOM_ACTIVE_INDEX_CONFIGS = [
|
||||
{ key: 'ordinaryUsers', field: 'ordinaryActiveNum', type: 'GENERAL_USER_ACTIVE_NUM' },
|
||||
{ key: 'hosts', field: 'anchorActiveNum', type: 'HOST_USER_ACTIVE_NUM' }
|
||||
]
|
||||
|
||||
export default {
|
||||
components: { LineGraphCharts },
|
||||
data() {
|
||||
@ -52,42 +92,6 @@ export default {
|
||||
latestActiveListLoading: true,
|
||||
latestActiveList: [],
|
||||
latestActiveIndex: {},
|
||||
// 活跃指标
|
||||
activeIndexs: [
|
||||
{ name: '活跃用户数', field: 'activeUserNum', type: 'ACTIVE_USER_NUM' },
|
||||
{ name: '新增注册人数', field: 'registUserNumOneDay', type: 'REGIST_USER_NUM_ONE_DAY' },
|
||||
{ name: '累计注册人数', field: 'registUserNumTotal', type: 'REGIST_USER_NUM_TOTAL' },
|
||||
{ name: '登录次数', field: 'loginTimes', type: 'LOGIN_TIMES' },
|
||||
{ name: '登录人数', field: 'loginUserNum', type: 'LOGIN_USER_NUM' },
|
||||
{ name: '上行消息数', field: 'upMsgNum', type: 'UP_MSG_NUM' },
|
||||
{ name: '发消息人数', field: 'sendMsgUserNum', type: 'SEND_MSG_USER_NUM' },
|
||||
{ name: 'APNs 推送数', field: 'apnsMsgNum', type: 'APNS_MSG_NUM' },
|
||||
{ name: '上行消息数(C2C)', field: 'c2cUpMsgNum', type: 'C2C_UP_MSG_NUM' },
|
||||
{ name: '下行消息数(C2C)', field: 'c2cDownMsgNum', type: 'C2C_DOWN_MSG_NUM' },
|
||||
{ name: '发消息人数(C2C)', field: 'c2cSendMsgUserNum', type: 'C2C_SEND_MSG_USER_NUM' },
|
||||
{ name: 'APNs 推送数(C2C)', field: 'c2cAPNSMsgNum', type: 'C2C_APNS_MSG_NUM' },
|
||||
{ name: '最高在线人数', field: 'maxOnlineNum', type: 'MAX_ONLINE_NUM' },
|
||||
{ name: '下行消息总数(C2C和群)', field: 'downMsgNum', type: 'FOWN_MSG_NUM' },
|
||||
{ name: '关系链对数增加量', field: 'chainIncrease', type: 'CHAIN_INCREASE' },
|
||||
{ name: '关系链对数删除量', field: 'chainDecrease', type: 'CHAIN_DECREASE' },
|
||||
{ name: '上行消息数(群)', field: 'groupUpMsgNum', type: 'GROUP_UP_MSG_NUM' },
|
||||
{ name: '下行消息数(群)', field: 'groupDownMsgNum', type: 'GROUP_DOWN_MSG_NUM' },
|
||||
{ name: '发消息人数(群)', field: 'groupSendMsgUserNum', type: 'GROUP_SEND_MSG_USER_NUM' },
|
||||
{ name: 'APNs 推送数(群)', field: 'groupAPNSMsgNum', type: 'GROUP_APNS_MSG_NUM' },
|
||||
{ name: '发消息群组数', field: 'groupSendMsgGroupNum', type: 'GROUP_SEND_MSG_GROUP_NUM' },
|
||||
{ name: '入群总数', field: 'groupJoinGroupTimes', type: 'GROUP_JOIN_GROUP_TIMES' },
|
||||
{ name: '退群总数', field: 'groupQuitGroupTimes', type: 'GROUP_QUIT_GROUP_TIMES' },
|
||||
{ name: '新增群组数', field: 'groupNewGroupNum', type: 'GROUP_NEW_GROUP_NUM' },
|
||||
{ name: '累计群组数', field: 'groupAllGroupNum', type: 'GROUP_ALL_GROUP_NUM' },
|
||||
{ name: '解散群个数', field: 'groupDestroyGroupNum', type: 'GROUP_DESTORY_GROUP_NUM' },
|
||||
{ name: '回调请求数', field: 'callbackReq', type: 'CALLBACK_REQ' },
|
||||
{ name: '回调应答数', field: 'callbackRsp', type: 'CALLBACK_RSP' }
|
||||
],
|
||||
// 自定义活跃指标
|
||||
customizeIndexs: [
|
||||
{ name: '普通用户活跃数', field: 'ordinaryActiveNum', type: 'GENERAL_USER_ACTIVE_NUM' },
|
||||
{ name: '主播活跃数', field: 'anchorActiveNum', type: 'HOST_USER_ACTIVE_NUM' }
|
||||
],
|
||||
chartsData: {
|
||||
data: [],
|
||||
title: ''
|
||||
@ -98,7 +102,29 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapGetters(['language']),
|
||||
activeIndexs() {
|
||||
const language = this.language
|
||||
return ACTIVE_INDEX_CONFIGS.map(item => ({
|
||||
...item,
|
||||
name: this.$t(`pages.dashboard.activeIndex.metrics.${item.key}`)
|
||||
}))
|
||||
},
|
||||
customizeIndexs() {
|
||||
const language = this.language
|
||||
return CUSTOM_ACTIVE_INDEX_CONFIGS.map(item => ({
|
||||
...item,
|
||||
name: this.$t(`pages.dashboard.activeIndex.customMetrics.${item.key}`)
|
||||
}))
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
language() {
|
||||
this.syncSelectedIndexByType()
|
||||
this.proccessIndexChartsData()
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.selectedIndex = {
|
||||
type: 'IM_ACTIVE',
|
||||
@ -108,33 +134,38 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
renderData() {
|
||||
const that = this
|
||||
that.latestActiveListLoading = true
|
||||
this.latestActiveListLoading = true
|
||||
listUserActiveIndex().then(res => {
|
||||
that.latestActiveListLoading = false
|
||||
this.latestActiveListLoading = false
|
||||
const { body } = res
|
||||
that.latestActiveList = body || []
|
||||
if (that.latestActiveList.length > 0) {
|
||||
that.latestActiveIndex = that.latestActiveList[that.latestActiveList.length - 1]
|
||||
this.latestActiveList = body || []
|
||||
if (this.latestActiveList.length > 0) {
|
||||
this.latestActiveIndex = this.latestActiveList[this.latestActiveList.length - 1]
|
||||
}
|
||||
that.proccessIndexChartsData()
|
||||
that.renderCharts()
|
||||
}).catch(er => {
|
||||
that.latestActiveListLoading = false
|
||||
this.proccessIndexChartsData()
|
||||
}).catch(() => {
|
||||
this.latestActiveListLoading = false
|
||||
})
|
||||
},
|
||||
syncSelectedIndexByType() {
|
||||
const source = this.selectedIndex.type === 'CUTOMIZE_ACTIVE' ? this.customizeIndexs : this.activeIndexs
|
||||
const matched = source.find(item => item.type === this.selectedIndex.data.type) || source[0] || {}
|
||||
this.selectedIndex = {
|
||||
...this.selectedIndex,
|
||||
data: matched
|
||||
}
|
||||
},
|
||||
proccessIndexChartsData() {
|
||||
const that = this
|
||||
const type = that.selectedIndex.type
|
||||
const data = that.selectedIndex.data
|
||||
const type = this.selectedIndex.type
|
||||
const data = this.selectedIndex.data
|
||||
const field = data.field
|
||||
that.chartsData.title = data.name
|
||||
that.chartsData.data = []
|
||||
if (!that.latestActiveList || that.latestActiveList.length <= 0 || !field) {
|
||||
this.chartsData.title = data.name
|
||||
this.chartsData.data = []
|
||||
if (!this.latestActiveList || this.latestActiveList.length <= 0 || !field) {
|
||||
return
|
||||
}
|
||||
const resultData = []
|
||||
that.latestActiveList.forEach(activeIndex => {
|
||||
this.latestActiveList.forEach(activeIndex => {
|
||||
if (type === 'IM_ACTIVE') {
|
||||
const value = activeIndex.imActiveIndex[field] || 0
|
||||
resultData.push([activeIndex.date, value])
|
||||
@ -144,7 +175,7 @@ export default {
|
||||
resultData.push([activeIndex.date, value])
|
||||
}
|
||||
})
|
||||
that.chartsData = {
|
||||
this.chartsData = {
|
||||
title: data.name,
|
||||
data: resultData
|
||||
}
|
||||
@ -155,105 +186,31 @@ export default {
|
||||
data: item
|
||||
}
|
||||
this.proccessIndexChartsData()
|
||||
},
|
||||
handleSearch() {
|
||||
this.renderData()
|
||||
},
|
||||
handleListToChartsData() {
|
||||
const that = this
|
||||
const chartsData = []
|
||||
if (that.list.length > 0) {
|
||||
that.list.forEach(item => {
|
||||
const date = formatDate(item.statisticsTime, 'yyyy-MM-dd')
|
||||
chartsData.push([date, (item.quantity || 0)])
|
||||
})
|
||||
}
|
||||
return chartsData
|
||||
},
|
||||
renderCharts() {
|
||||
const that = this
|
||||
const thatDayData = that.handleListToChartsData()
|
||||
that.subsidyIntegralCharts.setOption({
|
||||
color: ['#66b3ff', '#ce90e8', '#ff9c6e', '#5cdbd3'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(50,50,50,0.5)',
|
||||
axisPointer: {
|
||||
type: 'cross',
|
||||
label: {
|
||||
lineStyle: { color: '#009688' },
|
||||
crossStyle: { color: '#008acd' },
|
||||
shadowStyle: { color: 'rgba(200,200,200,0.2)' }
|
||||
}
|
||||
}
|
||||
},
|
||||
grid: {
|
||||
x: 20,
|
||||
y: 50,
|
||||
x2: 20,
|
||||
y2: 0,
|
||||
containLabel: true,
|
||||
borderColor: '#eee'
|
||||
},
|
||||
toolbox: { color: ['#1e90ff', '#1e90ff', '#1e90ff', '#1e90ff'], effectiveColor: '#ff4500' },
|
||||
xAxis: [
|
||||
{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 38
|
||||
},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
splitNumber: 24,
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }}
|
||||
}
|
||||
],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
axisTick: { show: true, length: 0 },
|
||||
splitNumber: 5,
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }}
|
||||
}],
|
||||
legend: { y: 10, textStyle: { color: '#8e929b' }},
|
||||
series: [
|
||||
{
|
||||
name: '补贴积分',
|
||||
type: 'line',
|
||||
stack: '补贴积分',
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData,
|
||||
areaStyle: {}
|
||||
}]
|
||||
}, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.active-index {
|
||||
.title {
|
||||
line-height: 60px;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
line-height: 60px;
|
||||
|
||||
.desc {
|
||||
color: #999999;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
|
||||
.block-card {
|
||||
width: 130px;
|
||||
margin-right: 5px;
|
||||
cursor: pointer;
|
||||
border-radius: 2px;
|
||||
margin-right:5px;
|
||||
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="daily-currency-charts">
|
||||
<el-select v-model="typeValue" placeholder="请选择" size="mini" @change="typeValueChange">
|
||||
<div class="daily-currency-charts" :data-language="language">
|
||||
<el-select v-model="typeValue" :placeholder="$t('pages.dashboard.shared.select')" size="mini" @change="typeValueChange">
|
||||
<el-option
|
||||
v-for="item in types"
|
||||
:key="item.value"
|
||||
@ -8,13 +8,12 @@
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<div id="barCharts" ref="barCharts" :style="'width: 100%;height:'+ height +';'" />
|
||||
<div id="barCharts" ref="barCharts" :style="'width: 100%;height:' + height + ';'" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
// import { currencyOrigins } from '@/constant/type'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@ -29,10 +28,6 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
types: [
|
||||
{ value: 0, name: '收入' },
|
||||
{ value: 1, name: '支出' }
|
||||
],
|
||||
dateNumber: '',
|
||||
typeValue: 0,
|
||||
barCharts: null,
|
||||
@ -42,37 +37,47 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['language']),
|
||||
types() {
|
||||
const language = this.language
|
||||
return [
|
||||
{ value: 0, name: this.$t('pages.dashboard.shared.income') },
|
||||
{ value: 1, name: this.$t('pages.dashboard.shared.expenditure') }
|
||||
]
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
chartsData: {
|
||||
handler(newVal) {
|
||||
const that = this
|
||||
that.groupChartsData = that.groupChartsDataByType()
|
||||
that.$nextTick(() => {
|
||||
that.renderCharts()
|
||||
handler() {
|
||||
this.groupChartsData = this.groupChartsDataByType()
|
||||
this.$nextTick(() => {
|
||||
this.renderCharts()
|
||||
})
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
language() {
|
||||
this.$nextTick(() => {
|
||||
this.renderCharts()
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
mounted() {
|
||||
const that = this
|
||||
that.barCharts = that.$echarts.init(that.$refs.barCharts)
|
||||
that.renderCharts()
|
||||
this.barCharts = this.$echarts.init(this.$refs.barCharts)
|
||||
this.renderCharts()
|
||||
window.addEventListener('resize', () => {
|
||||
that.barCharts.resize()
|
||||
this.barCharts.resize()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
groupChartsDataByType() {
|
||||
const that = this
|
||||
const obj = {
|
||||
income: [],
|
||||
expenditure: []
|
||||
}
|
||||
if (that.chartsData.length > 0) {
|
||||
that.chartsData.forEach(item => {
|
||||
if (this.chartsData.length > 0) {
|
||||
this.chartsData.forEach(item => {
|
||||
if (item.type === 0) {
|
||||
obj.income.push(item)
|
||||
}
|
||||
@ -84,7 +89,6 @@ export default {
|
||||
return obj
|
||||
},
|
||||
getBarData(list) {
|
||||
const that = this
|
||||
const dataKeys = []
|
||||
const dataList = []
|
||||
if (!list || list.length === 0) {
|
||||
@ -99,16 +103,18 @@ export default {
|
||||
name: item.originName,
|
||||
value: item.quantity,
|
||||
itemStyle: {
|
||||
color: that.getRandomColor()
|
||||
color: this.getRandomColor()
|
||||
}
|
||||
})
|
||||
}
|
||||
return { keys: dataKeys, data: dataList }
|
||||
},
|
||||
renderCharts() {
|
||||
const that = this
|
||||
const barData = that.getBarData(that.typeValue === 0 ? that.groupChartsData.income : that.groupChartsData.expenditure)
|
||||
that.barCharts.setOption({
|
||||
if (!this.barCharts) {
|
||||
return
|
||||
}
|
||||
const barData = this.getBarData(this.typeValue === 0 ? this.groupChartsData.income : this.groupChartsData.expenditure)
|
||||
this.barCharts.setOption({
|
||||
color: ['#66b3ff', '#ce90e8', '#ff9c6e', '#5cdbd3'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
@ -130,11 +136,9 @@ export default {
|
||||
containLabel: true,
|
||||
borderColor: '#eee'
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
show: false
|
||||
}
|
||||
],
|
||||
xAxis: [{
|
||||
show: false
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'category',
|
||||
data: barData.keys,
|
||||
@ -146,7 +150,7 @@ export default {
|
||||
width: 15,
|
||||
overflow: 'truncate',
|
||||
ellipsis: '...',
|
||||
formatter: function(value) {
|
||||
formatter(value) {
|
||||
return value.length > 10 ? value.substring(0, 10) + '...' : value
|
||||
}
|
||||
}
|
||||
@ -173,9 +177,8 @@ export default {
|
||||
return 'rgba(' + r + ',' + g + ',' + b + ',0.8)'
|
||||
},
|
||||
typeValueChange() {
|
||||
const that = this
|
||||
that.$nextTick(() => {
|
||||
that.renderCharts()
|
||||
this.$nextTick(() => {
|
||||
this.renderCharts()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div v-loading="loading" class="dily-register-user">
|
||||
<div v-loading="loading" class="dily-register-user" :data-language="language">
|
||||
<el-date-picker
|
||||
v-model="dateNumber"
|
||||
style="margin-bottom: 10px;"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
:placeholder="$t('pages.dashboard.goldOriginTop.datePlaceholder')"
|
||||
value-format="yyyyMMdd"
|
||||
size="mini"
|
||||
:picker-options="pickerOptions"
|
||||
@ -14,16 +14,16 @@
|
||||
<div v-for="(item, index) in list" :key="index">
|
||||
<el-card v-if="sysOriginPlatforms.includes(item.sysOrigin)" class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>金币TOP榜({{ item.sysOriginName }})</span>
|
||||
<span>{{ $t('pages.dashboard.goldOriginTop.title', { sysOriginName: item.sysOriginName }) }}</span>
|
||||
</div>
|
||||
<div style="padding: 10px 0px">
|
||||
<div style="padding: 10px 0">
|
||||
<el-row>
|
||||
<el-col class="card-col" :md="24" :xs="24">
|
||||
<bar-graph-charts
|
||||
ref="lineGraphCharts"
|
||||
:key="item.sysOrigin"
|
||||
:key="item.sysOrigin + '-' + language"
|
||||
:charts-data="item.list"
|
||||
:height="(item.list.length * 20)+'px'"
|
||||
:height="(item.list.length * 20) + 'px'"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
@ -58,7 +58,7 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls']),
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls', 'language']),
|
||||
sysOriginPlatforms() {
|
||||
if (!this.permissionsSysOriginPlatformAlls || this.permissionsSysOriginPlatformAlls.length <= 0) {
|
||||
return []
|
||||
@ -71,30 +71,31 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
loadOrigin() {
|
||||
const that = this
|
||||
that.loading = true
|
||||
this.loading = true
|
||||
latestStatisticsGoldOriginDetailsAll(this.dateNumber).then(res => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
const { body } = res
|
||||
const list = body || []
|
||||
that.list = list.filter(item => !item.sysOrigin || that.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
this.list = list.filter(item => !item.sysOrigin || this.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
}).catch(() => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
querySearch(queryString, cb) {
|
||||
var restaurants = currencyOrigins
|
||||
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
|
||||
const restaurants = currencyOrigins
|
||||
const results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
|
||||
cb(results)
|
||||
},
|
||||
createFilter(queryString) {
|
||||
return (restaurant) => {
|
||||
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) >= 0) || (restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) >= 0)
|
||||
return restaurant => {
|
||||
return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) >= 0 ||
|
||||
restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) >= 0
|
||||
}
|
||||
},
|
||||
handleSelect(item) {
|
||||
this.selectOrigin = item.value
|
||||
this.selectOriginName = item.name
|
||||
const selectedItem = item || currencyOrigins[0]
|
||||
this.selectOrigin = selectedItem.value
|
||||
this.selectOriginName = selectedItem.name
|
||||
this.loadOrigin()
|
||||
},
|
||||
clickAnalyze() {
|
||||
@ -111,15 +112,16 @@ export default {
|
||||
.box-card {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
|
||||
.card-col {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.register-logout-count {
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,21 +1,18 @@
|
||||
<template>
|
||||
<div v-loading="loading" class="dily-register-user">
|
||||
<div v-loading="loading" class="dily-register-user" :data-language="language">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="24">
|
||||
<el-autocomplete
|
||||
v-model="selectOriginName"
|
||||
popper-class="my-autocomplete"
|
||||
:fetch-suggestions="querySearch"
|
||||
placeholder="请输选择查看来源类型"
|
||||
:placeholder="$t('pages.dashboard.dailyCurrencyGold.originTypePlaceholder')"
|
||||
clearable
|
||||
style="width: 100%; padding-bottom: 10px;"
|
||||
@select="handleSelect"
|
||||
@clear="handleSelect"
|
||||
>
|
||||
<i
|
||||
slot="suffix"
|
||||
class="el-icon-edit el-input__icon"
|
||||
/>
|
||||
<i slot="suffix" class="el-icon-edit el-input__icon" />
|
||||
<template slot-scope="{ item }">
|
||||
<span class="name">{{ item.name }}</span>
|
||||
<div class="value font-info" style="font-size:12px;line-height: 12px; padding-bottom: 10px;">{{ item.value }}</div>
|
||||
@ -26,12 +23,20 @@
|
||||
<div v-for="(item, index) in list" :key="index">
|
||||
<el-card v-if="sysOriginPlatforms.includes(item.sysOrigin)" class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>近30金币来源明细({{ item.sysOriginName }}) <a class="font-blue" @click="clickAnalyze">实时分析</a></span>
|
||||
<span>
|
||||
{{ $t('pages.dashboard.dailyCurrencyGold.title', { sysOriginName: item.sysOriginName }) }}
|
||||
<a class="font-blue" @click="clickAnalyze">{{ $t('pages.dashboard.dailyCurrencyGold.realTimeAnalysis') }}</a>
|
||||
</span>
|
||||
</div>
|
||||
<div style="padding: 10px 0px">
|
||||
<div style="padding: 10px 0">
|
||||
<el-row>
|
||||
<el-col class="card-col" :md="24" :xs="24">
|
||||
<line-graph-charts ref="lineGraphCharts" :key="item.sysOrigin" :charts-data="item.list" height="300px" />
|
||||
<line-graph-charts
|
||||
ref="lineGraphCharts"
|
||||
:key="item.sysOrigin + '-' + language"
|
||||
:charts-data="item.list"
|
||||
height="300px"
|
||||
/>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -60,7 +65,7 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls']),
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls', 'language']),
|
||||
sysOriginPlatforms() {
|
||||
if (!this.permissionsSysOriginPlatformAlls || this.permissionsSysOriginPlatformAlls.length <= 0) {
|
||||
return []
|
||||
@ -73,30 +78,31 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
loadOrigin() {
|
||||
const that = this
|
||||
that.loading = true
|
||||
latestStatisticsGoldOriginDetails(that.selectOrigin).then(res => {
|
||||
that.loading = false
|
||||
this.loading = true
|
||||
latestStatisticsGoldOriginDetails(this.selectOrigin).then(res => {
|
||||
this.loading = false
|
||||
const { body } = res
|
||||
const list = body || []
|
||||
that.list = list.filter(item => !item.sysOrigin || that.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
this.list = list.filter(item => !item.sysOrigin || this.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
}).catch(() => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
querySearch(queryString, cb) {
|
||||
var restaurants = currencyOrigins
|
||||
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
|
||||
const restaurants = currencyOrigins
|
||||
const results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
|
||||
cb(results)
|
||||
},
|
||||
createFilter(queryString) {
|
||||
return (restaurant) => {
|
||||
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) >= 0) || (restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) >= 0)
|
||||
return restaurant => {
|
||||
return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) >= 0 ||
|
||||
restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) >= 0
|
||||
}
|
||||
},
|
||||
handleSelect(item) {
|
||||
this.selectOrigin = item.value
|
||||
this.selectOriginName = item.name
|
||||
const selectedItem = item || currencyOrigins[0]
|
||||
this.selectOrigin = selectedItem.value
|
||||
this.selectOriginName = selectedItem.name
|
||||
this.loadOrigin()
|
||||
},
|
||||
clickAnalyze() {
|
||||
@ -110,15 +116,16 @@ export default {
|
||||
.box-card {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
|
||||
.card-col {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.register-logout-count {
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="daily-currency-charts">
|
||||
<el-select v-model="typeValue" placeholder="请选择" size="mini" @change="typeValueChange">
|
||||
<div class="daily-currency-charts" :data-language="language">
|
||||
<el-select v-model="typeValue" :placeholder="$t('pages.dashboard.shared.select')" size="mini" @change="typeValueChange">
|
||||
<el-option
|
||||
v-for="item in types"
|
||||
:key="item.value"
|
||||
@ -8,14 +8,12 @@
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<div id="videoCharts" ref="videoCharts" :style="'width: 100%;height:'+ height +';'" />
|
||||
<div id="videoCharts" ref="videoCharts" :style="'width: 100%;height:' + height + ';'" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
// import { currencyOrigins } from '@/constant/type'
|
||||
// import { toMap } from '@/utils'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'DailyCurrencyCharts',
|
||||
@ -31,11 +29,6 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// currencyOriginMap: toMap(currencyOrigins, 'value'),
|
||||
types: [
|
||||
{ value: 0, name: '收入' },
|
||||
{ value: 1, name: '支出' }
|
||||
],
|
||||
typeValue: 0,
|
||||
videoRealTimeCharts: null,
|
||||
groupChartsData: {
|
||||
@ -44,37 +37,47 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['language']),
|
||||
types() {
|
||||
const language = this.language
|
||||
return [
|
||||
{ value: 0, name: this.$t('pages.dashboard.shared.income') },
|
||||
{ value: 1, name: this.$t('pages.dashboard.shared.expenditure') }
|
||||
]
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
chartsData: {
|
||||
handler(newVal) {
|
||||
const that = this
|
||||
that.groupChartsData = that.groupChartsDataByType()
|
||||
that.$nextTick(() => {
|
||||
that.renderCharts()
|
||||
handler() {
|
||||
this.groupChartsData = this.groupChartsDataByType()
|
||||
this.$nextTick(() => {
|
||||
this.renderCharts()
|
||||
})
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
language() {
|
||||
this.$nextTick(() => {
|
||||
this.renderCharts()
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
mounted() {
|
||||
const that = this
|
||||
that.videoRealTimeCharts = that.$echarts.init(that.$refs.videoCharts)
|
||||
that.renderCharts()
|
||||
this.videoRealTimeCharts = this.$echarts.init(this.$refs.videoCharts)
|
||||
this.renderCharts()
|
||||
window.addEventListener('resize', () => {
|
||||
that.videoRealTimeCharts.resize()
|
||||
this.videoRealTimeCharts.resize()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
groupChartsDataByType() {
|
||||
const that = this
|
||||
const obj = {
|
||||
income: [],
|
||||
expenditure: []
|
||||
}
|
||||
if (that.chartsData.length > 0) {
|
||||
that.chartsData.forEach(item => {
|
||||
if (this.chartsData.length > 0) {
|
||||
this.chartsData.forEach(item => {
|
||||
if (item.type === 0) {
|
||||
obj.income.push(item)
|
||||
}
|
||||
@ -89,7 +92,6 @@ export default {
|
||||
if (!list || list.length === 0) {
|
||||
return []
|
||||
}
|
||||
// const that = this
|
||||
const groupOrigin = {}
|
||||
const size = list.length - 1
|
||||
for (let index = size; index >= 0; index--) {
|
||||
@ -124,8 +126,10 @@ export default {
|
||||
return resultSeries
|
||||
},
|
||||
renderCharts() {
|
||||
const that = this
|
||||
that.videoRealTimeCharts.setOption({
|
||||
if (!this.videoRealTimeCharts) {
|
||||
return
|
||||
}
|
||||
this.videoRealTimeCharts.setOption({
|
||||
color: ['#66b3ff', '#ce90e8', '#ff9c6e', '#5cdbd3'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
@ -148,23 +152,21 @@ export default {
|
||||
borderColor: '#eee'
|
||||
},
|
||||
toolbox: { color: ['#1e90ff', '#1e90ff', '#1e90ff', '#1e90ff'], effectiveColor: '#ff4500' },
|
||||
xAxis: [
|
||||
{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 38
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
splitNumber: 24
|
||||
}
|
||||
],
|
||||
xAxis: [{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 38
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
splitNumber: 24
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
axisTick: { show: true, length: 0 },
|
||||
@ -176,13 +178,12 @@ export default {
|
||||
y: 10,
|
||||
textStyle: { color: '#8e929b' }
|
||||
},
|
||||
series: that.createSeries(that.typeValue === 0 ? that.groupChartsData.income : that.groupChartsData.expenditure)
|
||||
series: this.createSeries(this.typeValue === 0 ? this.groupChartsData.income : this.groupChartsData.expenditure)
|
||||
}, true)
|
||||
},
|
||||
typeValueChange() {
|
||||
const that = this
|
||||
that.$nextTick(() => {
|
||||
that.renderCharts()
|
||||
this.$nextTick(() => {
|
||||
this.renderCharts()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,46 +1,16 @@
|
||||
<template>
|
||||
<div class="dily-register-user">
|
||||
<div class="dily-register-user" :data-language="language">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="24">
|
||||
<div v-for="(item, index) in list" :key="index">
|
||||
<el-card v-if="sysOriginPlatforms.includes(item.sysOrigin)" class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>近30天货币收支({{ item.sysOriginName }})</span>
|
||||
<span>{{ $t('pages.dashboard.dailyCurrency.title', { sysOriginName: item.sysOriginName }) }}</span>
|
||||
</div>
|
||||
<div v-loading="loading" style="padding: 10px 0px">
|
||||
<!-- <el-row :gutter="20" class="register-logout-count">
|
||||
<el-col v-for="(nItem, nIndex) in item.lastMonths" :key="nIndex" :span="24" >
|
||||
<div class="date">{{ nItem.statisticsTime | dateFormat('yyyy-MM-dd') }}</div>
|
||||
</el-col>
|
||||
<el-col :md="6" :xs="24">
|
||||
<div class="block-card">
|
||||
<div class="block-card-title">男</div>
|
||||
<div class="block-card-content cite">{{ nItem.quantity || 0 }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :md="6" :xs="24">
|
||||
<div class="block-card">
|
||||
<div class="block-card-title">注销男</div>
|
||||
<div class="block-card-content cite">{{ item.latest ? item.latest.maleLogout || 0 : 0 }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :md="6" :xs="24">
|
||||
<div class="block-card">
|
||||
<div class="block-card-title">女</div>
|
||||
<div class="block-card-content cite">{{ item.latest ? item.latest.femaleCount || 0 :0 }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :md="6" :xs="24">
|
||||
<div class="block-card">
|
||||
<div class="block-card-title">注销女</div>
|
||||
<div class="block-card-content cite">{{ item.latest ?item.latest.femaleLogout || 0 :0 }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row> -->
|
||||
|
||||
<div v-loading="loading" style="padding: 10px 0">
|
||||
<el-row>
|
||||
<el-col class="card-col" :md="24" :xs="24">
|
||||
<line-graph-charts :key="item.sysOrigin" :charts-data="item.lastMonths" height="300px" />
|
||||
<line-graph-charts :key="item.sysOrigin + '-' + language" :charts-data="item.lastMonths" height="300px" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -66,7 +36,7 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls']),
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls', 'language']),
|
||||
sysOriginPlatforms() {
|
||||
if (!this.permissionsSysOriginPlatformAlls || this.permissionsSysOriginPlatformAlls.length <= 0) {
|
||||
return []
|
||||
@ -79,15 +49,14 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
renderData() {
|
||||
const that = this
|
||||
that.loading = true
|
||||
this.loading = true
|
||||
latestStatisticsCurrency().then(res => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
const { body } = res
|
||||
const list = body || []
|
||||
that.list = list.filter(item => !item.sysOrigin || that.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
this.list = list.filter(item => !item.sysOrigin || this.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
}).catch(() => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -98,15 +67,16 @@ export default {
|
||||
.box-card {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
|
||||
.card-col {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.register-logout-count {
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
<template>
|
||||
<div class="daily-currency-charts">
|
||||
<div id="videoCharts" ref="videoCharts" :style="'width: 100%;height:'+ height +';'" />
|
||||
<div id="videoCharts" ref="videoCharts" :style="'width: 100%;height:' + height + ';'" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { mapGetters } from 'vuex'
|
||||
import { formatDate } from '@/utils'
|
||||
|
||||
export default {
|
||||
name: 'DailyCurrencyCharts',
|
||||
props: {
|
||||
@ -24,27 +25,37 @@ export default {
|
||||
videoRealTimeCharts: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
computed: {
|
||||
...mapGetters(['language'])
|
||||
},
|
||||
watch: {
|
||||
chartsData: {
|
||||
handler() {
|
||||
this.renderCharts()
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
language() {
|
||||
this.renderCharts()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const that = this
|
||||
that.videoRealTimeCharts = that.$echarts.init(that.$refs.videoCharts)
|
||||
that.renderCharts()
|
||||
this.videoRealTimeCharts = this.$echarts.init(this.$refs.videoCharts)
|
||||
this.renderCharts()
|
||||
window.addEventListener('resize', () => {
|
||||
that.videoRealTimeCharts.resize()
|
||||
this.videoRealTimeCharts.resize()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleListToChartsData() {
|
||||
const that = this
|
||||
const charts = {
|
||||
integralIncome: [],
|
||||
integralExpenditure: [],
|
||||
goldIncome: [],
|
||||
goldExpenditure: []
|
||||
}
|
||||
if (that.chartsData.length > 0) {
|
||||
that.chartsData.forEach(item => {
|
||||
if (this.chartsData.length > 0) {
|
||||
this.chartsData.forEach(item => {
|
||||
const date = formatDate(item.statisticsTime, 'yyyy-MM-dd')
|
||||
if (item.currencyType === 'GOLD' && item.type === 0) {
|
||||
charts.goldIncome.push([date, (item.quantity || 0)])
|
||||
@ -60,9 +71,11 @@ export default {
|
||||
return charts
|
||||
},
|
||||
renderCharts() {
|
||||
const that = this
|
||||
const thatDayData = that.handleListToChartsData()
|
||||
that.videoRealTimeCharts.setOption({
|
||||
if (!this.videoRealTimeCharts) {
|
||||
return
|
||||
}
|
||||
const thatDayData = this.handleListToChartsData()
|
||||
this.videoRealTimeCharts.setOption({
|
||||
color: ['#66b3ff', '#ce90e8', '#ff9c6e', '#5cdbd3'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
@ -85,23 +98,21 @@ export default {
|
||||
borderColor: '#eee'
|
||||
},
|
||||
toolbox: { color: ['#1e90ff', '#1e90ff', '#1e90ff', '#1e90ff'], effectiveColor: '#ff4500' },
|
||||
xAxis: [
|
||||
{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 38
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
splitNumber: 24
|
||||
}
|
||||
],
|
||||
xAxis: [{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 38
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
splitNumber: 24
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
axisTick: { show: true, length: 0 },
|
||||
@ -115,9 +126,9 @@ export default {
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '金币收入',
|
||||
name: this.$t('pages.dashboard.dailyCurrency.goldIncome'),
|
||||
type: 'line',
|
||||
stack: '金币收入',
|
||||
stack: this.$t('pages.dashboard.dailyCurrency.goldIncome'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
@ -125,18 +136,19 @@ export default {
|
||||
areaStyle: {}
|
||||
},
|
||||
{
|
||||
name: '金币支出',
|
||||
name: this.$t('pages.dashboard.dailyCurrency.goldExpenditure'),
|
||||
type: 'line',
|
||||
stack: '金币支出',
|
||||
stack: this.$t('pages.dashboard.dailyCurrency.goldExpenditure'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.goldExpenditure,
|
||||
areaStyle: {}
|
||||
}, {
|
||||
name: '积分收入',
|
||||
},
|
||||
{
|
||||
name: this.$t('pages.dashboard.dailyCurrency.integralIncome'),
|
||||
type: 'line',
|
||||
stack: '金币收入',
|
||||
stack: this.$t('pages.dashboard.dailyCurrency.goldIncome'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
@ -144,15 +156,16 @@ export default {
|
||||
areaStyle: {}
|
||||
},
|
||||
{
|
||||
name: '积分支出',
|
||||
name: this.$t('pages.dashboard.dailyCurrency.integralExpenditure'),
|
||||
type: 'line',
|
||||
stack: '金币支出',
|
||||
stack: this.$t('pages.dashboard.dailyCurrency.goldExpenditure'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.integralExpenditure,
|
||||
areaStyle: {}
|
||||
}]
|
||||
}
|
||||
]
|
||||
}, true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,14 @@
|
||||
<template>
|
||||
<div class="dily-register-user">
|
||||
<div class="dily-register-user" :data-language="language">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="24">
|
||||
<el-select v-model="selectAreaCode" placeholder="请选择" style="margin-bottom: 10px;" size="mini" @change="changeAreaCode">
|
||||
<el-select
|
||||
v-model="selectAreaCode"
|
||||
:placeholder="$t('pages.dashboard.shared.select')"
|
||||
style="margin-bottom: 10px;"
|
||||
size="mini"
|
||||
@change="changeAreaCode"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in selecteOptions"
|
||||
:key="item.value"
|
||||
@ -12,15 +18,15 @@
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col v-if="isAllowLatestTotal" :span="24" style="margin-bottom: 10px;">
|
||||
<line-graph-charts-general height="300px" :area-code="selectAreaCode" />
|
||||
<line-graph-charts-general :key="'general-' + language" height="300px" :area-code="selectAreaCode" />
|
||||
</el-col>
|
||||
<el-col v-if="list && list.length > 0" :span="24">
|
||||
<div v-for="(item, index) in list" :key="index">
|
||||
<el-card v-if="sysOriginPlatforms.includes(item.sysOrigin)" class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>近30天内购({{ item.sysOriginName }})</span>
|
||||
<span>{{ $t('pages.dashboard.dailyPurchase.title', { sysOriginName: item.sysOriginName }) }}</span>
|
||||
</div>
|
||||
<div v-loading="loading" style="padding: 10px 0px">
|
||||
<div v-loading="loading" style="padding: 10px 0">
|
||||
<el-row :gutter="10" class="daily-purchase">
|
||||
<el-col :span="24">
|
||||
<div class="date">{{ (item.last ? item.last.statisticsTime : '') | dateFormat('yyyy-MM-dd') }}</div>
|
||||
@ -40,23 +46,22 @@
|
||||
<el-col :md="6" :xs="24">
|
||||
<div class="block-card">
|
||||
<div class="block-card-title">H5</div>
|
||||
<div class="block-card-content cite">{{ item.last ? item.last.h5Quantity || 0 :0 }}</div>
|
||||
<div class="block-card-content cite">{{ item.last ? item.last.h5Quantity || 0 : 0 }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :md="6" :xs="24">
|
||||
<div class="block-card">
|
||||
<div class="block-card-title">有效/退款</div>
|
||||
<div class="block-card-content cite">{{ item.last ?item.last.completeQuantity || 0 :0 }} / {{ item.last ?item.last.reimburseQuantity || 0 :0 }}</div>
|
||||
<div class="block-card-title">{{ $t('pages.dashboard.dailyPurchase.validRefund') }}</div>
|
||||
<div class="block-card-content cite">{{ item.last ? item.last.completeQuantity || 0 : 0 }} / {{ item.last ? item.last.reimburseQuantity || 0 : 0 }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col class="card-col" :md="24" :xs="24">
|
||||
<line-graph-charts ref="sysOriginCharts" :key="item.sysOrigin" :charts-data="item.lastMonths" height="300px" />
|
||||
<line-graph-charts :key="item.sysOrigin + '-' + language" ref="sysOriginCharts" :charts-data="item.lastMonths" height="300px" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -74,18 +79,21 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
selectAreaCode: 'DAILY',
|
||||
selecteOptions: [
|
||||
{ label: '每日', value: 'DAILY' },
|
||||
{ label: '沙特', value: 'ar' },
|
||||
{ label: '土耳其', value: 'tr' },
|
||||
{ label: '其他', value: 'OTHER' }
|
||||
],
|
||||
loading: false,
|
||||
list: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls']),
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls', 'language']),
|
||||
selecteOptions() {
|
||||
const language = this.language
|
||||
return [
|
||||
{ label: this.$t('pages.dashboard.dailyPurchase.regionDaily'), value: 'DAILY' },
|
||||
{ label: this.$t('pages.dashboard.dailyPurchase.regionSaudi'), value: 'ar' },
|
||||
{ label: this.$t('pages.dashboard.dailyPurchase.regionTurkey'), value: 'tr' },
|
||||
{ label: this.$t('pages.dashboard.dailyPurchase.regionOther'), value: 'OTHER' }
|
||||
]
|
||||
},
|
||||
isAllowLatestTotal() {
|
||||
return this.permissionsSysOriginPlatformAlls && this.permissionsSysOriginPlatformAlls.length > 1
|
||||
},
|
||||
@ -104,18 +112,17 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
renderData() {
|
||||
const that = this
|
||||
that.loading = true
|
||||
latestPurchaseAmountPlatform(that.selectAreaCode).then(res => {
|
||||
that.loading = false
|
||||
this.loading = true
|
||||
latestPurchaseAmountPlatform(this.selectAreaCode).then(res => {
|
||||
this.loading = false
|
||||
const { body } = res
|
||||
const list = body || []
|
||||
that.list = []
|
||||
that.$nextTick(() => {
|
||||
that.list = list.filter(item => !item.sysOrigin || that.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
this.list = []
|
||||
this.$nextTick(() => {
|
||||
this.list = list.filter(item => !item.sysOrigin || this.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
})
|
||||
}).catch(() => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
changeAreaCode() {
|
||||
@ -129,15 +136,16 @@ export default {
|
||||
.box-card {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
|
||||
.card-col {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.daily-purchase {
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -2,16 +2,16 @@
|
||||
<div class="subsidy-integral-charts">
|
||||
<el-card v-loading="listLoading">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>近30天内购(总揽)</span>
|
||||
<span>{{ $t('pages.dashboard.dailyPurchase.overviewTitle') }}</span>
|
||||
</div>
|
||||
<el-tag v-for="(item ,index) in platformCounts" :key="index" style="margin-right: 10px;">{{ item.label }}({{ item.type }}): {{ item.val }}</el-tag>
|
||||
<div id="subsidyIntegralCharts" ref="subsidyIntegralCharts" :style="'width: 100%;height:'+ height +';'" />
|
||||
<el-tag v-for="(item, index) in platformCounts" :key="index" style="margin-right: 10px;">{{ item.label }}({{ item.type }}): {{ item.val }}</el-tag>
|
||||
<div id="subsidyIntegralCharts" ref="subsidyIntegralCharts" :style="'width: 100%;height:' + height + ';'" />
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { mapGetters } from 'vuex'
|
||||
import { formatDate } from '@/utils'
|
||||
import { getDailyPurchaseAmountThirtyDays } from '@/api/statistics'
|
||||
|
||||
@ -35,6 +35,9 @@ export default {
|
||||
platformCounts: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['language'])
|
||||
},
|
||||
watch: {
|
||||
areaCode: {
|
||||
handler(newVal) {
|
||||
@ -43,81 +46,30 @@ export default {
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
language() {
|
||||
this.$nextTick(() => {
|
||||
this.renderCharts()
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const that = this
|
||||
that.subsidyIntegralCharts = that.$echarts.init(that.$refs.subsidyIntegralCharts)
|
||||
this.subsidyIntegralCharts = this.$echarts.init(this.$refs.subsidyIntegralCharts)
|
||||
window.addEventListener('resize', () => {
|
||||
that.subsidyIntegralCharts.resize()
|
||||
this.subsidyIntegralCharts.resize()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
renderData() {
|
||||
const that = this
|
||||
that.listLoading = true
|
||||
getDailyPurchaseAmountThirtyDays(that.areaCode).then(res => {
|
||||
this.listLoading = true
|
||||
getDailyPurchaseAmountThirtyDays(this.areaCode).then(res => {
|
||||
const { body } = res
|
||||
that.list = body || []
|
||||
that.renderCharts()
|
||||
that.listLoading = false
|
||||
// that.platformCounts = that.count(that.list)
|
||||
this.list = body || []
|
||||
this.renderCharts()
|
||||
this.listLoading = false
|
||||
})
|
||||
},
|
||||
count(list) {
|
||||
if (!list || list.length <= 0) {
|
||||
return []
|
||||
}
|
||||
|
||||
let androidPurchaseCount = 0
|
||||
let androidPurchaseIndex = 0
|
||||
let iosPurchaseCount = 0
|
||||
let iosPurchaseIndex = 0
|
||||
let h5PurchaseCount = 0
|
||||
let h5PurchaseCountIndex = 0
|
||||
let totalCount = 0
|
||||
let totalIndex = 0
|
||||
let refundCount = 0
|
||||
const size = list.length
|
||||
for (let index = 0; index < size; index++) {
|
||||
const item = list[index]
|
||||
totalCount += item.purchase
|
||||
refundCount += item.refund
|
||||
if (item && item.platform === 'Android') {
|
||||
androidPurchaseIndex += 1
|
||||
totalIndex += 1
|
||||
androidPurchaseCount += item.purchase
|
||||
}
|
||||
if (item && item.platform === 'iOS') {
|
||||
iosPurchaseIndex += 1
|
||||
totalIndex += 1
|
||||
iosPurchaseCount += item.purchase
|
||||
}
|
||||
if (item && item.platform === 'H5') {
|
||||
h5PurchaseCountIndex += 1
|
||||
totalIndex += 1
|
||||
h5PurchaseCount += item.purchase
|
||||
}
|
||||
}
|
||||
return [
|
||||
{ type: 'avg', label: 'Android', val: this.calAvg(androidPurchaseCount, androidPurchaseIndex) },
|
||||
{ type: 'avg', label: 'iOS', val: this.calAvg(iosPurchaseCount, iosPurchaseIndex) },
|
||||
{ type: 'avg', label: 'H5', val: this.calAvg(h5PurchaseCount, h5PurchaseCountIndex) },
|
||||
{ type: 'avg', label: 'Total2', val: this.calAvg(totalCount, totalIndex) },
|
||||
{ type: 'count', label: 'Refund', val: refundCount }
|
||||
]
|
||||
},
|
||||
calAvg(num, size) {
|
||||
if (!size || size <= 0) {
|
||||
return 0
|
||||
}
|
||||
return (num / size).toFixed(2) * 100 / 100
|
||||
},
|
||||
handleSearch() {
|
||||
this.renderData()
|
||||
},
|
||||
handleChartsData() {
|
||||
const that = this
|
||||
const iosPurchase = []
|
||||
const iosRefund = []
|
||||
const googlePurchase = []
|
||||
@ -125,8 +77,8 @@ export default {
|
||||
const h5Purchase = []
|
||||
const h5Refund = []
|
||||
const offline = []
|
||||
if (that.list.length > 0) {
|
||||
that.list.forEach(item => {
|
||||
if (this.list.length > 0) {
|
||||
this.list.forEach(item => {
|
||||
const date = formatDate(item.statisticsTime, 'yyyyMMdd')
|
||||
if (item.platform === 'iOS') {
|
||||
iosPurchase.push([date, (item.purchase || 0)])
|
||||
@ -141,106 +93,112 @@ export default {
|
||||
h5Purchase.push([date, (item.purchase || 0)])
|
||||
h5Refund.push([date, (item.refund || 0)])
|
||||
}
|
||||
if (item.platform === 'Offline' && that.areaCode === 'DAILY') {
|
||||
if (item.platform === 'Offline' && this.areaCode === 'DAILY') {
|
||||
offline.push([date, (item.purchase || 0)])
|
||||
}
|
||||
})
|
||||
}
|
||||
return { iosPurchase, iosRefund, googlePurchase, googleRefund, h5Purchase, h5Refund }
|
||||
return { iosPurchase, iosRefund, googlePurchase, googleRefund, h5Purchase, h5Refund, offline }
|
||||
},
|
||||
renderCharts() {
|
||||
const that = this
|
||||
const thatDayData = that.handleChartsData()
|
||||
|
||||
const series = [{
|
||||
name: 'Adnroid内购',
|
||||
type: 'line',
|
||||
stack: 'Adnroid内购',
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.googlePurchase,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#3eda86'
|
||||
if (!this.subsidyIntegralCharts) {
|
||||
return
|
||||
}
|
||||
const thatDayData = this.handleChartsData()
|
||||
const series = [
|
||||
{
|
||||
name: this.$t('pages.dashboard.dailyPurchase.androidPurchase'),
|
||||
type: 'line',
|
||||
stack: this.$t('pages.dashboard.dailyPurchase.androidPurchase'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.googlePurchase,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#3eda86'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: this.$t('pages.dashboard.dailyPurchase.androidRefund'),
|
||||
type: 'line',
|
||||
stack: this.$t('pages.dashboard.dailyPurchase.androidRefund'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.googleRefund,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#55886d'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: this.$t('pages.dashboard.dailyPurchase.iosPurchase'),
|
||||
type: 'line',
|
||||
stack: this.$t('pages.dashboard.dailyPurchase.iosPurchase'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.iosPurchase,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#303133'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: this.$t('pages.dashboard.dailyPurchase.iosRefund'),
|
||||
type: 'line',
|
||||
stack: this.$t('pages.dashboard.dailyPurchase.iosRefund'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.iosRefund,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#828486'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Offline',
|
||||
type: 'line',
|
||||
stack: 'Offline',
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.offline,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#6c4c49'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: this.$t('pages.dashboard.dailyPurchase.h5Purchase'),
|
||||
type: 'line',
|
||||
stack: this.$t('pages.dashboard.dailyPurchase.h5Purchase'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.h5Purchase,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#e9640e'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: this.$t('pages.dashboard.dailyPurchase.h5Refund'),
|
||||
type: 'line',
|
||||
stack: this.$t('pages.dashboard.dailyPurchase.h5Refund'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.h5Refund,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#ff9c6e'
|
||||
}
|
||||
}
|
||||
}, {
|
||||
name: 'Adnroid退款',
|
||||
type: 'line',
|
||||
stack: 'Adnroid退款',
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.googleRefund,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#55886d'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'iOS内购',
|
||||
type: 'line',
|
||||
stack: 'iOS内购',
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.iosPurchase,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#303133'
|
||||
}
|
||||
}, {
|
||||
name: 'iOS退款',
|
||||
type: 'line',
|
||||
stack: 'iOS退款',
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.iosRefund,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#828486'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Offline',
|
||||
type: 'line',
|
||||
stack: 'Offline',
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.offline,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#6c4c49'
|
||||
}
|
||||
}, {
|
||||
name: 'H5内购',
|
||||
type: 'line',
|
||||
stack: 'H5内购',
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.h5Purchase,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#e9640e'
|
||||
}
|
||||
}, {
|
||||
name: 'H5退款',
|
||||
type: 'line',
|
||||
stack: 'H5退款',
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.h5Refund,
|
||||
areaStyle: {},
|
||||
itemStyle: {
|
||||
color: '#ff9c6e'
|
||||
}
|
||||
}]
|
||||
that.subsidyIntegralCharts.setOption({
|
||||
// color: ['#3eda86', '#55886d', '#303133', '#828486', '#6c4c49', '#e9640e', '#ff9c6e', '#66b3ff', '#E6A23C', '#ce90e8', '#5cdbd3'],
|
||||
]
|
||||
this.subsidyIntegralCharts.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(50,50,50,0.5)',
|
||||
@ -262,23 +220,21 @@ export default {
|
||||
borderColor: '#eee'
|
||||
},
|
||||
toolbox: { color: ['#1e90ff', '#1e90ff', '#1e90ff', '#1e90ff'], effectiveColor: '#ff4500' },
|
||||
xAxis: [
|
||||
{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 38
|
||||
},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
splitNumber: 24,
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }}
|
||||
}
|
||||
],
|
||||
xAxis: [{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 38
|
||||
},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
splitNumber: 24,
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }}
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
axisTick: { show: true, length: 0 },
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
<template>
|
||||
<div class="daily-currency-charts">
|
||||
<el-tag v-for="(item ,index) in platformCounts" :key="index" style="margin-right: 10px;">{{ item.label }}({{ item.type }}): {{ item.val }}</el-tag>
|
||||
<div id="videoCharts" ref="videoCharts" :style="'width: 100%;height:'+ height +';'" />
|
||||
<el-tag v-for="(item, index) in platformCounts" :key="index" style="margin-right: 10px;">{{ item.label }}({{ item.type }}): {{ item.val }}</el-tag>
|
||||
<div id="videoCharts" ref="videoCharts" :style="'width: 100%;height:' + height + ';'" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'DailyCurrencyCharts',
|
||||
props: {
|
||||
@ -24,14 +26,25 @@ export default {
|
||||
platformCounts: []
|
||||
}
|
||||
},
|
||||
created() {
|
||||
computed: {
|
||||
...mapGetters(['language'])
|
||||
},
|
||||
watch: {
|
||||
chartsData: {
|
||||
handler() {
|
||||
this.renderCharts()
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
language() {
|
||||
this.renderCharts()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const that = this
|
||||
that.videoRealTimeCharts = that.$echarts.init(that.$refs.videoCharts)
|
||||
that.renderCharts()
|
||||
this.videoRealTimeCharts = this.$echarts.init(this.$refs.videoCharts)
|
||||
this.renderCharts()
|
||||
window.addEventListener('resize', () => {
|
||||
that.videoRealTimeCharts.resize()
|
||||
this.videoRealTimeCharts.resize()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
@ -66,7 +79,6 @@ export default {
|
||||
return (num / size).toFixed(2) * 100 / 100
|
||||
},
|
||||
handleListToChartsData() {
|
||||
const that = this
|
||||
const dataCharts = {
|
||||
androidQuantity: [],
|
||||
iosQuantity: [],
|
||||
@ -75,26 +87,27 @@ export default {
|
||||
reimburseQuantity: [],
|
||||
offlineQuantity: []
|
||||
}
|
||||
if (that.chartsData.length > 0) {
|
||||
that.chartsData.forEach(item => {
|
||||
if (this.chartsData.length > 0) {
|
||||
this.chartsData.forEach(item => {
|
||||
const date = item.dateNumber
|
||||
dataCharts.androidQuantity.push([date, (item.androidQuantity || 0)])
|
||||
dataCharts.iosQuantity.push([date, (item.iosQuantity || 0)])
|
||||
dataCharts.h5Quantity.push([date, (item.h5Quantity || 0)])
|
||||
dataCharts.completeQuantity.push([date, (item.completeQuantity || 0)])
|
||||
dataCharts.reimburseQuantity.push([date, (item.reimburseQuantity || 0)])
|
||||
if (that.areaCode === 'DAILY') {
|
||||
if (this.areaCode === 'DAILY') {
|
||||
dataCharts.offlineQuantity.push([date, (item.offlineQuantity || 0)])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// that.platformCounts = that.count(that.chartsData)
|
||||
return dataCharts
|
||||
},
|
||||
renderCharts() {
|
||||
const that = this
|
||||
const thatDayData = that.handleListToChartsData()
|
||||
if (!this.videoRealTimeCharts) {
|
||||
return
|
||||
}
|
||||
const thatDayData = this.handleListToChartsData()
|
||||
const series = [
|
||||
{
|
||||
name: 'Android',
|
||||
@ -149,9 +162,9 @@ export default {
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '有效',
|
||||
name: this.$t('pages.dashboard.dailyPurchase.valid'),
|
||||
type: 'line',
|
||||
stack: '有效',
|
||||
stack: this.$t('pages.dashboard.dailyPurchase.valid'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
@ -162,9 +175,9 @@ export default {
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '退款',
|
||||
name: this.$t('pages.dashboard.dailyPurchase.refund'),
|
||||
type: 'line',
|
||||
stack: '退款',
|
||||
stack: this.$t('pages.dashboard.dailyPurchase.refund'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
@ -173,9 +186,9 @@ export default {
|
||||
itemStyle: {
|
||||
color: '#F56C6C'
|
||||
}
|
||||
}]
|
||||
that.videoRealTimeCharts.setOption({
|
||||
// color: ['#3eda86', '#303133', '#e9640e', '#6c4c49', '#66b3ff', '#ce90e8', '#ff9c6e', '#5cdbd3', '#E6A23C'],
|
||||
}
|
||||
]
|
||||
this.videoRealTimeCharts.setOption({
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(50,50,50,0.5)',
|
||||
@ -197,23 +210,21 @@ export default {
|
||||
borderColor: '#eee'
|
||||
},
|
||||
toolbox: { color: ['#1e90ff', '#1e90ff', '#1e90ff', '#1e90ff'], effectiveColor: '#ff4500' },
|
||||
xAxis: [
|
||||
{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 38
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
splitNumber: 24
|
||||
}
|
||||
],
|
||||
xAxis: [{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 38
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
splitNumber: 24
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
axisTick: { show: true, length: 0 },
|
||||
|
||||
@ -1,43 +1,43 @@
|
||||
<template>
|
||||
<div class="dily-register-user">
|
||||
<div class="dily-register-user" :data-language="language">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="24">
|
||||
<div v-for="(item, index) in list" :key="index">
|
||||
<el-card v-if="sysOriginPlatforms.includes(item.sysOrigin)" class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>近30天新增({{ item.sysOriginName }})</span>
|
||||
<span>{{ $t('pages.dashboard.dailyRegisterUser.title', { sysOriginName: item.sysOriginName }) }}</span>
|
||||
</div>
|
||||
<div v-loading="loading" style="padding: 10px 0px">
|
||||
<div v-loading="loading" style="padding: 10px 0">
|
||||
<el-row :gutter="20" class="register-logout-count">
|
||||
<el-col :span="24">
|
||||
<div class="date">{{ item.registerLogout ? item.registerLogout.statisticsTime : '' | dateFormat('yyyy-MM-dd') }}</div>
|
||||
</el-col>
|
||||
<el-col :md="6" :xs="24">
|
||||
<div class="block-card">
|
||||
<div class="block-card-title">男</div>
|
||||
<div class="block-card-title">{{ $t('pages.dashboard.dailyRegisterUser.male') }}</div>
|
||||
<div class="block-card-content cite">{{ item.registerLogout ? item.registerLogout.maleCount || 0 : 0 }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :md="6" :xs="24">
|
||||
<div class="block-card">
|
||||
<div class="block-card-title">注销男</div>
|
||||
<div class="block-card-title">{{ $t('pages.dashboard.dailyRegisterUser.maleLogout') }}</div>
|
||||
<div class="block-card-content cite">{{ item.registerLogout ? item.registerLogout.maleLogout || 0 : 0 }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :md="6" :xs="24">
|
||||
<div class="block-card">
|
||||
<div class="block-card-title">女</div>
|
||||
<div class="block-card-content cite">{{ item.registerLogout ? item.registerLogout.femaleCount || 0 :0 }}</div>
|
||||
<div class="block-card-title">{{ $t('pages.dashboard.dailyRegisterUser.female') }}</div>
|
||||
<div class="block-card-content cite">{{ item.registerLogout ? item.registerLogout.femaleCount || 0 : 0 }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :md="6" :xs="24">
|
||||
<div class="block-card">
|
||||
<div class="block-card-title">注销女</div>
|
||||
<div class="block-card-content cite">{{ item.registerLogout ?item.registerLogout.femaleLogout || 0 :0 }}</div>
|
||||
<div class="block-card-title">{{ $t('pages.dashboard.dailyRegisterUser.femaleLogout') }}</div>
|
||||
<div class="block-card-content cite">{{ item.registerLogout ? item.registerLogout.femaleLogout || 0 : 0 }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col class="card-col" :md="24" :xs="24">
|
||||
<line-graph-charts :key="item.sysOrigin" :charts-data="item.lastMonths" height="300px" />
|
||||
<line-graph-charts :key="item.sysOrigin + '-' + language" :charts-data="item.lastMonths" height="300px" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -52,6 +52,7 @@
|
||||
import { latestRegisterLogout } from '@/api/statistics'
|
||||
import LineGraphCharts from './line-graph-charts'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'DilyRegisterUser',
|
||||
components: { LineGraphCharts },
|
||||
@ -62,7 +63,7 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls']),
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls', 'language']),
|
||||
sysOriginPlatforms() {
|
||||
if (!this.permissionsSysOriginPlatformAlls || this.permissionsSysOriginPlatformAlls.length <= 0) {
|
||||
return []
|
||||
@ -78,15 +79,14 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
renderData() {
|
||||
const that = this
|
||||
that.loading = true
|
||||
this.loading = true
|
||||
latestRegisterLogout().then(res => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
const { body } = res
|
||||
const list = body || []
|
||||
that.list = list.filter(item => !item.sysOrigin || that.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
this.list = list.filter(item => !item.sysOrigin || this.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
}).catch(() => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -97,15 +97,16 @@ export default {
|
||||
.box-card {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
|
||||
.card-col {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.register-logout-count {
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
<template>
|
||||
<div class="register-logout-count-charts">
|
||||
<div id="videoCharts" ref="videoCharts" :style="'width: 100%;height:'+ height +';'" />
|
||||
<div id="videoCharts" ref="videoCharts" :style="'width: 100%;height:' + height + ';'" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { mapGetters } from 'vuex'
|
||||
import { formatDate } from '@/utils'
|
||||
|
||||
export default {
|
||||
name: 'RegisterLogoutCountCharts',
|
||||
props: {
|
||||
@ -24,19 +25,29 @@ export default {
|
||||
videoRealTimeCharts: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
computed: {
|
||||
...mapGetters(['language'])
|
||||
},
|
||||
watch: {
|
||||
chartsData: {
|
||||
handler() {
|
||||
this.renderCharts()
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
language() {
|
||||
this.renderCharts()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const that = this
|
||||
that.videoRealTimeCharts = that.$echarts.init(that.$refs.videoCharts)
|
||||
that.renderCharts()
|
||||
this.videoRealTimeCharts = this.$echarts.init(this.$refs.videoCharts)
|
||||
this.renderCharts()
|
||||
window.addEventListener('resize', () => {
|
||||
that.videoRealTimeCharts.resize()
|
||||
this.videoRealTimeCharts.resize()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleListToChartsData() {
|
||||
const that = this
|
||||
const chartsData = {
|
||||
newMales: [],
|
||||
maleLogouts: [],
|
||||
@ -47,8 +58,8 @@ export default {
|
||||
const maleLogouts = chartsData.maleLogouts
|
||||
const newFamles = chartsData.newFamles
|
||||
const femaleLogouts = chartsData.femaleLogouts
|
||||
if (that.chartsData.length > 0) {
|
||||
that.chartsData.forEach(item => {
|
||||
if (this.chartsData.length > 0) {
|
||||
this.chartsData.forEach(item => {
|
||||
const date = formatDate(item.statisticsTime, 'yyyy-MM-dd')
|
||||
newMales.push([date, (item.maleCount || 0)])
|
||||
maleLogouts.push([date, (item.maleLogout || 0)])
|
||||
@ -59,9 +70,11 @@ export default {
|
||||
return chartsData
|
||||
},
|
||||
renderCharts() {
|
||||
const that = this
|
||||
const thatDayData = that.handleListToChartsData()
|
||||
that.videoRealTimeCharts.setOption({
|
||||
if (!this.videoRealTimeCharts) {
|
||||
return
|
||||
}
|
||||
const thatDayData = this.handleListToChartsData()
|
||||
this.videoRealTimeCharts.setOption({
|
||||
color: ['#66b3ff', '#ce90e8', '#ff9c6e', '#5cdbd3'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
@ -84,23 +97,21 @@ export default {
|
||||
borderColor: '#eee'
|
||||
},
|
||||
toolbox: { color: ['#1e90ff', '#1e90ff', '#1e90ff', '#1e90ff'], effectiveColor: '#ff4500' },
|
||||
xAxis: [
|
||||
{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 38
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
splitNumber: 24
|
||||
}
|
||||
],
|
||||
xAxis: [{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 38
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
splitNumber: 24
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
axisTick: { show: true, length: 0 },
|
||||
@ -111,9 +122,9 @@ export default {
|
||||
legend: { y: 10, textStyle: { color: '#8e929b' }},
|
||||
series: [
|
||||
{
|
||||
name: '新增男生',
|
||||
name: this.$t('pages.dashboard.dailyRegisterUser.newMale'),
|
||||
type: 'line',
|
||||
stack: '新增男生',
|
||||
stack: this.$t('pages.dashboard.dailyRegisterUser.newMale'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
@ -121,9 +132,9 @@ export default {
|
||||
areaStyle: {}
|
||||
},
|
||||
{
|
||||
name: '新增女生',
|
||||
name: this.$t('pages.dashboard.dailyRegisterUser.newFemale'),
|
||||
type: 'line',
|
||||
stack: '新增女生',
|
||||
stack: this.$t('pages.dashboard.dailyRegisterUser.newFemale'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
@ -131,9 +142,9 @@ export default {
|
||||
areaStyle: {}
|
||||
},
|
||||
{
|
||||
name: '注销男生',
|
||||
name: this.$t('pages.dashboard.dailyRegisterUser.logoutMale'),
|
||||
type: 'line',
|
||||
stack: '注销男生',
|
||||
stack: this.$t('pages.dashboard.dailyRegisterUser.logoutMale'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
@ -141,15 +152,16 @@ export default {
|
||||
areaStyle: {}
|
||||
},
|
||||
{
|
||||
name: '注销女生',
|
||||
name: this.$t('pages.dashboard.dailyRegisterUser.logoutFemale'),
|
||||
type: 'line',
|
||||
stack: '新增女生',
|
||||
stack: this.$t('pages.dashboard.dailyRegisterUser.newFemale'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.femaleLogouts,
|
||||
areaStyle: {}
|
||||
}]
|
||||
}
|
||||
]
|
||||
}, true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<div class="dily-register-user">
|
||||
<div class="dily-register-user" :data-language="language">
|
||||
<el-row :gutter="10">
|
||||
<el-col :span="24">
|
||||
<div v-for="(item, index) in list" :key="index">
|
||||
<el-card v-if="sysOriginPlatforms.includes(item.sysOrigin)" class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>近12月内购({{ item.sysOriginName }})</span>
|
||||
<span>{{ $t('pages.dashboard.monthlyPurchase.title', { sysOriginName: item.sysOriginName }) }}</span>
|
||||
</div>
|
||||
<div v-loading="loading" style="padding: 10px 0px">
|
||||
<div v-loading="loading" style="padding: 10px 0">
|
||||
<el-row :gutter="10" class="daily-purchase">
|
||||
<el-col :span="24">
|
||||
<div class="date">{{ item.last ? item.last.dateNumber : '' }}</div>
|
||||
@ -27,17 +27,17 @@
|
||||
<el-col :md="6" :xs="24">
|
||||
<div class="block-card">
|
||||
<div class="block-card-title">H5</div>
|
||||
<div class="block-card-content cite">{{ item.last ? item.last.h5Quantity || 0 :0 }}</div>
|
||||
<div class="block-card-content cite">{{ item.last ? item.last.h5Quantity || 0 : 0 }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :md="6" :xs="24">
|
||||
<div class="block-card">
|
||||
<div class="block-card-title">有效/退款</div>
|
||||
<div class="block-card-content cite">{{ item.last ?item.last.completeQuantity || 0 :0 }} / {{ item.last ?item.last.reimburseQuantity || 0 :0 }}</div>
|
||||
<div class="block-card-title">{{ $t('pages.dashboard.monthlyPurchase.validRefund') }}</div>
|
||||
<div class="block-card-content cite">{{ item.last ? item.last.completeQuantity || 0 : 0 }} / {{ item.last ? item.last.reimburseQuantity || 0 : 0 }}</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col class="card-col" :md="24" :xs="24">
|
||||
<line-graph-charts :key="item.sysOrigin" :charts-data="item.lastMonths" height="300px" />
|
||||
<line-graph-charts :key="item.sysOrigin + '-' + language" :charts-data="item.lastMonths" height="300px" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -63,7 +63,7 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls']),
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls', 'language']),
|
||||
sysOriginPlatforms() {
|
||||
if (!this.permissionsSysOriginPlatformAlls || this.permissionsSysOriginPlatformAlls.length <= 0) {
|
||||
return []
|
||||
@ -79,15 +79,14 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
renderData() {
|
||||
const that = this
|
||||
that.loading = true
|
||||
this.loading = true
|
||||
latestMonthlyPurchaseAmountPlatform().then(res => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
const { body } = res
|
||||
const list = body || []
|
||||
that.list = list.filter(item => !item.sysOrigin || that.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
this.list = list.filter(item => !item.sysOrigin || this.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
}).catch(() => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -98,15 +97,16 @@ export default {
|
||||
.box-card {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
|
||||
.card-col {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.daily-purchase {
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div class="daily-currency-charts">
|
||||
<div id="videoCharts" ref="videoCharts" :style="'width: 100%;height:'+ height +';'" />
|
||||
<div id="videoCharts" ref="videoCharts" :style="'width: 100%;height:' + height + ';'" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
import { formatDate } from '@/utils'
|
||||
export default {
|
||||
name: 'DailyCurrencyCharts',
|
||||
props: {
|
||||
@ -24,19 +24,29 @@ export default {
|
||||
videoRealTimeCharts: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
computed: {
|
||||
...mapGetters(['language'])
|
||||
},
|
||||
watch: {
|
||||
chartsData: {
|
||||
handler() {
|
||||
this.renderCharts()
|
||||
},
|
||||
deep: true
|
||||
},
|
||||
language() {
|
||||
this.renderCharts()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const that = this
|
||||
that.videoRealTimeCharts = that.$echarts.init(that.$refs.videoCharts)
|
||||
that.renderCharts()
|
||||
this.videoRealTimeCharts = this.$echarts.init(this.$refs.videoCharts)
|
||||
this.renderCharts()
|
||||
window.addEventListener('resize', () => {
|
||||
that.videoRealTimeCharts.resize()
|
||||
this.videoRealTimeCharts.resize()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
handleListToChartsData() {
|
||||
const that = this
|
||||
const dataCharts = {
|
||||
androidQuantity: [],
|
||||
iosQuantity: [],
|
||||
@ -45,8 +55,8 @@ export default {
|
||||
reimburseQuantity: [],
|
||||
offlineQuantity: []
|
||||
}
|
||||
if (that.chartsData.length > 0) {
|
||||
that.chartsData.forEach(item => {
|
||||
if (this.chartsData.length > 0) {
|
||||
this.chartsData.forEach(item => {
|
||||
const date = item.dateNumber
|
||||
dataCharts.androidQuantity.push([date, (item.androidQuantity || 0)])
|
||||
dataCharts.iosQuantity.push([date, (item.iosQuantity || 0)])
|
||||
@ -59,9 +69,11 @@ export default {
|
||||
return dataCharts
|
||||
},
|
||||
renderCharts() {
|
||||
const that = this
|
||||
const thatDayData = that.handleListToChartsData()
|
||||
that.videoRealTimeCharts.setOption({
|
||||
if (!this.videoRealTimeCharts) {
|
||||
return
|
||||
}
|
||||
const thatDayData = this.handleListToChartsData()
|
||||
this.videoRealTimeCharts.setOption({
|
||||
color: ['#3eda86', '#303133', '#e9640e', '#6c4c49', '#66b3ff', '#ce90e8', '#ff9c6e', '#5cdbd3', '#E6A23C'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
@ -84,23 +96,21 @@ export default {
|
||||
borderColor: '#eee'
|
||||
},
|
||||
toolbox: { color: ['#1e90ff', '#1e90ff', '#1e90ff', '#1e90ff'], effectiveColor: '#ff4500' },
|
||||
xAxis: [
|
||||
{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 38
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
splitNumber: 24
|
||||
}
|
||||
],
|
||||
xAxis: [{
|
||||
show: false,
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
splitArea: {
|
||||
show: true,
|
||||
areaStyle: { color: ['rgba(250,250,250,0.1)', 'rgba(200,200,200,0.1)'] }
|
||||
},
|
||||
axisLabel: {
|
||||
rotate: 38
|
||||
},
|
||||
axisLine: { lineStyle: { color: '#b7bdc7' }},
|
||||
splitLine: { lineStyle: { color: ['#eee'] }},
|
||||
splitNumber: 24
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
axisTick: { show: true, length: 0 },
|
||||
@ -154,9 +164,9 @@ export default {
|
||||
areaStyle: {}
|
||||
},
|
||||
{
|
||||
name: '有效',
|
||||
name: this.$t('pages.dashboard.monthlyPurchase.valid'),
|
||||
type: 'line',
|
||||
stack: '有效',
|
||||
stack: this.$t('pages.dashboard.monthlyPurchase.valid'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
@ -164,15 +174,16 @@ export default {
|
||||
areaStyle: {}
|
||||
},
|
||||
{
|
||||
name: '退款',
|
||||
name: this.$t('pages.dashboard.monthlyPurchase.refund'),
|
||||
type: 'line',
|
||||
stack: '退款',
|
||||
stack: this.$t('pages.dashboard.monthlyPurchase.refund'),
|
||||
smooth: 0.6,
|
||||
symbol: 'none',
|
||||
symbolSize: 10,
|
||||
data: thatDayData.reimburseQuantity,
|
||||
areaStyle: {}
|
||||
}]
|
||||
}
|
||||
]
|
||||
}, true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="daily-currency-charts">
|
||||
<el-select v-model="typeValue" placeholder="请选择" size="mini" @change="typeValueChange">
|
||||
<div class="daily-currency-charts" :data-language="language">
|
||||
<el-select v-model="typeValue" :placeholder="$t('pages.dashboard.shared.select')" size="mini" @change="typeValueChange">
|
||||
<el-option
|
||||
v-for="item in types"
|
||||
:key="item.value"
|
||||
@ -8,13 +8,12 @@
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<div id="barCharts" ref="barCharts" :style="'width: 100%;height:'+ height +';'" />
|
||||
<div id="barCharts" ref="barCharts" :style="'width: 100%;height:' + height + ';'" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
// import { currencyOrigins } from '@/constant/type'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@ -29,10 +28,6 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
types: [
|
||||
{ value: 0, name: '收入' },
|
||||
{ value: 1, name: '支出' }
|
||||
],
|
||||
dateNumber: '',
|
||||
typeValue: 0,
|
||||
barCharts: null,
|
||||
@ -42,37 +37,47 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['language']),
|
||||
types() {
|
||||
const language = this.language
|
||||
return [
|
||||
{ value: 0, name: this.$t('pages.dashboard.shared.income') },
|
||||
{ value: 1, name: this.$t('pages.dashboard.shared.expenditure') }
|
||||
]
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
chartsData: {
|
||||
handler(newVal) {
|
||||
const that = this
|
||||
that.groupChartsData = that.groupChartsDataByType()
|
||||
that.$nextTick(() => {
|
||||
that.renderCharts()
|
||||
handler() {
|
||||
this.groupChartsData = this.groupChartsDataByType()
|
||||
this.$nextTick(() => {
|
||||
this.renderCharts()
|
||||
})
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
language() {
|
||||
this.$nextTick(() => {
|
||||
this.renderCharts()
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
mounted() {
|
||||
const that = this
|
||||
that.barCharts = that.$echarts.init(that.$refs.barCharts)
|
||||
that.renderCharts()
|
||||
this.barCharts = this.$echarts.init(this.$refs.barCharts)
|
||||
this.renderCharts()
|
||||
window.addEventListener('resize', () => {
|
||||
that.barCharts.resize()
|
||||
this.barCharts.resize()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
groupChartsDataByType() {
|
||||
const that = this
|
||||
const obj = {
|
||||
income: [],
|
||||
expenditure: []
|
||||
}
|
||||
if (that.chartsData.length > 0) {
|
||||
that.chartsData.forEach(item => {
|
||||
if (this.chartsData.length > 0) {
|
||||
this.chartsData.forEach(item => {
|
||||
if (item.type === 0) {
|
||||
obj.income.push(item)
|
||||
}
|
||||
@ -84,7 +89,6 @@ export default {
|
||||
return obj
|
||||
},
|
||||
getBarData(list) {
|
||||
const that = this
|
||||
const dataKeys = []
|
||||
const dataList = []
|
||||
if (!list || list.length === 0) {
|
||||
@ -99,16 +103,18 @@ export default {
|
||||
name: item.originName,
|
||||
value: item.quantity,
|
||||
itemStyle: {
|
||||
color: that.getRandomColor()
|
||||
color: this.getRandomColor()
|
||||
}
|
||||
})
|
||||
}
|
||||
return { keys: dataKeys, data: dataList }
|
||||
},
|
||||
renderCharts() {
|
||||
const that = this
|
||||
const barData = that.getBarData(that.typeValue === 0 ? that.groupChartsData.income : that.groupChartsData.expenditure)
|
||||
that.barCharts.setOption({
|
||||
if (!this.barCharts) {
|
||||
return
|
||||
}
|
||||
const barData = this.getBarData(this.typeValue === 0 ? this.groupChartsData.income : this.groupChartsData.expenditure)
|
||||
this.barCharts.setOption({
|
||||
color: ['#66b3ff', '#ce90e8', '#ff9c6e', '#5cdbd3'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
@ -130,11 +136,9 @@ export default {
|
||||
containLabel: true,
|
||||
borderColor: '#eee'
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
show: false
|
||||
}
|
||||
],
|
||||
xAxis: [{
|
||||
show: false
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'category',
|
||||
data: barData.keys,
|
||||
@ -146,7 +150,7 @@ export default {
|
||||
width: 15,
|
||||
overflow: 'truncate',
|
||||
ellipsis: '...',
|
||||
formatter: function(value) {
|
||||
formatter(value) {
|
||||
return value.length > 10 ? value.substring(0, 10) + '...' : value
|
||||
}
|
||||
}
|
||||
@ -173,9 +177,8 @@ export default {
|
||||
return 'rgba(' + r + ',' + g + ',' + b + ',0.8)'
|
||||
},
|
||||
typeValueChange() {
|
||||
const that = this
|
||||
that.$nextTick(() => {
|
||||
that.renderCharts()
|
||||
this.$nextTick(() => {
|
||||
this.renderCharts()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div v-loading="loading" class="dily-register-user">
|
||||
<div v-loading="loading" class="dily-register-user" :data-language="language">
|
||||
<el-date-picker
|
||||
v-model="dateNumber"
|
||||
style="margin-bottom: 10px;"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
:placeholder="$t('pages.dashboard.userGoldTop.datePlaceholder')"
|
||||
value-format="yyyyMMdd"
|
||||
size="mini"
|
||||
:picker-options="pickerOptions"
|
||||
@ -14,10 +14,10 @@
|
||||
<div v-for="(item, index) in list" :key="index">
|
||||
<el-card v-if="sysOriginPlatforms.includes(item.sysOrigin)" class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>金币收支Top50({{ item.sysOriginName }})</span>
|
||||
<span>{{ $t('pages.dashboard.userGoldTop.title', { sysOriginName: item.sysOriginName }) }}</span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div style="font-size: 12px;color: #666;margin-bottom: 10px;">当日金币收支抽取前TOP50, 不含外部游戏</div>
|
||||
<div style="font-size: 12px;color: #666;margin-bottom: 10px;">{{ $t('pages.dashboard.userGoldTop.description') }}</div>
|
||||
<el-table
|
||||
:data="item.items"
|
||||
element-loading-text="Loading"
|
||||
@ -27,25 +27,25 @@
|
||||
<el-table-column label="No" width="50" align="center">
|
||||
<template slot-scope="scope">{{ scope.$index + 1 }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="roomProfile.roomName" label="用户" align="center" min-width="200">
|
||||
<el-table-column :label="$t('pages.dashboard.userGoldTop.user')" prop="roomProfile.roomName" align="center" min-width="200">
|
||||
<template slot-scope="scope">
|
||||
<user-table-exhibit :user-profile="scope.row.userProfile" :query-details="true" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="收入" width="100" align="center">
|
||||
<el-table-column :label="$t('pages.dashboard.userGoldTop.income')" width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div>{{ scope.row.groupTypeQuantity['0'] || 0 }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="支出" width="100" align="center">
|
||||
<el-table-column :label="$t('pages.dashboard.userGoldTop.expenditure')" width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div>{{ scope.row.groupTypeQuantity['1'] || 0 }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="quantity" label="合计" align="center" width="100" />
|
||||
<el-table-column fixed="right" label="操作" align="center" width="80">
|
||||
<el-table-column :label="$t('pages.dashboard.userGoldTop.total')" prop="quantity" align="center" width="100" />
|
||||
<el-table-column fixed="right" :label="$t('pages.dashboard.userGoldTop.action')" align="center" width="80">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click.native="clickQueryDetails(scope.row)">详情</el-button>
|
||||
<el-button type="text" @click.native="clickQueryDetails(scope.row)">{{ $t('pages.dashboard.userGoldTop.details') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -55,8 +55,8 @@
|
||||
|
||||
<div class="user-daily-currency-gold-top-drawer">
|
||||
<el-drawer
|
||||
title="详情"
|
||||
:before-close="() => queryDetailsVisible=false"
|
||||
:title="$t('pages.dashboard.userGoldTop.details')"
|
||||
:before-close="() => queryDetailsVisible = false"
|
||||
:visible="queryDetailsVisible"
|
||||
:close-on-press-escape="false"
|
||||
:wrapper-closable="false"
|
||||
@ -64,13 +64,12 @@
|
||||
:append-to-body="true"
|
||||
custom-class="drawer-auto-layout"
|
||||
>
|
||||
|
||||
<div class="bar-graph-charts" style="padding: 0px 10px">
|
||||
<div class="bar-graph-charts" style="padding: 0 10px">
|
||||
<bar-graph-charts
|
||||
ref="lineGraphCharts"
|
||||
:key="queryDetailsRow ? queryDetailsRow.userId : 'tmp'"
|
||||
:key="(queryDetailsRow ? queryDetailsRow.userId : 'tmp') + '-' + language"
|
||||
:charts-data="queryDetailsRow.items"
|
||||
:height="(queryDetailsRow.items ? queryDetailsRow.items.length > 5 ? queryDetailsRow.items.length * 40 : queryDetailsRow.items.length * 80: 300)+'px'"
|
||||
:height="(queryDetailsRow.items ? queryDetailsRow.items.length > 5 ? queryDetailsRow.items.length * 40 : queryDetailsRow.items.length * 80 : 300) + 'px'"
|
||||
/>
|
||||
</div>
|
||||
</el-drawer>
|
||||
@ -105,7 +104,7 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls']),
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls', 'language']),
|
||||
sysOriginPlatforms() {
|
||||
if (!this.permissionsSysOriginPlatformAlls || this.permissionsSysOriginPlatformAlls.length <= 0) {
|
||||
return []
|
||||
@ -118,30 +117,31 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
loadOrigin() {
|
||||
const that = this
|
||||
that.loading = true
|
||||
this.loading = true
|
||||
listDailyUserGoldTop(this.dateNumber).then(res => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
const { body } = res
|
||||
const list = body || []
|
||||
that.list = list.filter(item => !item.sysOrigin || that.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
this.list = list.filter(item => !item.sysOrigin || this.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
}).catch(() => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
querySearch(queryString, cb) {
|
||||
var restaurants = currencyOrigins
|
||||
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
|
||||
const restaurants = currencyOrigins
|
||||
const results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
|
||||
cb(results)
|
||||
},
|
||||
createFilter(queryString) {
|
||||
return (restaurant) => {
|
||||
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) >= 0) || (restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) >= 0)
|
||||
return restaurant => {
|
||||
return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) >= 0 ||
|
||||
restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) >= 0
|
||||
}
|
||||
},
|
||||
handleSelect(item) {
|
||||
this.selectOrigin = item.value
|
||||
this.selectOriginName = item.name
|
||||
const selectedItem = item || currencyOrigins[0]
|
||||
this.selectOrigin = selectedItem.value
|
||||
this.selectOriginName = selectedItem.name
|
||||
this.loadOrigin()
|
||||
},
|
||||
clickAnalyze() {
|
||||
@ -162,15 +162,16 @@ export default {
|
||||
.box-card {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
|
||||
.card-col {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.register-logout-count {
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="daily-currency-charts">
|
||||
<el-select v-model="typeValue" placeholder="请选择" size="mini" @change="typeValueChange">
|
||||
<div class="daily-currency-charts" :data-language="language">
|
||||
<el-select v-model="typeValue" :placeholder="$t('pages.dashboard.shared.select')" size="mini" @change="typeValueChange">
|
||||
<el-option
|
||||
v-for="item in types"
|
||||
:key="item.value"
|
||||
@ -8,13 +8,12 @@
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<div id="barCharts" ref="barCharts" :style="'width: 100%;height:'+ height +';'" />
|
||||
<div id="barCharts" ref="barCharts" :style="'width: 100%;height:' + height + ';'" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
// import { currencyOrigins } from '@/constant/type'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@ -29,10 +28,6 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
types: [
|
||||
{ value: 0, name: '收入' },
|
||||
{ value: 1, name: '支出' }
|
||||
],
|
||||
dateNumber: '',
|
||||
typeValue: 0,
|
||||
barCharts: null,
|
||||
@ -42,37 +37,47 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['language']),
|
||||
types() {
|
||||
const language = this.language
|
||||
return [
|
||||
{ value: 0, name: this.$t('pages.dashboard.shared.income') },
|
||||
{ value: 1, name: this.$t('pages.dashboard.shared.expenditure') }
|
||||
]
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
chartsData: {
|
||||
handler(newVal) {
|
||||
const that = this
|
||||
that.groupChartsData = that.groupChartsDataByType()
|
||||
that.$nextTick(() => {
|
||||
that.renderCharts()
|
||||
handler() {
|
||||
this.groupChartsData = this.groupChartsDataByType()
|
||||
this.$nextTick(() => {
|
||||
this.renderCharts()
|
||||
})
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
language() {
|
||||
this.$nextTick(() => {
|
||||
this.renderCharts()
|
||||
})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
mounted() {
|
||||
const that = this
|
||||
that.barCharts = that.$echarts.init(that.$refs.barCharts)
|
||||
that.renderCharts()
|
||||
this.barCharts = this.$echarts.init(this.$refs.barCharts)
|
||||
this.renderCharts()
|
||||
window.addEventListener('resize', () => {
|
||||
that.barCharts.resize()
|
||||
this.barCharts.resize()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
groupChartsDataByType() {
|
||||
const that = this
|
||||
const obj = {
|
||||
income: [],
|
||||
expenditure: []
|
||||
}
|
||||
if (that.chartsData.length > 0) {
|
||||
that.chartsData.forEach(item => {
|
||||
if (this.chartsData.length > 0) {
|
||||
this.chartsData.forEach(item => {
|
||||
if (item.type === 0) {
|
||||
obj.income.push(item)
|
||||
}
|
||||
@ -84,7 +89,6 @@ export default {
|
||||
return obj
|
||||
},
|
||||
getBarData(list) {
|
||||
const that = this
|
||||
const dataKeys = []
|
||||
const dataList = []
|
||||
if (!list || list.length === 0) {
|
||||
@ -99,16 +103,18 @@ export default {
|
||||
name: item.originName,
|
||||
value: item.quantity,
|
||||
itemStyle: {
|
||||
color: that.getRandomColor()
|
||||
color: this.getRandomColor()
|
||||
}
|
||||
})
|
||||
}
|
||||
return { keys: dataKeys, data: dataList }
|
||||
},
|
||||
renderCharts() {
|
||||
const that = this
|
||||
const barData = that.getBarData(that.typeValue === 0 ? that.groupChartsData.income : that.groupChartsData.expenditure)
|
||||
that.barCharts.setOption({
|
||||
if (!this.barCharts) {
|
||||
return
|
||||
}
|
||||
const barData = this.getBarData(this.typeValue === 0 ? this.groupChartsData.income : this.groupChartsData.expenditure)
|
||||
this.barCharts.setOption({
|
||||
color: ['#66b3ff', '#ce90e8', '#ff9c6e', '#5cdbd3'],
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
@ -130,11 +136,9 @@ export default {
|
||||
containLabel: true,
|
||||
borderColor: '#eee'
|
||||
},
|
||||
xAxis: [
|
||||
{
|
||||
show: false
|
||||
}
|
||||
],
|
||||
xAxis: [{
|
||||
show: false
|
||||
}],
|
||||
yAxis: [{
|
||||
type: 'category',
|
||||
data: barData.keys,
|
||||
@ -146,7 +150,7 @@ export default {
|
||||
width: 15,
|
||||
overflow: 'truncate',
|
||||
ellipsis: '...',
|
||||
formatter: function(value) {
|
||||
formatter(value) {
|
||||
return value.length > 10 ? value.substring(0, 10) + '...' : value
|
||||
}
|
||||
}
|
||||
@ -173,9 +177,8 @@ export default {
|
||||
return 'rgba(' + r + ',' + g + ',' + b + ',0.8)'
|
||||
},
|
||||
typeValueChange() {
|
||||
const that = this
|
||||
that.$nextTick(() => {
|
||||
that.renderCharts()
|
||||
this.$nextTick(() => {
|
||||
this.renderCharts()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div v-loading="loading" class="dily-register-user">
|
||||
<div v-loading="loading" class="dily-register-user" :data-language="language">
|
||||
<el-date-picker
|
||||
v-model="dateNumber"
|
||||
style="margin-bottom: 10px;"
|
||||
type="date"
|
||||
placeholder="选择日期"
|
||||
:placeholder="$t('pages.dashboard.rechargeTop.datePlaceholder')"
|
||||
value-format="yyyyMMdd"
|
||||
size="mini"
|
||||
:picker-options="pickerOptions"
|
||||
@ -14,10 +14,10 @@
|
||||
<div v-for="(item, index) in list" :key="index">
|
||||
<el-card v-if="sysOriginPlatforms.includes(item.sysOrigin)" class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>充值Top50({{ item.sysOriginName }})</span>
|
||||
<span>{{ $t('pages.dashboard.rechargeTop.title', { sysOriginName: item.sysOriginName }) }}</span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div style="font-size: 12px;color: #666;margin-bottom: 10px;">当日充值总额, 包含退款</div>
|
||||
<div style="font-size: 12px;color: #666;margin-bottom: 10px;">{{ $t('pages.dashboard.rechargeTop.description') }}</div>
|
||||
<el-table
|
||||
:data="item.items"
|
||||
element-loading-text="Loading"
|
||||
@ -27,12 +27,12 @@
|
||||
<el-table-column label="No" width="50" align="center">
|
||||
<template slot-scope="scope">{{ scope.$index + 1 }}</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="roomProfile.roomName" label="用户" align="center" min-width="200">
|
||||
<el-table-column :label="$t('pages.dashboard.rechargeTop.user')" prop="roomProfile.roomName" align="center" min-width="200">
|
||||
<template slot-scope="scope">
|
||||
<user-table-exhibit :user-profile="scope.row.userProfile" :query-details="true" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="金额" min-width="100" align="center">
|
||||
<el-table-column :label="$t('pages.dashboard.rechargeTop.amount')" min-width="100" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div>{{ scope.row.quantity || 0 }}</div>
|
||||
</template>
|
||||
@ -41,20 +41,17 @@
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listDailyUserRechargeTop } from '@/api/statistics'
|
||||
// import BarGraphCharts from './bar-graph-charts'
|
||||
import { currencyOrigins } from '@/constant/type'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { formatDate, beforeDateObject } from '@/utils'
|
||||
|
||||
export default {
|
||||
name: 'DilyRegisterUser',
|
||||
// components: { BarGraphCharts },
|
||||
data() {
|
||||
return {
|
||||
pickerOptions: {
|
||||
@ -71,7 +68,7 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls']),
|
||||
...mapGetters(['permissionsSysOriginPlatformAlls', 'language']),
|
||||
sysOriginPlatforms() {
|
||||
if (!this.permissionsSysOriginPlatformAlls || this.permissionsSysOriginPlatformAlls.length <= 0) {
|
||||
return []
|
||||
@ -84,30 +81,31 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
loadOrigin() {
|
||||
const that = this
|
||||
that.loading = true
|
||||
this.loading = true
|
||||
listDailyUserRechargeTop(this.dateNumber).then(res => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
const { body } = res
|
||||
const list = body || []
|
||||
that.list = list.filter(item => !item.sysOrigin || that.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
this.list = list.filter(item => !item.sysOrigin || this.permissionsSysOriginPlatformAlls.some(sys => sys.value === item.sysOrigin))
|
||||
}).catch(() => {
|
||||
that.loading = false
|
||||
this.loading = false
|
||||
})
|
||||
},
|
||||
querySearch(queryString, cb) {
|
||||
var restaurants = currencyOrigins
|
||||
var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
|
||||
const restaurants = currencyOrigins
|
||||
const results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants
|
||||
cb(results)
|
||||
},
|
||||
createFilter(queryString) {
|
||||
return (restaurant) => {
|
||||
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) >= 0) || (restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) >= 0)
|
||||
return restaurant => {
|
||||
return restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) >= 0 ||
|
||||
restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) >= 0
|
||||
}
|
||||
},
|
||||
handleSelect(item) {
|
||||
this.selectOrigin = item.value
|
||||
this.selectOriginName = item.name
|
||||
const selectedItem = item || currencyOrigins[0]
|
||||
this.selectOrigin = selectedItem.value
|
||||
this.selectOriginName = selectedItem.name
|
||||
this.loadOrigin()
|
||||
},
|
||||
changeDateNumber() {
|
||||
@ -121,15 +119,16 @@ export default {
|
||||
.box-card {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
|
||||
.card-col {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.register-logout-count {
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
.date {
|
||||
font-weight: bold;
|
||||
line-height: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
<template>
|
||||
<div class="customize-charts">
|
||||
<div class="customize-charts" :data-language="language">
|
||||
<el-row :gutter="10">
|
||||
<el-col v-for="item in tablePermissions" :key="item.component" :md="4" :sm="8" :xs="12">
|
||||
<div class="charts-tag flex-c" :class="{'charts-tag-selected': activeName === item.component}" @click="clickTag(item)">
|
||||
<div
|
||||
class="charts-tag flex-c"
|
||||
:class="{ 'charts-tag-selected': activeName === item.component }"
|
||||
@click="clickTag(item)"
|
||||
>
|
||||
<div class="nowrap-ellipsis">
|
||||
{{ item.title }}
|
||||
</div>
|
||||
@ -30,58 +34,69 @@ import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'DashboardCharts',
|
||||
components: { UserDailyCurrencyRechargeTop, UserDailyCurrencyGoldTop, DailyCurrencyGoldOriginTop, DailyRegisterUser, DailyCurrency, DailyPurchase, MonthlyPurchase, ActiveIndex, PropsSalesOverviewCharts, DailyCurrencyGold },
|
||||
components: {
|
||||
UserDailyCurrencyRechargeTop,
|
||||
UserDailyCurrencyGoldTop,
|
||||
DailyCurrencyGoldOriginTop,
|
||||
DailyRegisterUser,
|
||||
DailyCurrency,
|
||||
DailyPurchase,
|
||||
MonthlyPurchase,
|
||||
ActiveIndex,
|
||||
PropsSalesOverviewCharts,
|
||||
DailyCurrencyGold
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
activeName: '',
|
||||
tables: {
|
||||
'dashboard:added:daily': {
|
||||
title: '每日新增',
|
||||
titleKey: 'pages.dashboard.chartTabs.dailyAdded',
|
||||
component: 'DailyRegisterUser',
|
||||
sort: 1
|
||||
},
|
||||
'dashboard:active:situation': {
|
||||
title: '活跃情况',
|
||||
titleKey: 'pages.dashboard.chartTabs.activeOverview',
|
||||
component: 'ActiveIndex',
|
||||
sort: 2
|
||||
},
|
||||
'dashboard:daily:inapp:purchases': {
|
||||
title: '每日内购',
|
||||
titleKey: 'pages.dashboard.chartTabs.dailyPurchase',
|
||||
component: 'DailyPurchase',
|
||||
sort: 3
|
||||
},
|
||||
'dashboard:monthly:inapp:purchases': {
|
||||
title: '每月内购',
|
||||
titleKey: 'pages.dashboard.chartTabs.monthlyPurchase',
|
||||
component: 'MonthlyPurchase',
|
||||
sort: 4
|
||||
},
|
||||
'props:sales:overview:charts': {
|
||||
title: '道具销售情况',
|
||||
titleKey: 'pages.dashboard.chartTabs.propsSales',
|
||||
component: 'PropsSalesOverviewCharts',
|
||||
sort: 5
|
||||
},
|
||||
'dashboard:money:balance': {
|
||||
title: '货币收支',
|
||||
titleKey: 'pages.dashboard.chartTabs.currencyBalance',
|
||||
component: 'DailyCurrency',
|
||||
sort: 6
|
||||
},
|
||||
'dashboard:daily:gold': {
|
||||
title: '每日金币(分析)',
|
||||
titleKey: 'pages.dashboard.chartTabs.dailyGoldAnalysis',
|
||||
component: 'DailyCurrencyGold',
|
||||
sort: 7
|
||||
},
|
||||
'dashboard:daily:gold:origin:top': {
|
||||
title: '每日金币(来源榜)',
|
||||
titleKey: 'pages.dashboard.chartTabs.dailyGoldSourceTop',
|
||||
component: 'DailyCurrencyGoldOriginTop',
|
||||
sort: 8
|
||||
},
|
||||
'dashboard:daily:gold:user:top': {
|
||||
title: '用户金币(Top50)',
|
||||
titleKey: 'pages.dashboard.chartTabs.userGoldTop',
|
||||
component: 'UserDailyCurrencyGoldTop',
|
||||
sort: 9
|
||||
},
|
||||
'dashboard:daily:recharge:rank': {
|
||||
title: '每日充值(Top50)',
|
||||
titleKey: 'pages.dashboard.chartTabs.dailyRechargeTop',
|
||||
component: 'UserDailyCurrencyRechargeTop',
|
||||
sort: 10
|
||||
}
|
||||
@ -89,8 +104,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['buttonPermissions']),
|
||||
...mapGetters(['buttonPermissions', 'language']),
|
||||
tablePermissions() {
|
||||
const language = this.language
|
||||
if (!this.buttonPermissions || this.buttonPermissions.length <= 0) {
|
||||
return []
|
||||
}
|
||||
@ -102,7 +118,10 @@ export default {
|
||||
}
|
||||
const item = this.tables[permission]
|
||||
if (item) {
|
||||
tabMap[item.sort] = item
|
||||
tabMap[item.sort] = {
|
||||
...item,
|
||||
title: this.$t(item.titleKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -134,14 +153,17 @@ export default {
|
||||
color: #333;
|
||||
background-color: #eaeff2;
|
||||
}
|
||||
|
||||
.charts-tag:hover {
|
||||
background-color: #dfe9ee;
|
||||
}
|
||||
|
||||
.charts-tag-selected {
|
||||
background-color: #cadce5;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.customize-charts {
|
||||
.charts-tag {
|
||||
@ -151,13 +173,10 @@ export default {
|
||||
margin-bottom: 8px;
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@ -1,16 +1,20 @@
|
||||
<template>
|
||||
<div class="dashboard">
|
||||
<div class="dashboard" :data-language="language">
|
||||
<div v-if="activeName">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane v-for="item in tablePermissions" :key="item.component" :label="item.title" :name="item.component" />
|
||||
<el-tab-pane
|
||||
v-for="item in tablePermissions"
|
||||
:key="item.component"
|
||||
:label="item.title"
|
||||
:name="item.component"
|
||||
/>
|
||||
<component :is="activeName" />
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="welcome">
|
||||
<img src="@/assets/welcome.png" alt="">
|
||||
内部运营, 数据管理系统
|
||||
<!-- <sapn v-if="name">, 当前登录用户: {{ name }}</sapn> -->
|
||||
{{ $t('pages.dashboard.welcome') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -21,6 +25,7 @@ import Introduction from './introduction'
|
||||
import DashboardCharts from './dashboard-charts'
|
||||
import { mapGetters } from 'vuex'
|
||||
import { deepClone } from '@/utils'
|
||||
|
||||
export default {
|
||||
name: 'Dashboard',
|
||||
components: { DashboardCharts, Introduction },
|
||||
@ -29,12 +34,12 @@ export default {
|
||||
activeName: '',
|
||||
tables: {
|
||||
'dashboard:generalize': {
|
||||
title: '概括',
|
||||
titleKey: 'pages.dashboard.tabs.overview',
|
||||
component: 'Introduction',
|
||||
sort: 1
|
||||
},
|
||||
'dashboard:dashboard:charts': {
|
||||
title: '数据图表',
|
||||
titleKey: 'pages.dashboard.tabs.dataCharts',
|
||||
component: 'DashboardCharts',
|
||||
sort: 2
|
||||
}
|
||||
@ -42,8 +47,9 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['buttonPermissions', 'name']),
|
||||
...mapGetters(['buttonPermissions', 'language']),
|
||||
tablePermissions() {
|
||||
const language = this.language
|
||||
if (!this.buttonPermissions || this.buttonPermissions.length <= 0) {
|
||||
return []
|
||||
}
|
||||
@ -57,7 +63,10 @@ export default {
|
||||
}
|
||||
const item = this.tables[permission]
|
||||
if (item) {
|
||||
tabMap[item.sort] = item
|
||||
tabMap[item.sort] = {
|
||||
...item,
|
||||
title: this.$t(item.titleKey)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,17 +92,17 @@ export default {
|
||||
if (this.tablePermissions && this.tablePermissions.length > 0) {
|
||||
this.activeName = this.tablePermissions[0].component
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.welcome {
|
||||
width: 60%;
|
||||
padding: 100px 0px;
|
||||
padding: 100px 0;
|
||||
margin: auto;
|
||||
color: #666666;
|
||||
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="account-info region-card">
|
||||
<div class="account-info region-card" :data-language="language">
|
||||
<div class="card">
|
||||
<div class="account-info flex-l">
|
||||
<div class="avatar flex-c" :style="userAvatarColor">{{ firstNameStr }}</div>
|
||||
<div class="info">
|
||||
<div class="nickname">{{ name }}</div>
|
||||
<div class="account">账号: {{ loginName }}</div>
|
||||
<div class="account">{{ $t('pages.dashboard.account.accountLabel') }}: {{ loginName }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -15,27 +15,21 @@
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { extractColorByText } from '@/utils'
|
||||
|
||||
export default {
|
||||
name: 'AccountInfo',
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['buttonPermissions', 'name', 'loginName']),
|
||||
...mapGetters(['buttonPermissions', 'name', 'loginName', 'language']),
|
||||
userAvatarColor() {
|
||||
return 'background-color:' + extractColorByText(this.name) + ';'
|
||||
},
|
||||
firstNameStr() {
|
||||
return this.name ? this.name.trim().charAt(0) : '?'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.account-info {
|
||||
.avatar {
|
||||
@ -45,11 +39,11 @@ export default {
|
||||
color: #FFFFFF;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.info {
|
||||
padding: 0 10px;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
padding: 0px 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="my-native region-card">
|
||||
<div class="my-native region-card" :data-language="language">
|
||||
<div class="card">
|
||||
<div class="title">我的导航</div>
|
||||
<div class="subtitle">最近访问</div>
|
||||
<div class="content ">
|
||||
<div class="title">{{ $t('pages.dashboard.userNavigation.title') }}</div>
|
||||
<div class="subtitle">{{ $t('pages.dashboard.userNavigation.recentVisits') }}</div>
|
||||
<div class="content">
|
||||
<el-row :gutter="10">
|
||||
<el-col v-for="(item, index) in dashboard.recentPreviews" :key="index" :md="4" :sm="8" :xs="12">
|
||||
<div
|
||||
@ -12,12 +12,16 @@
|
||||
@mouseenter="mouseoverRecentPreviews(item)"
|
||||
>
|
||||
<div class="tag region-tag-color flex-c">
|
||||
<a :href="item.type === 'CUSTOM' ? item.link : 'javascript:void(0);'" :target="item.type === 'CUSTOM'?'_blank': ''" style="width: 100%" @click="clickCustomNavigations(item)">
|
||||
<a
|
||||
:href="item.type === 'CUSTOM' ? item.link : 'javascript:void(0);'"
|
||||
:target="item.type === 'CUSTOM' ? '_blank' : ''"
|
||||
style="width: 100%"
|
||||
@click="clickCustomNavigations(item)"
|
||||
>
|
||||
<div class="nowrap-ellipsis" style="width: 100%">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</a>
|
||||
<!-- <i v-if="mouseoveRecentSeletedId === item.id" class="el-icon-error" style="font-size: 18px;" @click.stop="removeRecentPreviews(item)" /> -->
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
@ -25,10 +29,9 @@
|
||||
</div>
|
||||
|
||||
<div class="native-content">
|
||||
|
||||
<div class="native-item">
|
||||
<div class="subtitle">自定义快捷</div>
|
||||
<div class="content ">
|
||||
<div class="subtitle">{{ $t('pages.dashboard.userNavigation.customShortcuts') }}</div>
|
||||
<div class="content">
|
||||
<el-row :gutter="10">
|
||||
<el-col v-for="(item, index) in dashboard.customNavigations" :key="index" :md="4" :sm="8" :xs="12">
|
||||
<div
|
||||
@ -41,39 +44,59 @@
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</a>
|
||||
<i v-if="mouseoveCustomNavigationId === item.id" class="el-icon-error" style="font-size: 18px;" @click.stop="removeCustomNavigations(item)" />
|
||||
<i
|
||||
v-if="mouseoveCustomNavigationId === item.id"
|
||||
class="el-icon-error"
|
||||
style="font-size: 18px;"
|
||||
@click.stop="removeCustomNavigations(item)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :md="4" :sm="8" :xs="12">
|
||||
<el-popover v-model="customNavigationFormVisible" width="400" trigger="click">
|
||||
<div class="add-native">
|
||||
<!-- <el-tabs v-model="activeAddNative">
|
||||
<el-tab-pane v-for="item in addNativeTables" :key="item.component" :label="item.title" :name="item.component" />
|
||||
<component :is="activeAddNative" />
|
||||
</el-tabs> -->
|
||||
<div class="blockquote">您可以使用此功能自由添加任意页面至快捷入口,目前仅支持 http 或 https 协议</div>
|
||||
<div class="blockquote">{{ $t('pages.dashboard.userNavigation.protocolTip') }}</div>
|
||||
<el-form ref="customNavigationForm" :model="customNavigationForm" :rules="customNavigationFormRules">
|
||||
<el-form-item label="入口名称" prop="name">
|
||||
<el-input v-model="customNavigationForm.name" placeholder="自定义导航入口名称" minlength="1" maxlength="30" show-word-limit />
|
||||
<el-form-item :label="$t('pages.dashboard.userNavigation.entryName')" prop="name">
|
||||
<el-input
|
||||
v-model="customNavigationForm.name"
|
||||
:placeholder="$t('pages.dashboard.userNavigation.entryNamePlaceholder')"
|
||||
minlength="1"
|
||||
maxlength="30"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="入口链接" prop="link">
|
||||
<el-input v-model="customNavigationForm.link" placeholder="自定义导航入口链接" minlength="1" maxlength="300" show-word-limit />
|
||||
<el-form-item :label="$t('pages.dashboard.userNavigation.entryLink')" prop="link">
|
||||
<el-input
|
||||
v-model="customNavigationForm.link"
|
||||
:placeholder="$t('pages.dashboard.userNavigation.entryLinkPlaceholder')"
|
||||
minlength="1"
|
||||
maxlength="300"
|
||||
show-word-limit
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="customNavigationFormLoading" :disabled="customNavigationFormLoading" @click="onSubmitCustomNavigationForm">添加</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="customNavigationFormLoading"
|
||||
:disabled="customNavigationFormLoading"
|
||||
@click="onSubmitCustomNavigationForm"
|
||||
>
|
||||
{{ $t('pages.dashboard.userNavigation.add') }}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div slot="reference">
|
||||
<div class="tag region-tag-color flex-c">
|
||||
<div class="nowrap-ellipsis">
|
||||
<i class="el-icon-circle-plus-outline" style="margin: 0px 3px; font-weight: bold;" /><strong>添加快捷入口</strong>
|
||||
<i class="el-icon-circle-plus-outline" style="margin: 0 3px; font-weight: bold;" />
|
||||
<strong>{{ $t('pages.dashboard.userNavigation.addShortcut') }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-popover>
|
||||
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
@ -86,23 +109,25 @@
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import { addDashboardCustom, removeDashboardPreviews, removeDashboardCustom, addDashboardPreviews } from '@/api/ops-system'
|
||||
|
||||
export default {
|
||||
name: 'MyNavigation',
|
||||
data() {
|
||||
var checkLink = (rule, value, callback) => {
|
||||
const checkLink = (rule, value, callback) => {
|
||||
if (!value) {
|
||||
return callback(new Error('请输入支持 http 或 https 协议'))
|
||||
return callback(new Error(this.$t('pages.dashboard.userNavigation.protocolValidation')))
|
||||
}
|
||||
|
||||
if (value.startsWith('http://') || value.startsWith('https://')) {
|
||||
return callback()
|
||||
}
|
||||
return callback(new Error('请输入支持 http 或 https 协议'))
|
||||
return callback(new Error(this.$t('pages.dashboard.userNavigation.protocolValidation')))
|
||||
}
|
||||
|
||||
return {
|
||||
addNativeTables: [
|
||||
{ title: '搜索添加', component: 'DailyPurchase' },
|
||||
{ title: '自定义添加', component: 'MonthlyPurchase' }
|
||||
{ titleKey: 'pages.dashboard.userNavigation.searchAdd', component: 'DailyPurchase' },
|
||||
{ titleKey: 'pages.dashboard.userNavigation.customAdd', component: 'MonthlyPurchase' }
|
||||
],
|
||||
customNavigationFormVisible: false,
|
||||
customNavigationFormLoading: false,
|
||||
@ -113,7 +138,7 @@ export default {
|
||||
link: ''
|
||||
},
|
||||
customNavigationFormRules: {
|
||||
name: [{ required: true, message: '必填字段', trigger: 'blur' }],
|
||||
name: [{ required: true, message: this.$t('pages.dashboard.userNavigation.requiredField'), trigger: 'blur' }],
|
||||
link: [{ required: true, trigger: 'blur', validator: checkLink }]
|
||||
},
|
||||
mouseoveRecentSeletedId: '',
|
||||
@ -121,15 +146,33 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['buttonPermissions', 'name', 'dashboard'])
|
||||
...mapGetters(['buttonPermissions', 'name', 'dashboard', 'language'])
|
||||
},
|
||||
created() {
|
||||
watch: {
|
||||
language() {
|
||||
this.customNavigationFormRules = {
|
||||
name: [{ required: true, message: this.$t('pages.dashboard.userNavigation.requiredField'), trigger: 'blur' }],
|
||||
link: [{
|
||||
required: true,
|
||||
trigger: 'blur',
|
||||
validator: (rule, value, callback) => {
|
||||
if (!value) {
|
||||
return callback(new Error(this.$t('pages.dashboard.userNavigation.protocolValidation')))
|
||||
}
|
||||
|
||||
if (value.startsWith('http://') || value.startsWith('https://')) {
|
||||
return callback()
|
||||
}
|
||||
|
||||
return callback(new Error(this.$t('pages.dashboard.userNavigation.protocolValidation')))
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
loadDashboard() {
|
||||
this.$store.dispatch('user/getUserDashboard').then(res => {
|
||||
console.log('success')
|
||||
}).catch(er => {
|
||||
this.$store.dispatch('user/getUserDashboard').catch(er => {
|
||||
console.error('loadDashboard', er)
|
||||
})
|
||||
},
|
||||
@ -146,59 +189,56 @@ export default {
|
||||
this.$router.push(item.link)
|
||||
}
|
||||
},
|
||||
|
||||
mouseoutCustomNavigations(item) {
|
||||
mouseoutCustomNavigations() {
|
||||
this.mouseoveCustomNavigationId = ''
|
||||
},
|
||||
mouseoverCustomNavigations(item) {
|
||||
this.mouseoveCustomNavigationId = item.id
|
||||
},
|
||||
removeCustomNavigations(item) {
|
||||
const that = this
|
||||
removeDashboardCustom(item.id).then(res => {
|
||||
that.$opsMessage.success()
|
||||
that.loadDashboard()
|
||||
removeDashboardCustom(item.id).then(() => {
|
||||
this.$opsMessage.success()
|
||||
this.loadDashboard()
|
||||
}).catch(er => {
|
||||
console.error('removeCustomNavigations', er)
|
||||
})
|
||||
},
|
||||
mouseoutRecentPreviews(item) {
|
||||
mouseoutRecentPreviews() {
|
||||
this.mouseoveRecentSeletedId = ''
|
||||
},
|
||||
mouseoverRecentPreviews(item) {
|
||||
this.mouseoveRecentSeletedId = item.id
|
||||
},
|
||||
removeRecentPreviews(item) {
|
||||
const that = this
|
||||
removeDashboardPreviews(item.id).then(res => {
|
||||
that.$opsMessage.success()
|
||||
that.loadDashboard()
|
||||
removeDashboardPreviews(item.id).then(() => {
|
||||
this.$opsMessage.success()
|
||||
this.loadDashboard()
|
||||
}).catch(er => {
|
||||
console.error('removeRecentPreviews', er)
|
||||
})
|
||||
},
|
||||
onSubmitCustomNavigationForm() {
|
||||
const that = this
|
||||
that.$refs.customNavigationForm.validate((valid) => {
|
||||
this.$refs.customNavigationForm.validate((valid) => {
|
||||
if (!valid) {
|
||||
console.error('error submit!!')
|
||||
return false
|
||||
}
|
||||
that.customNavigationFormLoading = true
|
||||
addDashboardCustom(that.customNavigationForm).then(res => {
|
||||
that.$opsMessage.success()
|
||||
that.customNavigationFormLoading = false
|
||||
that.customNavigationFormVisible = false
|
||||
that.loadDashboard()
|
||||
}).catch(er => {
|
||||
that.customNavigationFormLoading = false
|
||||
that.customNavigationFormVisible = false
|
||||
this.customNavigationFormLoading = true
|
||||
addDashboardCustom(this.customNavigationForm).then(() => {
|
||||
this.$opsMessage.success()
|
||||
this.customNavigationFormLoading = false
|
||||
this.customNavigationFormVisible = false
|
||||
this.loadDashboard()
|
||||
}).catch(() => {
|
||||
this.customNavigationFormLoading = false
|
||||
this.customNavigationFormVisible = false
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.my-native {
|
||||
.tag {
|
||||
@ -207,15 +247,12 @@ export default {
|
||||
line-height: 32px;
|
||||
padding: 0 12px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
font-size: 12px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
@ -1,41 +1,10 @@
|
||||
<template>
|
||||
<div class="waiting-processing region-card">
|
||||
<div class="waiting-processing region-card" :data-language="language">
|
||||
<div class="card">
|
||||
<div class="title">每日一文</div>
|
||||
<div class="tips-text">{{ textKey }}</div>
|
||||
|
||||
<!-- <div class="content">
|
||||
<el-row :gutter="10">
|
||||
<el-col :md="8">
|
||||
<div class="tag region-tag-color">
|
||||
<div class="tag-title">待处理</div>
|
||||
<div class="quantity">0</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :md="8">
|
||||
<div class="tag region-tag-color">
|
||||
<div class="tag-title">待定</div>
|
||||
<div class="quantity">0</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :md="8">
|
||||
<div class="tag region-tag-color">
|
||||
<div class="tag-title">已处理</div>
|
||||
<div class="quantity">0</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
开发中, 敬请期待...
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div> -->
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="title">系统时间</div>
|
||||
<div class="title">{{ $t('pages.dashboard.systemTime.title') }}</div>
|
||||
<div class="system-date">
|
||||
<div>时区: {{ nowDateTimeZone }}</div>
|
||||
<p>时间: {{ nowDateTime | dateFormat }}</p>
|
||||
<div>{{ $t('pages.dashboard.systemTime.timezone') }}: {{ nowDateTimeZone }}</div>
|
||||
<p>{{ $t('pages.dashboard.systemTime.time') }}: {{ nowDateTime | dateFormat }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -43,154 +12,34 @@
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
import Cookies from 'js-cookie'
|
||||
import { getCurrentTimeZone } from '@/lang'
|
||||
|
||||
export default {
|
||||
name: 'AccountInfo',
|
||||
data() {
|
||||
return {
|
||||
nowDateTime: new Date(),
|
||||
nowDateTimeZone: new Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
textKey: 'DailyText',
|
||||
toipsText: '',
|
||||
copywriting: [
|
||||
'得到的失去的在乎的忘掉的都让它随风而去。',
|
||||
'再多的不幸,都是曾经,都会过去,一如窗外的雨,淋过,湿过,走了,远了。曾经的美好,留于心底,曾经的悲伤,置于脑后,不恋,不恨。',
|
||||
'别人相信的事实,未必是你的。',
|
||||
'当你带着同情心去看时,你可以在你的心中创造一个美丽的空间。',
|
||||
'有时候,记忆是甜的,照片无论怎么老旧泛黄。',
|
||||
'当我回到我的中心,一个包裹着优雅的提醒等待着我:永远从温柔中流淌。',
|
||||
'漫长的人生,其实只是瞬间,一定学着,让自己在人生途中,不后悔。',
|
||||
'给事留一个机会;给人留一个空间,给己留一份尊严。有些事想不开别想,得不到别要;看不开,就背着;放不下,就记着;舍不得,就留着。晚安!',
|
||||
'过分的理性,令女人失去了女人的属性。',
|
||||
'强者创造事变,弱者受制于上帝给他铺排的事变。',
|
||||
'快乐来自于以感激的心情,去接受眼前的生活。',
|
||||
'少时浪费生命寻找金钱,老时浪费金钱寻找生命。',
|
||||
'生活需要微笑,是微笑让这个世界变得更加温暖,变得更加的美丽生动,变得丰富多彩了有了微笑河流才那么清澈,有了微笑天空才那么蔚蓝。',
|
||||
'大鸟是关不住的,它总要飞向天空。',
|
||||
'用%的灵感加上%的汗水,去换取%的辉煌成就。',
|
||||
'有信心就会有成功,有思索就会有思路,有努力就会有收获。',
|
||||
'中国式管理,讲起来就是水的管理。和美国式管理偏向火的管理颇为不同。我们主张以柔克刚,先礼后兵,继旧开新,生生不息,无一不和水有关。晚安!',
|
||||
'只有抵住最黑的暗,才能收获最光的亮。',
|
||||
'人到无求多自由,人品若山极崇峻。',
|
||||
'这个世界,我们第一次来,也是最后一次。',
|
||||
'你改变不了过去,但你可以改变现在。',
|
||||
'行不通的真理是假真理,说不通的道理是假道理。',
|
||||
'清晨的暖阳,浩瀚的夜空,过去的美好,余下的人生。',
|
||||
'有喜就有悲,有阴影也就有光,不悲观不乐观,活在当下最重要。',
|
||||
'在我的生命中,从未遭受过失败,我所遇到的,都是暂时的挫折罢了。',
|
||||
'清新的空气,快乐的气息,透过空气射入你的灵魂里,将阳光呼吸,将幸福抱起,泡一杯甜蜜的咖啡,品尝幸福的意义。',
|
||||
'不管忙或是闲,放飞心情就是休闲。不管近或是远,内心宁静路就不远。',
|
||||
'勇者,脚下都是路;智者,知道走哪一条路最好。',
|
||||
'日久不一定生情,但必定见人心。有时候也怕,时间会说出真话。',
|
||||
'你要让你的能力,配得上你的虚荣,让你的优秀配得上你的自尊,让你的视野配得上你的骄傲。',
|
||||
'世界上最勇敢的事情是微笑着听你说你们之间的爱情,你的回忆里没有我,而我还听得那么认真。',
|
||||
'女人对待感情常有惯性,有了爱,就希望能一直爱下去。',
|
||||
'人生至高无上的幸福,莫过于确信自己被人所爱。',
|
||||
'人生就是一个个选择,有对有错,选择了,就不要后悔。',
|
||||
'给自己一个机会,重新开始。',
|
||||
'有时候我们觉得累,是因为在人生的道路上,忘记了去哪。',
|
||||
'经历了那么那么多,才知道自己不过是一个供人娱乐的玩具而已',
|
||||
'有钱的人把自己的房子装饰得漂亮;有德的人把自己的身心修养得很好。',
|
||||
'追逐梦想,寻觅梦想的清香。',
|
||||
'能做自己的人非常少,但是必须努力呀。',
|
||||
'工作做得好,你会更自豪。',
|
||||
'既然选择了,就要咬牙坚持走下去。',
|
||||
'年后的年轻美貌,与你是否每一天坚持喝颜如玉有关,保养,是女人最好的修行!',
|
||||
'拼搏实现梦想,坚持铸就辉煌。',
|
||||
'人生路上,留一点遗憾在生活中,也许比完美更觉得美!天地本不全,人间便不可能完整,也算是对不完美的缺憾,一种自我安慰吧!佛且这么说,何况我们人呢!',
|
||||
'我们要学会在顺境中感恩和体会幸福,在逆境中成熟和坚强!',
|
||||
'你从来就不应该从一个时刻跳到另一个时刻,而应该停留在你脚下的那个时刻。',
|
||||
'当我们在责备别人时,岂不是也在间接宽容自己。',
|
||||
'你的生活,源于你的选择。',
|
||||
'我们的目的是什么?是胜利!不惜一切代价争取胜利!',
|
||||
'我在书上看到过这样一句话,说是倘若我们的生命中遭遇到了遮蔽阳光的云层,那么唯一的理由是,我们的心灵飞得还不够高。所以我就在想啊,如果我能不断地努力,不断地到达一个更高的地方,那么是不是就再没有那么多能够遮蔽我视线的障碍了。晚安!',
|
||||
'我与不属于我的东西和谐相处。我用爱让它自由自在。',
|
||||
'人活着首先是要对自己负责,负责让自己这辈子都幸福。',
|
||||
'我们很在乎得到,一旦拥有就难以放下。其实拥有只是短暂的,那些东西即使再好,和你再密不可分,到最后都会离你而去。',
|
||||
'当你开始依照习惯行事,你的进取精神就会因此而丧失。',
|
||||
'凡人看人是看你拥有多少钱财,上帝看人看的是你做了多少善事。',
|
||||
'我希望你有足够的自由来瞥见你心中的爱,并对它的深处感到惊奇。',
|
||||
'是你忘了带我走。我们就这样迷散在陌生的风雨里,从此天各一方,两两相望。',
|
||||
'过去终是过去,那人,那事,那情,任你留恋,都是云烟。',
|
||||
'如果学到的知识,却不能修养自己,帮助别人,那么学的知识又有什么用呢?',
|
||||
'人与人之间的距离,要保持好,太近了会扎人,太远了会伤人。',
|
||||
'不管见不见面,总有朋友把你惦念。早安,朋友!愿幸福一直在你身边!',
|
||||
'锲而不舍你能发觉,喜欢上的便是运动自身!',
|
||||
'如果我们一直消极的活着,那么这辈子就一点指望也没有了。',
|
||||
'男人要有地位,但不能高得吓人。稻微一努力,自己就有可能站到他们的身边,这样的男人,才最令女人期待!',
|
||||
'倒霉的时候要默默熬过去,不要声张否则留下的都是笑柄。',
|
||||
'十六岁的时候看六十岁还很遥远,六十岁的时候看十六岁仿佛就在昨天。',
|
||||
'赚别人的钱,越多越好,贫穷才是命运的最大的敌人。',
|
||||
'一个人,经得起挫折,受得起委屈,方能为自己赢得美好的人生。',
|
||||
'你没挽留,我没回头,如此余生各自安好,也没有谁不好,也许只是时间不凑巧吧。',
|
||||
'只有自己足够强大,才会有用的话语权。',
|
||||
'你不能控制他人,但你可以掌握自己。'
|
||||
],
|
||||
nowDateTimeZone: getCurrentTimeZone(),
|
||||
timeIndexInterval: null
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['buttonPermissions', 'name', 'loginName'])
|
||||
...mapGetters(['language'])
|
||||
},
|
||||
created() {
|
||||
const that = this
|
||||
that.textKey = this.getDailyText()
|
||||
|
||||
if (that.timeIndexInterval) {
|
||||
clearInterval(that.timeIndexInterval)
|
||||
if (this.timeIndexInterval) {
|
||||
clearInterval(this.timeIndexInterval)
|
||||
}
|
||||
|
||||
that.timeIndexInterval = setInterval(() => {
|
||||
that.nowDateTime = new Date()
|
||||
this.timeIndexInterval = setInterval(() => {
|
||||
this.nowDateTime = new Date()
|
||||
}, 1000)
|
||||
},
|
||||
methods: {
|
||||
getDailyText() {
|
||||
try {
|
||||
const text = Cookies.get(this.textKey)
|
||||
if (!text) {
|
||||
const randomText = this.copywriting[Math.floor((Math.random() * this.copywriting.length))] || this.copywriting[0]
|
||||
const date = new Date()
|
||||
Cookies.set(this.textKey, `${date.getFullYear()}${date.getMonth()}${date.getDate()}#${randomText}`)
|
||||
return randomText
|
||||
}
|
||||
|
||||
return text.split('#')[1]
|
||||
} catch (er) {
|
||||
return this.copywriting[Math.floor((Math.random() * this.copywriting.length))] || this.copywriting[0]
|
||||
}
|
||||
beforeDestroy() {
|
||||
if (this.timeIndexInterval) {
|
||||
clearInterval(this.timeIndexInterval)
|
||||
this.timeIndexInterval = null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
<style scoped lang="scss">
|
||||
.waiting-processing {
|
||||
.content {
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
.tag {
|
||||
width: 100%;
|
||||
line-height: 32px;
|
||||
padding: 5px 12px;
|
||||
margin-bottom: 8px;
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
cursor: pointer;
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
.quantity {
|
||||
font-weight: bold;
|
||||
font-size: 24px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="quick-link">
|
||||
<div class="quick-link" :data-language="language">
|
||||
<el-card>
|
||||
<div class="content">
|
||||
<el-row :gutter="12">
|
||||
<el-col v-for="(item,index) in links" :key="index" class="item-card" :sm="6" @click.native="clickCard(item)">
|
||||
<el-col v-for="(item, index) in links" :key="index" class="item-card" :sm="6" @click.native="clickCard(item)">
|
||||
<el-card shadow="hover">
|
||||
{{ item.title }}
|
||||
</el-card>
|
||||
@ -11,10 +11,10 @@
|
||||
</el-row>
|
||||
</div>
|
||||
<el-divider />
|
||||
<div class="dashboard-text">开发使用</div>
|
||||
<div class="dashboard-text">{{ $t('pages.dashboard.quickLink.devUsage') }}</div>
|
||||
<div class="content">
|
||||
<el-row :gutter="12">
|
||||
<el-col v-for="(item,index) in devLinks" :key="index" class="item-card" :sm="6" @click.native="clickCard(item)">
|
||||
<el-col v-for="(item, index) in devLinks" :key="index" class="item-card" :sm="6" @click.native="clickCard(item)">
|
||||
<el-card shadow="hover">
|
||||
{{ item.title }}
|
||||
</el-card>
|
||||
@ -22,30 +22,36 @@
|
||||
</el-row>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'QuickLink',
|
||||
data() {
|
||||
return {
|
||||
links: [
|
||||
{ title: '测试后台管理', link: 'http://test.back.sugartimeapp.com/' },
|
||||
{ title: '测试经纪人后台', link: 'http://test.broker.sugartimeapp.com/' },
|
||||
{ title: '线上后台', link: 'http://admin.sugartimeapp.com/' },
|
||||
{ title: '线上经纪人后台', link: 'http://broker.sugartimeapp.com/' },
|
||||
{ title: '线上IM后台', link: 'http://im.sugartimeapp.com/' }
|
||||
],
|
||||
devLinks: [
|
||||
{ title: '开发经纪人后台', link: 'http://dev.broker.sugartimeapp.com/' },
|
||||
{ title: '开发环境jenkins', link: 'http://dev.jenkins.sugartimeapp.com/' },
|
||||
{ title: '测试环境jenkins', link: 'http://test.jenkins.sugartimeapp.com/' },
|
||||
{ title: '开发环境supervisor', link: 'http://119.23.230.191:9001/' },
|
||||
{ title: '测试环境supervisor', link: 'http://47.254.89.114:9001/' },
|
||||
{ title: '线上环境supervisor', link: 'http://47.251.15.209:9001/' },
|
||||
{ title: '图谱API文档', link: 'http://cloud.doc.tuputech.com/' }
|
||||
computed: {
|
||||
...mapGetters(['language']),
|
||||
links() {
|
||||
const language = this.language
|
||||
return [
|
||||
{ title: this.$t('pages.dashboard.quickLink.testAdmin'), link: 'http://test.back.sugartimeapp.com/' },
|
||||
{ title: this.$t('pages.dashboard.quickLink.testBroker'), link: 'http://test.broker.sugartimeapp.com/' },
|
||||
{ title: this.$t('pages.dashboard.quickLink.productionAdmin'), link: 'http://admin.sugartimeapp.com/' },
|
||||
{ title: this.$t('pages.dashboard.quickLink.productionBroker'), link: 'http://broker.sugartimeapp.com/' },
|
||||
{ title: this.$t('pages.dashboard.quickLink.productionIm'), link: 'http://im.sugartimeapp.com/' }
|
||||
]
|
||||
},
|
||||
devLinks() {
|
||||
const language = this.language
|
||||
return [
|
||||
{ title: this.$t('pages.dashboard.quickLink.devBroker'), link: 'http://dev.broker.sugartimeapp.com/' },
|
||||
{ title: this.$t('pages.dashboard.quickLink.devJenkins'), link: 'http://dev.jenkins.sugartimeapp.com/' },
|
||||
{ title: this.$t('pages.dashboard.quickLink.testJenkins'), link: 'http://test.jenkins.sugartimeapp.com/' },
|
||||
{ title: this.$t('pages.dashboard.quickLink.devSupervisor'), link: 'http://119.23.230.191:9001/' },
|
||||
{ title: this.$t('pages.dashboard.quickLink.testSupervisor'), link: 'http://47.254.89.114:9001/' },
|
||||
{ title: this.$t('pages.dashboard.quickLink.productionSupervisor'), link: 'http://47.251.15.209:9001/' },
|
||||
{ title: this.$t('pages.dashboard.quickLink.graphApiDocs'), link: 'http://cloud.doc.tuputech.com/' }
|
||||
]
|
||||
}
|
||||
},
|
||||
@ -60,6 +66,7 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
.content {
|
||||
margin-top: 20px;
|
||||
|
||||
.item-card {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<div class="filter-container">
|
||||
<el-select
|
||||
v-model="listQuery.sysOrigin"
|
||||
placeholder="系统"
|
||||
:placeholder="$t('pages.eggExchangeRecord.placeholder.system')"
|
||||
style="width: 120px"
|
||||
class="filter-item"
|
||||
@change="handleSearch"
|
||||
@ -26,7 +26,7 @@
|
||||
<account-input
|
||||
v-model="listQuery.userId"
|
||||
:sys-origin="listQuery.sysOrigin"
|
||||
placeholder="用户ID"
|
||||
:placeholder="$t('pages.eggExchangeRecord.placeholder.userId')"
|
||||
/>
|
||||
</div>
|
||||
<el-button
|
||||
@ -36,7 +36,7 @@
|
||||
:disabled="searchDisabled"
|
||||
@click="handleSearch"
|
||||
>
|
||||
搜索
|
||||
{{ $t('pages.eggExchangeRecord.action.search') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
@ -48,7 +48,7 @@
|
||||
>
|
||||
<el-table-column
|
||||
prop="sysOrigin"
|
||||
label="来源系统"
|
||||
:label="$t('pages.eggExchangeRecord.table.sourceSystem')"
|
||||
align="center"
|
||||
width="80"
|
||||
>
|
||||
@ -59,7 +59,7 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="用户" align="center" min-width="200">
|
||||
<el-table-column :label="$t('pages.eggExchangeRecord.table.user')" align="center" min-width="200">
|
||||
<template slot-scope="scope">
|
||||
<user-table-exhibit
|
||||
:user-profile="scope.row.userBaseInfo"
|
||||
@ -67,8 +67,8 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="兑换数量" prop="quantity" align="center" />
|
||||
<el-table-column label="奖品" align="center">
|
||||
<el-table-column :label="$t('pages.eggExchangeRecord.table.exchangeQuantity')" prop="quantity" align="center" />
|
||||
<el-table-column :label="$t('pages.eggExchangeRecord.table.prize')" align="center">
|
||||
<template slot-scope="scope">
|
||||
<img
|
||||
v-if="scope.row.type === 'GOLD'"
|
||||
@ -94,7 +94,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="createTime"
|
||||
label="创建时间"
|
||||
:label="$t('pages.eggExchangeRecord.table.createdAt')"
|
||||
width="200"
|
||||
align="center"
|
||||
>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<template>
|
||||
<div class="egg-lottery-cnf">
|
||||
<div class="filter-container">
|
||||
<el-select
|
||||
v-model="listQuery.sysOrigin"
|
||||
placeholder="归属系统"
|
||||
:placeholder="$t('pages.eggLotteryCnf.placeholder.system')"
|
||||
style="width: 120px"
|
||||
class="filter-item"
|
||||
@change="changeSysOrigin"
|
||||
@ -18,16 +18,22 @@
|
||||
<span style="float: left;margin-left:10px">{{ item.label }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleSearch"> 搜索 </el-button>
|
||||
<el-button type="primary" class="filter-item" @click="clickAdd"> <i class="el-icon-circle-plus" /> 添加</el-button>
|
||||
<el-button type="primary" class="filter-item" :loading="submitLoading" :disabled="submitDisabled" @click="clickSave"><i class="el-icon-success" /> 保存</el-button>
|
||||
<!-- <el-button type="text" @click="clickSetEggExtractRatio">奖金池:{{ prizePool }}</el-button>
|
||||
<el-button type="text" :loading="extractRatioLoading" :disabled="extractRatioLoading" @click="clickSetEggExtractRatio">抽取率:{{ extractRatio || '-' }}</el-button> -->
|
||||
<el-button class="filter-item" type="primary" icon="el-icon-search" @click="handleSearch">
|
||||
{{ $t('pages.eggLotteryCnf.action.search') }}
|
||||
</el-button>
|
||||
<el-button type="primary" class="filter-item" @click="clickAdd">
|
||||
<i class="el-icon-circle-plus" /> {{ $t('pages.eggLotteryCnf.action.add') }}
|
||||
</el-button>
|
||||
<el-button type="primary" class="filter-item" :loading="submitLoading" :disabled="submitDisabled" @click="clickSave">
|
||||
<i class="el-icon-success" /> {{ $t('pages.eggLotteryCnf.action.save') }}
|
||||
</el-button>
|
||||
<!-- <el-button type="text" @click="clickSetEggExtractRatio">{{ $t('pages.eggLotteryCnf.action.prizePool') }}{{ prizePool }}</el-button>
|
||||
<el-button type="text" :loading="extractRatioLoading" :disabled="extractRatioLoading" @click="clickSetEggExtractRatio">{{ $t('pages.eggLotteryCnf.action.extractRatio') }}{{ extractRatio || '-' }}</el-button> -->
|
||||
</div>
|
||||
<el-alert
|
||||
type="info"
|
||||
:closable="false"
|
||||
description="注意: 不要随意对记录数据进行删除操作, 如果用户已拥有碎片将会被同步删除"
|
||||
:description="$t('pages.eggLotteryCnf.message.notice')"
|
||||
/>
|
||||
<div class="conf-row">
|
||||
<el-table
|
||||
@ -38,22 +44,26 @@
|
||||
highlight-current-row
|
||||
>
|
||||
<el-table-column
|
||||
label="序号"
|
||||
:label="$t('pages.eggLotteryCnf.table.sort')"
|
||||
min-width="80"
|
||||
align="center"
|
||||
>
|
||||
<template scope="scope">
|
||||
<el-input v-model="scope.row.sort" size="small" placeholder="请输入序号" @input="submitDisabled=false" />
|
||||
<el-input
|
||||
v-model="scope.row.sort"
|
||||
size="small"
|
||||
:placeholder="$t('pages.eggLotteryCnf.placeholder.sort')"
|
||||
@input="submitDisabled = false"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="奖品"
|
||||
:label="$t('pages.eggLotteryCnf.table.prize')"
|
||||
min-width="80"
|
||||
align="center"
|
||||
>
|
||||
<template scope="scope">
|
||||
|
||||
<el-dropdown>
|
||||
<span class="el-dropdown-link">
|
||||
<div v-if="scope.row.sourceCover" class="preview-img flex-c">
|
||||
@ -71,76 +81,100 @@
|
||||
<img v-else-if="scope.row.sourceType === 'GAME_COUPON'" src="@/assets/game_coupon.png" width="35" height="35">
|
||||
<img v-else-if="scope.row.sourceType === 'SPECIAL_ID'" src="@/assets/special_id.png" width="35" height="35">
|
||||
</div>
|
||||
<div v-else>设置<i class="el-icon-arrow-down el-icon--right" /></div>
|
||||
<div v-else>
|
||||
{{ $t('pages.eggLotteryCnf.action.set') }}<i class="el-icon-arrow-down el-icon--right" />
|
||||
</div>
|
||||
</span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item @click.native="clickSelectReward('PROPS',scope.row)">道具</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clickAddReward('SPECIAL_ID',scope.row)">靓号</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clickAddReward('GOLD',scope.row)">金币</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clickAddReward('DIAMOND',scope.row)">钻石</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clickAddReward('GAME_COUPON',scope.row)">游戏券</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clickSelectReward('PROPS', scope.row)">{{ $t('pages.eggLotteryCnf.rewardType.props') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clickAddReward('SPECIAL_ID', scope.row)">{{ $t('pages.eggLotteryCnf.rewardType.specialId') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clickAddReward('GOLD', scope.row)">{{ $t('pages.eggLotteryCnf.rewardType.gold') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clickAddReward('DIAMOND', scope.row)">{{ $t('pages.eggLotteryCnf.rewardType.diamond') }}</el-dropdown-item>
|
||||
<el-dropdown-item @click.native="clickAddReward('GAME_COUPON', scope.row)">{{ $t('pages.eggLotteryCnf.rewardType.gameCoupon') }}</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="奖品量"
|
||||
:label="$t('pages.eggLotteryCnf.table.prizeQuantity')"
|
||||
min-width="80"
|
||||
align="center"
|
||||
>
|
||||
<template scope="scope">
|
||||
<el-input v-model="scope.row.prizeQuantity" size="small" placeholder="请输入奖品数量" @input="submitDisabled=false" />
|
||||
<el-input
|
||||
v-model="scope.row.prizeQuantity"
|
||||
size="small"
|
||||
:placeholder="$t('pages.eggLotteryCnf.placeholder.prizeQuantity')"
|
||||
@input="submitDisabled = false"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="碎片"
|
||||
:label="$t('pages.eggLotteryCnf.table.fragmentsSize')"
|
||||
min-width="80"
|
||||
align="center"
|
||||
>
|
||||
<template scope="scope">
|
||||
<el-input v-model="scope.row.fragmentsSize" size="small" placeholder="请输入碎片兑换数量" @input="submitDisabled=false" />
|
||||
<el-input
|
||||
v-model="scope.row.fragmentsSize"
|
||||
size="small"
|
||||
:placeholder="$t('pages.eggLotteryCnf.placeholder.fragmentsSize')"
|
||||
@input="submitDisabled = false"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="碎片价值"
|
||||
:label="$t('pages.eggLotteryCnf.table.fragmentsAmount')"
|
||||
min-width="80"
|
||||
align="center"
|
||||
>
|
||||
<template scope="scope">
|
||||
<el-input v-model="scope.row.fragmentsAmount" size="small" placeholder="请输入碎片价值" @input="submitDisabled=false" />
|
||||
<el-input
|
||||
v-model="scope.row.fragmentsAmount"
|
||||
size="small"
|
||||
:placeholder="$t('pages.eggLotteryCnf.placeholder.fragmentsAmount')"
|
||||
@input="submitDisabled = false"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="库存"
|
||||
:label="$t('pages.eggLotteryCnf.table.stockQuantity')"
|
||||
min-width="80"
|
||||
align="center"
|
||||
>
|
||||
<template scope="scope">
|
||||
<el-input v-model.number="scope.row.stockQuantity" size="small" placeholder="请输入库存" @input="submitDisabled=false" />
|
||||
<el-input
|
||||
v-model.number="scope.row.stockQuantity"
|
||||
size="small"
|
||||
:placeholder="$t('pages.eggLotteryCnf.placeholder.stockQuantity')"
|
||||
@input="submitDisabled = false"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="已消耗"
|
||||
:label="$t('pages.eggLotteryCnf.table.consumeStockQuantity')"
|
||||
min-width="80"
|
||||
align="center"
|
||||
>
|
||||
<template scope="scope">
|
||||
{{ scope.row.consumeStockQuantity||0 }}
|
||||
{{ scope.row.consumeStockQuantity || 0 }}
|
||||
<el-button type="text" class="el-icon-refresh-right" @click="clickResetConsumeStockQuantity(scope.row)" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column
|
||||
label="操作"
|
||||
:label="$t('pages.eggLotteryCnf.table.action')"
|
||||
width="80"
|
||||
align="center"
|
||||
>
|
||||
<template scope="scope">
|
||||
<el-button type="text" class="filter-item" @click="clickDel(scope.row, scope.$index)"> 删除</el-button>
|
||||
<el-button type="text" class="filter-item" @click="clickDel(scope.row, scope.$index)">
|
||||
{{ $t('pages.eggLotteryCnf.action.delete') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -148,14 +182,13 @@
|
||||
<props-source-select-drawer
|
||||
v-if="propsSourceSelectDrawerVisible"
|
||||
:sys-origin="listQuery.sysOrigin"
|
||||
@close="propsSourceSelectDrawerVisible=false"
|
||||
@close="propsSourceSelectDrawerVisible = false"
|
||||
@select="selectPropsSource"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import PropsSourceSelectDrawer from '@/components/data/PropsSourceSelectDrawer'
|
||||
import { getEggConfig, updateEggConfig, resetEggConsumeStockQuantity, getEggExtractRatio, setEggExtractRatio, getEggPrizePool } from '@/api/game'
|
||||
import { pickerOptions } from '@/constant/el-const'
|
||||
@ -272,37 +305,40 @@ export default {
|
||||
this.list.push(this.createConfItem())
|
||||
this.submitDisabled = false
|
||||
},
|
||||
getValidationMessage(type, index) {
|
||||
return this.$t(`pages.eggLotteryCnf.validation.${type}`, { index: index + 1 })
|
||||
},
|
||||
clickSave() {
|
||||
const that = this
|
||||
if (that.submitDisabled) {
|
||||
that.$opsMessage.warn('当前没有任何操作~')
|
||||
that.$opsMessage.warn(that.$t('pages.eggLotteryCnf.message.noChanges'))
|
||||
return
|
||||
}
|
||||
const errors = []
|
||||
for (let index = 0; index < that.list.length; index++) {
|
||||
const item = that.list[index]
|
||||
if (!that.validNumber(item.sort, 0, 99999999)) {
|
||||
errors.push(`[${index + 1}行]序号, 错误请输入阿拉伯数字>=0 && <= 99999999`)
|
||||
errors.push(that.getValidationMessage('sort', index))
|
||||
}
|
||||
if (!item.sourceType) {
|
||||
errors.push(`[${index + 1}行]奖品, 为空`)
|
||||
errors.push(that.getValidationMessage('prize', index))
|
||||
}
|
||||
if (!that.validNumber(item.prizeQuantity, 0, 99999999)) {
|
||||
errors.push(`[${index + 1}行]奖品数量, 错误请输入阿拉伯数字>=1 && <= 99999999`)
|
||||
errors.push(that.getValidationMessage('prizeQuantity', index))
|
||||
}
|
||||
if (!that.validNumber(item.stockQuantity, -1, 99999999)) {
|
||||
errors.push(`[${index + 1}行]库存数量, 错误请输入阿拉伯数字>=-1 && <= 99999999`)
|
||||
errors.push(that.getValidationMessage('stockQuantity', index))
|
||||
}
|
||||
if (!that.validNumber(item.fragmentsSize, 1, 99999999)) {
|
||||
errors.push(`[${index + 1}行]碎片数量, 错误请输入阿拉伯数字>=1 && <= 99999999`)
|
||||
errors.push(that.getValidationMessage('fragmentsSize', index))
|
||||
}
|
||||
if (!that.validNumber(item.fragmentsAmount, 1, 99999999)) {
|
||||
errors.push(`[${index + 1}行]碎片价值, 错误请输入阿拉伯数字>=1 && <= 99999999`)
|
||||
errors.push(that.getValidationMessage('fragmentsAmount', index))
|
||||
}
|
||||
if (errors.length > 0) {
|
||||
errors.push('请更正后重新提交!!!')
|
||||
that.$confirm(errors.join('<br>'), '提示', {
|
||||
confirmButtonText: '确定',
|
||||
errors.push(that.$t('pages.eggLotteryCnf.validation.fixAndSubmit'))
|
||||
that.$confirm(errors.join('<br>'), that.$t('pages.eggLotteryCnf.dialog.title'), {
|
||||
confirmButtonText: that.$t('pages.eggLotteryCnf.dialog.confirm'),
|
||||
showCancelButton: false,
|
||||
type: 'warning',
|
||||
dangerouslyUseHTMLString: true
|
||||
@ -335,7 +371,9 @@ export default {
|
||||
},
|
||||
clickDel(row, index) {
|
||||
const that = this
|
||||
that.$confirm('用户已拥有对应碎片数据将会同步删除, 是否继续?', '提示', {
|
||||
that.$confirm(that.$t('pages.eggLotteryCnf.dialog.deleteConfirm'), that.$t('pages.eggLotteryCnf.dialog.title'), {
|
||||
confirmButtonText: that.$t('pages.eggLotteryCnf.dialog.confirm'),
|
||||
cancelButtonText: that.$t('pages.eggLotteryCnf.dialog.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
that.list.splice(index, 1)
|
||||
@ -348,7 +386,9 @@ export default {
|
||||
},
|
||||
clickResetConsumeStockQuantity(row) {
|
||||
const that = this
|
||||
that.$confirm('是否确定重置库存消耗', '提示', {
|
||||
that.$confirm(that.$t('pages.eggLotteryCnf.dialog.resetConfirm'), that.$t('pages.eggLotteryCnf.dialog.title'), {
|
||||
confirmButtonText: that.$t('pages.eggLotteryCnf.dialog.confirm'),
|
||||
cancelButtonText: that.$t('pages.eggLotteryCnf.dialog.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
resetEggConsumeStockQuantity(row.id).then(res => {
|
||||
@ -380,11 +420,11 @@ export default {
|
||||
},
|
||||
clickSetEggExtractRatio() {
|
||||
const that = this
|
||||
that.$prompt('计算方式:门票- (门票 * 概率)=抽取', '门票抽取', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
that.$prompt(that.$t('pages.eggLotteryCnf.dialog.extractFormula'), that.$t('pages.eggLotteryCnf.dialog.extractTitle'), {
|
||||
confirmButtonText: that.$t('pages.eggLotteryCnf.dialog.confirm'),
|
||||
cancelButtonText: that.$t('pages.eggLotteryCnf.dialog.cancel'),
|
||||
inputPattern: /^\d{1,5}(\.\d{0,5})?$/,
|
||||
inputErrorMessage: '范围0~99999小数最多5位'
|
||||
inputErrorMessage: that.$t('pages.eggLotteryCnf.dialog.extractInputError')
|
||||
}).then(({ value }) => {
|
||||
that.extractRatioLoading = true
|
||||
setEggExtractRatio(that.listQuery.sysOrigin, value).then(res => {
|
||||
@ -400,13 +440,15 @@ export default {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.egg-lottery-cnf {
|
||||
.preview-img {
|
||||
position: relative;
|
||||
|
||||
.player {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
right: 0;
|
||||
top: -10px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<div class="filter-container">
|
||||
<el-select
|
||||
v-model="listQuery.sysOrigin"
|
||||
placeholder="系统"
|
||||
:placeholder="$t('pages.eggLotteryRecord.placeholder.system')"
|
||||
style="width: 120px"
|
||||
class="filter-item"
|
||||
@change="handleSearch"
|
||||
@ -26,7 +26,7 @@
|
||||
<account-input
|
||||
v-model="listQuery.userId"
|
||||
:sys-origin="listQuery.sysOrigin"
|
||||
placeholder="用户ID"
|
||||
:placeholder="$t('pages.eggLotteryRecord.placeholder.userId')"
|
||||
/>
|
||||
</div>
|
||||
<el-button
|
||||
@ -36,7 +36,7 @@
|
||||
:disabled="searchDisabled"
|
||||
@click="handleSearch"
|
||||
>
|
||||
搜索
|
||||
{{ $t('pages.eggLotteryRecord.action.search') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
@ -48,7 +48,7 @@
|
||||
>
|
||||
<el-table-column
|
||||
prop="sysOrigin"
|
||||
label="来源系统"
|
||||
:label="$t('pages.eggLotteryRecord.table.sourceSystem')"
|
||||
align="center"
|
||||
width="80"
|
||||
>
|
||||
@ -59,7 +59,7 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="用户" align="center" min-width="200">
|
||||
<el-table-column :label="$t('pages.eggLotteryRecord.table.user')" align="center" min-width="200">
|
||||
<template slot-scope="scope">
|
||||
<user-table-exhibit
|
||||
:user-profile="scope.row.userBaseInfo"
|
||||
@ -67,19 +67,19 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="付费 / 抽次数" align="center">
|
||||
<el-table-column :label="$t('pages.eggLotteryRecord.table.paidDrawCount')" align="center">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.lotteryFee }} / {{ scope.row.quantity }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="中奖碎片" align="center">
|
||||
<el-table-column :label="$t('pages.eggLotteryRecord.table.winningFragments')" align="center">
|
||||
<template slot-scope="scope">
|
||||
<props-row :list="scope.row.winningDetailsList" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
prop="createTime"
|
||||
label="创建时间"
|
||||
:label="$t('pages.eggLotteryRecord.table.createdAt')"
|
||||
width="200"
|
||||
align="center"
|
||||
>
|
||||
|
||||
@ -15,17 +15,21 @@ export default {
|
||||
components: { EggExchangeRecord, EggLotteryRecord, EggLotteryCnf },
|
||||
data() {
|
||||
return {
|
||||
activeName: 'EggExchangeRecord',
|
||||
tables: [
|
||||
activeName: 'EggExchangeRecord'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tables() {
|
||||
return [
|
||||
{
|
||||
title: '碎片兑换',
|
||||
title: this.$t('pages.gameEgg.tabs.exchangeRecord'),
|
||||
component: 'EggExchangeRecord'
|
||||
}, {
|
||||
title: '抽奖记录',
|
||||
title: this.$t('pages.gameEgg.tabs.lotteryRecord'),
|
||||
component: 'EggLotteryRecord'
|
||||
},
|
||||
{
|
||||
title: '配置',
|
||||
title: this.$t('pages.gameEgg.tabs.config'),
|
||||
component: 'EggLotteryCnf'
|
||||
}
|
||||
]
|
||||
|
||||
@ -10,16 +10,16 @@
|
||||
>
|
||||
<div class="form-edit">
|
||||
<el-form ref="form" :model="form" :rules="formRules" label-width="110px" style="margin-right:50px;">
|
||||
<el-form-item prop="gameType" label="游戏类型">
|
||||
<el-form-item prop="gameType" :label="$t('pages.gameLotteryConfigForm.form.gameType')">
|
||||
<el-select
|
||||
v-model="form.gameType"
|
||||
placeholder="游戏类型"
|
||||
:placeholder="$t('pages.gameLotteryConfigForm.placeholder.gameType')"
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
>
|
||||
<el-option v-for="(item, index) in (lotteryGameTypes || [])" :key="index" :label="item.name" :value="item.value">
|
||||
<el-option v-for="(item, index) in (lotteryGameTypes || [])" :key="index" :label="getLotteryGameTypeLabel(item)" :value="item.value">
|
||||
<div style="float: left;margin-left:10px">
|
||||
{{ item.name }}
|
||||
{{ getLotteryGameTypeLabel(item) }}
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
@ -64,24 +64,24 @@
|
||||
<el-col :span="14" style="text-align: right;">
|
||||
<span style="font-weight:bold;"> {{ getTypeName(item) }}</span>
|
||||
<span v-if="item.type === 'SPECIAL_ID'" style="margin-left: 0.3rem;">
|
||||
<span style="margin-right: 0.3rem;">类型:{{ item.content }}</span>数量:<el-input v-model="item.quantity" v-number :value="item.quantity" style="width: 10%;" placeholder="数量" />
|
||||
<span style="margin-right: 0.3rem;">{{ $t('pages.gameLotteryConfigForm.label.type') }}:{{ item.content }}</span>{{ $t('pages.gameLotteryConfigForm.label.quantity') }}:<el-input v-model="item.quantity" v-number :value="item.quantity" style="width: 10%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.quantity')" />
|
||||
</span>
|
||||
<span v-else-if="item.type === 'GOLD' || item.type === 'DIAMOND' || isGameCoupon(item.type)" style="margin-left: 0.3rem;">
|
||||
数量:<el-input v-model="item.content" v-number :value="item.content" style="width: 10%;" placeholder="数量" />
|
||||
{{ $t('pages.gameLotteryConfigForm.label.quantity') }}:<el-input v-model="item.content" v-number :value="item.content" style="width: 10%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.quantity')" />
|
||||
</span>
|
||||
<span v-else-if="item.type === 'BADGE'" style="margin-left: 0.3rem;">
|
||||
<span style="margin-right: 0.3rem;">{{ item.badgeName }}</span>天数:<el-input v-model="item.quantity" v-number :value="item.quantity" style="width: 10%;" placeholder="天数" /></span>
|
||||
<span style="margin-right: 0.3rem;">{{ item.badgeName }}</span>{{ $t('pages.gameLotteryConfigForm.label.days') }}:<el-input v-model="item.quantity" v-number :value="item.quantity" style="width: 10%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.days')" /></span>
|
||||
<span v-else>
|
||||
<span v-if="item.type === 'GIFT'" style="margin-left: 0.3rem;">数量:</span>
|
||||
<span v-else>天数:</span>
|
||||
<el-input v-model="item.quantity" v-number :value="item.quantity" style="width: 10%;" :placeholder="item.type === 'GIFT' ? '数量' : '天数'" />
|
||||
<span v-if="item.type === 'GIFT'" style="margin-left: 0.3rem;">{{ $t('pages.gameLotteryConfigForm.label.quantity') }}:</span>
|
||||
<span v-else>{{ $t('pages.gameLotteryConfigForm.label.days') }}:</span>
|
||||
<el-input v-model="item.quantity" v-number :value="item.quantity" style="width: 10%;" :placeholder="item.type === 'GIFT' ? $t('pages.gameLotteryConfigForm.placeholder.quantity') : $t('pages.gameLotteryConfigForm.placeholder.days')" />
|
||||
</span>
|
||||
<span style="margin-left: 0.3rem;">库存:<el-input v-model="item.inventory" v-number :value="item.inventory" style="width: 10%;" placeholder="所需碎片" /></span>
|
||||
<span style="margin-left: 0.3rem;">{{ $t('pages.gameLotteryConfigForm.label.inventory') }}:<el-input v-model="item.inventory" v-number :value="item.inventory" style="width: 10%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.inventory')" /></span>
|
||||
<span v-if="form.gameType === 'EGG'" style="color:#d8ae36;margin-left: 0.3rem;">
|
||||
所需碎片:<el-input v-model="item.dataHelp" v-number :value="item.dataHelp" style="width: 7%;" placeholder="所需碎片" />
|
||||
{{ $t('pages.gameLotteryConfigForm.label.requiredFragments') }}:<el-input v-model="item.dataHelp" v-number :value="item.dataHelp" style="width: 7%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.requiredFragments')" />
|
||||
</span>
|
||||
<span style="color:#f78e8e;margin-left: 0.3rem;">
|
||||
概率:<el-input v-model="item.probability" oninput="value=value.replace(/[^0-9.]/g,'')" :value="item.probability" style="width: 10%;" placeholder="概率" />
|
||||
{{ $t('pages.gameLotteryConfigForm.label.probability') }}:<el-input v-model="item.probability" oninput="value=value.replace(/[^0-9.]/g,'')" :value="item.probability" style="width: 10%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.probability')" />
|
||||
</span>
|
||||
</el-col>
|
||||
<el-col :span="2" style="text-align: right;">
|
||||
@ -90,7 +90,7 @@
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
<el-form-item label="添加配置">
|
||||
<el-form-item :label="$t('pages.gameLotteryConfigForm.form.addConfig')">
|
||||
<div class="content-list">
|
||||
<el-row v-for="(item, index) in form.tmpConfigList" :key="index">
|
||||
<div class="content-box">
|
||||
@ -101,11 +101,11 @@
|
||||
<el-col :span="4">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.content'"
|
||||
:rules="{required: true, message: '必填字段不可为空', trigger: 'blur'}"
|
||||
:rules="getRequiredFieldRule()"
|
||||
>
|
||||
<el-select
|
||||
v-model="item.content"
|
||||
placeholder="请选择"
|
||||
:placeholder="$t('pages.gameLotteryConfigForm.placeholder.select')"
|
||||
style="width:100%"
|
||||
filterable
|
||||
>
|
||||
@ -116,33 +116,33 @@
|
||||
<el-col :span="3">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.quantity'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<span><el-input v-model="item.quantity" v-number style="width: 100%;" placeholder="数量" /></span>
|
||||
<span><el-input v-model="item.quantity" v-number style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.quantity')" /></span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.inventory'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<span><el-input v-model="item.inventory" v-number style="width: 100%;" placeholder="库存数" /></span>
|
||||
<span><el-input v-model="item.inventory" v-number style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.inventory')" /></span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="form.gameType === 'EGG'" :span="3">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.dataHelp'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<span><el-input v-model="item.dataHelp" v-number style="width: 100%;" placeholder="碎片数" /></span>
|
||||
<span><el-input v-model="item.dataHelp" v-number style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.requiredFragments')" /></span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.probability'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<span><el-input v-model="item.probability" oninput="value=value.replace(/[^0-9.]/g,'')" style="width: 100%;" placeholder="概率(0.1就是10%)" /></span>
|
||||
<span><el-input v-model="item.probability" oninput="value=value.replace(/[^0-9.]/g,'')" style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.probabilityExample')" /></span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
@ -154,33 +154,33 @@
|
||||
<el-col :span="5">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.content'"
|
||||
:rules="{ required: true, message: '必填字段不可为空', trigger: 'blur'}"
|
||||
:rules="getRequiredFieldRule()"
|
||||
>
|
||||
<el-input v-model.trim="item.content" v-number type="text" placeholder="请输入内容" />
|
||||
<el-input v-model.trim="item.content" v-number type="text" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.inputContent')" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.inventory'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<span><el-input v-model="item.inventory" v-number style="width: 100%;" placeholder="库存数" /></span>
|
||||
<span><el-input v-model="item.inventory" v-number style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.inventory')" /></span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="form.gameType === 'EGG'" :span="3">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.dataHelp'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<span><el-input v-model="item.dataHelp" v-number style="width: 100%;" placeholder="碎片数" /></span>
|
||||
<span><el-input v-model="item.dataHelp" v-number style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.requiredFragments')" /></span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.probability'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<span><el-input v-model="item.probability" oninput="value=value.replace(/[^0-9.]/g,'')" style="width: 100%;" placeholder="概率(0.1就是10%)" /></span>
|
||||
<span><el-input v-model="item.probability" oninput="value=value.replace(/[^0-9.]/g,'')" style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.probabilityExample')" /></span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
@ -192,11 +192,11 @@
|
||||
<el-col :span="3">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.content'"
|
||||
:rules="{required: true, message: '必填字段不可为空', trigger: 'blur'}"
|
||||
:rules="getRequiredFieldRule()"
|
||||
>
|
||||
<el-select
|
||||
v-model="item.content"
|
||||
placeholder="请选择"
|
||||
:placeholder="$t('pages.gameLotteryConfigForm.placeholder.select')"
|
||||
style="width:100%"
|
||||
filterable
|
||||
@change="(val)=> changeContent(item, val)"
|
||||
@ -215,16 +215,16 @@
|
||||
<el-col :span="5">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.quantity'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<!-- <span><el-input v-model="item.quantity" v-number style="width: 100%;" placeholder="天数" /></span> -->
|
||||
<!-- <span><el-input v-model="item.quantity" v-number style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.days')" /></span> -->
|
||||
|
||||
<el-autocomplete
|
||||
v-model="item.quantity"
|
||||
v-number
|
||||
popper-class="my-autocomplete"
|
||||
:fetch-suggestions="querySearchBadgeRestaurants"
|
||||
placeholder="天数"
|
||||
:placeholder="$t('pages.gameLotteryConfigForm.placeholder.days')"
|
||||
>
|
||||
<template slot-scope="{ item }">
|
||||
<div class="name">{{ item.value }}</div>
|
||||
@ -237,25 +237,25 @@
|
||||
<el-col :span="3">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.inventory'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<span><el-input v-model="item.inventory" v-number style="width: 100%;" placeholder="库存数" /></span>
|
||||
<span><el-input v-model="item.inventory" v-number style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.inventory')" /></span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="form.gameType === 'EGG'" :span="3">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.dataHelp'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<span><el-input v-model="item.dataHelp" v-number style="width: 100%;" placeholder="碎片数" /></span>
|
||||
<span><el-input v-model="item.dataHelp" v-number style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.requiredFragments')" /></span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.probability'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<span><el-input v-model="item.probability" oninput="value=value.replace(/[^0-9.]/g,'')" style="width: 100%;" placeholder="概率(0.1就是10%)" /></span>
|
||||
<span><el-input v-model="item.probability" oninput="value=value.replace(/[^0-9.]/g,'')" style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.probabilityExample')" /></span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
@ -286,11 +286,11 @@
|
||||
<el-col :span="3">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.content'"
|
||||
:rules="{required: true, message: '必填字段不可为空', trigger: 'blur'}"
|
||||
:rules="getRequiredFieldRule()"
|
||||
>
|
||||
<el-select
|
||||
v-model="item.content"
|
||||
placeholder="请选择"
|
||||
:placeholder="$t('pages.gameLotteryConfigForm.placeholder.select')"
|
||||
style="width:100%"
|
||||
filterable
|
||||
@change="(val)=> changeContent(item, val)"
|
||||
@ -309,33 +309,33 @@
|
||||
<el-col :span="3">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.quantity'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<div><el-input v-model="item.quantity" v-number style="width: 100%;" placeholder="数量/天数" /></div>
|
||||
<div><el-input v-model="item.quantity" v-number style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.quantityOrDays')" /></div>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.inventory'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<span><el-input v-model="item.inventory" v-number style="width: 100%;" placeholder="库存数" /></span>
|
||||
<span><el-input v-model="item.inventory" v-number style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.inventory')" /></span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col v-if="form.gameType === 'EGG'" :span="3">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.dataHelp'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<span><el-input v-model="item.dataHelp" v-number style="width: 100%;" placeholder="碎片数" /></span>
|
||||
<span><el-input v-model="item.dataHelp" v-number style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.requiredFragments')" /></span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item
|
||||
:prop="'tmpConfigList.' + index + '.probability'"
|
||||
:rules="{ required: true, message: '不可为空', trigger: 'blur'}"
|
||||
:rules="getNotEmptyRule()"
|
||||
>
|
||||
<span><el-input v-model="item.probability" oninput="value=value.replace(/[^0-9.]/g,'')" style="width: 100%;" placeholder="概率(0.1就是10%)" /></span>
|
||||
<span><el-input v-model="item.probability" oninput="value=value.replace(/[^0-9.]/g,'')" style="width: 100%;" :placeholder="$t('pages.gameLotteryConfigForm.placeholder.probabilityExample')" /></span>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="3">
|
||||
@ -348,34 +348,34 @@
|
||||
|
||||
</div>
|
||||
<div>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['AVATAR_FRAME'].loading" @click="addContent('AVATAR_FRAME')"><i class="el-icon-circle-plus" />头像框</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['RIDE'].loading" @click="addContent('RIDE')"><i class="el-icon-circle-plus" />座驾</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['NOBLE_VIP'].loading" @click="addContent('NOBLE_VIP')"><i class="el-icon-circle-plus" />贵族</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['THEME'].loading" @click="addContent('THEME')"><i class="el-icon-circle-plus" />房间背景主题</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['GIFT'].loading" @click="addContent('GIFT')"><i class="el-icon-circle-plus" />礼物</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" @click="addContent('SPECIAL_ID')"><i class="el-icon-circle-plus" />靓号</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" @click="addContent('GOLD')"><i class="el-icon-circle-plus" />金币</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" @click="addContent('DIAMOND')"><i class="el-icon-circle-plus" />钻石</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" @click="addContent('GAME_COUPON')"><i class="el-icon-circle-plus" />游戏券</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['BADGE'].loading" @click="addContent('BADGE')"><i class="el-icon-circle-plus" />用户徽章</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['ROOM_BADGE'].loading" @click="addContent('ROOM_BADGE')"><i class="el-icon-circle-plus" />房间徽章</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['EMOJI'].loading" @click="addContent('EMOJI')"><i class="el-icon-circle-plus" />表情包</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['FLOAT_PICTURE'].loading" @click="addContent('FLOAT_PICTURE')"><i class="el-icon-circle-plus" />飘窗</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['CHAT_BUBBLE'].loading" @click="addContent('CHAT_BUBBLE')"><i class="el-icon-circle-plus" />聊天气泡</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['FRAGMENTS'].loading" @click="addContent('FRAGMENTS')"><i class="el-icon-circle-plus" />碎片</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['AVATAR_FRAME'].loading" @click="addContent('AVATAR_FRAME')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('AVATAR_FRAME') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['RIDE'].loading" @click="addContent('RIDE')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('RIDE') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['NOBLE_VIP'].loading" @click="addContent('NOBLE_VIP')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('NOBLE_VIP') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['THEME'].loading" @click="addContent('THEME')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('THEME') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['GIFT'].loading" @click="addContent('GIFT')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('GIFT') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" @click="addContent('SPECIAL_ID')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('SPECIAL_ID') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" @click="addContent('GOLD')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('GOLD') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" @click="addContent('DIAMOND')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('DIAMOND') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" @click="addContent('GAME_COUPON')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('GAME_COUPON') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['BADGE'].loading" @click="addContent('BADGE')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('BADGE') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['ROOM_BADGE'].loading" @click="addContent('ROOM_BADGE')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('ROOM_BADGE') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['EMOJI'].loading" @click="addContent('EMOJI')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('EMOJI') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['FLOAT_PICTURE'].loading" @click="addContent('FLOAT_PICTURE')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('FLOAT_PICTURE') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['CHAT_BUBBLE'].loading" @click="addContent('CHAT_BUBBLE')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('CHAT_BUBBLE') }}</el-button>
|
||||
<el-button type="text" :disabled="disableAddContent" :loading="propsTypeData['FRAGMENTS'].loading" @click="addContent('FRAGMENTS')"><i class="el-icon-circle-plus" />{{ getAddButtonLabel('FRAGMENTS') }}</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<span v-if="1 - sumProbability > 0">概率还差 <span style="color:red;">{{ (1 - sumProbability).toFixed(3) }}</span> 凑满1; <span style="color: #b3b1b1;">完整概率为"1",小数最多三位数!</span></span>
|
||||
<span v-else-if="1 == sumProbability" style="color:#38c95e;">概率已拼凑完整; </span>
|
||||
<span v-else style="color:#ebbe40;">概率已超过{{ (sumProbability - 1).toFixed(3) }},请调整! <span style="color: #b3b1b1;">完整概率为"1",小数最多三位数!</span></span>
|
||||
<span v-if="1 - sumProbability > 0">{{ $t('pages.gameLotteryConfigForm.message.probabilityRemaining', { value: (1 - sumProbability).toFixed(3) }) }} <span style="color: #b3b1b1;">{{ $t('pages.gameLotteryConfigForm.message.totalProbabilityHint') }}</span></span>
|
||||
<span v-else-if="1 == sumProbability" style="color:#38c95e;">{{ $t('pages.gameLotteryConfigForm.message.probabilityComplete') }} </span>
|
||||
<span v-else style="color:#ebbe40;">{{ $t('pages.gameLotteryConfigForm.message.probabilityExceeded', { value: (sumProbability - 1).toFixed(3) }) }} <span style="color: #b3b1b1;">{{ $t('pages.gameLotteryConfigForm.message.totalProbabilityHint') }}</span></span>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div slot="footer">
|
||||
<el-button @click="handleClose()">取消</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="submitForm()">保存</el-button>
|
||||
<el-button @click="handleClose()">{{ $t('pages.gameLotteryConfigForm.action.cancel') }}</el-button>
|
||||
<el-button type="primary" :loading="submitLoading" @click="submitForm()">{{ $t('pages.gameLotteryConfigForm.action.save') }}</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
@ -406,7 +406,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
const commonRules = [
|
||||
{ required: true, message: '必填字段不可为空', trigger: 'blur' }
|
||||
{ required: true, message: this.$t('pages.propsSourceGroupForm.validation.requiredField'), trigger: 'blur' }
|
||||
]
|
||||
return {
|
||||
specialIdTypes,
|
||||
@ -468,68 +468,6 @@ export default {
|
||||
list: []
|
||||
}
|
||||
},
|
||||
propsTypeMap: {
|
||||
'EMOJI': {
|
||||
value: 'EMOJI',
|
||||
name: '用户-表情包'
|
||||
},
|
||||
'BADGE': {
|
||||
value: 'BADGE',
|
||||
name: '用户-徽章'
|
||||
},
|
||||
'ROOM_BADGE': {
|
||||
value: 'BADGE',
|
||||
name: '房间-徽章'
|
||||
},
|
||||
'AVATAR_FRAME': {
|
||||
value: 'PROPS',
|
||||
name: '头像框'
|
||||
},
|
||||
'CHAT_BUBBLE': {
|
||||
value: 'PROPS',
|
||||
name: '聊天气泡'
|
||||
},
|
||||
'FRAGMENTS': {
|
||||
value: 'PROPS',
|
||||
name: '碎片'
|
||||
},
|
||||
'RIDE': {
|
||||
value: 'PROPS',
|
||||
name: '座驾'
|
||||
},
|
||||
'NOBLE_VIP': {
|
||||
value: 'PROPS',
|
||||
name: '贵族'
|
||||
},
|
||||
'GIFT': {
|
||||
value: 'GIFT',
|
||||
name: '礼物'
|
||||
},
|
||||
'GOLD': {
|
||||
value: 'GOLD',
|
||||
name: '金币'
|
||||
},
|
||||
'DIAMOND': {
|
||||
value: 'DIAMOND',
|
||||
name: '钻石'
|
||||
},
|
||||
'SPECIAL_ID': {
|
||||
value: 'SPECIAL_ID',
|
||||
name: '靓号'
|
||||
},
|
||||
'THEME': {
|
||||
value: 'PROPS',
|
||||
name: '房间背景主题'
|
||||
},
|
||||
'GAME_COUPON': {
|
||||
value: 'GAME_COUPON',
|
||||
name: '游戏券'
|
||||
},
|
||||
'FLOAT_PICTURE': {
|
||||
value: 'PROPS',
|
||||
name: '飘窗'
|
||||
}
|
||||
},
|
||||
isChangeSource: false,
|
||||
propsValidDays,
|
||||
propsCurrencyType,
|
||||
@ -558,11 +496,15 @@ export default {
|
||||
sourceTypeList: [],
|
||||
selectType: {},
|
||||
isLoadSourceTypeList: false,
|
||||
listTypeLoading: false,
|
||||
badgeRestaurants: [{ 'value': '0', 'label': '永久' }]
|
||||
listTypeLoading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
badgeRestaurants() {
|
||||
const locale = this.$i18n.locale
|
||||
void locale
|
||||
return [{ value: '0', label: this.$t('pages.gameLotteryConfigForm.word.permanent') }]
|
||||
},
|
||||
rowCover() {
|
||||
return this.row ? this.row.propsSourceRecordDTO.cover : ''
|
||||
},
|
||||
@ -576,7 +518,10 @@ export default {
|
||||
return !this.form.sourceUrl
|
||||
},
|
||||
textOptTitle() {
|
||||
return (this.row && this.row.id ? '修改' : '添加') + '(' + this.sysOrigin + ')'
|
||||
return this.$t('pages.gameLotteryConfigForm.dialog.title', {
|
||||
action: this.isUpdate ? this.$t('pages.gameLotteryConfigForm.action.edit') : this.$t('pages.gameLotteryConfigForm.action.add'),
|
||||
system: this.sysOrigin
|
||||
})
|
||||
},
|
||||
isUpdate() {
|
||||
return this.row && this.row.id
|
||||
@ -631,9 +576,60 @@ export default {
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getRequiredFieldRule() {
|
||||
return { required: true, message: this.$t('pages.propsSourceGroupForm.validation.requiredField'), trigger: 'blur' }
|
||||
},
|
||||
getNotEmptyRule() {
|
||||
return { required: true, message: this.$t('pages.propsSourceGroupForm.validation.notEmpty'), trigger: 'blur' }
|
||||
},
|
||||
getLotteryGameTypeLabel(item) {
|
||||
if (!item) {
|
||||
return ''
|
||||
}
|
||||
if (item.value === 'EGG') {
|
||||
return this.$t('pages.gameLotteryConfigForm.gameType.egg')
|
||||
}
|
||||
return item.name
|
||||
},
|
||||
getPropsTypeValue(type) {
|
||||
if (type === 'EMOJI') {
|
||||
return 'EMOJI'
|
||||
}
|
||||
if (type === 'BADGE' || type === 'ROOM_BADGE') {
|
||||
return 'BADGE'
|
||||
}
|
||||
if (type === 'GIFT' || type === 'GOLD' || type === 'DIAMOND' || type === 'SPECIAL_ID' || type === 'GAME_COUPON') {
|
||||
return type
|
||||
}
|
||||
return 'PROPS'
|
||||
},
|
||||
getResourceTypeName(type) {
|
||||
const keyMap = {
|
||||
AVATAR_FRAME: 'avatarFrame',
|
||||
RIDE: 'ride',
|
||||
NOBLE_VIP: 'nobleVip',
|
||||
THEME: 'theme',
|
||||
GIFT: 'gift',
|
||||
SPECIAL_ID: 'specialId',
|
||||
GOLD: 'gold',
|
||||
DIAMOND: 'diamond',
|
||||
GAME_COUPON: 'gameCoupon',
|
||||
BADGE: 'userBadge',
|
||||
ROOM_BADGE: 'roomBadge',
|
||||
EMOJI: 'emoji',
|
||||
FLOAT_PICTURE: 'floatPicture',
|
||||
CHAT_BUBBLE: 'chatBubble',
|
||||
FRAGMENTS: 'fragments'
|
||||
}
|
||||
const key = keyMap[type]
|
||||
return key ? this.$t(`pages.propsSourceGroupForm.resourceType.${key}`) : ''
|
||||
},
|
||||
getAddButtonLabel(type) {
|
||||
return this.getResourceTypeName(type)
|
||||
},
|
||||
querySearchBadgeRestaurants(queryString, cb) {
|
||||
var badgeRestaurants = this.badgeRestaurants
|
||||
var results = queryString ? badgeRestaurants.filter(restaurant => {
|
||||
const badgeRestaurants = this.badgeRestaurants
|
||||
const results = queryString ? badgeRestaurants.filter(restaurant => {
|
||||
return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0)
|
||||
}) : badgeRestaurants
|
||||
cb(results)
|
||||
@ -686,11 +682,7 @@ export default {
|
||||
})
|
||||
},
|
||||
getTypeName(item) {
|
||||
const typeData = this.propsTypeMap[item.detailType]
|
||||
if (typeData) {
|
||||
return typeData.name
|
||||
}
|
||||
return ''
|
||||
return this.getResourceTypeName(item.detailType)
|
||||
},
|
||||
deleteUpdateItem(index) {
|
||||
this.form.rewardConfigList.splice(index, 1)
|
||||
@ -856,7 +848,7 @@ export default {
|
||||
addContentData(type) {
|
||||
const that = this
|
||||
that.form.tmpConfigList.push({
|
||||
type: that.propsTypeMap[type].value,
|
||||
type: that.getPropsTypeValue(type),
|
||||
clickType: type,
|
||||
content: '',
|
||||
quantity: '',
|
||||
@ -864,7 +856,7 @@ export default {
|
||||
inventory: '',
|
||||
dataHelp: '',
|
||||
ext: {
|
||||
title: that.propsTypeMap[type].name,
|
||||
title: that.getResourceTypeName(type),
|
||||
selectVal: { id: '', cover: '', sourceUrl: '' }
|
||||
}
|
||||
})
|
||||
@ -923,13 +915,13 @@ export default {
|
||||
return
|
||||
}
|
||||
if (!that.form.rewardConfigList || that.form.rewardConfigList.length < 1) {
|
||||
that.$opsMessage.fail('请资源组配置内容.')
|
||||
that.$opsMessage.fail(that.$t('pages.gameLotteryConfigForm.message.configRequired'))
|
||||
return
|
||||
}
|
||||
that.submitLoading = true
|
||||
const form = deepClone(that.form)
|
||||
form.rewardConfigList = []
|
||||
// 校验总概率是否为1
|
||||
// The combined probability must equal 1 before submit.
|
||||
that.sumProbability = 0.000
|
||||
that.form.rewardConfigList.forEach((item, index) => {
|
||||
form.rewardConfigList.push({
|
||||
@ -946,7 +938,7 @@ export default {
|
||||
})
|
||||
if (that.sumProbability.toFixed(3) > 1 || that.sumProbability.toFixed(3) < 1) {
|
||||
that.submitLoading = false
|
||||
that.$opsMessage.fail('总概率不等于‘ 1 ’,请参考底部提示!')
|
||||
that.$opsMessage.fail(that.$t('pages.gameLotteryConfigForm.message.totalProbabilityInvalid'))
|
||||
return
|
||||
}
|
||||
saveOrUpdateGameLotteryGroup(form).then(res => {
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<div class="filter-container">
|
||||
<el-select
|
||||
v-model="listQuery.sysOrigin"
|
||||
placeholder="归属系统"
|
||||
:placeholder="$t('pages.gameLotteryConfig.placeholder.system')"
|
||||
style="width: 120px"
|
||||
class="filter-item"
|
||||
@change="handleSearch"
|
||||
@ -40,13 +40,13 @@
|
||||
/>
|
||||
<el-select
|
||||
v-model="listQuery.gameType"
|
||||
placeholder="游戏类型"
|
||||
:placeholder="$t('pages.gameLotteryConfig.placeholder.gameType')"
|
||||
style="width: 120px"
|
||||
class="filter-item"
|
||||
clearable
|
||||
@change="handleSearch"
|
||||
>
|
||||
<el-option v-for="item in lotteryGameTypes" :key="item.value" :label="item.name" :value="item.value" />
|
||||
<el-option v-for="item in lotteryGameTypes" :key="item.value" :label="getLotteryGameTypeLabel(item)" :value="item.value" />
|
||||
</el-select>
|
||||
<el-button
|
||||
class="filter-item"
|
||||
@ -54,7 +54,7 @@
|
||||
icon="el-icon-search"
|
||||
@click="handleSearch"
|
||||
>
|
||||
搜索
|
||||
{{ $t('pages.gameLotteryConfig.action.search') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="filter-item"
|
||||
@ -62,7 +62,7 @@
|
||||
icon="el-icon-edit"
|
||||
@click="handleCreate"
|
||||
>
|
||||
添加
|
||||
{{ $t('pages.gameLotteryConfig.action.add') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
@ -74,10 +74,10 @@
|
||||
@cell-mouse-enter="handleMouseEnter"
|
||||
>
|
||||
<el-table-column prop="id" width="200" label="ID" align="center" />
|
||||
<el-table-column width="100" prop="gameType" label="类型名称" align="center">
|
||||
<el-table-column width="100" prop="gameType" :label="$t('pages.gameLotteryConfig.table.typeName')" align="center">
|
||||
<template slot-scope="scope">
|
||||
<span v-for="(item, index) in lotteryGameTypes" :key="index">
|
||||
<span v-if="item.value === scope.row.gameType">{{ item.name }}</span>
|
||||
<span v-if="item.value === scope.row.gameType">{{ getLotteryGameTypeLabel(item) }}</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@ -91,20 +91,20 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
<el-table-column label="道具" align="center">
|
||||
<el-table-column :label="$t('pages.gameLotteryConfig.table.props')" align="center">
|
||||
<template slot-scope="scope">
|
||||
<props-row :list="scope.row.rewardConfigList" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="时间" align="center">
|
||||
<el-table-column :label="$t('pages.gameLotteryConfig.table.time')" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div>创建时间:{{ scope.row.createTime | dateFormat }}</div>
|
||||
<div>修改时间:{{ scope.row.updateTime | dateFormat }}</div>
|
||||
<div>{{ $t('pages.gameLotteryConfig.time.createdAt') }}: {{ scope.row.createTime | dateFormat }}</div>
|
||||
<div>{{ $t('pages.gameLotteryConfig.time.updatedAt') }}: {{ scope.row.updateTime | dateFormat }}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column fixed="right" label="操作" align="center" width="150">
|
||||
<el-table-column fixed="right" :label="$t('pages.gameLotteryConfig.table.actions')" align="center" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click.native="handleUpdate(scope.row)">编辑</el-button>
|
||||
<el-button type="text" @click.native="handleUpdate(scope.row)">{{ $t('pages.gameLotteryConfig.action.edit') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -142,10 +142,6 @@ export default {
|
||||
editSysOrigin: '',
|
||||
sysOriginPlatforms,
|
||||
lotteryGameTypes,
|
||||
showcaseTypes: [
|
||||
{ value: false, name: '下架' },
|
||||
{ value: true, name: '上架' }
|
||||
],
|
||||
formEditVisable: false,
|
||||
thisRow: {},
|
||||
thatSelectedUserId: {},
|
||||
@ -164,7 +160,13 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permissionsSysOriginPlatforms'])
|
||||
...mapGetters(['permissionsSysOriginPlatforms']),
|
||||
showcaseTypes() {
|
||||
return [
|
||||
{ value: false, name: this.$t('pages.propsSourceGroupForm.word.offShelf') },
|
||||
{ value: true, name: this.$t('pages.propsSourceGroupForm.word.onShelf') }
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
const that = this
|
||||
@ -176,6 +178,15 @@ export default {
|
||||
that.renderData()
|
||||
},
|
||||
methods: {
|
||||
getLotteryGameTypeLabel(item) {
|
||||
if (!item) {
|
||||
return ''
|
||||
}
|
||||
if (item.value === 'EGG') {
|
||||
return this.$t('pages.gameLotteryConfigForm.gameType.egg')
|
||||
}
|
||||
return item.name
|
||||
},
|
||||
renderData(isClean) {
|
||||
const that = this
|
||||
that.listLoading = true
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
<el-popover
|
||||
placement="bottom"
|
||||
title="选中道具"
|
||||
:title="$t('pages.gameLotteryConfigForm.popover.selectedProps')"
|
||||
width="500"
|
||||
trigger="click"
|
||||
>
|
||||
@ -29,12 +29,12 @@
|
||||
</div>
|
||||
<div class="opetion">
|
||||
<el-form ref="form" :model="form" :rules="formRules" label-width="110px" style="margin:30px; 50px 0px 0px">
|
||||
<el-form-item label="类型名称" prop="name">
|
||||
<el-form-item :label="$t('pages.gameLotteryConfigForm.label.typeName')" prop="name">
|
||||
<el-input v-model.trim="form.name" type="text" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<el-button slot="reference">click</el-button>
|
||||
<el-button slot="reference">{{ $t('pages.gameLotteryConfigForm.action.select') }}</el-button>
|
||||
</el-popover>
|
||||
|
||||
</template>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-dialog
|
||||
title="抽奖奖励配置列表"
|
||||
:title="$t('pages.luckyBoxAwardConfig.dialog.detailsListTitle')"
|
||||
:visible.sync="isDialog"
|
||||
:before-close="handleClose"
|
||||
:close-on-click-modal="false"
|
||||
@ -17,7 +17,7 @@
|
||||
:disabled="isAdd"
|
||||
@click="handleAdd"
|
||||
>
|
||||
添加
|
||||
{{ $t('pages.luckyBoxAwardConfig.action.add') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
@ -28,9 +28,13 @@
|
||||
highlight-current-row
|
||||
>
|
||||
<el-table-column type="index" width="50" label="No" />
|
||||
<el-table-column prop="sysOrigin" label="平台" align="center" width="280" />
|
||||
<el-table-column prop="propsType" width="280" label="类型" align="center" />
|
||||
<el-table-column label="资源" width="280" align="center">
|
||||
<el-table-column prop="sysOrigin" :label="$t('pages.luckyBoxAwardConfig.table.platform')" align="center" width="280" />
|
||||
<el-table-column width="280" :label="$t('pages.luckyBoxAwardConfig.table.type')" align="center">
|
||||
<template slot-scope="scope">
|
||||
{{ getPropsTypeLabel(scope.row.propsType) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('pages.luckyBoxAwardConfig.table.resource')" width="280" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div class="preview-img">
|
||||
<el-image
|
||||
@ -47,23 +51,23 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="lotteryNumber" label="目标次数" align="center" width="280" />
|
||||
<el-table-column prop="validDays" label="有效天数" align="center" width="280" />
|
||||
<el-table-column prop="createTime" label="创建时间" align="center" width="300">
|
||||
<el-table-column prop="lotteryNumber" :label="$t('pages.luckyBoxAwardConfig.table.targetCount')" align="center" width="280" />
|
||||
<el-table-column prop="validDays" :label="$t('pages.luckyBoxAwardConfig.table.validDays')" align="center" width="280" />
|
||||
<el-table-column prop="createTime" :label="$t('pages.luckyBoxAwardConfig.table.createdAt')" align="center" width="300">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.createTime | dateFormat }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column fixed="right" label="操作" align="center">
|
||||
<el-table-column fixed="right" :label="$t('pages.luckyBoxAwardConfig.table.actions')" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click.native="hanldeEidt(scope.row)">编辑</el-button>
|
||||
<el-button type="text" @click.native="hanldeEidt(scope.row)">{{ $t('pages.luckyBoxAwardConfig.action.edit') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div>
|
||||
<el-dialog
|
||||
title="道具配置"
|
||||
:title="$t('pages.luckyBoxAwardConfig.dialog.detailsFormTitle')"
|
||||
:visible.sync="innerEditVisible"
|
||||
width="550px"
|
||||
top="50px"
|
||||
@ -74,14 +78,14 @@
|
||||
<div style="height: 500px;overflow: auto;">
|
||||
<el-form
|
||||
ref="dataForm"
|
||||
:rules="formRules"
|
||||
:rules="dialogFormRules"
|
||||
:model="formData"
|
||||
style="width: 400px; margin-left:50px;"
|
||||
>
|
||||
<el-form-item label="系统" prop="sysOrigin">
|
||||
<el-form-item :label="$t('pages.luckyBoxAwardConfig.form.system')" prop="sysOrigin">
|
||||
<el-select
|
||||
v-model="formData.sysOrigin"
|
||||
placeholder="选择系统"
|
||||
:placeholder="$t('pages.luckyBoxAwardConfig.placeholder.selectSystem')"
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
@change="changeSysOrigin"
|
||||
@ -97,18 +101,23 @@
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择类型" prop="propsType">
|
||||
<el-form-item :label="$t('pages.luckyBoxAwardConfig.form.propsType')" prop="propsType">
|
||||
<el-select
|
||||
v-model="formData.propsType"
|
||||
placeholder="类型"
|
||||
:placeholder="$t('pages.luckyBoxAwardConfig.placeholder.propsType')"
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
@change="changePropsType"
|
||||
>
|
||||
<el-option v-for="item in propsTypes" :key="item.value" :label="item.name" :value="item.value" />
|
||||
<el-option
|
||||
v-for="item in localizedPropsTypes"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择资源" prop="propsId">
|
||||
<el-form-item :label="$t('pages.luckyBoxAwardConfig.form.propsId')" prop="propsId">
|
||||
<div v-if="selectProps.cover" class="payer-source">
|
||||
<div class="paler-icon">
|
||||
<svgaplayer
|
||||
@ -127,24 +136,24 @@
|
||||
@select="selectPropsSourcePopover"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="目标次数" prop="lotteryNumber">
|
||||
<el-input v-model="formData.lotteryNumber" v-number placeholder="目标次数" />
|
||||
<el-form-item :label="$t('pages.luckyBoxAwardConfig.form.targetCount')" prop="lotteryNumber">
|
||||
<el-input v-model="formData.lotteryNumber" v-number :placeholder="$t('pages.luckyBoxAwardConfig.placeholder.targetCount')" />
|
||||
</el-form-item>
|
||||
<el-form-item label="有效天数" prop="validDays">
|
||||
<el-input v-model="formData.validDays" v-number placeholder="有效天数" />
|
||||
<el-form-item :label="$t('pages.luckyBoxAwardConfig.form.validDays')" prop="validDays">
|
||||
<el-input v-model="formData.validDays" v-number :placeholder="$t('pages.luckyBoxAwardConfig.placeholder.validDays')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="innerEditVisible = false">
|
||||
取消
|
||||
{{ $t('common.cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:loading="submitLoading"
|
||||
type="primary"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
提交
|
||||
{{ $t('common.submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
@ -173,9 +182,6 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const commonRules = [
|
||||
{ required: true, message: '必填字段不可为空', trigger: 'blur' }
|
||||
]
|
||||
const propsTypeMap = {}
|
||||
propsTypes.forEach(item => {
|
||||
propsTypeMap[item.value] = {
|
||||
@ -212,19 +218,29 @@ export default {
|
||||
validDays: '',
|
||||
sysOrigin: 'HALAR'
|
||||
},
|
||||
formRules: {
|
||||
propsType: commonRules,
|
||||
propsId: commonRules,
|
||||
lotteryNumber: commonRules,
|
||||
validDays: commonRules,
|
||||
sysOrigin: commonRules
|
||||
},
|
||||
submitLoading: false,
|
||||
isAdd: true,
|
||||
listLoading: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
localizedPropsTypes() {
|
||||
return this.propsTypes.map(item => ({
|
||||
...item,
|
||||
name: this.getPropsTypeLabel(item.value)
|
||||
}))
|
||||
},
|
||||
dialogFormRules() {
|
||||
const requiredMessage = this.$t('pages.luckyBoxAwardConfig.validation.requiredField')
|
||||
const commonRules = [{ required: true, message: requiredMessage, trigger: 'blur' }]
|
||||
return {
|
||||
propsType: commonRules,
|
||||
propsId: commonRules,
|
||||
lotteryNumber: commonRules,
|
||||
validDays: commonRules,
|
||||
sysOrigin: commonRules
|
||||
}
|
||||
},
|
||||
...mapGetters(['permissionsSysOriginPlatforms'])
|
||||
},
|
||||
watch: {
|
||||
@ -253,6 +269,9 @@ export default {
|
||||
this.propsTypes = this.propsTypes.filter(item => !(item.value === 'CUSTOMIZE' || item.value === 'FRAGMENTS'))
|
||||
},
|
||||
methods: {
|
||||
getPropsTypeLabel(type) {
|
||||
return this.$t(`pages.luckyBoxAwardConfig.propsType.${type}`)
|
||||
},
|
||||
changeSysOrigin(val) {
|
||||
const that = this
|
||||
that.formData.propsType = ''
|
||||
|
||||
@ -12,14 +12,14 @@
|
||||
<div style="height: 500px;overflow: auto;">
|
||||
<el-form
|
||||
ref="dataForm"
|
||||
:rules="rules"
|
||||
:rules="formRules"
|
||||
:model="formData"
|
||||
style="width: 400px; margin-left:50px;"
|
||||
>
|
||||
<el-form-item label="系统" prop="sysOrigin">
|
||||
<el-form-item :label="$t('pages.luckyBoxAwardConfig.form.system')" prop="sysOrigin">
|
||||
<el-select
|
||||
v-model="formData.sysOrigin"
|
||||
placeholder="选择系统"
|
||||
:placeholder="$t('pages.luckyBoxAwardConfig.placeholder.selectSystem')"
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
>
|
||||
@ -34,33 +34,33 @@
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="关联类型" prop="lotteryType">
|
||||
<el-form-item :label="$t('pages.luckyBoxAwardConfig.form.lotteryType')" prop="lotteryType">
|
||||
<el-select
|
||||
v-model="formData.lotteryType"
|
||||
placeholder="类型"
|
||||
:placeholder="$t('pages.luckyBoxAwardConfig.placeholder.type')"
|
||||
clearable
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
>
|
||||
<el-option label="经典" :value="'CLASSICS'" />
|
||||
<el-option label="星座" :value="'CONSTELLATION'" />
|
||||
<el-option :label="$t('pages.luckyBoxAwardConfig.lotteryType.CLASSICS')" :value="'CLASSICS'" />
|
||||
<el-option :label="$t('pages.luckyBoxAwardConfig.lotteryType.CONSTELLATION')" :value="'CONSTELLATION'" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model.trim="formData.name" type="text" placeholder="名称" />
|
||||
<el-form-item :label="$t('pages.luckyBoxAwardConfig.form.name')" prop="name">
|
||||
<el-input v-model.trim="formData.name" type="text" :placeholder="$t('pages.luckyBoxAwardConfig.placeholder.name')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="handleClose">
|
||||
取消
|
||||
{{ $t('common.cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:loading="submitLoading"
|
||||
type="primary"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
提交
|
||||
{{ $t('common.submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
@ -90,11 +90,6 @@ export default {
|
||||
name: '',
|
||||
lotteryType: ''
|
||||
},
|
||||
rules: {
|
||||
sysOrigin: [{ required: true, message: '必填项不可为空', trigger: 'blur' }],
|
||||
name: [{ required: true, message: '必填项不可为空', trigger: 'blur' }],
|
||||
lotteryType: [{ required: true, message: '必填项不可为空', trigger: 'blur' }]
|
||||
},
|
||||
submitLoading: false
|
||||
}
|
||||
},
|
||||
@ -103,7 +98,19 @@ export default {
|
||||
return this.updateData === null
|
||||
},
|
||||
title() {
|
||||
return this.isAdd ? `添加(${this.sysOrigin})` : `修改(${this.updateData.sysOrigin})`
|
||||
const system = this.isAdd ? this.sysOrigin : this.updateData.sysOrigin
|
||||
const action = this.isAdd
|
||||
? this.$t('pages.luckyBoxAwardConfig.action.add')
|
||||
: this.$t('pages.luckyBoxAwardConfig.action.edit')
|
||||
return this.$t('pages.luckyBoxAwardConfig.dialog.formTitle', { action, system })
|
||||
},
|
||||
formRules() {
|
||||
const requiredMessage = this.$t('pages.luckyBoxAwardConfig.validation.requiredField')
|
||||
return {
|
||||
sysOrigin: [{ required: true, message: requiredMessage, trigger: 'blur' }],
|
||||
name: [{ required: true, message: requiredMessage, trigger: 'blur' }],
|
||||
lotteryType: [{ required: true, message: requiredMessage, trigger: 'blur' }]
|
||||
}
|
||||
},
|
||||
...mapGetters(['permissionsSysOriginPlatforms'])
|
||||
},
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<div class="filter-container">
|
||||
<el-select
|
||||
v-model="listQuery.sysOrigin"
|
||||
placeholder="系统"
|
||||
:placeholder="$t('pages.luckyBoxAwardConfig.filter.system')"
|
||||
style="width: 120px"
|
||||
class="filter-item"
|
||||
@change="handleSearch"
|
||||
@ -21,14 +21,14 @@
|
||||
</el-select>
|
||||
<el-select
|
||||
v-model="listQuery.lotteryType"
|
||||
placeholder="关联类型"
|
||||
:placeholder="$t('pages.luckyBoxAwardConfig.filter.lotteryType')"
|
||||
style="width:120px;"
|
||||
class="filter-item"
|
||||
clearable
|
||||
@change="handleSearch"
|
||||
>
|
||||
<el-option label="经典" :value="'CLASSICS'" />
|
||||
<el-option label="星座" :value="'CONSTELLATION'" />
|
||||
<el-option :label="$t('pages.luckyBoxAwardConfig.lotteryType.CLASSICS')" :value="'CLASSICS'" />
|
||||
<el-option :label="$t('pages.luckyBoxAwardConfig.lotteryType.CONSTELLATION')" :value="'CONSTELLATION'" />
|
||||
</el-select>
|
||||
<el-button
|
||||
:loading="searchLoading"
|
||||
@ -37,7 +37,7 @@
|
||||
icon="el-icon-search"
|
||||
@click="handleSearch"
|
||||
>
|
||||
搜索
|
||||
{{ $t('common.search') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="filter-item"
|
||||
@ -46,7 +46,7 @@
|
||||
icon="el-icon-edit"
|
||||
@click="handleAdd"
|
||||
>
|
||||
添加
|
||||
{{ $t('pages.luckyBoxAwardConfig.action.add') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
@ -56,26 +56,26 @@
|
||||
fit
|
||||
highlight-current-row
|
||||
>
|
||||
<el-table-column prop="sysOrigin" label="平台" align="center" />
|
||||
<el-table-column label="类型" align="center">
|
||||
<el-table-column prop="sysOrigin" :label="$t('pages.luckyBoxAwardConfig.table.platform')" align="center" />
|
||||
<el-table-column :label="$t('pages.luckyBoxAwardConfig.table.type')" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div>
|
||||
<el-tag v-if="scope.row.lotteryType === 'CLASSICS'">经典</el-tag>
|
||||
<el-tag v-else-if="scope.row.lotteryType === 'CONSTELLATION'">星座</el-tag>
|
||||
<el-tag v-if="scope.row.lotteryType === 'CLASSICS'">{{ $t('pages.luckyBoxAwardConfig.lotteryType.CLASSICS') }}</el-tag>
|
||||
<el-tag v-else-if="scope.row.lotteryType === 'CONSTELLATION'">{{ $t('pages.luckyBoxAwardConfig.lotteryType.CONSTELLATION') }}</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="name" label="名称" align="center" width="200" />
|
||||
<el-table-column prop="createTime" label="创建时间" align="center" width="200">
|
||||
<el-table-column prop="name" :label="$t('pages.luckyBoxAwardConfig.table.name')" align="center" width="200" />
|
||||
<el-table-column prop="createTime" :label="$t('pages.luckyBoxAwardConfig.table.createdAt')" align="center" width="200">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.createTime | dateFormat }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column fixed="right" label="操作" align="center" width="380">
|
||||
<el-table-column fixed="right" :label="$t('pages.luckyBoxAwardConfig.table.actions')" align="center" width="380">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click.native="hanldeEidt(scope.row)">编辑</el-button>
|
||||
<el-button type="text" @click.native="handleAwardConfigList(scope.row)">奖励配置</el-button>
|
||||
<el-button type="text" @click.native="handlDel(scope.row)">删除</el-button>
|
||||
<el-button type="text" @click.native="hanldeEidt(scope.row)">{{ $t('pages.luckyBoxAwardConfig.action.edit') }}</el-button>
|
||||
<el-button type="text" @click.native="handleAwardConfigList(scope.row)">{{ $t('pages.luckyBoxAwardConfig.action.rewardConfig') }}</el-button>
|
||||
<el-button type="text" @click.native="handlDel(scope.row)">{{ $t('pages.luckyBoxAwardConfig.action.delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -187,14 +187,14 @@ export default {
|
||||
},
|
||||
// 删除
|
||||
handlDel(row) {
|
||||
this.$confirm('确认删除吗?', '提示', {
|
||||
this.$confirm(this.$t('pages.luckyBoxAwardConfig.confirm.deleteMessage'), this.$t('pages.luckyBoxAwardConfig.confirm.title'), {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.listLoading = true
|
||||
deleteAwardConfig(row.id).then((res) => {
|
||||
this.listLoading = false
|
||||
this.$message({
|
||||
message: '删除成功',
|
||||
message: this.$t('pages.luckyBoxAwardConfig.message.deleteSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
this.renderData()
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-dialog
|
||||
title="道具配置列表"
|
||||
:title="$t('pages.luckyBoxBountyConfig.dialog.detailsListTitle')"
|
||||
:visible.sync="isDialog"
|
||||
:before-close="handleClose"
|
||||
:close-on-click-modal="false"
|
||||
@ -16,7 +16,7 @@
|
||||
icon="el-icon-edit"
|
||||
@click="handleAdd"
|
||||
>
|
||||
添加
|
||||
{{ $t('pages.luckyBoxBountyConfig.action.add') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
@ -26,8 +26,8 @@
|
||||
fit
|
||||
highlight-current-row
|
||||
>
|
||||
<el-table-column prop="sysOrigin" label="平台" align="center" width="280" />
|
||||
<el-table-column label="资源" width="280" align="center">
|
||||
<el-table-column prop="sysOrigin" :label="$t('pages.luckyBoxBountyConfig.table.platform')" align="center" width="280" />
|
||||
<el-table-column :label="$t('pages.luckyBoxBountyConfig.table.resource')" width="280" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div class="preview-img">
|
||||
<el-image
|
||||
@ -44,23 +44,23 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="targetQuantity" label="目标数量" align="center" width="280" />
|
||||
<el-table-column prop="validDays" label="有效天数" align="center" width="280" />
|
||||
<el-table-column prop="createTime" label="创建时间" align="center" width="300">
|
||||
<el-table-column prop="targetQuantity" :label="$t('pages.luckyBoxBountyConfig.table.targetQuantity')" align="center" width="280" />
|
||||
<el-table-column prop="validDays" :label="$t('pages.luckyBoxBountyConfig.table.validDays')" align="center" width="280" />
|
||||
<el-table-column prop="createTime" :label="$t('pages.luckyBoxBountyConfig.table.createdAt')" align="center" width="300">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.createTime | dateFormat }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column fixed="right" label="操作" align="center">
|
||||
<el-table-column fixed="right" :label="$t('pages.luckyBoxBountyConfig.table.actions')" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click.native="hanldeDelete(scope.row)">删除</el-button>
|
||||
<el-button type="text" @click.native="hanldeDelete(scope.row)">{{ $t('pages.luckyBoxBountyConfig.action.delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div>
|
||||
<el-dialog
|
||||
title="道具配置"
|
||||
:title="$t('pages.luckyBoxBountyConfig.dialog.detailsFormTitle')"
|
||||
:visible.sync="innerEditVisible"
|
||||
width="550px"
|
||||
top="50px"
|
||||
@ -71,14 +71,14 @@
|
||||
<div style="height: 500px;overflow: auto;">
|
||||
<el-form
|
||||
ref="dataForm"
|
||||
:rules="formRules"
|
||||
:rules="dialogFormRules"
|
||||
:model="formData"
|
||||
style="width: 400px; margin-left:50px;"
|
||||
>
|
||||
<el-form-item label="系统" prop="sysOrigin">
|
||||
<el-form-item :label="$t('pages.luckyBoxBountyConfig.form.system')" prop="sysOrigin">
|
||||
<el-select
|
||||
v-model="formData.sysOrigin"
|
||||
placeholder="选择系统"
|
||||
:placeholder="$t('pages.luckyBoxBountyConfig.placeholder.selectSystem')"
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
@change="changeSysOrigin"
|
||||
@ -94,18 +94,18 @@
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择类型" prop="propsType">
|
||||
<el-form-item :label="$t('pages.luckyBoxBountyConfig.form.propsType')" prop="propsType">
|
||||
<el-select
|
||||
v-model="formData.propsType"
|
||||
placeholder="类型"
|
||||
:placeholder="$t('pages.luckyBoxBountyConfig.placeholder.propsType')"
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
@change="changePropsType"
|
||||
>
|
||||
<el-option v-for="item in propsTypes" :key="item.value" :label="item.name" :value="item.value" />
|
||||
<el-option v-for="item in localizedPropsTypes" :key="item.value" :label="item.name" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="选择资源" prop="propsId">
|
||||
<el-form-item :label="$t('pages.luckyBoxBountyConfig.form.propsId')" prop="propsId">
|
||||
<div v-if="selectProps.cover" class="payer-source">
|
||||
<div class="paler-icon">
|
||||
<svgaplayer
|
||||
@ -124,24 +124,24 @@
|
||||
@select="selectPropsSourcePopover"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="目标数量" prop="targetQuantity">
|
||||
<el-input v-model="formData.targetQuantity" v-number placeholder="目标数量" />
|
||||
<el-form-item :label="$t('pages.luckyBoxBountyConfig.form.targetQuantity')" prop="targetQuantity">
|
||||
<el-input v-model="formData.targetQuantity" v-number :placeholder="$t('pages.luckyBoxBountyConfig.placeholder.targetQuantity')" />
|
||||
</el-form-item>
|
||||
<el-form-item label="有效天数" prop="validDays">
|
||||
<el-input v-model="formData.validDays" v-number placeholder="有效天数" />
|
||||
<el-form-item :label="$t('pages.luckyBoxBountyConfig.form.validDays')" prop="validDays">
|
||||
<el-input v-model="formData.validDays" v-number :placeholder="$t('pages.luckyBoxBountyConfig.placeholder.validDays')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="innerEditVisible = false">
|
||||
取消
|
||||
{{ $t('common.cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:loading="submitLoading"
|
||||
type="primary"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
提交
|
||||
{{ $t('common.submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
@ -166,9 +166,6 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const commonRules = [
|
||||
{ required: true, message: '必填字段不可为空', trigger: 'blur' }
|
||||
]
|
||||
const propsTypeMap = {}
|
||||
propsTypes.forEach(item => {
|
||||
propsTypeMap[item.value] = {
|
||||
@ -205,18 +202,28 @@ export default {
|
||||
validDays: '',
|
||||
sysOrigin: 'HALAR'
|
||||
},
|
||||
formRules: {
|
||||
propsType: commonRules,
|
||||
propsId: commonRules,
|
||||
targetQuantity: commonRules,
|
||||
validDays: commonRules,
|
||||
sysOrigin: commonRules
|
||||
},
|
||||
submitLoading: false,
|
||||
listLoading: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
dialogFormRules() {
|
||||
const requiredMessage = this.$t('pages.luckyBoxBountyConfig.validation.requiredField')
|
||||
const commonRules = [{ required: true, message: requiredMessage, trigger: 'blur' }]
|
||||
return {
|
||||
propsType: commonRules,
|
||||
propsId: commonRules,
|
||||
targetQuantity: commonRules,
|
||||
validDays: commonRules,
|
||||
sysOrigin: commonRules
|
||||
}
|
||||
},
|
||||
localizedPropsTypes() {
|
||||
return this.propsTypes.map(item => ({
|
||||
...item,
|
||||
name: this.getPropsTypeLabel(item.value)
|
||||
}))
|
||||
},
|
||||
...mapGetters(['permissionsSysOriginPlatforms'])
|
||||
},
|
||||
watch: {
|
||||
@ -237,6 +244,9 @@ export default {
|
||||
this.propsTypes = this.propsTypes.filter(item => !(item.value === 'CUSTOMIZE' || item.value === 'FRAGMENTS'))
|
||||
},
|
||||
methods: {
|
||||
getPropsTypeLabel(type) {
|
||||
return this.$t(`pages.luckyBoxBountyConfig.propsType.${type}`)
|
||||
},
|
||||
changeSysOrigin(val) {
|
||||
const that = this
|
||||
that.formData.propsType = ''
|
||||
@ -282,16 +292,15 @@ export default {
|
||||
this.formData = {}
|
||||
this.selectProps = {}
|
||||
},
|
||||
// 删除
|
||||
hanldeDelete(row) {
|
||||
this.$confirm('确认删除吗?', '提示', {
|
||||
this.$confirm(this.$t('pages.luckyBoxBountyConfig.confirm.deleteMessage'), this.$t('pages.luckyBoxBountyConfig.confirm.title'), {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.listLoading = true
|
||||
deleteBountyDetailsConfig(row.id).then((res) => {
|
||||
this.listLoading = false
|
||||
this.$message({
|
||||
message: '删除成功',
|
||||
message: this.$t('pages.luckyBoxBountyConfig.message.deleteSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
this.renderData()
|
||||
|
||||
@ -12,14 +12,14 @@
|
||||
<div style="height: 500px;overflow: auto;">
|
||||
<el-form
|
||||
ref="dataForm"
|
||||
:rules="rules"
|
||||
:rules="formRules"
|
||||
:model="formData"
|
||||
style="width: 400px; margin-left:50px;"
|
||||
>
|
||||
<el-form-item label="系统" prop="sysOrigin">
|
||||
<el-form-item :label="$t('pages.luckyBoxBountyConfig.form.system')" prop="sysOrigin">
|
||||
<el-select
|
||||
v-model="formData.sysOrigin"
|
||||
placeholder="选择系统"
|
||||
:placeholder="$t('pages.luckyBoxBountyConfig.placeholder.selectSystem')"
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
>
|
||||
@ -34,31 +34,31 @@
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="type">
|
||||
<el-form-item :label="$t('pages.luckyBoxBountyConfig.form.type')" prop="type">
|
||||
<el-select
|
||||
v-model="formData.type"
|
||||
placeholder="类型"
|
||||
:placeholder="$t('pages.luckyBoxBountyConfig.placeholder.type')"
|
||||
clearable
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
>
|
||||
<el-option label="每日" :value="'DAILY'" />
|
||||
<el-option label="每周" :value="'WEEKLY'" />
|
||||
<el-option :label="$t('pages.luckyBoxBountyConfig.type.DAILY')" :value="'DAILY'" />
|
||||
<el-option :label="$t('pages.luckyBoxBountyConfig.type.WEEKLY')" :value="'WEEKLY'" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="礼物类型">
|
||||
<el-form-item :label="$t('pages.luckyBoxBountyConfig.form.giftType')">
|
||||
<el-select
|
||||
v-model="formData.giftType"
|
||||
placeholder="礼物类型"
|
||||
:placeholder="$t('pages.luckyBoxBountyConfig.placeholder.giftType')"
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
@change="getGiftListInfo()"
|
||||
>
|
||||
<el-option v-for="(item) in giftConfigTabs" :key="item.value" :label="item.name" :value="item.value" />
|
||||
<el-option v-for="(item) in localizedGiftConfigTabs" :key="item.value" :label="item.name" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="giftId" label="资源">
|
||||
<el-select v-model="formData.giftId" v-loading="giftLoading" placeholder="请选择" style="width:100%;" @change="showPhoto">
|
||||
<el-form-item prop="giftId" :label="$t('pages.luckyBoxBountyConfig.form.resource')">
|
||||
<el-select v-model="formData.giftId" v-loading="giftLoading" :placeholder="$t('pages.luckyBoxBountyConfig.placeholder.select')" style="width:100%;" @change="showPhoto">
|
||||
<el-option
|
||||
v-for="(item, index) in gifts"
|
||||
:key="index"
|
||||
@ -79,14 +79,14 @@
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="handleClose">
|
||||
取消
|
||||
{{ $t('common.cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:loading="submitLoading"
|
||||
type="primary"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
提交
|
||||
{{ $t('common.submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
@ -129,12 +129,6 @@ export default {
|
||||
giftPhoto: ''
|
||||
|
||||
},
|
||||
rules: {
|
||||
sysOrigin: [{ required: true, message: '必填项不可为空', trigger: 'blur' }],
|
||||
giftType: [{ required: true, message: '必填项不可为空', trigger: 'blur' }],
|
||||
giftId: [{ required: true, message: '必填项不可为空', trigger: 'blur' }],
|
||||
type: [{ required: true, message: '必填项不可为空', trigger: 'blur' }]
|
||||
},
|
||||
submitLoading: false
|
||||
}
|
||||
},
|
||||
@ -142,8 +136,27 @@ export default {
|
||||
isAdd() {
|
||||
return this.updateData === null
|
||||
},
|
||||
localizedGiftConfigTabs() {
|
||||
return this.giftConfigTabs.map(item => ({
|
||||
...item,
|
||||
name: this.$t(`pages.luckyBoxBountyConfig.giftType.${item.value}`)
|
||||
}))
|
||||
},
|
||||
title() {
|
||||
return this.isAdd ? `添加(${this.sysOrigin})` : `修改(${this.updateData.sysOrigin})`
|
||||
const system = this.isAdd ? this.sysOrigin : this.updateData.sysOrigin
|
||||
const action = this.isAdd
|
||||
? this.$t('pages.luckyBoxBountyConfig.action.add')
|
||||
: this.$t('pages.luckyBoxBountyConfig.action.edit')
|
||||
return this.$t('pages.luckyBoxBountyConfig.dialog.formTitle', { action, system })
|
||||
},
|
||||
formRules() {
|
||||
const requiredMessage = this.$t('pages.luckyBoxBountyConfig.validation.requiredField')
|
||||
return {
|
||||
sysOrigin: [{ required: true, message: requiredMessage, trigger: 'blur' }],
|
||||
giftType: [{ required: true, message: requiredMessage, trigger: 'blur' }],
|
||||
giftId: [{ required: true, message: requiredMessage, trigger: 'blur' }],
|
||||
type: [{ required: true, message: requiredMessage, trigger: 'blur' }]
|
||||
}
|
||||
},
|
||||
...mapGetters(['permissionsSysOriginPlatforms'])
|
||||
},
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
<div class="filter-container">
|
||||
<el-select
|
||||
v-model="listQuery.sysOrigin"
|
||||
placeholder="系统"
|
||||
:placeholder="$t('pages.luckyBoxBountyConfig.filter.system')"
|
||||
style="width: 120px"
|
||||
class="filter-item"
|
||||
@change="handleSearch"
|
||||
@ -21,14 +21,14 @@
|
||||
</el-select>
|
||||
<el-select
|
||||
v-model="listQuery.type"
|
||||
placeholder="类型"
|
||||
:placeholder="$t('pages.luckyBoxBountyConfig.filter.type')"
|
||||
style="width:120px;"
|
||||
class="filter-item"
|
||||
clearable
|
||||
@change="handleSearch"
|
||||
>
|
||||
<el-option label="每日" :value="'DAILY'" />
|
||||
<el-option label="每周" :value="'WEEKLY'" />
|
||||
<el-option :label="$t('pages.luckyBoxBountyConfig.type.DAILY')" :value="'DAILY'" />
|
||||
<el-option :label="$t('pages.luckyBoxBountyConfig.type.WEEKLY')" :value="'WEEKLY'" />
|
||||
</el-select>
|
||||
<el-button
|
||||
:loading="searchLoading"
|
||||
@ -37,7 +37,7 @@
|
||||
icon="el-icon-search"
|
||||
@click="handleSearch"
|
||||
>
|
||||
搜索
|
||||
{{ $t('common.search') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
class="filter-item"
|
||||
@ -46,7 +46,7 @@
|
||||
icon="el-icon-edit"
|
||||
@click="handleAdd"
|
||||
>
|
||||
添加
|
||||
{{ $t('pages.luckyBoxBountyConfig.action.add') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table
|
||||
@ -56,16 +56,16 @@
|
||||
fit
|
||||
highlight-current-row
|
||||
>
|
||||
<el-table-column prop="sysOrigin" label="平台" align="center" />
|
||||
<el-table-column label="类型" align="center">
|
||||
<el-table-column prop="sysOrigin" :label="$t('pages.luckyBoxBountyConfig.table.platform')" align="center" />
|
||||
<el-table-column :label="$t('pages.luckyBoxBountyConfig.table.type')" align="center">
|
||||
<template slot-scope="scope">
|
||||
<div>
|
||||
<el-tag v-if="scope.row.type === 'DAILY'" type="danger">每日</el-tag>
|
||||
<el-tag v-else-if="scope.row.type === 'WEEKLY'">每周</el-tag>
|
||||
<el-tag v-if="scope.row.type === 'DAILY'" type="danger">{{ $t('pages.luckyBoxBountyConfig.type.DAILY') }}</el-tag>
|
||||
<el-tag v-else-if="scope.row.type === 'WEEKLY'">{{ $t('pages.luckyBoxBountyConfig.type.WEEKLY') }}</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="封面" align="center">
|
||||
<el-table-column :label="$t('pages.luckyBoxBountyConfig.table.cover')" align="center">
|
||||
<template slot-scope="scope">
|
||||
<el-image
|
||||
style="width: 50px; height: 50px"
|
||||
@ -74,16 +74,16 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="createTime" label="创建时间" align="center" width="200">
|
||||
<el-table-column prop="createTime" :label="$t('pages.luckyBoxBountyConfig.table.createdAt')" align="center" width="200">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.createTime | dateFormat }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column fixed="right" label="操作" align="center" width="380">
|
||||
<el-table-column fixed="right" :label="$t('pages.luckyBoxBountyConfig.table.actions')" align="center" width="380">
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click.native="hanldeEidt(scope.row)">编辑</el-button>
|
||||
<el-button type="text" @click.native="handleProbabilityConfigList(scope.row)">道具配置</el-button>
|
||||
<el-button type="text" @click.native="handlDel(scope.row)">删除</el-button>
|
||||
<el-button type="text" @click.native="hanldeEidt(scope.row)">{{ $t('pages.luckyBoxBountyConfig.action.edit') }}</el-button>
|
||||
<el-button type="text" @click.native="handleProbabilityConfigList(scope.row)">{{ $t('pages.luckyBoxBountyConfig.action.propsConfig') }}</el-button>
|
||||
<el-button type="text" @click.native="handlDel(scope.row)">{{ $t('pages.luckyBoxBountyConfig.action.delete') }}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -193,16 +193,15 @@ export default {
|
||||
this.bountyConfigEditVisible = false
|
||||
this.renderData(event === 'create')
|
||||
},
|
||||
// 删除
|
||||
handlDel(row) {
|
||||
this.$confirm('确认删除吗?', '提示', {
|
||||
this.$confirm(this.$t('pages.luckyBoxBountyConfig.confirm.deleteMessage'), this.$t('pages.luckyBoxBountyConfig.confirm.title'), {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
this.listLoading = true
|
||||
deleteBountyConfig(row.id).then((res) => {
|
||||
this.listLoading = false
|
||||
this.$message({
|
||||
message: '删除成功',
|
||||
message: this.$t('pages.luckyBoxBountyConfig.message.deleteSuccess'),
|
||||
type: 'success'
|
||||
})
|
||||
this.renderData()
|
||||
|
||||
@ -3,67 +3,67 @@
|
||||
<div v-loading="loading" class="fortune-config">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="130px">
|
||||
<el-alert
|
||||
title="单抽获取以下幸运值概率(单位%)"
|
||||
:title="$t('pages.luckyBoxFortuneConfig.alert.singleDraw')"
|
||||
type="info"
|
||||
:closable="false"
|
||||
style="margin-bottom: 20px;"
|
||||
/>
|
||||
<el-form-item prop="oneDot" label="1点">
|
||||
<el-form-item prop="oneDot" :label="$t('pages.luckyBoxFortuneConfig.label.oneDot')">
|
||||
<el-input v-model="form.oneDot" v-number />
|
||||
</el-form-item>
|
||||
<el-form-item prop="twoDot" label="2点">
|
||||
<el-form-item prop="twoDot" :label="$t('pages.luckyBoxFortuneConfig.label.twoDot')">
|
||||
<el-input v-model.trim="form.twoDot" v-number />
|
||||
</el-form-item>
|
||||
<el-form-item label="3点" prop="threeDot">
|
||||
<el-form-item :label="$t('pages.luckyBoxFortuneConfig.label.threeDot')" prop="threeDot">
|
||||
<el-input v-model="form.threeDot" v-number />
|
||||
</el-form-item>
|
||||
<el-alert
|
||||
title="10抽获取以下幸运值概率(单位%)"
|
||||
:title="$t('pages.luckyBoxFortuneConfig.alert.tenDraws')"
|
||||
type="info"
|
||||
:closable="false"
|
||||
style="margin-bottom: 20px;"
|
||||
/>
|
||||
<el-form-item prop="aroundElevenDot" label="11-15点">
|
||||
<el-form-item prop="aroundElevenDot" :label="$t('pages.luckyBoxFortuneConfig.label.aroundElevenDot')">
|
||||
<el-input v-model="form.aroundElevenDot" v-number />
|
||||
</el-form-item>
|
||||
<el-form-item prop="aroundSixteenDot" label="16-20点">
|
||||
<el-form-item prop="aroundSixteenDot" :label="$t('pages.luckyBoxFortuneConfig.label.aroundSixteenDot')">
|
||||
<el-input v-model.trim="form.aroundSixteenDot" v-number />
|
||||
</el-form-item>
|
||||
<el-form-item label="21-25点" prop="aroundTwentyOneDot">
|
||||
<el-form-item :label="$t('pages.luckyBoxFortuneConfig.label.aroundTwentyOneDot')" prop="aroundTwentyOneDot">
|
||||
<el-input v-model="form.aroundTwentyOneDot" v-number />
|
||||
</el-form-item>
|
||||
<el-form-item label="26-30点" prop="aroundTwentySixDot">
|
||||
<el-form-item :label="$t('pages.luckyBoxFortuneConfig.label.aroundTwentySixDot')" prop="aroundTwentySixDot">
|
||||
<el-input v-model="form.aroundTwentySixDot" v-number />
|
||||
</el-form-item>
|
||||
<el-alert
|
||||
title="50抽获取以下幸运值概率(单位%)"
|
||||
:title="$t('pages.luckyBoxFortuneConfig.alert.fiftyDraws')"
|
||||
type="info"
|
||||
:closable="false"
|
||||
style="margin-bottom: 20px;"
|
||||
/>
|
||||
<el-form-item prop="aroundFiftyOneDot" label="51-100点">
|
||||
<el-form-item prop="aroundFiftyOneDot" :label="$t('pages.luckyBoxFortuneConfig.label.aroundFiftyOneDot')">
|
||||
<el-input v-model="form.aroundFiftyOneDot" v-number />
|
||||
</el-form-item>
|
||||
<el-form-item prop="aroundOneHundredDot" label="101-150点">
|
||||
<el-form-item prop="aroundOneHundredDot" :label="$t('pages.luckyBoxFortuneConfig.label.aroundOneHundredDot')">
|
||||
<el-input v-model.trim="form.aroundOneHundredDot" v-number />
|
||||
</el-form-item>
|
||||
<el-alert
|
||||
title="幸运时刻配置"
|
||||
:title="$t('pages.luckyBoxFortuneConfig.alert.luckyMoment')"
|
||||
type="info"
|
||||
:closable="false"
|
||||
style="margin-bottom: 20px;"
|
||||
/>
|
||||
<el-form-item label="幸运时刻1" prop="luckyTimeOne">
|
||||
<el-form-item :label="$t('pages.luckyBoxFortuneConfig.label.luckyTimeOne')" prop="luckyTimeOne">
|
||||
<el-input v-model="form.luckyTimeOne" v-number />
|
||||
</el-form-item>
|
||||
<el-form-item label="幸运时刻2" prop="luckyTimeTwo">
|
||||
<el-form-item :label="$t('pages.luckyBoxFortuneConfig.label.luckyTimeTwo')" prop="luckyTimeTwo">
|
||||
<el-input v-model="form.luckyTimeTwo" v-number />
|
||||
</el-form-item>
|
||||
<el-form-item label="幸运时刻时长(S)" prop="luckyTimeDuration">
|
||||
<el-form-item :label="$t('pages.luckyBoxFortuneConfig.label.luckyTimeDuration')" prop="luckyTimeDuration">
|
||||
<el-input v-model="form.luckyTimeDuration" v-number />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">提交</el-button>
|
||||
<el-button type="primary" @click="onSubmit">{{ $t('pages.luckyBoxFortuneConfig.action.submit') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
@ -76,7 +76,6 @@ import { mapGetters } from 'vuex'
|
||||
export default {
|
||||
name: 'FortuneConfig',
|
||||
data() {
|
||||
const commonValid = [{ required: true, message: '必填字段不可为空', trigger: 'blur' }]
|
||||
return {
|
||||
loading: false,
|
||||
form: {
|
||||
@ -97,8 +96,14 @@ export default {
|
||||
},
|
||||
fortuneConfigQuery: {
|
||||
sysOrigin: 'HALAR'
|
||||
},
|
||||
rules: {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permissionsSysOriginPlatforms']),
|
||||
rules() {
|
||||
const commonValid = [{ required: true, message: this.$t('pages.luckyBoxFortuneConfig.validation.requiredField'), trigger: 'blur' }]
|
||||
return {
|
||||
oneDot: commonValid,
|
||||
twoDot: commonValid,
|
||||
threeDot: commonValid,
|
||||
@ -115,9 +120,6 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['permissionsSysOriginPlatforms'])
|
||||
},
|
||||
created() {
|
||||
const that = this
|
||||
const querySystem = this.permissionsSysOriginPlatforms[0]
|
||||
@ -151,12 +153,12 @@ export default {
|
||||
parseInt(that.form.aroundElevenDot) === 0 || parseInt(that.form.aroundSixteenDot) === 0 ||
|
||||
parseInt(that.form.aroundTwentyOneDot) === 0 || parseInt(that.form.aroundTwentySixDot) === 0 ||
|
||||
parseInt(that.form.aroundFiftyOneDot) === 0 || parseInt(that.form.aroundOneHundredDot) === 0) {
|
||||
that.$opsMessage.fail('概率必须大于0!')
|
||||
that.$opsMessage.fail(that.$t('pages.luckyBoxFortuneConfig.message.probabilityGreaterThanZero'))
|
||||
return
|
||||
}
|
||||
|
||||
if (probability_1 !== 100 || probability_2 !== 100 || probability_3 !== 100) {
|
||||
that.$opsMessage.fail('概率必须等于100!')
|
||||
that.$opsMessage.fail(that.$t('pages.luckyBoxFortuneConfig.message.probabilityMustEqualHundred'))
|
||||
return
|
||||
}
|
||||
that.$refs.form.validate((valid) => {
|
||||
@ -165,9 +167,9 @@ export default {
|
||||
return false
|
||||
}
|
||||
|
||||
that.$confirm('是否确认提交?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
that.$confirm(that.$t('pages.luckyBoxFortuneConfig.confirm.submitMessage'), that.$t('pages.luckyBoxFortuneConfig.confirm.title'), {
|
||||
confirmButtonText: that.$t('pages.luckyBoxFortuneConfig.confirm.confirmButtonText'),
|
||||
cancelButtonText: that.$t('pages.luckyBoxFortuneConfig.confirm.cancelButtonText'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
that.loading = true
|
||||
|
||||
@ -12,14 +12,14 @@
|
||||
<div style="height: 500px;overflow: auto;">
|
||||
<el-form
|
||||
ref="dataForm"
|
||||
:rules="rules"
|
||||
:rules="formRules"
|
||||
:model="formData"
|
||||
style="width: 400px; margin-left:50px;"
|
||||
>
|
||||
<el-form-item label="系统" prop="sysOrigin">
|
||||
<el-form-item :label="$t('pages.luckyBoxStandardConfig.form.system')" prop="sysOrigin">
|
||||
<el-select
|
||||
v-model="formData.sysOrigin"
|
||||
placeholder="选择系统"
|
||||
:placeholder="$t('pages.luckyBoxStandardConfig.placeholder.selectSystem')"
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
>
|
||||
@ -34,36 +34,36 @@
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型" prop="lotteryType">
|
||||
<el-form-item :label="$t('pages.luckyBoxStandardConfig.form.type')" prop="lotteryType">
|
||||
<el-select
|
||||
v-model="formData.lotteryType"
|
||||
placeholder="类型"
|
||||
:placeholder="$t('pages.luckyBoxStandardConfig.placeholder.type')"
|
||||
clearable
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
>
|
||||
<el-option label="经典" :value="'CLASSICS'" />
|
||||
<el-option label="星座" :value="'CONSTELLATION'" />
|
||||
<el-option :label="$t('pages.luckyBoxStandardConfig.lotteryType.CLASSICS')" :value="'CLASSICS'" />
|
||||
<el-option :label="$t('pages.luckyBoxStandardConfig.lotteryType.CONSTELLATION')" :value="'CONSTELLATION'" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model.trim="formData.name" type="text" placeholder="名称" />
|
||||
<el-form-item :label="$t('pages.luckyBoxStandardConfig.form.name')" prop="name">
|
||||
<el-input v-model.trim="formData.name" type="text" :placeholder="$t('pages.luckyBoxStandardConfig.placeholder.name')" />
|
||||
</el-form-item>
|
||||
<el-form-item label="展示礼物数量" prop="giftQuantity">
|
||||
<el-input v-model.trim="formData.giftQuantity" type="text" placeholder="展示礼物数量" />
|
||||
<el-form-item :label="$t('pages.luckyBoxStandardConfig.form.giftQuantity')" prop="giftQuantity">
|
||||
<el-input v-model.trim="formData.giftQuantity" type="text" :placeholder="$t('pages.luckyBoxStandardConfig.placeholder.giftQuantity')" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="handleClose">
|
||||
取消
|
||||
{{ $t('common.cancel') }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:loading="submitLoading"
|
||||
type="primary"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
提交
|
||||
{{ $t('common.submit') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
@ -94,11 +94,6 @@ export default {
|
||||
lotteryType: '',
|
||||
giftQuantity: ''
|
||||
},
|
||||
rules: {
|
||||
sysOrigin: [{ required: true, message: '必填项不可为空', trigger: 'blur' }],
|
||||
lotteryType: [{ required: true, message: '必填项不可为空', trigger: 'blur' }],
|
||||
giftQuantity: [{ required: true, message: '必填项不可为空', trigger: 'blur' }]
|
||||
},
|
||||
submitLoading: false
|
||||
}
|
||||
},
|
||||
@ -107,7 +102,19 @@ export default {
|
||||
return this.updateData === null
|
||||
},
|
||||
title() {
|
||||
return this.isAdd ? `添加(${this.sysOrigin})` : `修改(${this.updateData.sysOrigin})`
|
||||
const system = this.isAdd ? this.sysOrigin : this.updateData.sysOrigin
|
||||
const action = this.isAdd
|
||||
? this.$t('pages.luckyBoxStandardConfig.action.add')
|
||||
: this.$t('pages.luckyBoxStandardConfig.action.edit')
|
||||
return this.$t('pages.luckyBoxStandardConfig.dialog.formTitle', { action, system })
|
||||
},
|
||||
formRules() {
|
||||
const requiredMessage = this.$t('pages.luckyBoxStandardConfig.validation.requiredField')
|
||||
return {
|
||||
sysOrigin: [{ required: true, message: requiredMessage, trigger: 'blur' }],
|
||||
lotteryType: [{ required: true, message: requiredMessage, trigger: 'blur' }],
|
||||
giftQuantity: [{ required: true, message: requiredMessage, trigger: 'blur' }]
|
||||
}
|
||||
},
|
||||
...mapGetters(['permissionsSysOriginPlatforms'])
|
||||
},
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-dialog
|
||||
title="礼物配置列表"
|
||||
:title="$t('pages.luckyBoxGiftDetails.dialog.listTitle')"
|
||||
:visible.sync="isDialog"
|
||||
:before-close="handleClose"
|
||||
:close-on-click-modal="false"
|
||||
@ -17,10 +17,10 @@
|
||||
:disabled="isAdd"
|
||||
@click="handleAdd"
|
||||
>
|
||||
添加
|
||||
{{ $t("pages.luckyBoxGiftDetails.action.add") }}
|
||||
</el-button>
|
||||
<el-alert
|
||||
title="luckyBox礼物配置-必读"
|
||||
:title="$t('pages.luckyBoxGiftDetails.alert.title')"
|
||||
type="warning"
|
||||
:description="description"
|
||||
show-icon
|
||||
@ -35,9 +35,22 @@
|
||||
highlight-current-row
|
||||
>
|
||||
<el-table-column type="index" width="50" label="No" />
|
||||
<el-table-column prop="sysOrigin" label="平台" align="center" width="280" />
|
||||
<el-table-column prop="name" label="名称" align="center" width="280" />
|
||||
<el-table-column label="封面" align="center">
|
||||
<el-table-column
|
||||
prop="sysOrigin"
|
||||
:label="$t('pages.luckyBoxGiftDetails.table.platform')"
|
||||
align="center"
|
||||
width="280"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
:label="$t('pages.luckyBoxGiftDetails.table.name')"
|
||||
align="center"
|
||||
width="280"
|
||||
/>
|
||||
<el-table-column
|
||||
:label="$t('pages.luckyBoxGiftDetails.table.cover')"
|
||||
align="center"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-image
|
||||
style="width: 50px; height: 50px"
|
||||
@ -46,22 +59,38 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="giftCandy" label="金币" align="center" width="280" />
|
||||
<el-table-column prop="createTime" label="创建时间" align="center" width="300">
|
||||
<el-table-column
|
||||
prop="giftCandy"
|
||||
:label="$t('pages.luckyBoxGiftDetails.table.gold')"
|
||||
align="center"
|
||||
width="280"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="createTime"
|
||||
:label="$t('pages.luckyBoxGiftDetails.table.createdAt')"
|
||||
align="center"
|
||||
width="300"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.createTime | dateFormat }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column fixed="right" label="操作" align="center">
|
||||
<el-table-column
|
||||
fixed="right"
|
||||
:label="$t('pages.luckyBoxGiftDetails.table.actions')"
|
||||
align="center"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-button type="text" @click.native="hanldeEidt(scope.row)">编辑</el-button>
|
||||
<el-button type="text" @click.native="hanldeEidt(scope.row)">{{
|
||||
$t("pages.luckyBoxGiftDetails.action.edit")
|
||||
}}</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div>
|
||||
<el-dialog
|
||||
title="礼物配置"
|
||||
:title="$t('pages.luckyBoxGiftDetails.dialog.formTitle')"
|
||||
width="550px"
|
||||
top="50px"
|
||||
:visible.sync="innerEditVisible"
|
||||
@ -74,12 +103,16 @@
|
||||
ref="dataForm"
|
||||
:rules="formRules"
|
||||
:model="formData"
|
||||
class="i18n-form"
|
||||
style="width: 400px; margin-left:50px;"
|
||||
>
|
||||
<el-form-item label="系统" prop="sysOrigin">
|
||||
<el-form-item
|
||||
:label="$t('pages.luckyBoxGiftDetails.form.system')"
|
||||
prop="sysOrigin"
|
||||
>
|
||||
<el-select
|
||||
v-model="formData.sysOrigin"
|
||||
placeholder="选择系统"
|
||||
:placeholder="$t('pages.luckyBoxGiftDetails.placeholder.selectSystem')"
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
>
|
||||
@ -94,25 +127,51 @@
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="formData.name" placeholder="名称" />
|
||||
<el-form-item
|
||||
:label="$t('pages.luckyBoxGiftDetails.form.name')"
|
||||
prop="name"
|
||||
>
|
||||
<el-input
|
||||
v-model="formData.name"
|
||||
:placeholder="$t('pages.luckyBoxGiftDetails.placeholder.name')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="序号" prop="sort">
|
||||
<el-input v-model="formData.sort" placeholder="序号" />
|
||||
<el-form-item
|
||||
:label="$t('pages.luckyBoxGiftDetails.form.sort')"
|
||||
prop="sort"
|
||||
>
|
||||
<el-input
|
||||
v-model="formData.sort"
|
||||
:placeholder="$t('pages.luckyBoxGiftDetails.placeholder.sort')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="礼物类型">
|
||||
<el-form-item :label="$t('pages.luckyBoxGiftDetails.form.giftType')">
|
||||
<el-select
|
||||
v-model="formData.giftType"
|
||||
placeholder="礼物类型"
|
||||
:placeholder="$t('pages.luckyBoxGiftDetails.placeholder.giftType')"
|
||||
style="width:100%;"
|
||||
class="filter-item"
|
||||
@change="getGiftListInfo()"
|
||||
>
|
||||
<el-option v-for="(item) in giftConfigTabs" :key="item.value" :label="item.name" :value="item.value" />
|
||||
<el-option
|
||||
v-for="item in localizedGiftConfigTabs"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item prop="giftId" label="资源">
|
||||
<el-select v-model="formData.giftId" v-loading="giftLoading" placeholder="请选择" style="width:100%;" @change="showPhoto">
|
||||
<el-form-item
|
||||
prop="giftId"
|
||||
:label="$t('pages.luckyBoxGiftDetails.form.resource')"
|
||||
>
|
||||
<el-select
|
||||
v-model="formData.giftId"
|
||||
v-loading="giftLoading"
|
||||
:placeholder="$t('pages.luckyBoxGiftDetails.placeholder.select')"
|
||||
style="width:100%;"
|
||||
@change="showPhoto"
|
||||
>
|
||||
<el-option
|
||||
v-for="(item, index) in gifts"
|
||||
:key="index"
|
||||
@ -133,14 +192,14 @@
|
||||
</div>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="innerEditVisible = false">
|
||||
取消
|
||||
{{ $t("common.cancel") }}
|
||||
</el-button>
|
||||
<el-button
|
||||
:loading="submitLoading"
|
||||
type="primary"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
提交
|
||||
{{ $t("common.submit") }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
@ -168,9 +227,6 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const commonRules = [
|
||||
{ required: true, message: '必填字段不可为空', trigger: 'blur' }
|
||||
]
|
||||
return {
|
||||
standardConfig: {
|
||||
id: '',
|
||||
@ -198,11 +254,6 @@ export default {
|
||||
giftId: '',
|
||||
sort: ''
|
||||
},
|
||||
formRules: {
|
||||
sysOrigin: commonRules,
|
||||
sort: commonRules,
|
||||
giftType: commonRules
|
||||
},
|
||||
gift: {
|
||||
id: '',
|
||||
giftPhoto: ''
|
||||
@ -214,7 +265,29 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
description() {
|
||||
return `礼物必须配置(${this.standardConfig.giftQuantity})个,游戏才可进行!`
|
||||
return this.$t('pages.luckyBoxGiftDetails.alert.description', {
|
||||
count: this.standardConfig.giftQuantity
|
||||
})
|
||||
},
|
||||
localizedGiftConfigTabs() {
|
||||
return this.giftConfigTabs.map(item => ({
|
||||
...item,
|
||||
label: this.$t(`pages.luckyBoxGiftDetails.giftType.${item.value}`)
|
||||
}))
|
||||
},
|
||||
formRules() {
|
||||
const commonRules = [
|
||||
{
|
||||
required: true,
|
||||
message: this.$t('pages.luckyBoxGiftDetails.validation.requiredField'),
|
||||
trigger: 'blur'
|
||||
}
|
||||
]
|
||||
return {
|
||||
sysOrigin: commonRules,
|
||||
sort: commonRules,
|
||||
giftType: commonRules
|
||||
}
|
||||
},
|
||||
...mapGetters(['permissionsSysOriginPlatforms'])
|
||||
},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user