HappyShip Logo

HappyShip

使用文档

AI导航站模板配置指南

本指南将详细介绍如何配置和部署 AI 工具导航站模板,包括内容配置、环境变量设置等完整流程。

📋 模板特色

  • 用户可以提交和管理 AI 工具信息
  • 支持 GitHub OAuth 登录验证
  • 管理员后台审核系统
  • 反链获取免费展示机会

1
第一步:内容配置

Header配置

网站标题、Logo图片等信息,在网站Header部分展示。

Header配置示例

配置项:

  • • 网站标题:显示在页面顶部
  • • Logo图片:网站品牌标识
  • • 导航菜单:网站主要页面链接

关于页面

这部分的内容,在首页底部,Footer上方,并且末尾自动携带超链接,导航到Category页面。

关于页面配置示例

建议结尾格式:以 "Let's start exploring the" 结尾,系统会自动添加到Category页面的链接。

认证页面

登录页面的标题配置。

推荐格式:Login to + 你网站的品牌名

例如:Login to AI Tools Hub

提交计划配置(重点来了)

⚠️ 重要机制说明

AI导航站模板的第一个计划是 Free,需要用户复制我们网站的徽标,在他网站上,等于给我们一条反链,以此来换取在我们网站展示的机会。

提交计划配置示例

配置说明:

  • 徽章链接:一般填写我们网站首页地址
    https://happyship.app/
  • 徽章图片:需要自己制作并上传,这张图片会显示到用户自己的网站上作为反链标识。

2
第二步:环境变量配置

基础功能集成配置

以下是从 快速开始页面 复制的基础配置,AI导航站同样需要这些配置:

(1)NEXTAUTH_SECRET和NEXTAUTH_URL配置

NEXTAUTH_SECRET直接点击右侧按钮,自动生成

NEXTAUTH_URL,这里需要填写你的网站域名,你需要提前购买一个域名,这是未来和你的网站代码绑定的

假设,你的域名是happyship.app,那这一栏填写:

https://happyship.app

末尾不要带 / ,否则代码会出错

(2)GOOGLE_CLIENT_ID,GOOGLE_CLIENT_SECRET配置

首先你要注册一个Google Cloud Console账号,网址:https://console.cloud.google.com/ ,这是用谷歌账号登录的

进入到后台页面,按照图示操作

Google Console配置步骤1
Google Console配置步骤2

然后Project name就随意填写一个名字就好,点击create

Google项目创建

等待创建成功后,右上角点击select project,之后左侧dashboard按照图示,鼠标放到APIS & Services,选择Oauth consent screen

Google OAuth同意屏幕配置

进到界面,选择Get Started,然后填写好相应的信息,根据真实信息填写就好

Google OAuth表单填写

Audience选择 外部,接着按要求填写好剩下的信息,最后创建就好

Google受众选择外部
创建OAuth客户端
选择Web应用程序

创建好后 点击右侧 Create Oauth Client

选择Web应用程序

选择Web Application

选择Web应用程序

然后接下来两个添加URL的部分都要填写,假设,我购买的域名是happyship.org

那第一个就填写https://happyship.org

第二个 填写:https://happyship.org/api/auth/callback/google

注:大家填写的时候,就直接复制我这个,然后把happyship.org替换成你的域名就好,这一步很重要,不要配置错了

Google URLs配置

然后点击Create,你会获得Client ID和Client secret,填写进去HappyShip上配置界面对应的输入框就好

Google客户端凭据

(3)配置Supabase

