使用 Cursor 從 0 到 1 開發一個全棧 chatbox 項目

大家好,我是 luckySnail,你肯定用過 AI 聊天工具。例如: Gemini,ChatGPT,claude AI 等產品,我們通過它們的 web 網站或者手機應用提出問題,得到答案。在之前如果你想要構建一個這樣的 AI 聊天應用程序,是需要大量時間才能開發出來,但是接下來,我將使用 cursor + vercel 的 Next.js 和 ai-sdk 快速搭建屬于你自己的 AI chat 工具,通過這篇文章你可以看到 AI 強大的輔助編程能力和 vercel 家超贊的工具!同時也能了解如何使用 AI 從 0 到 1 構建一個 web 應用,先看一下最終的產品:

image.png

如果你想直接看源碼: https://github.com/coderPerseus/easyChat 我還使用 deepwiki 生成了對應的項目文檔: https://deepwiki.com/coderPerseus/easyChat

環境準備

在正式開發前,你的設備需要有如下環境:

  • Node >= 18.18,pnpm 作為依賴管理工具

  • postgreSQL ,可以是本地或者在線

  • Curosr ,用作 AI 輔助編程

  • chrome 游覽器,其他游覽器也可

你需要具備的知識:

  • 前端基礎

  • 數據庫基礎

  • 計算機網絡基礎

  • 熟悉 React 開發 當然,你還需要有良好的軟件開發素養,否則你會發現寫的代碼不好維護,或者不易理解

項目初始化

在真正開發項目之前,讓我們先進行需求分析 和 技術選型

需求分析

  • 聊天頁面開發(基礎能力)
    • 包含提示的輸入框和發送 / 停止按鈕

    • 實現一個聊天區域來顯示對話記錄,一個列表展示會話歷史

    • 開發 /agent API 來處理請求

    • 確保每個對話的數據都被持久存儲

    • 通過流式傳輸返回所有結果

  • 高級能力
    • 增強聊天組件,支持 markdown 渲染、自動滾動、圖片上傳等

    • 實現函數調用,例如檢索當前時間

技術選型

根據需求,我選擇了我喜歡的并且也是主流的技術:

  • Next.js 作為全棧開發基礎框架

  • hono.js 作為后端框架,優化在 Next.js 中后端開發體驗

  • PostgreSQL 作為數據庫存儲對話記錄

  • DrizzleORM 作為 ORM ,更為便捷和高效的方式與數據庫進行交互

  • shadcn/ui 作為 UI 組件庫,tailwindcss 作為 css 框架

  • Vercel AI SDK 快速開發 AI 相關的服務,如果你也在開發 AI 相關的服務,強烈推薦使用它,能幫你減少 80% 的工作

  • Biome 進行代碼格式化和檢測(代替 ESLint + Prettier),需要你安裝 Biome 插件哦

  • zod : TypeScript 優先的數據驗證庫

對了,我們使用 Github 進行版本控制,維護代碼。使用 vercel 進行項目部署上線。

初始化

下面進行初始化項目,初始化項目完成后,我們應該就可以進行業務開發

1)根據 Next.js 官方文檔我們創建一個 Next.js 項目:

npx?create-next-app@latest

image.png

2)下面,根據官方文檔集成 shadcn/ui:

pnpm?dlx?shadcn@latest?init
pnpm?dlx?shadcn@latest?add?button

image.png

然后嘗試使用 Button 按鈕,發現集成成功!

注意這里有一個小細節就是我在入口的 layout 組件為 body 標簽添加了 suppressHydrationWarning ,作用是:抑制 React 在客戶端和服務器端渲染不匹配時產生的警告信息,這在處理動態內容(如日期、時間等)時特別有用,因為這些內容在服務器端和客戶端可能會有差異。

image.png

3)下面集成 Biome,保證相關代碼風格一致

pnpm?i?@biomejs/biome?-D

然后在 package.json 添加對應的腳本:

