@windrun-huaiin/third-ui 7.4.0 → 7.4.2

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 {
@@ -15,7 +15,7 @@ var moneyPriceTypes = require('./money-price-types.js');
15
15
 
16
16
  function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath }) {
17
17
  const fingerprintContext = fingerprintProvider.useFingerprintContextSafe();
18
- const { redirectToSignIn } = nextjs.useClerk();
18
+ const { redirectToSignIn, user } = nextjs.useClerk();
19
19
  const router = navigation.useRouter();
20
20
  const [billingType, setBillingType] = React.useState(data.billingSwitch.defaultKey);
21
21
  const [isProcessing, setIsProcessing] = React.useState(false);
@@ -38,14 +38,17 @@ function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath })
38
38
  }, [fingerprintContext]);
39
39
  // 优化 userContext 使用 useMemo
40
40
  const userContext = React.useMemo(() => {
41
- var _a, _b, _c, _d;
42
- return ({
43
- isAuthenticated: !!((_a = fingerprintContext === null || fingerprintContext === void 0 ? void 0 : fingerprintContext.xUser) === null || _a === void 0 ? void 0 : _a.clerkUserId),
44
- subscriptionStatus: getUserState(),
45
- subscriptionType: ((_c = (_b = fingerprintContext === null || fingerprintContext === void 0 ? void 0 : fingerprintContext.xSubscription) === null || _b === void 0 ? void 0 : _b.priceId) === null || _c === void 0 ? void 0 : _c.includes('yearly')) ? 'yearly' : 'monthly',
46
- subscriptionEndDate: (_d = fingerprintContext === null || fingerprintContext === void 0 ? void 0 : fingerprintContext.xSubscription) === null || _d === void 0 ? void 0 : _d.subPeriodEnd
47
- });
48
- }, [fingerprintContext, getUserState]);
41
+ var _a, _b, _c;
42
+ // 使用 Clerk 的 user 对象判断登录状态
43
+ const isAuth = !!(user === null || user === void 0 ? void 0 : user.id);
44
+ const userState = getUserState();
45
+ return {
46
+ isAuthenticated: isAuth,
47
+ subscriptionStatus: isAuth ? userState : moneyPriceTypes.UserState.Anonymous,
48
+ subscriptionType: ((_b = (_a = fingerprintContext === null || fingerprintContext === void 0 ? void 0 : fingerprintContext.xSubscription) === null || _a === void 0 ? void 0 : _a.priceId) === null || _b === void 0 ? void 0 : _b.includes('yearly')) ? 'yearly' : 'monthly',
49
+ subscriptionEndDate: (_c = fingerprintContext === null || fingerprintContext === void 0 ? void 0 : fingerprintContext.xSubscription) === null || _c === void 0 ? void 0 : _c.subPeriodEnd
50
+ };
51
+ }, [user, fingerprintContext, getUserState]);
49
52
  // 处理登录
50
53
  const handleLogin = React.useCallback(() => {
51
54
  if (signInPath) {
@@ -77,6 +80,25 @@ function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath })
77
80
  provider: config.activeProvider
78
81
  })
79
82
  });
83
+ // 检查是否是重定向或非JSON响应
84
+ if (response.redirected || response.status === 302 || response.status === 301) {
85
+ // 如果是重定向,直接跳转到重定向URL(通常是登录页面)
86
+ window.location.href = response.url;
87
+ return;
88
+ }
89
+ // 检查Content-Type是否为JSON
90
+ const contentType = response.headers.get('content-type');
91
+ if (!contentType || !contentType.includes('application/json')) {
92
+ // 如果不是JSON响应,可能是HTML登录页面,提示用户重新登录
93
+ console.error('Received non-JSON response, user may need to login');
94
+ if (signInPath) {
95
+ window.location.href = signInPath;
96
+ }
97
+ else {
98
+ redirectToSignIn();
99
+ }
100
+ return;
101
+ }
80
102
  const result = yield response.json();
