Compare commits

..

5 Commits

Author SHA1 Message Date
luo
889ff3bc28 Merge branch 'develop' 2026-08-21 17:23:16 +08:00
luo
3a819e86c9 fix: 套餐用量显示
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 6m52s
2026-07-23 12:02:34 +08:00
luo
e9c0e17d6a fix: 套餐用量显示
Some checks failed
构建并部署前端到测试环境 / build-and-deploy (push) Has been cancelled
2026-07-23 11:52:25 +08:00
luo
db7b3562da fix:将文案虚流量改成流量
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 7m23s
2026-07-21 15:24:02 +08:00
luo
f52970ae6c fix: 资产信息流量显示
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 6m22s
2026-07-21 14:51:29 +08:00
9 changed files with 269 additions and 59 deletions

View File

@@ -0,0 +1,19 @@
# Change: 统一资产套餐流量展示文案
## Why
资产信息页的当前生效套餐和套餐列表对同一虚流量数据使用了不一致且容易造成误解的展示文案。需要按业务术语统一为更通用的流量用量表述。
## What Changes
- 将“当前生效套餐”中虚流量统计区域的标题从“虚流量使用”调整为“流量用量”。
- 将“套餐列表”流量字段中虚流量已用值的标签从“已使用虚流量”调整为“已使用流量”。
- 保持现有流量字段、数值计算、进度条、可见性权限和接口契约不变。
## Impact
- Affected specs: `asset-package-traffic-display`
- Affected code:
- `src/views/asset-management/asset-information/components/CurrentPackageCard.vue`
- `src/views/asset-management/asset-information/components/PackageListCard.vue`
- Dependencies: `update-asset-package-traffic-threshold-layout` 中定义的套餐流量展示能力

View File

@@ -0,0 +1,19 @@
## ADDED Requirements
### Requirement: Asset Package Traffic Terminology
The asset information page SHALL use the approved traffic terminology while retaining the existing virtual traffic data source and display behavior.
#### Scenario: Current package displays the traffic usage heading
- **GIVEN** 当前生效套餐的虚流量统计区域可见
- **WHEN** 页面渲染该统计区域
- **THEN** 系统 MUST 将区域标题显示为“流量用量”
- **AND** 系统 MUST NOT 显示“虚流量使用”作为该区域标题
#### Scenario: Package list displays the used traffic label
- **GIVEN** 套餐列表记录的虚流量统计区域可见
- **WHEN** 页面渲染该记录的已用流量值
- **THEN** 系统 MUST 将字段标签显示为“已使用流量”
- **AND** 系统 MUST NOT 显示“已使用虚流量”作为该字段标签

View File

@@ -0,0 +1,5 @@
## 1. Implementation
- [x] 1.1 将当前生效套餐虚流量统计区域标题更新为“流量用量”。
- [x] 1.2 将套餐列表虚流量已用字段标签更新为“已使用流量”。
- [x] 1.3 验证文案变更不影响现有流量数值、进度条和权限可见性。

View File

@@ -0,0 +1,27 @@
# Change: 调整资产套餐真虚流量展示布局
## Why
资产信息页“当前生效套餐”和“套餐列表”目前将虚流量停机阈值及其断点标记放在虚流量使用区块,而真流量剩余未直接关联停机阈值。业务需要让停机阈值和断点与真流量剩余在同一区域展示,同时使虚流量区块完整呈现其基于真流量总量计算的总量和剩余。
## What Changes
- 在“当前生效套餐”和“套餐列表”的管理员/平台双流量视图中,将“虚流量停机阈值”展示项移至“真流量剩余”之后,继续显示现有的 `virtual_total_mb` 值。
- 将虚流量停机阈值对应的断点标记从虚流量进度条移至真流量进度条;断点位置继续按 `virtual_total_mb / real_total_mb` 计算。
- 在“虚流量使用”区块的“已使用”后新增:
- “总量”:显示真流量总量 `real_total_mb`
- “剩余”:按 `real_total_mb - virtual_used_mb` 计算。
- 保持真流量和虚流量进度条的现有计算口径、字段来源、权限控制及非管理员单一流量展示不变。
- 不修改后端接口、响应字段或数据模型。
## Impact
- Affected specs:
- `asset-package-traffic-display`
- `asset-package-traffic-permissions`
- Affected code:
- `src/views/asset-management/asset-information/components/CurrentPackageCard.vue`
- `src/views/asset-management/asset-information/components/PackageListCard.vue`
- Dependencies:
- 继续使用现有套餐流量字段:`real_total_mb``real_used_mb``virtual_used_mb``virtual_total_mb`
- 继续使用权限 `asset_info:view_current_package_real_usage``asset_info:view_current_package_virtual_usage`

