@windrun-huaiin/third-ui 7.3.6 → 7.3.7

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.
@@ -5,43 +5,35 @@
5
5
  */
6
6
  /**
7
7
  * 生成基于真实浏览器特征的fingerprint ID
8
- * 使用FingerprintJS收集浏览器特征并生成唯一标识
9
- * 只能在客户端使用
8
+ * 使用 FingerprintJS 收集浏览器特征并生成唯一标识
10
9
  */
11
10
  export declare function generateFingerprintId(): Promise<string>;
12
11
  /**
13
12
  * 获取当前的fingerprint ID
14
- * 只能在客户端使用
15
13
  */
16
14
  export declare function getFingerprintId(): string | null;
17
15
  /**
18
16
  * 设置fingerprint ID到存储
19
- * 只能在客户端使用
20
17
  */
21
18
  export declare function setFingerprintId(fingerprintId: string): void;
22
19
  /**
23
20
  * 清除fingerprint ID
24
- * 只能在客户端使用
25
21
  */
26
22
  export declare function clearFingerprintId(): void;
27
23
  /**
28
24
  * 获取或生成fingerprint ID
29
25
  * 如果不存在则自动生成新的
30
- * 只能在客户端使用
31
26
  */
32
27
  export declare function getOrGenerateFingerprintId(): Promise<string>;
33
28
  /**
34
29
  * 创建包含fingerprint ID的fetch headers
35
- * 只能在客户端使用
36
30
  */
37
31
  export declare function createFingerprintHeaders(): Promise<Record<string, string>>;
38
32
  /**
39
33
  * Hook for generating fingerprint headers
40
- * 只能在客户端使用
41
34
  */
42
35
  export declare function useFingerprintHeaders(): () => Promise<Record<string, string>>;
43
36
  /**
44
37
  * Create a fetch wrapper that automatically includes fingerprint headers
45
- * 只能在客户端使用
46
38
  */
47
39
  export declare function createFingerprintFetch(): (url: string | URL | Request, init?: RequestInit) => Promise<Response>;
@@ -1,92 +1,94 @@
1
1
  'use strict';
2
2
 
3
3
  var tslib_es6 = require('../../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.2/node_modules/tslib/tslib.es6.js');
4
- var fingerprintShared = require('./fingerprint-shared.js');
5
4
  var fp_esm = require('../../node_modules/.pnpm/@fingerprintjs_fingerprintjs@4.6.2/node_modules/@fingerprintjs/fingerprintjs/dist/fp.esm.js');
5
+ var fingerprintShared = require('./fingerprint-shared.js');
6
6
 
7
7
  /**
8
8
  * Fingerprint Client Utilities
9
9
  * 客户端专用的指纹生成和管理逻辑
10
10
  * 只能在浏览器环境中使用
11
11
  */
12
+ /**
13
+ * 检查浏览器存储(localStorage 和 cookie)中的指纹 ID
14
+ * 返回有效的 ID 或 null
15
+ */
16
+ function checkStoredFingerprintId() {
17
+ if (typeof window === 'undefined') {
18
+ return null;
19
+ }
20
+ // 优先检查 localStorage
21
+ const localStorageId = localStorage.getItem(fingerprintShared.FINGERPRINT_STORAGE_KEY);
22
+ if (localStorageId && fingerprintShared.isValidFingerprintId(localStorageId)) {
23
+ return localStorageId;
24
+ }
25
+ // 检查 cookie
26
+ const cookieId = getCookieValue(fingerprintShared.FINGERPRINT_COOKIE_NAME);
27
+ if (cookieId && fingerprintShared.isValidFingerprintId(cookieId)) {
28
+ // 同步到 localStorage
29
+ localStorage.setItem(fingerprintShared.FINGERPRINT_STORAGE_KEY, cookieId);
30
+ return cookieId;
31
+ }
32
+ return null;
33
+ }
12
34
  /**
13
35
  * 生成基于真实浏览器特征的fingerprint ID
14
- * 使用FingerprintJS收集浏览器特征并生成唯一标识
15
- * 只能在客户端使用
36
+ * 使用 FingerprintJS 收集浏览器特征并生成唯一标识
16
37
  */
