Day3:AI待办Web端完整实现

简介: Day3 完成前端核心链路开发:基于PNPM单体架构,集成Tailwind v4、React Router与Zustand;实现API-SDK统一请求、登录态管理、路由守卫、待办CRUD及AI资讯一键加入功能,全链路联调通过,支持回跳、状态反馈与类型安全。

Day3

Step1:初始化环境与依赖(已完成)

代码/命令

  • 安装依赖:pnpm i
  • 安装前端依赖:pnpm --filter @aitodos/web add react-router-dom zustand
  • 安装样式依赖:pnpm --filter @aitodos/web add -D tailwindcss postcss autoprefixer

配置说明

  • apps/web/package.json 已包含:react-router-domzustandtailwindcss@4
  • 当前样式方案使用 Tailwind v4 + Vite 插件(非 v3 的 tailwindcss init -p 流程)

关键代码(示例)

pnpm --filter @aitodos/web add react-router-dom zustand
pnpm --filter @aitodos/web add -D tailwindcss postcss autoprefixer

Step2:接入 API-SDK(已完成)

代码

  • packages/api-sdk/src/index.ts
  • apps/web/src/lib/api.ts

代码说明

  • createApiClient(baseUrl) 统一封装 request(),处理 JSON、状态码、错误抛出。
  • 已接入接口:
    • register / login / me
    • getProfile
    • listTodos / createTodo
    • listAiNews / addAiNewsToTodo

配置说明

  • apps/web/.env.localVITE_API_BASE_URL=http://localhost:3000/api
  • VITE_ 前缀表示该变量可在浏览器端访问。

关键代码(示例)

// apps/web/src/lib/api.ts
import {
    createApiClient } from "@aitodos/api-sdk";

const baseUrl = import.meta.env.VITE_API_BASE_URL ?? "http://localhost:3000/api";

export const api = createApiClient(baseUrl);

Step3:Zustand 业务状态(已完成)

代码

  • apps/web/src/store/auth.store.ts
  • apps/web/src/store/todo.store.ts
  • apps/web/src/store/news.store.ts

代码说明

  • auth.store:登录、注册、恢复登录态、拉取 me/profile
  • todo.store:待办拉取、新增。
  • news.store:资讯拉取、一键加入待办。
  • 统一保留 loadingerror 字段,页面直接订阅并展示状态。

配置说明

  • 登录态以 localStorage(aitodos_token) 保存。
  • 当前后端鉴权依赖 x-user-id,前端通过 dev-token-<userId> 解析用户 ID。

关键代码(示例)

// apps/web/src/store/auth.store.ts
const TOKEN_KEY = "aitodos_token";

export const extractUserIdFromToken = (token: string | null): string | null => {
   
  if (!token) return null;
  const prefix = "dev-token-";
  if (!token.startsWith(prefix)) return null;
  return token.slice(prefix.length) || null;
};

restoreSession: () => {
   
  const token = localStorage.getItem(TOKEN_KEY);
  set({
    token, hydrated: true });
}

Step4:注册/登录页(已完成)

代码

  • apps/web/src/pages/LoginPage.tsx
  • apps/web/src/pages/RegisterPage.tsx

代码说明

  • 注册后跳转登录页;登录成功跳转工作台。
  • 表单提交已做类型安全处理,不再使用 deprecated 的 FormEvent 别名。
  • 页面已展示错误反馈信息(如 Failed to fetch / 接口异常)。
  • 已优化登录跳转逻辑:支持登录后回跳来源页面(如 /todos / /ai-news)。
  • 已登录用户访问 /login/register 时自动跳转到 /web

配置说明

  • 注册与登录都走 api-sdk,避免页面直接写 fetch.

关键代码(示例)

// apps/web/src/pages/LoginPage.tsx
const redirectTo = (location.state as { from?: string } | null)?.from ?? "/web";

const onSubmit = async (e: FormSubmitEvent) => {
  e.preventDefault();
  await login({ email, password });
  navigate(redirectTo, { replace: true });
};

Step5:基础登录态与路由守卫(已完成)

代码

  • apps/web/src/App.tsx
  • apps/web/src/main.tsx

代码说明

  • main.tsx 使用 BrowserRouter 包裹 <App />,启用前端路由。
  • App.tsx 使用 ProtectedRoute:无 token 跳登录,有 token 访问业务页。
  • 应用启动时执行 restoreSession(),并在有 token 时执行 fetchMe()
  • 路由结构调整为:/ 门户页(公开) -> /web 工作台(受保护) -> /todos / /ai-news(受保护)。

配置说明

  • 这是 SPA 路由守卫方案;后续迁移 Next.js SSR 时再升级为服务端鉴权策略.

关键代码(示例)

// apps/web/src/main.tsx
<React.StrictMode>
  <BrowserRouter>
    <App />
  </BrowserRouter>
</React.StrictMode>

// apps/web/src/App.tsx
if (!hydrated) return <p className="p-6">恢复登录态中...</p>;
if (!token) return <Navigate to="/login" replace state={
  { from: location.pathname }} />;

