|
|
@@ -1,6 +1,6 @@
|
|
|
'use client'
|
|
|
|
|
|
-import { useEffect, useState } from 'react'
|
|
|
+import { useEffect, useState, useRef } from 'react'
|
|
|
import {
|
|
|
Button,
|
|
|
Modal,
|
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
App,
|
|
|
Typography,
|
|
|
Tag,
|
|
|
+ InputNumber,
|
|
|
} from 'antd'
|
|
|
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table'
|
|
|
import dayjs from 'dayjs'
|
|
|
@@ -40,7 +41,10 @@ interface RecordInfo {
|
|
|
totalDeposit: string
|
|
|
earnedUsd: string
|
|
|
earnedUsdPercent: string
|
|
|
+ allCopyAmount: string
|
|
|
+ allCopys: number
|
|
|
openTime: number
|
|
|
+ status: number
|
|
|
hasDetail?: boolean
|
|
|
priceOutType?: string
|
|
|
priceLower?: string
|
|
|
@@ -66,7 +70,7 @@ function MyLPPageContent() {
|
|
|
const [poolMap, setPoolMap] = useState<Record<string, LPInfo>>({})
|
|
|
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([])
|
|
|
const [batchClosing, setBatchClosing] = useState(false)
|
|
|
-
|
|
|
+ const inputNumberRef = useRef<React.ComponentRef<typeof InputNumber>>(null)
|
|
|
const fetchLPDetail = async (positions: RecordInfo[]) => {
|
|
|
message.loading(`正在查询当前页面仓位详细信息,请稍等...`)
|
|
|
|
|
|
@@ -81,9 +85,31 @@ function MyLPPageContent() {
|
|
|
`/api/my-lp/detail?address=${position.positionAddress}`
|
|
|
)
|
|
|
const data = await response.json()
|
|
|
+ const detailData = data.result.data
|
|
|
+ const { pool, bonusInfo } = detailData
|
|
|
+
|
|
|
+ const copyInfo = await fetch(
|
|
|
+ `/api/my-lp/copyInfo?parentPositionAddress=${bonusInfo.fromCreatorPosition}&poolAddress=${pool.poolAddress}`
|
|
|
+ )
|
|
|
+ let allCopyAmount = 0
|
|
|
+ const copyInfoData = await copyInfo.json()
|
|
|
+ if (copyInfoData.retCode === 0 && copyInfoData.result) {
|
|
|
+ allCopyAmount = copyInfoData.result.data.records
|
|
|
+ .filter((item: RecordInfo) => item.status === 0)
|
|
|
+ .reduce(
|
|
|
+ (acc: number, curr: RecordInfo) =>
|
|
|
+ acc + Number(curr.liquidityUsd),
|
|
|
+ 0
|
|
|
+ )
|
|
|
+ }
|
|
|
+ const newData = {
|
|
|
+ ...data.result.data,
|
|
|
+ allCopyAmount: allCopyAmount,
|
|
|
+ allCopys: copyInfoData.result.data.total,
|
|
|
+ }
|
|
|
return {
|
|
|
positionAddress: position.positionAddress,
|
|
|
- data: data.result.data,
|
|
|
+ data: newData,
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error(`获取仓位 ${position.positionAddress} 详情失败:`, error)
|
|
|
@@ -231,6 +257,52 @@ function MyLPPageContent() {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
+ function handleAddPosition(record: RecordInfo) {
|
|
|
+ message.loading({
|
|
|
+ key: 'addPosition',
|
|
|
+ content: '正在加仓...',
|
|
|
+ duration: 0,
|
|
|
+ })
|
|
|
+ Modal.confirm({
|
|
|
+ title: '加仓金额',
|
|
|
+ content: (
|
|
|
+ <InputNumber
|
|
|
+ placeholder="请输入加仓金额"
|
|
|
+ style={{ width: '100%' }}
|
|
|
+ ref={inputNumberRef}
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ onOk: async () => {
|
|
|
+ const quickCopyAmount = inputNumberRef.current?.value
|
|
|
+ message.destroy('addPosition')
|
|
|
+ return fetch('/api/lp-copy', {
|
|
|
+ method: 'POST',
|
|
|
+ body: JSON.stringify({
|
|
|
+ positionAddress: record.positionAddress,
|
|
|
+ nftMintAddress: record.nftMintAddress,
|
|
|
+ maxUsdValue: quickCopyAmount,
|
|
|
+ }),
|
|
|
+ })
|
|
|
+ .then((res) => res.json())
|
|
|
+ .then((data) => {
|
|
|
+ message.destroy('addPosition')
|
|
|
+ if (data.success) {
|
|
|
+ message.success('加仓成功')
|
|
|
+ } else {
|
|
|
+ message.error(data.error || '加仓失败')
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch((err) => {
|
|
|
+ console.error('Error adding position:', err)
|
|
|
+ message.error('加仓失败')
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onCancel: () => {
|
|
|
+ message.destroy('addPosition')
|
|
|
+ },
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
const columns: ColumnsType<RecordInfo> = [
|
|
|
{
|
|
|
title: 'LP Token',
|
|
|
@@ -271,11 +343,28 @@ function MyLPPageContent() {
|
|
|
// ),
|
|
|
// },
|
|
|
{
|
|
|
- title: 'Liquidity',
|
|
|
+ title: '复制金额/占比',
|
|
|
dataIndex: 'liquidityUsd',
|
|
|
key: 'liquidityUsd',
|
|
|
- render: (text: string) => (
|
|
|
- <span className="font-mono text-sm">${Number(text).toFixed(2)}</span>
|
|
|
+ render: (text: string, record: RecordInfo) => (
|
|
|
+ <span className="font-mono text-sm">
|
|
|
+ ${Number(text).toFixed(2)}
|
|
|
+ <span className="text-sm text-blue-500">
|
|
|
+ ({((Number(text) / Number(record.allCopyAmount)) * 100).toFixed(2)}
|
|
|
+ %)
|
|
|
+ </span>
|
|
|
+ </span>
|
|
|
+ ),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '总复制金额/复制数',
|
|
|
+ dataIndex: 'allCopyAmount',
|
|
|
+ key: 'allCopyAmount',
|
|
|
+ render: (text: string, record: RecordInfo) => (
|
|
|
+ <span className="font-mono text-sm text-orange-500">
|
|
|
+ ${Number(text).toFixed(2)}
|
|
|
+ <span className="text-sm text-blue-500">({record.allCopys})</span>
|
|
|
+ </span>
|
|
|
),
|
|
|
},
|
|
|
{
|
|
|
@@ -326,16 +415,16 @@ function MyLPPageContent() {
|
|
|
<span className="font-mono text-sm">${Number(text).toFixed(2)}</span>
|
|
|
),
|
|
|
},
|
|
|
- {
|
|
|
- title: 'Earned Percent',
|
|
|
- dataIndex: 'earnedUsdPercent',
|
|
|
- key: 'earnedUsdPercent',
|
|
|
- render: (text: string) => (
|
|
|
- <span className="font-mono text-sm">
|
|
|
- {(Number(text) * 100).toFixed(2)}%
|
|
|
- </span>
|
|
|
- ),
|
|
|
- },
|
|
|
+ // {
|
|
|
+ // title: 'Earned Percent',
|
|
|
+ // dataIndex: 'earnedUsdPercent',
|
|
|
+ // key: 'earnedUsdPercent',
|
|
|
+ // render: (text: string) => (
|
|
|
+ // <span className="font-mono text-sm">
|
|
|
+ // {(Number(text) * 100).toFixed(2)}%
|
|
|
+ // </span>
|
|
|
+ // ),
|
|
|
+ // },
|
|
|
{
|
|
|
title: '当前价格',
|
|
|
dataIndex: 'price',
|
|
|
@@ -436,6 +525,15 @@ function MyLPPageContent() {
|
|
|
key: 'bonusInfo',
|
|
|
render: (text: string, record: RecordInfo) => (
|
|
|
<div className="flex items-center gap-2">
|
|
|
+ {record?.bonusInfo?.fromCreatorWallet &&
|
|
|
+ record?.bonusInfo?.fromCreatorPosition && (
|
|
|
+ <Typography.Link
|
|
|
+ href={`https://www.byreal.io/en/portfolio?userAddress=${record.bonusInfo.fromCreatorWallet}&tab=current&positionAddress=${record.bonusInfo.fromCreatorPosition}&tokenAddress=${getPoolInfo(record.poolAddress).tokenAAddress}&tokenAddress=${getPoolInfo(record.poolAddress).tokenBAddress}`}
|
|
|
+ target="_blank"
|
|
|
+ >
|
|
|
+ 查看上级
|
|
|
+ </Typography.Link>
|
|
|
+ )}
|
|
|
<Typography.Link
|
|
|
href={`https://www.byreal.io/en/portfolio?userAddress=${record.walletAddress}&tab=current&positionAddress=${record.positionAddress}&tokenAddress=${getPoolInfo(record.poolAddress).tokenAAddress}&tokenAddress=${getPoolInfo(record.poolAddress).tokenBAddress}`}
|
|
|
target="_blank"
|
|
|
@@ -445,6 +543,9 @@ function MyLPPageContent() {
|
|
|
<Typography.Link onClick={() => handleClosePosition(record)}>
|
|
|
快速关仓
|
|
|
</Typography.Link>
|
|
|
+ <Typography.Link onClick={() => handleAddPosition(record)}>
|
|
|
+ 快速加仓
|
|
|
+ </Typography.Link>
|
|
|
</div>
|
|
|
),
|
|
|
},
|