@microcosmmoney/portal-react 3.13.0 → 3.13.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.
Files changed (73) hide show
  1. package/dist/index.d.ts +13 -0
  2. package/dist/index.js +27 -1
  3. package/dist/main-portal/components/dashboard/EcosystemStatsCard.d.ts +1 -0
  4. package/dist/main-portal/components/dashboard/EcosystemStatsCard.js +37 -0
  5. package/dist/main-portal/components/dashboard/LockPeriodsCard.d.ts +1 -0
  6. package/dist/main-portal/components/dashboard/LockPeriodsCard.js +16 -0
  7. package/dist/main-portal/components/dashboard/MCCPriceChart.d.ts +1 -0
  8. package/dist/main-portal/components/dashboard/MCCPriceChart.js +74 -0
  9. package/dist/main-portal/components/dashboard/MCCTokenStatsCard.d.ts +1 -0
  10. package/dist/main-portal/components/dashboard/MCCTokenStatsCard.js +39 -0
  11. package/dist/main-portal/components/dashboard/MCDStatsCard.d.ts +1 -0
  12. package/dist/main-portal/components/dashboard/MCDStatsCard.js +39 -0
  13. package/dist/main-portal/components/dashboard/MarketOverviewBar.d.ts +1 -0
  14. package/dist/main-portal/components/dashboard/MarketOverviewBar.js +141 -0
  15. package/dist/main-portal/components/dashboard/MiningWeightCard.d.ts +1 -0
  16. package/dist/main-portal/components/dashboard/MiningWeightCard.js +56 -0
  17. package/dist/main-portal/components/dashboard/MintingStatsCard.d.ts +1 -0
  18. package/dist/main-portal/components/dashboard/MintingStatsCard.js +29 -0
  19. package/dist/main-portal/components/dashboard/MyAssetsSummary.d.ts +1 -0
  20. package/dist/main-portal/components/dashboard/MyAssetsSummary.js +69 -0
  21. package/dist/main-portal/components/dashboard/MyMiningCard.d.ts +1 -0
  22. package/dist/main-portal/components/dashboard/MyMiningCard.js +46 -0
  23. package/dist/main-portal/components/dashboard/QuickActions.d.ts +1 -0
  24. package/dist/main-portal/components/dashboard/QuickActions.js +49 -0
  25. package/dist/main-portal/components/dashboard/UserDashboardPage.d.ts +1 -0
  26. package/dist/main-portal/components/dashboard/UserDashboardPage.js +36 -0
  27. package/dist/main-portal/components/mainnet/wave-text.d.ts +8 -0
  28. package/dist/main-portal/components/mainnet/wave-text.js +50 -0
  29. package/dist/main-portal/components/mining/MiningModal.js +1 -1
  30. package/dist/main-portal/components/providers/SolanaWalletProvider.js +1 -1
  31. package/dist/main-portal/components/resources/public-mining-modal.js +1 -1
  32. package/dist/main-portal/hooks/useAuth.js +3 -2
  33. package/dist/main-portal/lib/api/index.d.ts +2 -9
  34. package/dist/main-portal/lib/api/index.js +17 -210
  35. package/package.json +1 -1
  36. package/dist/main-portal/lib/analytics/hooks.d.ts +0 -139
  37. package/dist/main-portal/lib/analytics/hooks.js +0 -277
  38. package/dist/main-portal/lib/analytics/index.d.ts +0 -2
  39. package/dist/main-portal/lib/analytics/index.js +0 -19
  40. package/dist/main-portal/lib/analytics/types.d.ts +0 -611
  41. package/dist/main-portal/lib/analytics/types.js +0 -2
  42. package/dist/main-portal/lib/api/account.d.ts +0 -39
  43. package/dist/main-portal/lib/api/account.js +0 -86
  44. package/dist/main-portal/lib/api/admin.d.ts +0 -78
  45. package/dist/main-portal/lib/api/admin.js +0 -195
  46. package/dist/main-portal/lib/api/analytics.d.ts +0 -217
  47. package/dist/main-portal/lib/api/analytics.js +0 -55
  48. package/dist/main-portal/lib/api/mcc-holders.d.ts +0 -130
  49. package/dist/main-portal/lib/api/mcc-holders.js +0 -47
  50. package/dist/main-portal/lib/api/org-service-proxy.d.ts +0 -7
  51. package/dist/main-portal/lib/api/org-service-proxy.js +0 -55
  52. package/dist/main-portal/lib/api/strategies.d.ts +0 -101
  53. package/dist/main-portal/lib/api/strategies.js +0 -87
  54. package/dist/main-portal/lib/exchanges/config.d.ts +0 -34
  55. package/dist/main-portal/lib/exchanges/config.js +0 -185
  56. package/dist/main-portal/lib/exchanges/hooks/index.d.ts +0 -5
  57. package/dist/main-portal/lib/exchanges/hooks/index.js +0 -10
  58. package/dist/main-portal/lib/exchanges/hooks/useBinanceData.d.ts +0 -15
  59. package/dist/main-portal/lib/exchanges/hooks/useBinanceData.js +0 -216
  60. package/dist/main-portal/lib/exchanges/hooks/useBinanceDialogs.d.ts +0 -32
  61. package/dist/main-portal/lib/exchanges/hooks/useBinanceDialogs.js +0 -395
  62. package/dist/main-portal/lib/exchanges/hooks/useUserExchanges.d.ts +0 -15
  63. package/dist/main-portal/lib/exchanges/hooks/useUserExchanges.js +0 -51
  64. package/dist/main-portal/lib/exchanges/index.d.ts +0 -4
  65. package/dist/main-portal/lib/exchanges/index.js +0 -21
  66. package/dist/main-portal/lib/exchanges/types.d.ts +0 -102
  67. package/dist/main-portal/lib/exchanges/types.js +0 -2
  68. package/dist/main-portal/lib/exchanges/utils.d.ts +0 -1
  69. package/dist/main-portal/lib/exchanges/utils.js +0 -10
  70. package/dist/main-portal/lib/gcp-secrets.d.ts +0 -7
  71. package/dist/main-portal/lib/gcp-secrets.js +0 -45
  72. package/dist/main-portal/lib/mockWallet.d.ts +0 -130
  73. package/dist/main-portal/lib/mockWallet.js +0 -284