Step6:首页工作台(已完成)

代码

  • apps/web/src/pages/DashboardPage.tsx
  • apps/web/src/pages/PortalPage.tsx

代码说明

  • 展示个人信息:邮箱、昵称、角色。
  • 展示业务入口:/todos/ai-news
  • 门户页作为软件介绍首页,提供“进入web端”按钮。
  • 工作台模块化展示为:个人信息、TodoList、AI资讯。
  • 已补齐三态反馈:
    • loading:加载个人信息中
    • error:加载失败提示
    • empty:无 user / 无 profile 提示

配置说明

  • 工作台数据来源于 auth.storeuser/profile,非页面内直接请求.

关键代码(示例)

// apps/web/src/pages/DashboardPage.tsx
{loading ? <p className="mb-3 text-sm text-slate-600">加载个人信息中...</p> : null}
{error ? <p className="mb-3 text-sm text-red-600">加载失败:{error}</p> : null}

{!loading && !error && !user ? (
  <p className="mb-3 rounded bg-amber-50 px-3 py-2 text-sm text-amber-700">暂无用户信息,请重新登录后再试。</p>
) : null}

Step7:待办页(已完成)

代码

  • apps/web/src/pages/TodoPage.tsx
  • apps/web/src/store/todo.store.ts
  • apps/web/src/pages/components/TodoCreateForm.tsx
  • apps/web/src/pages/components/TodoQueueSection.tsx
  • apps/web/src/pages/components/DoneQueueSection.tsx

代码说明

  • 已实现完整 CRUD:新增、编辑、完成/改回未完成、删除。
  • 已实现未完成队列与已完成队列分区展示。
  • 已有基础三态展示:loading / empty / error
  • 页面结构已完成组件拆分:创建表单、未完成队列、已完成队列。

配置说明

  • 待办列表数据来源于 todo.storeitems,非页面内直接请求.

关键代码(示例)

// apps/web/src/pages/TodoPage.tsx
<TodoCreateForm
  title={title}
  description={description}
  onTitleChange={setTitle}
  onDescriptionChange={setDescription}
  onSubmit={onCreate}
/>

<TodoQueueSection ... />
<DoneQueueSection ... />

Step8:AI 资讯页(已完成)

代码

  • apps/web/src/pages/AiNewsPage.tsx
  • apps/web/src/store/news.store.ts

代码说明

  • 拉取并展示 AI 资讯列表(后端当前返回最新 5 条)。
  • 每条资讯提供“一键加入待办”按钮。
  • 点击后调用 addToTodo,并在按钮上展示“加入中...”防重复点击。
  • 失败时给出错误消息,成功后给出“已加入待办,正在跳转...”提示并跳转待办页。

配置说明

  • 资讯读取走后端 ai-news 缓存逻辑(Redis 日缓存),前端无需处理缓存细节.

关键代码(示例)

// apps/web/src/pages/AiNewsPage.tsx
const onAdd = async (newsId: string) => {
  if (!userId) return;
  setSubmittingId(newsId);
  await addToTodo(newsId, userId);
  navigate("/todos", { state: { message: "已从 AI 资讯加入待办" } });
};

Step9:一键加入待办全链路(已完成)

代码

  • apps/web/src/pages/AiNewsPage.tsx
  • apps/web/src/store/news.store.ts
  • apps/web/src/store/todo.store.ts
  • apps/web/src/pages/TodoPage.tsx

代码说明

  • 已实现一键加入待办功能,并跳转到待办页。
  • 已实现跨页成功提示:AiNewsPage 通过路由 state 传递消息给 TodoPage
  • TodoPage 显示消息后自动 2 秒消失,避免常驻。

配置说明

  • 一键加入待办功能依赖 news.storeaddToTodotodo.storecreateTodo.

Step10:联调验收(已完成)

验收清单

  • [x] 注册登录完整可用
  • [x] 工作台稳定显示个人信息
  • [x] AI 资讯可见并支持一键加入待办
  • [x] 待办页可见新增项
  • [x] 待办支持编辑 / 完成 / 删除

关键配置补充(当前已生效)

CORS(后端)

  • 文件:apps/server/src/main.ts
  • 说明:已加 app.enableCors(...),放行 http://localhost:5173,解决前后端联调跨域.
app.enableCors({
   
  origin: ["http://localhost:5173"],
  methods: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"],
  allowedHeaders: ["Content-Type", "Authorization", "x-user-id"],
  credentials: false
});

类型检查

  • 命令:pnpm --filter @aitodos/web type-check
  • 当前状态:已通过(tsc --noEmit 无报错).

当前结论

  • Day3 主链路已打通并完成优化:门户 -> 登录 -> 工作台 -> AI 资讯 -> 加入待办 -> 待办 CRUD。
  • 登录体验已优化:支持来源页回跳、已登录自动跳转、门户按登录态展示入口。
  • Todo 页面已完成组件化拆分,便于后续迁移 Next.js / SSR 时复用.