{"scripts":?{"lint":?"next?lint","format":?"biome?format?--write?.","lint:biome":?"biome?check?--apply.",}
}

下面設置編輯器的 Format Document With ,選擇 Configure Default Formatter 設置為 Biome。現在你的項目就又了格式化能力,你還可以在 git 提交的鏈路上進行預先 format 和 lint 等操作,保證提交的代碼是格式化的。 4)下面繼續集成 hono.js,我參考了文章思路: https://kuizuo.cn/blog/nextjs-with-hono/ 。首先根據官方文檔進行安裝

pnpm?i?hono
#?讓?hono?接管所有接口服務
mkdir?-p?"src/app/api/[[...route]]"?&&?touch?"src/app/api/[[...route]]/route.ts"

下面,開發 route.ts 內容,讓 hono 來接管接口服務

//?src/app/api/[[...route]]/route.ts
import?api?from?"@/server/api";
import?{?handle?}?from?"hono/vercel";
const?handler?=?handle(api);
export?{handler?as?GET,handler?as?POST,handler?as?PUT,handler?as?DELETE,handler?as?PATCH,
};

因為 Next.js 會自動掃描 app 下的文件夾進行熱更新,所以我們可以將服務端代碼放在根目錄的 server 文件夾下(其實你可以使用任何名稱),這里寫我們所有的服務端邏輯和接口,下面初始化一下服務端的基礎邏輯, 5)創建自定義校驗器,它的作用是進行請求數據驗證的工具函數,確保數據符合預期的格式和類型規范,并提供類型安全的驗證結果

//?src/server/api/validator.ts
import?type?{Context,MiddlewareHandler,Env,ValidationTargets,TypedResponse,Input,
}?from?"hono";
import?{?validator?}?from?"hono/validator";
import?type?{?z,?ZodSchema,?ZodError?}?from?"zod";export?type?Hook<T,E?extends?Env,P?extends?string,Target?extends?keyof?ValidationTargets?=?keyof?ValidationTargets,//?biome-ignore?lint/complexity/noBannedTypes:?<explanation>O?=?{}
>?=?(result:?(|?{?success:?true;?data:?T?}|?{?success:?false;?error:?ZodError;?data:?T?})?&?{target:?Target;},c:?Context<E,?P>
)?=>|?Response|?void|?TypedResponse<O>//?biome-ignore?lint/suspicious/noConfusingVoidType:?<explanation>|?Promise<Response?|?void?|?TypedResponse<O>>;type?HasUndefined<T>?=?undefined?extends?T???true?:?false;export?const?zValidator?=?<T?extends?ZodSchema,Target?extends?keyof?ValidationTargets,E?extends?Env,P?extends?string,In?=?z.input<T>,Out?=?z.output<T>,I?extends?Input?=?{in:?HasUndefined<In>?extends?true??{[K?in?Target]?:?K?extends?"json"??In:?HasUndefined<keyof?ValidationTargets[K]>?extends?true??{?[K2?in?keyof?In]?:?ValidationTargets[K][K2]?}:?{?[K2?in?keyof?In]:?ValidationTargets[K][K2]?};}:?{[K?in?Target]:?K?extends?"json"??In:?HasUndefined<keyof?ValidationTargets[K]>?extends?true??{?[K2?in?keyof?In]?:?ValidationTargets[K][K2]?}:?{?[K2?in?keyof?In]:?ValidationTargets[K][K2]?};};out:?{?[K?in?Target]:?Out?};},V?extends?I?=?I
>(target:?Target,schema:?T,hook?:?Hook<z.infer<T>,?E,?P,?Target>
):?MiddlewareHandler<E,?P,?V>?=>//?@ts-expect-error?not?typed?wellvalidator(target,?async?(value,?c)?=>?{const?result?=?await?schema.safeParseAsync(value);if?(hook)?{const?hookResult?=?await?hook({?data:?value,?...result,?target?},?c);if?(hookResult)?{if?(hookResult?instanceof?Response)?{return?hookResult;}if?("response"?in?hookResult)?{return?hookResult.response;}}}if?(!result.success)?{throw?result.error;}return?result.data?as?z.infer<T>;});

