diff --git "a/GPT\351\227\256\347\255\224\350\256\260\345\275\225/3\345\256\236\347\216\260\346\220\234\347\264\242\347\273\223\346\236\234\351\241\265.md" "b/GPT\351\227\256\347\255\224\350\256\260\345\275\225/3\345\256\236\347\216\260\346\220\234\347\264\242\347\273\223\346\236\234\351\241\265.md" new file mode 100644 index 0000000..3023fac --- /dev/null +++ "b/GPT\351\227\256\347\255\224\350\256\260\345\275\225/3\345\256\236\347\216\260\346\220\234\347\264\242\347\273\223\346\236\234\351\241\265.md" @@ -0,0 +1,238 @@ +# 3实现搜索结果 + +## 问ChatGPT的问题 + +现在要用 Next.js 与 chakra.ui 建`whois`站,根据如下描述与已有代码,写出`src/pages/whois/[domain].js`的代码,使用js自带fetch实现 + +### 用户案例 + +假设用户想要一个带 gantrol 的域名,比较想要 gantrol.com,用户主要想得到什么情报呢? + +- 这个域名的信息,最主要的是,有没有被注册、是否能买到 +- 有没有相关域名可以注册 + +### 外部api + +数据的结构决定代码的结构,必须了解数据,才能写出符合要求的代码。 + +```markdown +https://whois.freeaiapi.xyz/?name=${name}&suffix=${suffix} +``` + +示例:查询 gantrol.com,被拆分为 whois.freeaiapi.xyz/?name=gantrol&suffix=com + +请求的返回分为两种,不清楚怎么调用接口的同学也先别急,可以用 确认一下。 + +- available = true + + ```json + { + "status": "ok", + "name": "gantrol", + "suffix": "com", + "domain": "gantrol.com", + "creation_datetime": "2020-10-29T04:08:52Z", + "expiry_datetime": "2024-10-29T04:08:52Z", + "available": false, + "info": " Domain Name: GANTROL.COM\r\n Registry Domain ID: 2568931463_DOMAIN_COM-VRSN\r\n Registrar WHOIS Server: whois.paycenter.com.cn\r\n 《省略几百词》 .\r\n" + } + ``` + +- available = false + + ```json + { + "status": "ok", + "name": "gantrol", + "suffix": "org", + "domain": "gantrol.org", + "creation_datetime": "", + "expiry_datetime": "", + "available": true, + "info": "Domain not found.\r\n>>> Last update of WHOIS database: 2023-12-05T08:58:08Z <<<\r\n\r\nTerms of Use:..《省略几百词》.\r\n" + } + ``` + +### 基本界面设计 + +- 主页主体是Google极简风格的搜索框,商标位置先用文字“域名搜索”替代 + +- 用户搜索`gantrol.com` 后,网站跳转到`/whois/gantrol.com`,然后页面顶端是搜索框,其下是具体的域名信息 + + - "available": true, + +### 已有代码 + +#### index.js + +```jsx +import {Flex, Heading, IconButton, Input} from "@chakra-ui/react"; +import {SearchIcon} from "@chakra-ui/icons"; +import {useState} from "react"; +import {useRouter} from "next/router"; + +export default function Home() { + const [domain, setDomain] = useState(''); + const router = useRouter(); + + const handleSearch = () => { + if (domain) { + router.push(`/whois/${domain}`); + } + }; + + return ( + + 域名搜索 + + setDomain(e.target.value)} + // 基础屏幕尺寸下宽度为 90%(适用于较小屏幕的移动设备),以及中等屏幕尺寸(如平板或小型桌面显示器)下的宽度为 400px + width={{base: "90%", md: "400px"}} + /> + } + // 为按钮添加点击事件 + onClick={handleSearch} + /> + + + ); +} + + +``` + +### `src/pages/api/whois.js` + +```javascript +// 导入 Next.js 的 API 路由支持 +import { NextApiRequest, NextApiResponse } from "next"; + +// 处理 API 请求的函数 +export default async function handler(req, res) { + // 从查询字符串中获取域名和后缀 + const { domain } = req.query; + + // 检查是否提供了域名和后缀 + if (!domain) { + return res.status(400).json({ error: "缺少必要的参数:domain" }); + } + + // 解析域名和后缀 + const [name, suffix] = domain.split("."); + + // 构建外部 API 请求的 URL + const apiUrl = `https://whois.freeaiapi.xyz/?name=${name}&suffix=${suffix}`; + + try { + // 使用 fetch 发送请求到外部 API + const response = await fetch(apiUrl); + const data = await response.json(); + + // 将获取到的信息返回给客户端 + res.status(200).json(data); + } catch (error) { + // 处理可能发生的错误 + res.status(500).json({ error: "服务器错误,无法获取域名信息" }); + } +} +``` + + +## GPT 回答示例 + +> 注:回答不唯一 + +https://chat.openai.com/share/61630b22-ac41-4dac-ae29-0067e5a4b0de + +基于您提供的用户案例、外部 API 信息、基本界面设计,以及已有的 `index.js` 和 `src/pages/api/whois.js` 代码,我们可以编写 `src/pages/whois/[domain].js` 文件。这个文件将用于显示用户查询的域名信息。 + +代码将包括以下几个部分: + +1. 导入必要的模块和组件。 +2. 创建一个 React 组件,它将通过 Next.js 的 `useRouter` 钩子获取动态路由参数(即域名)。 +3. 使用 `useEffect` 钩子和 `fetch` 函数调用自定义的 `/api/whois` 接口以获取域名信息。 +4. 根据获取的数据,渲染域名信息。 +5. 处理加载状态和可能出现的错误。 + +接下来是具体的实现代码: + +```jsx +import { Box, Flex, Text, Spinner, Alert, AlertIcon } from "@chakra-ui/react"; +import { useRouter } from "next/router"; +import { useEffect, useState } from "react"; + +export default function Whois() { + const router = useRouter(); + const { domain } = router.query; + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const [domainInfo, setDomainInfo] = useState(null); + + useEffect(() => { + if (domain) { + setLoading(true); + fetch(`/api/whois?domain=${domain}`) + .then(res => res.json()) + .then(data => { + setDomainInfo(data); + setLoading(false); + }) + .catch(error => { + console.error("Error fetching domain info:", error); + setError("无法获取域名信息,请稍后重试。"); + setLoading(false); + }); + } + }, [domain]); + + if (loading) { + return ; + } + + if (error) { + return ( + + + {error} + + ); + } + + return ( + + 域名信息查询结果 + {domainInfo && ( + + 域名: {domainInfo.domain} + 是否可注册: {domainInfo.available ? "是" : "否"} + {domainInfo.creation_datetime && ( + 创建时间: {domainInfo.creation_datetime} + )} + {domainInfo.expiry_datetime && ( + 过期时间: {domainInfo.expiry_datetime} + )} + 详细信息: + {domainInfo.info} + + )} + + ); +} +``` + +在这段代码中,我们首先从路由中获取 `domain` 参数,然后使用 `useEffect` 钩子在组件加载时发送请求到我们的 API 接口。请求成功时,我们将数据存储在状态变量中,并在页面上显示它。同时,我们也处理了加载状态和可能发生的错误。 diff --git a/README.md b/README.md index 4f71c26..ba4f747 100644 --- a/README.md +++ b/README.md @@ -11,10 +11,10 @@ [ChatGPT](https://chat.openai.com/)账号可选。 -目前进度:实现主页、后端接口转发freeaiapi。 +目前进度:实现主页、后端接口转发freeaiapi、搜索结果页。 -- 部署到 Vercel: [![部署到 Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/gantrol/whois-nextjs/tree/step2&project-name=whois-nextjs&repository-name=whois-nextjs) -- 用Github在线编辑器打开:[![用Github在线编辑器打开](https://github.com/codespaces/badge.svg)](https://codespaces.new/gantrol/whois-nextjs/tree/step2) +- 部署到 Vercel: [![部署到 Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/gantrol/whois-nextjs/tree/step3&project-name=whois-nextjs&repository-name=whois-nextjs) +- 用Github在线编辑器打开:[![用Github在线编辑器打开](https://github.com/codespaces/badge.svg)](https://codespaces.new/gantrol/whois-nextjs/tree/step3) ## 基本分析 @@ -76,5 +76,5 @@ https://whois.freeaiapi.xyz/?name=${name}&suffix=${suffix} - src/pages/index.js:网站主页,[对应GPT问答记录](GPT问答记录/1设计index页面.md) - src/pages/api/whois.js:后端接口,用于转发外部接口,[对应GPT问答记录](GPT问答记录/2实现后端whois接口.md) -- src/pages/whois/[domain].js:搜索详情页 +- src/pages/whois/[domain].js:搜索详情页,[对应GPT问答记录](GPT问答记录/3实现搜索结果页.md) diff --git a/src/pages/whois/[domain].js b/src/pages/whois/[domain].js index d66e09a..f02b9b6 100644 --- a/src/pages/whois/[domain].js +++ b/src/pages/whois/[domain].js @@ -1,5 +1,61 @@ +import { Box, Flex, Text, Spinner, Alert, AlertIcon } from "@chakra-ui/react"; +import { useRouter } from "next/router"; +import { useEffect, useState } from "react"; + export default function Whois() { + const router = useRouter(); + const { domain } = router.query; + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + const [domainInfo, setDomainInfo] = useState(null); + + useEffect(() => { + if (domain) { + setLoading(true); + fetch(`/api/whois?domain=${domain}`) + .then(res => res.json()) + .then(data => { + setDomainInfo(data); + setLoading(false); + }) + .catch(error => { + console.error("Error fetching domain info:", error); + setError("无法获取域名信息,请稍后重试。"); + setLoading(false); + }); + } + }, [domain]); + + if (loading) { + return ; + } + + if (error) { + return ( + + + {error} + + ); + } + return ( -
假装有个结果页
+ + 域名信息查询结果 + {domainInfo && ( + + 域名: {domainInfo.domain} + 是否可注册: {domainInfo.available ? "是" : "否"} + {domainInfo.creation_datetime && ( + 创建时间: {domainInfo.creation_datetime} + )} + {domainInfo.expiry_datetime && ( + 过期时间: {domainInfo.expiry_datetime} + )} + 详细信息: + {domainInfo.info} + + )} + ); }