@gup-fe/js-sdk 2.1.2 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,134 +1,178 @@
1
1
  # @gup-fe/js-sdk
2
2
 
3
- 这是一个现代化的、基于 React 构建的统一登录与交互 SDK。无论您使用的是纯 HTML 页面还是基于 React/Vue 的现代前端工程,都可以轻松接入。
4
-
5
- ## 特性
6
-
7
- - ⚡️ **开箱即用**: 内置样式自动动态注入,无需繁琐地手动引入 CSS 文件。
8
- - ⚛️ **原生 React 支持**: 提供了一系列可复用的 React 组件(`Login`, `MobileLogin`, `UidLogin` 等),可深度嵌入您的 React 组件树中。
9
- - 🌍 **通用兼容**: 提供 ES Modules 格式供现代构建工具(Vite, Webpack 等)进行 Tree-shaking 优化,同时提供 UMD 格式供传统 `<script>` 标签直接无缝接入。
3
+ 统一登录与交互 SDK,支持 React 项目及任意框架项目的命令式调用。
10
4
 
11
5
  ## 安装
12
6
 
13
- 如果您的项目使用了构建工具,请通过 npm/yarn/pnpm 安装:
14
-
15
7
  ```bash
16
8
  npm install @gup-fe/js-sdk
17
9
  # 或者
18
10
  pnpm add @gup-fe/js-sdk
19
11
  ```
20
12
 