6)創建錯誤處理文件,給到客戶端更好的錯誤提示:

//?src/server/api/error.ts
import?{?z?}?from?"zod";
import?type?{?Context?}?from?"hono";
import?{?HTTPException?}?from?"hono/http-exception";
import?type?{?ContentfulStatusCode?}?from?"hono/utils/http-status";export?class?ApiError?extends?HTTPException?{public?readonly?code?:?ContentfulStatusCode;constructor({code,message,}:?{code?:?ContentfulStatusCode;message:?string;})?{super(code,?{?message?});this.code?=?code;}
}export?function?handleError(err:?Error,?c:?Context):?Response?{if?(err?instanceof?z.ZodError)?{const?firstError?=?err.errors[0];return?c.json({?code:?422,?message:?`\`${firstError.path}\`:?${firstError.message}`?},422);}/***?This?is?a?generic?error,?we?should?log?it?and?return?a?500*/return?c.json({code:?500,message:?"服務端錯誤,?請稍后再試。",},{?status:?500?});
}

下面我們創建我們的第一個接口,驗證 honojs 是否引入成功:

//?src/server/api/routes/hello.ts
import?{?Hono?}?from?"hono";
const?app?=?new?Hono().get("/hello",?(c)?=>c.json({?message:?"Hello,?luckyChat"?})
);
export?default?app;

7)最后,開發入口文件:

//?src/server/api/index.ts
import?{?handleError?}?from?"./error";
import?{?Hono?}?from?"hono";
import?helloRoute?from?"./routes/hello";
const?app?=?new?Hono().basePath("/api");
app.onError(handleError);
const?routes?=?app.route("/",?helloRoute);
export?default?app;
export?type?AppType?=?typeof?routes;

現在我們不僅有了接口,還有了服務端接口的類型聲明,我們可以非常方便的在客戶端進行類型安全的接口請求,我們不需要寫路由,也不需要寫類型相關的內容,真的是 amazing,我們趕緊在客戶端調用第一個接口吧!在調用接口前, 8)我們先封裝一個 fetch 方法:

