mod(frontend): 订阅分组下拉显示备注
- 订阅管理/分配订阅:下拉项展示分组备注 - 兑换码/订阅类型:下拉项展示分组备注 - 复用 GroupOptionItem/GroupBadge 保持一致体验
This commit is contained in:
@@ -238,7 +238,30 @@
|
||||
v-model="generateForm.group_id"
|
||||
:options="subscriptionGroupOptions"
|
||||
:placeholder="t('admin.redeem.selectGroupPlaceholder')"
|
||||
/>
|
||||
>
|
||||
<template #selected="{ option }">
|
||||
<GroupBadge
|
||||
v-if="option"
|
||||
:name="(option as unknown as GroupOption).label"
|
||||
:platform="(option as unknown as GroupOption).platform"
|
||||
:subscription-type="(option as unknown as GroupOption).subscriptionType"
|
||||
:rate-multiplier="(option as unknown as GroupOption).rate"
|
||||
/>
|
||||
<span v-else class="text-gray-400">{{
|
||||
t('admin.redeem.selectGroupPlaceholder')
|
||||
}}</span>
|
||||
</template>
|
||||
<template #option="{ option, selected }">
|
||||
<GroupOptionItem
|
||||
:name="(option as unknown as GroupOption).label"
|
||||
:platform="(option as unknown as GroupOption).platform"
|
||||
:subscription-type="(option as unknown as GroupOption).subscriptionType"
|
||||
:rate-multiplier="(option as unknown as GroupOption).rate"
|
||||
:description="(option as unknown as GroupOption).description"
|
||||
:selected="selected"
|
||||
/>
|
||||
</template>
|
||||
</Select>
|
||||
</div>
|
||||
<div>
|
||||
<label class="input-label">{{ t('admin.redeem.validityDays') }}</label>
|
||||
@@ -370,7 +393,7 @@ import { useAppStore } from '@/stores/app'
|
||||
import { useClipboard } from '@/composables/useClipboard'
|
||||
import { adminAPI } from '@/api/admin'
|
||||
import { formatDateTime } from '@/utils/format'
|
||||
import type { RedeemCode, RedeemCodeType, Group } from '@/types'
|
||||
import type { RedeemCode, RedeemCodeType, Group, GroupPlatform, SubscriptionType } from '@/types'
|
||||
import type { Column } from '@/components/common/types'
|
||||
import AppLayout from '@/components/layout/AppLayout.vue'
|
||||
import TablePageLayout from '@/components/layout/TablePageLayout.vue'
|
||||
@@ -378,12 +401,23 @@ import DataTable from '@/components/common/DataTable.vue'
|
||||
import Pagination from '@/components/common/Pagination.vue'
|
||||
import ConfirmDialog from '@/components/common/ConfirmDialog.vue'
|
||||
import Select from '@/components/common/Select.vue'
|
||||
import GroupBadge from '@/components/common/GroupBadge.vue'
|
||||
import GroupOptionItem from '@/components/common/GroupOptionItem.vue'
|
||||
import Icon from '@/components/icons/Icon.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const appStore = useAppStore()
|
||||
const { copyToClipboard: clipboardCopy } = useClipboard()
|
||||
|
||||
interface GroupOption {
|
||||
value: number
|
||||
label: string
|
||||
description: string | null
|
||||
platform: GroupPlatform
|
||||
subscriptionType: SubscriptionType
|
||||
rate: number
|
||||
}
|
||||
|
||||
const showGenerateDialog = ref(false)
|
||||
const showResultDialog = ref(false)
|
||||
const generatedCodes = ref<RedeemCode[]>([])
|
||||
@@ -395,7 +429,11 @@ const subscriptionGroupOptions = computed(() => {
|
||||
.filter((g) => g.subscription_type === 'subscription')
|
||||
.map((g) => ({
|
||||
value: g.id,
|
||||
label: g.name
|
||||
label: g.name,
|
||||
description: g.description,
|
||||
platform: g.platform,
|
||||
subscriptionType: g.subscription_type,
|
||||
rate: g.rate_multiplier
|
||||
}))
|
||||
})
|
||||
|
||||
|
||||
@@ -466,7 +466,28 @@
|
||||
v-model="assignForm.group_id"
|
||||
:options="subscriptionGroupOptions"
|
||||
:placeholder="t('admin.subscriptions.selectGroup')"
|
||||
/>
|
||||
>
|
||||
<template #selected="{ option }">
|
||||
<GroupBadge
|
||||
v-if="option"
|
||||
:name="(option as unknown as GroupOption).label"
|
||||
:platform="(option as unknown as GroupOption).platform"
|
||||
:subscription-type="(option as unknown as GroupOption).subscriptionType"
|
||||
:rate-multiplier="(option as unknown as GroupOption).rate"
|
||||
/>
|
||||
<span v-else class="text-gray-400">{{ t('admin.subscriptions.selectGroup') }}</span>
|
||||
</template>
|
||||
<template #option="{ option, selected }">
|
||||
<GroupOptionItem
|
||||
:name="(option as unknown as GroupOption).label"
|
||||
:platform="(option as unknown as GroupOption).platform"
|
||||
:subscription-type="(option as unknown as GroupOption).subscriptionType"
|
||||
:rate-multiplier="(option as unknown as GroupOption).rate"
|
||||
:description="(option as unknown as GroupOption).description"
|
||||
:selected="selected"
|
||||
/>
|
||||
</template>
|
||||
</Select>
|
||||
<p class="input-hint">{{ t('admin.subscriptions.groupHint') }}</p>
|
||||
</div>
|
||||
<div>
|
||||
@@ -584,7 +605,7 @@ import { ref, reactive, computed, onMounted, onUnmounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useAppStore } from '@/stores/app'
|
||||
import { adminAPI } from '@/api/admin'
|
||||
import type { UserSubscription, Group } from '@/types'
|
||||
import type { UserSubscription, Group, GroupPlatform, SubscriptionType } from '@/types'
|
||||
import type { SimpleUser } from '@/api/admin/usage'
|
||||
import type { Column } from '@/components/common/types'
|
||||
import { formatDateOnly } from '@/utils/format'
|
||||
@@ -597,11 +618,21 @@ import ConfirmDialog from '@/components/common/ConfirmDialog.vue'
|
||||
import EmptyState from '@/components/common/EmptyState.vue'
|
||||
import Select from '@/components/common/Select.vue'
|
||||
import GroupBadge from '@/components/common/GroupBadge.vue'
|
||||
import GroupOptionItem from '@/components/common/GroupOptionItem.vue'
|
||||
import Icon from '@/components/icons/Icon.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const appStore = useAppStore()
|
||||
|
||||
interface GroupOption {
|
||||
value: number
|
||||
label: string
|
||||
description: string | null
|
||||
platform: GroupPlatform
|
||||
subscriptionType: SubscriptionType
|
||||
rate: number
|
||||
}
|
||||
|
||||
// User column display mode: 'email' or 'username'
|
||||
const userColumnMode = ref<'email' | 'username'>('email')
|
||||
const USER_COLUMN_MODE_KEY = 'subscription-user-column-mode'
|
||||
@@ -777,7 +808,14 @@ const groupOptions = computed(() => [
|
||||
const subscriptionGroupOptions = computed(() =>
|
||||
groups.value
|
||||
.filter((g) => g.subscription_type === 'subscription' && g.status === 'active')
|
||||
.map((g) => ({ value: g.id, label: g.name }))
|
||||
.map((g) => ({
|
||||
value: g.id,
|
||||
label: g.name,
|
||||
description: g.description,
|
||||
platform: g.platform,
|
||||
subscriptionType: g.subscription_type,
|
||||
rate: g.rate_multiplier
|
||||
}))
|
||||
)
|
||||
|
||||
const applyFilters = () => {
|
||||
|
||||
Reference in New Issue
Block a user