今年的情人节,给心爱的她一个不一样的礼物吧

今天是 2022 年 2 月 2 日,距离今年的情人节只有不到两周的时间了。

给大家隆重介绍一个网站,憨憨.我爱你

参考示例网站:

  • 表白幻灯片.憨憨.我爱你
    • 源码
  • 恋爱计时器.憨憨.我爱你
    • 源码

目录

  • 申请流程
    • 域名申请
    • 邮箱申请
    • 其他说明
      • 如需帮助
      • 还想要其他的域名
      • 感觉慷慨
      • 跃跃欲试
  • 开源
    • 设计
      • 技术选型
      • 数据库设计
      • 技术准备
      • 接口设计
    • 代码实现
      • 封装 Cloudflare SDK
      • 封装校验工具类
      • 页面请求封装
      • 注意点

申请流程

打开官网首页: 憨憨.我爱你

(由于该网站数据库使用的是 PlanetScale 免费服务,位于美东,所以访问可能会稍微有点慢。请耐心等待。)

请添加图片描述

使用 Authing 账号登录(可以手机、邮箱注册,Github 账号登录,或者微信小程序扫码,后续还会添加更多登录方式)。

请添加图片描述

可以分别点击进入域名申请和邮箱申请。

域名申请

域名申请界面如下:

请添加图片描述

支持的绑定方式有三种:

  • CNAME: 可以使用 Github Pages、 Netlify、 Gitee、 Coding.net、 Cloudflare 等提供托管服务的平台
    • 值参考: willin.github.io
    • 注意: 不支持 Vercel ,因为 Vercel 默认情况下并不支持绑定二级域名(除非所有权在你个人名下)
  • A: IPv4 需要自己搭建服务器,并进行绑定
    • 值参考: 1.2.3.4 (你服务器的 ip 地址)
  • AAAA: IPv6 需要自己搭建服务器,并进行绑定
    • 不做表述,不太推荐非专业人士选择
    • 如果你需要同时绑定 IPv4 和 IPv6 的话,建议建议注册 A 类型,然后 ISSUE 或邮件联系我配合处理

其中还有一项 Proxied(CDN),如果不知道作用,可以尝试开启或关闭来测试。

邮箱申请

域名申请界面如下:

请添加图片描述

目前使用了 Cloudflare 的邮件转发服务,但由于暂不支持 IDN 域名,所以可以提前抢注,第一时间拥有。

其他说明

如需帮助

欢迎在 Github 上关注我: willin ,如果在为心爱的她准备礼物时遇到问题,可以为你免费提供技术咨询。

还想要其他的域名

  • js.cool (在多次协商后,目前已经支持 Vercel 绑定)
  • log.lu (敬请期待)

感觉慷慨

  • 您可以将该网站分享给更多的人
  • 您也可以通过以下渠道进行打赏:
    • 微信
    • 支付宝
    • 爱发电
    • Github Sponsors
    • Paypal

跃跃欲试

或许你也有很多想法,想要实现。您可以:

  • 使用 Authing 快速集成开发你自己的应用
  • Fork 本项目源码(完全开源),并提供你自己的域名服务
    • 项目源码
  • 在 Github 上对本项目进行完善和优化
    • 项目后续规划

开源

接下来,开始一个重要的环节。俗话说,授人以鱼不如授人以渔。我将 憨憨.我爱你 的源码 进行开源,并详细讲解一下设计与实现的全部过程。

设计

这个项目大概花了我 3 个小时左右完成。为了扬长避短,我使用了 UI 框架,所以就没有额外的 UI 设计了,直接用几个基础组件快速上手该项目。

技术选型

首先,第一步是技术选型。因为我要提供的是一项免费的服务,所以尽量也选择一些免费的服务商,及一些相关的技术栈。

服务商的选择:

  • Cloudflare: 提供免费的域名解析、CDN 加速以及开放的接口
  • Vercel: 面向个人的免费应用托管,支持 Node.js 环境,使用 Next.js 框架
  • PlanetScale: 具有一定免费额度的云端 MySQL 服务
  • Prisma: Cloud Studio 管理数据库