//?src/lib/fetch.ts
import?type?{?AppType?}?from?"@/server/api";
import?{?hc?}?from?"hono/client";
import?ky?from?"ky";const?baseUrl?=process.env.NODE_ENV?===?"development"??"http://localhost:3000":?process.env.NEXT_PUBLIC_APP_URL;export?const?fetch?=?ky.extend({hooks:?{afterResponse:?[async?(_,?__,?response:?Response)?=>?{if?(response.ok)?{return?response;//?biome-ignore?lint/style/noUselessElse:?<explanation>}?else?{throw?await?response.json();}},],},
});export?const?client?=?hc<AppType>(baseUrl?as?string,?{fetch:?fetch,
});

ky 庫是一個基于瀏覽器原生 Fetch API 的輕量級HTTP客戶端庫,提供了更簡潔友好的接口,使用它更好的與 honojs 集成,這里我們使用 hc 和 AppType 創建了一個安全的接口請求方式:

// src/app/page.tsx
import { Button } from "@/components/ui/button";
import { Heart } from "lucide-react";
import { client } from "@/lib/fetch";
async function getData() {try {const res = await client.api.hello.$get();if (!res.ok) {// This will activate the closest `error.js` Error Boundarythrow new Error("Failed to fetch data");}return res.json();} catch (error) {console.error("獲取數據失敗:", error);return { message: "AI 助手" };}
}
export default async function Home() {const { message } = await getData();return (<div><div>{message}</div><Button><Heart className="mr-2 h-4 w-4" /> lucky Snail</Button></div>);
}

當我們在使用 client 的時候它會進行代碼提示告訴你目前可以使用哪些接口,并且在后面我們可以借助 InferResponseType 和 typeof 等 ts 關鍵字來使用接口對應的 ts 類型,我們只需要在服務端定義好類型聲明,在客戶端直接消費即可 👍。

9)下面進行最重要的一步,也就是數據庫初始化,有開發經驗的應該都知道數據庫設計的好,可以大大降低系統復雜度,減少不必要的代碼,這么重要的事情肯定是需要 AI 的參與的,我們把需求給到 AI,然后讓 AI 幫忙進行初步數據庫設計,下面在 cursor 中進行 ask:

提示詞:現在集成 DrizzleORM, and AI SDK.使用 postgreSQL 作為數據庫,驅動使用 postgres,數據庫名字叫 chatAI ,數據庫就一張表,存儲 AI 對話記錄,設計良好的數據庫表結構,最后開發 /agent API 來處理聊天請求,這里使用大模型為 Deepseek ,大模型的 key 存在 環境變量的 DEEPSEEK_API_KEY ,數據庫集成參考 @https://orm.drizzle.team/docs/get-started-postgresql ,先梳理需求,然后一步步進行實現

AI 給到的數據庫結構如下:

//?src/lib/db/schema.ts
import?{?pgTable,?serial,?text,?timestamp,?varchar?}?from?'drizzle-orm/pg-core';//?聊天消息類型
export?const?chatMessages?=?pgTable('chat_messages',?{id:?serial('id').primaryKey(),sessionId:?varchar('session_id',?{?length:?255?}).notNull(),role:?varchar('role',?{?length:?50?}).notNull(),?//?'user'?或?'assistant'content:?text('content').notNull(),createdAt:?timestamp('created_at').defaultNow().notNull(),
});//?會話信息
export?const?chatSessions?=?pgTable('chat_sessions',?{id:?serial('id').primaryKey(),sessionId:?varchar('session_id',?{?length:?255?}).unique().notNull(),title:?varchar('title',?{?length:?255?}),createdAt:?timestamp('created_at').defaultNow().notNull(),updatedAt:?timestamp('updated_at').defaultNow().notNull(),
});

這里 AI 幫我們創建好了數據庫的表結構,它能理解需求,并給出合理的數據庫設計:

  • chat_sessions 表:存儲聊天會話信息

  • chat_messages 表:存儲聊天消息 還幫我們在 package.json 添加了生成和運行遷移的腳本,我們在 env 配置到 DATABASE_URL,執行腳本即可初始化數據庫

現在我們完成了項目初始化,我們可以使用 cursor 提供的 /generate Cursor Rules 來生成項目開發指導,在后面業務能力開發中,我們每次都攜帶上這條 rules ,它能幫 AI 更好的生成內容

image.png

現在已經搭建好了前端和后端基礎能力,并且生成了項目開發的 rules ,下面就全部交給 AI 來進行業務開發,我們只需要做一個合格的測試和 code review 就好了!

核心能力開發

一個聊天應用最核心的就是輸入提示詞 => AI 大模型響應內容 => 展示內容 => 繼續對話

1)開發 chat,提示詞如下

下面 @project-structure.mdc 就是我們生成的項目開發 rules

@project-structure.mdc 使用 ai-sdk 開發 /agent API 來處理聊天請求,遵循 RESTful API 風格,這里使用大模型為 Deepseek ,大模型的 key 存在 環境變量的 DEEPSEEK_API_KEY ,然后在開發對應的 chat 頁面,一個輸入框,右側有發送和暫停按鈕,支持接收用戶的輸入,支持發送和停止能力,這里使用 @ai-sdk/react 快速進行開發,需要流式輸出 AI 生成內容。代碼組件化,模塊化,盡可能使用 shadui/cn 組件開發,先梳理需求,然后一步步進行實現

AI 可能需要比較漫長時間完成工作,在這個過程中,我們可以思考下一個提示詞,在 AI 生成完成后,我們需要進行檢查和修復 bug,當然你是可以借助 AI 來 fix error。這里需要額外注意的是當我們 chat 中斷的時候應該把已經生成的內容進行存儲數據庫

2)開發創建新會話能力,支持會話緩存到本地

@project-structure.mdc 支持創建新會話,并且會話 id 存儲 localStorage ,在頁面刷新的時候會話 id 依然存在,注意點擊停止需要把當前會話進行存儲

3)開發歷史會話列表展示,支持切換會話

@project-structure.mdc 開發歷史對話記錄功能,先進行接口開發,這里兩個接口:獲取所有會話列表和獲取指定 id 的會話信息,前端需要將會話列表封裝為單獨組件,點擊會話列表項能進入該對話,數據接口邏輯使用自定義 hooks,保證代碼清晰易理解。 注意客戶端需要使用封裝的 fetch 導出的 client 進行接口請求

4)支持 markdown 渲染 AI 生成的內容,優化頁面布局 UI,支持內容自動滾動底部 上面完成后,我們有了基本的 chat 功能頁面,但是可能這時候頁面比較丑不太美觀,現在進行優化

@project-structure.mdc 你是資深 UI 設計師,現在進行項目優化:
1,實現 markdown 渲染流式內容。添加在對話中自動滾動到底部的能力
2. 優化目前的頁面 UI,頁面布局為左邊的側邊欄,展示歷史記錄和新對話能力都放在左邊,當屏幕寬度小于 tailwindcss 的 lg 的時候就不展示側邊欄,右側對話框 UI ,也需要進行優化,注意不要新增元素和修改邏輯,僅僅是對元素布局和 UI進行優化,參考優秀的 chatbox UI 設計

5)支持 function call 能力,獲取當前時間