相关文章
|
1月前
|
人工智能 缓存 前端开发
Day4-5:Web 双端适配与 Admin 系统全栈落地实录
本文档整合了 Day 4 与 Day 5 的开发进展,核心涵盖 Web 端响应式 UI 复现、云端资讯 API 接入,以及 Admin 管理系统的架构设计与模块化开发步骤,打通了从用户体验到后台管理的完整链路。
|
1月前
|
人工智能 监控
AI元认知skills
我方自研Skills体系已孕育出“元认知婴儿雏形”:具备初步自我约束、路线竞争、停点审查及二层自查能力,能主动质疑表象、校验逻辑闭环、探寻真实边界。虽尚未形成稳定误差模型与自主进化能力,但已超越技巧调用,迈入高阶思考新阶段。(239字)
|
1月前
|
人工智能 缓存 前端开发
从 0 到 1:AI Todos 项目 Day1 实战——用 pnpm + Turbo 搭建可迭代的 Monorepo 基线
记录AI待办(AiTodos)Monorepo项目的首日基础工程搭建全过程,涵盖pnpm工作区配置、目录骨架初始化、Turbo任务编排、TypeScript统一配置、Vite/Fastify应用初始化、跨包共享(shared/api-sdk/store)及标准化脚本建设,完成可运行、可检查、可扩展的现代化前端工程基线。
|
8天前
|
人工智能 机器人 Shell
专访 Bub 作者们:如何开发一个好记性又懂人的 Agent
这期播客主要聊了 Bub 是什么、它和普通聊天机器人/Agent 框架有什么不同,以及它背后的 Tape 记忆机制和插件化设计。简单来说,Bub 可以理解成一个以 channel 为中心的 AI Agent 框架。它不是只在命令行里写代码,也不只是一个群聊机器人,而是希望把不同 IM、命令行、工具、记忆和运行上下文连接起来,让用户可以根据自己的场景做一个定制版 Agent。
168 9
|
8天前
|
人工智能 资源调度 调度
AI时代,大学生应该提前准备什么?
AI时代,大学生面临就业重塑与能力升级的双重挑战。本文聚焦认知重构、三大核心能力(统筹力、技术力、实战力)及行动路径,倡导从“工具使用者”进阶为“AI决策者”,以T型+AI复合素养应对变革,在人机协同中抢占未来先机。
|
8天前
|
安全 人机交互 调度
《零基础搭建OpenClaw迁移训练环境指南》
智能体仿真完美、落地即崩的行业死结,根源从来不是仿真精度不足,而是传统Sim2Real始终困在视觉特征匹配的表层逻辑里。本文拆解OpenClaw颠覆性的虚实迁移方案,它彻底抛弃暴力域随机化的老路,构建了一套以跨感官因果认知为核心的迁移体系。通过阶梯式虚实过渡、动态经验权重调节、执行器在线自校准与虚实数据双向闭环,让智能体学习物理世界的本质规律而非表面特征。
115 6
|
8天前
|
人工智能 前端开发 JavaScript
Vibe Coding 时代,为什么 Tailwind + Shadcn/ui 正在成为现代前端的默认答案
这篇文章想讨论的,不只是 `Tailwind CSS + shadcn/ui` 为什么流行,而是为什么它们会在 Vibe Coding 时代越来越像现代前端的默认组合。相比传统组件库,这套方案把样式、结构与组件源码更直接地暴露在项目本身中,既提升了开发者的控制权,也降低了 AI 理解、修改和协作的成本。
|
8天前
|
机器学习/深度学习 存储 并行计算
PyTorch深度学习实战 |从深度学习入门到项目化的任务(以Alexnet网络花分类任务为例)
本文介绍了PyTorch深度学习实战中的项目化开发方法。作者指出实际项目与玩具数据集的不同之处,强调需要考虑数据标准化、模型保存和实验追踪等工程问题。文章详细讲解了项目化文件结构,包括configs、models、utils等模块的划分,并提供了关键工具函数的实现,如YAML配置加载、模型检查点保存/加载、评估指标计算等。通过一个AlexNet训练示例,展示了如何将模型训练、验证和预测逻辑分离,构建完整的工程闭环。文章强调深度学习实战中80%时间在处理工程问题,只有20%在模型架构上,帮助读者从学习阶段过渡
97 0
|
2月前
|
SQL 消息中间件 存储
阿里云 EventHouse 正式公测!连接企业数据与 AI Agent,释放实时数据价值
统一接入、沉淀并治理多源异构数据,支持自然语言对话分析,加速业务数据转化为可执行洞察。
374 30
|
1月前
|
人工智能 开发工具 开发者
[理论篇-9]Skill系统与能力封装
用最直白的话讲清楚 **Skill(技能)** 是什么、为什么 2025 年下半年它从一个小众概念变成了 AI 行业的新基建,以及它会怎么改变你和 AI 的相处方式——不管你是开发者、产品经理、运营、还是只想让 AI 多帮自己干点活的普通用户。
425 4

热门文章

最新文章