@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.
- package/dist/clerk/fingerprint/use-fingerprint.js +11 -53
- package/dist/clerk/fingerprint/use-fingerprint.mjs +12 -54
- package/dist/main/money-price/money-price-interactive.js +17 -5
- package/dist/main/money-price/money-price-interactive.mjs +17 -5
- package/package.json +3 -3
- package/src/clerk/fingerprint/use-fingerprint.ts +14 -53
- package/src/main/money-price/money-price-interactive.tsx +23 -4
|
@@ -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(
|
|
112
|
-
method: '
|
|
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
|
-
|
|
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
|
-
|
|
170
|
-
|
|
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 {
|
|
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(
|
|
110
|
-
method: '
|
|
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
|
-
|
|
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
|
-
|
|
168
|
-
|
|
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
|
|
30
|
+
if (!(xSubscription === null || xSubscription === void 0 ? void 0 : xSubscription.status) || xSubscription.status !== 'active')
|
|
32
31
|
return moneyPriceTypes.UserState.FreeUser;
|
|
33
|
-
|
|
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
|
-
|
|
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
|
|
28
|
+
if (!(xSubscription === null || xSubscription === void 0 ? void 0 : xSubscription.status) || xSubscription.status !== 'active')
|
|
30
29
|
return UserState.FreeUser;
|
|
31
|
-
|
|
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
|
-
|
|
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.
|
|
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/
|
|
79
|
-
"@windrun-huaiin/
|
|
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(
|
|
130
|
-
method: '
|
|
131
|
-
headers:
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
44
|
-
|
|
45
|
-
|
|
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>(() => {
|