@project-structure.mdc @web 參考文檔支持 function call 能力,以獲取最新時間為例

優化

如果你做到這里,相信你的項目肯定還有一些 bug 和 UI 細節需要進行優化,你可以和 AI 一起進行優化,給大家看一下我和 AI 的 chat

image.png

不斷的修復和優化,最終我的 chatbox 就出現啦!

image.png

你打幾分呢?

總結

  1. AI 目前編程能力已經超過 90% 的工程師了,它在開發功能安全性和兼容性考慮上十分的全面,但是它也有能力邊界,在面對復雜系統,奇怪的需求上是不如人的。所以程序員以后更多是做決策,做 AI 與需求的橋梁,通過我們的經驗和直覺去選擇接受還是拒絕 AI 的生成

  2. 日常 AI 編程開發中,推薦使用方式為 gemini 做設計和文檔類工作,寫代碼部分交給 claude

  3. 需要我們能夠合理的進行模塊拆分,能夠識別 AI 代碼是不是合理的

  4. 系統設計是 AI 時代程序員的必須要提升的技能,推薦一本書《軟件設計的哲學》第二版

  5. 知識廣度,全棧能力對前端有很大的幫助,借助 AI 快速將想法變成現實是程序員的紅利

  6. 持續學習,跟進最新的 AI 是保證自己有競爭力的關鍵

  7. Vibe Coding 必然會成為新的編碼方式,純手工編程必然會像 php 一樣成為歷史

  8. 目前來看,編程智能體(Agent)真的很成功,讓我這種普通人能夠快速 開發出產品。

參考:

  1. https://claude.ai/chat/fd4c29a3-3b5c-4965-9670-4380dcc28f98

  2. https://www.youtube.com/watch?v=tlrf4lu8Myc

  3. https://bigbang.easykol.com/search/following?platform=TIKTOK&url=https://www.tiktok.com/@meditationbuddhism

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/907114.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/907114.shtml
英文地址,請注明出處:http://en.pswp.cn/news/907114.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

嵌入式學習的第二十六天-系統編程-文件IO+目錄

一、文件IO相關函數 1.read/write cp #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <stdio.h> #include<unistd.h> #include<string.h>int main(int argc, char **argv) {if(argc<3){fprintf(stderr, …

SCADA|KingSCADA信創4.0-Win10安裝過程