View File

@@ -0,0 +1,55 @@
## ADDED Requirements
### Requirement: Virtual Traffic Threshold Aligns With Real Traffic Remaining
For super admins and platform users, the asset information page SHALL display the virtual traffic stop threshold immediately after real traffic remaining in both the `当前生效套餐` card and each applicable `套餐列表` row.
The displayed stop-threshold value MUST continue to use `virtual_total_mb`. The corresponding breakpoint marker MUST render on the real traffic progress bar and MUST continue to calculate its position as `virtual_total_mb / real_total_mb`.
#### Scenario: Current package shows threshold and breakpoint with real traffic
- **GIVEN** 当前登录账号的 `user_type``1``2`
- **AND** 当前套餐可展示真流量和虚流量使用信息
- **WHEN** 页面渲染“当前生效套餐”的流量信息
- **THEN** 系统 MUST 在真流量剩余后展示虚流量停机阈值
- **AND** 停机阈值 MUST 显示 `virtual_total_mb` 的现有格式化值
- **AND** 系统 MUST 将停机阈值断点标记渲染在真流量进度条
- **AND** 断点位置 MUST 按 `virtual_total_mb / real_total_mb` 计算
- **AND** 系统 MUST NOT 在虚流量进度条渲染该断点标记
#### Scenario: Package list shows threshold and breakpoint with real traffic
- **GIVEN** 当前登录账号的 `user_type``1``2`
- **AND** 套餐列表中的记录可展示真流量和虚流量使用信息
- **WHEN** 页面渲染该记录的流量信息
- **THEN** 系统 MUST 在真流量剩余后展示虚流量停机阈值
- **AND** 停机阈值 MUST 显示该记录的 `virtual_total_mb` 的现有格式化值
- **AND** 系统 MUST 将该记录的停机阈值断点标记渲染在真流量进度条
- **AND** 断点位置 MUST 按该记录的 `virtual_total_mb / real_total_mb` 计算
- **AND** 系统 MUST NOT 在虚流量进度条渲染该断点标记
### Requirement: Virtual Traffic Usage Displays Real Total And Remaining
For super admins and platform users, the `虚流量使用` section on the asset information page SHALL display virtual traffic used, real traffic total, and remaining virtual traffic capacity in that order in both the `当前生效套餐` card and each applicable `套餐列表` row.
The total MUST use `real_total_mb`. The remaining value MUST be calculated as `real_total_mb - virtual_used_mb`.
#### Scenario: Current package virtual traffic shows total and remaining
- **GIVEN** 当前登录账号的 `user_type``1``2`
- **AND** 当前套餐可展示虚流量使用信息
- **WHEN** 页面渲染“当前生效套餐”的虚流量使用区块
- **THEN** 系统 MUST 在虚流量已使用后展示总量
- **AND** 总量 MUST 显示 `real_total_mb` 的现有格式化值
- **AND** 系统 MUST 在总量后展示剩余
- **AND** 剩余 MUST 显示 `real_total_mb - virtual_used_mb` 的现有格式化值
#### Scenario: Package list virtual traffic shows total and remaining
- **GIVEN** 当前登录账号的 `user_type``1``2`
- **AND** 套餐列表中的记录可展示虚流量使用信息
- **WHEN** 页面渲染该记录的虚流量使用区块
- **THEN** 系统 MUST 在虚流量已使用后展示总量
- **AND** 总量 MUST 显示该记录的 `real_total_mb` 的现有格式化值
- **AND** 系统 MUST 在总量后展示剩余
- **AND** 剩余 MUST 显示 `real_total_mb - virtual_used_mb` 的现有格式化值

View File

