diff --git a/frontend/src/components/channels/AvailableChannelsTable.vue b/frontend/src/components/channels/AvailableChannelsTable.vue
index 5963daff..e6f75766 100644
--- a/frontend/src/components/channels/AvailableChannelsTable.vue
+++ b/frontend/src/components/channels/AvailableChannelsTable.vue
@@ -83,6 +83,7 @@
:subscription-type="(g.subscription_type || 'standard') as SubscriptionType"
:rate-multiplier="g.rate_multiplier"
:user-rate-multiplier="userGroupRates[g.id] ?? null"
+ always-show-rate
/>
-
diff --git a/frontend/src/components/common/GroupBadge.vue b/frontend/src/components/common/GroupBadge.vue
index 83f4b8aa..3303d909 100644
--- a/frontend/src/components/common/GroupBadge.vue
+++ b/frontend/src/components/common/GroupBadge.vue
@@ -37,13 +37,20 @@ interface Props {
userRateMultiplier?: number | null // 用户专属倍率
showRate?: boolean
daysRemaining?: number | null // 剩余天数(订阅类型时使用)
+ /**
+ * 订阅分组默认在右侧 label 展示"订阅"或剩余天数;
+ * 开启后订阅分组也改为显示倍率(保留订阅主题色 label,配合可用渠道这类
+ * 只关心费率、不关心有效期的场景)。
+ */
+ alwaysShowRate?: boolean
}
const props = withDefaults(defineProps(), {
subscriptionType: 'standard',
showRate: true,
daysRemaining: null,
- userRateMultiplier: null
+ userRateMultiplier: null,
+ alwaysShowRate: false
})
const { t } = useI18n()
@@ -71,7 +78,8 @@ const showLabel = computed(() => {
// Label text
const labelText = computed(() => {
- if (isSubscription.value) {
+ const rateLabel = props.rateMultiplier !== undefined ? `${props.rateMultiplier}x` : ''
+ if (isSubscription.value && !props.alwaysShowRate) {
// 如果有剩余天数,显示天数
if (props.daysRemaining !== null && props.daysRemaining !== undefined) {
if (props.daysRemaining <= 0) {
@@ -82,7 +90,7 @@ const labelText = computed(() => {
// 否则显示"订阅"
return t('groups.subscription')
}
- return props.rateMultiplier !== undefined ? `${props.rateMultiplier}x` : ''
+ return rateLabel
})
// Label style based on type and days remaining
diff --git a/frontend/src/components/layout/AppSidebar.vue b/frontend/src/components/layout/AppSidebar.vue
index d828dc88..9dc107f6 100644
--- a/frontend/src/components/layout/AppSidebar.vue
+++ b/frontend/src/components/layout/AppSidebar.vue
@@ -640,7 +640,12 @@ const flagAdminPayment = () => adminSettingsStore.paymentEnabled
// buildSelfNavItems 构造用户自己的导航项(用户端主菜单和管理员的"我的账户"子菜单共享这组声明)。
// withDashboard=true 时包含仪表盘(用户端),false 时不含(管理员的个人区已经有独立仪表盘入口)。
-function buildSelfNavItems(withDashboard: boolean): NavItem[] {
+// includeAvailableChannels=false 时省略"可用渠道"入口——管理员在 admin 区已经有一个显眼入口,
+// 重复显示会让管理员同时看到两处"可用渠道"。
+//
+// 条目顺序:密钥 → 用量 → 可用渠道 → 渠道状态 → 订阅/支付 → 兑换/资料。
+// 可用渠道紧挨渠道状态之上,让用户"先看自己能用什么、再看对应状态"。
+function buildSelfNavItems(withDashboard: boolean, includeAvailableChannels = true): NavItem[] {
const items: NavItem[] = []
if (withDashboard) {
items.push({ path: '/dashboard', label: t('nav.dashboard'), icon: DashboardIcon })
@@ -648,11 +653,15 @@ function buildSelfNavItems(withDashboard: boolean): NavItem[] {
items.push(
{ path: '/keys', label: t('nav.apiKeys'), icon: KeyIcon },
{ path: '/usage', label: t('nav.usage'), icon: ChartIcon, hideInSimpleMode: true },
+ )
+ if (includeAvailableChannels) {
+ items.push({ path: '/available-channels', label: t('nav.availableChannels'), icon: ChannelIcon, hideInSimpleMode: true, featureFlag: flagAvailableChannels })
+ }
+ items.push(
{ path: '/monitor', label: t('nav.channelStatus'), icon: SignalIcon, featureFlag: flagChannelMonitor },
{ path: '/subscriptions', label: t('nav.mySubscriptions'), icon: CreditCardIcon, hideInSimpleMode: true },
{ path: '/purchase', label: t('nav.buySubscription'), icon: RechargeSubscriptionIcon, hideInSimpleMode: true, featureFlag: flagPayment },
{ path: '/orders', label: t('nav.myOrders'), icon: OrderListIcon, hideInSimpleMode: true, featureFlag: flagPayment },
- { path: '/available-channels', label: t('nav.availableChannels'), icon: ChannelIcon, hideInSimpleMode: true },
{ path: '/redeem', label: t('nav.redeem'), icon: GiftIcon, hideInSimpleMode: true },
{ path: '/profile', label: t('nav.profile'), icon: UserIcon },
...customMenuItemsForUser.value.map((item): NavItem => ({