哈嘍,你好啊,我是雷工! 現如今很多地方開始要求信創版, 最近就遇到一個現場要求用信創。 首先找官方要了最新的信創版安裝包。 由于有之前安裝組態王授權驅動裝藍屏的經歷,此次特意問了下該標識win10的軟件是否可以在win11系統上安裝。 技術反饋win11專業版上可以安裝…

AI時代新詞-人工智能倫理審查(AI Ethics Review)

一、什么是人工智能倫理審查&#xff08;AI Ethics Review&#xff09;&#xff1f; 人工智能倫理審查&#xff08;AI Ethics Review&#xff09;是指在人工智能&#xff08;AI&#xff09;系統的開發、部署和使用過程中&#xff0c;對其可能涉及的倫理、法律和社會問題進行系…

GitLab 從 17.10 到 18.0.1 的升級指南

本文分享從 GitLab 中文本 17.10.0 升級到 18.0.1 的完整過程。 升級前提 查看當前安裝實例的版本。有多種方式可以查看&#xff1a; 方式一&#xff1a; /help頁面 可以直接在 /help頁面查看當前實例的版本。以極狐GitLab SaaS 為例&#xff0c;在瀏覽器中輸入 https://ji…

python:基礎爬蟲、搭建簡易網站

一、基礎爬蟲代碼&#xff1a; # 導包 import requests # 從指定網址爬取數據 response requests.get("http://192.168.34.57:8080") print(response) # 獲取數據 print(response.text)二、使用FastAPI快速搭建網站&#xff1a; # TODO FastAPI 是一個現代化、快速…

從0開始學習R語言--Day10--時間序列分析數據

在數據分析中&#xff0c;我們經常會看到帶有時間屬性的數據&#xff0c;比如股價波動&#xff0c;各種商品銷售數據&#xff0c;網站的網絡用戶活躍度等。一般來說&#xff0c;根據需求我們會分為兩種&#xff0c;分析歷史數據的特點和預測未來時間段的數據。 移動平均 移動平…

倚光科技在二元衍射面加工技術上的革新:引領光學元件制造新方向?

倚光科技二元衍射面加工技術&#xff08;呈現出細膩的光碟反射紋路&#xff09; 在光學元件制造領域&#xff0c;二元衍射面的加工技術一直是行業發展的關鍵驅動力之一。其精準的光相位調制能力&#xff0c;在諸多前沿光學應用中扮演著不可或缺的角色。然而&#xff0c;長期以來…

【redis原理篇】底層數據結構

SDS Redis是基于C語言實現的&#xff0c;但是Redis中大量使用的字符串并沒有直接使用C語言字符串。 一、SDS 的設計動機 傳統 C 字符串以 \0 結尾&#xff0c;存在以下問題&#xff1a; 性能瓶頸&#xff1a;獲取長度需遍歷字符數組&#xff0c;時間復雜度 O(n)。緩沖區溢出…

尚硅谷redis7 20-redis10大類型之zset

zset是redis中的有序集合【sorted set】 zset就是在set基礎上&#xff0c;每個val值前加一個score分數值。 之前set是k1 v1 v2 v3現在zset是k1 score1 v1 score2 v2 向有序集合中加入一個元素和該元素的分數 ZADD key score member [score member...] 添加元素 127. 0. 0. …

STM32 SPI通信(軟件)

一、SPI簡介 SPI&#xff08;Serial Peripheral Interface&#xff09;是由Motorola公司開發的一種通用數據總線四根通信線&#xff1a;SCK&#xff08;Serial Clock&#xff09;、MOSI&#xff08;Master Output Slave Input&#xff09;、MISO&#xff08;Master Input Slav…

Kotlin Native與C/C++高效互操作:技術原理與性能優化指南

一、互操作基礎與性能瓶頸分析 1.1 Kotlin Native調用原理 Kotlin Native通過LLVM編譯器生成機器碼,與C/C++的互操作基于以下核心機制: CInterop工具:解析C頭文件生成Kotlin/Native綁定(.klib),自動生成類型映射和包裝函數雙向調用約定: Kotlin調用C:直接通過生成的綁…