其实,本来是想使用 Cloudflare 全家桶的,就是用 Cloudflare Pages (静态网站) + Cloudflare Workers (Serverless 方法执行)及 KV (键值对存储),但是由于时间和精力的限制,所以就采用了更简单快捷的实现方式。

技术栈:

  • Typescript: 虽然我喜欢用更少的代码做更多的事情,但 TS 带给我更高效的团队协作舞台
  • Next.js: 一个全栈框架(前端使用 React,后端类似于 http 模块和 Express),支持 SSR(服务器端渲染)和 SSG(静态站点生成)
    • @authing/nextjs: Authing SSO 集成 SDK
  • Prisma: 下一代的 ORM 框架,支持多种数据库(本项目使用为 MySQL)和数据库迁移(Migration)
  • Tailwind CSS: 下一代的 CSS 框架,实用第一
    • Daisy UI:封装了一些 UI 样式组件

数据库设计

由于我用的是 Authing 用户集成,所以省去了用户表的设计和用户相关接口的设计。

// 域名类型
enum DomainType {AAAAACNAME
}// 审核状态
enum Status {// 待审核PENDING// 激活ACTIVE// 已删除DELETED// 被管理员禁用BANNED
}// 域名记录表
model Domains {// Cloudflare 域名记录的 ID,同时作为表主键 idid        String      @id @default(cuid()) @db.VarChar(32)// 自增 id,没有什么实际意义,只是为了减少查询(毕竟有调用配额限制),实际项目中不推荐自增主键及自增 id 使用no        Int         @default(autoincrement()) @db.UnsignedIntname      String      @db.VarChar(255)punycode  String      @db.VarChar(255)type      DomainType  @default(CNAME)content   String      @default("") @db.VarChar(255)proxied   Boolean     @default(true)// Authing 的用户 iduser      String      @default("") @db.VarChar(32)status    Status      @default(ACTIVE)createdAt DateTime    @default(now())updatedAt DateTime    @updatedAt@@index([no])@@index([name, punycode])@@index([user, status, createdAt])
}// 邮箱表
model Emails {// 由于 Cloudflare 邮箱还没有提供开放接口,所以需要人工审核和操作,这里会填入默认的 cuid 作为主键 idid        String      @id @default(cuid()) @db.VarChar(32)// 自增 id,没有什么实际意义,只是为了减少查询(毕竟有调用配额限制),实际项目中不推荐自增主键及自增 id 使用no        Int         @default(autoincrement()) @db.UnsignedIntname      String      @db.VarChar(255)punycode  String      @db.VarChar(255)content   String      @default("") @db.VarChar(255)user      String      @default("") @db.VarChar(32)status    Status      @default(PENDING)createdAt DateTime    @default(now())updatedAt DateTime    @updatedAt@@index([no])@@index([name, punycode])@@index([user, status, createdAt])
}

非常简单,参考注释说明。另外,我本来是打算只存一个名称的,但由于会重复注册,比如说我注册了一个中文名老王,你又注册了一个对应的 punycode 代码名 xn--qbyt9x,就会冲突,所以索性(偷懒)都存下吧。

技术准备

  • 中文域名需要掌握的 Punycode 知识: RFC 3492 规范
  • Cloudflare API 接口
    • 创建一条解析: Create DNS Record
    • 修改一条解析: Patch DNS Record
    • 删除一条解析: Delete DNS Record
  • Authing SSO 集成,可以参考我之前的文章: 《全栈框架应用快速集成 Authing SSO》

先把 Next.js 网站框架搭建起来,部署到 Vercel 上进行测试。可以再加上 Tailwind CSS 和 Authing SSO 集成。第一步准备工作就算完成了。

接口设计

为了快速(偷懒)实现,我分别创建了增删改查四个接口。

查询接口:

检查域名是否存在
F
T
T
F
T
F
Start
是否登录
失败
End
检查是否为保留域名
检查数据库重复
允许注册

创建接口:

创建域名
F
T
T
F
T
F
T
F
Start
是否登录
失败
End
检查是否为保留域名
用户是否已经注册域名
检查数据库重复
注册

数据库查询用户是否已经注册域名和是否存在同名可以用一次查询完成,这里为了提高查询性能进行了拆分。

修改接口:

检查域名是否存在
F
T
F 修改记录数 0
T
Start
是否登录
失败
End
修改 id 和 用户匹配的记录
修改成功

删除接口与修改接口同。邮箱接口与域名类似,不再赘述。

代码实现

封装 Cloudflare SDK

当然也有现成的库可以直接用,但是因为没几行代码,我就自己手撸了。

import { Domains } from '@prisma/client';
import { CfAPIToken, CfZoneId } from '../config';const BASE_URL = 'https://api.cloudflare.com/client/v4';export type CFResult = {success: boolean;result: {id: string;};
};const headers = {Authorization: `Bearer ${CfAPIToken}`,'Content-Type': 'application/json'
};export const createDomain = async (form: Pick<Domains, 'name' | 'content' | 'type' | 'proxied'>
): Promise<string> => {const res = await fetch(`${BASE_URL}/zones/${CfZoneId}/dns_records`, {method: 'POST',headers,body: JSON.stringify({ ...form, ttl: 1 })});const data = (await res.json()) as CFResult;if (data.success) {return data.result.id;}return '';
};export const updateDomain = async (id: string,form: Pick<Domains, 'name' | 'content' | 'type' | 'proxied'>
): Promise<boolean> => {const res = await fetch(`${BASE_URL}/zones/${CfZoneId}/dns_records/${id}`, {method: 'PATCH',headers,body: JSON.stringify({ ...form, ttl: 1 })});const data = (await res.json()) as CFResult;console.error(data);return data.success;
};export const deleteDomain = async (id: string): Promise<boolean> => {const res = await fetch(`${BASE_URL}/zones/${CfZoneId}/dns_records/${id}`, {method: 'DELETE',headers});const data = (await res.json()) as CFResult;return !!data.result.id;
};

封装校验工具类

需要有一定的正则基础,如果你需要在线调试工具,可以访问: regexper.js.cool

域名(CNAME)校验正则:

/^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$/;

邮箱校验正则:

/^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;

IPv4 校验正则:

/^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;

IPv6 校验正则:

/^((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])){3}))|:)))(%.+)?$/;

页面请求封装

以域名注册提交为例:

async function submit(e: SyntheticEvent) {e.preventDefault();// 因为我 Vue、 React 都会用,且用的都比较少// 所以获取表单数据,我用的是 Vanilla JS 方式,通用性更高// 如果你不熟悉,可以用 React 的方式const target = e.currentTarget as typeof e.currentTarget & {type: { value: DomainType };content: { value: string };proxied: { checked: boolean };};const type = target.type.value;const content = target.content.value;if (!validateContent(type, content)) {return;}const form = {type,content,proxied: target.proxied.checked,name,punycode: toASCII(name)};// 我建议对 Fetch 进行封装,为了追求效率(偷懒),我就没有做const res = await fetch(`/api/domain/create`, {method: 'POST',body: JSON.stringify(form),headers: {'content-type': 'application/json'}});// 所以像这样的处理,就非常不优雅,而且还可以统一封装,将错误提示使用通知条组件之类的const result = (await res.json()) as { success: boolean; id: string };if (result.success) {router.reload();} else {alert('出错啦!请稍后重试');}
}

可复用的代码可以进行封装。参考软件工程的思想:高内聚、低耦合。我这里举的是一个较为反面的教材,代码臃肿、可读性低。

注意点

  • 由于 Tailwind CSS 3 采用了全新的 JIT 机制,purgecss 不再需要
  • 关注 React 性能,如 useState 之类的 Hooks,尽量放在页面级别,不要放在组件级别(尤其是会循环生成的组件)
  • 使用 useMemodebounce 之类的方式进行缓存、防抖、限流,以提升应用性能
  • 使用 Next.js 框架(或普通 React 应用)时,大部分情况下,多了解 swr 及其内部的一些核心思想会很有裨益

剩下的代码部分就枯燥且简单了。


差不多就讲这么多吧。记得分享哦!

willin | 憨憨.我爱你 | 项目源码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/56069.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python 告诉你,情人节该送什么礼物?

作者 | 丁彦军 责编 | 伍杏玲 掐指一算 明天就是情人节了&#xff01; 还没来得及准备的人 要么被打断腿&#xff0c;要么注孤生 不过目测已经有一大批直男 已经为送什么礼物发愁了 还在送掺杂着布偶的鲜花束&#xff1f; 还在发五块二毛的大红包&#xff1f; 有没有想过为啥别…