@@ -0,0 +1,22 @@
## ADDED Requirements
### Requirement: Traffic Threshold And Virtual Statistics Follow Existing Usage Permissions
The asset information page SHALL apply the existing real and virtual traffic usage permissions to the relocated virtual traffic stop threshold, breakpoint marker, and added virtual traffic statistics.
#### Scenario: Hidden real traffic usage also hides relocated threshold and breakpoint
- **GIVEN** 当前登录账号的 `user_type``1``2`
- **AND** 账号缺少 `asset_info:view_current_package_real_usage` 权限
- **WHEN** 页面渲染“当前生效套餐”或“套餐列表”的套餐流量信息
- **THEN** 系统 MUST NOT 显示真流量统计
- **AND** 系统 MUST NOT 显示位于真流量区域的虚流量停机阈值
- **AND** 系统 MUST NOT 显示位于真流量进度条的停机阈值断点标记
#### Scenario: Hidden virtual traffic usage also hides added virtual statistics
- **GIVEN** 当前登录账号的 `user_type``1``2`
- **AND** 账号缺少 `asset_info:view_current_package_virtual_usage` 权限
- **WHEN** 页面渲染“当前生效套餐”或“套餐列表”的套餐流量信息
- **THEN** 系统 MUST NOT 显示虚流量使用区块
- **AND** 系统 MUST NOT 显示虚流量区块中的已使用、总量或剩余统计

View File

@@ -0,0 +1,16 @@
## 1. Implementation
- [x] 1.1 调整“当前生效套餐”真流量统计项,在真流量剩余后展示虚流量停机阈值,并保持 `virtual_total_mb` 的现有值格式化规则。
- [x] 1.2 将“当前生效套餐”的停机阈值断点标记移至真流量进度条,继续按 `virtual_total_mb / real_total_mb` 定位。
- [x] 1.3 调整“当前生效套餐”虚流量统计项,在已使用后展示真流量总量和按 `real_total_mb - virtual_used_mb` 计算的剩余量。
- [x] 1.4 对套餐列表的每条管理员/平台套餐记录应用相同的阈值、断点和虚流量统计布局。
- [x] 1.5 保持非管理员单一流量展示、现有权限可见性和各进度条百分比计算不变。
## 2. Verification
- [x] 2.1 验证“当前生效套餐”中停机阈值显示在真流量剩余后,且其值仍为 `virtual_total_mb`
- [x] 2.2 验证“当前生效套餐”中断点显示在真流量进度条,且其位置仍按 `virtual_total_mb / real_total_mb` 计算。
- [x] 2.3 验证“当前生效套餐”虚流量使用依次显示已使用、总量(`real_total_mb`)和剩余(`real_total_mb - virtual_used_mb`)。
- [x] 2.4 验证套餐列表的管理员/平台套餐记录具有与当前生效套餐一致的展示布局和计算结果。
- [x] 2.5 验证真流量或虚流量查看权限缺失时,不展示该权限对应的统计项及关联阈值/断点内容。
- [x] 2.6 验证非管理员账号继续使用现有单一流量展示,且真流量与虚流量进度百分比不变。

View File

