type
Post
status
Published
date
Feb 8, 2026
slug
nextjs-shopping-platform-012
summary
tags
Next.js
category
编程学习
icon
password
1. Section Intro
In this section, we're going to take care of two things. First, the user managment in the admin aream then the admin search functionality.
在本章节中,我们将处理两件事。首先是管理区域中的用户管理,然后是管理搜索功能。
So we'll create an action and then use that action within a page to get and display users.
因此,我们将创建一个操作,然后在页面中使用该操作来获取和显示用户。
We'll also add the ability to delete users using the same delete-dialog component that we used for orders and products.
我们还将添加删除用户的功能,使用与订单和产品相同的删除对话框组件。
We want to be able to edit some of the user info, so we'll add that.
我们希望能够编辑一些用户信息,因此我们将添加该功能。
Then once the users are done, we'll move to the admin search. If you notice, there is a search in the header on the products, orders and users pages. What I want is if they search while on the products page, then it searches the products. Then we'll do the same for the orders and users as well.
然后,一旦用户部分完成,我们将转向管理搜索。如果你注意到,在产品、订单和用户页面的页眉中有一个搜索框。我想要的是,如果他们在产品页面上搜索,那么就搜索产品。然后我们也会对订单和用户做同样的处理。
2. Get & Display Users 获取并显示用户
Now that we can manage orders and products as an admin, let's add the ability to show and manage users. We will start with the user action.
既然我们可以作为管理员管理订单和产品,让我们添加显示和管理用户的功能。我们将从用户操作开始。
Open the
lib/actions/users.actions.ts and add the following function:
打开 lib/actions/users.actions.ts 并添加以下函数:You will need to import the
PAGE_SIZE constant from the constants module.
你需要从 constants 模块导入 PAGE_SIZE 常量。This function is simple. We are just getting all the users from the database and returning them. We are also returning the total number of pages so that we can use it to paginate the users.
这个函数很简单。我们只是从数据库中获取所有用户并返回它们。我们还返回总页数,以便我们可以用它来对用户进行分页。
Users Page 用户页面
Let's create the users page just to test out the action for now. Create a file at
app/admin/users/page.tsx and add the following code:
让我们创建用户页面来暂时测试一下这个操作。在 app/admin/users/page.tsx 创建一个文件并添加以下代码:You should see the users in the console.
你应该能在控制台中看到用户。
Now let's add them on to the page in a table.
现在让我们在页面上用表格显示它们。
We will use a ShadCN table like we did with the other resources.
我们将像处理其他资源一样使用 ShadCN 表格。
Open the
src/app/admin/users/page.tsx file and add the following imports:
打开 src/app/admin/users/page.tsx 文件并添加以下导入:We need to get the page from the search params, so add the following code to the function:
我们需要从搜索参数中获取页码,所以向函数添加以下代码:
We are passing the page from the search params to the action. We are also getting the users from the action.
我们正在将搜索参数中的页码传递给操作。我们还从操作中获取用户。
Now add the following code to the return statement:
现在向返回语句添加以下代码:
We are showing a table with the users. We are also showing a pagination component. To test pagination, you can pass in
limit:2 to the action.
我们正在显示一个包含用户的表格。我们还显示一个分页组件。要测试分页,你可以向操作传入 limit:2。In the next lesson, we will add delete functionality.
在下一课中,我们将添加删除功能。
3. Delete Users 删除用户
Now we want to be able to delete users. Let's start by creating an action in the
lib/actions/user.actions.ts file:
现在我们希望能够删除用户。让我们先在 lib/actions/user.actions.ts 文件中创建一个 action:We already have the deleteDialog component that just takes in an action. So let's open the
app/admin/users/page.tsx file and import the deleteDialog component if you have not already as well as the deleteUser action:
我们已经有了一个只接受 action 的 deleteDialog 组件。所以让我们打开 app/admin/users/page.tsx 文件,如果还没有导入 deleteDialog 组件和 deleteUser action 的话,现在就导入它们:Now add the deleteDialog component to the page where we have the comment:
现在将 deleteDialog 组件添加到页面中有注释的地方:
Try deleting a user and see if it works.
尝试删除一个用户,看看是否正常工作。
4. Edit User Page 编辑用户页面
We want admins to be able to edit user information.
我们希望管理员能够编辑用户信息。
updateUserSchema 更新用户模式
Let's start by adding the Zod schema for updating a user. Open the
lib/validators.ts file and add the following code:
让我们先添加用于更新用户的 Zod 模式。打开 lib/validators.ts 文件并添加以下代码:We have the id, name and role fields.
我们有 id、name 和 role 字段。
Role Constant 角色常量
We are also going to create a constant for the role. Open the
lib/constants/index.ts file and add the following code:
我们还将为角色创建一个常量。打开 lib/constants/index.ts 文件并添加以下代码:We first check to see if the roles are set in the environment variables. If they are, we split them by a comma and space. If they are not, we set the roles to an array with the admin and user roles. This makes it easier to add or remove roles in the future.
我们首先检查角色是否在环境变量中设置。如果设置了,我们用逗号和空格将它们拆分。如果没有设置,我们将角色设置为包含 admin 和 user 角色的数组。这样可以方便将来添加或删除角色。
We'll go ahead and add the roles in the
.env file.
我们将在 .env 文件中添加角色。ShadCN Select ShadCN 选择组件
We are going to use the select component from ShadCN. Open a terminal and run the following command:
我们将使用 ShadCN 的选择组件。打开终端并运行以下命令:
User Page 用户页面
Let's create the update user form. Create a file at
app/admin/users/[id]/page.tsx and add the following code:
让我们创建更新用户表单。在 app/admin/users/[id]/page.tsx 创建一个文件并添加以下代码:We are bringing in the
getUserById action that we already created to get the user. We are getting the id from the params and passing it to the action. We are also checking to see if the user exists. If it doesn't, we are going to use the notFound function to return a 404 page. We are also logging the user to the console.
我们引入了之前创建的 getUserById 操作来获取用户。我们从 params 中获取 id 并将其传递给操作。我们还检查用户是否存在。如果不存在,我们将使用 notFound 函数返回 404 页面。我们还将用户信息记录到控制台。In the next lesson, we will work on the form.
在下一课中,我们将处理表单。
5. Edit User Form 编辑用户表单
Now let's add the edit user form. Create a new file at
app/admin/users/[id]/update-user-form.tsx and add the following code for now:现在让我们添加编辑用户表单。在
app/admin/users/[id]/update-user-form.tsx 位置创建一个新文件,并暂时添加以下代码:We are bringing in a bunch of UI components, hooks and some other stuff. The component function will take in a user prop with the type of
z.infer<typeof updateUserSchema>. We are initializing the form with the useForm hook from React Hook Form with the default values from the user prop. We are also using the zodResolver from @hookform/resolvers/zod to validate the form data against the schema.我们引入了一组 UI 组件、钩子和其他一些内容。组件函数将接收一个 user 属性,其类型为
z.infer<typeof updateUserSchema>。我们使用 React Hook Form 的 useForm 钩子初始化表单,并使用 user 属性中的值作为默认值。我们还使用 @hookform/resolvers/zod 中的 zodResolver 来根据模式验证表单数据。Then we're returning an empty form for now. Let's add it to the page. Open the
app/admin/users/[id]/page.tsx file and import the updateUserForm component and add it to the page.然后我们暂时返回一个空表单。让我们将其添加到页面中。打开
app/admin/users/[id]/page.tsx 文件,导入 updateUserForm 组件并将其添加到页面中。We already have the user to pass in. For now, you will just see the text 'form' on the page. Let's start to add some fields to the form.
我们已经有要传入的 user 数据了。目前,你只会在页面上看到 'form' 这个文本。让我们开始向表单添加一些字段。
Here is the first
div with the email field:这是包含邮箱字段的第一个
div:This is disabled because we don't want to be able to change this here. Save it and you should see the input with the text.
这个字段被禁用了,因为我们不希望在这里更改邮箱。保存文件后,你应该会看到带有文本的输入框。
Next, we have the name field:
接下来,我们有姓名字段:
Next is the role field. Here we will use the select component from the ShadCN UI.
接下来是角色字段。这里我们将使用 ShadCN UI 中的选择组件。
The
USER_ROLES is an array of strings that we defined in the lib/constants.ts file. We are mapping over it and creating a select item for each role. We are also using the onValueChange prop to update the value of the field when the user selects a new value.USER_ROLES 是我们在 lib/constants.ts 文件中定义的字符串数组。我们遍历这个数组并为每个角色创建一个选择项。我们还使用 onValueChange 属性在用户选择新值时更新字段的值。Finally, we have the button to submit the form.
最后,我们有提交表单的按钮。
Now that we have the form, in the next lesson, we will add a submit handler and the update action that it will call.
现在我们已经有了表单,在下一节课中,我们将添加一个提交处理程序以及它将要调用的更新操作。
6. Update User Action & Submit Handler 更新用户操作和提交处理器
Now that we have a form displayed, we need to handle the form submission. Let's start by adding a new action in the
lib/actions/user.actions.ts file:
既然我们已经显示了表单,现在需要处理表单提交。让我们首先在 lib/actions/user.actions.ts 文件中添加一个新的操作:Be sure to import
updateUserSchema:
确保导入 updateUserSchema:Now go back to the form at
app/admin/users/[id]/update-user-form.tsx and import the new action:
现在回到 app/admin/users/[id]/update-user-form.tsx 中的表单,并导入新的操作:Now, add the
onSubmit handler:
现在,添加 onSubmit 处理器:Add the
onSubmit handler to the form:
将 onSubmit 处理器添加到表单中:Now, try and update a user name.
现在,尝试更新一个用户名。
7. Admin Search Form 管理员搜索表单
Now we are going to make the search bar in the admin area work. It will search products on the products page, orders on the orders and users on the users page.
现在我们要让管理区域的搜索栏正常工作。它将在产品页面搜索产品,在订单页面搜索订单,在用户页面搜索用户。
Let's create a new file at
components/admin/admin-search.tsx and add the following code:
让我们在 components/admin/admin-search.tsx 创建一个新文件并添加以下代码:I added
sr-only to the button, which will make it only visible to screen readers. So we hit enter to submit the form.
我为按钮添加了 sr-only 类,这将使它只对屏幕阅读器可见。所以我们按回车键来提交表单。We are getting the path name and the form action url. Then we set the
queryValue to the query value in the URL. When we type in the search, we set that value to whatever is typed. When we submit, we submit to formActionUrl, which could be either admin/orders, admin/products or admin/users.
我们获取路径名和表单提交地址。然后我们将 queryValue 设置为 URL 中的 query 值。当我们在搜索框中输入时,我们将该值设置为输入的内容。当我们提交时,我们提交到 formActionUrl,它可以是 admin/orders、admin/products 或 admin/users。Add Form To Layout 将表单添加到布局
Now let's add the form to the admin layout. Open the
app/admin/layout.tsx file and add the following import:
现在让我们将表单添加到管理员布局中。打开 app/admin/layout.tsx 文件并添加以下导入:Replace the
Input with the component:
用该组件替换 Input:Remove the import for the
Input as you do not need it anymore.
删除 Input 的导入,因为你不再需要它了。Products Remove Filter 产品移除筛选器
If you go to
/admin/products it will already work because we already implemented this in the getAllProducts action.
如果你访问 /admin/products,它已经可以工作了,因为我们已经在 getAllProducts 操作中实现了这一点。Let's add an option to remove the filter. Open the
app/admin/products/page.tsx and replace the h1 heading with the following:
让我们添加一个移除筛选器的选项。打开 app/admin/products/page.tsx 并用以下内容替换 h1 标题:Now you can remove the filter.
现在你可以移除筛选器了。
Now we want it to work with orders and users.
现在我们希望它也能用于订单和用户。
8. Admin Order Searc 订单搜索
Now that we have our
admin-search component and product search working in the admin area, let's add the same functionality to orders.
既然我们已经在管理区域拥有了 admin-search 组件和产品搜索功能,现在让我们为订单添加相同的功能。We will start by having the
getAllOrders function take in a query and filter
by it.
我们将首先让 getAllOrders 函数接收一个查询参数并根据它进行筛选。Open the
orders.actions.ts file and add the following code for the getAllOrders function:
打开 orders.actions.ts 文件并为 getAllOrders 函数添加以下代码:Changes 变更
We added a new param of
query.
我们添加了一个新的 query 参数。We then added the
QueryFilter and added it to the where object in the query.
然后我们添加了 QueryFilter 并将其添加到查询的 where 对象中。Orders Page 订单页面
Now open the
app/admin/orders/page.tsx file and make the following changes:
现在打开 app/admin/orders/page.tsx 文件并进行以下更改:Add a new
query param to the SearchParams prop:
向 SearchParams 属性添加一个新的 query 参数:Pass the query into the
getAllOrders function call:
将查询传递给 getAllOrders 函数调用:In the return, replace the
h1 heading with the following:
在返回语句中,用以下内容替换 h1 标题:Now you should see an option to remove the filter.
现在您应该能看到一个移除筛选的选项。
Let's do users next.
接下来让我们处理用户。
9. Admin User Search 用户搜索
Let's add the same search functionality to users.
让我们为用户添加相同的搜索功能。
We will start by having the
getAllUsers function take in a query and filter
by it.我们将从让
getAllUsers 函数接收一个查询参数并根据它进行筛选开始。Open the
users.actions.ts file and add the following code for the getAllUsers function:打开
users.actions.ts 文件,为 getAllUsers 函数添加以下代码:Changes 变更
We added a new param of
query.我们添加了一个新的
query 参数。We then added the
QueryFilter and added it to the where object in the query.然后我们添加了
QueryFilter 并将其添加到查询中的 where 对象里。Users Page 用户页面
Now open the
app/admin/users/page.tsx file and make the following changes:现在打开
app/admin/users/page.tsx 文件并进行以下更改:Add a new
query param to the SearchParams prop:在
SearchParams 属性中添加一个新的 query 参数:Pass the query into the
getAllUsers function call:将查询参数传递给
getAllUsers 函数调用:In the return, replace the
h1 heading with the following:在返回值中,将
h1 标题替换为以下内容:Now you should see an option to remove the filter.
现在你应该能看到一个移除筛选器的选项。
Now we have admin search functionality.
现在我们已经拥有了管理员搜索功能。
📎 参考文章
- 一些引用
- 引用文章
欢迎您在底部评论区留言,一起交流~
Loading...