情人节礼物怎么选?适合送给女朋友的数码好物

再过几天就是2.14日情人节了&#xff0c;很多情侣可能都是异地&#xff0c;不能一起过&#xff0c;虽然小编不是一个浪漫的人&#xff0c;但是节日仪式感还是要有的&#xff01;人不能在一起&#xff0c;但是礼物不能少&#xff0c;下面来看看几款数码好物吧&#xff01; 【蓝…

情人节,程序员到底该怎么给对象挑礼物?

下周就要情人节了&#xff0c;我知道&#xff0c;你们着急&#xff0c;买点什么送给我心爱的对象呢&#xff1f; 作为一名程序员&#xff0c;如何快乐简单不掉头发的为各种节日安排好女朋友的礼物可能是个难题。 当网络上在讨论程序员的时候&#xff0c;脸谱化的礼物往往就是…

七夕情人节生日节日表白网页,不是程序员也会用~

话不多说&#xff0c;直接给xdm上干货&#xff0c;不是程序员也能用&#xff0c;快给你的另一半不一样的romance吧&#xff01; 目录 一、效果 二、代码 一、效果 二、代码&#xff08;要视个人情况修改的数据本人已注释&#xff0c;图片可以放上你们甜蜜的照片哦&#xff0…

送给TA的浪漫程序礼物

