定价分组功能使用指南
功能概述
定价分组是 NEXTY.DEV 模板提供的一项灵活的定价管理功能,允许你将定价计划按照自定义分组进行组织和展示。这为前端页面的定价展示提供了极大的灵活性——无论你需要在多个页面、多个组件中以不同方式展示定价信息,都可以轻松实现。
核心优势
- 灵活分组: 自定义分组标识 (slug),按需组织定价计划
- 前端自由度高: 可根据分组筛选展示,适配多种页面布局
数据结构
分组表 (pricing_plan_groups)
分组使用 slug 作为主键,简化查询和关联:
lib/db/schema.ts
export const pricingPlanGroups = pgTable('pricing_plan_groups', {
slug: varchar('slug', { length: 100 }).primaryKey(),
createdAt: timestamp('created_at', { withTimezone: true })
.defaultNow()
.notNull(),
})定价计划表中的分组字段
每个定价计划通过 groupSlug 字段关联到分组:
lib/db/schema.ts
// pricingPlans 表
groupSlug: varchar('group_slug', { length: 100 })
.references(() => pricingPlanGroups.slug, { onDelete: 'restrict' })
.default('default')
.notNull(),注意: 分组采用外键约束,删除分组前需先移除该分组下的所有定价计划。
管理后台操作
1. 分组管理入口
在管理员仪表板的定价管理页面 (/dashboard/prices),点击 "Manage Groups" 按钮打开分组管理弹窗。
2. 创建分组
在分组管理弹窗中:
- 在输入框中输入分组标识 (slug)
- Slug 只能包含小写字母、数字和连字符 (如
annual、monthly、enterprise-plans) - 点击 "+" 按钮或按回车键创建分组

3. 删除分组
在分组管理弹窗中:
- 每个分组右侧显示该分组下的定价计划数量
- 只有没有关联定价计划的分组才能删除
default分组是系统保留分组,不可删除
4. 分组列表展示
在定价计划列表页 (/dashboard/prices) 的表格中,Group 列显示每个定价计划所属的分组,方便快速查看和筛选。
为定价计划指定分组
创建定价计划时选择分组
在创建定价计划表单中,Group 字段允许你:
- 从下拉列表中选择已有分组
- 直接输入新的分组标识并快捷创建
编辑定价计划时修改分组
编辑定价计划时,可以随时更改其所属分组,系统会立即生效。

前端展示组件
NEXTY.DEV 提供了三个开箱即用的定价展示组件,满足不同场景需求:
1. PricingByGroup (推荐)
根据 groupSlug 分组展示定价卡片,支持 Tab 切换。
这是最灵活的展示方式,适用于大多数 SaaS 产品的定价页面。
import { PricingByGroup } from "@/components/pricing";
export default function PricingPage() {
return <PricingByGroup />;
}默认行为:
- 筛选
groupSlug为annual、monthly、onetime的计划 - 以 Tab 形式切换展示
- 优先显示年付 (annual) 标签页
- 自动隐藏无计划的标签页
自定义分组展示:
如果你使用了自定义分组 (如 basic、pro、enterprise),只需修改前端组件逻辑,让前端根据分组筛选定价计划即可:
// 示例:按自定义分组筛选
const basicPlans = allPlans.filter((plan) => plan.groupSlug === "basic");
const proPlans = allPlans.filter((plan) => plan.groupSlug === "pro");
const enterprisePlans = allPlans.filter((plan) => plan.groupSlug === "enterprise");2. PricingAll
一次性展示所有激活的定价卡片,不进行分组。
适用于定价计划较少、或需要并排展示所有选项的场景。
import { PricingAll } from "@/components/pricing";
export default function SimplePricingPage() {
return <PricingAll />;
}特点:
- 展示所有
isActive = true的定价计划 - 自动根据计划数量调整网格列数
- 无 Tab 切换,适合简洁的定价展示
3. PricingByPaymentType
根据支付类型 (月付/年付/一次性) 自动分组展示。
与 PricingByGroup 类似的 Tab 切换体验,但分组逻辑基于 paymentType 和 recurringInterval 字段,而非 groupSlug。
import { PricingByPaymentType } from "@/components/pricing";
export default function PaymentTypePricingPage() {
return <PricingByPaymentType />;
}自动分类逻辑:
- 月付:
paymentType为 recurring 且recurringInterval为 month/every-month - 年付:
paymentType为 recurring 且recurringInterval为 year/every-year - 一次性:
paymentType为 one_time/onetime
组件对比
| 组件 | 分组依据 | 展示方式 | 推荐场景 |
|---|---|---|---|
PricingByGroup | groupSlug 字段 | Tab 切换 | 自定义分组、灵活控制展示 |
PricingAll | 无分组 | 全部展示 | 计划较少、简洁页面 |
PricingByPaymentType | 支付类型字段 | Tab 切换 | 按支付周期区分展示 |
相关文件
- 组件:
components/pricing/PricingByGroup.tsx,PricingAll.tsx,PricingByPaymentType.tsx - Server Actions:
actions/prices/groups.ts,actions/prices/public.ts - 数据库 Schema:
lib/db/schema.ts - 类型定义:
types/pricing.ts - 状态管理:
stores/pricingGroupStore.ts - 管理页面:
app/[locale]/(protected)/dashboard/(admin)/prices/