From 03043192ddf00f9a36b7454799a9152cd1b50a0b Mon Sep 17 00:00:00 2001
From: admin <344137771@qq.com>
Date: Tue, 06 Jan 2026 11:13:45 +0800
Subject: [PATCH] 1

---
 src/views/cryptos/darkpoolTrading/index.vue |  466 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 466 insertions(+), 0 deletions(-)

diff --git a/src/views/cryptos/darkpoolTrading/index.vue b/src/views/cryptos/darkpoolTrading/index.vue
new file mode 100644
index 0000000..a8968fd
--- /dev/null
+++ b/src/views/cryptos/darkpoolTrading/index.vue
@@ -0,0 +1,466 @@
+<template>
+    <div class="app-container app-page bg-white rounded-2xl shadow-lg border border-gray-200 overflow-hidden">
+        <!-- 顶部导航栏 -->
+        <assets-head :title="$t('暗池交易')" />
+
+        <!-- Tab切换区 -->
+        <div class="fixed-section bg-white py-2 px-6 flex rounded-lg mx-4 mt-4 mb-2 border border-gray-200">
+            <button @click="activeTab = 'products'" :class="['tab-button flex-1 py-2 font-medium rounded-lg transition-all duration-200',
+                activeTab === 'products' ? 'active text-red-600' : 'text-gray-700']">
+                {{ $t('产品列表') }}
+            </button>
+            <button @click="activeTab = 'records'" :class="['tab-button flex-1 py-2 font-medium rounded-lg transition-all duration-200',
+                activeTab === 'records' ? 'active text-red-600' : 'text-gray-700']">
+                {{ $t('my') }}
+            </button>
+        </div>
+
+        <!-- 内容区: 可滚动 -->
+        <div class="content-flex hide-scrollbar px-4 pb-6 overflow-y-auto">
+            <!-- 产品列表 -->
+            <div v-show="activeTab === 'products'" class="space-y-4">
+                <div v-for="product in products" :key="product.id"
+                    class="bg-white rounded-xl p-4 border border-gray-200 shadow-sm hover:shadow-md transition-shadow">
+                    <div class="flex justify-between items-start">
+                        <div class="flex-1">
+                            <!-- 产品标题区域 -->
+                            <div class="flex items-center justify-between mb-3">
+                                <div class="flex items-center">
+                                    <div>
+                                        <h3 class="text-gray-800 font-bold text-base">
+                                            {{ product.stockName }}({{ product.stockCode }})</h3>
+                                        <!-- <p class="text-gray-500 text-xs mt-1">{{ product.stockCode }}</p> -->
+                                    </div>
+                                </div>
+                            </div>
+
+                            <!-- 价格信息区域 -->
+                            <div class="bg-gray-50 rounded-lg p-3 mb-3">
+                                <div class="flex justify-between items-center">
+                                    <div>
+                                        <p class="text-gray-500 text-xs">{{ $t('委托价格') }}</p>
+                                        <p class="text-gray-800 font-bold text-lg">
+                                            {{ product.nowPrice }} $
+                                        </p>
+                                    </div>
+                                    <div class="text-right">
+                                        <div class="flex items-center">
+                                            <span class="iconify text-gray-400 mr-1"
+                                                data-icon="mdi:clock-outline"></span>
+                                            <span class="text-gray-500 text-xs">{{ $t('最小数量') }}</span>
+                                        </div>
+                                        <div class="px-3 py-1 rounded-full text-xs font-medium">
+                                            {{ product.stockNum }}
+                                        </div>
+                                    </div>
+                                </div>
+                                <!-- <div class="flex justify-between items-center">
+                                    <div>
+                                        <p class="text-gray-500 text-xs">{{ $t('委托价格') }}</p>
+                                        <p class="text-gray-800 font-bold text-lg">
+                                            {{ product.currentPrice }} $
+                                        </p>
+                                    </div>
+                                </div> -->
+                            </div>
+                        </div>
+                    </div>
+                    <!-- 下单按钮 -->
+                    <div class="mt-4 pt-3 border-t border-gray-100">
+                        <button @click="openTradeModal(product)"
+                            class="trade-btn w-full bg-green-600 hover:bg-green-700 text-white py-3 rounded-lg text-sm font-bold transition-colors shadow-sm flex items-center justify-center">
+                            <span class="iconify mr-2"></span>
+                            {{ $t('确认下单') }}
+                        </button>
+                    </div>
+                </div>
+                <van-empty v-if="products.length === 0" :description="$t('暂无数据')" />
+            </div>
+
+            <!-- 购买记录 -->
+            <div v-show="activeTab === 'records'">
+                <!-- 子Tab切换区 -->
+                <div class="bg-gray-100 py-1 px-4 flex rounded-lg mb-4">
+                    <button @click="activeSubTab = 'position'" :class="['subtab-button flex-1 py-2 text-sm font-medium rounded-lg transition-all duration-200',
+                        activeSubTab === 'position' ? 'active text-red-600' : 'text-gray-700']">
+                        {{ $t('持仓') }}
+                    </button>
+                    <button @click="activeSubTab = 'history'" :class="['subtab-button flex-1 py-2 text-sm font-medium rounded-lg transition-all duration-200',
+                        activeSubTab === 'history' ? 'active text-red-600' : 'text-gray-700']">
+                        {{ $t('历史') }}
+                    </button>
+                </div>
+
+                <!-- 持仓部分 -->
+                <div v-show="activeSubTab === 'position'" class="space-y-4">
+                    <div v-for="position in positions" :key="position.id"
+                        class="bg-white rounded-xl p-4 border border-gray-200 shadow-sm hover:shadow-md transition-shadow">
+                        <div class="flex justify-between items-center">
+                            <div>
+                                <h3 class="text-gray-800 font-bold">{{ position.stockName }}</h3>
+                                <p class="text-gray-500 text-sm mt-1">{{ position.symbol }}</p>
+                            </div>
+                            <div class="flex">
+                                <button @click="closePosition(position)"
+                                    class="close-btn bg-red-600 hover:bg-red-700 text-white py-2 px-4 rounded-lg text-sm transition-colors font-medium">
+                                    {{ $t('平仓') }}
+                                </button>
+                            </div>
+                        </div>
+
+                        <div class="grid grid-cols-2 gap-4 mt-4">
+                            <div>
+                                <p class="text-gray-500 text-xs">{{ $t('买入价格') }}</p>
+                                <p class="text-gray-800 font-medium">{{ position.price }} $</p>
+                            </div>
+                            <div>
+                                <p class="text-gray-500 text-xs">{{ $t('买入金额') }}</p>
+                                <p class="text-gray-800 font-medium">{{ formatNumberWithComma(position.volume) }} $</p>
+                            </div>
+                            <div>
+                                <p class="text-gray-500 text-xs">{{ $t('交易时间') }}</p>
+                                <p class="text-gray-800 font-medium">{{ position.createTime }}</p>
+                            </div>
+                            <!-- <div>
+                                <p class="text-gray-500 text-xs">{{ $t('状态') }}</p>
+                                <p class="text-green-500 font-medium">{{ position.status }}</p>
+                            </div> -->
+                        </div>
+
+                        <div class="mt-4 pt-3 border-t border-gray-100">
+                            <div class="flex justify-between items-center">
+                                <p class="text-gray-500 text-xs">{{ $t('浮动盈亏') }}</p>
+                                <p :class="['font-bold', position.profitLoss >= 0 ? 'text-green-500' : 'text-red-500']">
+                                    {{ position.profitLoss >= 0 ? '+' : '' }} {{ position.profitLoss }} $ | {{
+                                        position.profitLossPercentage }}%
+                                </p>
+                            </div>
+                        </div>
+                    </div>
+                    <van-empty v-if="positions.length === 0" :description="$t('暂无数据')" />
+                </div>
+
+                <!-- 历史部分 -->
+                <div v-show="activeSubTab === 'history'" class="space-y-4">
+                    <div v-for="history in histories" :key="history.id"
+                        class="bg-white rounded-xl p-4 border border-gray-200 shadow-sm hover:shadow-md transition-shadow">
+                        <div class="flex justify-between items-center">
+                            <div>
+                                <h3 class="text-gray-800 font-bold">{{ history.stockName }}</h3>
+                                <p class="text-gray-500 text-sm mt-1">{{ history.symbol }}</p>
+                            </div>
+                            <span class="bg-gray-100 text-gray-800 text-xs px-2 py-1 rounded-full tj"
+                                :class="[history.state == 'position' ? 'cg' : history.state == 'failed' ? 'sb' : history.state == 'closed' ? 'pc' : '']">
+                                {{ startStr[history.state] }}
+                            </span>
+                        </div>
+
+                        <div class="grid grid-cols-2 gap-4 mt-4">
+                            <div>
+                                <p class="text-gray-500 text-xs">{{ $t('买入价格') }}</p>
+                                <p class="text-gray-800 font-medium">{{ history.price }} $</p>
+                            </div>
+                            <div>
+                                <p class="text-gray-500 text-xs">{{ $t('买入金额') }}</p>
+                                <p class="text-gray-800 font-medium">{{ formatNumberWithComma(history.volume) }} $</p>
+                            </div>
+                            <div>
+                                <p class="text-gray-500 text-xs">{{ $t('交易时间') }}</p>
+                                <p class="text-gray-800 font-medium">{{ history.createTime }}</p>
+                            </div>
+
+                            <div>
+                                <p class="text-gray-500 text-xs">{{ $t('卖出价格') }}</p>
+                                <p class="text-gray-800 font-medium">{{ history.closePrice ? history.closePrice + ' $' :
+                                    '--' }}</p>
+                            </div>
+                            <div>
+                                <p class="text-gray-500 text-xs">{{ $t('卖出金额') }}</p>
+                                <p class="text-gray-800 font-medium">
+                                    {{ history.closePrice ? formatNumberWithComma(history.closePrice *
+                                        history.symbolValue) : '--' }}</p>
+                            </div>
+
+                            <div>
+                                <p class="text-gray-500 text-xs">{{ $t('状态') }}</p>
+                                <p class="text-orange-500 font-medium tj"
+                                    :class="[history.state == 'position' ? 'cg' : history.state == 'failed' ? 'sb' : history.state == 'closed' ? 'pc' : '']">
+                                    {{ startStr[history.state] }}</p>
+                            </div>
+                            <div>
+                                <p class="text-gray-500 text-xs">{{ $t("订单号") }}</p>
+                                <p :class="['font-bold']">
+                                    {{ history.orderNo }}
+                                </p>
+                            </div>
+                        </div>
+
+                        <div class="mt-4 pt-3 border-t border-gray-100" v-if="history.state == 'closed'">
+                            <div class="flex justify-between items-center">
+                                <p class="text-gray-500 text-xs">{{ $t('盈亏') }}</p>
+                                <p :class="['font-bold', history.profitLoss >= 0 ? 'text-green-500' : 'text-red-500']">
+                                    {{ history.profitLoss >= 0 ? '+' : '' }} {{ history.profitLoss }} $ | {{
+                                        history.profitLossPercentage }}%
+                                </p>
+                            </div>
+                        </div>
+                    </div>
+                    <van-empty v-if="histories.length === 0" :description="$t('暂无数据')" />
+                </div>
+            </div>
+        </div>
+
+        <!-- 交易弹框 -->
+        <van-popup v-model:show="showTradeModal">
+            <!-- <div v-if="showTradeModal"
+                class="fixed inset-0 bg-gray-800 bg-opacity-70 flex items-center justify-center p-4 z-50"
+                @click="closeTradeModal"> -->
+            <div class="bg-white rounded-xl w-full p-6" style="width:40rem" @click.stop>
+                <div class="flex justify-between items-center mb-4">
+                    <h3 class="text-gray-800 text-lg font-bold">{{ $t('确认下单') }}</h3>
+                    <button @click="closeTradeModal" class="text-gray-500 hover:text-gray-800">
+                        <span class="iconify text-xl" data-icon="mdi:close"></span>
+                    </button>
+                </div>
+
+                <div class="bg-gray-100 rounded-lg p-4 mb-4">
+                    <div class="flex justify-between">
+                        <h4 class="text-gray-800 font-bold">
+                            {{ selectedProduct?.stockName }}({{ selectedProduct?.stockCode }})</h4>
+                        <!-- <span class="text-gray-500 text-sm">{{ selectedProduct?.stockCode }}</span> -->
+                    </div>
+                    <p class="text-gray-800 mt-2 font-bold text-xl">
+                        $ {{ selectedProduct?.nowPrice }}
+                    </p>
+                </div>
+
+                <div class="space-y-4">
+                    <div>
+                        <label class="text-gray-500 text-sm mb-1 block">{{ $t('交易数量') }}</label>
+                        <input v-model="tradeQuantity" type="number"
+                            class="w-full bg-white border border-gray-300 rounded-lg px-4 py-3 text-gray-800 focus:outline-none focus:ring-2 focus:ring-green-500"
+                            :placeholder="$t('请输入数量')" oninput="value = value.replace(/[^\d]/g, '').replace(/^0+/, '')"
+                            min="1">
+                    </div>
+                </div>
+
+                <div class="flex space-x-3 mt-6">
+                    <button @click="closeTradeModal"
+                        class="flex-1 bg-transparent border border-red-600 text-red-600 py-3 rounded-lg transition-colors hover:bg-red-50 font-medium">
+                        {{ $t('取消') }}
+                    </button>
+                    <button @click="confirmTrade"
+                        class="flex-1 bg-green-600 text-white py-3 rounded-lg transition-colors hover:bg-green-700 font-medium">
+                        {{ $t('确认') }}
+                    </button>
+                </div>
+            </div>
+            <!-- </div> -->
+        </van-popup>
+
+    </div>
+</template>
+
+<script setup>
+import { ref, reactive, watch } from 'vue'
+import { _getDpList, _buyStockDp, _getDpHistories, _getDpOrderList, _getDzCloseStockDp } from '@/service/quotes.api'
+import { showConfirmDialog } from 'vant';
+import { useI18n } from 'vue-i18n'
+import { showToast } from 'vant'
+import { formatNumberWithComma } from '@/utils/utis';
+
+// 响应式数据
+const { t } = useI18n()
+const activeTab = ref('products')
+const activeSubTab = ref('position')
+const showTradeModal = ref(false)
+const selectedProduct = ref(null)
+const tradeQuantity = ref(1)
+const tradeType = ref('buy') // 'buy' or 'close'
+const startStr = {
+    submitted: t('submitted'),
+    position: t('持仓'),
+    failed: t('失败'),
+    closed: t('平仓')
+}
+
+// 产品数据
+const products = ref([])
+
+// 获取产品数据
+const getProducts = () => {
+    _getDpList().then(res => {
+        products.value = res.records
+    })
+}
+
+// 持仓数据
+const positions = ref([])
+
+// 历史数据
+const histories = ref([])
+
+// 获取历史数据
+const getHistories = () => {
+    _getDpHistories().then(res => {
+        histories.value = res.records
+    })
+}
+
+// 获取持仓数据
+const getOrderList = () => {
+    _getDpOrderList().then(res => {
+        positions.value = res.records
+    })
+}
+
+// 监听activeTab切换并调用接口
+watch([activeTab, activeSubTab], ([newTab, newSubTab]) => {
+    // 获取产品数据
+    if (newTab == 'products') {
+        getProducts()
+    }
+    // 获取历史数据
+    else if (newTab == 'records' && activeSubTab.value == 'history') {
+        getHistories()
+    }
+    // 获取持仓数据
+    else if (newTab == 'records' && activeSubTab.value == 'position') {
+        getOrderList()
+    }
+}, { immediate: true })
+
+// 方法
+// 打开下单弹窗
+const openTradeModal = (product, type = 'buy') => {
+    selectedProduct.value = product
+    tradeType.value = type
+    tradeQuantity.value = 1
+    showTradeModal.value = true
+}
+// 关闭下单弹窗
+const closeTradeModal = () => {
+    showTradeModal.value = false
+    selectedProduct.value = null
+    tradeQuantity.value = 1
+}
+// 确认下单
+const confirmTrade = async () => {
+    if (tradeType.value === 'buy') {
+        if (!tradeQuantity.value || tradeQuantity.value == 0) {
+            showToast(t('请输入数量'))
+            return
+        }
+        // 买入
+        const newPosition = {
+            dzId: selectedProduct.value.uuid,
+            num: tradeQuantity.value,
+        }
+        let res = await _buyStockDp(newPosition)
+        showToast(t('SuccessfulOperation'))
+    }
+    closeTradeModal()
+}
+// 平仓
+const closePosition = (row) => {
+    showConfirmDialog({
+        title: t('平仓提示'),
+        message: t('是否平仓?'),
+        confirmButtonText: t('确认'),
+        cancelButtonText: t('取消'),
+    }).then(async () => {
+        let res = await _getDzCloseStockDp({ id: row.uuid })
+        showToast(t('SuccessfulOperation'))
+        getOrderList()
+    }).catch(() => { });
+}
+
+</script>
+
+<style scoped>
+button {
+    /* font-size: ; */
+}
+
+.border,
+.border-t {
+    border-color: #ccc;
+}
+
+.cg {
+    color: greenyellow !important;
+}
+
+.sb {
+    color: red !important;
+}
+
+.pc {
+    color: #aaa;
+}
+
+.tj {
+    color: green;
+}
+
+.app-container {
+    width: 100%;
+    min-height: 812px;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+    margin: 0 auto;
+    font-size: 1.8rem;
+}
+
+.fixed-section {
+    flex-shrink: 0;
+}
+
+.content-flex {
+    flex: 1;
+    overflow-y: auto;
+    min-height: 0;
+}
+
+.hide-scrollbar::-webkit-scrollbar {
+    display: none;
+}
+
+.hide-scrollbar {
+    -ms-overflow-style: none;
+    scrollbar-width: none;
+}
+
+.app-page {
+    border: 1px solid #e2e8f0;
+    border-radius: 12px;
+    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
+}
+
+.tab-button.active {
+    background-color: rgba(239, 68, 68, 0.15);
+    color: #dc2626;
+    font-weight: 600;
+}
+
+.subtab-button.active {
+    background-color: rgba(239, 68, 68, 0.15);
+    color: #dc2626;
+    font-weight: 600;
+}
+
+/* 移动端适配 */
+@media (max-width: 768px) {
+    .app-container {
+        width: 100%;
+        height: 100vh;
+        border-radius: 0;
+    }
+
+    .app-page {
+        border-radius: 0;
+        box-shadow: none;
+    }
+}
+</style>
\ No newline at end of file

--
Gitblit v1.9.3