❉ 520程序员求婚HtmlJsCss烟花❤ (爱心3D动画,自定义文字&#xff0c;背景音乐)/ 程序员表白必备 一年一度的/520情人节/七夕情人节/生日礼物/告白师妹/程序员表白, 非常经典的程序员式的表达爱情的方式&#xff0c;是你哄女朋友开心的终极武器。在人们的印象中&#xff0c;程…

还没有表白神器?情人节来喽,快为心爱的她送上一份专属的礼物吧~

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; &#x1f33b;&#x1f33b;&#x1f33b;Hello&#xff0c;大家好我叫是Dream呀&#xff0c;一个有趣的Python博主&#xff0c;多多关照&#x1f61c;&#x1f61c;&#x1f61c; &#x1f3…

程序员在情人节送什么礼物呢?

点击上方“程序人生”&#xff0c;选择“置顶公众号” 第一时间关注程序猿&#xff08;媛&#xff09;身边的故事 情人节快到了&#xff0c;程序员们给女友准备什么惊&#xff08;奇&#xff09;喜(葩)的礼物呢&#xff1f;看看下面的程序员怎么答的吧—— 世界有一种语言&…

七夕送什么礼物会让对方惊喜呢!2022最全情人节礼物指南

不知不觉这一年的七夕情人节就要来临啦&#xff01;生活中喜欢给对方制造小惊喜的人一定不会错过这个节日的了。虽然说礼物的款式很多好像很好选&#xff0c;但是真的到了要挑礼物的时候却不知道选什么礼物了&#xff01;于是作为一个好物测评博主&#xff0c;为了让大家能够挑…

【烟花代码】,情人节,情侣生日礼物代码适用

【烟花代码】&#xff0c;情人节&#xff0c;情侣生日礼物代码适用 老规矩&#xff0c;先上效果图 图片做了加速处理&#xff0c;放樱花的位置&#xff0c;速度完全由点击控制。 1初始化粒子系统 var Particle function(x, y, hue){this.x x;this.y y;this.coordLast [{…

七夕节送女朋友什么礼物最好、七夕最走心的礼物清单

现在的人&#xff0c;对于七夕节&#xff0c;有着说不出来的感觉&#xff0c;微妙又复杂&#xff0c;尤其是部分年轻人&#xff0c;已经把七夕节当成了情人节&#xff0c;对自己喜爱的人&#xff0c;送礼物&#xff0c;买手机&#xff0c;各种讨好&#xff0c;礼物并没规定大小…

情人节送什么礼物?四款情人节潮流数码好物推荐

情人节是一个特别的日子&#xff0c;是表达爱意和祝福的机会&#xff0c;如果您正在寻找一件特别的礼物&#xff0c;下面这篇文章不容错过。 推荐1&#xff1a;南卡小音舱蓝牙耳机&#xff08;299元&#xff09; 作为最能表达仪式感和诚意的礼物&#xff0c;精致和实用是很重要…

送给女朋友的情人节礼物---超贴心小程序

送给女朋友的情人节礼物 使用云开发 云函数云存储云数据库 目前只开放体验版 我们的视频教程(免费)链接为https://static-b5208986-2c02-437e-9a27-cfeba1779ced.bspapp.com/ 天气预报语音合成 会返回天气预报得语音 天气预报获取 天气预报 api https://tianqiapi.com/ f…

七夕情人节送女朋友什么礼物?七夕情人节礼物推荐

七夕情人节送女朋友什么礼物最好呢&#xff1f;七夕作为我们的传统情人节&#xff0c;当然送礼物要用心浪漫啦&#xff0c;今天就给大家介绍几款干货满满的七夕礼物清单吧&#xff0c;有了这些再也不用担心不会挑礼物啦。 一、南卡runner pro3骨传导耳机 这种不伤耳的骨传导耳…

HTML5适合的情人节礼物有纪念日期功能

前言 利用HTML5&#xff0c;css&#xff0c;js实现爱心树 以及 纪念日期的功能 网页有播放音乐功能 以及打字倾诉感情的画面&#xff0c;非常适合情人节送给女朋友 具体的HTML代码 具体只要修改代码里面的男某某和女某某 文字段也可自行修改&#xff0c;还有代码下半部分的J…

情人节的程序员浪漫表白HTML礼物(生日亦可用)

首页展示 前言 上次写了份代码是去年七夕节为我的一个好友弄百日纪念日写的&#xff0c;有兴趣的朋友可以看一下https://blog.csdn.net/weixin_43341045/article/details/98533156&#xff0c;明天就是情人节了&#xff0c;无论你是和她&#xff08;他&#xff09;过一个浪漫的…

适合送女朋友的情人节礼物?畅销火热的好物分享

这不马上就到2.14情人节了吗&#xff0c;大家都准备好情人节礼物送给女/男朋友了吗&#xff1f;如果还没有&#xff0c;不妨来看看我为大家推荐的几款畅销火热的好物&#xff0c;总有一款是喜欢的。 一、南卡小音舱蓝牙耳机 蓝牙耳机了解一下&#xff0c;很多人都喜欢戴着耳机听…

情人节送给粉丝的礼物

怦然心动 今天是七夕&#xff0c;一个牛郎和织女鹊桥相会的日子。 还有他们的孩子也跟他们在一起。 感谢你们一直陪伴至今&#xff0c;我不善于表达&#xff0c;我对你们的感激都在这张画布里。 代码不算多&#xff0c;特效也不是很花哨&#xff0c;情人节她更在意的是你口中的…

内网使用数据库工具访问数据库Chat2DB

Chat2DBChat2DB&#x1f680;智能的通用数据库工具和SQL客户端&#xff08;General-purpose database tools and SQL clients with AI (ChatGPT)&#xff09;,支持MySQL、PostgreSQL、Oracle、SQLServer、ClickHouse、OceanBase、H2、SQLite等等 https://chat2db.opensource.al…

大型语言模型综述全新出炉!从T5到GPT-4最全盘点,国内20余位研究者联合撰写...

点击下方卡片&#xff0c;关注“CVer”公众号 AI/CV重磅干货&#xff0c;第一时间送达 点击进入—>【计算机视觉】微信技术交流群 转载自&#xff1a;机器之心 为什么仿佛一夜之间&#xff0c;自然语言处理&#xff08;NLP&#xff09;领域就突然突飞猛进&#xff0c;摸到了…

【案例教程】GPT模型支持下的Python-GEE遥感云大数据分析、管理与可视化技术及多领域案例实践实践技术

随着航空、航天、近地空间等多个遥感平台的不断发展&#xff0c;近年来遥感技术突飞猛进。由此&#xff0c;遥感数据的空间、时间、光谱分辨率不断提高&#xff0c;数据量也大幅增长&#xff0c;使其越来越具有大数据特征。对于相关研究而言&#xff0c;遥感大数据的出现为其提…