81
103
  if (result.success && ((_a = result.data) === null || _a === void 0 ? void 0 : _a.sessionUrl)) {
82
104
  window.location.href = result.data.sessionUrl;
@@ -13,7 +13,7 @@ import { UserState } from './money-price-types.mjs';
13
13
 
14
14
  function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath }) {
15
15
  const fingerprintContext = useFingerprintContextSafe();
16
- const { redirectToSignIn } = useClerk();
16
+ const { redirectToSignIn, user } = useClerk();
17
17
  const router = useRouter();
18
18
  const [billingType, setBillingType] = useState(data.billingSwitch.defaultKey);
19
19
  const [isProcessing, setIsProcessing] = useState(false);
@@ -36,14 +36,17 @@ function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath })
36
36
  }, [fingerprintContext]);
37
37
  // 优化 userContext 使用 useMemo
38
38
  const userContext = useMemo(() => {
39
- var _a, _b, _c, _d;
40
- return ({
41
- isAuthenticated: !!((_a = fingerprintContext === null || fingerprintContext === void 0 ? void 0 : fingerprintContext.xUser) === null || _a === void 0 ? void 0 : _a.clerkUserId),
42
- subscriptionStatus: getUserState(),
43
- subscriptionType: ((_c = (_b = fingerprintContext === null || fingerprintContext === void 0 ? void 0 : fingerprintContext.xSubscription) === null || _b === void 0 ? void 0 : _b.priceId) === null || _c === void 0 ? void 0 : _c.includes('yearly')) ? 'yearly' : 'monthly',
44
- subscriptionEndDate: (_d = fingerprintContext === null || fingerprintContext === void 0 ? void 0 : fingerprintContext.xSubscription) === null || _d === void 0 ? void 0 : _d.subPeriodEnd
45
- });
46
- }, [fingerprintContext, getUserState]);
39
+ var _a, _b, _c;
40
+ // 使用 Clerk 的 user 对象判断登录状态
41
+ const isAuth = !!(user === null || user === void 0 ? void 0 : user.id);
42
+ const userState = getUserState();
43
+ return {
44
+ isAuthenticated: isAuth,
45
+ subscriptionStatus: isAuth ? userState : UserState.Anonymous,
46
+ subscriptionType: ((_b = (_a = fingerprintContext === null || fingerprintContext === void 0 ? void 0 : fingerprintContext.xSubscription) === null || _a === void 0 ? void 0 : _a.priceId) === null || _b === void 0 ? void 0 : _b.includes('yearly')) ? 'yearly' : 'monthly',
47
+ subscriptionEndDate: (_c = fingerprintContext === null || fingerprintContext === void 0 ? void 0 : fingerprintContext.xSubscription) === null || _c === void 0 ? void 0 : _c.subPeriodEnd
48
+ };
49
+ }, [user, fingerprintContext, getUserState]);
47
50
  // 处理登录
48
51
  const handleLogin = useCallback(() => {
49
52
  if (signInPath) {
@@ -75,6 +78,25 @@ function MoneyPriceInteractive({ data, config, upgradeApiEndpoint, signInPath })
75
78
  provider: config.activeProvider
76
79
  })
77
80
  });
81
+ // 检查是否是重定向或非JSON响应
82
+ if (response.redirected || response.status === 302 || response.status === 301) {
83
+ // 如果是重定向,直接跳转到重定向URL(通常是登录页面)
84
+ window.location.href = response.url;
85
+ return;
86
+ }
87
+ // 检查Content-Type是否为JSON
88
+ const contentType = response.headers.get('content-type');
89
+ if (!contentType || !contentType.includes('application/json')) {
90
+ // 如果不是JSON响应,可能是HTML登录页面,提示用户重新登录
91
+ console.error('Received non-JSON response, user may need to login');
92
+ if (signInPath) {
93
+ window.location.href = signInPath;
94
+ }
95
+ else {
96
+ redirectToSignIn();
97
+ }
98
+ return;
99
+ }
78
100
  const result = yield response.json();