21
- > **⚠️ 特别注意(针对 Vue 3 或非 React 项目):**
22
- > SDK 的底层 UI 是基于 React 渲染的,但为了避免在 React 宿主项目中产生冲突(导致 Invalid Hook Call 等报错),SDK **没有将 React 打包进源码中**。
23
- > 因此,如果您在 **Vue 3** 等其他非 React 环境中使用,必须手动在您的项目中安装 `react` 和 `react-dom` 作为运行时依赖,打包工具(如 Vite/Webpack)才能正常为您编译:
24
- > ```bash
25
- > npm install react react-dom
26
- > ```
13
+ > **⚠️ 注意:**
14
+ > - **React 项目**:直接使用主入口即可。
15
+ > - **非 React 项目**:使用内置了所有依赖(包括 React)的 `bundle` 版本,无需手动安装任何依赖。
16
+ > - **无构建工具**:请参考下文的 [CDN 接入](#4-cdn--无构建工具接入)。
17
+
18
+ ---
27
19
 
28
20
  ## 快速上手
29
21
 
30
- ### 方式一:命令式调用(推荐,适用于任意框架)
22
+ ### 1. 初始化 (推荐)
31
23
 
32
- 这是最通用的接入方式。无论您的业务逻辑写在 Vue、原生 JS 还是普通 HTML 中,只要调用 `login()`,SDK 就会自动在 `document.body` 中动态挂载登录弹窗。
24
+ 在项目入口处调用 `init` 方法配置全局参数,后续调用 API 时无需重复传入 `gameId`。
33
25
 
34
26
  ```javascript
35
- import { login } from '@gup-fe/js-sdk';
27
+ import { init } from '@gup-fe/js-sdk';
36
28
 
37
- // 一键调出登录弹窗并获取其控制句柄
38
- const { close } = login({
39
- gameId: '5242',
40
- // loginTypes: ['phone', 'uid'], // 可选:指定开启哪些登录方式
41
- onLoginSuccess: (data) => {
42
- console.log('🎉 登录成功!获取到的数据:', data)
43
- // 成功后主动关闭登录弹窗
44
- close()
45
- },
46
- onLoginError: (error) => {
47
- console.error('❌ 登录失败:', error)
48
- }
49
- });
29
+ init({ gameId: '5242' });
50
30
  ```
51
31
 
52
- ### 方式二:声明式调用(适用于 React 项目)
32
+ ### 2. React 项目
53
33
 
54
- 如果您使用的是 React,想要更好地控制弹窗的显隐和生命周期,可以直接引入 `Login` 组件。
34
+ 直接引入 `Login` 组件。
55
35
 
56
36
  ```tsx
57
- import { useState } from 'react';
58
- import { Login } from '@gup-fe/js-sdk';
37
+ import { useState, useEffect } from 'react';
38
+ import { Login, isLoggedIn, getUserInfo, logout } from '@gup-fe/js-sdk';
59
39
 
60
40
  function App() {
61
41
  const [isOpen, setIsOpen] = useState(false);
42
+ const [user, setUser] = useState(null);
43
+
44
+ useEffect(() => {
45
+ if (isLoggedIn()) {
46
+ setUser(getUserInfo());
47
+ }
48
+ }, []);
62
49
 
63
50
  return (
64
51
  <div>
65
- <button onClick={() => setIsOpen(true)}>点击登录</button>
52
+ {user ? (
53
+ <div>
54
+ <span>你好,{user.username}</span>
55
+ <button onClick={() => { logout(); setUser(null); }}>退出</button>
56
+ </div>
57
+ ) : (
58
+ <button onClick={() => setIsOpen(true)}>登录</button>
59
+ )}
66
60
 
67
- {/* 渲染 SDK 提供的组件 */}
68
61
  <Login
69
62
  open={isOpen}
70
- gameId="5242"
71
- onClose={() => setIsOpen(false)}
63
+ onOpenChange={setIsOpen}
64
+ onLoginSuccess={(data) => {
65
+ setUser(getUserInfo());
66
+ setIsOpen(false);
67
+ }}
72
68
  />
73
69
  </div>
74
70
  );
75
71
  }
76
72
  ```
77
73
 
78
- ### 方式三:无构建工具接入(传统 HTML 页面 / CDN)
74
+ 适用于 Vue、原生 JS 等使用构建工具(Vite/Webpack)的项目。使用 `/bundle` 入口可以免去手动安装 React 的麻烦。
75
+
76
+ ```javascript
77
+ import { login, logout, isLoggedIn } from '@gup-fe/js-sdk/bundle';
78
+
79
+ const { close } = login({
80
+ onLoginSuccess: (data) => {
81
+ console.log('登录成功', data);
82
+ close();
83
+ }
84
+ });
85
+ ```
79
86
 
80
- 通过传统的 `<script>` 标签引入 UMD 格式的构建产物。加载后,SDK 会自动将方法挂载到浏览器的全局变量 `window.SDK` 上。
87
+ ### 4. CDN / 无构建工具接入
81
88
 
82
- *(注:请在实际发布后,将路径中的版本号替换为您上传的真实版本)*
89
+ 对于不使用 `npm` 的原生 HTML 页面,请按照以下顺序引入。推荐使用 `bundle` 版本以获得最简单的“零依赖”接入体验(已内置 React 运行时,无需手动引入 React)。
83
90
 
84
91
  ```html
85
- <!DOCTYPE html>
86
- <html>
87
- <head>
88
- <meta charset="utf-8">
89
- <title>JS SDK Demo</title>
90
- </head>
91
- <body>
92
- <!-- 1. 必须先引入 React 运行时库 -->
93
- <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
94
- <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
95
-
96
- <!-- 2. 引入 SDK 的 UMD 产物 -->
97
- <script src="https://unpkg.com/@gup-fe/js-sdk@2.1.0/dist/js-sdk.umd.js"></script>
92
+ <!-- 推荐使用 bundle 版本,已内置所有依赖(包含 React) -->
93
+ <script src="https://unpkg.com/@gup-fe/js-sdk/dist/js-sdk.bundle.umd.js"></script>
94
+
95
+ <script>
96
+ SDK.init({ gameId: '5242' });
98
97
 
99
- <script>
100
- // 直接使用全局变量 SDK 调用
101
- SDK.login({
102
- gameId: '5242'
103
- });
104
- </script>
105
- </body>
106
- </html>
98
+ SDK.login({
99
+ onLoginSuccess: (data) => console.log('登录成功', data)
100
+ });
101
+ </script>
107
102
  ```
108
103
 
109
- ## 关于样式 (CSS) 的说明
110
-
111
- 为了提供最佳的开发者体验,本 SDK 在构建打包时已经**将 CSS 样式转换并内联打包到了 JS 中**。
112
- 这意味着,当您执行 `login()` 或渲染 `<Login />` 组件时,SDK 内部会自动将相关的 `<style>` 标签注入到文档的 `<head>` 中。
113
- **您不需要、也不应该尝试手动去 `import '@gup-fe/js-sdk/dist/xxx.css'`。** 所有的 UI 都会“开箱即用”地完美呈现。
104
+ ---
114
105
 
115
106
  ## API 参考
116
107
 
117
- ### `login(options)`
108
+ ### 核心方法
109
+
110
+ #### `init(config)`
111
+ 初始化 SDK 全局配置。
112
+ - `config.gameId`: (必填) 游戏 ID。
118
113
 
119
- 触发并显示登录组件的核心方法。
114
+ #### `login(options)`
115
+ 唤起登录弹窗。
116
+ - `options.onLoginSuccess`: 登录成功回调。
117
+ - `options.onLoginError`: 登录失败回调。
118
+ - `options.loginTypes`: 可选。自定义登录方式 `['phone', 'uid', 'account']`。
120
119
 
121
- | 参数名 | 类型 | 必填 | 默认值 | 说明 |
122
- | ------------ | -------------- | ---- | ------ | ---------------------------------------- |
123
- | `gameId` | `string` | **是** | - | 当前业务/游戏的唯一标识 ID |
124
- | `loginTypes` | `LoginTypes[]` | 否 | - | 支持的登录方式列表,例如 `['phone', 'uid']` |
125
- | `onLoginSuccess` | `(data: any) => void` | 否 | - | 无论哪种登录方式,**登录成功**后触发的回调,并返回登录信息 |
126
- | `onLoginError` | `(error: any) => void`| 否 | - | 无论哪种登录方式,**登录失败**后触发的回调,并返回错误信息 |
120
+ #### `logout()`
121
+ 清除当前登录状态。
122
+
123
+ #### `isLoggedIn()`
124
+ 判断当前是否已登录。
125
+
126
+ #### `getUserInfo()`
127
+ 获取当前登录的用户信息(返回 `UserInfo` 对象)。
128
+
129
+ ### 类型定义
130
+
131
+ #### `UserInfo`
132
+ ```typescript
133
+ interface UserInfo {
134
+ username: string;
135
+ openid: string;
136
+ account?: PassAccount;
137
+ // ... 其他属性
138
+ }
139
+ ```
140
+
141
+ ---
142
+
143
+ ## UI 自定义 (StyleVars)
144
+
145
+ SDK 支持通过 `styleVars` 参数自定义基础视觉样式(基于 CSS 变量)。
146
+
147
+ ### 支持的变量
148
+
149
+ | 变量名 | 说明 | 默认值 |
150
+ | --- | --- | --- |
151
+ | `--primary-color` | 主题色(按钮、高亮等) | `#497efe` |
152
+ | `--icon-color` | 图标颜色 | `#497efe` |
153
+ | `--input-bg-color` | 输入框背景色 | `#f5f5f5` |
154
+ | `--input-border-color` | 输入框边框颜色 | `transparent` |
155
+ | `--input-label-color` | 输入框标签文字颜色 | `#999999` |
156
+
157
+ ### 使用示例
158
+
159
+ #### 1. React 方式
160
+ ```tsx
161
+ <Login
162
+ styleVars={{
163
+ '--primary-color': '#ff5000',
164
+ '--input-bg-color': '#ffffff',
165
+ '--input-border-color': '#eeeeee'
166
+ }}
167
+ />
168
+ ```
169
+
170
+ #### 2. 命令式方式
171
+ ```javascript
172
+ login({
173
+ styleVars: {
174
+ '--primary-color': '#00c853'
175
+ }
176
+ });
177
+ ```
127
178
 
128
- ### 导出的核心组件与配置
129
- 对于有高度定制化需求的业务方,SDK 同样暴露了以下底层组件:
130
- - `Login`:完整的登录弹窗业务组件。
131
- - `MobileLogin`:仅含“手机号验证码”界面的登录组件。
132
- - `UidLogin`:仅含“账号密码”界面的登录组件。
133
- - `ConfigProvider`:SDK 全局上下文配置组件。
134
- - `LOGIN_TYPES`:登录方式相关的类型常量。
package/dist/index.d.ts CHANGED
@@ -7,6 +7,34 @@ declare interface AutoLoginConfig {
7
7
  days?: number;
8
8
  }
9
9
 
10
+ export declare interface CallbackLoginData {
11
+ account: {
12
+ account_type: number;
13
+ mobile: string;
14
+ type: number;
15
+ uid: string;
16
+ view_name: string;
17
+ };
18
+ entity: {
19
+ account: string;
20
+ account_type: number;
21
+ openid: string;
22
+ time: number;
23
+ type: number;
24
+ realname?: any;
25
+ };
26
+ token: string;
27
+ sign: string;
28
+ accid: string;
29
+ extra_data: {
30
+ [key: string]: unknown;
31
+ };
32
+ gaplaySign?: string;
33
+ realname?: any;
34
+ _auth?: string;
35
+ channel?: number;
36
+ }
37
+
10
38
  declare interface ConfigContextType {
11
39
  gameId: string;
12
40
  autoLoginConfig: AutoLoginConfig;
@@ -16,10 +44,10 @@ declare interface ConfigContextType {
16
44
  currentLoginType?: LoginTypes;
17
45
  defaultLoginType?: LoginTypes;
18
46
  setCurrentLoginType: (newLoginType: LoginTypes) => void;
19
- onUidLoginSuccess?: (data: any) => void;
20
- onPhoneLoginSuccess?: ((data: PhoneLoginResponse) => void) | ((data: PhoneLoginResponse) => Promise<void>);
21
- onAccountLoginSuccess?: (data: PhoneLoginResponse) => void;
22
- onLoginSuccess?: (data: any) => void;
47
+ onUidLoginSuccess?: (data: CallbackLoginData) => void;
48
+ onPhoneLoginSuccess?: ((data: CallbackLoginData) => void) | ((data: CallbackLoginData) => Promise<void>);
49
+ onAccountLoginSuccess?: (data: CallbackLoginData) => void;
50
+ onLoginSuccess?: (data: CallbackLoginData) => void;
23
51
  onLoginError?: (error: any) => void;
24
52
  closeable?: boolean;
25
53
  uidLoginConfig?: {
@@ -34,30 +62,51 @@ declare interface ConfigContextType {
34
62
  };
35
63
  isShowGiantLogo: boolean;
36
64
  setIsShowGiantLogo: (value: boolean) => void;
65
+ showRealNameModal: boolean;
66
+ setShowRealNameModal: (show: boolean) => void;
67
+ triggerRealNameAuth: () => void;
68
+ isAutoLoggingIn: boolean;
69
+ setIsAutoLoggingIn: (value: boolean) => void;
70
+ autoLoginAccountName: string;
71
+ setAutoLoginAccountName: (value: string) => void;
72
+ onClose?: () => void;
37
73
  }
38
74
 
39
75
  export declare function ConfigProvider({ children, value }: ConfigProviderProps): JSX.Element;
40
76
 
77
+ declare interface ConfigProviderInput extends Omit<ConfigContextType, 'gameId' | 'autoLoginConfig' | 'setCurrentLoginType' | 'isShowGiantLogo' | 'setIsShowGiantLogo' | 'showRealNameModal' | 'setShowRealNameModal' | 'triggerRealNameAuth' | 'isAutoLoggingIn' | 'setIsAutoLoggingIn' | 'autoLoginAccountName' | 'setAutoLoginAccountName'> {
78
+ gameId?: string;
79
+ autoLoginConfig?: AutoLoginConfig;
80
+ }
81
+
41
82
  declare interface ConfigProviderProps {
42
83
  children: default_2.ReactNode;
43
- value: Omit<ConfigContextType, 'autoLoginConfig' | 'setCurrentLoginType' | 'setIsShowGiantLogo' | 'isShowGiantLogo'> & {
44
- autoLoginConfig?: AutoLoginConfig;
45
- };
84
+ value: ConfigProviderInput;
46
85
  }
47
86
 
87
+ export declare function getGameId(gameId?: string): string;
88
+
89
+ export declare const getUserInfo: (gameId?: string) => UserInfo;
90
+
91
+ export declare function init(config: {
92
+ gameId: string;
93
+ }): void;
94
+
95
+ export declare const isLoggedIn: (gameId?: string) => boolean;
96
+
48
97
  export declare function Login({ open, onOpenChange, sceneId, onPhoneLoginSuccess, onAccountLoginSuccess, onUidLoginSuccess, onLoginSuccess, onLoginError, closeable, mountToaster, toastConfigs, ...props }: Props): JSX.Element;
49
98
 
50
99
  export declare function login({ loginTypes, defaultLoginType, gameId, onLoginSuccess, onLoginError, }: {
51
100
  loginTypes?: LoginTypes[];
52
101
  defaultLoginType?: LoginTypes;
53
- gameId: string;
54
- onLoginSuccess?: (data: any) => void;
102
+ gameId?: string;
103
+ onLoginSuccess?: (data: CallbackLoginData) => void;
55
104
  onLoginError?: (error: any) => void;
56
105
  }): {
57
106
  close: () => void;
58
107
  };
59
108
 
60
- export declare const LOGIN_TYPES: {
109
+ declare const LOGIN_TYPES: {
61
110
  readonly ROLE_ID: "roleid";
62
111
  readonly GIANT: "giant";
63
112
  readonly MOBILE: "mobile";
@@ -76,6 +125,8 @@ export declare interface LoginOptions {
76
125
 
77
126
  declare type LoginTypes = typeof LOGIN_TYPES[keyof typeof LOGIN_TYPES];
78
127
 
128
+ export declare const logout: (gameId?: string) => void;
129
+
79
130
  export declare function MobileLogin(): JSX.Element;
80
131
 
81
132
  export declare interface PassAccount {
@@ -95,6 +146,7 @@ export declare interface PhoneLoginResponse {
95
146
  view_name: string;
96
147
  };
97
148
  channel_info: {
149
+ realname: any;
98
150
  code: number;
99
151
  sign: string;
100
152
  token: string;
@@ -105,6 +157,7 @@ export declare interface PhoneLoginResponse {
105
157
  openid: string;
106
158
  time: number;
107
159
  type: number;
160
+ realname?: any;
108
161
  };
109
162
  extra_data: {
110
163
  appunid: string;
@@ -120,16 +173,18 @@ export declare interface PhoneLoginResponse {
120
173
  };
121
174
  };
122
175
  token: string;
176
+ _auth: string;
123
177
  }
124
178
 
125
- declare interface Props extends Omit<ConfigContextType, 'setCurrentLoginType' | 'setIsShowGiantLogo' | 'isShowGiantLogo' | 'autoLoginConfig'> {
179
+ declare interface Props extends Omit<ConfigContextType, 'gameId' | 'setCurrentLoginType' | 'setIsShowGiantLogo' | 'isShowGiantLogo' | 'autoLoginConfig' | 'showRealNameModal' | 'setShowRealNameModal' | 'triggerRealNameAuth' | 'isAutoLoggingIn' | 'setIsAutoLoggingIn' | 'autoLoginAccountName' | 'setAutoLoginAccountName' | 'onClose'> {
180
+ gameId?: string;
126
181
  open?: boolean;
127
182
  onOpenChange?: (open: boolean) => void;
128
- onPhoneLoginSuccess?: (data: PhoneLoginResponse) => void;
129
- onAccountLoginSuccess?: (data: PhoneLoginResponse) => void;
183
+ onPhoneLoginSuccess?: (data: CallbackLoginData) => void;
184
+ onAccountLoginSuccess?: (data: CallbackLoginData) => void;
130
185
  sceneId?: number;
131
- onUidLoginSuccess?: (data: any) => void;
132
- onLoginSuccess?: (data: any) => void;
186
+ onUidLoginSuccess?: (data: CallbackLoginData) => void;
187
+ onLoginSuccess?: (data: CallbackLoginData) => void;
133
188
  onLoginError?: (error: any) => void;
134
189
  autoLoginConfig?: AutoLoginConfig;
135
190
  closeable?: boolean;
@@ -137,8 +192,53 @@ declare interface Props extends Omit<ConfigContextType, 'setCurrentLoginType' |
137
192
  toastConfigs?: ToastConfigs;
138
193
  }
139
194
 
195
+ export declare interface QuickLoginResponse {
196
+ account: {
197
+ account_type: number;
198
+ mobile: string;
199
+ type: number;
200
+ uid: string;
201
+ view_name: string;
202
+ };
203
+ channel_info: {
204
+ code: number;
205
+ sign: string;
206
+ token: string;
207
+ gaplaySign: string;
208
+ entity: {
209
+ account: string;
210
+ account_type: number;
211
+ openid: string;
212
+ time: number;
213
+ type: number;
214
+ realname: any;
215
+ };
216
+ extra_data: {
217
+ [key: string]: unknown;
218
+ };
219
+ };
220
+ token: string;
221
+ _auth?: string;
222
+ }
223
+
224
+ export declare interface SavedAccount {
225
+ openid: string;
226
+ username: string;
227
+ uid: string;
228
+ mobile: string;
229
+ accountType: number;
230
+ authorization: string;
231
+ loginAt: number;
232
+ loginCnt: number;
233
+ gameId: string;
234
+ }
235
+
140
236
  export declare const SDK: {
237
+ init: typeof init;
141
238
  login: typeof login;
239
+ logout: (gameId?: string) => void;
240
+ getUserInfo: (gameId?: string) => UserInfo;
241
+ isLoggedIn: (gameId?: string) => boolean;
142
242
  };
143
243
 
144
244
  declare interface StyleVars {
@@ -172,12 +272,6 @@ export declare function UidLogin({ onUidLoginSuccess: onUidLoginSuccessProp, cus
172
272
  }): JSX.Element;
173
273
 
174
274
  export declare interface UserInfo {
175
- id: string;
176
- email: string;
177
- name?: string;
178
- }
179
-
180
- export declare interface UserInfoV2 {
181
275
  $version: 'v2';
182
276
  account?: PassAccount;
183
277
  channelId: number;