@windrun-huaiin/third-ui 7.4.1 → 7.5.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.
@@ -97,7 +97,7 @@ function useFingerprint(config) {
97
97
  }
98
98
  }), [fingerprintId, config.apiEndpoint]);
99
99
  /**
100
- * 刷新用户数据
100
+ * 刷新用户数据 - 使用POST请求(后端支持upsert逻辑)
101
101
  */
102
102
  const refreshUserData = React.useCallback(() => tslib_es6.__awaiter(this, void 0, void 0, function* () {
103
103
  if (!fingerprintId) {
@@ -108,17 +108,14 @@ function useFingerprint(config) {
108
108
  try {
109
109
  setError(null);
110
110
  const fingerprintHeaders = yield fingerprintClient.createFingerprintHeaders();
111
- const response = yield fetch(`${config.apiEndpoint}?fingerprintId=${fingerprintId}`, {
112
- method: 'GET',
113
- headers: fingerprintHeaders,
111
+ const response = yield fetch(config.apiEndpoint, {
112
+ method: 'POST',
113
+ headers: Object.assign({ 'Content-Type': 'application/json' }, fingerprintHeaders),
114
+ body: JSON.stringify({ fingerprintId }),
114
115
  });
115
116
  if (!response.ok) {
116
- if (response.status === 404) {
117
- // 用户不存在,需要重新初始化
118
- yield initializeAnonymousUser();
119
- return;
120
- }
121
- throw new Error('Failed to fetch user data');
117
+ const errorData = yield response.json().catch(() => ({}));
118
+ throw new Error(errorData.error || 'Failed to refresh user data');
122
119
  }
123
120
  const data = yield response.json();
124
121
  if (data.success) {
@@ -132,60 +129,21 @@ function useFingerprint(config) {
132
129
  console.error('Failed to refresh user data:', err);
133
130
  setError(err instanceof Error ? err.message : 'Unknown error');
134
131
  }
135
- }), [fingerprintId, initializeAnonymousUser, config.apiEndpoint]);
136
- /**
137
- * 检查现有用户数据(仅在有fingerprint ID时执行)
138
- */
139
- const checkExistingUser = React.useCallback(() => tslib_es6.__awaiter(this, void 0, void 0, function* () {
140
- if (!fingerprintId) {
141
- console.warn('Cannot check existing user: Fingerprint ID is missing', { fingerprintId, isLoading, isInitialized });
142
- return;
143
- }
144
- try {
145
- const fingerprintHeaders = yield fingerprintClient.createFingerprintHeaders();
146
- const response = yield fetch(`${config.apiEndpoint}?fingerprintId=${fingerprintId}`, {
147
- method: 'GET',
148
- headers: fingerprintHeaders,
149
- });
150
- if (response.ok) {
151
- const data = yield response.json();
152
- if (data.success) {
153
- const updatedXUser = data.xUser || { userId: '', fingerprintId, clerkUserId: '', email: '', status: '', createdAt: '' };
154
- setXUser(updatedXUser);
155
- setXCredit(data.xCredit || null);
156
- setXSubscription(data.xSubscription || null);
157
- setIsInitialized(true);
158
- }
159
- }
160
- }
161
- catch (err) {
162
- console.error('Failed to check existing user:', err);
163
- }
164
132
  }), [fingerprintId, config.apiEndpoint]);
165
133
  // 第一阶段:页面加载完成后生成指纹ID
166
134
  React.useEffect(() => {
167
135
  const initFingerprint = () => tslib_es6.__awaiter(this, void 0, void 0, function* () {
168
136
  setIsLoading(true);
169
- const currentFingerprintId = yield initializeFingerprintId();
170
- if (currentFingerprintId) {
171
- setIsLoading(false);
172
- }
173
- else {
174
- setIsLoading(false);
175
- }
137
+ yield initializeFingerprintId();
138
+ setIsLoading(false);
176
139
  });
177
140
  initFingerprint();
178
141
  }, [initializeFingerprintId]);
179
- // 第二阶段:有指纹ID后检查现有用户
180
- React.useEffect(() => {
181
- if (!fingerprintId || isInitialized || isLoading)
182
- return;
183
- checkExistingUser();
184
- }, [fingerprintId, isInitialized, isLoading, checkExistingUser]);
185
- // 第三阶段:如果没有现有用户且自动初始化开启,则创建新用户
142
+ // 第二阶段:有指纹ID后直接初始化用户(后端支持upsert逻辑)
186
143
  React.useEffect(() => {
187
144
  if (!fingerprintId || isInitialized || isLoading || error || config.autoInitialize === false)
188
145
  return;
146
+ // 直接使用 POST 请求,后端会处理查询-不存在则创建的逻辑
189
147
  initializeAnonymousUser();
190
148
  }, [fingerprintId, isInitialized, isLoading, error, initializeAnonymousUser, config.autoInitialize]);
191
149
  return {
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  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';
3
3
  import { useState, useCallback, useEffect } from 'react';
4
- import { createFingerprintHeaders, getOrGenerateFingerprintId } from './fingerprint-client.mjs';
4
+ import { getOrGenerateFingerprintId, createFingerprintHeaders } from './fingerprint-client.mjs';
5
5
 
6
6
  /**
7
7
  * Hook for managing fingerprint ID and anonymous user data
@@ -95,7 +95,7 @@ function useFingerprint(config) {
95
95
  }
96
96
  }), [fingerprintId, config.apiEndpoint]);
97
97
  /**
98
- * 刷新用户数据
98
+ * 刷新用户数据 - 使用POST请求(后端支持upsert逻辑)
99
99
  */
100
100
  const refreshUserData = useCallback(() => __awaiter(this, void 0, void 0, function* () {
101
101
  if (!fingerprintId) {
@@ -106,17 +106,14 @@ function useFingerprint(config) {
106
106
  try {
107
107
  setError(null);
108
108
  const fingerprintHeaders = yield createFingerprintHeaders();
109
- const response = yield fetch(`${config.apiEndpoint}?fingerprintId=${fingerprintId}`, {
110
- method: 'GET',
111
- headers: fingerprintHeaders,
109
+ const response = yield fetch(config.apiEndpoint, {
110
+ method: 'POST',
111
+ headers: Object.assign({ 'Content-Type': 'application/json' }, fingerprintHeaders),
112
+ body: JSON.stringify({ fingerprintId }),
112
113
  });
113
114
  if (!response.ok) {
114
- if (response.status === 404) {
115
- // 用户不存在,需要重新初始化
116
- yield initializeAnonymousUser();
117
- return;
118
- }
119
- throw new Error('Failed to fetch user data');
115
+ const errorData = yield response.json().catch(() => ({}));
116
+ throw new Error(errorData.error || 'Failed to refresh user data');
120
117
  }
121
118
  const data = yield response.json();
122
119
  if (data.success) {
@@ -130,60 +127,21 @@ function useFingerprint(config) {
130
127
  console.error('Failed to refresh user data:', err);
131
128
  setError(err instanceof Error ? err.message : 'Unknown error');
132
129
  }
133
- }), [fingerprintId, initializeAnonymousUser, config.apiEndpoint]);
134
- /**
135
- * 检查现有用户数据(仅在有fingerprint ID时执行)
136
- */
137
- const checkExistingUser = useCallback(() => __awaiter(this, void 0, void 0, function* () {
138
- if (!fingerprintId) {
139
- console.warn('Cannot check existing user: Fingerprint ID is missing', { fingerprintId, isLoading, isInitialized });
140
- return;
141
- }
142
- try {
143
- const fingerprintHeaders = yield createFingerprintHeaders();
144
- const response = yield fetch(`${config.apiEndpoint}?fingerprintId=${fingerprintId}`, {
145
- method: 'GET',
146
- headers: fingerprintHeaders,
147
- });
148
- if (response.ok) {
149
- const data = yield response.json();
150
- if (data.success) {
151
- const updatedXUser = data.xUser || { userId: '', fingerprintId, clerkUserId: '', email: '', status: '', createdAt: '' };
152
- setXUser(updatedXUser);
153
- setXCredit(data.xCredit || null);
154
- setXSubscription(data.xSubscription || null);
155
- setIsInitialized(true);
156
- }
157
- }
158
- }
159
- catch (err) {
160
- console.error('Failed to check existing user:', err);
161
- }
162
130
  }), [fingerprintId, config.apiEndpoint]);
163
131
  // 第一阶段:页面加载完成后生成指纹ID
164
132
  useEffect(() => {
165
133
  const initFingerprint = () => __awaiter(this, void 0, void 0, function* () {
166
134
  setIsLoading(true);
167
- const currentFingerprintId = yield initializeFingerprintId();
168
- if (currentFingerprintId) {
169
- setIsLoading(false);
170
- }
171
- else {
172
- setIsLoading(false);
173
- }
135
+ yield initializeFingerprintId();
136
+ setIsLoading(false);
174
137
  });
175
138
  initFingerprint();
176
139
  }, [initializeFingerprintId]);
177
- // 第二阶段:有指纹ID后检查现有用户
178
- useEffect(() => {
179
- if (!fingerprintId || isInitialized || isLoading)
180
- return;
181
- checkExistingUser();
182
- }, [fingerprintId, isInitialized, isLoading, checkExistingUser]);
183
- // 第三阶段:如果没有现有用户且自动初始化开启,则创建新用户
140
+ // 第二阶段:有指纹ID后直接初始化用户(后端支持upsert逻辑)
184
141
  useEffect(() => {
185
142
  if (!fingerprintId || isInitialized || isLoading || error || config.autoInitialize === false)
186
143
  return;
144
+ // 直接使用 POST 请求,后端会处理查询-不存在则创建的逻辑
187
145
  initializeAnonymousUser();
188
146
  }, [fingerprintId, isInitialized, isLoading, error, initializeAnonymousUser, config.autoInitialize]);
189
147
  return {
@@ -22,20 +22,32 @@ function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath })
22
22
  const [tooltip, setTooltip] = React.useState({ show: false, content: '', x: 0, y: 0 });
23
23
  // 确定用户状态
24
24
  const getUserState = React.useCallback(() => {
25
- var _a, _b;
26
25
  if (!fingerprintContext)
27
26
  return moneyPriceTypes.UserState.Anonymous;
28
27
  const { xUser, xSubscription } = fingerprintContext;
29
28
  if (!(xUser === null || xUser === void 0 ? void 0 : xUser.clerkUserId))
30
29
  return moneyPriceTypes.UserState.Anonymous;
31
- if (!(xSubscription === null || xSubscription === void 0 ? void 0 : xSubscription.status) || xSubscription.status === 'free')
30
+ if (!(xSubscription === null || xSubscription === void 0 ? void 0 : xSubscription.status) || xSubscription.status !== 'active')
32
31
  return moneyPriceTypes.UserState.FreeUser;
33
- if ((_a = xSubscription.priceName) === null || _a === void 0 ? void 0 : _a.includes('Pro'))
32
+ // 通过 priceId 精确匹配订阅计划
33
+ const userPriceId = xSubscription.priceId;
34
+ if (!userPriceId)
35
+ return moneyPriceTypes.UserState.FreeUser;
36
+ const providerConfig = moneyPriceConfigUtil.getActiveProviderConfig(config);
37
+ // 检查是否为 Pro 计划 (月付或年付)
38
+ const proMonthly = providerConfig.products.pro.plans.monthly.priceId;
39
+ const proYearly = providerConfig.products.pro.plans.yearly.priceId;
40
+ if (userPriceId === proMonthly || userPriceId === proYearly) {
34
41
  return moneyPriceTypes.UserState.ProUser;
35
- if ((_b = xSubscription.priceName) === null || _b === void 0 ? void 0 : _b.includes('Ultra'))
42
+ }
43
+ // 检查是否为 Ultra 计划 (月付或年付)
44
+ const ultraMonthly = providerConfig.products.ultra.plans.monthly.priceId;
45
+ const ultraYearly = providerConfig.products.ultra.plans.yearly.priceId;
46
+ if (userPriceId === ultraMonthly || userPriceId === ultraYearly) {
36
47
  return moneyPriceTypes.UserState.UltraUser;
48
+ }
37
49
  return moneyPriceTypes.UserState.FreeUser;
38
- }, [fingerprintContext]);
50
+ }, [fingerprintContext, config]);
39
51
  // 优化 userContext 使用 useMemo
40
52
  const userContext = React.useMemo(() => {
41
53
  var _a, _b, _c;
@@ -20,20 +20,32 @@ function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath })
20
20
  const [tooltip, setTooltip] = useState({ show: false, content: '', x: 0, y: 0 });
21
21
  // 确定用户状态
22
22
  const getUserState = useCallback(() => {
23
- var _a, _b;
24
23
  if (!fingerprintContext)
25
24
  return UserState.Anonymous;
26
25
  const { xUser, xSubscription } = fingerprintContext;
27
26
  if (!(xUser === null || xUser === void 0 ? void 0 : xUser.clerkUserId))
28
27
  return UserState.Anonymous;
29
- if (!(xSubscription === null || xSubscription === void 0 ? void 0 : xSubscription.status) || xSubscription.status === 'free')
28
+ if (!(xSubscription === null || xSubscription === void 0 ? void 0 : xSubscription.status) || xSubscription.status !== 'active')
30
29
  return UserState.FreeUser;
31
- if ((_a = xSubscription.priceName) === null || _a === void 0 ? void 0 : _a.includes('Pro'))
30
+ // 通过 priceId 精确匹配订阅计划
31
+ const userPriceId = xSubscription.priceId;
32
+ if (!userPriceId)
33
+ return UserState.FreeUser;
34
+ const providerConfig = getActiveProviderConfig(config);
35
+ // 检查是否为 Pro 计划 (月付或年付)
36
+ const proMonthly = providerConfig.products.pro.plans.monthly.priceId;
37
+ const proYearly = providerConfig.products.pro.plans.yearly.priceId;
38
+ if (userPriceId === proMonthly || userPriceId === proYearly) {
32
39
  return UserState.ProUser;
33
- if ((_b = xSubscription.priceName) === null || _b === void 0 ? void 0 : _b.includes('Ultra'))
40
+ }
41
+ // 检查是否为 Ultra 计划 (月付或年付)
42
+ const ultraMonthly = providerConfig.products.ultra.plans.monthly.priceId;
43
+ const ultraYearly = providerConfig.products.ultra.plans.yearly.priceId;
44
+ if (userPriceId === ultraMonthly || userPriceId === ultraYearly) {
34
45
  return UserState.UltraUser;
46
+ }
35
47
  return UserState.FreeUser;
36
- }, [fingerprintContext]);
48
+ }, [fingerprintContext, config]);
37
49
  // 优化 userContext 使用 useMemo
38
50
  const userContext = useMemo(() => {
39
51
  var _a, _b, _c;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windrun-huaiin/third-ui",
3
- "version": "7.4.1",
3
+ "version": "7.5.0",
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/base-ui": "^8.1.2",
79
- "@windrun-huaiin/lib": "^7.1.2"
78
+ "@windrun-huaiin/lib": "^7.1.2",
79
+ "@windrun-huaiin/base-ui": "^8.1.2"
80
80
  },
81
81
  "peerDependencies": {
82
82
  "react": "19.1.0",
@@ -113,7 +113,7 @@ export function useFingerprint(config: FingerprintConfig): UseFingerprintResult
113
113
  }, [fingerprintId, config.apiEndpoint]);
114
114
 
115
115
  /**
116
- * 刷新用户数据
116
+ * 刷新用户数据 - 使用POST请求(后端支持upsert逻辑)
117
117
  */
118
118
  const refreshUserData = useCallback(async () => {
119
119
  if (!fingerprintId) {
@@ -126,18 +126,18 @@ export function useFingerprint(config: FingerprintConfig): UseFingerprintResult
126
126
  setError(null);
127
127
 
128
128
  const fingerprintHeaders = await createFingerprintHeaders();
129
- const response = await fetch(`${config.apiEndpoint}?fingerprintId=${fingerprintId}`, {
130
- method: 'GET',
131
- headers: fingerprintHeaders,
129
+ const response = await fetch(config.apiEndpoint, {
130
+ method: 'POST',
131
+ headers: {
132
+ 'Content-Type': 'application/json',
133
+ ...fingerprintHeaders,
134
+ },
135
+ body: JSON.stringify({ fingerprintId }),
132
136
  });
133
137
 
134
138
  if (!response.ok) {
135
- if (response.status === 404) {
136
- // 用户不存在,需要重新初始化
137
- await initializeAnonymousUser();
138
- return;
139
- }
140
- throw new Error('Failed to fetch user data');
139
+ const errorData = await response.json().catch(() => ({}));
140
+ throw new Error(errorData.error || 'Failed to refresh user data');
141
141
  }
142
142
 
143
143
  const data = await response.json();
@@ -151,37 +151,6 @@ export function useFingerprint(config: FingerprintConfig): UseFingerprintResult
151
151
  console.error('Failed to refresh user data:', err);
152
152
  setError(err instanceof Error ? err.message : 'Unknown error');
153
153
  }
154
- }, [fingerprintId, initializeAnonymousUser, config.apiEndpoint]);
155
-
156
- /**
157
- * 检查现有用户数据(仅在有fingerprint ID时执行)
158
- */
159
- const checkExistingUser = useCallback(async () => {
160
- if (!fingerprintId) {
161
- console.warn('Cannot check existing user: Fingerprint ID is missing', { fingerprintId, isLoading, isInitialized });
162
- return;
163
- }
164
-
165
- try {
166
- const fingerprintHeaders = await createFingerprintHeaders();
167
- const response = await fetch(`${config.apiEndpoint}?fingerprintId=${fingerprintId}`, {
168
- method: 'GET',
169
- headers: fingerprintHeaders,
170
- });
171
-
172
- if (response.ok) {
173
- const data = await response.json();
174
- if (data.success) {
175
- const updatedXUser = data.xUser || { userId: '', fingerprintId, clerkUserId: '', email: '', status: '', createdAt: '' };
176
- setXUser(updatedXUser);
177
- setXCredit(data.xCredit || null);
178
- setXSubscription(data.xSubscription || null);
179
- setIsInitialized(true);
180
- }
181
- }
182
- } catch (err) {
183
- console.error('Failed to check existing user:', err);
184
- }
185
154
  }, [fingerprintId, config.apiEndpoint]);
186
155
 
187
156
  // 第一阶段:页面加载完成后生成指纹ID
@@ -189,25 +158,17 @@ export function useFingerprint(config: FingerprintConfig): UseFingerprintResult
189
158
  const initFingerprint = async () => {
190
159
  setIsLoading(true);
191
160
  const currentFingerprintId = await initializeFingerprintId();
192
- if (currentFingerprintId) {
193
- setIsLoading(false);
194
- } else {
195
- setIsLoading(false);
196
- }
161
+ setIsLoading(false);
197
162
  };
198
163
 
199
164
  initFingerprint();
200
165
  }, [initializeFingerprintId]);
201
166
 
202
- // 第二阶段:有指纹ID后检查现有用户
203
- useEffect(() => {
204
- if (!fingerprintId || isInitialized || isLoading) return;
205
- checkExistingUser();
206
- }, [fingerprintId, isInitialized, isLoading, checkExistingUser]);
207
-
208
- // 第三阶段:如果没有现有用户且自动初始化开启,则创建新用户
167
+ // 第二阶段:有指纹ID后直接初始化用户(后端支持upsert逻辑)
209
168
  useEffect(() => {
210
169
  if (!fingerprintId || isInitialized || isLoading || error || config.autoInitialize === false) return;
170
+
171
+ // 直接使用 POST 请求,后端会处理查询-不存在则创建的逻辑
211
172
  initializeAnonymousUser();
212
173
  }, [fingerprintId, isInitialized, isLoading, error, initializeAnonymousUser, config.autoInitialize]);
213
174
 
@@ -40,11 +40,30 @@ export function MoneyPriceInteractive({
40
40
  const { xUser, xSubscription } = fingerprintContext;
41
41
 
42
42
  if (!xUser?.clerkUserId) return UserState.Anonymous;
43
- if (!xSubscription?.status || xSubscription.status === 'free') return UserState.FreeUser;
44
- if (xSubscription.priceName?.includes('Pro')) return UserState.ProUser;
45
- if (xSubscription.priceName?.includes('Ultra')) return UserState.UltraUser;
43
+ if (!xSubscription?.status || xSubscription.status !== 'active') return UserState.FreeUser;
44
+
45
+ // 通过 priceId 精确匹配订阅计划
46
+ const userPriceId = xSubscription.priceId;
47
+ if (!userPriceId) return UserState.FreeUser;
48
+
49
+ const providerConfig = getActiveProviderConfig(config);
50
+
51
+ // 检查是否为 Pro 计划 (月付或年付)
52
+ const proMonthly = providerConfig.products.pro.plans.monthly.priceId;
53
+ const proYearly = providerConfig.products.pro.plans.yearly.priceId;
54
+ if (userPriceId === proMonthly || userPriceId === proYearly) {
55
+ return UserState.ProUser;
56
+ }
57
+
58
+ // 检查是否为 Ultra 计划 (月付或年付)
59
+ const ultraMonthly = providerConfig.products.ultra.plans.monthly.priceId;
60
+ const ultraYearly = providerConfig.products.ultra.plans.yearly.priceId;
61
+ if (userPriceId === ultraMonthly || userPriceId === ultraYearly) {
62
+ return UserState.UltraUser;
63
+ }
64
+
46
65
  return UserState.FreeUser;
47
- }, [fingerprintContext]);
66
+ }, [fingerprintContext, config]);
48
67
 
49
68
  // 优化 userContext 使用 useMemo
50
69
  const userContext = useMemo<UserContext>(() => {