79
101
  if (result.success && ((_a = result.data) === null || _a === void 0 ? void 0 : _a.sessionUrl)) {
80
102
  window.location.href = result.data.sessionUrl;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var coseBase$1 = require('../../../../../_virtual/cose-base2.js');
3
+ var coseBase$1 = require('../../../../../_virtual/cose-base.js');
4
4
  var layoutBase = require('../../../layout-base@1.0.2/node_modules/layout-base/layout-base.js');
5
5
 
6
6
  var coseBase = coseBase$1.__module.exports;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var coseBase$1 = require('../../../../../_virtual/cose-base.js');
3
+ var coseBase$1 = require('../../../../../_virtual/cose-base2.js');
4
4
  var layoutBase = require('../../../layout-base@2.0.1/node_modules/layout-base/layout-base.js');
5
5
 
6
6
  var coseBase = coseBase$1.__module.exports;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var layoutBase$1 = require('../../../../../_virtual/layout-base2.js');
3
+ var layoutBase$1 = require('../../../../../_virtual/layout-base.js');
4
4
 
5
5
  var layoutBase = layoutBase$1.__module.exports;
6
6
 
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var layoutBase$1 = require('../../../../../_virtual/layout-base.js');
3
+ var layoutBase$1 = require('../../../../../_virtual/layout-base2.js');
4
4
 
5
5
  var layoutBase = layoutBase$1.__module.exports;
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windrun-huaiin/third-ui",
3
- "version": "7.4.0",
3
+ "version": "7.4.2",
4
4
  "description": "Third-party integrated UI components for windrun-huaiin projects",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -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
 
@@ -21,7 +21,7 @@ export function MoneyPriceInteractive({
21
21
  signInPath
22
22
  }: MoneyPriceInteractiveProps) {
23
23
  const fingerprintContext = useFingerprintContextSafe();
24
- const { redirectToSignIn } = useClerk();
24
+ const { redirectToSignIn, user } = useClerk();
25
25
  const router = useRouter();
26
26
  const [billingType, setBillingType] = useState<'monthly' | 'yearly'>(
27
27
  data.billingSwitch.defaultKey as 'monthly' | 'yearly'
@@ -47,12 +47,18 @@ export function MoneyPriceInteractive({
47
47
  }, [fingerprintContext]);
48
48
 
49
49
  // 优化 userContext 使用 useMemo
50
- const userContext = useMemo<UserContext>(() => ({
51
- isAuthenticated: !!fingerprintContext?.xUser?.clerkUserId,
52
- subscriptionStatus: getUserState(),
53
- subscriptionType: fingerprintContext?.xSubscription?.priceId?.includes('yearly') ? 'yearly' : 'monthly',
54
- subscriptionEndDate: fingerprintContext?.xSubscription?.subPeriodEnd
55
- }), [fingerprintContext, getUserState]);
50
+ const userContext = useMemo<UserContext>(() => {
51
+ // 使用 Clerk 的 user 对象判断登录状态
52
+ const isAuth = !!user?.id;
53
+ const userState = getUserState();
54
+
55
+ return {
56
+ isAuthenticated: isAuth,
57
+ subscriptionStatus: isAuth ? userState : UserState.Anonymous,
58
+ subscriptionType: fingerprintContext?.xSubscription?.priceId?.includes('yearly') ? 'yearly' : 'monthly',
59
+ subscriptionEndDate: fingerprintContext?.xSubscription?.subPeriodEnd
60
+ };
61
+ }, [user, fingerprintContext, getUserState]);
56
62
 
57
63
  // 处理登录
58
64
  const handleLogin = useCallback(() => {
@@ -92,6 +98,26 @@ export function MoneyPriceInteractive({
92
98
  })
93
99
  });
94
100
 
101
+ // 检查是否是重定向或非JSON响应
102
+ if (response.redirected || response.status === 302 || response.status === 301) {
103
+ // 如果是重定向,直接跳转到重定向URL(通常是登录页面)
104
+ window.location.href = response.url;
105
+ return;
106
+ }
107
+
108
+ // 检查Content-Type是否为JSON
109
+ const contentType = response.headers.get('content-type');
110
+ if (!contentType || !contentType.includes('application/json')) {
111
+ // 如果不是JSON响应,可能是HTML登录页面,提示用户重新登录
112
+ console.error('Received non-JSON response, user may need to login');
113
+ if (signInPath) {
114
+ window.location.href = signInPath;
115
+ } else {
116
+ redirectToSignIn();
117
+ }
118
+ return;
119
+ }
120
+
95
121
  const result = await response.json();
96
122
 
97
123
  if (result.success && result.data?.sessionUrl) {