From befe50b3e5f55de76a5337b9ae13cd95d44a4e22 Mon Sep 17 00:00:00 2001 From: yml2213 Date: Mon, 5 Oct 2026 15:54:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(rock):=20=E6=94=AF=E6=8C=81=E6=89=8B?= =?UTF-8?q?=E5=8A=A8=E9=87=87=E8=B4=AD=E6=8C=87=E5=AE=9A=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E9=80=9A=E7=94=A8=20Token=20=E5=BC=B9=E7=AA=97=E4=B8=8E?= =?UTF-8?q?=E5=AE=9E=E6=97=B6=E7=A7=AF=E5=88=86=E8=AF=95=E7=AE=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增手动采购 Modal 弹窗,支持自由输入指定数量(InputNumber)与快捷胶囊选择(10/20/50/100/全部可购); 2. 动态联动 0666.pro 实时积分余额,提供单价折算(21点/个)、预计消耗与结余防超支校验; 3. PageHeader 采购按钮与指标看板无缝唤起采购弹窗,采购完成后自动关闭并刷新数据。 --- frontend/src/pages/PlatformRock.tsx | 186 +++++++++++++++++++++++++++- 1 file changed, 180 insertions(+), 6 deletions(-) diff --git a/frontend/src/pages/PlatformRock.tsx b/frontend/src/pages/PlatformRock.tsx index 996108b..3799823 100644 --- a/frontend/src/pages/PlatformRock.tsx +++ b/frontend/src/pages/PlatformRock.tsx @@ -46,6 +46,8 @@ export default function PlatformRock() { const [testingConn, setTestingConn] = useState(false) const [savingConfig, setSavingConfig] = useState(false) const [purchasing, setPurchasing] = useState(false) + const [purchaseModalOpen, setPurchaseModalOpen] = useState(false) + const [purchaseCount, setPurchaseCount] = useState(50) // Token 列表与筛选 const [tokens, setTokens] = useState([]) @@ -169,12 +171,22 @@ export default function PlatformRock() { } } - // 批量采购 50 个 - const handlePurchase = async (count = 50) => { + const openPurchaseModal = (count = 50) => { + setPurchaseCount(count) + setPurchaseModalOpen(true) + } + + // 采购指定数量 Token + const handlePurchase = async (count: number) => { + if (!count || count <= 0) { + message.warning('请输入有效的采购数量') + return + } setPurchasing(true) try { const res = await rockApi.purchaseTokens(count) message.success(res.message || `成功采购 ${count} 个通用黑色 Token!`) + setPurchaseModalOpen(false) loadData() loadTokens() } catch (e) { @@ -371,6 +383,10 @@ export default function PlatformRock() { const warningStock = config?.token_warning_stock ?? 10 const isStockLow = availableStock <= warningStock const hasMismatch = (stats?.mismatch_stock ?? 0) > 0 + const upstreamPoints = stats?.upstream_points ?? 0 + const maxPurchasable = Math.max(0, Math.floor(upstreamPoints / 21)) + const estimatedCost = (purchaseCount || 0) * 21 + const isPointsInsufficient = estimatedCost > upstreamPoints return (
@@ -382,14 +398,14 @@ export default function PlatformRock() {
- {(stats?.upstream_points ?? 0).toFixed(1)} + {upstreamPoints.toFixed(1)} 点
账号: {stats?.username || '未同步'} - 约可采购 {Math.floor((stats?.upstream_points ?? 0) / 21)} 个 + openPurchaseModal(maxPurchasable > 0 ? Math.min(50, maxPurchasable) : 10)} + style={{ fontWeight: 600, color: '#2563eb', cursor: 'pointer' }} + title="点击快速打开手动采购弹窗" + > + 约可采购 {maxPurchasable} 个 ➔ +
@@ -761,7 +783,159 @@ export default function PlatformRock() { }, }} /> + + {/* 手动采购指定数量 Token 弹窗 */} + + + 手动采购通用黑色 Token (0666.pro) + + } + open={purchaseModalOpen} + onCancel={() => setPurchaseModalOpen(false)} + footer={[ + , + , + ]} + destroyOnClose + width={500} + > +
+ {/* 账户与资产概览 */} +
+ + +
0666.pro 采购商户
+
+ {stats?.username || '正常商户'} +
+ + +
当前实时积分余额
+
+ {upstreamPoints.toFixed(1)} 点 +
+ +
+ +
+ 采购单价:21 点 / 个 + 最大可采购:{maxPurchasable} 个 +
+
+ + {/* 采购数量输入 */} +
+
+ 采购数量: +
+ 0 ? maxPurchasable : 10000} + value={purchaseCount} + onChange={(val) => setPurchaseCount(val || 1)} + style={{ width: '100%' }} + addonAfter="个 Token" + size="large" + /> +
+ + {/* 快捷数量选择胶囊 */} +
+
快捷选择:
+ + {[10, 20, 50, 100].map((num) => ( + + ))} + {maxPurchasable > 0 && ( + + )} + +
+ + {/* 实时消耗与结余试算 */} +
+
+ + 本次采购消耗积分: + + + {estimatedCost} 点 + +
+
+ + {isPointsInsufficient + ? '⚠️ 账户积分不足,请先充值或减少采购数量' + : '采购后预计剩余积分:'} + + {!isPointsInsufficient && ( + + {(upstreamPoints - estimatedCost).toFixed(1)} 点 + + )} +
+
+
+
) } +