@@ -31,7 +31,7 @@
<template v-if="isAdminOrPlatform"> <template v-if="isAdminOrPlatform">
<div class="flow-stats-container"> <div class="flow-stats-container">
<!-- 真流量 --> <!-- 真流量 -->
<div v-if="canViewCurrentPackageRealUsage" class="flow-stat-section"> <div v-if="canShowCurrentPackageRealUsage" class="flow-stat-section">
<div class="flow-stat-label">真流量使用</div> <div class="flow-stat-label">真流量使用</div>
<div class="flow-stat-row"> <div class="flow-stat-row">
<span class="stat-item"> <span class="stat-item">
@@ -54,7 +54,15 @@
) )
}}</span> }}</span>
</span> </span>
<span v-if="canShowCurrentPackageVirtualUsage" class="stat-item">
<span class="stat-label">停机阈值</span>
<span class="stat-value">{{
formatDataSize(currentPackage.virtual_total_mb || 0)
}}</span>
</span>
</div> </div>
<div class="progress-wrapper">
<div class="progress-track">
<ElProgress <ElProgress
:percentage=" :percentage="
getUsageProgress( getUsageProgress(
@@ -72,10 +80,23 @@
" "
:stroke-width="10" :stroke-width="10"
/> />
<div
v-if="canShowCurrentPackageVirtualUsage"
class="breakpoint-marker"
:style="
getBreakpointMarkerStyle(
currentPackage.virtual_total_mb || 0,
currentPackage.real_total_mb || 0
)
"
:title="`停机阈值/真流量总量: ${formatDataSize(currentPackage.virtual_total_mb || 0)} / ${formatDataSize(currentPackage.real_total_mb || 0)}`"
></div>
</div>
</div>
</div> </div>
<!-- 虚流量 --> <!-- 虚流量 -->
<div v-if="canShowCurrentPackageVirtualUsage" class="flow-stat-section"> <div v-if="canShowCurrentPackageVirtualUsage" class="flow-stat-section">
<div class="flow-stat-label">流量使</div> <div class="flow-stat-label">流量用</div>
<div class="flow-stat-row"> <div class="flow-stat-row">
<span class="stat-item"> <span class="stat-item">
<span class="stat-label">已使用</span> <span class="stat-label">已使用</span>
@@ -84,9 +105,17 @@
}}</span> }}</span>
</span> </span>
<span class="stat-item"> <span class="stat-item">
<span class="stat-label">停机阈值</span> <span class="stat-label">总量</span>
<span class="stat-value">{{ <span class="stat-value">{{
formatDataSize(currentPackage.virtual_total_mb || 0) formatDataSize(currentPackage.real_total_mb || 0)
}}</span>
</span>
<span class="stat-item">
<span class="stat-label">剩余</span>
<span class="stat-value">{{
formatDataSize(
(currentPackage.real_total_mb || 0) - (currentPackage.virtual_used_mb || 0)
)
}}</span> }}</span>
</span> </span>
</div> </div>
@@ -110,16 +139,6 @@
" "
:stroke-width="10" :stroke-width="10"
/> />
<div
class="breakpoint-marker"
:style="
getBreakpointMarkerStyle(
currentPackage.virtual_total_mb || 0,
currentPackage.real_total_mb || 0
)
"
:title="`停机阈值/真流量总量: ${formatDataSize(currentPackage.virtual_total_mb || 0)} / ${formatDataSize(currentPackage.real_total_mb || 0)}`"
></div>
</div> </div>
<span class="progress-percentage"> <span class="progress-percentage">
{{ {{
@@ -317,13 +336,17 @@
const canViewCurrentPackageVirtualUsage = computed(() => const canViewCurrentPackageVirtualUsage = computed(() =>
hasAuth('asset_info:view_current_package_virtual_usage') hasAuth('asset_info:view_current_package_virtual_usage')
) )
const canShowCurrentPackageRealUsage = computed(
() =>
canViewCurrentPackageRealUsage.value || props.currentPackage?.enable_virtual_data === false
)
const canShowCurrentPackageVirtualUsage = computed( const canShowCurrentPackageVirtualUsage = computed(
() => () =>
canViewCurrentPackageVirtualUsage.value && props.currentPackage?.enable_virtual_data !== false canViewCurrentPackageVirtualUsage.value && props.currentPackage?.enable_virtual_data !== false
) )
const shouldShowTrafficCard = computed(() => { const shouldShowTrafficCard = computed(() => {
if (!isAdminOrPlatform.value) return true if (!isAdminOrPlatform.value) return true
return canViewCurrentPackageRealUsage.value || canShowCurrentPackageVirtualUsage.value return canShowCurrentPackageRealUsage.value || canShowCurrentPackageVirtualUsage.value
}) })
const descriptionsColumn = computed(() => { const descriptionsColumn = computed(() => {

View File

@@ -74,7 +74,7 @@
<template #default="scope"> <template #default="scope">
<div class="traffic-progress"> <div class="traffic-progress">
<template v-if="isAdminOrPlatform && shouldShowAdminTrafficBreakdown(scope.row)"> <template v-if="isAdminOrPlatform && shouldShowAdminTrafficBreakdown(scope.row)">
<div v-if="canViewCurrentPackageRealUsage" class="progress-text"> <div v-if="canShowPackageRealUsage(scope.row)" class="progress-text">
<span class="used" <span class="used"
>已使用真流量: {{ formatDataSize(scope.row.real_used_mb || 0) }}</span >已使用真流量: {{ formatDataSize(scope.row.real_used_mb || 0) }}</span
> >
@@ -89,29 +89,60 @@
) )
}}</span }}</span
> >
<span v-if="canShowPackageVirtualUsage(scope.row)" class="total"
>停机阈值: {{ formatDataSize(scope.row.virtual_total_mb || 0) }}</span
>
</div> </div>
<div v-if="canShowPackageRealUsage(scope.row)" class="progress-wrapper">
<div class="progress-track">
<ElProgress <ElProgress
v-if="canViewCurrentPackageRealUsage"
style="margin-top: 4px" style="margin-top: 4px"
:percentage=" :percentage="
getUsageProgress(scope.row.real_used_mb || 0, scope.row.real_total_mb || 0) getUsageProgress(
scope.row.real_used_mb || 0,
scope.row.real_total_mb || 0
)
" "
:color=" :color="
getProgressColorByPercentage( getProgressColorByPercentage(
getUsageProgress(scope.row.real_used_mb || 0, scope.row.real_total_mb || 0) getUsageProgress(
scope.row.real_used_mb || 0,
scope.row.real_total_mb || 0
)
) )
" "
/> />
<div
v-if="canShowPackageVirtualUsage(scope.row)"
class="breakpoint-marker"
:style="
getBreakpointMarkerStyle(
scope.row.virtual_total_mb || 0,
scope.row.real_total_mb || 0
)
"
:title="`停机阈值/真流量总量: ${formatDataSize(scope.row.virtual_total_mb || 0)} / ${formatDataSize(scope.row.real_total_mb || 0)}`"
></div>
</div>
</div>
<div <div
v-if="canShowPackageVirtualUsage(scope.row)" v-if="canShowPackageVirtualUsage(scope.row)"
class="progress-text" class="progress-text"
:style="{ marginTop: canViewCurrentPackageRealUsage ? '8px' : '0' }" :style="{ marginTop: canShowPackageRealUsage(scope.row) ? '8px' : '0' }"
> >
<span class="used" <span class="used"
>已使用流量: {{ formatDataSize(scope.row.virtual_used_mb || 0) }}</span >已使用流量: {{ formatDataSize(scope.row.virtual_used_mb || 0) }}</span
> >
<span class="total" <span class="total"
>停机阈值: {{ formatDataSize(scope.row.virtual_total_mb || 0) }}</span >总量: {{ formatDataSize(scope.row.real_total_mb || 0) }}</span
>
<span class="remaining"
>剩余:
{{
formatDataSize(
(scope.row.real_total_mb || 0) - (scope.row.virtual_used_mb || 0)
)
}}</span
> >
</div> </div>
<div v-if="canShowPackageVirtualUsage(scope.row)" class="progress-wrapper"> <div v-if="canShowPackageVirtualUsage(scope.row)" class="progress-wrapper">
@@ -134,16 +165,6 @@
) )
" "
/> />
<div
class="breakpoint-marker"
:style="
getBreakpointMarkerStyle(
scope.row.virtual_total_mb || 0,
scope.row.real_total_mb || 0
)
"
:title="`停机阈值/真流量总量: ${formatDataSize(scope.row.virtual_total_mb || 0)} / ${formatDataSize(scope.row.real_total_mb || 0)}`"
></div>
</div> </div>
<span class="progress-percentage"> <span class="progress-percentage">
{{ {{
@@ -579,12 +600,15 @@
// Props 使用 API 类型 // Props 使用 API 类型
type PackageInfo = AssetPackageUsageRecord type PackageInfo = AssetPackageUsageRecord
const canShowPackageRealUsage = (pkg: PackageInfo) =>
canViewCurrentPackageRealUsage.value || pkg.enable_virtual_data === false
const canShowPackageVirtualUsage = (pkg: PackageInfo) => const canShowPackageVirtualUsage = (pkg: PackageInfo) =>
canViewCurrentPackageVirtualUsage.value && pkg.enable_virtual_data !== false canViewCurrentPackageVirtualUsage.value && pkg.enable_virtual_data !== false
const shouldShowAdminTrafficBreakdown = (pkg: PackageInfo) => { const shouldShowAdminTrafficBreakdown = (pkg: PackageInfo) => {
if (!isAdminOrPlatform.value) return true if (!isAdminOrPlatform.value) return true
return canViewCurrentPackageRealUsage.value || canShowPackageVirtualUsage(pkg) return canShowPackageRealUsage(pkg) || canShowPackageVirtualUsage(pkg)
} }
interface Props { interface Props {