首先注册一个Supabase账号 (https://supabase.com/) ,有免费额度,尽管用,用超了代表你也开始赚钱了

注册好后,会自动导航到创建部分,首先创建的Organiaztion,也就是组织,一个组织,有两个免费的数据库可以配置,这里我们先创建组织,自定义名字

Supabase组织创建

创建好组织后,在下一个界面会让我们Create new project,这就是数据库,我们要自己配置好名字和密码

Supabase项目创建

等待创建好后,左侧Dashbord点击最下边的Project Setting,然后选择Data API,这里的project url 复制下来,填写到HappyShip中Supabase URL的输入框

Supabase项目URL

接下来点击Go to Api

Supabase转到API

这里会显示ANON KEY和Service Role Key,填写到HappyShip的NEXT_PUBLIC_SUPABASE_ANON_KEY和SUPABASE_SERVICE_ROLE_KEY输入框,到这里,环境变量就配置好了,不过数据库我们还要配置

Supabase API密钥

左侧DashBorad,找到SQL Editor,点击进去,然后把下面的sql命令复制进去,然后点击右侧绿色按钮run 直到返回Success. No rows returned ,到这里 数据库就完全配置好了,已经可以用了

Supabase SQL编辑器
AI导航站专用 SQL 配置:
AI导航站数据库结构
-- 1. 创建用户表 (支持GitHub和Google登录)
CREATE TABLE IF NOT EXISTS public.users (
  id VARCHAR(255) PRIMARY KEY,
  email VARCHAR(255) UNIQUE NOT NULL,
  name VARCHAR(255),
  avatar_url TEXT,
  provider VARCHAR(20) NOT NULL, -- 'github' | 'google'
  provider_id VARCHAR(255) NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  total_submissions INTEGER DEFAULT 0
);

-- 2. 创建核心工具表 (包含所有必要字段)
CREATE TABLE IF NOT EXISTS public.web_navigation (
  id SERIAL PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  title VARCHAR(255),
  url VARCHAR(500),
  content TEXT,
  detail TEXT,
  category_name VARCHAR(100),
  thumbnail_url TEXT,
  image_url TEXT,
  collection_time TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  star_rating INTEGER DEFAULT 0,
  tag_name TEXT,
  website_data JSONB DEFAULT '{}',
  
  -- 用户和支付相关字段
  user_id VARCHAR(255),
  payment_status VARCHAR(20) DEFAULT 'unpaid', -- 'unpaid' | 'basic' | 'pro'
  payment_id VARCHAR(255),
  payment_time TIMESTAMP WITH TIME ZONE,
  featured BOOLEAN DEFAULT FALSE,
  submit_status VARCHAR(20) DEFAULT 'draft' -- 'draft' | 'pending' | 'published' | 'rejected'
);

-- 3. 创建支付记录表 (专用于Stripe支付)
CREATE TABLE IF NOT EXISTS public.payments (
  id SERIAL PRIMARY KEY,
  tool_id INTEGER REFERENCES public.web_navigation(id),
  user_id VARCHAR(255) REFERENCES public.users(id),
  plan_type VARCHAR(20) NOT NULL, -- 'basic' | 'pro'
  amount DECIMAL(10, 2) NOT NULL,
  currency VARCHAR(3) DEFAULT 'USD',
  stripe_payment_intent_id VARCHAR(255) NOT NULL, -- Stripe PaymentIntent ID
  stripe_session_id VARCHAR(255), -- Stripe Checkout Session ID
  status VARCHAR(20) DEFAULT 'pending', -- 'pending' | 'completed' | 'failed' | 'refunded'
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  stripe_metadata JSONB DEFAULT '{}' -- 存储Stripe相关的额外信息
);

-- 4. 创建分类表 (保持现有结构)
CREATE TABLE IF NOT EXISTS public.navigation_category (
  id SERIAL PRIMARY KEY,
  name VARCHAR(255) NOT NULL,
  title VARCHAR(255),
  sort INTEGER,
  create_time TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  create_by INTEGER,
  del_flag INTEGER DEFAULT 0
);

-- 创建标签表
CREATE TABLE IF NOT EXISTS public.tags (
  id SERIAL PRIMARY KEY,
  name VARCHAR(255) UNIQUE NOT NULL,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);

-- 添加索引
CREATE INDEX IF NOT EXISTS idx_tags_name ON public.tags(name);

-- 插入现有的标签数据
INSERT INTO public.tags (name) VALUES
('Text Generation'),
('Image Generation'),
('Video Generation'),
('Audio Generation'),
('Music Creation'),
('Speech to Text'),
('Text to Speech'),
('Chatbot'),
('Virtual Assistant'),
('Copywriting'),
('Content Creation'),
('Social Media'),
('Cold Emails'),
('Marketing'),
('SEO'),
('Advertising'),
('Conversion'),
('CRM'),
('Communication'),
('Community'),
('Productivity'),
('Automation'),
('Low-Code'),
('No-Code'),
('Code Generation'),
('API Integration'),
('Data Analysis'),
('Data Visualization'),
('Machine Learning'),
('Summarization'),
('Translation'),
('Education'),
('E-Learning'),
('Healthcare'),
('Finance'),
('Legal'),
('HR'),
('Recruitment'),
('Customer Support'),
('E-commerce'),
('Gaming'),
('Design'),
('Graphic Design'),
('Video Editing'),
('Animation'),
('3D Modeling'),
('Security'),
('Cryptography'),
('Research'),
('Knowledge Base')
ON CONFLICT (name) DO NOTHING;

-- 添加更新时间触发器
CREATE TRIGGER update_tags_updated_at BEFORE UPDATE ON public.tags 
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

-- 添加索引以提升查询性能

-- web_navigation 表索引
CREATE INDEX IF NOT EXISTS idx_web_navigation_user_id ON public.web_navigation(user_id);
CREATE INDEX IF NOT EXISTS idx_web_navigation_payment_status ON public.web_navigation(payment_status);
CREATE INDEX IF NOT EXISTS idx_web_navigation_featured ON public.web_navigation(featured);
CREATE INDEX IF NOT EXISTS idx_web_navigation_submit_status ON public.web_navigation(submit_status);
CREATE INDEX IF NOT EXISTS idx_web_navigation_category_name ON public.web_navigation(category_name);
CREATE INDEX IF NOT EXISTS idx_web_navigation_collection_time ON public.web_navigation(collection_time);

-- users 表索引
CREATE INDEX IF NOT EXISTS idx_users_email ON public.users(email);
CREATE INDEX IF NOT EXISTS idx_users_provider ON public.users(provider);
CREATE INDEX IF NOT EXISTS idx_users_provider_id ON public.users(provider_id);

-- payments 表索引
CREATE INDEX IF NOT EXISTS idx_payments_user_id ON public.payments(user_id);
CREATE INDEX IF NOT EXISTS idx_payments_tool_id ON public.payments(tool_id);
CREATE INDEX IF NOT EXISTS idx_payments_status ON public.payments(status);
CREATE INDEX IF NOT EXISTS idx_payments_stripe_payment_intent_id ON public.payments(stripe_payment_intent_id);
CREATE INDEX IF NOT EXISTS idx_payments_created_at ON public.payments(created_at);

-- 添加更新时间触发器
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
    NEW.updated_at = CURRENT_TIMESTAMP;
    RETURN NEW;
END;
$$ language 'plpgsql';

-- 为需要的表添加触发器
CREATE TRIGGER update_users_updated_at BEFORE UPDATE ON public.users 
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();

CREATE TRIGGER update_payments_updated_at BEFORE UPDATE ON public.payments 
    FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
可选:网站基础信息表

以下两个SQL文件包含分类和示例工具数据,可根据需要选择性执行:

插入分类数据 (insert_category_data.sql)
下载 SQL 文件

用于插入AI工具分类数据,包含助手聊天、内容创作、图像视觉、视频音频等多个分类。

插入示例工具数据 (insert_data.sql)
下载 SQL 文件

包含示例AI工具数据,如ChatGPT、Adobe、Suno AI等热门工具信息,可作为网站初始内容使用。

(4)配置Cloudflare R2(图片存储服务)

说明:Cloudflare R2是用于存储用户上传图片的对象存储服务,配置后可以实现图片的上传和访问功能。

首先进入Cloudflare(https://www.cloudflare.com/zh-cn/),注册一个账号

Cloudflare注册页面

进入后在左侧Dashboard往下滑,找到R2对象存储,然后点进去后,点击右侧的创建存储桶

R2对象存储创建存储桶

然后正常填写存储桶的名字就好,别的配置保持默认不用变

然后点击左上角R2对象存储回到R2主界面

返回R2主界面

然后如图所示,点击API,然后点击下面的管理API令牌

管理API令牌

进去后点击下面的创建User令牌

创建User令牌

名字任意,然后权限设置成最上面的"管理员读和写",别的保持默认,然后滑动到最下面,点击创建

设置令牌权限

重要配置说明:

  • Cloudflare R2 Access Key ID对应的就是"访问密钥 ID"
  • Cloudflare R2 Secret Access Key对应的就是"机密访问密钥"
  • Cloudflare R2 Endpoint对应的就是"为 S3 客户端使用管辖权地特定的终结点"

直接复制到HappyShip对应位置就好

复制API凭据

接下来点击完成,返回R2的主界面,点击进去我们刚才创建的存储桶,点击设置,然后点击左侧的自定义域,点击添加,然后自定义一个存储桶的域名

比如我的主域名是happyship.app,那给存储桶的域名一般是image.happyship.app,或者asset.happyship.app,这样的子域名,不能直接拿主域名,而是要在前边加入任意的后缀

注意:这一步的前提是,你的主域名要绑定在了Cloudflare,如果还没有绑定,可以看一下我这篇公众号文章,滑到底部,有讲怎么把购买后的域名绑定到Cloudflare(https://mp.weixin.qq.com/s/O2XQ2HXgaAD6lT9josg3FQ

自定义域名配置

绑定好了之后,在HappyShip需要填写的CLOUDFLARE_R2_PUBLIC_URL,比如我绑定的子域名是image.happyship.app,那我需要填写:https://image.happyship.app

然后Cloudflare R2 Bucket Name对应的就是你存储桶之前的命名

如果你忘记了名字,可以看我图片这里,找到你自己存储桶的名字

查看存储桶名字

(5)配置Stripe

请先确保你注册了Stripe,并且开通了商户,Stripe开通教程:https://mp.weixin.qq.com/s/br0anhSFN8qXlnbogk-sfg

创建好Stripe商家后,会进入一个test/sandbox模式,也就是测试模式,这里需要退出来,进入真实模式

进入了真实模式之后,在右侧会有Publishable key和Secret key,直接复制进去HappyShip的STRIPE_SECRET_KEY和NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY输入框中

Stripe密钥配置

接着点击左侧Product catalog,然后如图示,右侧创建产品

Stripe产品目录

接着填写产品名字,还有设置价格。价格一般是把币种选择为USD,然后输入你希望的价格,然后名字的话,我们一共要创建两个产品,分别填写BASIC和PRO,然后Description可以空着,最重要的是一点要选择Recurring

Stripe产品定价

创建好两个产品后,分别点击进去两个产品,如图所示,找到price id,复制进去HappyShip中的STRIPE_BASIC_PRICE_ID和STRIPE_PRO_PRICE_ID

注:看清楚哪个是basic,哪个是pro,别搞混了

Stripe价格ID

接着点击左下角Developers,在弹出的栏目选择Webhooks,接着Add destination

Stripe Webhooks配置

勾选:

  • checkout.session.completed
Stripe Webhook事件选择1

配置好后如图2所示

Stripe Webhook事件选择2

点击下一步,默认勾选Webhook

Stripe端点URL配置

最后只需要修改Endpoint URL

举个例子,我的域名是happyship.org,那这里就要填

https://happyship.org/api/stripe/webhooks

大家实际做的时候,只需要把我这个复制,然后把域名替换就好,好了之后点击Create,就大功告成了

Stripe端点URL配置

最后创建好后,重新打开这个webhooks,点进去,右侧有个secret,把这串secret复制,粘贴到HappyShip的STRIPE_WEBHOOK_SECRET配置

Stripe Webhook密钥

到这一步全部在HappyShip网站的配置就完成了,进入最后预览确认界面,点击推送

AI导航站特有配置

NEXT_PUBLIC_SITE_URL

配置网站的基础URL地址。

配置格式:

NEXT_PUBLIC_SITE_URL=https://你的域名.com

举个例子:https://happyship.app (把//后面改成你的域名就好,末尾不要带/)

GitHub OAuth配置

配置 GitHub OAuth 应用,用于用户登录验证。

第一步:创建 GitHub OAuth App

1. 准备一个 GitHub 账号,然后进入:

https://github.com/settings/developers

2. 点击右上角 "New OAuth App"

GitHub OAuth App创建页面

第二步:填写 OAuth App 信息

Application name:

随便填写

Homepage URL:

https://你的域名.com

把域名改成你的域名就好,末尾不要带/

Authorization callback URL:

https://你的域名.com/api/auth/callback/github

只需要把域名替换成你的域名就好,别的不用动

GitHub OAuth App信息填写页面

第三步:获取配置信息

创建完成后,你会看到:

  • GitHub Client ID 对应 Client ID,直接复制
  • GitHub Client Secret 需要点击 "Generate New Client Secret" 按钮生成,然后复制
GitHub OAuth App配置信息获取页面

管理员账户配置

配置管理员用户名和密码,用于登录网站后台管理系统。

配置说明:

  • 管理员用户名:自定义设置,建议使用易记忆的用户名
  • 管理员密码:自定义设置,建议使用强密码

注意:请妥善保管管理员账户信息,用于登录网站后台,批准、删除用户提交的工具。

管理员后台地址

配置完成后,可以通过以下地址访问管理员后台:

后台地址格式:

https://你的域名.com/master

例如:HappyShip的AI导航站模板管理员后台地址是:https://ai-navigation-temp.vercel.app/master
把域名替换成你的域名就好

3
授权Github App推送代码

为什么需要Github App授权?

为了提高安全性,HappyShip 现在使用 Github App 的方式来推送代码,而不是传统的 OAuth 方式。这样您只需要授权特定组织的读写权限,而不是所有代码库的权限,大大降低了安全风险。

重要:这个授权过程只需要进行一次,后续所有的代码库都将自动在您的组织下创建和推送。

创建Github组织

首先,您需要在Github中创建一个组织来存放您的项目代码:

2

选择 "Free" 免费计划

3

填写组织名称(建议使用您的用户名或项目名称)

Github创建组织页面,显示组织名称输入框
4

点击 "Complete Setup" 完成创建

Github组织创建完成页面

✅ 完成!

组织创建完成后,当您在 HappyShip 中点击"推送代码"时,系统会自动引导您安装 Github App 到这个组织。安装完成后,所有后续的代码库都会自动在这个组织下创建。

4
把代码部署到Vercel

⚠️ 重要变更通知

Vercel 近期变更了政策,不再允许用户免费部署组织中的代码库。为了继续使用免费部署服务,您需要将代码库从组织转移到个人账户。

操作步骤:在代码推送到组织后,进入组织仓库的 Settings → Danger Zone → Transfer repository,点击并输入指定字符串,确认转移到个人账户。

仓库转移操作

代码推送到组织后,需要先将仓库转移到个人账户,然后再进行Vercel部署:

1

进入组织中的代码仓库页面

Github仓库Settings页面,显示Danger Zone中的Transfer repository选项
2

点击 Settings → 然后鼠标往下滑动到页面底部,找到 Danger Zone → Transfer repository

Github仓库Settings页面,显示Danger Zone中的Transfer repository选项
Github仓库Settings页面,显示Danger Zone中的Transfer repository选项
3

Select one of my organizations : 选择你的个人Github用户名作为新的所有者

4

输入指定的确认字符串,点击确认转移

仓库转移确认对话框,显示输入确认字符串的界面

后续即可按照常规Vercel流程进行部署:

部署成功页面

点击右上角头像---Your repositories,然后找到刚才在HappyShip创建的仓库,点击进入仓库页面,找到名字叫做环境变量的文件,点开,然后复制里边的内容

部署成功页面
部署成功页面

注:不要复制带# 号的内容,就只复制下面配置的,如图

GitHub环境变量文件

之后,在推送成功页面打开Vercel,如果没注册过账号的,注册一下。每个账号都有免费额度,足够用了,还是那句话,等你需要付费的时候,你已经开始赚钱了,前期不要考虑这么多,最快捷最方便把网站启动才是关键,专心搞流量

接着注册登录后,选择Continue with Github,然后登陆在HappyShip网站上你登录的Github账号

注:这里一定要是同一个Github账号,否则会出现代码不同步的情况。

Vercel GitHub登录

当你创建好后,就会出现类似我图片中这样,让你选择一个你Github目前账号中存在的代码仓库,进行导入。如果你记得仓库名,就直接点击右侧import,这时候我们可以回到刚才的推送成功页面,然后如图所示,找到刚才生成的仓库名

Vercel导入仓库
Vercel导入仓库

接着往下拉,如图所示,鼠标点开Environment Variables,把我们刚才在环境变量文件中复制的东西一次性粘贴进去。

注:这里不需要一行一行粘贴,直接像我刚才提到的,除去#号的段落,别的一次性复制,然后Vercel支持一次性粘贴,好了之后点击Deploy就好了,然后等待生成成功

Vercel环境变量配置

生成好后,进入这个项目,然后上方一栏找到Setting,点击后左侧找到Domains,可以把你购买的域名添加进去,这就就大功告成了

Vercel域名配置

🎉 配置完成!

恭喜!您已经完成了 AI 导航站模板的完整配置。现在您的网站具备以下功能:

用户功能:

  • GitHub 登录验证
  • 提交 AI 工具信息
  • 免费展示机会获取

管理功能:

  • 管理员后台系统
  • 工具审核和管理
  • 反链机制管理

目录