17
38
  function generateFingerprintId() {
18
39
  return tslib_es6.__awaiter(this, void 0, void 0, function* () {
19
40
  if (typeof window === 'undefined') {
20
41
  throw new Error('generateFingerprintId can only be used in browser environment');
21
42
  }
22
- // 首先检查现有ID
23
- const existingId = getFingerprintId();
24
- if (existingId && fingerprintShared.isValidFingerprintId(existingId)) {
43
+ // 检查现有 ID
44
+ const existingId = checkStoredFingerprintId();
45
+ if (existingId) {
46
+ console.log('Using existing fingerprint ID:', existingId);
25
47
  return existingId;
26
48
  }
27
- // 检查cookie
28
- const cookieId = getCookieValue(fingerprintShared.FINGERPRINT_COOKIE_NAME);
29
- if (cookieId && fingerprintShared.isValidFingerprintId(cookieId)) {
30
- // 同步到localStorage
31
- localStorage.setItem(fingerprintShared.FINGERPRINT_STORAGE_KEY, cookieId);
32
- return cookieId;
33
- }
34
49
  try {
35
- // 使用FingerprintJS生成基于浏览器特征的指纹
50
+ // 使用 FingerprintJS 生成指纹
36
51
  const fp = yield fp_esm.default.load();
37
52
  const result = yield fp.get();
38
53
  const fingerprintId = `fp_${result.visitorId}`;
39
- // 存储到localStorage和cookie
54
+ // 存储到 localStorage cookie
40
55
  localStorage.setItem(fingerprintShared.FINGERPRINT_STORAGE_KEY, fingerprintId);
41
- setCookie(fingerprintShared.FINGERPRINT_COOKIE_NAME, fingerprintId, 365); // 365天过期
56
+ setCookie(fingerprintShared.FINGERPRINT_COOKIE_NAME, fingerprintId, 365);
57
+ console.log('Generated new fingerprint ID:', fingerprintId);
42
58
  return fingerprintId;
43
59
  }
44
60
  catch (error) {
45
61
  console.warn('Failed to generate fingerprint with FingerprintJS:', error);
46
- // 降级方案:生成时间戳+随机数
62
+ // 降级方案:生成基于时间戳和随机数的 ID
47
63
  const fallbackId = `fp_fallback_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
48
64
  localStorage.setItem(fingerprintShared.FINGERPRINT_STORAGE_KEY, fallbackId);
49
65
  setCookie(fingerprintShared.FINGERPRINT_COOKIE_NAME, fallbackId, 365);
66
+ console.log('Generated fallback fingerprint ID:', fallbackId);
50
67
  return fallbackId;
51
68
  }
52
69
  });
53
70
  }
54
71
  /**
55
72
  * 获取当前的fingerprint ID
56
- * 只能在客户端使用
57
73
  */
58
74
  function getFingerprintId() {
59
- if (typeof window === 'undefined') {
60
- return null;
61
- }
62
- // 首先检查localStorage
63
- const localStorageId = localStorage.getItem(fingerprintShared.FINGERPRINT_STORAGE_KEY);
64
- if (localStorageId) {
65
- return localStorageId;
66
- }
67
- // 检查cookie
68
- const cookieId = getCookieValue(fingerprintShared.FINGERPRINT_COOKIE_NAME);
69
- if (cookieId) {
70
- // 同步到localStorage
71
- localStorage.setItem(fingerprintShared.FINGERPRINT_STORAGE_KEY, cookieId);
72
- return cookieId;
73
- }
74
- return null;
75
+ return checkStoredFingerprintId();
75
76
  }
76
77
  /**
77
78
  * 设置fingerprint ID到存储
78
- * 只能在客户端使用
79
79
  */
80
80
  function setFingerprintId(fingerprintId) {
81
81
  if (typeof window === 'undefined') {
82
82
  throw new Error('setFingerprintId can only be used in browser environment');
83
83
  }
84
+ if (!fingerprintShared.isValidFingerprintId(fingerprintId)) {
85
+ throw new Error('Invalid fingerprint ID');
86
+ }
84
87
  localStorage.setItem(fingerprintShared.FINGERPRINT_STORAGE_KEY, fingerprintId);
85
88
  setCookie(fingerprintShared.FINGERPRINT_COOKIE_NAME, fingerprintId, 365);
86
89
  }
87
90
  /**
88
91
  * 清除fingerprint ID
89
- * 只能在客户端使用
90
92
  */
91
93
  function clearFingerprintId() {
92
94
  if (typeof window === 'undefined') {
@@ -98,12 +100,12 @@ function clearFingerprintId() {
98
100
  /**
99
101
  * 获取或生成fingerprint ID
100
102
  * 如果不存在则自动生成新的
101
- * 只能在客户端使用
102
103
  */
103
104
  function getOrGenerateFingerprintId() {
104
105
  return tslib_es6.__awaiter(this, void 0, void 0, function* () {
105
- const existingId = getFingerprintId();
106
+ const existingId = checkStoredFingerprintId();
106
107
  if (existingId) {
108
+ console.log('Retrieved existing fingerprint ID:', existingId);
107
109
  return existingId;
108
110
  }
109
111
  return yield generateFingerprintId();
@@ -111,7 +113,6 @@ function getOrGenerateFingerprintId() {
111
113
  }
112
114
  /**
113
115
  * 创建包含fingerprint ID的fetch headers
114
- * 只能在客户端使用
115
116
  */
116
117
  function createFingerprintHeaders() {
117
118
  return tslib_es6.__awaiter(this, void 0, void 0, function* () {
@@ -123,14 +124,12 @@ function createFingerprintHeaders() {
123
124
  }
124
125
  /**
125
126
  * Hook for generating fingerprint headers
126
- * 只能在客户端使用
127
127
  */
128
128
  function useFingerprintHeaders() {
129
129
  return createFingerprintHeaders;
130
130
  }
131
131
  /**
132
132
  * Create a fetch wrapper that automatically includes fingerprint headers
133
- * 只能在客户端使用
134
133
  */
135
134
  function createFingerprintFetch() {
136
135
  return (url, init) => tslib_es6.__awaiter(this, void 0, void 0, function* () {
@@ -1,90 +1,92 @@
1
1
  import { __awaiter } from '../../node_modules/.pnpm/@rollup_plugin-typescript@12.1.4_rollup@4.46.2_tslib@2.8.1_typescript@5.9.2/node_modules/tslib/tslib.es6.mjs';
2
- import { FINGERPRINT_STORAGE_KEY, isValidFingerprintId, FINGERPRINT_COOKIE_NAME } from './fingerprint-shared.mjs';
3
2
  import index from '../../node_modules/.pnpm/@fingerprintjs_fingerprintjs@4.6.2/node_modules/@fingerprintjs/fingerprintjs/dist/fp.esm.mjs';
3
+ import { isValidFingerprintId, FINGERPRINT_STORAGE_KEY, FINGERPRINT_COOKIE_NAME } from './fingerprint-shared.mjs';
4
4
 
5
5
  /**
6
6
  * Fingerprint Client Utilities
7
7
  * 客户端专用的指纹生成和管理逻辑
8
8
  * 只能在浏览器环境中使用
9
9
  */
10
+ /**
11
+ * 检查浏览器存储(localStorage 和 cookie)中的指纹 ID
12
+ * 返回有效的 ID 或 null
13
+ */
14
+ function checkStoredFingerprintId() {
15
+ if (typeof window === 'undefined') {
16
+ return null;
17
+ }
18
+ // 优先检查 localStorage
19
+ const localStorageId = localStorage.getItem(FINGERPRINT_STORAGE_KEY);
20
+ if (localStorageId && isValidFingerprintId(localStorageId)) {
21
+ return localStorageId;
22
+ }
23
+ // 检查 cookie
24
+ const cookieId = getCookieValue(FINGERPRINT_COOKIE_NAME);
25
+ if (cookieId && isValidFingerprintId(cookieId)) {
26
+ // 同步到 localStorage
27
+ localStorage.setItem(FINGERPRINT_STORAGE_KEY, cookieId);
28
+ return cookieId;
29
+ }
30
+ return null;
31
+ }
10
32
  /**
11
33
  * 生成基于真实浏览器特征的fingerprint ID
12
- * 使用FingerprintJS收集浏览器特征并生成唯一标识
13
- * 只能在客户端使用
34
+ * 使用 FingerprintJS 收集浏览器特征并生成唯一标识
14
35
  */
15
36
  function generateFingerprintId() {
16
37
  return __awaiter(this, void 0, void 0, function* () {
17
38
  if (typeof window === 'undefined') {
18
39
  throw new Error('generateFingerprintId can only be used in browser environment');
19
40
  }
20
- // 首先检查现有ID
21
- const existingId = getFingerprintId();
22
- if (existingId && isValidFingerprintId(existingId)) {
41
+ // 检查现有 ID
42
+ const existingId = checkStoredFingerprintId();
43
+ if (existingId) {
44
+ console.log('Using existing fingerprint ID:', existingId);
23
45
  return existingId;
24
46
  }
25
- // 检查cookie
26
- const cookieId = getCookieValue(FINGERPRINT_COOKIE_NAME);
27
- if (cookieId && isValidFingerprintId(cookieId)) {
28
- // 同步到localStorage
29
- localStorage.setItem(FINGERPRINT_STORAGE_KEY, cookieId);
30
- return cookieId;
31
- }
32
47
  try {
33
- // 使用FingerprintJS生成基于浏览器特征的指纹
48
+ // 使用 FingerprintJS 生成指纹
34
49
  const fp = yield index.load();
35
50
  const result = yield fp.get();
36
51
  const fingerprintId = `fp_${result.visitorId}`;
37
- // 存储到localStorage和cookie
52
+ // 存储到 localStorage cookie
38
53
  localStorage.setItem(FINGERPRINT_STORAGE_KEY, fingerprintId);
39
- setCookie(FINGERPRINT_COOKIE_NAME, fingerprintId, 365); // 365天过期
54
+ setCookie(FINGERPRINT_COOKIE_NAME, fingerprintId, 365);
55
+ console.log('Generated new fingerprint ID:', fingerprintId);
40
56
  return fingerprintId;
41
57
  }
42
58
  catch (error) {
43
59
  console.warn('Failed to generate fingerprint with FingerprintJS:', error);
44
- // 降级方案:生成时间戳+随机数
60
+ // 降级方案:生成基于时间戳和随机数的 ID
45
61
  const fallbackId = `fp_fallback_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
46
62
  localStorage.setItem(FINGERPRINT_STORAGE_KEY, fallbackId);
47
63
  setCookie(FINGERPRINT_COOKIE_NAME, fallbackId, 365);
64
+ console.log('Generated fallback fingerprint ID:', fallbackId);
48
65
  return fallbackId;
49
66
  }
50
67
  });
51
68
  }
52
69
  /**
53
70
  * 获取当前的fingerprint ID
54
- * 只能在客户端使用
55
71
  */
56
72
  function getFingerprintId() {
57
- if (typeof window === 'undefined') {
58
- return null;
59
- }
60
- // 首先检查localStorage
61
- const localStorageId = localStorage.getItem(FINGERPRINT_STORAGE_KEY);
62
- if (localStorageId) {
63
- return localStorageId;
64
- }
65
- // 检查cookie
66
- const cookieId = getCookieValue(FINGERPRINT_COOKIE_NAME);
67
- if (cookieId) {
68
- // 同步到localStorage
69
- localStorage.setItem(FINGERPRINT_STORAGE_KEY, cookieId);
70
- return cookieId;
71
- }
72
- return null;
73
+ return checkStoredFingerprintId();
73
74
  }
74
75
  /**
75
76
  * 设置fingerprint ID到存储
76
- * 只能在客户端使用
77
77
  */
78
78
  function setFingerprintId(fingerprintId) {
79
79
  if (typeof window === 'undefined') {
80
80
  throw new Error('setFingerprintId can only be used in browser environment');
81
81
  }
82
+ if (!isValidFingerprintId(fingerprintId)) {
83
+ throw new Error('Invalid fingerprint ID');
84
+ }
82
85
  localStorage.setItem(FINGERPRINT_STORAGE_KEY, fingerprintId);
83
86
  setCookie(FINGERPRINT_COOKIE_NAME, fingerprintId, 365);
84
87
  }
85
88
  /**
86
89
  * 清除fingerprint ID
87
- * 只能在客户端使用
88
90
  */
89
91
  function clearFingerprintId() {
90
92
  if (typeof window === 'undefined') {
@@ -96,12 +98,12 @@ function clearFingerprintId() {
96
98
  /**
97
99
  * 获取或生成fingerprint ID
98
100
  * 如果不存在则自动生成新的
99
- * 只能在客户端使用
100
101
  */
101
102
  function getOrGenerateFingerprintId() {
102
103
  return __awaiter(this, void 0, void 0, function* () {
103
- const existingId = getFingerprintId();
104
+ const existingId = checkStoredFingerprintId();
104
105
  if (existingId) {
106
+ console.log('Retrieved existing fingerprint ID:', existingId);
105
107
  return existingId;
106
108
  }
107
109
  return yield generateFingerprintId();
@@ -109,7 +111,6 @@ function getOrGenerateFingerprintId() {
109
111
  }
110
112
  /**
111
113
  * 创建包含fingerprint ID的fetch headers
112
- * 只能在客户端使用
113
114
  */
114
115
  function createFingerprintHeaders() {
115
116
  return __awaiter(this, void 0, void 0, function* () {
@@ -121,14 +122,12 @@ function createFingerprintHeaders() {
121
122
  }
122
123
  /**
123
124
  * Hook for generating fingerprint headers
124
- * 只能在客户端使用
125
125
  */
126
126
  function useFingerprintHeaders() {
127
127
  return createFingerprintHeaders;
128
128
  }
129
129
  /**
130
130
  * Create a fetch wrapper that automatically includes fingerprint headers
131
- * 只能在客户端使用
132
131
  */
133
132
  function createFingerprintFetch() {
134
133
  return (url, init) => __awaiter(this, void 0, void 0, function* () {
@@ -10,6 +10,20 @@ var fingerprintClient = require('./fingerprint-client.js');
10
10
  * Accepts configuration to customize API endpoint and behavior
11
11
  */
12
12
  function useFingerprint(config) {
13
+ // 服务端渲染检查
14
+ if (typeof window === 'undefined') {
15
+ return {
16
+ fingerprintId: null,
17
+ xUser: null,
18
+ xCredit: null,
19
+ xSubscription: null,
20
+ isLoading: false,
21
+ isInitialized: false,
22
+ error: 'Server-side rendering is not supported',
23
+ initializeAnonymousUser: () => tslib_es6.__awaiter(this, void 0, void 0, function* () { }),
24
+ refreshUserData: () => tslib_es6.__awaiter(this, void 0, void 0, function* () { }),
25
+ };
26
+ }
13
27
  const [fingerprintId, setFingerprintIdState] = React.useState(null);
14
28
  const [xUser, setXUser] = React.useState(null);
15
29
  const [xCredit, setXCredit] = React.useState(null);
@@ -21,11 +35,9 @@ function useFingerprint(config) {
21
35
  * 第一阶段:初始化fingerprint ID
22
36
  */
23
37
  const initializeFingerprintId = React.useCallback(() => tslib_es6.__awaiter(this, void 0, void 0, function* () {
24
- if (typeof window === 'undefined')
25
- return null;
26
38
  try {
27
- // 优先检查现有ID, 没有就生成新的fingerprint ID
28
39
  const currentFingerprintId = yield fingerprintClient.getOrGenerateFingerprintId();
40
+ console.log('Initialized fingerprintId:', currentFingerprintId);
29
41
  setFingerprintIdState(currentFingerprintId);
30
42
  return currentFingerprintId;
31
43
  }
@@ -40,7 +52,12 @@ function useFingerprint(config) {
40
52
  */
41
53
  const initializeAnonymousUser = React.useCallback(() => tslib_es6.__awaiter(this, void 0, void 0, function* () {
42
54
  if (!fingerprintId) {
43
- console.warn('Cannot initialize user without fingerprint ID');
55
+ console.warn('Cannot initialize user: Fingerprint ID is missing', {
56
+ fingerprintId,
57
+ isLoading,
58
+ isInitialized,
59
+ });
60
+ setError('Cannot initialize user: Missing fingerprint ID');
44
61
  return;
45
62
  }
46
63
  try {
@@ -86,8 +103,15 @@ function useFingerprint(config) {
86
103
  * 刷新用户数据
87
104
  */
88
105
  const refreshUserData = React.useCallback(() => tslib_es6.__awaiter(this, void 0, void 0, function* () {
89
- if (!fingerprintId)
106
+ if (!fingerprintId) {
107
+ console.warn('Cannot refresh user data: Fingerprint ID is missing', {
108
+ fingerprintId,
109
+ isLoading,
110
+ isInitialized,
111
+ });
112
+ setError('Cannot refresh user data: Missing fingerprint ID');
90
113
  return;
114
+ }
91
115
  try {
92
116
  setError(null);
93
117
  const fingerprintHeaders = yield fingerprintClient.createFingerprintHeaders();
@@ -119,8 +143,14 @@ function useFingerprint(config) {
119
143
  * 检查现有用户数据(仅在有fingerprint ID时执行)
120
144
  */
121
145
  const checkExistingUser = React.useCallback(() => tslib_es6.__awaiter(this, void 0, void 0, function* () {
122
- if (!fingerprintId)
146
+ if (!fingerprintId) {
147
+ console.warn('Cannot check existing user: Fingerprint ID is missing', {
148
+ fingerprintId,
149
+ isLoading,
150
+ isInitialized,
151
+ });
123
152
  return;
153
+ }
124
154
  try {
125
155
  const fingerprintHeaders = yield fingerprintClient.createFingerprintHeaders();
126
156
  const response = yield fetch(`${config.apiEndpoint}?fingerprintId=${fingerprintId}`, {
@@ -143,25 +173,27 @@ function useFingerprint(config) {
143
173
  }), [fingerprintId, config.apiEndpoint]);
144
174
  // 第一阶段:页面加载完成后生成指纹ID
145
175
  React.useEffect(() => {
146
- if (typeof window === 'undefined')
147
- return;
148
176
  const initFingerprint = () => tslib_es6.__awaiter(this, void 0, void 0, function* () {
149
- yield initializeFingerprintId();
150
- setIsLoading(false); // 第一阶段完成,结束加载状态
177
+ setIsLoading(true);
178
+ const currentFingerprintId = yield initializeFingerprintId();
179
+ if (currentFingerprintId) {
180
+ setIsLoading(false);
181
+ }
182
+ else {
183
+ setIsLoading(false);
184
+ }
151
185
  });
152
186
  initFingerprint();
153
187
  }, [initializeFingerprintId]);
154
188
  // 第二阶段:有指纹ID后检查现有用户
155
189
  React.useEffect(() => {
156
- if (!fingerprintId || isInitialized)
190
+ if (!fingerprintId || isInitialized || isLoading)
157
191
  return;
158
192
  checkExistingUser();
159
- }, [fingerprintId, isInitialized, checkExistingUser]);
193
+ }, [fingerprintId, isInitialized, isLoading, checkExistingUser]);
160
194
  // 第三阶段:如果没有现有用户且自动初始化开启,则创建新用户
161
195
  React.useEffect(() => {
162
- if (!fingerprintId || isInitialized || isLoading || error)
163
- return;
164
- if (config.autoInitialize === false)
196
+ if (!fingerprintId || isInitialized || isLoading || error || config.autoInitialize === false)
165
197
  return;
166
198
  initializeAnonymousUser();
167
199
  }, [fingerprintId, isInitialized, isLoading, error, initializeAnonymousUser, config.autoInitialize]);
@@ -8,6 +8,20 @@ import { createFingerprintHeaders, setFingerprintId, getOrGenerateFingerprintId
8
8
  * Accepts configuration to customize API endpoint and behavior
9
9
  */
10
10
  function useFingerprint(config) {
11
+ // 服务端渲染检查
12
+ if (typeof window === 'undefined') {
13
+ return {
14
+ fingerprintId: null,
15
+ xUser: null,
16
+ xCredit: null,
17
+ xSubscription: null,
18
+ isLoading: false,
19
+ isInitialized: false,
20
+ error: 'Server-side rendering is not supported',
21
+ initializeAnonymousUser: () => __awaiter(this, void 0, void 0, function* () { }),
22
+ refreshUserData: () => __awaiter(this, void 0, void 0, function* () { }),
23
+ };
24
+ }
11
25
  const [fingerprintId, setFingerprintIdState] = useState(null);
12
26
  const [xUser, setXUser] = useState(null);
13
27
  const [xCredit, setXCredit] = useState(null);
@@ -19,11 +33,9 @@ function useFingerprint(config) {
19
33
  * 第一阶段:初始化fingerprint ID
20
34
  */
21
35
  const initializeFingerprintId = useCallback(() => __awaiter(this, void 0, void 0, function* () {
22
- if (typeof window === 'undefined')
23
- return null;
24
36
  try {
25
- // 优先检查现有ID, 没有就生成新的fingerprint ID
26
37
  const currentFingerprintId = yield getOrGenerateFingerprintId();
38
+ console.log('Initialized fingerprintId:', currentFingerprintId);
27
39
  setFingerprintIdState(currentFingerprintId);
28
40
  return currentFingerprintId;
29
41
  }
@@ -38,7 +50,12 @@ function useFingerprint(config) {
38
50
  */
39
51
  const initializeAnonymousUser = useCallback(() => __awaiter(this, void 0, void 0, function* () {
40
52
  if (!fingerprintId) {
41
- console.warn('Cannot initialize user without fingerprint ID');
53
+ console.warn('Cannot initialize user: Fingerprint ID is missing', {
54
+ fingerprintId,
55
+ isLoading,
56
+ isInitialized,
57
+ });
58
+ setError('Cannot initialize user: Missing fingerprint ID');
42
59
  return;
43
60
  }
44
61
  try {
@@ -84,8 +101,15 @@ function useFingerprint(config) {
84
101
  * 刷新用户数据
85
102
  */
86
103
  const refreshUserData = useCallback(() => __awaiter(this, void 0, void 0, function* () {
87
- if (!fingerprintId)
104
+ if (!fingerprintId) {
105
+ console.warn('Cannot refresh user data: Fingerprint ID is missing', {
106
+ fingerprintId,
107
+ isLoading,
108
+ isInitialized,
109
+ });
110
+ setError('Cannot refresh user data: Missing fingerprint ID');
88
111
  return;
112
+ }
89
113
  try {
90
114
  setError(null);
91
115
  const fingerprintHeaders = yield createFingerprintHeaders();
@@ -117,8 +141,14 @@ function useFingerprint(config) {
117
141
  * 检查现有用户数据(仅在有fingerprint ID时执行)
118
142
  */
119
143
  const checkExistingUser = useCallback(() => __awaiter(this, void 0, void 0, function* () {
120
- if (!fingerprintId)
144
+ if (!fingerprintId) {
145
+ console.warn('Cannot check existing user: Fingerprint ID is missing', {
146
+ fingerprintId,
147
+ isLoading,
148
+ isInitialized,
149
+ });
121
150
  return;
151
+ }
122
152
  try {
123
153
  const fingerprintHeaders = yield createFingerprintHeaders();
124
154
  const response = yield fetch(`${config.apiEndpoint}?fingerprintId=${fingerprintId}`, {
@@ -141,25 +171,27 @@ function useFingerprint(config) {
141
171
  }), [fingerprintId, config.apiEndpoint]);
142
172
  // 第一阶段:页面加载完成后生成指纹ID
143
173
  useEffect(() => {
144
- if (typeof window === 'undefined')
145
- return;
146
174
  const initFingerprint = () => __awaiter(this, void 0, void 0, function* () {
147
- yield initializeFingerprintId();
148
- setIsLoading(false); // 第一阶段完成,结束加载状态
175
+ setIsLoading(true);
176
+ const currentFingerprintId = yield initializeFingerprintId();
177
+ if (currentFingerprintId) {
178
+ setIsLoading(false);
179
+ }
180
+ else {
181
+ setIsLoading(false);
182
+ }
149
183
  });
150
184
  initFingerprint();
151
185
  }, [initializeFingerprintId]);
152
186
  // 第二阶段:有指纹ID后检查现有用户
153
187
  useEffect(() => {
154
- if (!fingerprintId || isInitialized)
188
+ if (!fingerprintId || isInitialized || isLoading)
155
189
  return;
156
190
  checkExistingUser();
157
- }, [fingerprintId, isInitialized, checkExistingUser]);
191
+ }, [fingerprintId, isInitialized, isLoading, checkExistingUser]);
158
192
  // 第三阶段:如果没有现有用户且自动初始化开启,则创建新用户
159
193
  useEffect(() => {
160
- if (!fingerprintId || isInitialized || isLoading || error)
161
- return;
162
- if (config.autoInitialize === false)
194
+ if (!fingerprintId || isInitialized || isLoading || error || config.autoInitialize === false)
163
195
  return;
164
196
  initializeAnonymousUser();
165
197
  }, [fingerprintId, isInitialized, isLoading, error, initializeAnonymousUser, config.autoInitialize]);
@@ -1,4 +1,4 @@
1
- import { __module as coseBase$1 } from '../../../../../_virtual/cose-base.mjs';
1
+ import { __module as coseBase$1 } from '../../../../../_virtual/cose-base2.mjs';
2
2
  import { __require as requireLayoutBase } from '../../../layout-base@1.0.2/node_modules/layout-base/layout-base.mjs';
3
3
 
4
4
  var coseBase = coseBase$1.exports;
@@ -1,4 +1,4 @@
1
- import { __module as coseBase$1 } from '../../../../../_virtual/cose-base2.mjs';
1
+ import { __module as coseBase$1 } from '../../../../../_virtual/cose-base.mjs';
2
2
  import { __require as requireLayoutBase } from '../../../layout-base@2.0.1/node_modules/layout-base/layout-base.mjs';
3
3
 
4
4
  var coseBase = coseBase$1.exports;
@@ -1,4 +1,4 @@
1
- import { __module as layoutBase$1 } from '../../../../../_virtual/layout-base.mjs';
1
+ import { __module as layoutBase$1 } from '../../../../../_virtual/layout-base2.mjs';
2
2
 
3
3
  var layoutBase = layoutBase$1.exports;
4
4
 
@@ -1,4 +1,4 @@
1
- import { __module as layoutBase$1 } from '../../../../../_virtual/layout-base2.mjs';
1
+ import { __module as layoutBase$1 } from '../../../../../_virtual/layout-base.mjs';
2
2
 
3
3
  var layoutBase = layoutBase$1.exports;
4
4
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windrun-huaiin/third-ui",
3
- "version": "7.3.6",
3
+ "version": "7.3.7",
4
4
  "description": "Third-party integrated UI components for windrun-huaiin projects",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -75,8 +75,8 @@
75
75
  "mermaid": "^11.6.0",
76
76
  "react-medium-image-zoom": "^5.2.14",
77
77
  "zod": "^3.22.4",
78
- "@windrun-huaiin/lib": "^7.1.2",
79
- "@windrun-huaiin/base-ui": "^8.1.2"
78
+ "@windrun-huaiin/base-ui": "^8.1.2",
79
+ "@windrun-huaiin/lib": "^7.1.2"
80
80
  },
81
81
  "peerDependencies": {
82
82
  "react": "19.1.0",
@@ -4,102 +4,100 @@
4
4
  * 只能在浏览器环境中使用
5
5
  */
6
6
 
7
- import {
8
- FINGERPRINT_STORAGE_KEY,
9
- FINGERPRINT_COOKIE_NAME,
10
- isValidFingerprintId
11
- } from './fingerprint-shared';
12
7
  import FingerprintJS from '@fingerprintjs/fingerprintjs';
8
+ import { FINGERPRINT_STORAGE_KEY, FINGERPRINT_COOKIE_NAME, isValidFingerprintId } from './fingerprint-shared';
13
9
 
14
10
  /**
15
- * 生成基于真实浏览器特征的fingerprint ID
16
- * 使用FingerprintJS收集浏览器特征并生成唯一标识
17
- * 只能在客户端使用
11
+ * 检查浏览器存储(localStorage 和 cookie)中的指纹 ID
12
+ * 返回有效的 ID 或 null
18
13
  */
19
- export async function generateFingerprintId(): Promise<string> {
14
+ function checkStoredFingerprintId(): string | null {
20
15
  if (typeof window === 'undefined') {
21
- throw new Error('generateFingerprintId can only be used in browser environment');
16
+ return null;
22
17
  }
23
18
 
24
- // 首先检查现有ID
25
- const existingId = getFingerprintId();
26
- if (existingId && isValidFingerprintId(existingId)) {
27
- return existingId;
19
+ // 优先检查 localStorage
20
+ const localStorageId = localStorage.getItem(FINGERPRINT_STORAGE_KEY);
21
+ if (localStorageId && isValidFingerprintId(localStorageId)) {
22
+ return localStorageId;
28
23
  }
29
24
 
30
- // 检查cookie
25
+ // 检查 cookie
31
26
  const cookieId = getCookieValue(FINGERPRINT_COOKIE_NAME);
32
27
  if (cookieId && isValidFingerprintId(cookieId)) {
33
- // 同步到localStorage
28
+ // 同步到 localStorage
34
29
  localStorage.setItem(FINGERPRINT_STORAGE_KEY, cookieId);
35
30
  return cookieId;
36
31
  }
37
32
 
33
+ return null;
34
+ }
35
+
36
+ /**
37
+ * 生成基于真实浏览器特征的fingerprint ID
38
+ * 使用 FingerprintJS 收集浏览器特征并生成唯一标识
39
+ */
40
+ export async function generateFingerprintId(): Promise<string> {
41
+ if (typeof window === 'undefined') {
42
+ throw new Error('generateFingerprintId can only be used in browser environment');
43
+ }
44
+
45
+ // 检查现有 ID
46
+ const existingId = checkStoredFingerprintId();
47
+ if (existingId) {
48
+ console.log('Using existing fingerprint ID:', existingId);
49
+ return existingId;
50
+ }
51
+
38
52
  try {
39
- // 使用FingerprintJS生成基于浏览器特征的指纹
53
+ // 使用 FingerprintJS 生成指纹
40
54
  const fp = await FingerprintJS.load();
41
55
  const result = await fp.get();
42
56
  const fingerprintId = `fp_${result.visitorId}`;
43
57
 
44
- // 存储到localStorage和cookie
58
+ // 存储到 localStorage cookie
45
59
  localStorage.setItem(FINGERPRINT_STORAGE_KEY, fingerprintId);
46
- setCookie(FINGERPRINT_COOKIE_NAME, fingerprintId, 365); // 365天过期
60
+ setCookie(FINGERPRINT_COOKIE_NAME, fingerprintId, 365);
47
61
 
62
+ console.log('Generated new fingerprint ID:', fingerprintId);
48
63
  return fingerprintId;
49
64
  } catch (error) {
50
65
  console.warn('Failed to generate fingerprint with FingerprintJS:', error);
51
- // 降级方案:生成时间戳+随机数
66
+ // 降级方案:生成基于时间戳和随机数的 ID
52
67
  const fallbackId = `fp_fallback_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
53
-
54
68
  localStorage.setItem(FINGERPRINT_STORAGE_KEY, fallbackId);
55
69
  setCookie(FINGERPRINT_COOKIE_NAME, fallbackId, 365);
56
-
70
+
71
+ console.log('Generated fallback fingerprint ID:', fallbackId);
57
72
  return fallbackId;
58
73
  }
59
74
  }
60
75
 
61
76
  /**
62
77
  * 获取当前的fingerprint ID
63
- * 只能在客户端使用
64
78
  */
65
79
  export function getFingerprintId(): string | null {
66
- if (typeof window === 'undefined') {
67
- return null;
68
- }
69
-
70
- // 首先检查localStorage
71
- const localStorageId = localStorage.getItem(FINGERPRINT_STORAGE_KEY);
72
- if (localStorageId) {
73
- return localStorageId;
74
- }
75
-
76
- // 检查cookie
77
- const cookieId = getCookieValue(FINGERPRINT_COOKIE_NAME);
78
- if (cookieId) {
79
- // 同步到localStorage
80
- localStorage.setItem(FINGERPRINT_STORAGE_KEY, cookieId);
81
- return cookieId;
82
- }
83
-
84
- return null;
80
+ return checkStoredFingerprintId();
85
81
  }
86
82
 
87
83
  /**
88
84
  * 设置fingerprint ID到存储
89
- * 只能在客户端使用
90
85
  */
91
86
  export function setFingerprintId(fingerprintId: string): void {
92
87
  if (typeof window === 'undefined') {
93
88
  throw new Error('setFingerprintId can only be used in browser environment');
94
89
  }
95
90
 
91
+ if (!isValidFingerprintId(fingerprintId)) {
92
+ throw new Error('Invalid fingerprint ID');
93
+ }
94
+
96
95
  localStorage.setItem(FINGERPRINT_STORAGE_KEY, fingerprintId);
97
96
  setCookie(FINGERPRINT_COOKIE_NAME, fingerprintId, 365);
98
97
  }
99
98
 
100
99
  /**
101
100
  * 清除fingerprint ID
102
- * 只能在客户端使用
103
101
  */
104
102
  export function clearFingerprintId(): void {
105
103
  if (typeof window === 'undefined') {
@@ -113,30 +111,29 @@ export function clearFingerprintId(): void {
113
111
  /**
114
112
  * 获取或生成fingerprint ID
115
113
  * 如果不存在则自动生成新的
116
- * 只能在客户端使用
117
114
  */
118
115
  export async function getOrGenerateFingerprintId(): Promise<string> {
119
- const existingId = getFingerprintId();
116
+ const existingId = checkStoredFingerprintId();
120
117
  if (existingId) {
118
+ console.log('Retrieved existing fingerprint ID:', existingId);
121
119
  return existingId;
122
120
  }
121
+
123
122
  return await generateFingerprintId();
124
123
  }
125
124
 
126
125
  /**
127
126
  * 创建包含fingerprint ID的fetch headers
128
- * 只能在客户端使用
129
127
  */
130
128
  export async function createFingerprintHeaders(): Promise<Record<string, string>> {
131
129
  const fingerprintId = await getOrGenerateFingerprintId();
132
130
  return {
133
- FINGERPRINT_HEADER_NAME : fingerprintId,
131
+ FINGERPRINT_HEADER_NAME: fingerprintId,
134
132
  };
135
133
  }
136
134
 
137
135
  /**
138
136
  * Hook for generating fingerprint headers
139
- * 只能在客户端使用
140
137
  */
141
138
  export function useFingerprintHeaders(): () => Promise<Record<string, string>> {
142
139
  return createFingerprintHeaders;
@@ -144,7 +141,6 @@ export function useFingerprintHeaders(): () => Promise<Record<string, string>> {
144
141
 
145
142
  /**
146
143
  * Create a fetch wrapper that automatically includes fingerprint headers
147
- * 只能在客户端使用
148
144
  */
149
145
  export function createFingerprintFetch() {
150
146
  return async (url: string | URL | Request, init?: RequestInit) => {
@@ -19,6 +19,21 @@ import type {
19
19
  * Accepts configuration to customize API endpoint and behavior
20
20
  */
21
21
  export function useFingerprint(config: FingerprintConfig): UseFingerprintResult {
22
+ // 服务端渲染检查
23
+ if (typeof window === 'undefined') {
24
+ return {
25
+ fingerprintId: null,
26
+ xUser: null,
27
+ xCredit: null,
28
+ xSubscription: null,
29
+ isLoading: false,
30
+ isInitialized: false,
31
+ error: 'Server-side rendering is not supported',
32
+ initializeAnonymousUser: async () => {},
33
+ refreshUserData: async () => {},
34
+ };
35
+ }
36
+
22
37
  const [fingerprintId, setFingerprintIdState] = useState<string | null>(null);
23
38
  const [xUser, setXUser] = useState<XUser | null>(null);
24
39
  const [xCredit, setXCredit] = useState<XCredit | null>(null);
@@ -31,11 +46,9 @@ export function useFingerprint(config: FingerprintConfig): UseFingerprintResult
31
46
  * 第一阶段:初始化fingerprint ID
32
47
  */
33
48
  const initializeFingerprintId = useCallback(async () => {
34
- if (typeof window === 'undefined') return null;
35
-
36
49
  try {
37
- // 优先检查现有ID, 没有就生成新的fingerprint ID
38
50
  const currentFingerprintId = await getOrGenerateFingerprintId();
51
+ console.log('Initialized fingerprintId:', currentFingerprintId);
39
52
  setFingerprintIdState(currentFingerprintId);
40
53
  return currentFingerprintId;
41
54
  } catch (error) {
@@ -50,7 +63,12 @@ export function useFingerprint(config: FingerprintConfig): UseFingerprintResult
50
63
  */
51
64
  const initializeAnonymousUser = useCallback(async () => {
52
65
  if (!fingerprintId) {
53
- console.warn('Cannot initialize user without fingerprint ID');
66
+ console.warn('Cannot initialize user: Fingerprint ID is missing', {
67
+ fingerprintId,
68
+ isLoading,
69
+ isInitialized,
70
+ });
71
+ setError('Cannot initialize user: Missing fingerprint ID');
54
72
  return;
55
73
  }
56
74
 
@@ -103,7 +121,15 @@ export function useFingerprint(config: FingerprintConfig): UseFingerprintResult
103
121
  * 刷新用户数据
104
122
  */
105
123
  const refreshUserData = useCallback(async () => {
106
- if (!fingerprintId) return;
124
+ if (!fingerprintId) {
125
+ console.warn('Cannot refresh user data: Fingerprint ID is missing', {
126
+ fingerprintId,
127
+ isLoading,
128
+ isInitialized,
129
+ });
130
+ setError('Cannot refresh user data: Missing fingerprint ID');
131
+ return;
132
+ }
107
133
 
108
134
  try {
109
135
  setError(null);
@@ -140,7 +166,14 @@ export function useFingerprint(config: FingerprintConfig): UseFingerprintResult
140
166
  * 检查现有用户数据(仅在有fingerprint ID时执行)
141
167
  */
142
168
  const checkExistingUser = useCallback(async () => {
143
- if (!fingerprintId) return;
169
+ if (!fingerprintId) {
170
+ console.warn('Cannot check existing user: Fingerprint ID is missing', {
171
+ fingerprintId,
172
+ isLoading,
173
+ isInitialized,
174
+ });
175
+ return;
176
+ }
144
177
 
145
178
  try {
146
179
  const fingerprintHeaders = await createFingerprintHeaders();
@@ -165,11 +198,14 @@ export function useFingerprint(config: FingerprintConfig): UseFingerprintResult
165
198
 
166
199
  // 第一阶段:页面加载完成后生成指纹ID
167
200
  useEffect(() => {
168
- if (typeof window === 'undefined') return;
169
-
170
201
  const initFingerprint = async () => {
171
- await initializeFingerprintId();
172
- setIsLoading(false); // 第一阶段完成,结束加载状态
202
+ setIsLoading(true);
203
+ const currentFingerprintId = await initializeFingerprintId();
204
+ if (currentFingerprintId) {
205
+ setIsLoading(false);
206
+ } else {
207
+ setIsLoading(false);
208
+ }
173
209
  };
174
210
 
175
211
  initFingerprint();
@@ -177,15 +213,14 @@ export function useFingerprint(config: FingerprintConfig): UseFingerprintResult
177
213
 
178
214
  // 第二阶段:有指纹ID后检查现有用户
179
215
  useEffect(() => {
180
- if (!fingerprintId || isInitialized) return;
216
+ if (!fingerprintId || isInitialized || isLoading) return;
181
217
 
182
218
  checkExistingUser();
183
- }, [fingerprintId, isInitialized, checkExistingUser]);
219
+ }, [fingerprintId, isInitialized, isLoading, checkExistingUser]);
184
220
 
185
221
  // 第三阶段:如果没有现有用户且自动初始化开启,则创建新用户
186
222
  useEffect(() => {
187
- if (!fingerprintId || isInitialized || isLoading || error) return;
188
- if (config.autoInitialize === false) return;
223
+ if (!fingerprintId || isInitialized || isLoading || error || config.autoInitialize === false) return;
189
224
 
190
225
  initializeAnonymousUser();
191
226
  }, [fingerprintId, isInitialized, isLoading, error, initializeAnonymousUser, config.autoInitialize]);
@@ -201,6 +236,4 @@ export function useFingerprint(config: FingerprintConfig): UseFingerprintResult
201
236
  initializeAnonymousUser,
202
237
  refreshUserData,
203
238
  };
204
- }
205
-
206
- // createFingerprintFetch moved to fingerprint.ts
239
+ }