feat: add dashboard stats redesign spec and login i18n completion
This commit is contained in:
1 parent
b0539c0014
commit
8410a2cac4
7 files changed
+805
-715
No files matched your search
@@ -0,0 +1,163 @@
|
|||||||
|
# 技术契约与架构设计书:Dashboard 统计卡片重设计
|
||||||
|
|
||||||
|
**版本**:v1.0
|
||||||
|
**日期**:2026-03-13
|
||||||
|
**作者**:system-architect
|
||||||
|
**状态**:待评审
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、现状诊断
|
||||||
|
|
||||||
|
### 当前 API 响应结构
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"total_auth_codes": 12,
|
||||||
|
"active_licenses": 2,
|
||||||
|
"expiring_soon": 0,
|
||||||
|
"abnormal_alerts": 2,
|
||||||
|
"growth_rate": {
|
||||||
|
"auth_codes": 100.00,
|
||||||
|
"licenses": 0.00
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 现存问题清单
|
||||||
|
|
||||||
|
| # | 问题 | 严重性 |
|
||||||
|
|---|------|--------|
|
||||||
|
| 1 | `growth_rate` 语义不清——是"同比"上月还是"环比"?无时间标注 | 高 |
|
||||||
|
| 2 | 两个增长率字段(auth_codes / licenses)对用户的业务价值极低,不知道要对比什么 | 高 |
|
||||||
|
| 3 | 前端 `statsData` 中的 `key` 映射与 i18n label 不一致(注释与实际label错位) | 中 |
|
||||||
|
| 4 | `expiring_soon` 统计的是"30天内到期的授权码",但卡片标签写的是"即将过期",口径模糊 | 中 |
|
||||||
|
| 5 | 没有"今日新增"这类高频关注的运营指标 | 中 |
|
||||||
|
| 6 | 增长率算法缺陷:上月总数为0时直接返回0而非100% | 低 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、竞品分析(License Management SaaS 参考)
|
||||||
|
|
||||||
|
### Keygen.sh / LicenseSpring / Cryptlex 共性 Dashboard 指标
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────┐
|
||||||
|
│ 高频关注(运营视角) │
|
||||||
|
│ • 今日新增授权码 / 本月新增授权码(绝对数 + 环比昨日/上月)│
|
||||||
|
│ • 活跃设备数(在线 License) │
|
||||||
|
│ • 即将到期(7天 / 30天)→ 需要跟进续费 │
|
||||||
|
│ • 异常告警(心跳超时 / 被撤销) │
|
||||||
|
└─────────────────────────────────────────────────────────┘
|
||||||
|
┌─────────────────────────────────────────────────────────┐
|
||||||
|
│ 中频关注(管理视角) │
|
||||||
|
│ • 授权码总量(存量指标) │
|
||||||
|
│ • 活跃许可证总量(存量指标) │
|
||||||
|
│ • 月度增长率(MoM Growth Rate,附说明文字"vs 上月") │
|
||||||
|
└─────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 关键竞品设计原则
|
||||||
|
|
||||||
|
1. **增长率必须标注对比周期**:统一用「vs. 上月同期」,数字旁展示箭头 ↑ ↓ 和颜色区分正负
|
||||||
|
2. **增长率不放卡片主数值**:作为副文本展示(小字 + 颜色),主数值展示绝对数
|
||||||
|
3. **即将到期细分**:7天 为紧急(红),30天 为预警(橙)
|
||||||
|
4. **今日新增**:运营最关注的高频指标,竞品均在首位展示
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、重设计方案
|
||||||
|
|
||||||
|
### 3.1 新指标体系(6张卡片)
|
||||||
|
|
||||||
|
| 位置 | 指标名 | 计算口径 | 副文本 |
|
||||||
|
|------|--------|---------|--------|
|
||||||
|
| 卡片1 | 授权码总量 | `COUNT(authorization_codes)` | ↑ 本月新增 N 个 |
|
||||||
|
| 卡片2 | 活跃许可证 | `COUNT(licenses WHERE status='active')` | ↑ 较上月 +X% |
|
||||||
|
| 卡片3 | 今日新增授权 | `COUNT(licenses WHERE DATE(created_at)=TODAY)` | 昨日 N 个 |
|
||||||
|
| 卡片4 | 7天内到期 | `COUNT(auth_codes WHERE end_date BETWEEN now AND now+7d AND NOT locked)` | 紧急跟进 |
|
||||||
|
| 卡片5 | 30天内到期 | `COUNT(auth_codes WHERE end_date BETWEEN now AND now+30d AND NOT locked)` | 含7天内 |
|
||||||
|
| 卡片6 | 异常告警 | `COUNT(licenses WHERE status='active' AND heartbeat_timeout)` | 心跳超时 |
|
||||||
|
|
||||||
|
> 删除:`auth_codes 增长率`、`licenses 增长率` 作为独立卡片(改为副文本方式展示)
|
||||||
|
|
||||||
|
### 3.2 增长率展示方式(副文本,不占卡片)
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────────┐
|
||||||
|
│ 🔑 授权码总量 │
|
||||||
|
│ 12 │
|
||||||
|
│ ↑ 本月新增 2 个 │ ← 副文本:绝对增量
|
||||||
|
└──────────────────────────┘
|
||||||
|
|
||||||
|
┌──────────────────────────┐
|
||||||
|
│ ✅ 活跃许可证 │
|
||||||
|
│ 98 │
|
||||||
|
│ ↑ +12.5% vs. 上月 │ ← 副文本:百分比增长率 + 标注
|
||||||
|
└──────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 新 API Response Schema
|
||||||
|
|
||||||
|
```go
|
||||||
|
// StatsOverviewResponse 重设计
|
||||||
|
type StatsOverviewResponse struct {
|
||||||
|
// 存量指标
|
||||||
|
TotalAuthCodes int64 `json:"total_auth_codes"` // 授权码总量
|
||||||
|
ActiveLicenses int64 `json:"active_licenses"` // 活跃许可证
|
||||||
|
|
||||||
|
// 流量指标
|
||||||
|
TodayNewLicenses int64 `json:"today_new_licenses"` // 今日新增许可证
|
||||||
|
YesterdayNewLicenses int64 `json:"yesterday_new_licenses"` // 昨日新增(用于对比)
|
||||||
|
MonthNewAuthCodes int64 `json:"month_new_auth_codes"` // 本月新增授权码
|
||||||
|
|
||||||
|
// 风险指标
|
||||||
|
ExpiringIn7Days int64 `json:"expiring_in_7days"` // 7天内到期
|
||||||
|
ExpiringIn30Days int64 `json:"expiring_in_30days"` // 30天内到期
|
||||||
|
AbnormalAlerts int64 `json:"abnormal_alerts"` // 异常告警
|
||||||
|
|
||||||
|
// 增长率(作为副文本,不占独立卡片)
|
||||||
|
GrowthRate struct {
|
||||||
|
AuthCodesMoM float64 `json:"auth_codes_mom"` // 授权码月环比
|
||||||
|
LicensesMoM float64 `json:"licenses_mom"` // 许可证月环比
|
||||||
|
} `json:"growth_rate"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、影响面分析(全栈)
|
||||||
|
|
||||||
|
### 后端改动文件
|
||||||
|
|
||||||
|
| 文件 | 操作 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `backend/internal/models/license.go` | 修改 | 更新 `StatsOverviewResponse` struct |
|
||||||
|
| `backend/internal/service/license_service.go` | 修改 | 重写 `GetStatsOverview()` 实现,增加今日/昨日新增查询 |
|
||||||
|
| `backend/internal/api/handlers/license_handler.go` | 无需修改 | Handler 层直接透传 |
|
||||||
|
|
||||||
|
### 前端改动文件
|
||||||
|
|
||||||
|
| 文件 | 操作 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| `frontend/src/views/Dashboard.vue` | 修改 | 重新定义 `statsData` 6张卡片,增加副文本字段渲染 |
|
||||||
|
| `frontend/src/i18n/locales/zh.json` | 修改 | 更新 `dashboard.stats.*` key |
|
||||||
|
| `frontend/src/i18n/locales/en.json` | 修改 | 同上 |
|
||||||
|
| `frontend/src/i18n/locales/ja.json` | 修改 | 同上 |
|
||||||
|
| `frontend/src/api/dashboard.ts` | 修改 | 更新 `getOverviewStats` 返回类型定义 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、实施优先级建议
|
||||||
|
|
||||||
|
**P0(立即)**:
|
||||||
|
- 重命名"即将过期"为"30天内到期",语义清晰化
|
||||||
|
- 增长率卡片改为副文本方式(不移除数据,只改展示层)
|
||||||
|
- 增长率数字旁加"vs. 上月"标注
|
||||||
|
|
||||||
|
**P1(本迭代)**:
|
||||||
|
- 新增"今日新增"卡片(需要后端加一个 COUNT 查询)
|
||||||
|
- "即将过期"拆分7天/30天两档
|
||||||
|
|
||||||
|
**P2(下迭代)**:
|
||||||
|
- 卡片支持点击跳转到过滤后的列表页
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
# 技术契约与架构设计书:登录页国际化补全
|
||||||
|
|
||||||
|
**版本**:v1.0
|
||||||
|
**日期**:2026-03-13
|
||||||
|
**作者**:system-architect
|
||||||
|
**状态**:待 task-coder 实施
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、问题诊断
|
||||||
|
|
||||||
|
`src/views/Login.vue` 中存在 **8 处**硬编码英文字符串,未通过 `t()` 调用 i18n 系统,导致切换语言后这些文案不随语言切换。
|
||||||
|
|
||||||
|
### 硬编码清单(按 DOM 位置)
|
||||||
|
|
||||||
|
| 位置 | 当前硬编码值 | 目标 key |
|
||||||
|
|------|-------------|---------|
|
||||||
|
| `.hero-title` | `Secure License<br/>Management` | `login.heroTitleLine1` / `login.heroTitleLine2` |
|
||||||
|
| `.hero-subtitle` | `Streamline your software licensing...` | `login.heroSubtitle` |
|
||||||
|
| stat-label "Active Licenses" | `Active Licenses` | `login.stats.activeLicenses` |
|
||||||
|
| stat-label "Uptime" | `Uptime` | `login.stats.uptime` |
|
||||||
|
| stat-label "Support" | `Support` | `login.stats.support` |
|
||||||
|
| `.title` (card) | `Welcome back` | `login.welcomeTitle` |
|
||||||
|
| `.subtitle` (card) | `Sign in to your account to continue` | `login.welcomeSubtitle` |
|
||||||
|
| `.login-footer p` | `© 2025 Cedar-V. All rights reserved.` | `login.copyright` |
|
||||||
|
|
||||||
|
> **保持原样(不需国际化)**:品牌名 `Cedar-V`、数字统计值 `10K+` / `99.9%` / `24/7`、语言选项标签(自语言名称自描述惯例)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、数据模型层(Schema)— i18n 键值设计
|
||||||
|
|
||||||
|
### 新增键(追加至三端 `login` 对象末尾,位于 `error` 块之后)
|
||||||
|
|
||||||
|
```jsonc
|
||||||
|
// en.json
|
||||||
|
"heroTitleLine1": "Secure License",
|
||||||
|
"heroTitleLine2": "Management",
|
||||||
|
"heroSubtitle": "Streamline your software licensing workflow with our enterprise-grade platform.",
|
||||||
|
"stats": {
|
||||||
|
"activeLicenses": "Active Licenses",
|
||||||
|
"uptime": "Uptime",
|
||||||
|
"support": "Support"
|
||||||
|
},
|
||||||
|
"welcomeTitle": "Welcome back",
|
||||||
|
"welcomeSubtitle": "Sign in to your account to continue",
|
||||||
|
"copyright": "© 2025 Cedar-V. All rights reserved."
|
||||||
|
|
||||||
|
// zh.json
|
||||||
|
"heroTitleLine1": "安全许可证",
|
||||||
|
"heroTitleLine2": "管理平台",
|
||||||
|
"heroSubtitle": "使用我们的企业级平台,简化您的软件许可证管理工作流程。",
|
||||||
|
"stats": {
|
||||||
|
"activeLicenses": "活跃许可证",
|
||||||
|
"uptime": "可用率",
|
||||||
|
"support": "全天支持"
|
||||||
|
},
|
||||||
|
"welcomeTitle": "欢迎回来",
|
||||||
|
"welcomeSubtitle": "登录您的账户以继续",
|
||||||
|
"copyright": "© 2025 Cedar-V. 保留所有权利。"
|
||||||
|
|
||||||
|
// ja.json
|
||||||
|
"heroTitleLine1": "セキュアな",
|
||||||
|
"heroTitleLine2": "ライセンス管理",
|
||||||
|
"heroSubtitle": "エンタープライズグレードのプラットフォームで、ソフトウェアライセンス管理を効率化。",
|
||||||
|
"stats": {
|
||||||
|
"activeLicenses": "アクティブライセンス",
|
||||||
|
"uptime": "稼働率",
|
||||||
|
"support": "サポート"
|
||||||
|
},
|
||||||
|
"welcomeTitle": "おかえりなさい",
|
||||||
|
"welcomeSubtitle": "アカウントにサインインして続けてください",
|
||||||
|
"copyright": "© 2025 Cedar-V. All rights reserved."
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、前端交互层(View)— 修改意图
|
||||||
|
|
||||||
|
### 目标文件
|
||||||
|
|
||||||
|
| 文件 | 操作 |
|
||||||
|
|------|------|
|
||||||
|
| `src/i18n/locales/en.json` | 追加 8 个新键至 `login` 对象 |
|
||||||
|
| `src/i18n/locales/zh.json` | 追加 8 个新键至 `login` 对象 |
|
||||||
|
| `src/i18n/locales/ja.json` | 追加 8 个新键至 `login` 对象 |
|
||||||
|
| `src/views/Login.vue` | 模板层 8 处硬编码 → `{{ t('login.*') }}` |
|
||||||
|
|
||||||
|
### Login.vue 模板变更对照
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- BEFORE -->
|
||||||
|
<h1 class="hero-title">Secure License<br/>Management</h1>
|
||||||
|
|
||||||
|
<!-- AFTER -->
|
||||||
|
<h1 class="hero-title">{{ t('login.heroTitleLine1') }}<br/>{{ t('login.heroTitleLine2') }}</h1>
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- BEFORE -->
|
||||||
|
<p class="hero-subtitle">Streamline your software licensing workflow with our enterprise-grade platform.</p>
|
||||||
|
|
||||||
|
<!-- AFTER -->
|
||||||
|
<p class="hero-subtitle">{{ t('login.heroSubtitle') }}</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- BEFORE (3 stat labels) -->
|
||||||
|
<span class="stat-label">Active Licenses</span>
|
||||||
|
<span class="stat-label">Uptime</span>
|
||||||
|
<span class="stat-label">Support</span>
|
||||||
|
|
||||||
|
<!-- AFTER -->
|
||||||
|
<span class="stat-label">{{ t('login.stats.activeLicenses') }}</span>
|
||||||
|
<span class="stat-label">{{ t('login.stats.uptime') }}</span>
|
||||||
|
<span class="stat-label">{{ t('login.stats.support') }}</span>
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- BEFORE -->
|
||||||
|
<h2 class="title">Welcome back</h2>
|
||||||
|
<p class="subtitle">Sign in to your account to continue</p>
|
||||||
|
|
||||||
|
<!-- AFTER -->
|
||||||
|
<h2 class="title">{{ t('login.welcomeTitle') }}</h2>
|
||||||
|
<p class="subtitle">{{ t('login.welcomeSubtitle') }}</p>
|
||||||
|
```
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- BEFORE -->
|
||||||
|
<p>© 2025 Cedar-V. All rights reserved.</p>
|
||||||
|
|
||||||
|
<!-- AFTER -->
|
||||||
|
<p>{{ t('login.copyright') }}</p>
|
||||||
|
```
|
||||||
@@ -121,7 +121,6 @@ const appStore = useAppStore()
|
|||||||
|
|
||||||
// 快捷选择选项
|
// 快捷选择选项
|
||||||
const quickOptions = computed(() => [
|
const quickOptions = computed(() => [
|
||||||
{ label: t('chart.licenseTrend.quickOptions.today'), value: 'today' },
|
|
||||||
{ label: t('chart.licenseTrend.quickOptions.week'), value: 'week' },
|
{ label: t('chart.licenseTrend.quickOptions.week'), value: 'week' },
|
||||||
{ label: t('chart.licenseTrend.quickOptions.month'), value: 'month' }
|
{ label: t('chart.licenseTrend.quickOptions.month'), value: 'month' }
|
||||||
])
|
])
|
||||||
@@ -161,7 +160,7 @@ const chartOption = computed(() => {
|
|||||||
return {
|
return {
|
||||||
grid: {
|
grid: {
|
||||||
left: 60,
|
left: 60,
|
||||||
right: 30,
|
right: 50,
|
||||||
top: 30,
|
top: 30,
|
||||||
bottom: 60,
|
bottom: 60,
|
||||||
containLabel: false
|
containLabel: false
|
||||||
@@ -277,24 +276,17 @@ const handleQuickSelect = (value: string) => {
|
|||||||
let endDate: Date
|
let endDate: Date
|
||||||
|
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case 'today':
|
case 'week':
|
||||||
// 本日:今天到今天
|
// 最近7天:今天往前6天
|
||||||
startDate = new Date(today)
|
startDate = new Date(today)
|
||||||
|
startDate.setDate(today.getDate() - 6)
|
||||||
endDate = new Date(today)
|
endDate = new Date(today)
|
||||||
break
|
break
|
||||||
case 'week':
|
|
||||||
// 本周:本周一到本周日
|
|
||||||
const currentDay = today.getDay() // 0=周日, 1=周一, ..., 6=周六
|
|
||||||
const mondayOffset = currentDay === 0 ? 6 : currentDay - 1 // 计算到周一的偏移
|
|
||||||
startDate = new Date(today)
|
|
||||||
startDate.setDate(today.getDate() - mondayOffset)
|
|
||||||
endDate = new Date(startDate)
|
|
||||||
endDate.setDate(startDate.getDate() + 6) // 周日
|
|
||||||
break
|
|
||||||
case 'month':
|
case 'month':
|
||||||
// 本月:当前月1号到当前月末
|
// 最近30天:今天往前29天
|
||||||
startDate = new Date(today.getFullYear(), today.getMonth(), 1)
|
startDate = new Date(today)
|
||||||
endDate = new Date(today.getFullYear(), today.getMonth() + 1, 0) // 下个月0号=本月最后一天
|
startDate.setDate(today.getDate() - 29)
|
||||||
|
endDate = new Date(today)
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -17,7 +17,18 @@
|
|||||||
"usernameMinLength": "Username must be at least 3 characters",
|
"usernameMinLength": "Username must be at least 3 characters",
|
||||||
"passwordRequired": "Please enter password",
|
"passwordRequired": "Please enter password",
|
||||||
"passwordMinLength": "Password must be at least 6 characters"
|
"passwordMinLength": "Password must be at least 6 characters"
|
||||||
}
|
},
|
||||||
|
"heroTitleLine1": "Secure License",
|
||||||
|
"heroTitleLine2": "Management",
|
||||||
|
"heroSubtitle": "Streamline your software licensing workflow with our enterprise-grade platform.",
|
||||||
|
"stats": {
|
||||||
|
"activeLicenses": "Active Licenses",
|
||||||
|
"uptime": "Uptime",
|
||||||
|
"support": "Support"
|
||||||
|
},
|
||||||
|
"welcomeTitle": "Welcome back",
|
||||||
|
"welcomeSubtitle": "Sign in to your account to continue",
|
||||||
|
"copyright": "© 2025 Cedar-V. All rights reserved."
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"expand": "Expand Sidebar",
|
"expand": "Expand Sidebar",
|
||||||
@@ -295,9 +306,8 @@
|
|||||||
"licenseTrend": {
|
"licenseTrend": {
|
||||||
"title": "License Trend",
|
"title": "License Trend",
|
||||||
"quickOptions": {
|
"quickOptions": {
|
||||||
"today": "Today",
|
"week": "Last 7 Days",
|
||||||
"week": "This Week",
|
"month": "Last 30 Days"
|
||||||
"month": "This Month"
|
|
||||||
},
|
},
|
||||||
"datePicker": {
|
"datePicker": {
|
||||||
"rangeSeparator": "to",
|
"rangeSeparator": "to",
|
||||||
@@ -314,9 +324,8 @@
|
|||||||
"endDate": "End Date",
|
"endDate": "End Date",
|
||||||
"separator": "to",
|
"separator": "to",
|
||||||
"quickOptions": {
|
"quickOptions": {
|
||||||
"today": "Today",
|
"week": "Last 7 Days",
|
||||||
"week": "This Week",
|
"month": "Last 30 Days"
|
||||||
"month": "This Month"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,7 +17,18 @@
|
|||||||
"usernameMinLength": "ユーザー名は3文字以上である必要があります",
|
"usernameMinLength": "ユーザー名は3文字以上である必要があります",
|
||||||
"passwordRequired": "パスワードを入力してください",
|
"passwordRequired": "パスワードを入力してください",
|
||||||
"passwordMinLength": "パスワードは6文字以上である必要があります"
|
"passwordMinLength": "パスワードは6文字以上である必要があります"
|
||||||
}
|
},
|
||||||
|
"heroTitleLine1": "セキュアな",
|
||||||
|
"heroTitleLine2": "ライセンス管理",
|
||||||
|
"heroSubtitle": "エンタープライズグレードのプラットフォームで、ソフトウェアライセンス管理を効率化。",
|
||||||
|
"stats": {
|
||||||
|
"activeLicenses": "アクティブライセンス",
|
||||||
|
"uptime": "稼働率",
|
||||||
|
"support": "サポート"
|
||||||
|
},
|
||||||
|
"welcomeTitle": "おかえりなさい",
|
||||||
|
"welcomeSubtitle": "アカウントにサインインして続けてください",
|
||||||
|
"copyright": "© 2025 Cedar-V. All rights reserved."
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"expand": "サイドバーを展開",
|
"expand": "サイドバーを展開",
|
||||||
@@ -294,9 +305,8 @@
|
|||||||
"licenseTrend": {
|
"licenseTrend": {
|
||||||
"title": "ライセンストレンド",
|
"title": "ライセンストレンド",
|
||||||
"quickOptions": {
|
"quickOptions": {
|
||||||
"today": "今日",
|
"week": "直7日間",
|
||||||
"week": "今週",
|
"month": "直30日間"
|
||||||
"month": "今月"
|
|
||||||
},
|
},
|
||||||
"datePicker": {
|
"datePicker": {
|
||||||
"rangeSeparator": "から",
|
"rangeSeparator": "から",
|
||||||
@@ -313,9 +323,8 @@
|
|||||||
"endDate": "終了日付",
|
"endDate": "終了日付",
|
||||||
"separator": "から",
|
"separator": "から",
|
||||||
"quickOptions": {
|
"quickOptions": {
|
||||||
"today": "今日",
|
"week": "直7日間",
|
||||||
"week": "今週",
|
"month": "直30日間"
|
||||||
"month": "今月"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -17,7 +17,18 @@
|
|||||||
"usernameMinLength": "用户名至少需要3个字符",
|
"usernameMinLength": "用户名至少需要3个字符",
|
||||||
"passwordRequired": "请输入密码",
|
"passwordRequired": "请输入密码",
|
||||||
"passwordMinLength": "密码至少需要6个字符"
|
"passwordMinLength": "密码至少需要6个字符"
|
||||||
}
|
},
|
||||||
|
"heroTitleLine1": "软件授权",
|
||||||
|
"heroTitleLine2": "管理系统",
|
||||||
|
"heroSubtitle": "赋能软件商业化,构建 B2B 与 B2C 全场景的软件授权体系。",
|
||||||
|
"stats": {
|
||||||
|
"activeLicenses": "活跃许可证",
|
||||||
|
"uptime": "可用率",
|
||||||
|
"support": "全天支持"
|
||||||
|
},
|
||||||
|
"welcomeTitle": "欢迎回来",
|
||||||
|
"welcomeSubtitle": "登录您的账户以继续",
|
||||||
|
"copyright": "© 2025 Cedar-V. 保留所有权利。"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"expand": "展开侧边栏",
|
"expand": "展开侧边栏",
|
||||||
@@ -328,9 +339,8 @@
|
|||||||
"licenseTrend": {
|
"licenseTrend": {
|
||||||
"title": "授权趋势",
|
"title": "授权趋势",
|
||||||
"quickOptions": {
|
"quickOptions": {
|
||||||
"today": "本日",
|
"week": "最近7天",
|
||||||
"week": "本周",
|
"month": "最近30天"
|
||||||
"month": "本月"
|
|
||||||
},
|
},
|
||||||
"datePicker": {
|
"datePicker": {
|
||||||
"rangeSeparator": "至",
|
"rangeSeparator": "至",
|
||||||
@@ -347,9 +357,8 @@
|
|||||||
"endDate": "结束日期",
|
"endDate": "结束日期",
|
||||||
"separator": "至",
|
"separator": "至",
|
||||||
"quickOptions": {
|
"quickOptions": {
|
||||||
"today": "本日",
|
"week": "最近7天",
|
||||||
"week": "本周",
|
"month": "最近30天"
|
||||||
"month": "本月"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
+451
-678
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user