Github
如使用README的Vercel一键部署,只需看数据库创建这一步 #
效果预览:
Logo & 界面设计全来自于 ChatGPT 的 DALL·E
选用Astro,主要是轻量级快速开发,性能满分
初始化项目
- 使用官方模版
pnpm create astro@latest
- 安装TailwindCss
pnpm astro add tailwind
- 安装Vercel和数据库工具 - 白嫖Vercel免费服务器
pnpm astro add vercel
pnpm add @vercel/postgres
- 运行服务 - 访问 http://localhost:4321/
pnpm run dev
简单几步项目就运行起来了
爬取GPTs数据
发布会了,大量的GPTs被创建出来,创意的GPTs非常多
现在只需从Google里爬取即可,搜索 「site:chat.openai.com/g/」 ,即可以看到所有收录的GPTs应用
如需获取ai画画分类的话,搜索 「site:chat.openai.com/g/ Drawing」
爬虫工具使用: github.com/bda-researc…
支持使用了Cheerio/JSDOM来操作标签
也可以使用已经爬取的6800+的数据包: GPTs数据包
数据库
白嫖Vercel免费服务器,同时也使用免费的256M的 Postgres 数据库。
创建完成后,复制环境变量信息到项目的.env文件
在Vercel的Postgres页面的Query下快速创建三个表
- GPTs数据存储表
CREATE TABLE "public"."gpts_lists" (
"id" int8 NOT NULL,
"title" varchar,
"url" varchar,
"icon" varchar,
"author" varchar,
"description" text,
"content" text,
"twitter" varchar,
"youtube" varchar,
"category" varchar,
"weights" int4 DEFAULT 0,
"scores" int4 DEFAULT 0,
"created_titme" timestamptz DEFAULT now(),
"search_key" varchar,
PRIMARY KEY ("id")
);
- 分类信息表
-- Sequence and defined type
CREATE SEQUENCE IF NOT EXISTS categories_id_seq;
-- Table Definition
CREATE TABLE "public"."categories" (
"id" int4 NOT NULL DEFAULT nextval('categories_id_seq'::regclass),
"categories_name" varchar(255) NOT NULL,
PRIMARY KEY ("id")
);
- GPTs数据与分类的关系表,一个GPTs可以对应1-3个分类,多对多的关系
CREATE TABLE "public"."list_categories" (
"list_id" int4 NOT NULL,
"category_id" int4 NOT NULL,
CONSTRAINT "list_categories_category_id_fkey" FOREIGN KEY ("category_id") REFERENCES "public"."categories"("id"),
CONSTRAINT "list_categories_list_id_fkey" FOREIGN KEY ("list_id") REFERENCES "public"."gpts_lists"("id"),
PRIMARY KEY ("list_id","category_id")
);
下载数据包INSERT数据: GPTs数据包
开发API接口
按照Astro的目录规定,在pages/api创建文件即是api接口
设计了4个接口,外加1个提供给创建GPTs时自定义Actions事件使用的search接口
分类查询接口:GET /api/categories
- 全量获取所有分类
GPTs列表查询接口: GET /api/get
- 获取GPTs数据
- 参数:page - 用于翻页
- 参数:cate - 分类ID,用于查询分类下的数据
- 参数:keyword - 关键字搜索
GPTs列表总数接口: GET /api/get-count
- 获取GPTs数据总数,跟列表拆分,主要是怕数据量多时,查COUNT会导致列表数据返回慢
- 参数:cate - 分类ID,用于查询分类下的数据
- 参数:keyword - 关键字搜索
GPTs详情: GET /api/get-by-key
- 获取GPTs详情,使用key字段,是想让URL更有语义,也把key加了数据库索引
- 参数:key - 对应的是列表数据的search_key
GPTs搜索:POST /api/search.json
- 提供创建自定义GPTs的Actions使用
- 接口创建使用openapi的格式复制Actions里即可,如下展示通过助手对话查找GPTs:
页面开发
Astro 以.astro
后缀命名,语法与 JSX 语法相似。支持使用所有主流的UI框架
为了轻量开发,直接使用了astro模版语法来做SSR,数据是在服务器端读取,渲染到前端显示
前端的异步请求,使用原生JS来做交互处理,页面上实现了
- 关键字搜索
- 分类切换时数据请求和页面渲染
- 分页数据加载与渲染
分类数据渲染模块 Categories.astro
---
let lists = [{id:0,categories_name:'👌 All'},{id:-1,categories_name:'🔥 Popular'}];
const searchVal = Astro.url.searchParams.get('s') || '';
const response = await fetch(`${Astro.url.origin}/api/categories`);
if (response.ok) {
const json = await response.json();
lists.push(...json.data.lists);
}
---
<div id="categories" class="flex gap-2 flex-wrap py-4 text-sm [&_[data-status=active]]:bg-green-800 [&_[data-status=active]]:text-white [&_[data-status=active]]:border-green-800">
{
lists.map((item: {id: number, categories_name: string}) => (
<button data-status={(item.id === 0 && !searchVal) && 'active'} data-id={item.id} class="border rounded-lg px-4 py-1 bg-white hover:border-green-600 hover:text-green-600 dark:bg-black dark:border-gray-700 dark:hover:border-green-600">{item.categories_name}</button>
))
}
</div>
Astro 组件的两个代码围栏(---)之间的 frontmatter 组件脚本内部定义本地 JavaScript 变量。然后,可以使用类似 JSX 的表达式将这些变量注入到组件的 HTML 模板中!
轻量的模版语法,使用起来非常爽
更多查看仓库源码:github.com/CH563/gtps-…
部署
项目开发完成后,提交到githud
登录到Vercel,添加新项目:
选择提交上的项目,「Import」
因为已使用Astro安装了Vercel,Vercel自动配置Astro Preset
环境变量记得检查不要漏添加,不然数据库无法读取
致此,Astro就完成并部署上线了
好久没写博文了,以上只是记录了体验Astro使用和Vercel部署,如有问题或建议请指正,谢谢大家!
查看仓库源码:github.com/CH563/gtps-…