云原生安全 SaaS :從基礎到實踐

&#x1f525;「炎碼工坊」技術彈藥已裝填&#xff01; 點擊關注 → 解鎖工業級干貨【工具實測|項目避坑|源碼燃燒指南】 1. 基礎概念 什么是 SaaS&#xff1f; SaaS&#xff08;Software as a Service&#xff0c;軟件即服務&#xff09;是一種基于云計算的軟件交付模式。用…

git clone 提速

git上的項目時間久了 .git文件夾非常大&#xff0c;這時候更新一次項目需要花費很長的時間&#xff0c;解決方法也很簡單&#xff0c;加一個depth參數&#xff0c;命令如下&#xff1a; git clone --depth 1 https://github.com/xxxxxx/xxxxxx指定了 depth 1 的時候&#xff0…

Redis 性能優化:核心技術、技巧與最佳實踐

Redis 作為高性能的內存數據庫,其性能優化是系統設計中的關鍵環節。本文結合 Redis 官方文檔及實踐經驗,從內存管理、延遲優化、CPU 效率、網絡配置等多個維度,系統性地闡述 Redis 性能優化的核心技術與最佳實踐。 通過以下優化手段,Redis 可在高并發、低延遲場景中發揮極致…

PostgreSQL 14 pacemaker 高可用集群

核心架構原理 集群組成&#xff08;典型三節點結構&#xff09;&#xff1a; [Node1] PostgreSQL Pacemaker Corosync pcsd [Node2] PostgreSQL Pacemaker Corosync pcsd [Node3] PostgreSQL Pacemaker Corosync pcsd ? ? ? ← Corosync 多…

影刀Fun叉鳥-2048

文章目錄 僅為自動化演示&#xff0c;實際2048判定邏輯需要更加嚴謹 參考代碼 # 使用提醒: # 1. xbot包提供軟件自動化、數據表格、Excel、日志、AI等功能 # 2. package包提供訪問當前應用數據的功能&#xff0c;如獲取元素、訪問全局變量、獲取資源文件等功能 # 3. 當此模塊作…

Vue3.5 企業級管理系統實戰(二十):角色菜單

本篇聚焦于角色菜單權限分配功能的實現&#xff0c;圍繞“給角色賦予菜單權限”這一核心場景&#xff0c;從接口設計、組件封裝到頁面集成展開完整技術方案的闡述。主要內容包括&#xff1a; 1. 角色權限接口開發&#xff1a;定義獲取角色權限、分配權限等接口&#xff0c;規范…

go實現釘釘三方登錄

釘釘的的官方開發文檔中只給出了java實現三方登錄的&#xff0c;我們準備用go語言來實現 實現網頁方式登錄應用&#xff08;登錄第三方網站&#xff09; - 釘釘開放平臺 首先就是按照文檔進行操作&#xff0c;備注好網站的信息 獲得應用憑證&#xff0c;我們后面會用到 之后…

一、OpenCV的基本操作

目錄 1、OpenCV的模塊 2、OpenCV的基礎操作 2.1圖像的IO操作 2.2繪制幾何圖形 2.3獲取并修改圖像中的像素點 2.4 獲取圖像的屬性 2.5圖像通道的拆分與合并 2.6色彩空間的改變 3、OpenCV的算數操作 3.1圖像的加法 3.2圖像的混合 3.3總結 1、OpenCV的模塊 2、OpenCV的基…

虛擬機配置橋接,遠程工具直接訪問

虛擬機網絡配置 前言windows下安裝linux虛擬機配置網絡1、設置虛擬機網絡模式&#xff1a;橋接模式2、配置網絡參數1、查看本機電腦連接的網絡情況2、打開虛擬機&#xff0c;編輯配置文件3、編輯虛擬網絡 3、測試連通性 前言 好不容易裝上了虛擬機&#xff0c;輸入命令時又發現…