| @@ -0,0 +1,232 @@ | |||
| # 登录 Widget 使用指南 | |||
| ## 概述 | |||
| 登录 Widget 是一个可嵌入到任何网页的登录表单组件。通过一行 `<script>` 标签引入,即可在你的网站上展示 New API 的登录界面。用户登录成功后,通过回调函数返回用户数据,由嵌入方自行处理后续逻辑。 | |||
| **当前版本仅支持密码登录。** | |||
| --- | |||
| ## 快速开始 | |||
| ### 1. 引入脚本 | |||
| 在你的 HTML 页面中添加 `<script>` 标签,`src` 指向你的 New API 服务地址: | |||
| ```html | |||
| <script src="https://your-domain.com/static/login-widget.js"></script> | |||
| ``` | |||
| ### 2. 创建容器 | |||
| 在页面中放置一个 DOM 元素作为 Widget 的挂载点: | |||
| ```html | |||
| <div id="login-container"></div> | |||
| ``` | |||
| ### 3. 初始化 Widget | |||
| 在脚本加载后调用 `NewApiLoginWidget.init()`: | |||
| ```html | |||
| <script> | |||
| var widget = NewApiLoginWidget.init({ | |||
| container: '#login-container', | |||
| apiUrl: 'https://your-domain.com', | |||
| onSuccess: function(data) { | |||
| console.log('登录成功', data); | |||
| // 在这里处理登录成功逻辑 | |||
| }, | |||
| onError: function(err) { | |||
| console.log('登录失败', err.message); | |||
| } | |||
| }); | |||
| </script> | |||
| ``` | |||
| ### 完整示例 | |||
| ```html | |||
| <!DOCTYPE html> | |||
| <html> | |||
| <head> | |||
| <meta charset="UTF-8"> | |||
| <title>我的网站</title> | |||
| </head> | |||
| <body> | |||
| <h1>欢迎</h1> | |||
| <!-- 登录 Widget 挂载点 --> | |||
| <div id="login-container"></div> | |||
| <!-- 引入 Widget 脚本 --> | |||
| <script src="https://your-domain.com/static/login-widget.js"></script> | |||
| <!-- 初始化 --> | |||
| <script> | |||
| var widget = NewApiLoginWidget.init({ | |||
| container: '#login-container', | |||
| apiUrl: 'https://your-domain.com', | |||
| onSuccess: function(data) { | |||
| // 登录成功,保存用户信息 | |||
| localStorage.setItem('user', JSON.stringify(data)); | |||
| alert('欢迎, ' + data.username); | |||
| }, | |||
| onError: function(err) { | |||
| alert('登录失败: ' + err.message); | |||
| } | |||
| }); | |||
| </script> | |||
| </body> | |||
| </html> | |||
| ``` | |||
| --- | |||
| ## API 参考 | |||
| ### `NewApiLoginWidget.init(options)` | |||
| 初始化并渲染登录表单。 | |||
| #### 参数 | |||
| | 参数 | 类型 | 必填 | 说明 | | |||
| |------|------|------|------| | |||
| | `container` | `string` 或 `Element` | 是 | 挂载点,支持 CSS 选择器字符串或 DOM 元素 | | |||
| | `apiUrl` | `string` | 是 | New API 服务地址,如 `https://api.example.com` | | |||
| | `onSuccess` | `function` | 否 | 登录成功回调,参数为用户数据对象 | | |||
| | `onError` | `function` | 否 | 登录失败回调,参数为 `{ message: string }` | | |||
| | `theme` | `string` | 否 | 主题,可选 `'light'`(默认)或 `'dark'` | | |||
| #### 返回值 | |||
| 返回一个对象,包含以下方法: | |||
| | 方法 | 说明 | | |||
| |------|------| | |||
| | `destroy()` | 卸载 Widget,清除 DOM | | |||
| #### onSuccess 回调数据 | |||
| ```json | |||
| { | |||
| "id": 1, | |||
| "username": "user", | |||
| "display_name": "用户", | |||
| "role": 1, | |||
| "status": 1, | |||
| "group": "default" | |||
| } | |||
| ``` | |||
| | 字段 | 类型 | 说明 | | |||
| |------|------|------| | |||
| | `id` | number | 用户 ID | | |||
| | `username` | string | 用户名 | | |||
| | `display_name` | string | 显示名称 | | |||
| | `role` | number | 角色(1=普通用户,10+=管理员,100+=超级管理员) | | |||
| | `status` | number | 状态 | | |||
| | `group` | string | 用户组 | | |||
| --- | |||
| ## 主题 | |||
| ### Light(默认) | |||
| ```js | |||
| NewApiLoginWidget.init({ | |||
| container: '#login', | |||
| apiUrl: 'https://your-domain.com', | |||
| // theme: 'light' // 默认就是 light,可省略 | |||
| }); | |||
| ``` | |||
| ### Dark | |||
| ```js | |||
| NewApiLoginWidget.init({ | |||
| container: '#login', | |||
| apiUrl: 'https://your-domain.com', | |||
| theme: 'dark' | |||
| }); | |||
| ``` | |||
| --- | |||
| ## 销毁 Widget | |||
| 当不再需要登录表单时(如登录成功后),调用 `destroy()` 移除: | |||
| ```js | |||
| var widget = NewApiLoginWidget.init({ ... }); | |||
| // 登录成功后销毁 | |||
| widget.destroy(); | |||
| ``` | |||
| --- | |||
| ## 同一页面多个实例 | |||
| 支持在同一页面创建多个 Widget 实例(如同时显示 Light 和 Dark 主题): | |||
| ```html | |||
| <div id="login-light"></div> | |||
| <div id="login-dark"></div> | |||
| <script src="https://your-domain.com/static/login-widget.js"></script> | |||
| <script> | |||
| var widget1 = NewApiLoginWidget.init({ | |||
| container: '#login-light', | |||
| apiUrl: 'https://your-domain.com', | |||
| theme: 'light' | |||
| }); | |||
| var widget2 = NewApiLoginWidget.init({ | |||
| container: '#login-dark', | |||
| apiUrl: 'https://your-domain.com', | |||
| theme: 'dark' | |||
| }); | |||
| </script> | |||
| ``` | |||
| --- | |||
| ## 注意事项 | |||
| 1. **跨域支持**:Widget 支持跨域嵌入。你的 New API 服务已配置 CORS,允许任意域名调用登录接口。 | |||
| 2. **HTTPS**:生产环境建议 New API 服务使用 HTTPS,否则部分浏览器功能可能受限。 | |||
| 3. **不管理会话**:Widget 只负责登录验证并返回用户数据,不会自动管理嵌入方的登录状态。你需要在 `onSuccess` 回调中自行处理用户会话。 | |||
| 4. **两步验证(2FA)**:当前版本不支持 2FA。如果用户启用了两步验证,`onError` 会收到提示信息。 | |||
| 5. **文件大小**:Widget JS 约 146KB(含 React 运行时),gzip 后约 48KB。 | |||
| --- | |||
| ## 常见问题 | |||
| ### Q: 引入脚本后页面报错 `NewApiLoginWidget is not defined` | |||
| 确保 `<script src="...login-widget.js">` 在调用 `init()` 的 `<script>` 之前。浏览器按顺序执行脚本,Widget 脚本必须先加载完成。 | |||
| ### Q: 登录成功后如何调用 New API 的其他接口 | |||
| `onSuccess` 返回的数据中不包含 Token。你需要: | |||
| - 方案一:调用 `/api/token` 接口用用户密码创建一个 API Token | |||
| - 方案二:在 New API 后端登录后,使用返回的用户信息自行实现会话管理 | |||
| ### Q: 可以自定义样式吗 | |||
| Widget 使用 Shadow DOM 隔离样式,外部 CSS 不会影响内部。当前仅支持 `light` 和 `dark` 两种内置主题。如需深度自定义,需要修改 `web/widget/styles.css` 并重新构建。 | |||
| ### Q: 如何重新构建 Widget | |||
| ```bash | |||
| cd web/widget && bun install && bun run build | |||
| ``` | |||
| 构建产物输出到 `web/dist/static/login-widget.js`。重新编译后端(`go build`)后生效。 | |||