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 时复用.
相关文章
|
机器学习/深度学习 人工智能 API
大模型推理服务全景图
国内大模型推理需求激增,性能提升的主战场将从训练转移到推理。
2684 120
|
存储 程序员 芯片
微机原理与接口技术 8086微处理器系统结构详解
本文主要详解8086微处理器系统结构。主要从以下几个方面进行分析与总结:8086 CPU结构、EU与BIU的结构和功能、8086寄存器结构、8086系统时钟与指令周期、周期概念、8086系统时钟、指令周期、总线周期、8086存储器组织、堆栈的概念、存储器组织与I/O结构、存储体与总线的连接、8086的内外部中断、中断向量表。
2630 0
微机原理与接口技术 8086微处理器系统结构详解
|
9天前
|
人工智能 Android开发 iOS开发
阿里云JVS Claw官网找到了:jvsclaw.aliyun.com 免费使用阿里版龙虾,真正的开箱即用
阿里云JVS Claw是基于OpenClaw打造的轻量级AI龙虾助手,免配置、开箱即用。支持网页/手机/电脑多端访问(无需下载),提供7天免费体验及29元起月付套餐,操作更简单、响应更快。官网直达:https://t.aliyun.com/U/IJbaxg
291 1
|
人工智能 算法 程序员
人类专家:这代码逻辑我看不太懂。AI:没关系,能跑通,而且比你快
英伟达新论文《SATLUTION》震撼AI与编程界:AI自主进化出SAT求解器,竟超越人类冠军。它不靠补全代码,而是通过“规划+编码”双智能体,在严格规则与验证下自我迭代。70轮后,性能反超顶尖人工求解器,成本却不足2万美元。更深远的是,人类角色正从“写代码”转向“定规则、做验证”。这不仅是技术突破,更是对程序员未来的重新定义:我们或将成为AI的教练与考官,而非唯一的手艺人。
333 12
|
9月前
|
XML 缓存 API
eBay 商品详情 API 深度解析:从基础信息到变体数据获取全方案
本文详解如何通过 eBay 的 GetItem 和 GetMultipleItems 接口获取商品详情数据,涵盖基础属性、价格、变体、卖家信息等,并提供可复用的 Python 代码。内容包括 API 核心参数、响应结构、代码实现、实战注意事项及扩展方向,助力跨境电商开发。
|
9月前
|
存储 数据采集 监控
电子病历在 HIS 系统中扮演了一个什么角色?
电子病历是医院信息系统(HIS)的核心与基础,承担临床信息中枢和业务驱动引擎的角色。它全面记录患者诊疗信息,推动医嘱执行、信息流转等关键流程,汇聚多系统数据,形成完整诊疗视图。作为患者信息的“单一真实来源”,电子病历保障医疗质量与安全,支持运营管理和科研决策,同时促进医疗协同与信息互通。其结构化数据在法规合规、医院评级等方面也具有重要意义。可以说,电子病历是现代HIS不可或缺的核心组件。
307 0
电子病历在 HIS 系统中扮演了一个什么角色?
|
5月前
|
弹性计算 人工智能
阿里云优惠券详解:免费领取、查询、使用以及个人、企业和学生代金券领取入口整理
阿里云优惠券免费领取攻略:个人、企业及学生均可领,最高享2088元代金券+6折整单折扣。学生专享300元无门槛券,企业可申5亿算力补贴。附领取入口、查询与使用教程,购云服务器更省钱!
|
7月前
|
人工智能 供应链 算法
智能体来了!拥抱智能体:零基础者的职业新机遇与就业培训的时代使命
AI智能体正从概念走向产业应用,零基础者可通过系统培训掌握实用技能,实现职业突破。借助可视化工具,普通人也能快速入门,搭建解决实际问题的智能体。专业就业培训则打通技术与产业需求,培养复合型人才,推动个人成长与企业增效双赢,助力数字经济高质量发展。
262 5
|
存储 安全 前端开发
Elasticsearch 使用误区之六——富文本内容写入前不清洗
【10月更文挑战第6天】在大数据和全文搜索领域,Elasticsearch(简称ES)凭借其强大的搜索和分析能力,成为众多企业和开发者的首选工具。然而,在实际应用中,很多开发者在使用ES时存在一些误区,其中之一便是富文本内容写入前不进行清洗。本文将深入探讨这一误区,并提供一些实用的清洗策略和最佳实践。
312 3
|
存储 小程序 前端开发
微信小程序与Java后端实现微信授权登录功能
微信小程序极大地简化了登录注册流程。对于用户而言,仅仅需要点击授权按钮,便能够完成登录操作,无需经历繁琐的注册步骤以及输入账号密码等一系列复杂操作,这种便捷的登录方式极大地提升了用户的使用体验
3837 12

热门文章

最新文章