@@ -1,15 +0,0 @@
1
- import type { AccountBalance, Position, OpenOrder, Trade, GroupedPosition, GroupedOrders, GroupedTrades } from "../types";
2
- export interface UseBinanceDataReturn {
3
- userId: string | null;
4
- accountBalance: AccountBalance | null;
5
- positions: Position[];
6
- openOrders: OpenOrder[];
7
- trades: Trade[];
8
- groupedPositions: GroupedPosition[];
9
- groupedOrders: GroupedOrders[];
10
- groupedTrades: GroupedTrades[];
11
- loading: boolean;
12
- error: string | null;
13
- fetchData: () => Promise<void>;
14
- }
15
- export declare function useBinanceData(): UseBinanceDataReturn;
@@ -1,216 +0,0 @@
1
- "use strict";
2
- // AI-generated · AI-managed · AI-maintained
3
- "use client";
4
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
- if (k2 === undefined) k2 = k;
6
- var desc = Object.getOwnPropertyDescriptor(m, k);
7
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8
- desc = { enumerable: true, get: function() { return m[k]; } };
9
- }
10
- Object.defineProperty(o, k2, desc);
11
- }) : (function(o, m, k, k2) {
12
- if (k2 === undefined) k2 = k;
13
- o[k2] = m[k];
14
- }));
15
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
16
- Object.defineProperty(o, "default", { enumerable: true, value: v });
17
- }) : function(o, v) {
18
- o["default"] = v;
19
- });
20
- var __importStar = (this && this.__importStar) || (function () {
21
- var ownKeys = function(o) {
22
- ownKeys = Object.getOwnPropertyNames || function (o) {
23
- var ar = [];
24
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
25
- return ar;
26
- };
27
- return ownKeys(o);
28
- };
29
- return function (mod) {
30
- if (mod && mod.__esModule) return mod;
31
- var result = {};
32
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
33
- __setModuleDefault(result, mod);
34
- return result;
35
- };
36
- })();
37
- Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.useBinanceData = useBinanceData;
39
- const react_1 = require("react");
40
- const auth_service_1 = require("../../auth-service");
41
- function useBinanceData() {
42
- const [userId, setUserId] = (0, react_1.useState)(null);
43
- const [loading, setLoading] = (0, react_1.useState)(true);
44
- const [error, setError] = (0, react_1.useState)(null);
45
- const [accountBalance, setAccountBalance] = (0, react_1.useState)(null);
46
- const [positions, setPositions] = (0, react_1.useState)([]);
47
- const [openOrders, setOpenOrders] = (0, react_1.useState)([]);
48
- const [trades, setTrades] = (0, react_1.useState)([]);
49
- (0, react_1.useEffect)(() => {
50
- const unsubscribe = (0, auth_service_1.onAuthChange)((user) => {
51
- if (user?.uid) {
52
- setUserId(user.uid);
53
- }
54
- else {
55
- setUserId(null);
56
- }
57
- });
58
- return () => unsubscribe();
59
- }, []);
60
- const fetchData = (0, react_1.useCallback)(async () => {
61
- if (!userId)
62
- return;
63
- setLoading(true);
64
- setError(null);
65
- try {
66
- const { getCurrentUserToken } = await Promise.resolve().then(() => __importStar(require('../../auth-service')));
67
- const token = await getCurrentUserToken();
68
- if (!token) {
69
- setError("用户未登录");
70
- setLoading(false);
71
- return;
72
- }
73
- const balanceRes = (0, auth_service_1.guardAuthResponse)(await fetch(`/api/exchanges/binance/account`, {
74
- headers: {
75
- 'Authorization': `Bearer ${token}`
76
- }
77
- }));
78
- if (balanceRes.ok) {
79
- const data = await balanceRes.json();
80
- setAccountBalance(data);
81
- }
82
- else {
83
- const errorData = await balanceRes.json();
84
- throw new Error(errorData.error || '获取账户信息失败');
85
- }
86
- const positionsRes = (0, auth_service_1.guardAuthResponse)(await fetch(`/api/exchanges/binance/positions`, {
87
- headers: {
88
- 'Authorization': `Bearer ${token}`
89
- }
90
- }));
91
- if (positionsRes.ok) {
92
- const data = await positionsRes.json();
93
- setPositions(data.positions || []);
94
- }
95
- const ordersRes = (0, auth_service_1.guardAuthResponse)(await fetch(`/api/exchanges/binance/orders`, {
96
- headers: {
97
- 'Authorization': `Bearer ${token}`
98
- }
99
- }));
100
- if (ordersRes.ok) {
101
- const data = await ordersRes.json();
102
- setOpenOrders(data.orders || []);
103
- }
104
- const tradesRes = (0, auth_service_1.guardAuthResponse)(await fetch(`/api/exchanges/binance/history`, {
105
- headers: {
106
- 'Authorization': `Bearer ${token}`
107
- }
108
- }));
109
- if (tradesRes.ok) {
110
- const data = await tradesRes.json();
111
- setTrades(data.trades || []);
112
- }
113
- }
114
- catch (err) {
115
- setError(err instanceof Error ? err.message : "获取数据失败");
116
- }
117
- finally {
118
- setLoading(false);
119
- }
120
- }, [userId]);
121
- (0, react_1.useEffect)(() => {
122
- if (userId) {
123
- fetchData();
124
- }
125
- }, [userId, fetchData]);
126
- const getGroupedPositions = (0, react_1.useCallback)(() => {
127
- const groups = new Map();
128
- positions.forEach(pos => {
129
- if (!groups.has(pos.symbol)) {
130
- groups.set(pos.symbol, {
131
- symbol: pos.symbol,
132
- totalUnrealizedProfit: 0,
133
- orders: []
134
- });
135
- }
136
- const group = groups.get(pos.symbol);
137
- if (pos.side === "LONG") {
138
- group.longPosition = pos;
139
- }
140
- else {
141
- group.shortPosition = pos;
142
- }
143
- group.totalUnrealizedProfit += pos.unrealizedProfit;
144
- });
145
- openOrders.forEach(order => {
146
- if (groups.has(order.symbol)) {
147
- groups.get(order.symbol).orders.push(order);
148
- }
149
- });
150
- groups.forEach(group => {
151
- group.orders.sort((a, b) => {
152
- const timeA = typeof a.time === 'number' ? a.time : new Date(a.time).getTime();
153
- const timeB = typeof b.time === 'number' ? b.time : new Date(b.time).getTime();
154
- return timeB - timeA;
155
- });
156
- });
157
- return Array.from(groups.values()).sort((a, b) => b.totalUnrealizedProfit - a.totalUnrealizedProfit);
158
- }, [positions, openOrders]);
159
- const getGroupedOrders = (0, react_1.useCallback)(() => {
160
- const groups = new Map();
161
- openOrders.forEach(order => {
162
- if (!groups.has(order.symbol)) {
163
- groups.set(order.symbol, {
164
- symbol: order.symbol,
165
- orders: [],
166
- totalQuantity: 0
167
- });
168
- }
169
- const group = groups.get(order.symbol);
170
- group.orders.push(order);
171
- group.totalQuantity += order.quantity - order.filled;
172
- });
173
- groups.forEach(group => {
174
- group.orders.sort((a, b) => {
175
- const timeA = typeof a.time === 'number' ? a.time : new Date(a.time).getTime();
176
- const timeB = typeof b.time === 'number' ? b.time : new Date(b.time).getTime();
177
- return timeB - timeA;
178
- });
179
- });
180
- return Array.from(groups.values()).sort((a, b) => b.orders.length - a.orders.length);
181
- }, [openOrders]);
182
- const getGroupedTrades = (0, react_1.useCallback)(() => {
183
- const groups = new Map();
184
- trades.forEach(trade => {
185
- if (!groups.has(trade.symbol)) {
186
- groups.set(trade.symbol, {
187
- symbol: trade.symbol,
188
- trades: [],
189
- totalRealizedPnl: 0,
190
- totalVolume: 0
191
- });
192
- }
193
- const group = groups.get(trade.symbol);
194
- group.trades.push(trade);
195
- group.totalRealizedPnl += trade.realizedPnl;
196
- group.totalVolume += trade.quantity;
197
- });
198
- groups.forEach(group => {
199
- group.trades.sort((a, b) => b.time - a.time);
200
- });
201
- return Array.from(groups.values()).sort((a, b) => b.totalRealizedPnl - a.totalRealizedPnl);
202
- }, [trades]);
203
- return {
204
- userId,
205
- accountBalance,
206
- positions,
207
- openOrders,
208
- trades,
209
- groupedPositions: getGroupedPositions(),
210
- groupedOrders: getGroupedOrders(),
211
- groupedTrades: getGroupedTrades(),
212
- loading,
213
- error,
214
- fetchData
215
- };
216
- }
@@ -1,32 +0,0 @@
1
- import type { OpenOrder, Position, CleanupProgress, CleanupPreview } from "../types";
2
- export type DialogType = 'cancel' | 'modify' | 'add' | 'close' | 'cleanup' | null;
3
- export interface UseBinanceDialogsReturn {
4
- dialogOpen: boolean;
5
- dialogType: DialogType;
6
- selectedOrder: OpenOrder | null;
7
- selectedPosition: Position | null;
8
- dialogLoading: boolean;
9
- inputPrice: string;
10
- inputQuantity: string;
11
- orderType: 'MARKET' | 'LIMIT';
12
- cleanupSymbol: string;
13
- cleanupPreview: CleanupPreview | null;
14
- cleanupLoading: boolean;
15
- cleanupJobId: string | null;
16
- cleanupProgress: CleanupProgress | null;
17
- setInputPrice: (value: string) => void;
18
- setInputQuantity: (value: string) => void;
19
- setOrderType: (value: 'MARKET' | 'LIMIT') => void;
20
- handleOpenCancelDialog: (order: OpenOrder) => void;
21
- handleOpenModifyDialog: (order: OpenOrder) => void;
22
- handleOpenAddDialog: (position: Position) => void;
23
- handleOpenCloseDialog: (position: Position) => void;
24
- handleOpenCleanupDialog: (symbol: string) => Promise<void>;
25
- handleCloseDialog: () => void;
26
- handleCancelOrder: () => Promise<void>;
27
- handleModifyOrder: () => Promise<void>;
28
- handleAddPosition: () => Promise<void>;
29
- handleClosePosition: () => Promise<void>;
30
- handleExecuteCleanup: () => Promise<void>;
31
- }
32
- export declare function useBinanceDialogs(fetchData: () => Promise<void>): UseBinanceDialogsReturn;
@@ -1,395 +0,0 @@
1
- "use strict";
2
- // AI-generated · AI-managed · AI-maintained
3
- "use client";
4
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
5
- if (k2 === undefined) k2 = k;
6
- var desc = Object.getOwnPropertyDescriptor(m, k);
7
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
8
- desc = { enumerable: true, get: function() { return m[k]; } };
9
- }
10
- Object.defineProperty(o, k2, desc);
11
- }) : (function(o, m, k, k2) {
12
- if (k2 === undefined) k2 = k;
13
- o[k2] = m[k];
14
- }));
15
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
16
- Object.defineProperty(o, "default", { enumerable: true, value: v });
17
- }) : function(o, v) {
18
- o["default"] = v;
19
- });
20
- var __importStar = (this && this.__importStar) || (function () {
21
- var ownKeys = function(o) {
22
- ownKeys = Object.getOwnPropertyNames || function (o) {
23
- var ar = [];
24
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
25
- return ar;
26
- };
27
- return ownKeys(o);
28
- };
29
- return function (mod) {
30
- if (mod && mod.__esModule) return mod;
31
- var result = {};
32
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
33
- __setModuleDefault(result, mod);
34
- return result;
35
- };
36
- })();
37
- Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.useBinanceDialogs = useBinanceDialogs;
39
- const react_1 = require("react");
40
- const sonner_1 = require("sonner");
41
- const api_service_1 = require("../../api-service");
42
- const auth_service_1 = require("../../auth-service");
43
- const order_id_generator_1 = require("../../order-id-generator");
44
- function detectPlatform() {
45
- if (typeof window === 'undefined')
46
- return 'web';
47
- const ua = navigator.userAgent.toLowerCase();
48
- if (ua.includes('android'))
49
- return 'android';
50
- if (ua.includes('iphone') || ua.includes('ipad'))
51
- return 'ios';
52
- return 'web';
53
- }
54
- function useBinanceDialogs(fetchData) {
55
- const [dialogOpen, setDialogOpen] = (0, react_1.useState)(false);
56
- const [dialogType, setDialogType] = (0, react_1.useState)(null);
57
- const [selectedOrder, setSelectedOrder] = (0, react_1.useState)(null);
58
- const [selectedPosition, setSelectedPosition] = (0, react_1.useState)(null);
59
- const [dialogLoading, setDialogLoading] = (0, react_1.useState)(false);
60
- const [cleanupSymbol, setCleanupSymbol] = (0, react_1.useState)('');
61
- const [cleanupPreview, setCleanupPreview] = (0, react_1.useState)(null);
62
- const [cleanupLoading, setCleanupLoading] = (0, react_1.useState)(false);
63
- const [cleanupJobId, setCleanupJobId] = (0, react_1.useState)(null);
64
- const [cleanupProgress, setCleanupProgress] = (0, react_1.useState)(null);
65
- const [inputPrice, setInputPrice] = (0, react_1.useState)('');
66
- const [inputQuantity, setInputQuantity] = (0, react_1.useState)('');
67
- const [orderType, setOrderType] = (0, react_1.useState)('MARKET');
68
- const handleCloseDialog = (0, react_1.useCallback)(() => {
69
- setDialogOpen(false);
70
- setDialogType(null);
71
- setSelectedOrder(null);
72
- setSelectedPosition(null);
73
- setInputPrice('');
74
- setInputQuantity('');
75
- setOrderType('MARKET');
76
- setDialogLoading(false);
77
- setCleanupSymbol('');
78
- setCleanupPreview(null);
79
- }, []);
80
- const handleOpenCancelDialog = (0, react_1.useCallback)((order) => {
81
- setSelectedOrder(order);
82
- setDialogType('cancel');
83
- setDialogOpen(true);
84
- }, []);
85
- const handleOpenModifyDialog = (0, react_1.useCallback)((order) => {
86
- setSelectedOrder(order);
87
- setInputPrice(order.price.toString());
88
- setDialogType('modify');
89
- setDialogOpen(true);
90
- }, []);
91
- const handleOpenAddDialog = (0, react_1.useCallback)((position) => {
92
- setSelectedPosition(position);
93
- setInputQuantity('');
94
- setDialogType('add');
95
- setDialogOpen(true);
96
- }, []);
97
- const handleOpenCloseDialog = (0, react_1.useCallback)((position) => {
98
- setSelectedPosition(position);
99
- setInputQuantity(position.amount.toString());
100
- setDialogType('close');
101
- setDialogOpen(true);
102
- }, []);
103
- const handleOpenCleanupDialog = (0, react_1.useCallback)(async (symbol) => {
104
- setCleanupSymbol(symbol);
105
- setDialogType('cleanup');
106
- setDialogOpen(true);
107
- setCleanupLoading(true);
108
- try {
109
- const { getCurrentUserToken } = await Promise.resolve().then(() => __importStar(require('../../auth-service')));
110
- const token = await getCurrentUserToken();
111
- if (!token) {
112
- sonner_1.toast.error("用户未登录");
113
- return;
114
- }
115
- const res = (0, auth_service_1.guardAuthResponse)(await fetch(`/api/exchanges/binance/orders/cleanup/preview?symbol=${symbol}&priceBuffer=0.005`, {
116
- headers: { 'Authorization': `Bearer ${token}` }
117
- }));
118
- if (res.ok) {
119
- const data = await res.json();
120
- setCleanupPreview(data.data);
121
- }
122
- else {
123
- const errorData = await res.json();
124
- throw new Error(errorData.error || '获取预览失败');
125
- }
126
- }
127
- catch (err) {
128
- sonner_1.toast.error(err instanceof Error ? err.message : '获取预览失败');
129
- handleCloseDialog();
130
- }
131
- finally {
132
- setCleanupLoading(false);
133
- }
134
- }, [handleCloseDialog]);
135
- const pollCleanupStatus = (0, react_1.useCallback)(async (jobId, token) => {
136
- const pollInterval = 2000;
137
- const maxPolls = 300;
138
- for (let i = 0; i < maxPolls; i++) {
139
- try {
140
- const res = (0, auth_service_1.guardAuthResponse)(await fetch(`/api/exchanges/binance/orders/cleanup/status?jobId=${jobId}`, {
141
- headers: { 'Authorization': `Bearer ${token}` }
142
- }));
143
- if (!res.ok) {
144
- const errorData = await res.json();
145
- throw new Error(errorData.error || '获取状态失败');
146
- }
147
- const data = await res.json();
148
- const progress = data.data;
149
- setCleanupProgress(progress);
150
- if (progress.status === 'completed') {
151
- const result = progress.result;
152
- const totalMerged = (result?.LONG?.tp_merged || 0) + (result?.SHORT?.tp_merged || 0);
153
- const totalDeleted = (result?.LONG?.open_deleted || 0) + (result?.SHORT?.open_deleted || 0);
154
- sonner_1.toast.success(`订单整理完成: 合并${totalMerged}个止盈, 删除${totalDeleted}个开仓`);
155
- setCleanupJobId(null);
156
- setCleanupProgress(null);
157
- handleCloseDialog();
158
- fetchData();
159
- return;
160
- }
161
- if (progress.status === 'failed') {
162
- throw new Error(progress.error || '任务执行失败');
163
- }
164
- await new Promise(resolve => setTimeout(resolve, pollInterval));
165
- }
166
- catch (err) {
167
- sonner_1.toast.error(err instanceof Error ? err.message : '获取状态失败');
168
- setCleanupJobId(null);
169
- setCleanupProgress(null);
170
- setDialogLoading(false);
171
- return;
172
- }
173
- }
174
- sonner_1.toast.error('任务超时,请检查订单状态');
175
- setCleanupJobId(null);
176
- setCleanupProgress(null);
177
- setDialogLoading(false);
178
- }, [fetchData, handleCloseDialog]);
179
- const handleExecuteCleanup = (0, react_1.useCallback)(async () => {
180
- if (!cleanupSymbol)
181
- return;
182
- setDialogLoading(true);
183
- setCleanupProgress(null);
184
- try {
185
- const { getCurrentUserToken } = await Promise.resolve().then(() => __importStar(require('../../auth-service')));
186
- const token = await getCurrentUserToken();
187
- if (!token) {
188
- sonner_1.toast.error("用户未登录");
189
- return;
190
- }
191
- const res = (0, auth_service_1.guardAuthResponse)(await fetch('/api/exchanges/binance/orders/cleanup', {
192
- method: 'POST',
193
- headers: {
194
- 'Authorization': `Bearer ${token}`,
195
- 'Content-Type': 'application/json'
196
- },
197
- body: JSON.stringify({ symbol: cleanupSymbol, priceBuffer: 0.005 })
198
- }));
199
- if (res.ok) {
200
- const data = await res.json();
201
- const jobId = data.jobId;
202
- if (jobId) {
203
- setCleanupJobId(jobId);
204
- sonner_1.toast.info('任务已提交,正在执行...');
205
- pollCleanupStatus(jobId, token);
206
- }
207
- else {
208
- throw new Error('未获取到任务ID');
209
- }
210
- }
211
- else {
212
- const errorData = await res.json();
213
- throw new Error(errorData.error || '执行整理失败');
214
- }
215
- }
216
- catch (err) {
217
- sonner_1.toast.error(err instanceof Error ? err.message : '执行整理失败');
218
- setDialogLoading(false);
219
- }
220
- }, [cleanupSymbol, pollCleanupStatus]);
221
- const handleCancelOrder = (0, react_1.useCallback)(async () => {
222
- if (!selectedOrder)
223
- return;
224
- setDialogLoading(true);
225
- try {
226
- const result = await (0, api_service_1.cancelBinanceOrder)(selectedOrder.symbol, selectedOrder.clientOrderId || selectedOrder.orderId);
227
- if (result.success) {
228
- sonner_1.toast.success(`订单 ${selectedOrder.orderId} 已成功取消`);
229
- handleCloseDialog();
230
- fetchData();
231
- }
232
- else {
233
- throw new Error(result.error || '撤单失败');
234
- }
235
- }
236
- catch (err) {
237
- sonner_1.toast.error(err instanceof Error ? err.message : '撤单失败');
238
- }
239
- finally {
240
- setDialogLoading(false);
241
- }
242
- }, [selectedOrder, fetchData, handleCloseDialog]);
243
- const handleModifyOrder = (0, react_1.useCallback)(async () => {
244
- if (!selectedOrder || !inputPrice)
245
- return;
246
- const newPrice = parseFloat(inputPrice);
247
- if (isNaN(newPrice) || newPrice <= 0) {
248
- sonner_1.toast.error("请输入有效的价格");
249
- return;
250
- }
251
- setDialogLoading(true);
252
- try {
253
- const result = await (0, api_service_1.modifyBinanceOrder)(selectedOrder.symbol, selectedOrder.clientOrderId || selectedOrder.orderId, newPrice);
254
- if (result.success) {
255
- sonner_1.toast.success(`订单价格已修改为 ${newPrice}`);
256
- handleCloseDialog();
257
- fetchData();
258
- }
259
- else {
260
- throw new Error(result.error || '追单失败');
261
- }
262
- }
263
- catch (err) {
264
- sonner_1.toast.error(err instanceof Error ? err.message : '追单失败');
265
- }
266
- finally {
267
- setDialogLoading(false);
268
- }
269
- }, [selectedOrder, inputPrice, fetchData, handleCloseDialog]);
270
- const handleAddPosition = (0, react_1.useCallback)(async () => {
271
- if (!selectedPosition || !inputQuantity)
272
- return;
273
- const quantity = parseFloat(inputQuantity);
274
- if (isNaN(quantity) || quantity <= 0) {
275
- sonner_1.toast.error("请输入有效的数量");
276
- return;
277
- }
278
- if (orderType === 'LIMIT') {
279
- const price = parseFloat(inputPrice);
280
- if (isNaN(price) || price <= 0) {
281
- sonner_1.toast.error("请输入有效的价格");
282
- return;
283
- }
284
- }
285
- setDialogLoading(true);
286
- try {
287
- const side = selectedPosition.side === 'LONG' ? 'BUY' : 'SELL';
288
- const positionSide = selectedPosition.side;
289
- const clientOrderId = (0, order_id_generator_1.generateUserOrderId)(detectPlatform(), 'add');
290
- const result = await (0, api_service_1.placeBinanceOrder)({
291
- symbol: selectedPosition.symbol,
292
- side: side,
293
- positionSide: positionSide,
294
- quantity: quantity,
295
- orderType: orderType,
296
- price: orderType === 'LIMIT' ? parseFloat(inputPrice) : undefined,
297
- clientOrderId: clientOrderId
298
- });
299
- if (result.success) {
300
- const orderTypeText = orderType === 'MARKET' ? '市价' : '限价';
301
- sonner_1.toast.success(`${selectedPosition.symbol} ${positionSide} ${orderTypeText}开仓 ${quantity}`);
302
- handleCloseDialog();
303
- fetchData();
304
- }
305
- else {
306
- throw new Error(result.error || '开仓失败');
307
- }
308
- }
309
- catch (err) {
310
- sonner_1.toast.error(err instanceof Error ? err.message : '开仓失败');
311
- }
312
- finally {
313
- setDialogLoading(false);
314
- }
315
- }, [selectedPosition, inputQuantity, inputPrice, orderType, fetchData, handleCloseDialog]);
316
- const handleClosePosition = (0, react_1.useCallback)(async () => {
317
- if (!selectedPosition || !inputQuantity)
318
- return;
319
- const quantity = parseFloat(inputQuantity);
320
- if (isNaN(quantity) || quantity <= 0) {
321
- sonner_1.toast.error("请输入有效的数量");
322
- return;
323
- }
324
- if (quantity > selectedPosition.amount) {
325
- sonner_1.toast.error(`平仓数量不能大于持仓数量 ${selectedPosition.amount}`);
326
- return;
327
- }
328
- if (orderType === 'LIMIT') {
329
- const price = parseFloat(inputPrice);
330
- if (isNaN(price) || price <= 0) {
331
- sonner_1.toast.error("请输入有效的价格");
332
- return;
333
- }
334
- }
335
- setDialogLoading(true);
336
- try {
337
- const side = selectedPosition.side === 'LONG' ? 'SELL' : 'BUY';
338
- const positionSide = selectedPosition.side;
339
- const clientOrderId = (0, order_id_generator_1.generateUserOrderId)(detectPlatform(), 'close');
340
- const result = await (0, api_service_1.placeBinanceOrder)({
341
- symbol: selectedPosition.symbol,
342
- side: side,
343
- positionSide: positionSide,
344
- quantity: quantity,
345
- orderType: orderType,
346
- price: orderType === 'LIMIT' ? parseFloat(inputPrice) : undefined,
347
- clientOrderId: clientOrderId
348
- });
349
- if (result.success) {
350
- const orderTypeText = orderType === 'MARKET' ? '市价' : '限价';
351
- sonner_1.toast.success(`${selectedPosition.symbol} ${positionSide} ${orderTypeText}平仓 ${quantity}`);
352
- handleCloseDialog();
353
- fetchData();
354
- }
355
- else {
356
- throw new Error(result.error || '平仓失败');
357
- }
358
- }
359
- catch (err) {
360
- sonner_1.toast.error(err instanceof Error ? err.message : '平仓失败');
361
- }
362
- finally {
363
- setDialogLoading(false);
364
- }
365
- }, [selectedPosition, inputQuantity, inputPrice, orderType, fetchData, handleCloseDialog]);
366
- return {
367
- dialogOpen,
368
- dialogType,
369
- selectedOrder,
370
- selectedPosition,
371
- dialogLoading,
372
- inputPrice,
373
- inputQuantity,
374
- orderType,
375
- cleanupSymbol,
376
- cleanupPreview,
377
- cleanupLoading,
378
- cleanupJobId,
379
- cleanupProgress,
380
- setInputPrice,
381
- setInputQuantity,
382
- setOrderType,
383
- handleOpenCancelDialog,
384
- handleOpenModifyDialog,
385
- handleOpenAddDialog,
386
- handleOpenCloseDialog,
387
- handleOpenCleanupDialog,
388
- handleCloseDialog,
389
- handleCancelOrder,
390
- handleModifyOrder,
391
- handleAddPosition,
392
- handleClosePosition,
393
- handleExecuteCleanup
394
- };
395
- }
@@ -1,15 +0,0 @@
1
- export interface UserExchangeAccount {
2
- exchangeId: string;
3
- exchangeName: string;
4
- accountName: string;
5
- displayName: string;
6
- status: 'active' | 'inactive' | 'error';
7
- }
8
- export declare function useUserExchanges(): {
9
- boundExchanges: string[];
10
- isExchangeBound: (exchangeId: string) => boolean;
11
- isSelectedExchangeAvailable: (selectedExchange: string) => boolean;
12
- isLoading: boolean;
13
- error: any;
14
- refresh: import("swr").KeyedMutator<string[]>;
15
- };