From 08b89e625290310601c6996442faa5deafb599c1 Mon Sep 17 00:00:00 2001 From: fengsilin Date: Wed, 20 May 2026 15:17:16 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=B7=BB=E5=8A=A0=E7=99=BB=E5=BD=95=20?= =?UTF-8?q?Widget=20=E8=AE=BE=E8=AE=A1=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 纯前端登录表单 Widget,通过 + +``` + +## Widget API + +### `NewApiLoginWidget.init(options)` + +| 参数 | 类型 | 必填 | 说明 | +|------|------|------|------| +| `container` | `string \| Element` | 是 | 挂载点,CSS 选择器或 DOM 元素 | +| `apiUrl` | `string` | 是 | new-api 服务地址 | +| `onSuccess` | `(data: UserData) => void` | 否 | 登录成功回调 | +| `onError` | `(err: { message: string }) => void` | 否 | 登录失败回调 | +| `theme` | `'light' \| 'dark'` | 否 | 主题,默认 `'light'` | + +### 返回值 + +`{ destroy: () => void }` — 调用 `destroy()` 卸载 Widget 并清理 DOM。 + +### 回调数据格式 + +```typescript +// onSuccess 回调参数 +interface UserData { + id: number; + username: string; + display_name: string; + role: number; + status: number; + group: string; +} +``` + +## 技术方案 + +### 构建方式 + +在 `web/widget/` 目录下创建独立的 Vite 入口,打包成 UMD 格式。 + +``` +web/widget/ + index.jsx # 入口:init() API,创建 Shadow DOM 并挂载 React 组件 + LoginForm.jsx # 登录表单组件(参考 web/src/components/auth/LoginForm.jsx) + styles.css # Widget 样式 + vite.config.js # UMD 打包配置 +``` + +### 样式隔离 + +使用 Shadow DOM 隔离 Widget 样式,防止与嵌入方 CSS 冲突。 + +### API 调用 + +直接调用现有 `POST /api/user/login` 接口,跨域 CORS 已开启(`AllowAllOrigins + AllowCredentials`)。 + +请求: +```json +POST {apiUrl}/api/user/login +{ "username": "xxx", "password": "xxx" } +``` + +响应(成功): +```json +{ + "success": true, + "data": { + "id": 1, + "username": "user", + "display_name": "User", + "role": 1, + "status": 1, + "group": "default" + } +} +``` + +响应(失败): +```json +{ "success": false, "message": "用户名或密码错误" } +``` + +### 打包产物 + +- 输出:`web/build/static/login-widget.js` +- 格式:UMD(全局暴露 `NewApiLoginWidget`) +- CSS 内联到 JS bundle 中,通过 Shadow DOM 注入 +- React 和 ReactDOM 打包进 bundle(避免要求嵌入方提供 React) + +### 托管 + +由 new-api 后端的静态文件服务自动托管。构建流程: +1. `cd web && bun run build` — 构建主前端 +2. `cd web/widget && bun run build` — 构建 Widget(输出到 `web/build/static/`) +3. 最终 `web/build/static/login-widget.js` 随 new-api 部署 + +## 改动范围 + +| 位置 | 改动 | +|------|------| +| `web/widget/` | 新增目录,Widget 源码 | +| 后端 | **无改动** | +| 构建流程 | `Makefile` 或 `web/package.json` 添加 Widget 构建步骤 | + +## 范围限定(当前迭代) + +- 仅支持**密码登录** +- 不处理 2FA +- 不处理 OAuth/Passkey 等其他登录方式 +- 不管理嵌入方的认证状态(通过回调交由嵌入方处理)