Explorar o código

Merge branch 'web3_transection'

# Conflicts:
#	src/router/index.js
#	src/views/HomeIndex.vue
Hexinkui hai 1 mes
pai
achega
4ebac83216
Modificáronse 60 ficheiros con 8183 adicións e 620 borrados
  1. 7 0
      package-lock.json
  2. 1 0
      package.json
  3. 1 1
      src/App.vue
  4. 6 0
      src/assets/icon/bitcoin/bt.svg
  5. 6 0
      src/assets/icon/bitcoin/feilv.svg
  6. 6 0
      src/assets/icon/bitcoin/guizhe.svg
  7. 6 0
      src/assets/icon/bitcoin/huazhuan.svg
  8. 6 0
      src/assets/icon/bitcoin/jiaoyi.svg
  9. 6 0
      src/assets/icon/bitcoin/jilu.svg
  10. 4 4
      src/assets/icon/bitcoin/jisuan.svg
  11. 6 0
      src/assets/icon/bitcoin/jisuanqi.svg
  12. 6 0
      src/assets/icon/bitcoin/jisuanqicaidan.svg
  13. 4 0
      src/assets/icon/bitcoin/lishidingdan.svg
  14. 111 0
      src/assets/icon/bitcoin/querenpin.svg
  15. 6 0
      src/assets/icon/bitcoin/shezhi.svg
  16. 7 0
      src/assets/icon/bitcoin/shijia.svg
  17. 1 0
      src/assets/icon/bitcoin/shijiazyzs.svg
  18. 33 0
      src/assets/icon/bitcoin/xialadaka.svg
  19. 2 0
      src/assets/icon/bitcoin/xianjia.svg
  20. 2 0
      src/assets/icon/bitcoin/xianjiak.svg
  21. 22 0
      src/assets/icon/bitcoin/xianjiazyzs.svg
  22. 57 0
      src/composables/useBodyScrollLock.js
  23. 129 0
      src/router/index.js
  24. 1 2
      src/views/HomeIndex.vue
  25. 497 0
      src/views/bitcoin/Calculator.vue
  26. 226 0
      src/views/bitcoin/CommonFunctionsPopup/CommonFunctionsPopup.vue
  27. 177 0
      src/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/TradeRules.vue
  28. 510 0
      src/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/TradeSettings.vue
  29. 171 0
      src/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/components/PositionMode.vue
  30. 132 0
      src/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/components/SelectionSheet.vue
  31. 194 0
      src/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/components/TradeNotificationPopup.vue
  32. 93 0
      src/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/components/TriggerValueSheet.vue
  33. 732 538
      src/views/bitcoin/Index.vue
  34. 176 0
      src/views/bitcoin/StatusComponent/ConfirmPing.vue
  35. 175 0
      src/views/bitcoin/StatusComponent/InsufficientBalance.vue
  36. 880 0
      src/views/bitcoin/TradeFutures.vue
  37. 113 0
      src/views/bitcoin/TradeLayout.vue
  38. 11 0
      src/views/bitcoin/TradeOptions.vue
  39. 118 0
      src/views/bitcoin/calculator/FundingRateReminder.vue
  40. 211 0
      src/views/bitcoin/calculator/LeverageSlider.vue
  41. 249 0
      src/views/bitcoin/components/ClosePositionSheet.vue
  42. 170 0
      src/views/bitcoin/components/FundingOptions.vue
  43. 1 0
      src/views/bitcoin/components/LeveragePopup.vue
  44. 289 0
      src/views/bitcoin/components/LimitOrderModal.vue
  45. 171 0
      src/views/bitcoin/components/MarginInfoSheet.vue
  46. 4 3
      src/views/bitcoin/components/OrderConfirmPopup.vue
  47. 3 1
      src/views/bitcoin/components/OrderTimeSheet.vue
  48. 165 0
      src/views/bitcoin/components/OrderType.vue
  49. 116 0
      src/views/bitcoin/components/ProfitAndLossPrompt.vue
  50. 10 1
      src/views/bitcoin/components/TakeProfitsTopLoss.vue
  51. 3 1
      src/views/bitcoin/components/TriggerPrice.vue
  52. 17 3
      src/views/bitcoin/components/position.vue
  53. 4 2
      src/views/bitcoin/components/priceLimit.vue
  54. 88 64
      src/views/bitcoin/components/sellOrder.vue
  55. 367 0
      src/views/bitcoin/lever/TradeMargin.vue
  56. 368 0
      src/views/bitcoin/lever/TradeSeconds.vue
  57. 272 0
      src/views/bitcoin/lever/components/ChooseThisCycle.vue
  58. 126 0
      src/views/bitcoin/lever/components/KLineChart.vue
  59. 483 0
      src/views/bitcoin/lever/components/MarketPriceAndPlan.vue
  60. 425 0
      src/views/bitcoin/lever/yii.vue

+ 7 - 0
package-lock.json

@@ -9,6 +9,7 @@
       "version": "0.1.0",
       "dependencies": {
         "axios": "^1.13.2",
+        "klinecharts": "^8.6.3",
         "vant": "^4.9.21",
         "vue": "^3.2.13",
         "vue-router": "^4.0.3",
@@ -4271,6 +4272,12 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/klinecharts": {
+      "version": "8.6.3",
+      "resolved": "https://registry.npmjs.org/klinecharts/-/klinecharts-8.6.3.tgz",
+      "integrity": "sha512-hGDtWiMNywEDneZFmt+vZ6tOYutCDWV5FPBcXcn7L8kGwe73Q5yJayk8UzP9pIQSBWyxswWIySKh/BVFA6GhuQ==",
+      "license": "Apache-2.0"
+    },
     "node_modules/klona": {
       "version": "2.0.6",
       "resolved": "https://registry.npmmirror.com/klona/-/klona-2.0.6.tgz",

+ 1 - 0
package.json

@@ -8,6 +8,7 @@
   },
   "dependencies": {
     "axios": "^1.13.2",
+    "klinecharts": "^8.6.3",
     "vant": "^4.9.21",
     "vue": "^3.2.13",
     "vue-router": "^4.0.3",

+ 1 - 1
src/App.vue

@@ -1,5 +1,5 @@
 <template>
-  <router-view />
+  <router-view/>
 </template>
 
 <style lang="less"></style>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6 - 0
src/assets/icon/bitcoin/bt.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6 - 0
src/assets/icon/bitcoin/feilv.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6 - 0
src/assets/icon/bitcoin/guizhe.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6 - 0
src/assets/icon/bitcoin/huazhuan.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6 - 0
src/assets/icon/bitcoin/jiaoyi.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6 - 0
src/assets/icon/bitcoin/jilu.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 4 - 4
src/assets/icon/bitcoin/jisuan.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6 - 0
src/assets/icon/bitcoin/jisuanqi.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6 - 0
src/assets/icon/bitcoin/jisuanqicaidan.svg


+ 4 - 0
src/assets/icon/bitcoin/lishidingdan.svg

@@ -0,0 +1,4 @@
+<svg width="27" height="14" viewBox="0 0 27 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="1" height="14" fill="#979797"/>
+<path d="M25.9167 0H15.0833C14.796 0 14.5205 0.114136 14.3173 0.317301C14.1141 0.520465 14 0.796015 14 1.08333V11.9167C14 12.204 14.1141 12.4795 14.3173 12.6827C14.5205 12.8859 14.796 13 15.0833 13H22.4425C22.5849 13.0004 22.7259 12.9726 22.8573 12.9181C22.9888 12.8636 23.1081 12.7835 23.2083 12.6824L26.6824 9.20833C26.7835 9.1081 26.8636 8.98878 26.9181 8.85732C26.9726 8.72585 27.0004 8.58487 27 8.44255V1.08333C27 0.796015 26.8859 0.520465 26.6827 0.317301C26.4795 0.114136 26.204 0 25.9167 0ZM15.0833 1.08333H25.9167V8.125H22.6667C22.523 8.125 22.3852 8.18207 22.2836 8.28365C22.1821 8.38523 22.125 8.523 22.125 8.66666V11.9167H15.0833V1.08333ZM25.1509 9.20833L23.2083 11.1509V9.20833H25.1509Z" fill="#979797"/>
+</svg>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 111 - 0
src/assets/icon/bitcoin/querenpin.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6 - 0
src/assets/icon/bitcoin/shezhi.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 7 - 0
src/assets/icon/bitcoin/shijia.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 0
src/assets/icon/bitcoin/shijiazyzs.svg


+ 33 - 0
src/assets/icon/bitcoin/xialadaka.svg

@@ -0,0 +1,33 @@
+<svg width="79" height="99" viewBox="0 0 79 99" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect x="48" y="39" width="31" height="60" rx="6" fill="#F5F5F5"/>
+<rect y="39" width="46" height="42" rx="6" fill="#F5F5F5"/>
+<rect y="83" width="46" height="7" rx="3.5" fill="#45B26B"/>
+<rect y="92" width="46" height="7" rx="3.5" fill="#DF384C"/>
+<rect width="79" height="36" rx="6" fill="#F5F5F5"/>
+<rect x="8.77344" y="15.2587" width="0.516132" height="13.8754" rx="0.258066" fill="#45B26B"/>
+<rect x="8" y="17.1088" width="2.06453" height="10.1753" rx="1.03226" fill="#45B26B"/>
+<rect x="14.1934" y="10.6335" width="0.516132" height="8.63359" rx="0.258066" fill="#DF384C"/>
+<rect x="13.4199" y="12.792" width="2.06453" height="4.62514" rx="1.03226" fill="#DF384C"/>
+<rect x="39.7422" y="8.78357" width="0.516132" height="7.09187" rx="0.258066" fill="#DF384C"/>
+<rect x="38.9688" y="10.0168" width="2.06453" height="3.23759" rx="1.03226" fill="#DF384C"/>
+<rect x="44.9023" y="2" width="0.516132" height="11.5628" rx="0.258066" fill="#45B26B"/>
+<rect x="44.1289" y="6.1626" width="2.06453" height="3.08342" rx="1.03226" fill="#45B26B"/>
+<rect x="65.5488" y="22.0422" width="0.516132" height="8.63359" rx="0.258066" fill="#DF384C"/>
+<rect x="64.7734" y="24.2007" width="2.06453" height="4.62514" rx="1.03226" fill="#DF384C"/>
+<rect x="70.7109" y="18.188" width="0.516132" height="5.70433" rx="0.258066" fill="#45B26B"/>
+<rect x="69.9355" y="19.5754" width="2.06453" height="3.08342" rx="1.03226" fill="#45B26B"/>
+<rect x="19.0977" y="18.8047" width="0.516132" height="6.9377" rx="0.258066" fill="#45B26B"/>
+<rect x="18.3223" y="20.6547" width="2.06453" height="3.23759" rx="1.03226" fill="#45B26B"/>
+<rect x="60.3867" y="18.8047" width="0.516132" height="11.4087" rx="0.258066" fill="#DF384C"/>
+<rect x="59.6133" y="19.5754" width="2.06453" height="5.24182" rx="1.03226" fill="#DF384C"/>
+<rect x="34.8398" y="11.8668" width="0.516132" height="6.9377" rx="0.258066" fill="#45B26B"/>
+<rect x="34.0645" y="13.7169" width="2.06453" height="3.23759" rx="1.03226" fill="#45B26B"/>
+<rect x="50.0645" y="7.55005" width="0.516132" height="6.9377" rx="0.258066" fill="#DF384C"/>
+<rect x="49.291" y="9.40027" width="2.06453" height="4.00845" rx="1.03226" fill="#DF384C"/>
+<rect x="24.2598" y="24.8174" width="0.516132" height="9.55861" rx="0.258066" fill="#DF384C"/>
+<rect x="23.4844" y="26.6672" width="2.06453" height="5.39599" rx="1.03226" fill="#DF384C"/>
+<rect x="29.4199" y="14.4878" width="0.516132" height="11.2545" rx="0.258066" fill="#45B26B"/>
+<rect x="28.6465" y="16.4919" width="2.06453" height="7.86273" rx="1.03226" fill="#45B26B"/>
+<rect x="55.4844" y="11.2502" width="0.516132" height="11.2545" rx="0.258066" fill="#45B26B"/>
+<rect x="54.7109" y="13.2544" width="2.06453" height="7.86273" rx="1.03226" fill="#45B26B"/>
+</svg>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2 - 0
src/assets/icon/bitcoin/xianjia.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 2 - 0
src/assets/icon/bitcoin/xianjiak.svg


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 22 - 0
src/assets/icon/bitcoin/xianjiazyzs.svg


+ 57 - 0
src/composables/useBodyScrollLock.js

@@ -0,0 +1,57 @@
+/*// src/composables/useBodyScrollLock.js*/
+import { watch, onUnmounted, onActivated, onDeactivated } from 'vue'
+
+// 全局变量
+let lockCount = 0
+let scrollTop = 0 // 记录页面滚动到了哪里
+
+export function useBodyScrollLock(visibleRef) {
+
+  const lock = () => {
+    lockCount++
+    if (lockCount === 1) {
+      // 1. 记住当前滚到了哪里
+      scrollTop = window.scrollY || document.documentElement.scrollTop
+
+      // 2. 把 body 变成 fixed,强制钉在当前位置
+      // 这样浏览器想滚也滚不动了,物理锁死
+      document.body.style.position = 'fixed'
+      document.body.style.top = `-${scrollTop}px`
+      document.body.style.width = '100%'
+      document.body.style.overflow = 'hidden'
+    }
+  }
+
+  const unlock = () => {
+    if (lockCount > 0) lockCount--
+    if (lockCount === 0) {
+      // 3. 恢复原样
+      document.body.style.position = ''
+      document.body.style.top = ''
+      document.body.style.width = ''
+      document.body.style.overflow = ''
+
+      // 4. 瞬间滚回刚才的位置(无缝衔接)
+      window.scrollTo(0, scrollTop)
+    }
+  }
+
+  // 监听变化
+  watch(visibleRef, (val) => {
+    if (val) lock()
+    else unlock()
+  }, { immediate: true })
+
+  // 清理逻辑
+  onUnmounted(() => {
+    if (visibleRef.value) unlock()
+  })
+
+  onActivated(() => {
+    if (visibleRef.value) lock()
+  })
+
+  onDeactivated(() => {
+    if (visibleRef.value) unlock()
+  })
+}

+ 129 - 0
src/router/index.js

@@ -30,6 +30,16 @@ import RechargeChangeCoin from "../views/index/recharge/ChangeCoin.vue";
 import Transfer from "../views/index/recharge/Transfer.vue";
 import TransferHistory from "../views/index/recharge/TransferHistory.vue";
 import UserAsset from "../views/asset/UserAsset.vue";
+import TradeLayout from '@/views/bitcoin/TradeLayout.vue'; // 新建的公共父组件
+import TradeFutures from '@/views/bitcoin/TradeFutures.vue'; // (合约)
+import TradeSeconds from '@/views/bitcoin/lever/TradeSeconds.vue'; // 秒合约(占位)
+import TradeOptions from '@/views/bitcoin/TradeOptions.vue'; // 期权(占位)
+import TradeMargin from '@/views/bitcoin/lever/TradeMargin.vue';
+import Calculator from '../views/bitcoin/Calculator.vue' // 新建的计算器页面
+import CommonFunctionsPopup from '@/views/bitcoin/CommonFunctionsPopup/CommonFunctionsPopup.vue' // 子组件路径
+import TradeSettings from '@/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/TradeSettings.vue'// 新建
+import TradeRules from '@/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/TradeRules.vue'       // 新建
+
 
 const routes = [
   {
@@ -189,6 +199,125 @@ const routes = [
     name: "userAsset",
     component: UserAsset,
   },
+    {
+        path: "/",
+        name: "home",
+        component: HomeIndex,
+    },
+    {
+    path: "/bitcoin",
+    component: TradeLayout, // 而是布局组件
+    // 当访问 /bitcoin 时,自动重定向到 /bitcoin/contract
+    redirect: '/bitcoin/contract',
+    children: [
+      // 1. 核心交易子路由
+      {
+        path: 'contract',
+        name: 'TradeContract',
+        component: TradeFutures, // 核心交易逻辑
+        meta: { title: '合约' }
+      },
+      {
+        path: 'seconds',
+        name: 'TradeSeconds',
+        component: TradeSeconds,
+        meta: { title: '秒合约' }
+      },
+      {
+        path: 'options',
+        name: 'TradeOptions',
+        component: TradeOptions,
+        meta: { title: '期权' }
+      },
+      {
+        path: 'margin',
+        name: 'TradeMargin',
+        component: TradeMargin,
+        meta: { title: '杠杆' }
+      },
+      { path: 'settings',
+        name: 'TradeSettings',
+        component: TradeSettings },
+      { path: 'calculator',
+        name: 'calculator',
+        component: Calculator },
+     ]
+    },
+    {
+        path: "/applyPermission",
+        name: "applyPermission",
+        component: ApplyPermission,
+    },
+    {
+        path: "/splashScreen",
+        name: "splashScreen",
+        component: SplashScreen,
+    },
+    {
+        path: "/riskTips",
+        name: "riskTips",
+        component: RiskTips,
+    },
+    {
+        path: "/searchIcon",
+        name: "searchIcon",
+        component: SearchIcon,
+    },
+    {
+        path: "/notification",
+        name: "notification",
+        component: Notification,
+    },
+    {
+        path: "/indexUser",
+        name: "indexUser",
+        component: IndexUser,
+    },
+    {
+        path: "/userCenter",
+        name: "userCenter",
+        component: UserCenter,
+    },
+    {
+        path: "/marketDetails",
+        name: "marketDetails",
+        component: MarketDetails,
+    },
+    {
+        path: "/historyIndex",
+        name: "historyIndex",
+        component: HistoryIndex,
+    },
+    {
+        path: "/entrustDetails",
+        name: "entrustDetails",
+        component: EntrustDetails,
+    },
+    {
+        path: "/positionDetails",
+        name: "positionDetails",
+        component: PositionDetails,
+    },
+    {
+        path: "/icoIndex",
+        name: "icoIndex",
+        component: IcoIndex,
+    },
+    {
+        path: "/loanIndex",
+        name: "loanIndex",
+        component: LoanIndex,
+    },
+    {
+        path: "/loanRules",
+        name: "loanRules",
+        component: LoanRules,
+    },
+    {
+        path: "/userLoanIndex",
+        name: "userLoanIndex",
+        component: UserLoanIndex,
+    },
 ];
 
 const router = createRouter({

+ 1 - 2
src/views/HomeIndex.vue

@@ -6,7 +6,7 @@
         class="tabbar-item"
         v-for="(item, index) in tabbarList"
         :key="index"
-        @click="tabbarChange(item.key, item.path)">
+        @click="tabbarChange(item.key)">
         <img
           class="item-image"
           :src="current === item.key ? item.selectedImage : item.image"
@@ -62,7 +62,6 @@
     },
     {
       key: "user",
-      path: "/userIndex",
       image: require("@/assets/icon/tabbar/user-circle.png"),
       selectedImage: require("@/assets/icon/tabbar/user-circle.png"),
       text: "我的",

+ 497 - 0
src/views/bitcoin/Calculator.vue

@@ -0,0 +1,497 @@
+<template>
+  <div class="calculator-page">
+    <div class="nav-bar">
+      <div class="nav-left" @click="$router.back()">
+        <div>
+          <VanIcon size="18" name="arrow-left"/>
+        </div>
+      </div>
+      <div class="nav-title">计算器</div>
+      <div class="nav-right"></div>
+    </div>
+
+    <div class="header-info">
+      <div class="icon-wrapper">
+        <vanIcon size="20" name="bars" />
+      </div>
+      <h2 class="pair-name">BTCUSDT 永续</h2>
+    </div>
+
+    <div class="tabs-wrapper">
+      <div class="tabs-content pf600">
+        <div
+          v-for="(tab, index) in tabs"
+          :key="index"
+          class="tab-item"
+          :class="{ active: currentTab === index }"
+          @click="currentTab = index"
+        >
+          {{ tab }}
+          <div class="active-bar" v-if="currentTab === index"></div>
+        </div>
+      </div>
+    </div>
+
+    <div v-if="currentTab === 2" class="mode-selectors">
+      <div class="select-box">全仓 ▾</div>
+      <div class="select-box">单向持仓</div>
+    </div>
+
+    <div class="trade-direction">
+      <button
+        class="dir-btn long"
+        :class="{ active: direction === 'long' }"
+        @click="direction = 'long'"
+      >
+        买入(做多)
+      </button>
+      <button
+        class="dir-btn short"
+        :class="{ active: direction === 'short' }"
+        @click="direction = 'short'"
+      >
+        卖出(做空)
+      </button>
+    </div>
+
+    <div v-if="currentTab === 5" class="funding-rate-display">
+      <div class="rate-value">0.0030%</div>
+      <div class="rate-label" @click="showModal=true">当前资金费率
+        <VanIcon name="question-o" />
+      </div>
+    </div>
+
+    <div v-if="currentTab !== 4 && currentTab !== 5" class="leverage-section">
+      <div class="label">倍数</div>
+
+      <div class="leverage-control">
+        <button class="ctrl-btn" @click="stepLeverage(-1)">-</button>
+        <div class="leverage-val">{{ leverage }}x</div>
+        <button class="ctrl-btn" @click="stepLeverage(1)">+</button>
+      </div>
+
+      <div class="slider-area">
+        <LeverageSlider
+          v-model="leverage"
+          :marks="leverageMarks"
+          :color="themeColor"
+        />
+      </div>
+
+      <div class="leverage-tip">
+        当前杠杆倍数最高可持有头寸 1,800,000,000 USDT
+      </div>
+    </div>
+
+    <div class="form-group">
+      <div v-if="currentTab !== 4 && currentTab !== 5" class="input-row">
+        <div class="input-container">
+          <span class="placeholder" v-show="!form.entryPrice">开仓价格</span>
+          <input type="number" v-model="form.entryPrice" />
+          <div class="suffix">USDT <span class="tag-latest">最新</span></div>
+        </div>
+      </div>
+
+      <template v-if="currentTab === 0">
+        <div class="input-row">
+          <div class="input-container">
+            <span class="placeholder" v-show="!form.closePrice">平仓价格</span>
+            <input type="number" v-model="form.closePrice" />
+            <div class="suffix">USDT</div>
+          </div>
+        </div>
+        <div class="input-row">
+          <div class="input-container">
+            <span class="placeholder" v-show="!form.amount">成交数量</span>
+            <input type="number" v-model="form.amount" />
+            <div class="suffix">BTC</div>
+          </div>
+        </div>
+      </template>
+
+      <template v-if="currentTab === 1">
+        <div class="input-row">
+          <div class="input-container">
+            <span class="placeholder" v-show="!form.amount">成交数量</span>
+            <input type="number" v-model="form.amount" />
+            <div class="suffix">BTC</div>
+          </div>
+        </div>
+        <div class="input-row">
+          <div class="input-container">
+            <span class="placeholder" v-show="!form.pnl">预期收益额</span>
+            <input type="number" v-model="form.pnl" />
+            <div class="suffix">USDT</div>
+          </div>
+        </div>
+      </template>
+
+      <template v-if="currentTab === 2">
+        <div class="input-row">
+          <div class="input-container">
+            <span class="placeholder" v-show="!form.amount">开仓数量</span>
+            <input type="number" v-model="form.amount" />
+            <div class="suffix">BTC</div>
+          </div>
+        </div>
+        <div class="input-row">
+          <div class="input-container">
+            <span class="placeholder" v-show="!form.margin">保证金</span>
+            <input type="number" v-model="form.margin" />
+            <div class="suffix">USDT</div>
+          </div>
+        </div>
+      </template>
+
+      <template v-if="currentTab === 3">
+        <div class="input-row">
+          <div class="input-container">
+            <span class="placeholder" v-show="!form.balance">账户余额</span>
+            <input type="number" v-model="form.balance" />
+            <div class="suffix">USDT</div>
+          </div>
+        </div>
+      </template>
+
+      <template v-if="currentTab === 4">
+        <div class="grid-header">
+          <span>开仓价格(USDT)</span>
+          <span>成交数量(BTC)</span>
+        </div>
+        <div class="dynamic-row" v-for="(item, idx) in avgPriceList" :key="idx">
+          <div class="input-container half">
+            <input type="number" v-model="item.price" placeholder="0.00" />
+          </div>
+          <div class="input-container half">
+            <input type="number" v-model="item.amount" placeholder="0.00" />
+          </div>
+          <div style="display: flex; align-items: center;">
+            <div class="remove-btn" @click="removeRow(idx)" v-if="avgPriceList.length > 1">
+              <span>-</span>
+            </div>
+          </div>
+        </div>
+        <button class="add-position-btn" @click="addRow">增加仓位</button>
+      </template>
+
+      <template v-if="currentTab === 5">
+        <div class="input-row">
+          <div class="input-container">
+            <span class="placeholder" v-show="!form.entryPrice">标记价格</span>
+            <input type="number" v-model="form.entryPrice" />
+            <div class="suffix">USDT <span class="tag-latest">最新</span></div>
+          </div>
+        </div>
+        <div class="input-row">
+          <div class="input-container">
+            <span class="placeholder" v-show="!form.amount">持仓数量</span>
+            <input type="number" v-model="form.amount" />
+            <div class="suffix">BTC</div>
+          </div>
+        </div>
+      </template>
+    </div>
+
+    <div class="result-section">
+      <h3>计算结果</h3>
+      <p class="sub-text">实际市场存在变动,计算价格仅供参考</p>
+
+      <div v-if="currentTab === 0">
+        <div class="res-row"><span>保证金</span><span>{{ result.margin }} USDT</span></div>
+        <div class="res-row"><span>收益</span><span :class="resultClass">{{ result.pnl }} USDT</span></div>
+        <div class="res-row"><span>收益率</span><span :class="resultClass">{{ result.roe }}%</span></div>
+      </div>
+
+      <div v-if="currentTab === 1">
+        <div class="res-row"><span>目标价格</span><span>-- USDT</span></div>
+      </div>
+
+      <div v-if="currentTab === 2">
+        <div class="res-row"><span>强平价格</span><span>-- USDT</span></div>
+      </div>
+
+      <div v-if="currentTab === 3">
+        <div class="res-row"><span>可开</span><span>-- USDT</span></div>
+        <div class="res-row"><span>可开</span><span>-- BTC</span></div>
+        <p class="small-tip">此计算最大可开数量时,将不考虑您的开仓损失</p>
+      </div>
+
+      <div v-if="currentTab === 4">
+        <div class="res-row"><span>开仓均价</span><span>-- USDT</span></div>
+      </div>
+
+      <div v-if="currentTab === 5">
+        <div class="res-row"><span>资金费用</span><span>-- USDT</span></div>
+      </div>
+    </div>
+
+    <div class="footer-btns">
+      <button class="btn-reset" @click="reset">重置</button>
+      <button class="btn-calc" :style="{ background: themeColor }" @click="calculate">计算</button>
+    </div>
+    <div>
+      <ProfitAndLossPrompt
+          v-model:visible="showModal"
+      ></ProfitAndLossPrompt>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { Icon as VanIcon } from 'vant';
+import {ref, computed, defineAsyncComponent} from 'vue';
+// 请确保路径正确,指向刚才那个更新过的子组件
+const LeverageSlider = defineAsyncComponent(()=>import('./calculator/LeverageSlider.vue'));
+const ProfitAndLossPrompt = defineAsyncComponent(() => import('./calculator/FundingRateReminder.vue'));
+
+//资金费率提示
+const showModal = ref(false);
+
+
+// 状态定义
+const tabs = ['收益', '目标价格', '强平价格', '可开', '开仓均价', '资金费用'];
+const currentTab = ref(0);
+const direction = ref('long');
+const leverage = ref(10); // 默认从 10x 开始
+
+// ★ 固定阶梯数组 (10, 50, 100, 500, 1000)
+const leverageMarks = [10, 50, 100, 500, 1000];
+
+const form = ref({
+  entryPrice: '',
+  closePrice: '',
+  amount: '',
+  margin: '',
+  balance: '',
+  pnl: ''
+});
+
+const avgPriceList = ref([{ price: '', amount: '' }, { price: '', amount: '' }]);
+const result = ref({ margin: '--', pnl: '--', roe: '--' });
+
+// 计算属性
+const themeColor = computed(() => direction.value === 'long' ? '#2ebd85' : '#f6465d');
+const resultClass = computed(() => {
+  if (parseFloat(result.value.pnl) > 0) return 'text-green';
+  if (parseFloat(result.value.pnl) < 0) return 'text-red';
+  return '';
+});
+
+// ★ 核心修改:步进式调整杠杆 (点击加减号时)
+const stepLeverage = (dir) => {
+  // 1. 找到当前值在数组中的索引
+  let currentIndex = leverageMarks.indexOf(leverage.value);
+
+  // 如果当前值不在数组里(比如手动改成了20),就找一个最近的索引
+  if (currentIndex === -1) {
+    // 简单逻辑:默认归位到 0
+    currentIndex = 0;
+  }
+
+  // 2. 计算下一个索引
+  let nextIndex = currentIndex + dir;
+
+  // 3. 边界限制
+  if (nextIndex < 0) nextIndex = 0;
+  if (nextIndex >= leverageMarks.length) nextIndex = leverageMarks.length - 1;
+
+  // 4. 更新值
+  leverage.value = leverageMarks[nextIndex];
+};
+
+// 简单计算逻辑 (Tab 0 收益)
+const calculate = () => {
+  if (currentTab.value === 0) {
+    const entry = parseFloat(form.value.entryPrice);
+    const close = parseFloat(form.value.closePrice);
+    const amt = parseFloat(form.value.amount);
+    const lev = leverage.value;
+
+    if (entry && close && amt && lev) {
+      const margin = (entry * amt) / lev;
+      let pnl = 0;
+      if (direction.value === 'long') {
+        pnl = (close - entry) * amt;
+      } else {
+        pnl = (entry - close) * amt;
+      }
+      const roe = (pnl / margin) * 100;
+
+      result.value = {
+        margin: margin.toFixed(2),
+        pnl: pnl.toFixed(2),
+        roe: roe.toFixed(2)
+      };
+    }
+  }
+};
+
+// 其他辅助函数
+const addRow = () => avgPriceList.value.push({ price: '', amount: '' });
+const removeRow = (idx) => avgPriceList.value.splice(idx, 1);
+const reset = () => {
+  form.value = { entryPrice: '', closePrice: '', amount: '', margin: '', balance: '', pnl: '' };
+  result.value = { margin: '--', pnl: '--', roe: '--' };
+  leverage.value = 10;
+};
+</script>
+
+<style scoped>
+* {
+  box-sizing: border-box;
+}
+
+.calculator-page {
+  font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', sans-serif;
+  background: #fff;
+  min-height: 100vh;
+  padding-bottom: 90px;
+  color: #333;
+  z-index: 200;
+  position: fixed;       /* 固定定位 */
+  top: 0;
+  left: 0;
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+}
+
+/* 导航 & 头部 */
+.nav-bar { display: flex; justify-content: space-between; align-items: center;
+  height: 44px; padding: 0 16px; }
+.nav-left { font-size: 24px; cursor: pointer; }
+.nav-title { font-size: 18px; font-weight: 600; }
+.nav-right { width: 20px; }
+
+.header-info {
+  display: flex;
+  align-items: center;
+  padding: 8px 12px;
+  background-color: #fff;
+  width: 100%;
+}
+
+.icon-wrapper {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 24px;
+  height: 24px;
+  margin-bottom: 1px;
+}
+
+.pair-name {
+  margin: 0;
+  font-size: 18px;
+  font-weight: bold;
+  color: #333;
+  line-height: 1;
+}
+
+/* Tabs */
+.tabs-wrapper { overflow-x: auto; scrollbar-width: none; margin-bottom: 15px; }
+.tabs-content { display: flex; justify-content: space-between; padding: 0 15px;
+  border-bottom: 1px solid #f5f5f5; }
+.tab-item { white-space: nowrap; padding: 12px 0; font-size: 14px; color: #999; position: relative;
+  cursor: pointer; }
+.tab-item.active { color: #111; font-weight: 600; }
+.active-bar { position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); width: 20px;
+  height: 3px; background: #111; border-radius: 2px; }
+
+/* 模式选择 */
+.mode-selectors { display: flex; gap: 10px; padding: 0 16px; margin-bottom: 15px; }
+.select-box { flex: 1; background: #f5f5f5; height: 36px; display: flex; align-items: center;
+  padding: 0 12px; border-radius: 4px; font-size: 14px; color: #333; }
+
+/* 做多做空 */
+.trade-direction { display: flex; gap: 10px; padding: 0 16px; margin-bottom: 20px; }
+.dir-btn { flex: 1; padding: 10px 0; border: none; border-radius: 4px; font-size: 14px;
+  cursor: pointer; background: #f5f5f5; color: #999; transition: all 0.2s; }
+.dir-btn.long.active { background: #2ebd85; color: #fff; font-weight: 600; }
+.dir-btn.short.active { background: #f6465d; color: #fff; font-weight: 600; }
+
+/* 资金费率 */
+.funding-rate-display { text-align: center; padding: 20px 0; }
+.rate-value { font-size: 32px; color: #666; font-weight: 500; }
+.rate-label { font-size: 12px; color: #999; margin-top: 5px; }
+
+/* 杠杆区域 */
+.leverage-section { padding: 0 16px; margin-bottom: 20px; }
+.label { font-size: 12px; color: #666; margin-bottom: 8px; }
+
+/* 蓝色边框输入框 */
+.leverage-control {
+  display: flex;
+  align-items: center;
+  background: #f7f8fa;
+  border-radius: 6px;
+  height: 44px;
+  margin-bottom: 10px;
+  overflow: hidden;
+}
+.ctrl-btn {
+  width: 50px;
+  height: 100%;
+  border: none;
+  background: transparent;
+  font-size: 22px;
+  color: #999;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding-bottom: 4px;
+}
+.leverage-val {
+  flex: 1;
+  text-align: center;
+  font-size: 16px;
+  font-weight: 500;
+  color: #333;
+}
+.slider-area { padding: 0 10px; }
+.leverage-tip { font-size: 12px; color: #333; margin-top: 10px; }
+
+/* 表单 */
+.form-group { padding: 0 16px; }
+.input-row { margin-bottom: 12px; }
+.input-container { position: relative; display: flex; align-items: center; background: #f5f5f5;
+  height: 44px; border-radius: 4px; padding: 0 12px; }
+.placeholder { position: absolute; color: #bbb; font-size: 14px; pointer-events: none; }
+.input-container input { flex: 1; border: none; background: transparent; outline: none;
+  font-size: 14px; z-index: 1; height: 100%; width: 100%; }
+.suffix { font-size: 14px; color: #666; margin-left: 8px; z-index: 2; white-space: nowrap; }
+.tag-latest { color: #f6465d; margin-left: 4px; }
+
+/* 表格布局 */
+.grid-header { display: flex; font-size: 12px; color: #333; margin-bottom: 8px; }
+.grid-header span { flex: 1; }
+.dynamic-row { display: flex; gap: 10px; margin-bottom: 10px; align-items: center; }
+.input-container.half { flex: 1; }
+.remove-btn { width: 24px; height: 24px; border: 1px solid #f6465d; color: #f6465d;
+  border-radius: 50%; display: flex; align-items: center; justify-content: center;
+  font-size: 18px; cursor: pointer; margin-left: 5px; }
+.remove-btn span { margin-bottom: 5px; }
+.add-position-btn { width: 100%; height: 44px; background: #f6465d; color: white;
+  border: none; border-radius: 22px; margin-top: 10px; font-size: 14px; }
+
+/* 结果 */
+.result-section { padding: 20px 16px; }
+.result-section h3 { margin: 0 0 5px; font-size: 16px; font-weight: 600; }
+.sub-text { font-size: 12px; color: #999; margin-bottom: 15px; }
+.res-row { display: flex; justify-content: space-between; margin-bottom: 12px; font-size: 14px; }
+.res-row span:first-child { color: #666; }
+.res-row span:last-child { color: #333; font-weight: 500; }
+.text-green { color: #2ebd85; }
+.text-red { color: #f6465d; }
+.small-tip { font-size: 12px; color: #999; margin-top: 5px; }
+
+/* 底部按钮 */
+.footer-btns { position: fixed; bottom: 0; left: 0; width: 100%; background: #fff;
+  padding: 10px 16px 20px; display: flex; gap: 15px; box-shadow: 0 -2px 10px rgba(0,0,0,0.05);
+  box-sizing: border-box; z-index: 100; }
+.btn-reset { flex: 1; height: 44px; border: none; background: #bbb; color: #fff;
+  font-size: 16px; border-radius: 4px; }
+.btn-calc { flex: 2; height: 44px; border: none; color: #fff; font-size: 16px;
+  border-radius: 4px; font-weight: 600; transition: background 0.3s; }
+</style>

+ 226 - 0
src/views/bitcoin/CommonFunctionsPopup/CommonFunctionsPopup.vue

@@ -0,0 +1,226 @@
+<template>
+  <!-- Teleport 确保弹窗挂载到 body,层级最高 -->
+  <Teleport to="body">
+    <!-- 1. 遮罩层 -->
+    <Transition name="fade">
+      <div v-if="visible" class="modal-mask" @click="handleClose"></div>
+    </Transition>
+
+    <!-- 2. 弹窗面板 -->
+    <Transition name="slide-up">
+      <div v-if="visible" class="modal-panel" @click.stop>
+
+        <!-- 顶部小横条 -->
+        <div class="panel-handle-wrap">
+          <div class="panel-handle"></div>
+        </div>
+
+        <div class="panel-title">常用功能</div>
+
+        <!-- 九宫格菜单 -->
+        <div class="grid-container">
+          <div
+            v-for="(item, index) in menuItems"
+            :key="index"
+            class="grid-item"
+            @click="handleItemClick(item)"
+          >
+            <div class="icon-box">
+              <img
+                :src="getIconPath(item.icon)"
+                class="grid-icon-img"
+                loading="lazy"
+              />
+            </div>
+            <span class="label">{{ item.name }}</span>
+          </div>
+        </div>
+
+        <div class="safe-area-bottom"></div>
+      </div>
+    </Transition>
+    <TradeRules
+    v-model:visible="showRules"
+    />
+  </Teleport>
+</template>
+
+<script setup>
+import {toRef, watch} from 'vue'
+import { useRouter } from 'vue-router'
+import { ref, defineAsyncComponent } from 'vue';
+// 引入
+import TradeRules from  './GeneralLevel2/TradeRules.vue';
+import { useBodyScrollLock } from '@/composables/useBodyScrollLock' // 2. 引入 Hook
+
+// 控制显示的变量
+const showRules = ref(false);
+
+// 1. 接收父组件 (TradeLayout) 传来的 visible 状态
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    default: false
+  }
+})
+useBodyScrollLock(toRef(props, 'visible'))
+// 2. 定义事件,用于通知父组件修改 visible
+const emit = defineEmits(['update:visible'])
+
+const router = useRouter()
+
+// --- 关闭逻辑 ---
+const handleClose = () => {
+  // 通知父组件把 visible 设为 false
+  // 这样 TradeLayout 里的 showFunctions 就会变成 false
+  emit('update:visible', false)
+}
+
+// --- 点击菜单项逻辑 ---
+const handleItemClick = (item) => {
+  // 1. 先关闭弹窗
+  // handleClose()
+
+  // 2. 再跳转路由
+  // 注意:根据我们定好的路由表,这里跳转会离开 TradeLayout,
+  // 进入全屏的设置页/计算器页,这是符合预期的。
+  setTimeout(() => {
+    if (item.name === '交易设置') {
+      router.push({ name: 'TradeSettings' })
+    } else if (item.name === '交易规则') {
+      showRules.value = true
+    } else if (item.name === '计算器') {
+      router.push({ name: 'calculator' })
+    } else {
+      console.log('点击了其他:', item.name)
+    }
+  }, 200) // 稍微延迟一点点,让关闭动画看起来更自然(可选)
+}
+
+// --- 图标加载 ---
+const getIconPath = (iconName) => {
+  try {
+    return require(`../../../assets/icon/bitcoin/${iconName}`)
+  } catch (e) {
+    return ''
+  }
+}
+
+const menuItems = [
+  { name: '交易设置', icon: 'shezhi.svg' },
+  { name: '交易记录', icon: 'jilu.svg' },
+  { name: '计算器', icon: 'jisuan.svg' },
+  { name: '费率', icon: 'feilv.svg' },
+  { name: '资金划转', icon: 'huazhuan.svg' },
+  { name: 'OTC交易', icon: 'jiaoyi.svg' },
+  { name: '交易规则', icon: 'guizhe.svg' },
+]
+</script>
+
+<style scoped>
+/* 遮罩层 */
+.modal-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  height: 100vh;
+  background-color: rgba(0, 0, 0, 0.5);
+  z-index: 199; /* 保证层级够高 */
+}
+
+/* 弹窗面板 */
+.modal-panel {
+  position: fixed;
+  bottom: 0;
+  left: 50%;
+  transform: translateX(-50%);
+  width: 100%;
+  max-width: 600px; /* 限制最大宽度,适配桌面端 */
+  background: white;
+  border-radius: 16px 16px 0 0;
+  padding: 10px 0 0 0;
+  z-index: 200; /* 比遮罩层高 */
+}
+
+/* 把手装饰 */
+.panel-handle-wrap {
+  display: flex;
+  justify-content: center;
+  padding-bottom: 20px;
+}
+.panel-handle {
+  width: 36px;
+  height: 4px;
+  background: #E0E0E0;
+  border-radius: 2px;
+}
+
+/* 标题 */
+.panel-title {
+  font-size: 18px;
+  font-weight: bold;
+  color: #333;
+  padding: 0 20px 20px 20px;
+}
+
+/* 底部安全区适配 */
+.safe-area-bottom {
+  height: 30px;
+  padding-bottom: env(safe-area-inset-bottom);
+}
+
+/* --- 动画相关 --- */
+/* 淡入淡出 */
+.fade-enter-active, .fade-leave-active {
+  transition: opacity 0.3s ease;
+}
+.fade-enter-from, .fade-leave-to {
+  opacity: 0;
+}
+
+/* 底部滑入滑出 */
+.slide-up-enter-active, .slide-up-leave-active {
+  transition: transform 0.3s ease;
+}
+.slide-up-enter-from, .slide-up-leave-to {
+  transform: translate(-50%, 100%);
+}
+
+/* --- Grid 布局 --- */
+.grid-container {
+  display: grid;
+  grid-template-columns: repeat(4, 1fr);
+  row-gap: 25px;
+  padding: 0 10px 20px 10px;
+}
+.grid-item {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  cursor: pointer;
+  /* 添加点击反馈效果 */
+  active {
+    opacity: 0.7;
+  }
+}
+.icon-box {
+  width: 40px;
+  height: 40px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-bottom: 8px;
+}
+.grid-icon-img {
+  width: 100%;
+  height: 100%;
+  object-fit: contain;
+  display: block;
+}
+.label {
+  font-size: 12px;
+  color: #666;
+  text-align: center;
+}
+</style>

+ 177 - 0
src/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/TradeRules.vue

@@ -0,0 +1,177 @@
+<template>
+  <!-- Teleport 保证弹窗挂载到 body,层级最高 -->
+  <Teleport to="body">
+
+    <!-- 1. 遮罩层 (增加淡入淡出动画) -->
+    <Transition name="fade">
+      <div
+        v-if="visible"
+        class="mask-level-2"
+        @click="handleClose"
+      ></div>
+    </Transition>
+
+    <!-- 2. 弹窗主体 (增加底部滑入动画) -->
+    <Transition name="slide-up">
+      <div v-if="visible" class="popup-level-2">
+
+        <!-- 把手装饰 -->
+        <div class="handle-bar-wrap" @click="handleClose">
+          <div class="handle-bar"></div>
+        </div>
+
+        <div class="popup-title">交易规则</div>
+
+        <!-- 内容区域 -->
+        <div class="rules-content">
+          <div class="rule-row border-bottom">
+            <span class="label">最小价格波动</span>
+            <span class="value">0.01 USDT</span>
+          </div>
+          <div class="rule-row spacer-bottom">
+            <span class="label">价格倍数</span>
+            <span class="value">0.2 - 5</span>
+          </div>
+
+          <div class="rule-row">
+            <span class="label">订单规模</span>
+            <span class="value">5 - 9000000 USDT</span>
+          </div>
+          <div class="rule-row">
+            <span class="label">交易数量</span>
+            <span class="value">00001 - 9000 BTC</span>
+          </div>
+          <div class="rule-row">
+            <span class="label">最小数量波动</span>
+            <span class="value">0.00001 BTC</span>
+          </div>
+          <div class="rule-row">
+            <span class="label">市价单单笔最大数量</span>
+            <span class="value">75.45007539 BTC</span>
+          </div>
+          <div class="rule-row">
+            <span class="label">限价单单笔挂单数量</span>
+            <span class="value">200</span>
+          </div>
+          <div class="rule-row">
+            <span class="label">最大条件单挂单数量</span>
+            <span class="value">5</span>
+          </div>
+        </div>
+      </div>
+    </Transition>
+  </Teleport>
+</template>
+
+<script setup>
+import { watch, onUnmounted } from 'vue';
+
+// 1. 接收 visible 属性
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    default: false
+  }
+});
+
+// 2. 定义事件
+const emit = defineEmits(['update:visible', 'close']);
+
+// --- 滚动锁定逻辑 (防止背景跟随滚动) ---
+const lockScroll = () => {
+  document.body.style.overflow = 'hidden';
+};
+const unlockScroll = () => {
+  document.body.style.overflow = '';
+};
+
+// 监听 visible 变化
+watch(() => props.visible, (val) => {
+  if (val) {
+    lockScroll();
+  } else {
+    unlockScroll();
+  }
+});
+
+// 组件卸载时确保解锁,防止异常情况卡住
+onUnmounted(() => {
+  unlockScroll();
+});
+
+// --- 关闭处理 ---
+const handleClose = () => {
+  // 通知父组件把 visible 设为 false
+  emit('update:visible', false);
+  emit('close');
+};
+</script>
+
+<style scoped>
+/* --- 遮罩层样式 --- */
+.mask-level-2 {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  height: 100vh;
+  /* 你之前的 0.2 透明度 */
+  background: rgba(0, 0, 0, 0.2);
+  z-index: 2001;
+}
+
+/* --- 弹窗主体样式 --- */
+.popup-level-2 {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  background: white;
+  border-radius: 16px 16px 0 0;
+  z-index: 2002;
+  padding-bottom: calc(20px + env(safe-area-inset-bottom));
+  /* 限制最大高度,防止内容溢出 */
+  max-height: 85vh;
+  overflow-y: auto;
+}
+
+/* --- 内容样式保持不变 --- */
+.handle-bar-wrap {
+  display: flex; justify-content: center; padding: 10px 0;
+}
+.handle-bar {
+  width: 36px; height: 4px; background: #E0E0E0; border-radius: 2px;
+}
+.popup-title {
+  font-size: 18px; font-weight: bold; color: #333;
+  padding: 0 20px 20px 20px;
+}
+.rules-content { padding: 0 20px; }
+.rule-row {
+  display: flex; justify-content: space-between;
+  margin-bottom: 16px; font-size: 14px;
+}
+.label { color: #888; }
+.value { color: #333; font-weight: 500; text-align: right;}
+.border-bottom {
+  padding-bottom: 16px; border-bottom: 1px solid #f5f5f5; margin-bottom: 16px;
+}
+.spacer-bottom { margin-bottom: 30px; }
+
+/* --- Vue Transition 动画 --- */
+/* 1. 遮罩层淡入淡出 */
+.fade-enter-active, .fade-leave-active {
+  transition: opacity 0.3s ease;
+}
+.fade-enter-from, .fade-leave-to {
+  opacity: 0;
+}
+
+/* 2. 弹窗底部滑入滑出 */
+.slide-up-enter-active, .slide-up-leave-active {
+  transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
+}
+.slide-up-enter-from, .slide-up-leave-to {
+  transform: translateY(100%);
+}
+</style>

+ 510 - 0
src/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/TradeSettings.vue

@@ -0,0 +1,510 @@
+<template>
+  <div class="settings-page">
+    <div class="nav-bar">
+      <div class="back-icon" @click="$router.back()">
+        <div>
+          <VanIcon size="18" name="arrow-left"/>
+        </div>
+      </div>
+      <div class="nav-title">交易设置</div>
+      <div class="nav-right"></div>
+    </div>
+
+    <div class="tabs-header">
+      <div
+        class="tab-item"
+        :class="{ active: currentTab === 'mode' }"
+        @click="currentTab = 'mode'"
+      >
+        交易模式
+        <div class="active-line" v-if="currentTab === 'mode'"></div>
+      </div>
+      <div
+        class="tab-item"
+        :class="{ active: currentTab === 'pref' }"
+        @click="currentTab = 'pref'"
+      >
+        偏好
+        <div class="active-line" v-if="currentTab === 'pref'"></div>
+      </div>
+      <div
+        class="tab-item"
+        :class="{ active: currentTab === 'ui' }"
+        @click="currentTab = 'ui'"
+      >
+        界面
+        <div class="active-line" v-if="currentTab === 'ui'"></div>
+      </div>
+    </div>
+
+    <div class="content-scroll">
+
+      <div v-if="currentTab === 'mode'" class="tab-content fade-in">
+        <div class="list-item">
+          <div class="item-label">账户模式</div>
+          <div class="item-value">合约模式</div>
+        </div>
+
+        <div class="list-item clickable">
+          <div class="item-label">仓位模式</div>
+          <div class="item-value" @click="showModal1 = true">{{selectedLabel1}}
+            <div style="margin: 3px 0 0 2px;">
+              <VanIcon size="16" name="arrow"/>
+            </div>
+          </div>
+        </div>
+
+        <div class="list-item">
+          <div class="item-label">合约交易单位</div>
+          <div class="item-value">数量</div>
+        </div>
+
+        <div class="list-item">
+          <div class="item-label">期权交易单位</div>
+          <div class="item-value">币</div>
+        </div>
+
+        <div class="list-item">
+          <div class="item-label">稳定币偏好</div>
+          <div class="item-value">USDT</div>
+        </div>
+      </div>
+
+      <div v-if="currentTab === 'pref'" class="tab-content fade-in">
+        <div class="list-item clickable">
+          <div class="item-label">交易通知</div>
+          <div class="item-value" @click="showNotifyPopup = true">
+            <div class="arrow1" style="margin: 3px 0 0 2px;">
+              <VanIcon size="16" name="arrow"/>
+            </div>
+<!--            <span class="arrow">›</span>-->
+          </div>
+        </div>
+
+        <div class="list-item">
+          <div class="item-label">点击K线带入价格</div>
+          <div class="switch-box" :class="{ active: prefState.klinePrice }" @click="toggle('klinePrice')">
+            <div class="switch-circle"></div>
+          </div>
+        </div>
+
+        <div class="list-item">
+          <div class="item-label">点击订单表带入数量</div>
+          <div class="switch-box" :class="{ active: prefState.orderBookQty }" @click="toggle('orderBookQty')">
+            <div class="switch-circle"></div>
+          </div>
+        </div>
+
+        <div class="group-title">二次下单确认</div>
+
+        <div class="list-item">
+          <div class="item-label">下单确认</div>
+          <div class="switch-box" :class="{ active: prefState.orderConfirm }" @click="toggle('orderConfirm')">
+            <div class="switch-circle"></div>
+          </div>
+        </div>
+
+        <div class="list-item">
+          <div class="item-label">限价单</div>
+          <div class="switch-box" :class="{ active: prefState.limitOrder }" @click="toggle('limitOrder')">
+            <div class="switch-circle"></div>
+          </div>
+        </div>
+
+        <div class="list-item">
+          <div class="item-label">市价单</div>
+          <div class="switch-box" :class="{ active: prefState.marketOrder }" @click="toggle('marketOrder')">
+            <div class="switch-circle"></div>
+          </div>
+        </div>
+
+        <div class="list-item">
+          <div class="item-label">限价止盈止损订单</div>
+          <div class="switch-box" :class="{ active: prefState.limitTPSL }" @click="toggle('limitTPSL')">
+            <div class="switch-circle"></div>
+          </div>
+        </div>
+
+        <div class="list-item">
+          <div class="item-label">市价止盈止损</div>
+          <div class="switch-box" :class="{ active: prefState.marketTPSL }" @click="toggle('marketTPSL')">
+            <div class="switch-circle"></div>
+          </div>
+        </div>
+
+        <div class="list-item">
+          <div class="item-label">杠杆交易自动借还款</div>
+          <div class="switch-box" :class="{ active: prefState.autoBorrow }" @click="toggle('autoBorrow')">
+            <div class="switch-circle"></div>
+          </div>
+        </div>
+      </div>
+
+      <div v-if="currentTab === 'ui'" class="tab-content fade-in">
+        <div class="list-item clickable">
+          <div class="item-label">主题模式</div>
+          <div class="item-value text-gray" @click="showThemeModal = true">{{ currentThemeLabel }}
+             <div class="arrow1" style="margin: 3px 0 0 2px;">
+              <VanIcon size="16" name="arrow"/>
+            </div>
+          </div>
+        </div>
+
+        <div class="list-item clickable">
+          <div class="item-label">颜色设置</div>
+          <div class="item-value text-gray" @click="showColorModal = true">
+            <span v-if="currentColor === 'green_up'">
+                 <span class="green">绿涨</span><span class="red">红跌</span> <span class="green">↑</span><span class="red">↓</span>
+            </span>
+              <span v-else>
+                 <span class="red">红涨</span><span class="green">绿跌</span> <span class="red">↑</span><span class="green">↓</span>
+              </span>
+             <div class="arrow1" style="margin: 3px 0 0 2px;">
+              <VanIcon size="16" name="arrow"/>
+            </div>
+          </div>
+        </div>
+
+        <div class="layout-section">
+          <div class="section-label">交易页K线</div>
+          <div class="layout-grid">
+
+            <div class="layout-card" :class="{ selected: uiState.klineLayout === 'pull' }" @click="uiState.klineLayout = 'pull'">
+              <div class="preview-box">
+                <img src="../../../../assets/icon/bitcoin/xialadaka.svg" alt="">
+<!--                <div class="draw-kline top-part">-->
+<!--                  <div class="draw-candle red"></div>-->
+<!--                  <div class="draw-candle green"></div>-->
+<!--                </div>-->
+<!--                <div class="draw-bar bottom-part">-->
+<!--                  <div class="draw-btn red"></div>-->
+<!--                  <div class="draw-btn green"></div>-->
+<!--                </div>-->
+              </div>
+              <div class="card-text">下拉打开</div>
+            </div>
+
+            <div class="layout-card" :class="{ selected: uiState.klineLayout === 'bottom' }" @click="uiState.klineLayout = 'bottom'">
+              <div class="preview-box">
+                <div class="draw-bar top-part compact">
+                  <div class="draw-btn red"></div>
+                  <div class="draw-btn green"></div>
+                </div>
+                <div class="draw-kline bottom-part">
+                  <div class="draw-candle red"></div>
+                  <div class="draw-candle green"></div>
+                </div>
+              </div>
+              <div class="card-text">底部显示</div>
+            </div>
+
+            <div class="layout-card" :class="{ selected: uiState.klineLayout === 'none' }" @click="uiState.klineLayout = 'none'">
+              <div class="preview-box row-mode">
+                 <div class="draw-col left">
+                   <div class="draw-btn red full"></div>
+                 </div>
+                 <div class="draw-col right"></div>
+              </div>
+              <div class="card-text">不显示</div>
+            </div>
+          </div>
+        </div>
+
+        <div class="layout-section">
+          <div class="section-label">下单布局</div>
+          <div class="layout-grid two-col">
+
+            <div class="layout-card" :class="{ selected: uiState.orderLayout === 'left' }" @click="uiState.orderLayout = 'left'">
+              <div class="preview-box row-mode">
+                <div class="draw-col left selected-border">
+                  <div class="draw-btn green full"></div>
+                  <div class="draw-btn red full"></div>
+                </div>
+                <div class="draw-col right"></div>
+              </div>
+              <div class="card-text">左侧下单</div>
+            </div>
+
+            <div class="layout-card" :class="{ selected: uiState.orderLayout === 'right' }" @click="uiState.orderLayout = 'right'">
+              <div class="preview-box row-mode">
+                <div class="draw-col left"></div>
+                <div class="draw-col right selected-border">
+                   <div class="draw-btn green full"></div>
+                   <div class="draw-btn red full"></div>
+                </div>
+              </div>
+              <div class="card-text">右侧下单</div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+    </div>
+    <div>
+      <FundingOptions
+          v-model:visible="showModal1"
+          :selected-id="currentId1"
+          @confirm="handleConfirm1"
+      ></FundingOptions>
+    </div>
+
+    <SelectionSheet
+      v-model:visible="showThemeModal"
+      title="主题模式"
+      :options="themeOptions"
+      v-model="currentTheme"
+      @confirm="onThemeConfirm"
+    />
+
+    <SelectionSheet
+      v-model:visible="showColorModal"
+      title="颜色设置"
+      :options="colorOptions"
+      v-model="currentColor"
+      @confirm="onColorConfirm"
+    >
+      <template #option="{ item }">
+        <div v-if="item.value === 'green_up'">
+          <span class="green">绿涨</span><span class="red">红跌</span>
+          <span class="green icon-arrow">↑</span><span class="red icon-arrow">↓</span>
+        </div>
+        <div v-else>
+           <span class="red">红涨</span><span class="green">绿跌</span>
+           <span class="red icon-arrow">↑</span><span class="green icon-arrow">↓</span>
+        </div>
+      </template>
+    </SelectionSheet>
+    <div>
+      <TradeNotificationPopup v-model:visible="showNotifyPopup" />
+    </div>
+  </div>
+</template>
+
+<script setup>
+        import {ref, reactive,computed,} from 'vue'
+        import { Icon as VanIcon } from 'vant';
+        import FundingOptions from './components/PositionMode.vue'
+        import SelectionSheet from './components/SelectionSheet.vue' // 引入上面的组件
+        import TradeNotificationPopup from './components/TradeNotificationPopup.vue'
+        const showNotifyPopup = ref(false)
+                // --- 状态管理 ---
+        const showThemeModal = ref(false)
+        const showColorModal = ref(false)
+
+        const currentTheme = ref('system') // 默认值
+        const currentColor = ref('green_up') // 默认值
+
+        // --- 数据配置 ---
+        const themeOptions = [
+          { label: '跟随系统', value: 'system' },
+          { label: '日间模式', value: 'light' },
+          { label: '夜间模式', value: 'dark' },
+        ]
+
+        const colorOptions = [
+          { label: '绿涨红跌', value: 'green_up' },
+          { label: '红涨绿跌', value: 'red_up' },
+        ]
+
+        // --- 计算属性:用于在列表显示当前选中的文字 ---
+        const currentThemeLabel = computed(() => {
+          const item = themeOptions.find(opt => opt.value === currentTheme.value)
+          return item ? item.label : ''
+        })
+
+        // --- 回调函数 ---
+        const onThemeConfirm = (val) => {
+          console.log('主题已确认修改为:', val)
+          // 这里可以调用 API 或者修改全局 CSS 变量
+        }
+
+        const onColorConfirm = (val) => {
+          console.log('颜色已确认修改为:', val)
+          // 这里处理红绿涨跌的全局逻辑
+        }
+
+        /*账户模式*/
+        const showModal1 = ref(false);
+
+        // 定义状态用于存储
+        const currentId1 = ref(1); // 默认选中第一个
+        const selectedLabel1 = ref('单向持仓'); // 默认值
+        const selectedUnit1 = ref('%');      // 默认值
+
+        // 回调函数:子组件选中后触发
+        const handleConfirm1 = (item) => {
+          // console.log('子组件返回的对象:', item);
+
+          // 保存ID用于下次打开时回显高亮
+          currentId1.value = item.id;
+          // const a = item.label.slice(-2)
+
+          // 核心需求:在这里将值“拆开”为两个字符串
+          selectedLabel1.value = item.label.slice(0); // 字符串1: "涨跌幅"
+          selectedUnit1.value = item.unit;   // 字符串2: "%"
+        };
+
+        // 状态管理
+        const currentTab = ref('mode') // 默认显示偏好
+
+        // 偏好设置数据 (对应图1)
+        const prefState = reactive({
+          klinePrice: false,
+          orderBookQty: true, // 默认开启
+          orderConfirm: false,
+          limitOrder: false,
+          marketOrder: true,
+          limitTPSL: false,
+          marketTPSL: true,
+          autoBorrow: false
+        })
+
+        // 界面设置数据 (对应图3)
+        const uiState = reactive({
+          klineLayout: 'pull', // pull | bottom | none
+          orderLayout: 'left', // left | right
+        })
+
+      // 切换开关
+      const toggle = (key) => {
+        prefState[key] = !prefState[key]
+      }
+</script>
+
+<style scoped>
+
+/* 定义红绿颜色,用于颜色设置弹窗 */
+.green { color: #2EBD85; }
+.red { color: #E54755; }
+.icon-arrow { font-weight: bold; margin-left: 2px; }
+/* ================== 全局布局 ================== */
+.settings-page {
+  position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
+  background-color: #fff; z-index: 2000;
+  display: flex; flex-direction: column;
+}
+
+.content-scroll {
+  flex: 1; overflow-y: auto; padding-bottom: 40px;
+}
+
+/* 简单的淡入动画 */
+.fade-in {
+  animation: fadeIn 0.3s ease;
+}
+@keyframes fadeIn {
+  from { opacity: 0; transform: translateY(5px); }
+  to { opacity: 1; transform: translateY(0); }
+}
+
+/* ================== 顶部导航 & Tab ================== */
+.nav-bar {
+  height: 44px; display: flex; align-items: center; justify-content: space-between; padding: 0 15px;
+  background: #fff;
+  margin-top: 12px;
+}
+.nav-title { font-size: 17px; font-weight: 600; color: #333; }
+
+.tabs-header {
+  display: flex; padding-left: 16px; margin-top: 5px;
+  border-bottom: 1px solid #f9f9f9;
+}
+.tab-item {
+  margin-right: 24px; font-size: 16px; color: #999;
+  position: relative; padding-bottom: 10px; cursor: pointer;
+  transition: all 0.2s;
+}
+.tab-item.active { color: #333; font-weight: bold; font-size: 19px; }
+.active-line {
+  position: absolute; bottom: 0; left: 50%; transform: translateX(-50%);
+  width: 18px; height: 3px; background-color: #333; border-radius: 2px;
+}
+
+/* ================== 列表通用样式 ================== */
+.tab-content { padding: 0 16px; }
+.list-item {
+  display: flex; justify-content: space-between; align-items: center;
+  height: 56px; font-size: 15px; color: #333;
+}
+.item-value { display: flex; align-items: center; }
+.text-gray { color: #999; font-size: 14px; }
+.arrow { color: #ccc; margin-left: 8px; font-size: 18px; font-family: serif; position: relative; top: -1px; }
+
+.group-title {
+  margin-top: 24px; margin-bottom: 8px; font-size: 14px; color: #333; font-weight: 600;
+}
+
+/* ================== 开关组件 (Switch) ================== */
+.switch-box {
+  width: 50px; height: 30px; border-radius: 15px; background-color: #F0F0F0;
+  position: relative; cursor: pointer; transition: background-color 0.3s;
+}
+.switch-circle {
+  width: 26px; height: 26px; background: white; border-radius: 50%;
+  position: absolute; top: 2px; left: 2px; transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
+  box-shadow: 0 2px 4px rgba(0,0,0,0.2);
+}
+/* 激活状态:使用你截图中的红色 */
+.switch-box.active { background-color: #E54755; }
+.switch-box.active .switch-circle { transform: translateX(20px); }
+
+/* ================== 界面布局选择 (CSS 绘图核心) ================== */
+.layout-section { margin-top: 30px; }
+.section-label { font-size: 14px; font-weight: 600; color: #333; margin-bottom: 12px; }
+
+.layout-grid { display: flex; gap: 12px; }
+.layout-grid.two-col { justify-content: flex-start; }
+
+.layout-card {
+  width: 100px; cursor: pointer;
+  display: flex; flex-direction: column; align-items: center;
+}
+.card-text { margin-top: 8px; font-size: 12px; color: #999; }
+.layout-card.selected .card-text { color: #E54755; }
+
+/* 预览盒子 */
+.preview-box {
+  width: 100%; height: 120px; border-radius: 8px; border: 1px solid #eee;
+  padding: 6px; background: #fff;
+  display: flex; flex-direction: column; justify-content: space-between;
+  box-sizing: border-box; overflow: hidden;
+}
+/* 选中状态:红框 */
+.layout-card.selected .preview-box { border: 1px solid #E54755; background: rgba(229, 71, 85, 0.02); }
+
+/* --- CSS 绘图元件 --- */
+
+/* 1. K线图部分 (灰色背景 + 红绿柱子) */
+.draw-kline {
+  background: #F5F7FA; border-radius: 4px; position: relative;
+  display: flex; align-items: center; justify-content: center; gap: 4px;
+}
+.draw-candle { width: 4px; border-radius: 1px; }
+.draw-candle.red { height: 60%; background: #E54755; margin-top: 10%; }
+.draw-candle.green { height: 40%; background: #2EBD85; margin-bottom: 10%; }
+
+/* 2. 操作区部分 (灰色背景 + 红绿按钮条) */
+.draw-bar {
+  background: #F5F7FA; border-radius: 4px; padding: 4px;
+  display: flex; flex-direction: column; justify-content: flex-end; gap: 3px;
+}
+.draw-btn { height: 4px; width: 60%; border-radius: 2px; }
+.draw-btn.red { background: #E54755; }
+.draw-btn.green { background: #2EBD85; width: 80%; }
+.draw-btn.full { width: 100%; height: 6px; margin-bottom: 4px; }
+
+/* 上下结构高度调整 */
+.top-part { height: 60%; }
+.bottom-part { height: 35%; }
+.compact { height: 45%; } /* 底部布局时中间部分变矮 */
+
+/* 3. 左右布局模式 */
+.row-mode { flex-direction: row; gap: 4px; height: 100%; }
+.draw-col { flex: 1; background: #F5F7FA; border-radius: 4px; height: 100%; display: flex; flex-direction: column; justify-content: flex-end; padding: 4px; box-sizing: border-box; }
+.selected-border { border: 1px solid #1989fa; } /* 模拟选中边框 */
+
+/* 细节微调 */
+.layout-card:hover .preview-box { border-color: #ccc; }
+.layout-card.selected:hover .preview-box { border-color: #E54755; }
+
+</style>

+ 171 - 0
src/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/components/PositionMode.vue

@@ -0,0 +1,171 @@
+<template>
+  <Teleport to="body">
+    <div v-if="visible" class="modal-mask" @click="close">
+      <div class="modal-content" @click.stop>
+        <div class="handle-bar"></div>
+<!--        <div class="trigger fs18 fc333333 pf600">选择触发类型</div>-->
+        <div class="options-list">
+          <div
+            v-for="item in options"
+            :key="item.id"
+            class="option-card"
+            :class="{ 'active': selectedId === item.id }"
+            @click="handleSelect(item)"
+          >
+            <div class="card-header">
+              <span class="title">{{ item.label }}</span>
+              <div v-if="selectedId === item.id" class="check-icon">
+                <svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor"
+                     stroke-width="3" fill="none" stroke-linecap="round" stroke-linejoin="round"
+                     class="css-i6dzq1"><polyline points="20 6 9 17 4 12"></polyline></svg>
+              </div>
+            </div>
+            <div class="description">
+              {{ item.desc }}
+            </div>
+
+          </div>
+        </div>
+        <div class="fs12 fc666666">该设置对所有交易品种生效。若存在持仓或挂单,则不支持调整仓位模式。</div>
+      </div>
+    </div>
+
+  </Teleport>
+</template>
+
+<script setup>
+import { defineProps, defineEmits ,toRef} from 'vue';
+import { useBodyScrollLock } from '@/composables/useBodyScrollLock' // 2. 引入 Hook
+
+// 接收父组件传来的 modelValue (控制显示) 和 当前选中的ID
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    default: false
+  },
+  selectedId: {
+    type: [String, Number],
+    default: 1
+  }
+});
+useBodyScrollLock(toRef(props, 'visible'))
+const emit = defineEmits(['update:visible', 'confirm']);
+
+// 静态数据源 (保持不变)
+const options = [
+  {
+    id: 1,
+    label: '单向持仓',
+    desc: '一个交易品种仅可持有多或空单一方向的仓位。如果您已持有某一交易品种的仓位,买入或卖出时将增减原有仓位,' +
+          '而非开新的仓位。所有仓位共用保证金盈亏互抵可有效降低强平风险但强平时可能损失全部仓位'
+  },
+
+  {
+    id: 2,
+    label: '双向持仓' ,
+    desc: '一个交易品种可同时持有多和空两个方向\n' +
+          '的仓位。',
+  },
+];
+
+const close = () => {
+  emit('update:visible', false);
+};
+
+const handleSelect = (item) => {
+  // 1. 触发 confirm 事件,把整个对象带回去
+  emit('confirm', item);
+  // 2. 关闭弹窗
+  close();
+};
+</script>
+
+<style lang="less" scoped>
+.modal-mask {
+  position: fixed;
+  top: 0; left: 0; width: 100%; height: 100%;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: flex-end; /* 底部对齐 */
+  z-index: 2001; /* 极高的 Z-index */
+}
+
+.modal-content {
+  width: 100%;
+  background: white;
+  border-radius: 16px 16px 0 0;
+  padding: 20px;
+  padding-bottom: 40px;
+  max-height: 80vh;
+  overflow-y: auto;
+  animation: slideUp 0.3s ease-out;
+  .trigger{margin-bottom: 15px}
+}
+
+.handle-bar {
+  width: 40px;
+  height: 4px;
+  background: #E0E0E0;
+  border-radius: 2px;
+  margin: 0 auto 20px auto;
+}
+
+.option-card {
+  border: 1px solid #E0E0E0;
+  border-radius: 12px;
+  padding: 16px;
+  margin-bottom: 16px;
+  cursor: pointer;
+  transition: all 0.2s;
+  position: relative;
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 8px;
+}
+
+.title {
+  font-size: 16px;
+  font-weight: bold;
+  color: #333;
+}
+
+.description {
+  font-size: 13px;
+  color: #666;
+  line-height: 1.5;
+}
+
+/* 选中状态样式 */
+.option-card.active {
+  border-color: #F53F3F; /* 红色边框 */
+  background-color: #FFF9F9; /* 极淡的红色背景可选 */
+}
+
+.option-card.active .title {
+  color: #D92828; /* 红色标题 */
+}
+
+.option-card.active .description {
+  color: #D92828; /* 红色描述 */
+}
+
+.check-icon {
+  width: 24px;
+  height: 24px;
+  background: #D92828;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: white;
+}
+
+@keyframes slideUp {
+  from { transform: translateY(100%); }
+  to { transform: translateY(0); }
+}
+</style>

+ 132 - 0
src/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/components/SelectionSheet.vue

@@ -0,0 +1,132 @@
+<template>
+  <Teleport to="body">
+    <Transition name="fade">
+      <div v-if="visible" class="modal-mask" @click="close"></div>
+    </Transition>
+
+    <Transition name="slide-up">
+      <div v-if="visible" class="modal-panel" @click.stop>
+        <div class="handle-bar-wrap">
+          <div class="handle-bar"></div>
+        </div>
+
+        <div class="panel-title">{{ title }}</div>
+
+        <div class="options-list">
+          <div 
+            v-for="item in options" 
+            :key="item.value" 
+            class="option-item"
+            @click="selectItem(item.value)"
+          >
+            <div class="option-label" :class="{ active: tempValue === item.value }">
+              <slot name="option" :item="item">
+                {{ item.label }}
+              </slot>
+            </div>
+
+            <div v-if="tempValue === item.value" class="check-icon">
+              <svg viewBox="0 0 24 24" width="20" height="20" fill="none">
+                <circle cx="12" cy="12" r="10" fill="#E54755"/>
+                <path d="M7 12L10 15L17 8" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
+              </svg>
+            </div>
+          </div>
+        </div>
+
+        <div class="btn-area">
+          <button class="confirm-btn" @click="handleConfirm">确认</button>
+        </div>
+        
+        <div class="safe-area-bottom"></div>
+      </div>
+    </Transition>
+  </Teleport>
+</template>
+
+<script setup>
+import { ref, watch } from 'vue'
+
+const props = defineProps({
+  visible: Boolean,
+  title: String,
+  options: Array,   // 格式: [{ label: 'xxx', value: 'xxx' }]
+  modelValue: [String, Number] // 当前选中的值
+})
+
+const emit = defineEmits(['update:visible', 'update:modelValue', 'confirm'])
+
+// 临时选中的值(还没点确认前,不改变父组件的值)
+const tempValue = ref(props.modelValue)
+
+// 监听弹窗打开,每次打开时重置 tempValue 为父组件当前的值
+watch(() => props.visible, (val) => {
+  if (val) {
+    tempValue.value = props.modelValue
+  }
+})
+
+const selectItem = (val) => {
+  tempValue.value = val
+}
+
+const handleConfirm = () => {
+  emit('update:modelValue', tempValue.value) // 更新父组件 v-model
+  emit('confirm', tempValue.value) // 触发确认事件,带回值
+  close()
+}
+
+const close = () => {
+  emit('update:visible', false)
+}
+</script>
+
+<style scoped>
+.modal-mask {
+  position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
+  background-color: rgba(0, 0, 0, 0.5); z-index: 3000;
+}
+.modal-panel {
+  position: fixed; bottom: 0; left: 0; width: 100%;
+  background: white; border-radius: 16px 16px 0 0;
+  z-index: 3001; padding-bottom: 20px;
+}
+
+.handle-bar-wrap { display: flex; justify-content: center; padding-top: 10px; }
+.handle-bar { width: 36px; height: 4px; background: #E0E0E0; border-radius: 2px; }
+
+.panel-title {
+  font-size: 18px; font-weight: bold; color: #333;
+  padding: 20px 16px;
+}
+
+.options-list { padding: 0 16px; margin-bottom: 20px; }
+
+.option-item {
+  display: flex; justify-content: space-between; align-items: center;
+  height: 54px; cursor: pointer;
+}
+
+.option-label {
+  font-size: 16px; color: #333; flex: 1;
+  /* 选中时文字加粗 */
+}
+.option-label.active { font-weight: 600; }
+
+.btn-area { padding: 0 16px; }
+.confirm-btn {
+  width: 100%; height: 48px;
+  background-color: #E54755; color: white;
+  border: none; border-radius: 24px;
+  font-size: 16px; font-weight: 600;
+}
+.confirm-btn:active { opacity: 0.9; }
+
+.safe-area-bottom { height: env(safe-area-inset-bottom); }
+
+/* 动画 */
+.fade-enter-active, .fade-leave-active { transition: opacity 0.3s; }
+.fade-enter-from, .fade-leave-to { opacity: 0; }
+.slide-up-enter-active, .slide-up-leave-active { transition: transform 0.3s; }
+.slide-up-enter-from, .slide-up-leave-to { transform: translateY(100%); }
+</style>

+ 194 - 0
src/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/components/TradeNotificationPopup.vue

@@ -0,0 +1,194 @@
+<template>
+  <Teleport to="body">
+    <Transition name="fade">
+      <div v-if="visible" class="modal-mask" @click="close"></div>
+    </Transition>
+
+    <Transition name="slide-up">
+      <div v-if="visible" class="modal-panel" @click.stop>
+
+        <div class="handle-bar-wrap">
+          <div class="handle-bar"></div>
+        </div>
+
+        <div class="content-list">
+
+          <div class="notify-item">
+            <div class="item-header">
+              <span class="item-title">止盈止损通知</span>
+              <div class="switch-box" :class="{ active: state.tpsl }" @click="toggle('tpsl')">
+                <div class="switch-circle"></div>
+              </div>
+            </div>
+            <div class="item-desc">当止盈止损委托触发或成交时,您将收到通知</div>
+          </div>
+
+          <div class="notify-item">
+            <div class="item-header">
+              <span class="item-title">市价委托成交通知</span>
+              <div class="switch-box" :class="{ active: state.market }" @click="toggle('market')">
+                <div class="switch-circle"></div>
+              </div>
+            </div>
+            <div class="item-desc">当市价委托完全成交时,您将收到通知。极端情况下,通知可能会延迟</div>
+          </div>
+
+          <div class="notify-item">
+            <div class="item-header">
+              <span class="item-title">限价委托成交通知</span>
+              <div class="switch-box" :class="{ active: state.limit }" @click="toggle('limit')">
+                <div class="switch-circle"></div>
+              </div>
+            </div>
+            <div class="item-desc">当限价委托完全成交时,您将收到通知</div>
+          </div>
+
+          <div class="notify-item">
+            <div class="item-header">
+              <span class="item-title">只减仓改撤单通知</span>
+              <div class="switch-box" :class="{ active: state.reduce }" @click="toggle('reduce')">
+                <div class="switch-circle"></div>
+              </div>
+            </div>
+            <div class="item-desc">当只减仓委托被系统修改或撤单时,您将收到通知</div>
+          </div>
+
+          <div class="notify-item">
+            <div class="item-header">
+              <span class="item-title">资金费率通知</span>
+              <div class="switch-box" :class="{ active: state.funding }" @click="toggle('funding')">
+                <div class="switch-circle"></div>
+              </div>
+            </div>
+            <div class="item-desc">
+              当预估资金费率达到+/-{{ triggerValue }}%时,您将在结算前的30分钟收到通知
+              <span class="red-link" @click="showTriggerSheet = true">调整触发值</span>
+            </div>
+          </div>
+
+          <div class="safe-area-bottom"></div>
+        </div>
+
+        <TriggerValueSheet
+          v-model:visible="showTriggerSheet"
+          v-model="triggerValue"
+          @confirm="onTriggerConfirm"
+        />
+
+      </div>
+    </Transition>
+  </Teleport>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue'
+import TriggerValueSheet from './TriggerValueSheet.vue'
+
+const props = defineProps({
+  visible: Boolean
+})
+
+const emit = defineEmits(['update:visible'])
+
+const close = () => {
+  emit('update:visible', false)
+}
+
+// 内部开关状态
+const state = reactive({
+  tpsl: false,
+  market: true,
+  limit: false,
+  reduce: true,
+  funding: true
+})
+
+const toggle = (key) => {
+  state[key] = !state[key]
+}
+
+// 资金费率弹窗逻辑
+const showTriggerSheet = ref(false)
+const triggerValue = ref('0.375')
+
+const onTriggerConfirm = (val) => {
+  triggerValue.value = val
+  // 这里可以调用 API 保存设置
+}
+</script>
+
+<style scoped>
+/* ================== 弹窗结构 ================== */
+.modal-mask {
+  position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
+  background-color: rgba(0, 0, 0, 0.5); z-index: 2100; /* 层级高于设置页(2000) */
+}
+
+.modal-panel {
+  position: fixed; bottom: 0; left: 0; width: 100%;
+  max-height: 85vh; /* 限制最大高度,大概占屏幕 85% */
+  background: white; border-radius: 16px 16px 0 0;
+  z-index: 2101; /* 比遮罩高 */
+  display: flex; flex-direction: column;
+}
+
+/* 顶部灰色把手 */
+.handle-bar-wrap {
+  display: flex; justify-content: center; padding: 10px 0;
+}
+.handle-bar {
+  width: 36px; height: 4px; background: #E0E0E0; border-radius: 2px;
+}
+
+/* 内容列表区域 */
+.content-list {
+  flex: 1; overflow-y: auto; padding: 10px 16px 20px 16px;
+}
+
+/* ================== 列表项样式 ================== */
+.notify-item {
+  margin-bottom: 24px;
+}
+
+.item-header {
+  display: flex; justify-content: space-between; align-items: center;
+  margin-bottom: 8px;
+}
+
+.item-title {
+  font-size: 16px; font-weight: 600; color: #333;
+}
+
+.item-desc {
+  font-size: 13px; color: #888; line-height: 1.5;
+  text-align: justify; /* 两端对齐更整齐 */
+}
+
+/* 红色链接 */
+.red-link {
+  color: #DF384C; margin-left: 5px; cursor: pointer;
+}
+
+/* 底部安全区适配 */
+.safe-area-bottom { height: env(safe-area-inset-bottom); }
+
+/* ================== 开关组件 (红色) ================== */
+.switch-box {
+  width: 50px; height: 30px; border-radius: 15px; background-color: #F5F5F5;
+  position: relative; cursor: pointer; transition: background-color 0.3s;
+}
+.switch-circle {
+  width: 26px; height: 26px; background: white; border-radius: 50%;
+  position: absolute; top: 2px; left: 2px; transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
+  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+}
+.switch-box.active { background-color: #DF384C; } /* 红色激活态 */
+.switch-box.active .switch-circle { transform: translateX(20px); }
+
+/* ================== 动画效果 ================== */
+.fade-enter-active, .fade-leave-active { transition: opacity 0.3s; }
+.fade-enter-from, .fade-leave-to { opacity: 0; }
+
+.slide-up-enter-active, .slide-up-leave-active { transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.5, 1); }
+.slide-up-enter-from, .slide-up-leave-to { transform: translateY(100%); }
+</style>

+ 93 - 0
src/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/components/TriggerValueSheet.vue

@@ -0,0 +1,93 @@
+<template>
+  <Teleport to="body">
+    <Transition name="fade">
+      <div v-if="visible" class="modal-mask" @click="close"></div>
+    </Transition>
+
+    <Transition name="slide-up">
+      <div v-if="visible" class="modal-panel" @click.stop>
+        <div class="handle-bar-wrap"><div class="handle-bar"></div></div>
+
+        <div class="panel-title">资金费率触发值设置</div>
+
+        <div class="panel-content">
+          <div class="input-wrapper">
+            <input
+              type="text"
+              class="custom-input"
+              v-model="localValue"
+              placeholder="0.000"
+            />
+            <span class="suffix">触发值(%)</span>
+          </div>
+
+          <p class="desc-text">
+            资金费率为正,表做多仓位;资金费率为负,表做空仓位。您将在对应方向仓位的资金费率达到触发值时收到通知。
+          </p>
+
+          <button class="confirm-btn" @click="handleConfirm">确认</button>
+        </div>
+        <div class="safe-area-bottom"></div>
+      </div>
+    </Transition>
+  </Teleport>
+</template>
+
+<script setup>
+import { ref, watch } from 'vue'
+
+const props = defineProps({
+  visible: Boolean,
+  modelValue: [String, Number]
+})
+const emit = defineEmits(['update:visible', 'update:modelValue', 'confirm'])
+
+const localValue = ref(props.modelValue)
+
+watch(() => props.visible, (val) => {
+  if (val) localValue.value = props.modelValue
+})
+
+const close = () => emit('update:visible', false)
+const handleConfirm = () => {
+  emit('update:modelValue', localValue.value)
+  emit('confirm', localValue.value)
+  close()
+}
+</script>
+
+<style scoped>
+.modal-mask {
+  position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
+  background: rgba(0,0,0,0.5); z-index: 3000; /* 最高层级 */
+}
+.modal-panel {
+  position: fixed; bottom: 0; left: 0; width: 100%;
+  background: white; border-radius: 16px 16px 0 0;
+  z-index: 3001; padding-bottom: 20px;
+}
+.handle-bar-wrap { display: flex; justify-content: center; padding-top: 10px; }
+.handle-bar { width: 36px; height: 4px; background: #E0E0E0; border-radius: 2px; }
+.panel-title { font-size: 18px; font-weight: bold; color: #333; padding: 20px 16px 10px; }
+.panel-content { padding: 0 16px; }
+
+.input-wrapper {
+  background: #F7F8FA; border-radius: 4px; height: 48px;
+  display: flex; align-items: center; padding: 0 12px; margin-bottom: 12px;
+}
+.custom-input { flex: 1; background: transparent; border: none; font-size: 16px; outline: none; }
+.suffix { color: #999; font-size: 14px; }
+.desc-text { font-size: 13px; color: #888; line-height: 1.5; margin-bottom: 30px; text-align: justify; }
+
+.confirm-btn {
+  width: 100%; height: 48px; background: #DF384C; color: white;
+  border: none; border-radius: 24px; font-size: 16px; font-weight: 600;
+}
+.safe-area-bottom { height: env(safe-area-inset-bottom); }
+
+/* 动画 */
+.fade-enter-active, .fade-leave-active { transition: opacity 0.3s; }
+.fade-enter-from, .fade-leave-to { opacity: 0; }
+.slide-up-enter-active, .slide-up-leave-active { transition: transform 0.3s; }
+.slide-up-enter-from, .slide-up-leave-to { transform: translateY(100%); }
+</style>

+ 732 - 538
src/views/bitcoin/Index.vue

@@ -7,13 +7,13 @@
         </div>
         <div class="sys-notifi pf600 fs14 fcA8A8A8" @click="messageChange('contract')">秒合约</div>
         <div
-          class="sys-notifi pf600 fs14 fcA8A8A8"
-          @click="messageChange('secondContract')">
+            class="sys-notifi pf600 fs14 fcA8A8A8"
+            @click="messageChange('secondContract')">
           期权
         </div>
         <div
-          class="sys-notifi pf600 fs14 fcA8A8A8"
-          @click="messageChange('secondContract')">
+            class="sys-notifi pf600 fs14 fcA8A8A8"
+            @click="messageChange('secondContract')">
           杠杆
         </div>
       </div>
@@ -21,14 +21,15 @@
     </div>
     <div class="menu">
       <div class="menu-left">
-      <img class="fc333333" src="../../assets/icon/bitcoin/menu.svg" alt="">
-      <div class="pf600 fs18 fc121212" >BTCUSDT 永续</div>
-    </div>
-    <div class="menu-right fc333333">
-      <img src="../../assets/icon/bitcoin/jisuan.svg" alt="">
-      <img src="../../assets/icon/bitcoin/hangqing.svg" alt="">
-      <img src="../../assets/icon/bitcoin/den.svg" alt="">
-    </div>
+        <img class="fc333333" src="../../assets/icon/bitcoin/menu.svg" alt="">
+        <div class="pf600 fs18 fc121212">BTCUSDT 永续</div>
+      </div>
+      <div class="menu-right fc333333">
+
+        <img src="../../assets/icon/bitcoin/jisuanqi.svg" alt="" @click="$router.push({name: 'calculator'})">
+        <img src="../../assets/icon/bitcoin/hangqing.svg" alt="">
+        <img src="../../assets/icon/bitcoin/den.svg" alt="" @click="$router.push({ name: 'BitcoinFunctions' })">
+      </div>
     </div>
     <div class="menu-bottom">
       <div class="pf500 fs12 menu-leftb">
@@ -39,13 +40,13 @@
         <div>0.003%/1:57:32</div>
       </div>
     </div>
-    <div class="menu-content" >
-<!--      //左边-->
+    <div class="menu-content">
+      <!--      //左边-->
       <div class="menu-content-l">
         <div class="menu-content-lb pf400 fs14 fc666666">
           <span>价格</span><span>数量(USDT)</span>
         </div>
-        <div  class="menu-content-lb1">
+        <div class="menu-content-lb1">
           <div class="menu-content-lb1l pf400 fs14 fcFF7171">
             <span class="">40,166.82</span>
             <span>40,166.82</span>
@@ -75,7 +76,7 @@
           <p class="pf600 fs16 fcDF384C">5,678.00</p>
           <p class="fs12 fcA8A8A8 pf400">1,678.00</p>
         </div>
-        <div  class="menu-content-lb1">
+        <div class="menu-content-lb1">
           <div class="menu-content-lb1l pf400 fs14 fcFF7171">
             <span class="">40,166.82</span>
             <span>40,166.82</span>
@@ -103,7 +104,7 @@
         </div>
         <div class="menu-content-lb1">
           <div class="menu-content-lb1l pf400 fs12 fc333333" @click="isPickerVisible = true">
-            <span class="fs12">{{displayLabel}}</span>
+            <span class="fs12">{{ displayLabel }}</span>
             <img src="../../assets/icon/bitcoin/shendul.svg" alt="">
 
           </div>
@@ -116,139 +117,130 @@
       </div>
       <assetlessStateData v-if="isassetlessState"></assetlessStateData>
       <SellTradingStatusData v-if="isassetlessState"></SellTradingStatusData>
-<!--      //右边-->
-      <div  class="menu-content-r">
+      <!--      //右边-->
+      <div class="menu-content-r">
         <div class="menu-content-rb pf400 fs14">
-         <div class="menu-content-rb1 fs14 fc333333">
+          <div class="menu-content-rb1 fs14 fc333333" @click="showInfo = true">
             <img src="../../assets/icon/bitcoin/quancang.svg" alt="">
-            <span>全仓</span>
-         </div>
-         <img src="../../assets/icon/bitcoin/quangcang1.svg" alt="">
+            <span>{{ selectedLabel1 }}</span>
+          </div>
+          <div @click="showModal1 = true" style="font-size: 12px; margin-right: 12px;">
+            <VanIcon :style="{ fontWeight: 'bold' }" :name="showModal1 ? 'arrow-up' : 'arrow-down'"/>
+          </div>
 
 
-      </div>
+        </div>
         <div class="menu-content-rb pf400 fs14">
-         <div class="menu-content-rb1 fs14 fc333333">
+          <div class="menu-content-rb1 fs14 fc333333" @click="showModal3 = true">
             <img src="../../assets/icon/bitcoin/quancang.svg" alt="">
-            <span>市价</span>
-         </div>
-         <img src="../../assets/icon/bitcoin/quangcang1.svg" alt="">
-      </div>
+            <span>{{ selectedLabel2 }}</span>
+          </div>
+          <div @click="showModal2 = true" style="font-size: 12px; margin-right: 12px;">
+            <VanIcon :style="{ fontWeight: 'bold' }" :name="showModal2 ? 'arrow-up' : 'arrow-down'"/>
+          </div>
+
+        </div>
         <div class="menu-content-rb pf400 fs14">
-         <div class="menu-content-rb1 fs14 fc333333">
+          <div class="menu-content-rb1 fs14 fc333333">
             <span>125000</span>
-         </div>
+          </div>
           <span>最优价</span>
-      </div>
+        </div>
         <div class="menu-content-rb pf400 fs14 fc333333">≈25.2250 USDT</div>
         <div class="menu-content-rb pf400 fs14">
-         <div class="menu-content-rb1 fs14 fc333333">
+          <div class="menu-content-rb1 fs14 fc333333">
             <span class="menu-content-rb1s fc999999">数量</span>
-         </div>
-         <span>USDT</span>
-      </div>
+          </div>
+          <span>USDT</span>
+        </div>
         <div class="menu-content-rb pf400 fs14">
-         <div class="menu-content-rb1 fs14 fc333333">
-           <span class="menu-content-rb1s fc333333">可用</span>
-         </div>
-         <div class="menu-content-rb1">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span class="menu-content-rb1s fc333333">可用</span>
+          </div>
+          <div class="menu-content-rb1">
             <span>0</span>
             <span>USDT</span>
             <img class="fs16" src="../../assets/icon/bitcoin/qianbao1.svg" alt="">
-         </div>
+          </div>
 
-      </div>
+        </div>
         <div class="menu-content-rb pf400 fs14">
-         <div class="menu-content-rb1 fs14 fc333333">
-           <span class="menu-content-rb1s fc333333">倍数</span>
-         </div>
-         <div class="menu-content-rb1" @click="showLeverageModal = true">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span class="menu-content-rb1s fc333333">倍数</span>
+          </div>
+          <div class="menu-content-rb1" @click="showLeverageModal = true">
             <span></span>
             <span>{{ selectedLeverage }}X</span>
             <span>更多</span>
-         </div>
-
-      </div>
+          </div>
+        </div>
         <div class="menu-content-rb pf400 fs14">
-         <div class="menu-content-rb1 fs14 fc333333">
-<!--           <label class="custom-checkbox-container">-->
-<!--            <input type="checkbox" checked="checked">-->
-<!--            <span class="checkmark"></span>-->
-<!--            </label>-->
-           <van-checkbox
-              v-model="isEnabled"
-              shape="square"
-              checked-color="#DC4653"
-              icon-size="16px"
-           >
-           </van-checkbox>
-<!--           <input class="fs16" type="checkbox" id="bike" value="Bike">-->
-           <span class="menu-content-rb1s fc333333">只减仓</span>
-         </div>
-         <div class="menu-content-rb1" @click="showModal = true">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <van-checkbox
+                v-model="isEnabled"
+                shape="square"
+                checked-color="#DC4653"
+                icon-size="16px"
+            >
+            </van-checkbox>
+            <span class="menu-content-rb1s fc333333">只减仓</span>
+          </div>
+          <div class="menu-content-rb1" @click="showModal = true">
             <span></span>
             <span>{{ currentType }}</span>
-            <img class="fs16" src="../../assets/icon/bitcoin/quangcang1.svg" alt="">
-         </div>
-
-      </div>
+            <div style="font-size: 12px;">
+              <VanIcon :style="{ fontWeight: 'bold' }" :name="showModal ? 'arrow-up' : 'arrow-down'"/>
+            </div>
+            <!--            <img class="fs16" src="../../assets/icon/bitcoin/quangcang1.svg" alt="">-->
+          </div>
+        </div>
         <TakeProfitsTopLoss v-show="!isEnabled"></TakeProfitsTopLoss>
 
         <div class="menu-content-rb pf400 fs14">
-         <div class="menu-content-rb1 fs14 fc333333">
-           <span class="menu-content-rb1s fc333333">可用</span>
-         </div>
-         <div class="menu-content-rb1">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span class="menu-content-rb1s fc333333">可用</span>
+          </div>
+          <div class="menu-content-rb1">
             <span>0</span>
             <span>USDT</span>
-
-         </div>
-
-      </div>
+          </div>
+        </div>
         <div class="menu-content-rb pf400 fs14">
-         <div class="menu-content-rb1 fs14 fc333333">
-           <span class="menu-content-rb1s fc333333">保证金</span>
-         </div>
-         <div class="menu-content-rb1">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span class="menu-content-rb1s fc333333">保证金</span>
+          </div>
+          <div class="menu-content-rb1">
             <span>0</span>
             <span>USDT</span>
-
-         </div>
-
-      </div>
-
+          </div>
+        </div>
         <div class="menu-content-rb pf400 fs14" @click="showConfirm = true">
           <div class="pf400 fs16 fcFFFFFF">买入(做多)</div>
-
         </div>
-
         <div class="menu-content-rb pf400 fs14">
-         <div class="menu-content-rb1 fs14 fc333333">
-           <span class="menu-content-rb1s fc333333">可用</span>
-         </div>
-         <div class="menu-content-rb1">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span class="menu-content-rb1s fc333333">可用</span>
+          </div>
+          <div class="menu-content-rb1">
             <span>0</span>
             <span>USDT</span>
-
-         </div>
-
-      </div>
+          </div>
+        </div>
         <div class="menu-content-rb pf400 fs14">
-         <div class="menu-content-rb1 fs14 fc333333">
-           <span class="menu-content-rb1s fc333333">保证金</span>
-         </div>
-         <div class="menu-content-rb1">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span class="menu-content-rb1s fc333333">保证金</span>
+          </div>
+          <div class="menu-content-rb1">
             <span>0</span>
             <span>USDT</span>
-
-         </div>
-
-      </div>
+          </div>
+        </div>
         <div class="menu-content-rb pf400 fs14">
           <div class="pf400 fs16 fcFFFFFF" @click="showConfirm = true">卖出(做空)</div>
         </div>
       </div>
     </div>
+    <!--    订单列表组件-->
     <sellOrder></sellOrder>
     <!--    //各种弹窗-->
     <div v-if="isassetlessState">
@@ -279,64 +271,177 @@
           v-model="currentType"
       ></OrderTimeSheet>
     </div>
-  </div>
+    <div>
+      <MarginInfoSheet
+          v-model:visible="showInfo"
+      ></MarginInfoSheet>
+    </div>
+    <div>
+      <FundingOptions
+          v-model:visible="showModal1"
+          :selected-id="currentId1"
+          @confirm="handleConfirm1">
+      </FundingOptions>
+    </div>
 
+    <div>
+      <OrderType
+          v-model:visible="showModal2"
+          :selected-id="currentId2"
+          @confirm="handleConfirm2"
+      ></OrderType>
+    </div>
+
+    <div>
+      <LimitOrderModal
+          v-model:visible="showModal3"
+      ></LimitOrderModal>
+    </div>
+
+    <!--    <div>-->
+    <!--      <InsufficientBalance-->
+    <!--          v-model:visible="showRechargeModal"-->
+    <!--          @confirm="handleGoRecharge"-->
+    <!--      ></InsufficientBalance>-->
+    <!--    </div>-->
+  </div>
+<!--  <router-view v-slot="{ Component }">-->
+<!--    <keep-alive :include="['BitcoinFunctions', 'Calculator']">-->
+<!--      <component :is="Component" />-->
+<!--    </keep-alive>-->
+<!--  </router-view>-->
+  <router-view></router-view>
 </template>
 <script setup>
-    import { Checkbox as VanCheckbox } from 'vant';
-    // import { Icon as VanIcon, } from 'vant';
-    import { defineAsyncComponent } from 'vue';
-    import { ref ,computed} from 'vue';
-    // 懒加载多个组件
-    const priceLimit = defineAsyncComponent(() => import("./components/priceLimit.vue"));
-    const assetlessState = defineAsyncComponent(() => import("./components/assetlessState.vue"));
-    const assetlessStateData = defineAsyncComponent(() => import("./components/assetlessStateData.vue"));
-    const sellOrder = defineAsyncComponent(() => import('./components/sellOrder.vue'));
-    const SellTradingStatusData = defineAsyncComponent(() => import('./components/SellTradingStatusData.vue'));
-    const TakeProfitsTopLoss = defineAsyncComponent(() => import('./components/TakeProfitsTopLoss.vue'));
-    const ChooseThisDepth = defineAsyncComponent(() => import('./components/ChooseThisDepth.vue'));
-    const LeveragePopup = defineAsyncComponent(() => import('./components/LeveragePopup.vue'));
-    const OrderConfirmPopup = defineAsyncComponent(() => import('./components/OrderConfirmPopup.vue'));
-    const OrderTimeSheet = defineAsyncComponent(() => import('./components/OrderTimeSheet.vue'));
-    //GTC弹框
-    // 控制弹窗显示
-    const showModal = ref(false);
-
-    // 选中的值,默认为 GTC
-    const currentType = ref('GTC');
-
-
-    // --- 深度弹窗 ---
-    const isPickerVisible = ref(false); // 控制弹窗开关
-    const currentDepth = ref('depth1'); // 当前选中的深度
-    const depthMap = {
-      'depth1': '深度1',
-      'depth2': '深度2',
-      'depth3': '深度3',
-    };
-    const displayLabel = computed(() => depthMap[currentDepth.value] || '请选择');
-
-    //控制止盈止损
-    const isEnabled = ref(false);
-
-    //控制倍数
-    // 控制弹窗显示
-    const showLeverageModal = ref(false);
-    // 存储当前选中的倍数,默认 100
-    const selectedLeverage = ref(100);
-    // 处理子组件回传的确认事件
-    const handleConfirm = (value) => {
-      console.log('用户选择了:', value);
-      selectedLeverage.value = value;
-      // 这里可以继续添加发送 API 请求的逻辑
-    };
-
-    //做多买入
-    const showConfirm = ref(false);
-    const onOrderConfirmed = () => {
-      console.log('订单已提交');
-      // 这里可以添加 Toast 提示
-    };
+        import {Checkbox as VanCheckbox, Icon as VanIcon} from 'vant';
+        import {computed, defineAsyncComponent, ref} from 'vue';
+        import { useRouter } from 'vue-router'
+
+        const router = useRouter()
+
+        // 懒加载多个组件
+        const priceLimit = defineAsyncComponent(() => import("./components/priceLimit.vue"));
+        const assetlessState = defineAsyncComponent(() => import("./components/assetlessState.vue"));
+        const assetlessStateData = defineAsyncComponent(() => import("./components/assetlessStateData.vue"));
+        //订单列表组件
+        const sellOrder = defineAsyncComponent(() => import('./components/sellOrder.vue'));
+        const SellTradingStatusData = defineAsyncComponent(() => import('./components/SellTradingStatusData.vue'));
+        const TakeProfitsTopLoss = defineAsyncComponent(() => import('./components/TakeProfitsTopLoss.vue'));
+        const ChooseThisDepth = defineAsyncComponent(() => import('./components/ChooseThisDepth.vue'));
+        //控制倍数组件
+        const LeveragePopup = defineAsyncComponent(() => import('./components/LeveragePopup.vue'));
+        const OrderConfirmPopup = defineAsyncComponent(() => import('./components/OrderConfirmPopup.vue'));
+        const OrderTimeSheet = defineAsyncComponent(() => import('./components/OrderTimeSheet.vue'));
+        //全仓逐仓组件
+        const MarginInfoSheet = defineAsyncComponent(() => import('./components/MarginInfoSheet.vue'));
+        const FundingOptions = defineAsyncComponent(() => import('./components/FundingOptions.vue'));
+        const OrderType = defineAsyncComponent(() => import('./components/OrderType.vue'));
+        //余额不足提示
+        // const InsufficientBalance = defineAsyncComponent(() => import('./StatusComponent/InsufficientBalance.vue'));
+        const LimitOrderModal = defineAsyncComponent(() => import('./components/LimitOrderModal.vue'));
+        /*常用功能*/
+        // 跳转到子路由
+        const openFunctions = () => {
+          router.push({ name: 'BitcoinFunctions' })
+        }
+
+       /*市价说明*/
+        const showModal3 = ref(false);
+
+        // //余额不足提示
+        //   // 控制弹窗显示的变量
+        // const showRechargeModal = ref(false);
+        //
+        //   // 处理点击“立即充币”后的逻辑
+        // const handleGoRecharge = () => {
+        //   // console.log('用户点击了立即充币,正在跳转充值页面...');
+        //   // 这里写你的跳转逻辑,例如: router.push('/recharge')
+        // };
+
+        /*订单类型选项*/
+        const showModal2 = ref(false);
+
+        // 定义状态用于存储
+        const currentId2 = ref(1); // 默认选中第一个
+        const selectedLabel2 = ref('市价'); // 默认值
+        const selectedUnit2 = ref('%');      // 默认值
+
+        /*回调函数:子组件选中后触发*/
+        const handleConfirm2 = (item) => {
+          // console.log('子组件返回的对象:', item);
+
+          // 保存ID用于下次打开时回显高亮
+          currentId2.value = item.id;
+          // const a = item.label.slice(-2)
+
+          // 核心需求:在这里将值“拆开”为两个字符串
+          selectedLabel2.value = item.label.slice(0, 2); // 字符串1: "涨跌幅"
+          selectedUnit2.value = item.unit;   // 字符串2: "%"
+        };
+
+        /* 全仓逐仓选项*/
+        const showModal1 = ref(false);
+
+        // 定义状态用于存储
+        const currentId1 = ref(1); // 默认选中第一个
+        const selectedLabel1 = ref('全仓'); // 默认值
+        const selectedUnit1 = ref('%');      // 默认值
+
+        // 回调函数:子组件选中后触发
+        const handleConfirm1 = (item) => {
+          // console.log('子组件返回的对象:', item);
+
+          // 保存ID用于下次打开时回显高亮
+          currentId1.value = item.id;
+          // const a = item.label.slice(-2)
+
+          // 核心需求:在这里将值“拆开”为两个字符串
+          selectedLabel1.value = item.label.slice(0, 2); // 字符串1: "涨跌幅"
+          selectedUnit1.value = item.unit;   // 字符串2: "%"
+        };
+
+       /* // 全仓逐仓说明*/
+        const showInfo = ref(false);
+
+        /*//GTC弹框*/
+        // 控制弹窗显示
+        const showModal = ref(false);
+
+        // 选中的值,默认为 GTC
+        const currentType = ref('GTC');
+
+
+       /* // --- 深度弹窗 ---*/
+        const isPickerVisible = ref(false); // 控制弹窗开关
+        const currentDepth = ref('depth1'); // 当前选中的深度
+        const depthMap = {
+          'depth1': '深度1',
+          'depth2': '深度2',
+          'depth3': '深度3',
+        };
+        const displayLabel = computed(() => depthMap[currentDepth.value] || '请选择');
+
+        /*控制止盈止损*/
+        const isEnabled = ref(false);
+
+        /*控制倍数*/
+        // 控制弹窗显示
+        const showLeverageModal = ref(false);
+        // 存储当前选中的倍数,默认 100
+        const selectedLeverage = ref(100);
+        // 处理子组件回传的确认事件
+        const handleConfirm = (value) => {
+          // console.log('用户选择了:', value);
+          selectedLeverage.value = value;
+          // 这里可以继续添加发送 API 请求的逻辑
+        };
+
+        /*做多买入*/
+        const showConfirm = ref(false);
+        const onOrderConfirmed = () => {
+          // console.log('订单已提交');
+          // 这里可以添加 Toast 提示
+        };
 
 
 </script>
@@ -345,463 +450,552 @@
 /* 容器基础样式,基于 375px 设计稿 */
 :deep(.van-checkbox__icon--square .van-icon) {
   /* 这里的 4px 是圆角大小,数值越大越圆 */
-  border-radius: 2px !important;}
-  .market {
+  border-radius: 2px !important;
+}
+
+.market {
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-start;
+  align-items: center;
+  margin-bottom: 100px;
+  width: 100%;
+  z-index: 1;
+
+  .market-nav {
     display: flex;
-    flex-direction: column;
-    justify-content: flex-start;
+    flex-direction: row;
+    justify-content: space-between;
     align-items: center;
-    margin-bottom: 100px;
-    width: 100%;
+    margin-top: 21px;
+    width: 345px;
+    height: 24px;
 
-    .market-nav {
+    .nav-left {
       display: flex;
       flex-direction: row;
-      justify-content: space-between;
-      align-items: center;
-      margin-top: 21px;
-      width: 345px;
+      justify-content: flex-start;
+      align-items: flex-end;
+      width: 349px;
       height: 24px;
 
-      .nav-left {
-        display: flex;
-        flex-direction: row;
-        justify-content: flex-start;
-        align-items: flex-end;
-        width: 349px;
-        height: 24px;
-        div:nth-child(1){
-          position: relative;
-          .active-line{
-                position: absolute;
-                bottom: -6px;
-                left: 50%;
-                transform: translateX(-50%);
-                width: 20px;
-                height: 3px;
-                background-color: #323233;
-                border-radius: 2px;
-          }
-        }
-
-        .sys-notifi {
-          margin-left: 35px;
+      div:nth-child(1) {
+        position: relative;
+
+        .active-line {
+          position: absolute;
+          bottom: -6px;
+          left: 50%;
+          transform: translateX(-50%);
+          width: 20px;
+          height: 3px;
+          background-color: #323233;
+          border-radius: 2px;
         }
       }
 
-      .nav-right {
-        width: 20px;
-        height: 20px;
+      .sys-notifi {
+        margin-left: 35px;
       }
     }
-    .menu {
+
+    .nav-right {
+      width: 20px;
+      height: 20px;
+    }
+  }
+
+  .menu {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    margin-top: 21px;
+    width: 345px;
+    height: 24px;
+
+    .menu-left {
       display: flex;
       flex-direction: row;
-      justify-content: space-between;
+      justify-content: flex-start;
       align-items: center;
-      margin-top: 21px;
-      width: 345px;
-      height: 24px;
+      line-height: 0px;
 
-      .menu-left{
+      img {
+        margin: 0px 10px 0 0;
+      }
+    }
+
+    .menu-right {
+      img {
+        margin-left: 14px;
+      }
+    }
+  }
+
+  .menu-bottom {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    margin-top: 8px;
+    width: 345px;
+
+    .menu-leftb {
+      width: 61px;
+      height: 25px;
+      background-color: #45b26b;
+      border-radius: 5px;
+      color: #ffffff;
+      text-align: center;
+      line-height: 25px;
+    }
+
+    .menu-rightb {
+      text-align: right;
+    }
+  }
+
+  .menu-content {
+    width: 100%;
+    max-width: 345px;
+    display: flex;
+    flex-direction: row;
+    margin-top: 8px;
+
+    .menu-content-l {
+      flex: 1;
+
+      .menu-content-lb {
         display: flex;
         flex-direction: row;
-        justify-content: flex-start;
-        align-items: center;
-        line-height:0px;
-        img{
-          margin: 0px 10px 0 0;
-        }
+        justify-content: space-between;
+        padding-right: 14px;
       }
-      .menu-right{
-        img{
-          margin-left: 14px;
+
+      .menu-content-lb1 {
+        margin-top: 11px;
+        display: flex;
+        flex-direction: row;
+        justify-content: space-between;
+        padding-right: 14px;
+
+        .menu-content-lb1l {
+          display: flex;
+          flex-direction: column;
+          line-height: 22px;
         }
-      }
-    }
 
-    .menu-bottom {
-       display: flex;
-      flex-direction: row;
-      justify-content: space-between;
-      align-items: center;
-      margin-top: 8px;
-      width: 345px;
-      .menu-leftb{
-        width:61px;
-        height: 25px;
-        background-color: #45b26b;
-        border-radius: 5px;
-        color: #ffffff;
-        text-align: center;
-        line-height: 25px;
+        .menu-content-lb1r {
+          display: flex;
+          flex-direction: column;
+          line-height: 22px;
+        }
       }
-      .menu-rightb{
-        text-align: right;
+
+      .menu-content-lb1:nth-child(4) {
+        .menu-content-lb1l {
+          color: #45b26b;
+        }
       }
-    }
 
-    .menu-content{
-      width: 100%;
-      max-width: 345px;
-      display: flex;
-      flex-direction: row;
-      margin-top: 8px;
-      .menu-content-l{
-        flex: 1;
-        .menu-content-lb{
+      .menu-content-lb1:nth-child(5) {
+        .menu-content-lb1l {
+          width: 100%;
           display: flex;
           flex-direction: row;
           justify-content: space-between;
-          padding-right: 14px;
+          align-items: center;
+          background-color: #f5f5f5;
+          border-radius: 6px;
+          height: 24px;
+          padding: 0 5px 0 13px;
+
+
+        }
+
+        .menu-content-lb1r {
+          margin-left: 15px;
         }
-        .menu-content-lb1{
-          margin-top: 11px;
+      }
+
+      .menu-content-lb2 {
+        margin-top: 8px;
+        line-height: 16px;
+        //span:nth-child(2){
+        //  //border-style: dashed;
+        //}
+      }
+    }
+
+    .menu-content-r {
+      flex: 1;
+      flex-basis: 63.5px;
+      max-width: 204.25px;
+
+      .menu-content-rb:nth-of-type(4) {
+        background-color: transparent;
+        height: 20px;
+
+      }
+
+      .menu-content-rb {
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        background-color: #f5f5f5;
+        border-radius: 6px;
+        margin-bottom: 8px;
+        height: 38px;
+
+        span {
+          padding-right: 12px;
+
+        }
+
+        img {
+          padding-right: 12px;
+          //height: 16px;
+          //width: 16px;
+        }
+
+        .menu-content-rb1 {
+          text-align: center;
+          margin-left: 12px;
           display: flex;
-          flex-direction: row;
-          justify-content: space-between;
-           padding-right: 14px;
-          .menu-content-lb1l{
-            display: flex;
-            flex-direction: column;
-            line-height: 22px;
-          }
-          .menu-content-lb1r{
-            display: flex;
-            flex-direction: column;
-            line-height: 22px;
+          align-content: center;
+          justify-content: center;
+          align-items: center;
+
+          img {
+            padding-right: 6px;
+
           }
+
         }
-        .menu-content-lb1:nth-child(4){
-          .menu-content-lb1l{
-            color: #45b26b;
-          }
+      }
+
+      .menu-content-rb:nth-of-type(6) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          margin-left: 0;
         }
-        .menu-content-lb1:nth-child(5){
-          .menu-content-lb1l{
-            width: 100%;
-            display: flex;
-            flex-direction: row;
-            justify-content: space-between;
-            align-items: center;
-            background-color: #f5f5f5;
-            border-radius: 6px;
-            height: 24px;
-            padding: 0 5px 0 13px;
 
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(1) {
 
+            font-size: 12px;
           }
-          .menu-content-lb1r{
-            margin-left: 15px;
+
+          span:nth-child(2) {
+            margin: 0 9px 0 9px;
+            font-size: 12px;
           }
         }
 
-        .menu-content-lb2{
-          margin-top: 8px;
-          line-height: 16px;
-          //span:nth-child(2){
-          //  //border-style: dashed;
-          //}
+        span {
+          padding-right: 0;
         }
-      }
-      .menu-content-r{
-        flex: 1;
-        flex-basis: 63.5px;
-        max-width: 204.25px;
-        .menu-content-rb:nth-of-type(4){
-           background-color: transparent;
-            height:20px;
-
-        }
-        .menu-content-rb {
-            width: 100%;
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-            background-color: #f5f5f5;
-            border-radius: 6px;
-            margin-bottom: 8px;
-            height: 38px;
-          span{
-              padding-right: 12px;
-
-            }
-          img{
-            padding-right: 12px;
-            //height: 16px;
-            //width: 16px;
-          }
 
-          .menu-content-rb1{
-            text-align: center;
-            margin-left: 12px;
-            //padding-right: 12px;
+        img {
+          padding-right: 0;
+        }
 
-            img{
-              padding-right: 6px;
+      }
 
-            }
+      .menu-content-rb:nth-of-type(7) {
+        background-color: transparent;
+        height: 20px;
 
+        .menu-content-rb1 {
+          margin-left: 0;
+        }
+
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 9px 0 9px;
+            font-size: 12px;
           }
+
+          span:nth-child(3) {
+            color: #df384c;
           }
-        .menu-content-rb:nth-of-type(6){
-           background-color: transparent;
-            height:20px;
-           .menu-content-rb1{
-              margin-left: 0;
-            }
-          .menu-content-rb1:nth-child(2){
-            span:nth-child(1){
-
-               font-size: 12px;
-            }
-            span:nth-child(2){
-              margin:0 9px 0 9px;
-               font-size: 12px;
-            }
-          }
-           span{
-              padding-right: 0;
-            }
-          img{
-            padding-right: 0;
-          }
+        }
 
+        span {
+          padding-right: 0;
         }
-        .menu-content-rb:nth-of-type(7){
-           background-color: transparent;
-            height:20px;
-           .menu-content-rb1{
-              margin-left: 0;
-            }
-          .menu-content-rb1:nth-child(2){
-            span:nth-child(2){
-              margin:0 9px 0 9px;
-              font-size: 12px;
-            }
-            span:nth-child(3){
-              color: #df384c;
-            }
+
+        img {
+          padding-right: 0;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(8) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          display: flex;
+          align-items: center;
+          height: 24px;
+          margin-left: 0;
+          align-content: center;
+
+          input {
+            width: 16px;
+            height: 16px;
+            margin-right: 5px;
           }
-           span{
-              padding-right: 0;
-            }
-          img{
-            padding-right: 0;
+        }
+
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 9px 0 9px;
           }
+        }
+
+        .menu-content-rb1s {
+          margin-left: 6px;
+        }
 
+        span {
+          padding-right: 0;
         }
-        .menu-content-rb:nth-of-type(8){
-           background-color: transparent;
-            height:20px;
-           .menu-content-rb1{
-             display: flex;
-             align-items: center;
-             height: 24px;
-              margin-left: 0;
-             align-content: center;
-             input{
-                width:16px;
-               height: 16px;
-               margin-right: 5px;
-             }
-            }
-          .menu-content-rb1:nth-child(2){
-            span:nth-child(2){
-              margin:0 9px 0 9px;
-            }
+
+        img {
+          padding-right: 0;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(9) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          display: flex;
+          align-items: center;
+          height: 24px;
+          margin-left: 0;
+          align-content: center;
+
+          input {
+            width: 16px;
+            height: 16px;
+            margin-right: 5px;
           }
-          .menu-content-rb1s{
-            margin-left: 6px;
+
+          img {
+            padding-left: 5px;
+            font-size: 16px;
+            padding-top: 2px;
           }
-           span{
-              padding-right: 0;
-            }
-          img{
-            padding-right: 0;
+        }
+
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 9px 0 9px;
           }
+        }
 
+        span {
+          padding-right: 0;
         }
-        .menu-content-rb:nth-of-type(9){
-           background-color: transparent;
-            height:20px;
-           .menu-content-rb1{
-             display: flex;
-             align-items: center;
-             height: 24px;
-              margin-left: 0;
-             align-content: center;
-             input{
-                width:16px;
-               height: 16px;
-               margin-right: 5px;
-             }
-             img{
-               padding-left: 5px;
-               font-size: 16px;
-               padding-top: 2px;
-             }
-            }
-          .menu-content-rb1:nth-child(2){
-            span:nth-child(2){
-              margin:0 9px 0 9px;
-            }
-          }
-           span{
-              padding-right: 0;
-            }
-          img{
-            padding-right: 0;
-          }
 
+        img {
+          padding-right: 0;
         }
-        .menu-content-rb:nth-of-type(10){
-           background-color: transparent;
-            height:20px;
-           .menu-content-rb1{
-             display: flex;
-             align-items: center;
-             height: 24px;
-              margin-left: 0;
-             align-content: center;
-             input{
-                width:16px;
-               height: 16px;
-               margin-right: 5px;
-             }
-             img{
-               padding-left: 5px;
-               font-size: 16px;
-               padding-top: 2px;
-             }
-            }
-          .menu-content-rb1:nth-child(2){
-            span:nth-child(2){
-              margin:0 0px 0 5px;
-            }
+
+      }
+
+      .menu-content-rb:nth-of-type(10) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          display: flex;
+          align-items: center;
+          height: 24px;
+          margin-left: 0;
+          align-content: center;
+
+          input {
+            width: 16px;
+            height: 16px;
+            margin-right: 5px;
           }
-           span{
-              padding-right: 0;
-            }
-          img{
-            padding-right: 0;
+
+          img {
+            padding-left: 5px;
+            font-size: 16px;
+            padding-top: 2px;
           }
+        }
+
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 0px 0 5px;
+          }
+        }
 
+        span {
+          padding-right: 0;
         }
-        .menu-content-rb:nth-of-type(11){
-           background-color: transparent;
-            height:20px;
-           .menu-content-rb1{
-             display: flex;
-             align-items: center;
-             height: 24px;
-              margin-left: 0;
-             align-content: center;
-             input{
-                width:16px;
-               height: 16px;
-               margin-right: 5px;
-             }
-             img{
-               padding-left: 5px;
-               font-size: 16px;
-               padding-top: 2px;
-             }
-            }
-          .menu-content-rb1:nth-child(2){
-            span:nth-child(2){
-              margin:0 0px 0 5px;
-            }
+
+        img {
+          padding-right: 0;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(11) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          display: flex;
+          align-items: center;
+          height: 24px;
+          margin-left: 0;
+          align-content: center;
+
+          input {
+            width: 16px;
+            height: 16px;
+            margin-right: 5px;
           }
-           span{
-              padding-right: 0;
-            }
-          img{
-            padding-right: 0;
+
+          img {
+            padding-left: 5px;
+            font-size: 16px;
+            padding-top: 2px;
+          }
+        }
+
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 0px 0 5px;
           }
+        }
+
+        span {
+          padding-right: 0;
+        }
+
+        img {
+          padding-right: 0;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(12) {
+        background-color: #45b26b;
 
+        div {
+          margin: auto;
         }
-        .menu-content-rb:nth-of-type(12){
-           background-color: #45b26b;
-           div{margin: auto;}
-
-        }
-        .menu-content-rb:nth-of-type(13){
-           background-color: transparent;
-            height:20px;
-           .menu-content-rb1{
-             display: flex;
-             align-items: center;
-             height: 24px;
-              margin-left: 0;
-             align-content: center;
-             input{
-                width:16px;
-               height: 16px;
-               margin-right: 5px;
-             }
-             img{
-               padding-left: 5px;
-               font-size: 16px;
-               padding-top: 2px;
-             }
-            }
-          .menu-content-rb1:nth-child(2){
-            span:nth-child(2){
-              margin:0 0px 0 5px;
-            }
+
+      }
+
+      .menu-content-rb:nth-of-type(13) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          display: flex;
+          align-items: center;
+          height: 24px;
+          margin-left: 0;
+          align-content: center;
+
+          input {
+            width: 16px;
+            height: 16px;
+            margin-right: 5px;
           }
-           span{
-              padding-right: 0;
-            }
-          img{
-            padding-right: 0;
+
+          img {
+            padding-left: 5px;
+            font-size: 16px;
+            padding-top: 2px;
           }
+        }
 
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 0px 0 5px;
+          }
+        }
+
+        span {
+          padding-right: 0;
+        }
+
+        img {
+          padding-right: 0;
         }
-        .menu-content-rb:nth-of-type(14){
-           background-color: transparent;
-            height:20px;
-           .menu-content-rb1{
-             display: flex;
-             align-items: center;
-             height: 24px;
-              margin-left: 0;
-             align-content: center;
-             input{
-                width:16px;
-               height: 16px;
-               margin-right: 5px;
-             }
-             img{
-               padding-left: 5px;
-               font-size: 16px;
-               padding-top: 2px;
-             }
-            }
-          .menu-content-rb1:nth-child(2){
-            span:nth-child(2){
-              margin:0 0px 0 5px;
-            }
+
+      }
+
+      .menu-content-rb:nth-of-type(14) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          display: flex;
+          align-items: center;
+          height: 24px;
+          margin-left: 0;
+          align-content: center;
+
+          input {
+            width: 16px;
+            height: 16px;
+            margin-right: 5px;
           }
-           span{
-              padding-right: 0;
-            }
-          img{
-            padding-right: 0;
+
+          img {
+            padding-left: 5px;
+            font-size: 16px;
+            padding-top: 2px;
           }
+        }
 
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 0px 0 5px;
+          }
         }
-        .menu-content-rb:nth-of-type(15){
-           background-color: #df384c;
-           div{margin: auto;}
 
+        span {
+          padding-right: 0;
+        }
+
+        img {
+          padding-right: 0;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(15) {
+        background-color: #df384c;
+
+        div {
+          margin: auto;
         }
-        //.van-dropdown-menu__bar{
-        //  width: 214px;
-        //}
 
       }
+
+      //.van-dropdown-menu__bar{
+      //  width: 214px;
+      //}
+
     }
   }
+}
 </style>

+ 176 - 0
src/views/bitcoin/StatusComponent/ConfirmPing.vue

@@ -0,0 +1,176 @@
+<template>
+  <Teleport to="body">
+    <transition name="modal-fade">
+      <div v-if="visible" class="modal-mask" @click="handleClose">
+
+        <div class="modal-container" @click.stop>
+
+          <div class="modal-title">温馨提示</div>
+
+          <div class="modal-icon">
+            <img src="../../../assets/icon/bitcoin/querenpin.svg" alt="">
+          </div>
+
+          <p class="modal-text">确定要平仓吗?</p>
+
+          <button class="btn-primary" @click="handleConfirm">
+            确认
+          </button>
+
+          <button class="btn-secondary" @click="handleClose">
+            取消
+          </button>
+
+        </div>
+      </div>
+    </transition>
+  </Teleport>
+</template>
+
+<script setup>
+import { defineProps, defineEmits } from 'vue';
+import {useRouter} from "vue-router";
+  const router = useRouter();
+
+
+// 接收父组件传来的可见性状态
+defineProps({
+  visible: {
+    type: Boolean,
+    required: true
+  }
+});
+
+// 定义向父组件发送的事件
+const emit = defineEmits(['update:visible', 'confirm']);
+
+// 关闭弹窗
+const handleClose = () => {
+  // 发送事件让父组件把 visible 改为 false
+  emit('update:visible', false);
+};
+
+// 点击确认按钮
+const handleConfirm = () => {
+  console.log("lllll")
+  // 先触发确认操作,比如跳转充值页面
+  window.location.reload();
+  // router.replace({ path: '/bitcoin', query: { to: router.currentRoute.value.fullPath } })
+  // router.push('/bitcoin')
+  // emit('confirm');
+  // // 然后关闭弹窗
+  // handleClose();
+};
+</script>
+
+<style scoped>
+/* --- 遮罩层 --- */
+.modal-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, 0.6); /* 深色半透明背景 */
+  display: flex;
+  align-items: center; /* 垂直居中 */
+  justify-content: center; /* 水平居中 */
+  z-index: 9999; /* 保证在最上层 */
+  padding: 20px; /* 防止小屏贴边 */
+}
+
+/* --- 弹窗容器 --- */
+.modal-container {
+  width: 100%;
+  max-width: 315px; /* 在375屏上两边留有约30px间距,视觉效果舒适 */
+  background: #fff;
+  border-radius: 16px; /* 大圆角 */
+  padding: 24px 20px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  box-sizing: border-box;
+  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
+}
+
+/* --- 标题 --- */
+.modal-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #111827;
+  margin-bottom: 20px;
+}
+
+/* --- 图标区域 --- */
+.modal-icon {
+  margin-bottom: 16px;
+  /* 如果用图片,可以设置 width/height */
+}
+
+/* --- 文本 --- */
+.modal-text {
+  font-size: 15px;
+  color: #6B7280; /* 灰色的提示文字 */
+  margin: 0 0 32px 0; /* 底部留出较大空间给按钮 */
+}
+
+/* --- 通用按钮样式 --- */
+button {
+  border: none;
+  background: none;
+  font-size: 16px;
+  cursor: pointer;
+  width: 100%; /* 按钮撑满容器宽度 */
+  font-weight: 500;
+  transition: opacity 0.2s;
+}
+button:active {
+  opacity: 0.8; /* 点击反馈 */
+}
+
+/* --- 主按钮 (红色胶囊) --- */
+.btn-primary {
+  height: 48px;
+  background: #D93F4C; /* 提取的设计稿红色 */
+  color: white;
+  border-radius: 24px; /* 高度的一半,形成完美胶囊圆角 */
+  margin-bottom: 12px;
+}
+
+/* --- 次要按钮 (红色文字) --- */
+.btn-secondary {
+  height: 40px;
+  color: #D93F4C; /* 文字颜色与主按钮背景一致 */
+}
+
+/* --- 动画定义 (淡入 + 缩放弹出) --- */
+.modal-fade-enter-active,
+.modal-fade-leave-active {
+  transition: opacity 0.3s ease;
+}
+
+.modal-fade-enter-active .modal-container {
+  /* 弹窗进入时的弹性动画 */
+  animation: modal-pop-in 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
+}
+.modal-fade-leave-active .modal-container {
+  /* 弹窗离开时的动画 */
+  animation: modal-pop-in 0.3s reverse;
+}
+
+.modal-fade-enter-from,
+.modal-fade-leave-to {
+  opacity: 0;
+}
+
+@keyframes modal-pop-in {
+  from {
+    opacity: 0;
+    transform: scale(0.9);
+  }
+  to {
+    opacity: 1;
+    transform: scale(1);
+  }
+}
+</style>

+ 175 - 0
src/views/bitcoin/StatusComponent/InsufficientBalance.vue

@@ -0,0 +1,175 @@
+<template>
+  <Teleport to="body">
+    <transition name="modal-fade">
+      <div v-if="visible" class="modal-mask" @click="handleClose">
+
+        <div class="modal-container" @click.stop>
+
+          <div class="modal-title">温馨提示</div>
+
+          <div class="modal-icon">
+            <svg width="64" height="64" viewBox="0 0 64 64" fill="none" xmlns="http://www.w3.org/2000/svg">
+              <circle cx="38" cy="32" r="23.5" stroke="#9CA3AF" fill="white"/>
+              <circle cx="35" cy="32" r="23.5" stroke="#9CA3AF" fill="#F3F4F6"/>
+              <circle cx="32" cy="32" r="24" fill="#1F2937"/>
+              <circle cx="32" cy="32" r="22.5" stroke="#374151" stroke-width="3"/>
+              <path d="M32 18V21M32 43V46M36.5 25C36.5 23.5 35.5 22 32 22C28.5 22 27.5 23.5 27.5 25C27.5 28 31 29 33.5 30C36 31 37 33 37 36C37 39 35 41 32 41C29 41 27 39 27 36M27.5 25H26M36.5 36H38" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
+            </svg>
+          </div>
+
+          <p class="modal-text">余额不足,去充币</p>
+
+          <button class="btn-primary" @click="handleConfirm">
+            立即充币
+          </button>
+
+          <button class="btn-secondary" @click="handleClose">
+            取消
+          </button>
+
+        </div>
+      </div>
+    </transition>
+  </Teleport>
+</template>
+
+<script setup>
+import { defineProps, defineEmits } from 'vue';
+
+// 接收父组件传来的可见性状态
+defineProps({
+  visible: {
+    type: Boolean,
+    required: true
+  }
+});
+
+// 定义向父组件发送的事件
+const emit = defineEmits(['update:visible', 'confirm']);
+
+// 关闭弹窗
+const handleClose = () => {
+  // 发送事件让父组件把 visible 改为 false
+  emit('update:visible', false);
+};
+
+// 点击确认按钮
+const handleConfirm = () => {
+  // 先触发确认操作,比如跳转充值页面
+  emit('confirm');
+  // 然后关闭弹窗
+  handleClose();
+};
+</script>
+
+<style scoped>
+/* --- 遮罩层 --- */
+.modal-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, 0.6); /* 深色半透明背景 */
+  display: flex;
+  align-items: center; /* 垂直居中 */
+  justify-content: center; /* 水平居中 */
+  z-index: 9999; /* 保证在最上层 */
+  padding: 20px; /* 防止小屏贴边 */
+}
+
+/* --- 弹窗容器 --- */
+.modal-container {
+  width: 100%;
+  max-width: 315px; /* 在375屏上两边留有约30px间距,视觉效果舒适 */
+  background: #fff;
+  border-radius: 16px; /* 大圆角 */
+  padding: 24px 20px;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  box-sizing: border-box;
+  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
+}
+
+/* --- 标题 --- */
+.modal-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #111827;
+  margin-bottom: 20px;
+}
+
+/* --- 图标区域 --- */
+.modal-icon {
+  margin-bottom: 16px;
+  /* 如果用图片,可以设置 width/height */
+}
+
+/* --- 文本 --- */
+.modal-text {
+  font-size: 15px;
+  color: #6B7280; /* 灰色的提示文字 */
+  margin: 0 0 32px 0; /* 底部留出较大空间给按钮 */
+}
+
+/* --- 通用按钮样式 --- */
+button {
+  border: none;
+  background: none;
+  font-size: 16px;
+  cursor: pointer;
+  width: 100%; /* 按钮撑满容器宽度 */
+  font-weight: 500;
+  transition: opacity 0.2s;
+}
+button:active {
+  opacity: 0.8; /* 点击反馈 */
+}
+
+/* --- 主按钮 (红色胶囊) --- */
+.btn-primary {
+  height: 48px;
+  background: #D93F4C; /* 提取的设计稿红色 */
+  color: white;
+  border-radius: 24px; /* 高度的一半,形成完美胶囊圆角 */
+  margin-bottom: 12px;
+}
+
+/* --- 次要按钮 (红色文字) --- */
+.btn-secondary {
+  height: 40px;
+  color: #D93F4C; /* 文字颜色与主按钮背景一致 */
+}
+
+/* --- 动画定义 (淡入 + 缩放弹出) --- */
+.modal-fade-enter-active,
+.modal-fade-leave-active {
+  transition: opacity 0.3s ease;
+}
+
+.modal-fade-enter-active .modal-container {
+  /* 弹窗进入时的弹性动画 */
+  animation: modal-pop-in 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
+}
+.modal-fade-leave-active .modal-container {
+  /* 弹窗离开时的动画 */
+  animation: modal-pop-in 0.3s reverse;
+}
+
+.modal-fade-enter-from,
+.modal-fade-leave-to {
+  opacity: 0;
+}
+
+@keyframes modal-pop-in {
+  from {
+    opacity: 0;
+    transform: scale(0.9);
+  }
+  to {
+    opacity: 1;
+    transform: scale(1);
+  }
+}
+</style>

+ 880 - 0
src/views/bitcoin/TradeFutures.vue

@@ -0,0 +1,880 @@
+<template>
+  <div class="trade-futures-container">
+
+    <div class="menu">
+      <div class="menu-left">
+        <img class="fc333333" src="../../assets/icon/bitcoin/menu.svg" alt="">
+        <div class="pf600 fs18 fc121212">BTCUSDT 永续</div>
+      </div>
+      <div class="menu-right fc333333">
+        <img src="../../assets/icon/bitcoin/jisuanqi.svg" alt="" @click="router.push({name: 'calculator'})">
+        <img src="../../assets/icon/bitcoin/hangqing.svg" alt="">
+        <img src="../../assets/icon/bitcoin/den.svg" alt="" @click="showFunctions = true">
+      </div>
+    </div>
+
+    <div class="menu-bottom">
+      <div class="pf500 fs12 menu-leftb">
+        +2.18%
+      </div>
+      <div class="fc333333 fs12 pf400 menu-rightb">
+        <div>资金费率/倒计时</div>
+        <div>0.003%/1:57:32</div>
+      </div>
+    </div>
+    <div class="menu-content">
+      <div class="menu-content-l">
+        <div class="menu-content-lb pf400 fs14 fc666666">
+          <span>价格</span><span>数量(USDT)</span>
+        </div>
+
+        <div class="menu-content-lb1">
+          <div class="menu-content-lb1l pf400 fs14 fcFF7171">
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+          </div>
+          <div class="menu-content-lb1r pf400 fs14 fc444444">
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+          </div>
+        </div>
+
+        <div class="menu-content-lb2">
+          <p class="pf600 fs16 fcDF384C">5,678.00</p>
+          <p class="fs12 fcA8A8A8 pf400">1,678.00</p>
+        </div>
+
+        <div class="menu-content-lb1">
+          <div class="menu-content-lb1l pf400 fs14 fc333333">
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+            <span>40,166.82</span>
+          </div>
+          <div class="menu-content-lb1r pf400 fs14 fc444444">
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+            <span>37.80K</span>
+          </div>
+        </div>
+
+        <div class="menu-content-lb1">
+          <div class="menu-content-lb1l pf400 fs12 fc333333" @click="isPickerVisible = true">
+            <span class="fs12">{{ displayLabel }}</span>
+            <img src="../../assets/icon/bitcoin/shendul.svg" alt="">
+          </div>
+          <div class="menu-content-lb1r pf400 fs14 fc444444">
+            <img src="../../assets/icon/bitcoin/shendur.svg" alt="">
+            <img v-if="isassetlessState" src="../../assets/icon/bitcoin/wuzichan.svg" alt="">
+          </div>
+        </div>
+      </div>
+
+      <assetlessStateData v-if="isassetlessState"></assetlessStateData>
+      <SellTradingStatusData v-if="isassetlessState"></SellTradingStatusData>
+
+      <div class="menu-content-r">
+        <div class="menu-content-rb pf400 fs14">
+          <div class="menu-content-rb1 fs14 fc333333" @click="showInfo = true">
+            <img src="../../assets/icon/bitcoin/quancang.svg" alt="">
+            <span>{{ selectedLabel1 }}</span>
+          </div>
+          <div @click="showModal1 = true" style="font-size: 12px; margin-right: 12px;">
+            <VanIcon :style="{ fontWeight: 'bold' }" :name="showModal1 ? 'arrow-up' : 'arrow-down'"/>
+          </div>
+        </div>
+
+        <div class="menu-content-rb pf400 fs14">
+          <div class="menu-content-rb1 fs14 fc333333" @click="showModal3 = true">
+            <img src="../../assets/icon/bitcoin/quancang.svg" alt="">
+            <span>{{ selectedLabel2 }}</span>
+          </div>
+          <div @click="showModal2 = true" style="font-size: 12px; margin-right: 12px;">
+            <VanIcon :style="{ fontWeight: 'bold' }" :name="showModal2 ? 'arrow-up' : 'arrow-down'"/>
+          </div>
+        </div>
+
+        <div class="menu-content-rb pf400 fs14">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span>125000</span>
+          </div>
+          <span>最优价</span>
+        </div>
+        <div class="menu-content-rb pf400 fs14 fc333333">≈25.2250 USDT</div>
+
+        <div class="menu-content-rb pf400 fs14">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span class="menu-content-rb1s fc999999">数量</span>
+          </div>
+          <span>USDT</span>
+        </div>
+
+        <div class="menu-content-rb pf400 fs14">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span class="menu-content-rb1s fc333333">可用</span>
+          </div>
+          <div class="menu-content-rb1">
+            <span>0</span>
+            <span>USDT</span>
+            <img class="fs16" src="../../assets/icon/bitcoin/qianbao1.svg" alt="">
+          </div>
+        </div>
+
+        <div class="menu-content-rb pf400 fs14">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span class="menu-content-rb1s fc333333">倍数</span>
+          </div>
+          <div class="menu-content-rb1" @click="showLeverageModal = true">
+            <span></span>
+            <span>{{ selectedLeverage }}X</span>
+            <span>更多</span>
+          </div>
+        </div>
+
+        <div class="menu-content-rb pf400 fs14">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <van-checkbox
+                v-model="isEnabled"
+                shape="square"
+                checked-color="#DC4653"
+                icon-size="16px"
+            >
+            </van-checkbox>
+            <span class="menu-content-rb1s fc333333">只减仓</span>
+          </div>
+          <div class="menu-content-rb1" @click="showModal = true">
+            <span></span>
+            <span>{{ currentType }}</span>
+            <div style="font-size: 12px;">
+              <VanIcon :style="{ fontWeight: 'bold' }" :name="showModal ? 'arrow-up' : 'arrow-down'"/>
+            </div>
+          </div>
+        </div>
+
+        <TakeProfitsTopLoss v-show="!isEnabled"></TakeProfitsTopLoss>
+
+        <div class="menu-content-rb pf400 fs14">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span class="menu-content-rb1s fc333333">可用</span>
+          </div>
+          <div class="menu-content-rb1">
+            <span>0</span>
+            <span>USDT</span>
+          </div>
+        </div>
+        <div class="menu-content-rb pf400 fs14">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span class="menu-content-rb1s fc333333">保证金</span>
+          </div>
+          <div class="menu-content-rb1">
+            <span>0</span>
+            <span>USDT</span>
+          </div>
+        </div>
+
+        <div class="menu-content-rb pf400 fs14" @click="showConfirm = true">
+          <div class="pf400 fs16 fcFFFFFF">买入(做多)</div>
+        </div>
+
+        <div class="menu-content-rb pf400 fs14">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span class="menu-content-rb1s fc333333">可用</span>
+          </div>
+          <div class="menu-content-rb1">
+            <span>0</span>
+            <span>USDT</span>
+          </div>
+        </div>
+        <div class="menu-content-rb pf400 fs14">
+          <div class="menu-content-rb1 fs14 fc333333">
+            <span class="menu-content-rb1s fc333333">保证金</span>
+          </div>
+          <div class="menu-content-rb1">
+            <span>0</span>
+            <span>USDT</span>
+          </div>
+        </div>
+
+        <div class="menu-content-rb pf400 fs14">
+          <div class="pf400 fs16 fcFFFFFF" @click="showConfirm = true">卖出(做空)</div>
+        </div>
+      </div>
+    </div>
+
+    <sellOrder></sellOrder>
+
+    <div v-if="isassetlessState">
+      <assetlessState></assetlessState>
+    </div>
+
+    <ChooseThisDepth
+        v-model:show="isPickerVisible"
+        v-model="currentDepth"
+    ></ChooseThisDepth>
+
+    <LeveragePopup
+        v-model:visible="showLeverageModal"
+        :initial-value="selectedLeverage"
+        @confirm="handleConfirm">
+    </LeveragePopup>
+
+    <OrderConfirmPopup
+        v-model:visible="showConfirm"
+        @confirm="onOrderConfirmed">
+    </OrderConfirmPopup>
+
+    <OrderTimeSheet
+        v-model:visible="showModal"
+        v-model="currentType"
+    ></OrderTimeSheet>
+
+    <MarginInfoSheet
+        v-model:visible="showInfo"
+    ></MarginInfoSheet>
+
+    <FundingOptions
+        v-model:visible="showModal1"
+        :selected-id="currentId1"
+        @confirm="handleConfirm1">
+    </FundingOptions>
+
+    <OrderType
+        v-model:visible="showModal2"
+        :selected-id="currentId2"
+        @confirm="handleConfirm2"
+    ></OrderType>
+
+    <LimitOrderModal
+        v-model:visible="showModal3"
+    ></LimitOrderModal>
+    <CommonFunctionsPopup
+      v-model:visible="showFunctions"
+    ></CommonFunctionsPopup>
+  </div>
+</template>
+
+<script setup>
+import {Checkbox as VanCheckbox, Icon as VanIcon} from 'vant';
+import {computed, defineAsyncComponent, ref} from 'vue';
+import { useRouter } from 'vue-router'; // 【新增】 引入路由
+
+const router = useRouter(); // 【新增】 实例化路由
+
+// --- 异步组件引入 ---
+const priceLimit = defineAsyncComponent(() => import("./components/priceLimit.vue"));
+const assetlessState = defineAsyncComponent(() => import("./components/assetlessState.vue"));
+const assetlessStateData = defineAsyncComponent(() => import("./components/assetlessStateData.vue"));
+const sellOrder = defineAsyncComponent(() => import('./components/sellOrder.vue'));
+const SellTradingStatusData = defineAsyncComponent(() => import('./components/SellTradingStatusData.vue'));
+const TakeProfitsTopLoss = defineAsyncComponent(() => import('./components/TakeProfitsTopLoss.vue'));
+const ChooseThisDepth = defineAsyncComponent(() => import('./components/ChooseThisDepth.vue'));
+const LeveragePopup = defineAsyncComponent(() => import('./components/LeveragePopup.vue'));
+const OrderConfirmPopup = defineAsyncComponent(() => import('./components/OrderConfirmPopup.vue'));
+const OrderTimeSheet = defineAsyncComponent(() => import('./components/OrderTimeSheet.vue'));
+const MarginInfoSheet = defineAsyncComponent(() => import('./components/MarginInfoSheet.vue'));
+const FundingOptions = defineAsyncComponent(() => import('./components/FundingOptions.vue'));
+const OrderType = defineAsyncComponent(() => import('./components/OrderType.vue'));
+const LimitOrderModal = defineAsyncComponent(() => import('./components/LimitOrderModal.vue'));
+// 假设您的组件在 @/components/CommonFunctionsPopup.vue (请根据实际路径修改)
+const CommonFunctionsPopup = defineAsyncComponent(() => import('./CommonFunctionsPopup/CommonFunctionsPopup.vue'));
+
+// 控制弹窗显示的变量
+const showFunctions = ref(false);
+
+// --- 状态定义 ---
+const isassetlessState = ref(false);
+
+const isPickerVisible = ref(false);
+const currentDepth = ref('depth1');
+const depthMap = {
+  'depth1': '深度1',
+  'depth2': '深度2',
+  'depth3': '深度3',
+};
+const displayLabel = computed(() => depthMap[currentDepth.value] || '请选择');
+
+/* 市价说明 */
+const showModal3 = ref(false);
+
+/* 订单类型选项 */
+const showModal2 = ref(false);
+const currentId2 = ref(1);
+const selectedLabel2 = ref('市价');
+const selectedUnit2 = ref('%');
+const handleConfirm2 = (item) => {
+  currentId2.value = item.id;
+  selectedLabel2.value = item.label.slice(0, 2);
+  selectedUnit2.value = item.unit;
+};
+
+/* 全仓逐仓选项 */
+const showModal1 = ref(false);
+const currentId1 = ref(1);
+const selectedLabel1 = ref('全仓');
+const selectedUnit1 = ref('%');
+const handleConfirm1 = (item) => {
+  currentId1.value = item.id;
+  selectedLabel1.value = item.label.slice(0, 2);
+  selectedUnit1.value = item.unit;
+};
+
+/* 全仓逐仓说明 */
+const showInfo = ref(false);
+
+/* GTC 弹框 */
+const showModal = ref(false);
+const currentType = ref('GTC');
+
+/* 控制止盈止损显隐 */
+const isEnabled = ref(false);
+
+/* 控制倍数 */
+const showLeverageModal = ref(false);
+const selectedLeverage = ref(100);
+const handleConfirm = (value) => {
+  selectedLeverage.value = value;
+};
+
+/* 交易确认 */
+const showConfirm = ref(false);
+const onOrderConfirmed = () => {
+  // console.log('订单已提交');
+};
+</script>
+
+<style lang="less" scoped>
+:deep(.van-checkbox__icon--square .van-icon) {
+  border-radius: 2px !important;
+}
+
+.trade-futures-container {
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-start;
+  align-items: center;
+  margin-bottom: 100px;
+  width: 100%;
+}
+
+/* --- 【新增】 头部行情的样式 --- */
+.menu {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+  /* 既然Layout底部给了margin,这里如果不想要间距可以调整,或者保留 */
+  /* margin-top: 21px; */
+  width: 345px;
+  height: 24px;
+
+  .menu-left {
+    display: flex;
+    flex-direction: row;
+    justify-content: flex-start;
+    align-items: center;
+    line-height: 0px;
+
+    img {
+      margin: 0px 10px 0 0;
+    }
+  }
+
+  .menu-right {
+    img {
+      margin-left: 14px;
+    }
+  }
+}
+
+.menu-bottom {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: center;
+  margin-top: 8px;
+  width: 345px;
+
+  .menu-leftb {
+    width: 61px;
+    height: 25px;
+    background-color: #45b26b;
+    border-radius: 5px;
+    color: #ffffff;
+    text-align: center;
+    line-height: 25px;
+  }
+
+  .menu-rightb {
+    text-align: right;
+  }
+}
+/* --- 【新增】 头部样式结束 --- */
+
+.menu-content {
+    width: 100%;
+    max-width: 345px;
+    display: flex;
+    flex-direction: row;
+    margin-top: 8px;
+
+    .menu-content-l {
+      flex: 1;
+
+      .menu-content-lb {
+        display: flex;
+        flex-direction: row;
+        justify-content: space-between;
+        padding-right: 14px;
+      }
+
+      .menu-content-lb1 {
+        margin-top: 11px;
+        display: flex;
+        flex-direction: row;
+        justify-content: space-between;
+        padding-right: 14px;
+
+        .menu-content-lb1l {
+          display: flex;
+          flex-direction: column;
+          line-height: 22px;
+        }
+
+        .menu-content-lb1r {
+          display: flex;
+          flex-direction: column;
+          line-height: 22px;
+        }
+      }
+
+      .menu-content-lb1:nth-child(4) {
+        .menu-content-lb1l {
+          color: #45b26b;
+        }
+      }
+
+      .menu-content-lb1:nth-child(5) {
+        .menu-content-lb1l {
+          width: 100%;
+          display: flex;
+          flex-direction: row;
+          justify-content: space-between;
+          align-items: center;
+          background-color: #f5f5f5;
+          border-radius: 6px;
+          height: 24px;
+          padding: 0 5px 0 13px;
+
+
+        }
+
+        .menu-content-lb1r {
+          margin-left: 15px;
+        }
+      }
+
+      .menu-content-lb2 {
+        margin-top: 8px;
+        line-height: 16px;
+        //span:nth-child(2){
+        //  //border-style: dashed;
+        //}
+      }
+    }
+
+    .menu-content-r {
+      flex: 1;
+      flex-basis: 63.5px;
+      max-width: 204.25px;
+
+      .menu-content-rb:nth-of-type(4) {
+        background-color: transparent;
+        height: 20px;
+
+      }
+
+      .menu-content-rb {
+        width: 100%;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        background-color: #f5f5f5;
+        border-radius: 6px;
+        margin-bottom: 8px;
+        height: 38px;
+
+        span {
+          padding-right: 12px;
+
+        }
+
+        img {
+          padding-right: 12px;
+          //height: 16px;
+          //width: 16px;
+        }
+
+        .menu-content-rb1 {
+          text-align: center;
+          margin-left: 12px;
+          display: flex;
+          align-content: center;
+          justify-content: center;
+          align-items: center;
+
+          img {
+            padding-right: 6px;
+
+          }
+
+        }
+      }
+
+      .menu-content-rb:nth-of-type(6) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          margin-left: 0;
+        }
+
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(1) {
+
+            font-size: 12px;
+          }
+
+          span:nth-child(2) {
+            margin: 0 9px 0 9px;
+            font-size: 12px;
+          }
+        }
+
+        span {
+          padding-right: 0;
+        }
+
+        img {
+          padding-right: 0;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(7) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          margin-left: 0;
+        }
+
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 9px 0 9px;
+            font-size: 12px;
+          }
+
+          span:nth-child(3) {
+            color: #df384c;
+          }
+        }
+
+        span {
+          padding-right: 0;
+        }
+
+        img {
+          padding-right: 0;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(8) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          display: flex;
+          align-items: center;
+          height: 24px;
+          margin-left: 0;
+          align-content: center;
+
+          input {
+            width: 16px;
+            height: 16px;
+            margin-right: 5px;
+          }
+        }
+
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 9px 0 9px;
+          }
+        }
+
+        .menu-content-rb1s {
+          margin-left: 6px;
+        }
+
+        span {
+          padding-right: 0;
+        }
+
+        img {
+          padding-right: 0;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(9) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          display: flex;
+          align-items: center;
+          height: 24px;
+          margin-left: 0;
+          align-content: center;
+
+          input {
+            width: 16px;
+            height: 16px;
+            margin-right: 5px;
+          }
+
+          img {
+            padding-left: 5px;
+            font-size: 16px;
+            padding-top: 2px;
+          }
+        }
+
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 9px 0 9px;
+          }
+        }
+
+        span {
+          padding-right: 0;
+        }
+
+        img {
+          padding-right: 0;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(10) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          display: flex;
+          align-items: center;
+          height: 24px;
+          margin-left: 0;
+          align-content: center;
+
+          input {
+            width: 16px;
+            height: 16px;
+            margin-right: 5px;
+          }
+
+          img {
+            padding-left: 5px;
+            font-size: 16px;
+            padding-top: 2px;
+          }
+        }
+
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 0px 0 5px;
+          }
+        }
+
+        span {
+          padding-right: 0;
+        }
+
+        img {
+          padding-right: 0;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(11) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          display: flex;
+          align-items: center;
+          height: 24px;
+          margin-left: 0;
+          align-content: center;
+
+          input {
+            width: 16px;
+            height: 16px;
+            margin-right: 5px;
+          }
+
+          img {
+            padding-left: 5px;
+            font-size: 16px;
+            padding-top: 2px;
+          }
+        }
+
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 0px 0 5px;
+          }
+        }
+
+        span {
+          padding-right: 0;
+        }
+
+        img {
+          padding-right: 0;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(12) {
+        background-color: #45b26b;
+
+        div {
+          margin: auto;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(13) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          display: flex;
+          align-items: center;
+          height: 24px;
+          margin-left: 0;
+          align-content: center;
+
+          input {
+            width: 16px;
+            height: 16px;
+            margin-right: 5px;
+          }
+
+          img {
+            padding-left: 5px;
+            font-size: 16px;
+            padding-top: 2px;
+          }
+        }
+
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 0px 0 5px;
+          }
+        }
+
+        span {
+          padding-right: 0;
+        }
+
+        img {
+          padding-right: 0;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(14) {
+        background-color: transparent;
+        height: 20px;
+
+        .menu-content-rb1 {
+          display: flex;
+          align-items: center;
+          height: 24px;
+          margin-left: 0;
+          align-content: center;
+
+          input {
+            width: 16px;
+            height: 16px;
+            margin-right: 5px;
+          }
+
+          img {
+            padding-left: 5px;
+            font-size: 16px;
+            padding-top: 2px;
+          }
+        }
+
+        .menu-content-rb1:nth-child(2) {
+          span:nth-child(2) {
+            margin: 0 0px 0 5px;
+          }
+        }
+
+        span {
+          padding-right: 0;
+        }
+
+        img {
+          padding-right: 0;
+        }
+
+      }
+
+      .menu-content-rb:nth-of-type(15) {
+        background-color: #df384c;
+
+        div {
+          margin: auto;
+        }
+
+      }
+
+      //.van-dropdown-menu__bar{
+      //  width: 214px;
+      //}
+
+    }
+  }
+
+</style>

+ 113 - 0
src/views/bitcoin/TradeLayout.vue

@@ -0,0 +1,113 @@
+<template>
+  <div class="market-layout">
+    <div class="market-nav">
+      <div class="nav-left">
+        <div
+          class="nav-item pf600"
+          :class="isCurrent('TradeContract') ? 'fs18 fc121212' : 'fs14 fcA8A8A8'"
+          @click="switchTab('TradeContract')"
+        >
+          合约
+          <div v-if="isCurrent('TradeContract')" class="active-line"></div>
+        </div>
+
+        <div
+          class="nav-item pf600 sys-notifi"
+          :class="isCurrent('TradeSeconds') ? 'fs18 fc121212' : 'fs14 fcA8A8A8'"
+          @click="switchTab('TradeSeconds')"
+        >
+          秒合约
+          <div v-if="isCurrent('TradeSeconds')" class="active-line"></div>
+        </div>
+
+        <div
+          class="nav-item pf600 sys-notifi"
+          :class="isCurrent('TradeOptions') ? 'fs18 fc121212' : 'fs14 fcA8A8A8'"
+          @click="switchTab('TradeOptions')"
+        >
+          期权
+          <div v-if="isCurrent('TradeOptions')" class="active-line"></div>
+        </div>
+
+        <div
+          class="nav-item pf600 sys-notifi"
+          :class="isCurrent('TradeMargin') ? 'fs18 fc121212' : 'fs14 fcA8A8A8'"
+          @click="switchTab('TradeMargin')"
+        >
+          杠杆
+          <div v-if="isCurrent('TradeMargin')" class="active-line"></div>
+        </div>
+      </div>
+    </div>
+
+    <router-view></router-view>
+  </div>
+</template>
+
+<script setup>
+import { useRouter, useRoute } from 'vue-router';
+
+const router = useRouter();
+const route = useRoute();
+
+const switchTab = (name) => {
+  router.push({ name });
+};
+
+const isCurrent = (name) => {
+  return route.name === name;
+};
+</script>
+
+<style lang="less" scoped>
+.market-layout {
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-start;
+  align-items: center;
+  width: 100%;
+
+  /* 确保导航栏样式正常 */
+  .market-nav {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+    align-items: center;
+    margin-top: 21px;
+    width: 345px;
+    height: 24px;
+    /* 既然只放Tabs,可能需要一点底部间距,以免紧贴着下面的内容 */
+    margin-bottom: 18px;
+
+    .nav-left {
+      display: flex;
+      flex-direction: row;
+      justify-content: flex-start;
+      align-items: flex-end;
+      width: 349px;
+      height: 24px;
+
+      .nav-item {
+        position: relative;
+        cursor: pointer;
+        transition: all 0.2s;
+
+        .active-line {
+          position: absolute;
+          bottom: -6px;
+          left: 50%;
+          transform: translateX(-50%);
+          width: 20px;
+          height: 3px;
+          background-color: #323233;
+          border-radius: 2px;
+        }
+      }
+
+      .sys-notifi {
+        margin-left: 35px;
+      }
+    }
+  }
+}
+</style>

+ 11 - 0
src/views/bitcoin/TradeOptions.vue

@@ -0,0 +1,11 @@
+<script setup>
+
+</script>
+
+<template>
+<div>fjlzlnlf</div>
+</template>
+
+<style scoped lang="less">
+
+</style>

+ 118 - 0
src/views/bitcoin/calculator/FundingRateReminder.vue

@@ -0,0 +1,118 @@
+<template>
+  <Teleport to="body">
+    <transition name="fade">
+      <div v-if="visible" class="modal-mask" @click="close">
+
+        <div class="modal-container" @click.stop>
+
+          <div class="modal-title">资金费率</div>
+
+          <div class="modal-text">
+                  费率为正,做多仓位支付做空仓位
+                  费率为负,做空仓位支付做多仓位
+          </div>
+
+          <button class="main-btn" @click="close">
+            我知道了
+          </button>
+
+        </div>
+      </div>
+    </transition>
+  </Teleport>
+</template>
+
+<script setup>
+import { defineProps, defineEmits } from 'vue';
+
+defineProps({
+  visible: Boolean
+});
+
+const emit = defineEmits(['update:visible']);
+
+const close = () => {
+  emit('update:visible', false);
+};
+</script>
+
+<style scoped>
+/* --- 布局与遮罩 --- */
+.modal-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  height: 100vh;
+  background: rgba(0, 0, 0, 0.6); /* 深色遮罩 */
+  display: flex;
+  align-items: center; /* 垂直居中 */
+  justify-content: center; /* 水平居中 */
+  z-index: 999;
+}
+
+/* --- 弹窗卡片 --- */
+.modal-container {
+  width: 310px; /* 稍微宽一点,适配文字换行 */
+  background: #fff;
+  border-radius: 16px; /* 大圆角 */
+  padding: 24px 24px;
+  box-sizing: border-box;
+  text-align: center;
+  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
+}
+
+/* --- 标题 --- */
+.modal-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #111;
+  margin-bottom: 16px;
+}
+
+/* --- 正文 --- */
+.modal-text {
+  font-size: 15px;
+  color: #555; /* 稍微柔和的深灰色 */
+  line-height: 1.6; /* 增加行高,易读 */
+  text-align: justify; /* 两端对齐,像报纸一样整齐 */
+  max-width: 226px;
+  margin: 24px auto;
+}
+
+/* --- 红色按钮 --- */
+.main-btn {
+  width: 100%;
+  height: 46px;
+  background: #DE3545; /* 截图里的标准红 */
+  color: #fff;
+  font-size: 16px;
+  font-weight: 500;
+  border: none;
+  border-radius: 23px; /* 高度的一半,形成胶囊形状 */
+  cursor: pointer;
+}
+.main-btn:active {
+  opacity: 0.8; /* 点击反馈 */
+}
+
+/* --- 动画效果: 缩放弹入 --- */
+.fade-enter-active, .fade-leave-active {
+  transition: opacity 0.2s ease;
+}
+.fade-enter-active .modal-container {
+  animation: pop-in 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28); /* 弹性动画 */
+}
+.fade-leave-active .modal-container {
+  animation: pop-in 0.3s reverse;
+}
+
+.fade-enter-from, .fade-leave-to {
+  opacity: 0;
+}
+
+@keyframes pop-in {
+  0% { transform: scale(0.8); opacity: 0; }
+  100% { transform: scale(1); opacity: 1; }
+}
+</style>

+ 211 - 0
src/views/bitcoin/calculator/LeverageSlider.vue

@@ -0,0 +1,211 @@
+<template>
+  <div class="slider-wrapper">
+    <div
+      class="track-container"
+      ref="trackRef"
+      @mousedown.prevent="handleTrackDown"
+      @touchstart.prevent="handleTrackDown"
+    >
+      <div class="track-bg"></div>
+
+      <div
+        class="track-fill"
+        :style="{ width: percentage + '%', backgroundColor: color }"
+      ></div>
+
+      <div class="thumb anchor-thumb" :style="{ borderColor: color }"></div>
+
+      <div
+        class="thumb drag-thumb"
+        :style="{ left: percentage + '%', borderColor: color }"
+      ></div>
+    </div>
+
+    <div class="ticks">
+      <span
+        v-for="(mark, i) in marks"
+        :key="i"
+        class="tick-label"
+        :style="{ left: (i / (marks.length - 1)) * 100 + '%' }"
+      >
+        {{ mark }}x
+      </span>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, onUnmounted } from 'vue';
+
+const props = defineProps({
+  modelValue: { type: Number, default: 10 },
+  color: { type: String, default: '#f6465d' },
+  // 固定阶梯
+  marks: {
+    type: Array,
+    default: () => [10, 50, 100, 500, 1000]
+  }
+});
+
+const emit = defineEmits(['update:modelValue']);
+
+const trackRef = ref(null);
+const isDragging = ref(false);
+
+// === 核心 1: 根据当前数值,反推在轨道上的百分比位置 ===
+const percentage = computed(() => {
+  const currentVal = props.modelValue;
+  const list = props.marks;
+
+  // 找到当前数值对应数组里的第几个 (Index)
+  // 如果数值不在数组里(比如初始传入了11),则找最近的一个
+  let closestIndex = 0;
+  let minDiff = Infinity;
+
+  list.forEach((val, index) => {
+    const diff = Math.abs(val - currentVal);
+    if (diff < minDiff) {
+      minDiff = diff;
+      closestIndex = index;
+    }
+  });
+
+  // 比如有5个点,索引是0-4。第2个点位置就是 2/4 = 50%
+  return (closestIndex / (list.length - 1)) * 100;
+});
+
+const getClientX = (event) => {
+  if (event.touches && event.touches.length > 0) {
+    return event.touches[0].clientX;
+  }
+  return event.clientX;
+};
+
+// === 核心 2: 根据点击位置,吸附到最近的刻度 ===
+const updateValueByPosition = (clientX) => {
+  if (!trackRef.value) return;
+
+  const rect = trackRef.value.getBoundingClientRect();
+  const width = rect.width;
+  let offsetX = clientX - rect.left;
+
+  // 限制范围
+  if (offsetX < 0) offsetX = 0;
+  if (offsetX > width) offsetX = width;
+
+  // 计算当前触摸点占总长度的比例 (0.0 - 1.0)
+  const ratio = offsetX / width;
+
+  // 总段数 (比如5个点就是4段)
+  const segments = props.marks.length - 1;
+
+  // 四舍五入找到最近的索引
+  // 例如 ratio = 0.6,segments = 4 => 2.4 => round => 2 (即第3个点)
+  const targetIndex = Math.round(ratio * segments);
+
+  // 取出对应的值
+  const newValue = props.marks[targetIndex];
+
+  // 如果变了才发送更新
+  if (newValue !== props.modelValue) {
+    emit('update:modelValue', newValue);
+  }
+};
+
+const handleTrackDown = (e) => {
+  isDragging.value = true;
+  updateValueByPosition(getClientX(e));
+  document.addEventListener('mousemove', onDrag);
+  document.addEventListener('mouseup', stopDrag);
+  document.addEventListener('touchmove', onDrag, { passive: false });
+  document.addEventListener('touchend', stopDrag);
+};
+
+const onDrag = (e) => {
+  if (!isDragging.value) return;
+  if (e.type === 'touchmove') e.preventDefault();
+  updateValueByPosition(getClientX(e));
+};
+
+const stopDrag = () => {
+  isDragging.value = false;
+  document.removeEventListener('mousemove', onDrag);
+  document.removeEventListener('mouseup', stopDrag);
+  document.removeEventListener('touchmove', onDrag);
+  document.removeEventListener('touchend', stopDrag);
+};
+
+onUnmounted(() => stopDrag());
+</script>
+
+<style scoped>
+/* 样式保持不变,复用之前的优美样式 */
+.slider-wrapper {
+  padding: 15px 0;
+  width: 100%;
+  touch-action: none;
+  position: relative;
+  margin-bottom: 10px;
+}
+
+.track-container {
+  position: relative;
+  height: 8px;
+  width: 100%;
+  cursor: pointer;
+  padding: 10px 0;
+  margin-top: -10px;
+  margin-bottom: -10px;
+}
+
+.track-bg {
+  position: absolute;
+  top: 50%; transform: translateY(-50%);
+  width: 100%; height: 8px;
+  background: #f5f5f5;
+  border-radius: 4px;
+}
+
+.track-fill {
+  position: absolute;
+  top: 50%; transform: translateY(-50%);
+  height: 8px;
+  border-radius: 4px 0 0 4px;
+  pointer-events: none;
+  transition: width 0.1s; /* 增加一点过渡动画,让吸附效果更平滑 */
+}
+
+.thumb {
+  position: absolute;
+  top: 50%; transform: translate(-50%, -50%);
+  width: 26px; height: 26px;
+  background: #fff;
+  border: 2px solid;
+  border-radius: 50%;
+  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+  z-index: 2;
+  pointer-events: none;
+  box-sizing: border-box;
+  transition: left 0.1s; /* 增加一点过渡动画 */
+}
+
+.anchor-thumb { left: 0%; z-index: 1; }
+
+.ticks {
+  position: relative;
+  width: 100%;
+  height: 20px;
+  margin-top: 15px;
+}
+
+.tick-label {
+  position: absolute;
+  transform: translateX(-50%);
+  color: #5e6673;
+  font-size: 12px;
+  white-space: nowrap;
+}
+
+.tick-label:first-child { transform: translateX(0); }
+.tick-label:last-child { transform: translateX(-100%); }
+</style>

+ 249 - 0
src/views/bitcoin/components/ClosePositionSheet.vue

@@ -0,0 +1,249 @@
+<template>
+  <Teleport to="body">
+    <transition name="fade">
+      <div v-if="visible" class="modal-mask" @click="close"></div>
+    </transition>
+
+    <transition name="slide-up">
+      <div v-if="visible" class="modal-panel">
+        <div class="handle-wrap"><div class="handle"></div></div>
+
+        <div class="header-section">
+          <div class="coin-icon">
+            <img src="../../../assets/icon/bitcoin/bt.svg" alt="">
+<!--            <svg viewBox="0 0 64 64" width="100%" height="100%">-->
+<!--              <circle cx="32" cy="32" r="32" fill="#F7931A"/>-->
+<!--              <path d="M44.08 25.6c-0.4-2.69-1.65-4.12-4.46-5.09l0.91-3.66-2.23-0.56-0.89 3.56c-0.59-0.15-1.21-0.29-1.83-0.43l0.9-3.62-2.23-0.56-0.91 3.65c-0.48-0.11-0.98-0.22-1.46-0.33L28.7 18l-4.3 1.08s1.2 0.28 1.17 0.29c0.65 0.16 0.77 0.6 0.75 0.94l-0.75 3.02c0.05 0.01 0.1 0.03 0.17 0.05-0.05-0.01-0.11-0.03-0.17-0.04l-1.06 4.24c-0.08 0.2-0.28 0.8-0.73 0.69 0.01 0.02-1.17-0.29-1.17-0.29l-2.3 5.3 4.06 1.01c0.55 0.14 1.09 0.28 1.64 0.41l-0.92 3.69 2.23 0.56 0.91-3.66c0.61 0.16 1.2 0.31 1.8 0.45l-0.91 3.63 2.23 0.56 0.92-3.67c3.8 0.72 6.65 0.43 7.85-3 0.96-2.76-0.05-4.35-2.04-5.39 1.45-0.33 2.54-1.29 2.83-3.26zM38.2 36.2c-0.63 2.53-4.88 1.16-6.26 0.82l1.12-4.48c1.38 0.34 5.82 1.02 5.14 3.66zm0.67-8.93c-0.57 2.3-4.2 1.13-5.37 0.84l1.01-4.06c1.17 0.29 4.94 0.83 4.36 3.22z" fill="white"/>-->
+<!--            </svg>-->
+          </div>
+          <div class="title-col">
+            <div class="main-title">BTC/USDT 永续</div>
+            <div class="tags-row">
+              <span class="tag tag-buy">买入</span>
+              <span class="tag tag-mode">逐仓 20X</span>
+            </div>
+          </div>
+        </div>
+
+        <div class="price-row">
+          <span class="label">开仓价格</span><span class="value">1000.05 USDT</span>
+        </div>
+        <div class="price-row">
+          <span class="label">标记价格</span><span class="value">1000.05 USDT</span>
+        </div>
+
+        <div class="form-area">
+          <div class="input-box">
+            <span class="input-label">委托类型</span>
+            <div class="input-value-wrap">
+              <span>市价</span>
+              <svg viewBox="0 0 1024 1024" width="10" height="10"><path d="M512 714.667l-298.667-298.667h597.334l-298.667 298.667z" fill="#666"/></svg>
+            </div>
+          </div>
+          <div class="input-box"><span class="input-text-val">市价</span></div>
+          <div class="input-box">
+            <span class="input-label">数量</span><span class="input-suffix">BTC</span>
+          </div>
+        </div>
+
+        <div class="slider-section">
+          <div class="slider-header">可平 0.2562 BTC</div>
+
+          <div class="dumbbell-slider-wrap">
+            <input
+              type="range"
+              min="0"
+              max="100"
+              step="25"
+              v-model="percent"
+              class="dumbbell-slider"
+              :style="sliderTrackStyle"
+            />
+          </div>
+
+          <div class="percent-labels">
+            <span @click="percent=0">0%</span>
+            <span @click="percent=25">25%</span>
+            <span @click="percent=50">50%</span>
+            <span @click="percent=75">75%</span>
+            <span @click="percent=100">100%</span>
+          </div>
+        </div>
+
+        <div class="footer-section">
+          <div class="pnl-row">
+            <span>预计盈亏</span><span class="pnl-val">+0.30 USDT</span>
+          </div>
+          <button class="action-btn" @click="showModal4=true">平空</button>
+        </div>
+        <div class="safe-area"></div>
+      </div>
+    </transition>
+  </Teleport>
+
+  <div>
+    <ConfirmPing
+        v-model:visible="showModal4"
+    ></ConfirmPing>
+  </div>
+</template>
+
+<script setup>
+import {ref, computed, defineProps, defineEmits, defineAsyncComponent} from 'vue';
+const ConfirmPing = defineAsyncComponent(() => import("../StatusComponent/ConfirmPing.vue"));
+
+
+defineProps({ visible: Boolean });
+const emit = defineEmits(['update:visible']);
+
+const percent = ref(0); // 默认从0开始
+
+// 计算滑块轨道背景样式,实现红/灰填充
+const sliderTrackStyle = computed(() => {
+  return {
+    // 红色填充部分 + 灰色未填充部分
+    background: `linear-gradient(to right,
+                 #E04747 ${percent.value}%,
+                 #F2F3F5 ${percent.value}%)`
+  };
+});
+
+const close = () => emit('update:visible', false);
+//确认平仓
+const showModal4 = ref(false);
+</script>
+
+<style scoped lang="less">
+/* 全局变量 */
+:root { --red: #E04747; --green: #2EBD85; }
+
+/* 弹窗基础结构 (不变) */
+.modal-mask { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 998; }
+.modal-panel { position: fixed; bottom: 0; left: 0; width: 100%; background: #fff;
+  border-radius: 16px 16px 0 0; z-index: 999; font-family: sans-serif; }
+.handle-wrap { padding: 8px 0; display: flex; justify-content: center; }
+.handle { width: 36px; height: 4px; background: #E5E6EB; border-radius: 2px; }
+
+/* 头部样式 (不变) */
+.header-section { padding: 4px 20px 16px 20px; display: flex; align-items: center; gap: 12px; }
+.coin-icon { width: 40px; height: 40px; flex-shrink: 0; }
+.title-col { display: flex; flex-direction: column; justify-content: center; gap: 4px; }
+.main-title { font-size: 17px; font-weight: 600; color: #1F2124; line-height: 1.2; }
+.tags-row { display: flex; gap: 6px; }
+.tag { font-size: 11px; padding: 1px 5px; border-radius: 3px; transform: scale(0.95);
+  transform-origin: left center; }
+.tag-buy { background: #2EBD85; color: white; }
+.tag-mode { background: #B0B5BC; color: white; }
+
+/* 价格行 & 表单 (不变) */
+.price-row { display: flex; justify-content: space-between; padding: 2px 20px;
+  font-size: 13px; color: #86909C; }
+.price-row .value { color: #1F2124; font-weight: 500; }
+.form-area { padding: 16px 20px; display: flex; flex-direction: column; gap: 12px; }
+.input-box { background: #F7F8FA; height: 40px; border-radius: 4px; padding: 0 12px;
+  display: flex; align-items: center; justify-content: space-between; font-size: 14px; color: #1F2124; }
+.input-label { color: #86909C; }
+.input-value-wrap { display: flex; align-items: center; gap: 4px; }
+.input-suffix { color: #1F2124; }
+
+/* --- 滑块样式修正 (重点) --- */
+.slider-section { padding: 0 20px 0 20px; }
+.slider-header { font-size: 12px; color: #5E6673; margin-bottom: 16px; }
+
+.dumbbell-slider-wrap {
+  position: relative;
+  height: 24px; /* 高度与滑块Thumb一致 */
+  display: flex;
+  align-items: center;
+}
+
+/* 核心:input[type="range"] 样式调整 */
+.dumbbell-slider {
+  -webkit-appearance: none;
+  appearance: none; /* 兼容性 */
+  width: 100%;
+  height: 8px; /* 轨道粗细 */
+  border-radius: 4px;
+  outline: none;
+  margin: 0;
+  cursor: pointer;
+  z-index: 2; /* 确保在其他伪元素之上 */
+  position: relative;
+  /* 轨道背景由 js 动态计算 */
+}
+
+/* 轨道左侧填充(红色)和右侧未填充(灰色) */
+/* 通过背景渐变控制,由 `sliderTrackStyle` 绑定 */
+.dumbbell-slider::-webkit-slider-runnable-track {
+  background: transparent; /* 真正的轨道背景由input本身的背景负责 */
+  border-radius: 4px;
+  height: 8px;
+}
+.dumbbell-slider::-moz-range-track {
+  background: transparent;
+  border-radius: 4px;
+  height: 8px;
+}
+
+/* 滑块拖动钮 (Thumb) */
+.dumbbell-slider::-webkit-slider-thumb {
+  -webkit-appearance: none;
+  appearance: none;
+  height: 24px; /* 直径 */
+  width: 24px; /* 直径 */
+  border-radius: 50%;
+  background: #ffffff; /* 白底 */
+  //border: 2px solid var(--red); /* 红色边框 */
+  border: 2px solid #E04747;
+  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
+  margin-top: -8px; /* 垂直居中轨道 */
+  position: relative;
+  z-index: 3; /* 确保在最高层 */
+}
+.dumbbell-slider::-moz-range-thumb {
+  height: 24px;
+  width: 24px;
+  border-radius: 50%;
+  background: #ffffff;
+  border: 2px solid var(--red);
+  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
+  z-index: 3;
+}
+
+/* 固定在 0% 位置的圆圈 (通过伪元素实现) */
+.dumbbell-slider::before {
+  content: '';
+  position: absolute;
+  left: 0; /* 微调使其完全贴合 */
+  top: 50%;
+  transform: translateY(-50%);
+  height: 18px; /* 直径 */
+  width: 18px; /* 直径 */
+  border-radius: 50%;
+  background: #ffffff; /* 白底 */
+  //border: 2px solid var(--red); /* 红色边框 */
+  border: 2px solid red;
+
+  box-shadow: 0 1px 3px rgba(0,0,0,0.2);
+  z-index: 1; /* 在轨道之下,但又在滑块thumb之下 */
+  pointer-events: none; /* 不会影响滑块拖动 */
+}
+
+
+.percent-labels { display: flex; justify-content: space-between; margin-top: 12px;
+  font-size: 12px; color: #86909C; }
+
+/* 底部 (不变) */
+.footer-section { padding: 20px; }
+.pnl-row { display: flex; justify-content: space-between; margin-bottom: 16px; font-size: 14px; }
+.pnl-val { color: #2EBD85; font-weight: 500; }
+.action-btn { width: 100%; height: 44px; background: #2EBD85;
+  border-radius: 22px; border: none; color: white; font-size: 16px; font-weight: 600; }
+.safe-area { height: env(safe-area-inset-bottom); }
+
+/* 动画 (不变) */
+.fade-enter-active, .fade-leave-active { transition: opacity 0.2s; }
+.fade-enter-from, .fade-leave-to { opacity: 0; }
+.slide-up-enter-active, .slide-up-leave-active { transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1); }
+.slide-up-enter-from, .slide-up-leave-to { transform: translateY(100%); }
+</style>

+ 170 - 0
src/views/bitcoin/components/FundingOptions.vue

@@ -0,0 +1,170 @@
+<template>
+  <Teleport to="body">
+    <div v-if="visible" class="modal-mask" @click="close">
+      <div class="modal-content" @click.stop>
+        <div class="handle-bar"></div>
+<!--        <div class="trigger fs18 fc333333 pf600">选择触发类型</div>-->
+        <div class="options-list">
+          <div
+            v-for="item in options"
+            :key="item.id"
+            class="option-card"
+            :class="{ 'active': selectedId === item.id }"
+            @click="handleSelect(item)"
+          >
+            <div class="card-header">
+              <span class="title">{{ item.label }}</span>
+              <div v-if="selectedId === item.id" class="check-icon">
+                <svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor"
+                     stroke-width="3" fill="none" stroke-linecap="round" stroke-linejoin="round"
+                     class="css-i6dzq1"><polyline points="20 6 9 17 4 12"></polyline></svg>
+              </div>
+            </div>
+            <div class="description">
+              {{ item.desc }}
+            </div>
+
+          </div>
+        </div>
+        <div class="fs12 fc666666">该设置对所有交易品种生效。若存在持仓或挂单,则不支持调整仓位模式。</div>
+      </div>
+    </div>
+
+  </Teleport>
+</template>
+
+<script setup>
+import { defineProps, defineEmits ,toRef} from 'vue';
+import { useBodyScrollLock } from '@/composables/useBodyScrollLock' // 2. 引入 Hook
+
+// 接收父组件传来的 modelValue (控制显示) 和 当前选中的ID
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    default: false
+  },
+  selectedId: {
+    type: [String, Number],
+    default: 1
+  }
+});
+useBodyScrollLock(toRef(props, 'visible'))
+const emit = defineEmits(['update:visible', 'confirm']);
+
+// 静态数据源 (保持不变)
+const options = [
+  {
+    id: 1,
+    label: '全仓',
+    desc: '所有仓位共用保证金盈亏互抵可有效降低强平风险但强平时可能损失全部仓位',
+  },
+
+  {
+    id: 2,
+    label: '逐仓',
+    desc: '各仓位的保证金与盈亏单独核算强平时仅损失当前仓位' ,
+
+  },
+];
+
+const close = () => {
+  emit('update:visible', false);
+};
+
+const handleSelect = (item) => {
+  // 1. 触发 confirm 事件,把整个对象带回去
+  emit('confirm', item);
+  // 2. 关闭弹窗
+  close();
+};
+</script>
+
+<style lang="less" scoped>
+.modal-mask {
+  position: fixed;
+  top: 0; left: 0; width: 100%; height: 100%;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: flex-end; /* 底部对齐 */
+  z-index: 2001; /* 极高的 Z-index */
+}
+
+.modal-content {
+  width: 100%;
+  background: white;
+  border-radius: 16px 16px 0 0;
+  padding: 20px;
+  padding-bottom: 40px;
+  max-height: 80vh;
+  overflow-y: auto;
+  animation: slideUp 0.3s ease-out;
+  .trigger{margin-bottom: 15px}
+}
+
+.handle-bar {
+  width: 40px;
+  height: 4px;
+  background: #E0E0E0;
+  border-radius: 2px;
+  margin: 0 auto 20px auto;
+}
+
+.option-card {
+  border: 1px solid #E0E0E0;
+  border-radius: 12px;
+  padding: 16px;
+  margin-bottom: 16px;
+  cursor: pointer;
+  transition: all 0.2s;
+  position: relative;
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 8px;
+}
+
+.title {
+  font-size: 16px;
+  font-weight: bold;
+  color: #333;
+}
+
+.description {
+  font-size: 13px;
+  color: #666;
+  line-height: 1.5;
+}
+
+/* 选中状态样式 */
+.option-card.active {
+  border-color: #F53F3F; /* 红色边框 */
+  background-color: #FFF9F9; /* 极淡的红色背景可选 */
+}
+
+.option-card.active .title {
+  color: #D92828; /* 红色标题 */
+}
+
+.option-card.active .description {
+  color: #D92828; /* 红色描述 */
+}
+
+.check-icon {
+  width: 24px;
+  height: 24px;
+  background: #D92828;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: white;
+}
+
+@keyframes slideUp {
+  from { transform: translateY(100%); }
+  to { transform: translateY(0); }
+}
+</style>

+ 1 - 0
src/views/bitcoin/components/LeveragePopup.vue

@@ -256,6 +256,7 @@ const confirmSelection = () => {
   z-index: 2;
 }
 
+
 .inner-circle {
   width: 0px; /* 图片中看起来是实心的或者空心的,这里做个空心白底红圈 */
   height: 0px;

+ 289 - 0
src/views/bitcoin/components/LimitOrderModal.vue

@@ -0,0 +1,289 @@
+<template>
+  <Teleport to="body">
+    <div v-if="visible" class="modal-overlay" @click="close">
+      <div class="modal-content" @click.stop>
+        <div class="drag-handle"></div>
+
+        <div class="tabs-header">
+          <div
+            v-for="(tab, index) in tabs"
+            :key="index"
+            class="tab-item"
+            :class="{ active: currentTab === index }"
+            @click="currentTab = index"
+          >
+            {{ tab }}
+            <div v-if="currentTab === index" class="active-line"></div>
+          </div>
+        </div>
+
+        <div class="tab-body">
+
+          <div v-if="currentContent.topDesc" class="top-description">
+            {{ currentContent.topDesc }}
+          </div>
+
+          <div class="control-row">
+            <span class="label">图示说明</span>
+
+            <div v-if="currentTab === 1" class="checkbox-group">
+              <div class="checkbox-item" @click="setDirection('long')">
+                <div class="custom-checkbox" :class="{ checked: direction === 'long' }">
+                  <span v-if="direction === 'long'">✓</span>
+                </div>
+                <span>做多</span>
+              </div>
+              <div class="checkbox-item" @click="setDirection('short')">
+                <div class="custom-checkbox" :class="{ checked: direction === 'short' }">
+                  <span v-if="direction === 'short'">✓</span>
+                </div>
+                <span>做空</span>
+              </div>
+            </div>
+          </div>
+          <div class="image-container">
+            <img :src="currentContent.image" alt="" />
+          </div>
+
+          <div class="description-text fs12 fc999999">
+            <h3 v-if="currentContent.title">{{ currentContent.title }}</h3>
+            <div class="desc-content" v-html="currentContent.desc"></div>
+          </div>
+        </div>
+        <div class="footer">
+          <button class="confirm-btn" @click="close">确认</button>
+        </div>
+      </div>
+    </div>
+  </Teleport>
+</template>
+
+<script setup>
+import { ref, computed } from 'vue';
+
+const props = defineProps({
+  visible: { type: Boolean, default: false }
+});
+const emit = defineEmits(['update:visible']);
+
+// ================= 状态管理 =================
+const tabs = ['市价', '限价', '限价止盈止损', '市价止盈止损'];
+const currentTab = ref(0); // 默认为 0 (市价)
+const direction = ref('short'); // 仅用于 Tab 1 (限价) 的做多/做空
+
+// ================= 图片资源配置 =================
+// 请将此处路径替换为你项目中的实际图片路径
+const imgMap = {
+  market: require('../../../assets/icon/bitcoin/shijia.svg'),     // 市价
+  limitLong: require('../../../assets/icon/bitcoin/xianjia.svg'),   // 限价-做多
+  limitShort: require('../../../assets/icon/bitcoin/xianjiak.svg'), // 限价-做空
+  limitTpSl: require('../../../assets/icon/bitcoin/xianjiazyzs.svg'),  // 限价止盈止损
+  marketTpSl: require('../../../assets/icon/bitcoin/shijiazyzs.svg'),  // 市价止盈止损
+};
+
+// ================= 核心内容数据 =================
+// 使用 computed 动态生成当前 Tab 应显示的内容
+const currentContent = computed(() => {
+  switch (currentTab.value) {
+    case 0: // === 市价 ===
+      return {
+        topDesc: null,
+        image: imgMap.market,
+        title: '市价委托是指按照目前市场最优价格,进行快速买卖。',
+        desc: '当前价格2400,此时下单一笔市价单,它将会根据对手价直接成交,但成交均价可能不等于2400。'
+      };
+
+    case 1: // === 限价 (带做多/做空逻辑) ===
+      const isLong = direction.value === 'long';
+      return {
+        topDesc: null,
+        image: isLong ? imgMap.limitLong : imgMap.limitShort,
+        title: '限价委托是指以特定或更优价格进行买卖,限价单不能保证一定成交',
+        desc: isLong
+          ? '当前市价(A)下跌至委托限价(C)或以下,委托单将会自动执\n' +
+            '行:如果买单委托限价(B)高于或等于当前市价,委托单将会立\n' +
+            '即成交,因此当需要限价买入时,委托价格应低于当前价格。'
+          : '当价格(A)上涨至订单的限价(B)或以上,订单将会自动执行\n' +
+            '如果卖单的限价低于或等于当前价格,卖单可能会立即成交。因此,\n' +
+            '当需要限价卖出时,委托价格应高于当前价格。'
+      };
+
+    case 2: // === 限价止盈止损 ===
+      return {
+        topDesc: '限价止盈止损委托需要同时设置一个触发价格和一个委托价格。当市场最新价到达触发价时,按预先设置的委托价格和数量自动下单。',
+        image: imgMap.limitTpSl,
+        title: null,
+        // 使用 HTML 字符串来模拟截图中的红色文字高亮
+        desc: `
+          <p>当前价格为2,400 (A)。限价止盈止损单的触发价格可以设置为3,000 (B),高于当前价格;也可以设置为1,500 (C),低于当前价格。一旦价格上涨至3,000 (B),或下跌到1,500 (C),达到触发价,限价委托单将自动激活生效。</p>
+          <p style="margin-top:8px; font-weight:500;">备注:</p>
+          <ol style="padding-left: 15px; margin: 5px 0;">
+            <li>1)买入和卖出订单的限价都可以高于或低于触发价。比如,<span style="color:#dc3545">触发价B</span>可以和价格略低的<span style="color:#dc3545">委托价B1</span>组成限价止盈止损单,也可以和价格略高的<span style="color:#dc3545">委托价B2</span>组成限价止盈止损单;</li>
+            <li>2)在没有达到触发价时,限价单不会生效,即使价格达到限价的时间早于触发价也是如此。</li>
+            <li>3)当达到止损价格时,只能表明限价单将会自动激活并提交至市场,并不表示限价单将会立即成交。限价委托单被激活后,只有满足其成交条件才会最终执行。</li>
+          </ol>
+        `
+      };
+
+    case 3: // === 市价止盈止损 ===
+      return {
+        topDesc: '当触达设定的价格时,止损市价委托会自动触发。交易者需要设定一个价格去触发该类型委托。该类委托可以应用于设置市价止损和市价止盈委托。',
+        image: imgMap.marketTpSl,
+        title: null,
+        desc: '当前价格为2,400 (A)。市价止盈止损订单的触发价格可以设置为3,000 (B),高于当前价格;也可以设置为1,500(C),低于当前价格。一旦价格上涨至3,000(B),或下跌到1,500 (C),达到触发价,市价单将自动触发生效。'
+      };
+
+    default:
+      return {};
+  }
+});
+
+const setDirection = (val) => {
+  direction.value = val;
+};
+
+const close = () => {
+  emit('update:visible', false);
+};
+</script>
+
+<style scoped>
+/* 保持之前的遮罩和弹窗基础样式 */
+.modal-overlay {
+  position: fixed;
+  top: 0; left: 0; width: 100vw; height: 100vh;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex; align-items: flex-end; justify-content: center;
+  z-index: 1000;
+}
+
+.modal-content {
+  background: white;
+  width: 100%;
+  max-width: 500px;
+  border-radius: 16px 16px 0 0;
+  padding: 10px 20px 30px;
+  box-sizing: border-box;
+  max-height: 90vh;
+  overflow-y: auto; /* 内容过长时允许滚动 */
+  animation: slideUp 0.3s ease-out;
+}
+
+.drag-handle {
+  width: 40px; height: 4px; background: #e0e0e0;
+  border-radius: 2px; margin: 5px auto 15px;
+}
+
+/* Tabs Header */
+.tabs-header {
+  display: flex;
+  justify-content: space-between;
+  border-bottom: 1px solid #f0f0f0;
+  margin-bottom: 20px;
+}
+
+.tab-item {
+  padding: 10px 0;
+  font-size: 14px; /* 字体稍微调小以容纳4个Tab */
+  color: #999;
+  cursor: pointer;
+  position: relative;
+  font-weight: 500;
+  white-space: nowrap;
+}
+
+.tab-item.active {
+  color: #000;
+  font-weight: bold;
+}
+
+.active-line {
+  position: absolute; bottom: -1px; left: 50%;
+  transform: translateX(-50%);
+  width: 20px; height: 3px; background: #000; border-radius: 2px;
+}
+
+/* Top Description (用于止盈止损页面顶部) */
+.top-description {
+  font-size: 13px;
+  color: #333;
+  line-height: 1.6;
+  margin-bottom: 20px;
+  text-align: justify;
+}
+
+/* Controls */
+.control-row {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 15px;
+}
+
+.label {
+  font-size: 14px; font-weight: bold; color: #333;
+}
+
+.checkbox-group {
+  display: flex; gap: 20px;
+}
+
+.checkbox-item {
+  display: flex; align-items: center; cursor: pointer;
+  font-size: 14px; color: #666;
+}
+
+.custom-checkbox {
+  width: 16px; height: 16px; border: 1px solid #ccc;
+  border-radius: 4px; margin-right: 6px;
+  display: flex; align-items: center; justify-content: center;
+  color: white; font-size: 12px;
+}
+
+.custom-checkbox.checked {
+  background-color: #dc3545; border-color: #dc3545;
+}
+
+/* Image */
+.image-container {
+  width: 100%;
+  background: #fff;
+  display: flex; justify-content: center;
+  margin-bottom: 20px;
+}
+
+.image-container img {
+  max-width: 100%; height: auto; object-fit: contain;
+}
+
+/* Description Text */
+.description-text h3 {
+  font-size: 14px; color: #333; margin-bottom: 10px; font-weight: bold;
+}
+
+/* 深度选择器用于控制 v-html 内部样式 */
+.desc-content :deep(p) {
+  font-size: 12px; color: #888; line-height: 1.6; text-align: justify; margin-bottom: 8px;
+}
+
+.desc-content :deep(ol) {
+  font-size: 12px; color: #888; line-height: 1.6;
+}
+.desc-content :deep(li) {
+  margin-bottom: 4px;
+}
+
+/* Footer */
+.footer { margin-top: 20px; }
+.confirm-btn {
+  width: 100%; padding: 12px;
+  background-color: #dc3545; color: white;
+  border: none; border-radius: 24px;
+  font-size: 16px; font-weight: bold; cursor: pointer;
+}
+
+@keyframes slideUp {
+  from { transform: translateY(100%); }
+  to { transform: translateY(0); }
+}
+</style>

+ 171 - 0
src/views/bitcoin/components/MarginInfoSheet.vue

@@ -0,0 +1,171 @@
+<template>
+  <Teleport to="body">
+    <transition name="fade">
+      <div v-if="visible" class="modal-mask" @click="closeModal"></div>
+    </transition>
+
+    <transition name="slide-up">
+      <div v-if="visible" class="modal-panel">
+        <div class="panel-handle-wrap">
+          <div class="panel-handle"></div>
+        </div>
+
+        <div class="panel-content">
+          <div class="section">
+            <h3 class="section-title">逐仓模式</h3>
+            <p class="section-text">
+              根据用户操作一定数量保证金被分配到仓位上,如果仓位亏损到低于维持保证金的水平,仓位将被强平。在逐仓模式下,用户可以自行追加保证金
+            </p>
+          </div>
+
+          <div class="section">
+            <h3 class="section-title">全仓模式</h3>
+            <p class="section-text">
+              仓位保证金将共享全部同币种账户资产,如果仓位亏损低于一定比例,全仓系统将自动追加可用保证金。在强平事件中,交易者可能会损失全部保证金和账户资产
+            </p>
+          </div>
+        </div>
+
+        <div class="panel-footer">
+          <button class="confirm-btn" @click="closeModal">
+            我知道了
+          </button>
+        </div>
+
+        <div class="safe-area-bottom"></div>
+      </div>
+    </transition>
+  </Teleport>
+</template>
+
+<script setup>
+import { defineProps, defineEmits } from 'vue';
+
+// 接收 visible 属性
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    default: false
+  }
+});
+
+// 定义事件
+const emit = defineEmits(['update:visible']);
+
+// 关闭弹窗的方法
+const closeModal = () => {
+  emit('update:visible', false);
+};
+</script>
+
+<style scoped>
+/* 遮罩层 */
+.modal-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  height: 100vh;
+  background-color: rgba(0, 0, 0, 0.6); /* 稍微深一点的遮罩,突出文字 */
+  z-index: 2000;
+}
+
+/* 弹窗主体 */
+.modal-panel {
+  position: fixed;
+  bottom: 0;
+  left: 50%;
+  transform: translateX(-50%); /* 水平居中 */
+  width: 100%;
+  max-width: 600px; /* PC端限制最大宽度 */
+  background: white;
+  border-radius: 16px 16px 0 0;
+  z-index: 2001;
+  display: flex;
+  flex-direction: column;
+  box-sizing: border-box;
+}
+
+/* 顶部 Handle 区域 */
+.panel-handle-wrap {
+  padding: 12px 0 20px 0;
+  display: flex;
+  justify-content: center;
+}
+.panel-handle {
+  width: 36px;
+  height: 4px;
+  background: #E0E0E0;
+  border-radius: 2px;
+}
+
+/* 内容区域 */
+.panel-content {
+  padding: 0 20px;
+  /* 防止内容过多导致无法显示,增加滚动 */
+  max-height: 60vh;
+  overflow-y: auto;
+}
+
+.section {
+  margin-bottom: 24px;
+}
+
+.section-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #1A1A1A;
+  margin: 0 0 8px 0;
+  line-height: 1.4;
+}
+
+.section-text {
+  font-size: 14px;
+  color: #444; /* 设计稿文字看起来比纯黑淡一点 */
+  line-height: 1.6; /* 增加行高,提升阅读体验 */
+  margin: 0;
+  text-align: justify; /* 两端对齐,让大段文字更整齐 */
+}
+
+/* 底部按钮区域 */
+.panel-footer {
+  padding: 20px 20px 10px 20px;
+}
+
+.confirm-btn {
+  width: 100%;
+  height: 48px;
+  background: #DC3E48; /* 提取的红色 hex */
+  color: white;
+  border: none;
+  border-radius: 24px; /* 圆角按钮 */
+  font-size: 16px;
+  font-weight: 500;
+  cursor: pointer;
+  /* 点击时的按压效果 */
+  transition: opacity 0.2s;
+}
+.confirm-btn:active {
+  opacity: 0.9;
+}
+
+/* 底部安全区 */
+.safe-area-bottom {
+  height: env(safe-area-inset-bottom, 20px);
+}
+
+/* 动画定义 */
+.fade-enter-active, .fade-leave-active {
+  transition: opacity 0.3s ease;
+}
+.fade-enter-from, .fade-leave-to {
+  opacity: 0;
+}
+
+.slide-up-enter-active, .slide-up-leave-active {
+  transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
+}
+.slide-up-enter-from, .slide-up-leave-to {
+  transform: translate(-50%, 100%);
+}
+</style>

+ 4 - 3
src/views/bitcoin/components/OrderConfirmPopup.vue

@@ -64,7 +64,6 @@
             :style="contentStyle"
           >
             <div class="tpsl-inner">
-
               <div class="strategy-block">
                 <div class="block-header">
                   <span class="sub-title">止盈</span>
@@ -209,7 +208,8 @@ const handleConfirm = () => {
     .tag.leverage { background: #EFF0F2; color: #999; }
 
     /* 信息列表 */
-    .info-row { display: flex; justify-content: space-between; margin-bottom: 12px; font-size: 14px; }
+    .info-row { display: flex; justify-content: space-between; margin-bottom: 12px;
+      font-size: 14px; }
     .info-row .label { color: #999; }
     .info-row .value { color: #333; font-weight: 500; }
 
@@ -230,7 +230,8 @@ const handleConfirm = () => {
     }
     .strategy-block { margin-bottom: 10px; }
     .mt-15 { margin-top: 15px; }
-    .block-header { display: flex; justify-content: space-between; margin-bottom: 8px; font-size: 13px; }
+    .block-header { display: flex; justify-content: space-between; margin-bottom: 8px;
+      font-size: 13px; }
     .sub-title { font-weight: 600; color: #333; }
     .right-action { color: #333; display: flex; align-items: center; gap: 2px;
       svg{

+ 3 - 1
src/views/bitcoin/components/OrderTimeSheet.vue

@@ -40,6 +40,8 @@
 
 <script setup>
 import { defineProps, defineEmits } from 'vue';
+import { toRef } from 'vue' // 1. 引入 toRef
+import { useBodyScrollLock } from '@/composables/useBodyScrollLock' // 2. 引入 Hook
 
 // 定义接收的属性
 const props = defineProps({
@@ -52,7 +54,7 @@ const props = defineProps({
     default: ''
   }
 });
-
+useBodyScrollLock(toRef(props, 'visible'))
 // 定义抛出的事件
 const emit = defineEmits(['update:visible', 'update:modelValue']);
 

+ 165 - 0
src/views/bitcoin/components/OrderType.vue

@@ -0,0 +1,165 @@
+<template>
+  <Teleport to="body">
+    <div v-if="visible" class="modal-mask" @click="close">
+      <div class="modal-content" @click.stop>
+        <div class="handle-bar"></div>
+        <div class="trigger fs18 fc333333 pf600">选择订单类型</div>
+        <div class="options-list">
+          <div
+            v-for="item in options"
+            :key="item.id"
+            class="option-card"
+            :class="{ 'active': selectedId === item.id }"
+            @click="handleSelect(item)"
+          >
+            <div class="card-header">
+              <span class="title">{{ item.label }}</span>
+              <div v-if="selectedId === item.id" class="check-icon">
+                <svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor"
+                     stroke-width="3" fill="none" stroke-linecap="round" stroke-linejoin="round"
+                     class="css-i6dzq1"><polyline points="20 6 9 17 4 12"></polyline></svg>
+              </div>
+            </div>
+            <div class="description">
+              {{ item.desc }}
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </Teleport>
+</template>
+
+<script setup>
+import { defineProps, defineEmits } from 'vue';
+
+// 接收父组件传来的 modelValue (控制显示) 和 当前选中的ID
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    default: false
+  },
+  selectedId: {
+    type: [String, Number],
+    default: 1
+  }
+});
+
+const emit = defineEmits(['update:visible', 'confirm']);
+
+// 静态数据源 (保持不变)
+const options = [
+  {
+    id: 1,
+    label: '市价',
+    desc: '确保成交,快速买入或卖出'
+  },
+
+  {
+    id: 2,
+    label: '限价',
+    desc: '指定或更优价格进行买入或卖出'
+  }
+];
+
+const close = () => {
+  emit('update:visible', false);
+};
+
+const handleSelect = (item) => {
+  // 1. 触发 confirm 事件,把整个对象带回去
+  emit('confirm', item);
+  // 2. 关闭弹窗
+  close();
+};
+</script>
+
+<style lang="less" scoped>
+.modal-mask {
+  position: fixed;
+  top: 0; left: 0; width: 100%; height: 100%;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: flex-end; /* 底部对齐 */
+  z-index: 1000; /* 极高的 Z-index */
+}
+
+.modal-content {
+  width: 100%;
+  background: white;
+  border-radius: 16px 16px 0 0;
+  padding: 20px;
+  padding-bottom: 40px;
+  max-height: 80vh;
+  overflow-y: auto;
+  animation: slideUp 0.3s ease-out;
+  .trigger{margin-bottom: 15px}
+}
+
+.handle-bar {
+  width: 40px;
+  height: 4px;
+  background: #E0E0E0;
+  border-radius: 2px;
+  margin: 0 auto 20px auto;
+}
+
+.option-card {
+  border: 1px solid #E0E0E0;
+  border-radius: 12px;
+  padding: 16px;
+  margin-bottom: 16px;
+  cursor: pointer;
+  transition: all 0.2s;
+  position: relative;
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 8px;
+}
+
+.title {
+  font-size: 16px;
+  font-weight: bold;
+  color: #333;
+}
+
+.description {
+  font-size: 13px;
+  color: #666;
+  line-height: 1.5;
+}
+
+/* 选中状态样式 */
+.option-card.active {
+  border-color: #F53F3F; /* 红色边框 */
+  background-color: #FFF9F9; /* 极淡的红色背景可选 */
+}
+
+.option-card.active .title {
+  color: #D92828; /* 红色标题 */
+}
+
+.option-card.active .description {
+  color: #D92828; /* 红色描述 */
+}
+
+.check-icon {
+  width: 24px;
+  height: 24px;
+  background: #D92828;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: white;
+}
+
+@keyframes slideUp {
+  from { transform: translateY(100%); }
+  to { transform: translateY(0); }
+}
+</style>

+ 116 - 0
src/views/bitcoin/components/ProfitAndLossPrompt.vue

@@ -0,0 +1,116 @@
+<template>
+  <Teleport to="body">
+    <transition name="fade">
+      <div v-if="visible" class="modal-mask" @click="close">
+
+        <div class="modal-container" @click.stop>
+
+          <div class="modal-title">止盈止损</div>
+
+          <div class="modal-text">
+            止盈止损是指下单时提前为该订单预设止盈价及止损价,以锁定利润或控制损失。当订单完全成交时,系统将自动进行止盈止损委托。
+          </div>
+
+          <button class="main-btn" @click="close">
+            我知道了
+          </button>
+
+        </div>
+      </div>
+    </transition>
+  </Teleport>
+</template>
+
+<script setup>
+import { defineProps, defineEmits } from 'vue';
+
+defineProps({
+  visible: Boolean
+});
+
+const emit = defineEmits(['update:visible']);
+
+const close = () => {
+  emit('update:visible', false);
+};
+</script>
+
+<style scoped>
+/* --- 布局与遮罩 --- */
+.modal-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  height: 100vh;
+  background: rgba(0, 0, 0, 0.6); /* 深色遮罩 */
+  display: flex;
+  align-items: center; /* 垂直居中 */
+  justify-content: center; /* 水平居中 */
+  z-index: 999;
+}
+
+/* --- 弹窗卡片 --- */
+.modal-container {
+  width: 310px; /* 稍微宽一点,适配文字换行 */
+  background: #fff;
+  border-radius: 16px; /* 大圆角 */
+  padding: 24px 24px;
+  box-sizing: border-box;
+  text-align: center;
+  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
+}
+
+/* --- 标题 --- */
+.modal-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #111;
+  margin-bottom: 16px;
+}
+
+/* --- 正文 --- */
+.modal-text {
+  font-size: 15px;
+  color: #555; /* 稍微柔和的深灰色 */
+  line-height: 1.6; /* 增加行高,易读 */
+  text-align: justify; /* 两端对齐,像报纸一样整齐 */
+  margin-bottom: 24px;
+}
+
+/* --- 红色按钮 --- */
+.main-btn {
+  width: 100%;
+  height: 46px;
+  background: #DE3545; /* 截图里的标准红 */
+  color: #fff;
+  font-size: 16px;
+  font-weight: 500;
+  border: none;
+  border-radius: 23px; /* 高度的一半,形成胶囊形状 */
+  cursor: pointer;
+}
+.main-btn:active {
+  opacity: 0.8; /* 点击反馈 */
+}
+
+/* --- 动画效果: 缩放弹入 --- */
+.fade-enter-active, .fade-leave-active {
+  transition: opacity 0.2s ease;
+}
+.fade-enter-active .modal-container {
+  animation: pop-in 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28); /* 弹性动画 */
+}
+.fade-leave-active .modal-container {
+  animation: pop-in 0.3s reverse;
+}
+
+.fade-enter-from, .fade-leave-to {
+  opacity: 0;
+}
+
+@keyframes pop-in {
+  0% { transform: scale(0.8); opacity: 0; }
+  100% { transform: scale(1); opacity: 1; }
+}
+</style>

+ 10 - 1
src/views/bitcoin/components/TakeProfitsTopLoss.vue

@@ -3,6 +3,10 @@
     import { Icon as VanIcon, } from 'vant';
     import {defineAsyncComponent, ref} from 'vue';
     const TPSLSmartPopup = defineAsyncComponent(() => import('../components/TPSLSmartPopup.vue'));
+    const ProfitAndLossPrompt = defineAsyncComponent(() => import('../components/ProfitAndLossPrompt.vue'));
+
+    //止盈止损提示
+    const showModal = ref(false);
 
     // 1. 状态控制
     const isEnabled = ref(false); // 控制复选框选中状态,
@@ -35,7 +39,7 @@
         </van-checkbox>
         <span class="label-text">止盈止损</span>
 
-        <van-icon name="question-o" color="#999" size="16" class="help-icon" />
+        <van-icon name="question-o" color="#999" size="16" class="help-icon" @click="showModal = true"/>
       </div>
 
       <div v-if="isEnabled" class="right-action" @click="handleAdvanced">
@@ -73,6 +77,11 @@
         v-model:visible="showSmartTPSL"
         @confirm="handleConfirm1"
     ></TPSLSmartPopup>
+    <div>
+      <ProfitAndLossPrompt
+          v-model:visible="showModal"
+      ></ProfitAndLossPrompt>
+    </div>
   </div>
 </template>
 

+ 3 - 1
src/views/bitcoin/components/TriggerPrice.vue

@@ -15,7 +15,9 @@
             <div class="card-header">
               <span class="title">{{ item.label }}</span>
               <div v-if="selectedId === item.id" class="check-icon">
-                <svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="3" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><polyline points="20 6 9 17 4 12"></polyline></svg>
+                <svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor"
+                     stroke-width="3" fill="none" stroke-linecap="round" stroke-linejoin="round"
+                     class="css-i6dzq1"><polyline points="20 6 9 17 4 12"></polyline></svg>
               </div>
             </div>
             <div class="description">

+ 17 - 3
src/views/bitcoin/components/position.vue

@@ -1,5 +1,14 @@
 <script setup>
-import { Icon as VanIcon, Button as VanButton } from 'vant';
+    import {defineAsyncComponent, ref} from 'vue';
+
+    import { Icon as VanIcon, Button as VanButton } from 'vant';
+    const ClosePositionSheet   = defineAsyncComponent(() => import("./ClosePositionSheet.vue"));
+    //平仓平空
+    const showModal = ref(false);
+
+
+
+
 
 </script>
 
@@ -192,7 +201,7 @@ import { Icon as VanIcon, Button as VanButton } from 'vant';
         </div>
       </div>
 
-      <div class="footer-btn">
+      <div class="footer-btn" @click="showModal = true">
         <van-button block round color="#e6424a" class="close-btn">
           平仓
         </van-button>
@@ -202,6 +211,11 @@ import { Icon as VanIcon, Button as VanButton } from 'vant';
   </div>
     </div>
     </div>
+   <div>
+      <ClosePositionSheet
+          v-model:visible="showModal">
+      </ClosePositionSheet>
+    </div>
 </template>
 
 <style scoped lang="less">
@@ -362,7 +376,7 @@ import { Icon as VanIcon, Button as VanButton } from 'vant';
 .container {
   background-color: #fff;
   //min-height: 100vh;
-  padding: 15px;
+  padding: 15px 15px;
   font-family: sans-serif;
 }
 

+ 4 - 2
src/views/bitcoin/components/priceLimit.vue

@@ -15,7 +15,9 @@
             <div class="card-header">
               <span class="title">{{ item.label }}({{ item.unit }})</span>
               <div v-if="selectedId === item.id" class="check-icon">
-                <svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor" stroke-width="3" fill="none" stroke-linecap="round" stroke-linejoin="round" class="css-i6dzq1"><polyline points="20 6 9 17 4 12"></polyline></svg>
+                <svg viewBox="0 0 24 24" width="16" height="16" stroke="currentColor"
+                     stroke-width="3" fill="none" stroke-linecap="round" stroke-linejoin="round"
+                     class="css-i6dzq1"><polyline points="20 6 9 17 4 12"></polyline></svg>
               </div>
             </div>
             <div class="description">
@@ -79,7 +81,7 @@ const handleSelect = (item) => {
 };
 </script>
 
-<style>
+<style scoped>
 .modal-mask {
   position: fixed;
   top: 0; left: 0; width: 100%; height: 100%;

+ 88 - 64
src/views/bitcoin/components/sellOrder.vue

@@ -1,51 +1,59 @@
 <script setup>
-import {defineAsyncComponent, ref} from 'vue';
-const assetlessState = defineAsyncComponent(() => import("./assetlessState.vue"));
-const  position = defineAsyncComponent(() => import("./position.vue"));
-
-// 1. 模拟数据:为了还原图片,我们创建两个不同的订单对象
-const orders = ref([
-  {
-    id: 1,
-    symbol: 'BTC/USDT',
-    contractType: '永续',
-    side: 'buy', // 'buy' | 'sell'
-    leverage: '20X',
-    orderType: '市价',
-    amount: '0.215 USDT',
-    price: '0.215 USDT',
-    statusText: '止损',
-    triggerPrice: '标记价格>20',
-    time: '2025-11-04, 16:30',
-    stateText: '未触发',
-    canCancel: true // 显示红色撤单按钮
-  },
-  {
-    id: 2,
-    symbol: 'BTC/USDT',
-    contractType: '永续',
-    side: 'sell',
-    leverage: '20X',
-    orderType: '市价',
-    amount: '0.215 USDT',
-    price: '0.215 USDT',
-    statusText: '止盈',
-    triggerPrice: '标记价格>20',
-    time: '2025-11-04, 16:30',
-    stateText: '未触发',
-    canCancel: false // 显示灰色已完成/不可操作按钮
-  }
-]);
-
-// 当前选中的 Tab,默认选中 index 1 (当前委托)
-const currentTab = ref(0);
-const tabs = ['持有仓位(2)', '当前委托(2)'];
+    import {defineAsyncComponent, ref} from 'vue';
+    //状态组件
+    const assetlessState = defineAsyncComponent(() => import("./assetlessState.vue"));
+    //持有仓位组件
+    const position = defineAsyncComponent(() => import("./position.vue"));
+
+
+
+    // 1. 模拟数据:为了还原图片,我们创建两个不同的订单对象
+    const orders = ref([
+      {
+        id: 1,
+        symbol: 'BTC/USDT',
+        contractType: '永续',
+        side: 'buy', // 'buy' | 'sell'
+        leverage: '20X',
+        orderType: '市价',
+        amount: '0.215 USDT',
+        price: '0.215 USDT',
+        statusText: '止损',
+        triggerPrice: '标记价格>20',
+        time: '2025-11-04,16:30',
+        stateText: '未触发',
+        canCancel: true // 显示红色撤单按钮
+      },
+      {
+        id: 2,
+        symbol: 'BTC/USDT',
+        contractType: '永续',
+        side: 'sell',
+        leverage: '20X',
+        orderType: '市价',
+        amount: '0.215 USDT',
+        price: '0.215 USDT',
+        statusText: '止盈',
+        triggerPrice: '标记价格>20',
+        time: '2025-11-04,16:30',
+        stateText: '未触发',
+        canCancel: false // 显示灰色已完成/不可操作按钮
+      }
+    ]);
+
+    // 当前选中的 Tab,默认选中 index 1 (当前委托)
+    const currentTab = ref(0);
+    const tabs = ['持有仓位(0)', '当前委托(2)'];
+
+    // 按钮操作
+    const handleCancel = (id) => {
+      console.log('撤单 ID:', id);
+      // 这里写撤单逻辑
+    };
+
+    //平仓平空
+    const showModal3 = ref(false);
 
-// 按钮操作
-const handleCancel = (id) => {
-  console.log('撤单 ID:', id);
-  // 这里写撤单逻辑
-};
 </script>
 
 <template>
@@ -54,29 +62,31 @@ const handleCancel = (id) => {
     <div class="tabs-header">
       <div class="tabs-left">
         <div
-          v-for="(tab, index) in tabs"
-          :key="index"
-          class="tab-item"
-          :class="{ active: currentTab === index }"
-          @click="currentTab = index"
+            v-for="(tab, index) in tabs"
+            :key="index"
+            class="tab-item"
+            :class="{ active: currentTab === index }"
+            @click="currentTab = index"
         >
           {{ tab }}
           <div class="active-line" v-if="currentTab === index"></div>
         </div>
       </div>
 
-      <div  class="tabs-right">
+      <div class="tabs-right">
         <span class="history-icon" style="align-content: center; display: flex; gap: 5px; align-items: center">
           <img src="../../../assets/icon/bitcoin/shizhong.svg" alt=""> 全部</span>
       </div>
     </div>
-    <position v-if="currentTab==0"></position>
-
+    <position v-if="currentTab==0.9"></position>
+    <div >
+      <assetlessState v-if="isassetlessState"></assetlessState>
+    </div>
     <div v-if="currentTab==1" class="order-list">
       <div
-        v-for="item in orders"
-        :key="item.id"
-        class="order-card"
+          v-for="item in orders"
+          :key="item.id"
+          class="order-card"
       >
         <div class="card-top">
           <div class="coin-info">
@@ -96,9 +106,9 @@ const handleCancel = (id) => {
           </div>
 
           <button
-            v-if="item.canCancel"
-            class="btn-cancel"
-            @click="handleCancel(item.id)"
+              v-if="item.canCancel"
+              class="btn-cancel"
+              @click="handleCancel(item.id)"
           >
             撤单
           </button>
@@ -139,6 +149,8 @@ const handleCancel = (id) => {
 
       </div>
     </div>
+
+
   </div>
 </template>
 
@@ -308,7 +320,7 @@ const handleCancel = (id) => {
 .card-body-grid {
   display: grid;
   /* 定义三列,左侧和中间自动,右侧靠边 */
-  grid-template-columns: 1fr 1fr 1fr;
+  grid-template-columns: 1fr 2fr 1fr;
   row-gap: 12px; /* 行间距 */
 }
 
@@ -319,9 +331,20 @@ const handleCancel = (id) => {
 }
 
 /* 对齐方式 */
-.align-left { align-items: flex-start; }
-.align-center { align-items: center; }
-.align-right { align-items: flex-end; }
+.align-left {
+  align-items: flex-start;
+}
+
+.align-center {
+  align-items: center;
+  .value:nth-child(2){
+    margin-top: 2px;
+  }
+}
+
+.align-right {
+  align-items: flex-end;
+}
 
 .label {
   font-size: 12px;
@@ -332,6 +355,7 @@ const handleCancel = (id) => {
   font-size: 13px;
   color: #333;
   font-family: Helvetica, Arial, sans-serif; /* 数字字体优化 */
+  font-weight: 500;
 }
 
 .bold-text {

+ 367 - 0
src/views/bitcoin/lever/TradeMargin.vue

@@ -0,0 +1,367 @@
+<template>
+  <div class="page-container">
+    <header class="header">
+      <div class="left" style="display: flex; align-items: center;">
+        <img class="fc333333" src="@/assets/icon/bitcoin/menu.svg" alt="">
+        <h1 class="title">BTCUSDT</h1>
+      </div>
+      <div class="right">
+        <img src="@/assets/icon/bitcoin/den.svg" alt="" @click="showFunctions = true">
+      </div>
+    </header>
+
+    <section class="market-info">
+      <div class="price-block">
+        <div class="fs16" style="margin-bottom: 2px;">实时价格</div>
+        <div class="current-price">1,125,158.00</div>
+        <div class="sub-info ">
+          <span class="fiat fs14 ">≈35,458.00</span>
+          <span class="percent up fs14">+1.42%</span>
+        </div>
+      </div>
+
+      <div class="stat-grid">
+        <div class="stat-item">
+          <span class="label">24h 最高价</span>
+          <span class="value">78,776.76</span>
+        </div>
+        <div class="stat-item">
+          <span class="label">24h 成交量 (BTC)</span>
+          <span class="value">78,776.76</span>
+        </div>
+        <div class="stat-item">
+          <span class="label">24h 最低价</span>
+          <span class="value">78,776.76</span>
+        </div>
+        <div class="stat-item">
+          <span class="label">24h 成交额 (BTC)</span>
+          <span class="value">78,776.76</span>
+        </div>
+      </div>
+    </section>
+
+    <nav class="time-tabs">
+      <div
+        v-for="tab in tabs"
+        :key="tab"
+        class="tab-item"
+        :class="{ active: currentTab === tab }"
+        @click="switchPeriod(tab)"
+      >
+        {{ tab }}
+      </div>
+      <div class="tab-item icon">更多 <span class="triangle">◢</span></div>
+      <div class="tab-item icon">
+        <img src="@/assets/icon/bitcoin/lishidingdan.svg" alt="">
+      </div>
+    </nav>
+
+    <div class="chart-wrapper">
+      <div id="k-line-chart" class="kline-container"></div>
+    </div>
+    <MarketPriceAndPlan></MarketPriceAndPlan>
+    <div style="margin-bottom: 20px">
+      <sellOrder  ></sellOrder>
+    </div>
+
+  </div>
+</template>
+
+<script setup>
+import { onMounted, onUnmounted, ref } from 'vue'
+// ✅ 使用 namespace 引入,防止报错
+import * as klinecharts from 'klinecharts'
+import MarketPriceAndPlan from'./components/MarketPriceAndPlan.vue'
+import sellOrder from '@/views/bitcoin/components/sellOrder.vue';
+
+
+// --- 状态管理 ---
+const currentTab = ref('24h')
+const tabs = ['1h', '6h', '24h', '1w', '1m']
+let chartInstance = null
+
+// --- 数据生成逻辑 ---
+const generateData = (baseVal = 3812.74) => {
+  const data = []
+  let baseTime = new Date().getTime()
+  let basePrice = baseVal
+  for (let i = 0; i < 80; i++) {
+    const change = (Math.random() - 0.5) * 30
+    const close = basePrice + change
+    const open = basePrice + (Math.random() - 0.5) * 10
+    const high = Math.max(open, close) + Math.random() * 10
+    const low = Math.min(open, close) - Math.random() * 10
+    const volume = Math.random() * 100 + 50
+
+    data.push({ timestamp: baseTime, open, high, low, close, volume })
+    baseTime += 60 * 60 * 1000 // 1h 间隔
+    basePrice = close + (Math.random() * 2) // 稍微向上的趋势
+  }
+  return data
+}
+
+// --- 切换周期逻辑 ---
+const switchPeriod = (period) => {
+  currentTab.value = period
+  if (chartInstance) {
+    // 模拟数据刷新
+    const randomStart = 3800 + Math.random() * 100
+    chartInstance.applyNewData(generateData(randomStart))
+  }
+}
+
+// --- 初始化与配置 ---
+onMounted(() => {
+  const chartDOM = document.getElementById('k-line-chart')
+  if (!chartDOM) return
+
+  // 1. 初始化图表
+  chartInstance = klinecharts.init(chartDOM)
+  if (!chartInstance) return
+
+  // 2. 样式常量
+  const targetBlue = '#4A6EF5' // 截图中的蓝色虚线颜色
+  const gridColor = '#F2F4F6'  // 极淡的网格线
+  const textColor = '#929AA5'  // 灰色文字
+
+  // 3. 核心配置 (setStyleOptions)
+  chartInstance.setStyleOptions({
+    grid: {
+      show: true,
+      horizontal: {
+        show: true,
+        size: 1,
+        color: gridColor,
+        style: 'dash',
+        dashValue: [5, 5]
+      },
+      vertical: { show: false }
+    },
+    candle: {
+      type: 'candle_solid',
+      bar: {
+        upColor: '#2EBD85',
+        downColor: '#F6465D',
+        noChangeColor: '#2EBD85'
+      },
+      // ✅ 重点:蓝色价格指示线配置
+      priceMark: {
+        show: true,
+        high: { show: false },
+        low: { show: false },
+        last: {
+          show: true,
+          // 强制无论涨跌都显示蓝色
+          upColor: targetBlue,
+          downColor: targetBlue,
+          line: { show: true, style: 'dash', dashValue: [4, 3] },
+          text: {
+            show: true,
+            color: '#FFFFFF',
+            size: 11,
+            paddingLeft: 4,
+            paddingRight: 4,
+            borderRadius: 2
+          }
+        }
+      },
+      tooltip: {
+        // 只有按压时才显示十字光标
+        showRule: 'follow_cross',
+        showType: 'rect',
+        dataSource: 'none', // 隐藏浮层数据,保持清爽
+        crosshair: {
+          show: true,
+          horizontal: { line: { style: 'dash', color: textColor } },
+          vertical: { line: { style: 'dash', color: textColor } }
+        }
+      }
+    },
+    // ✅ 重点:技术指标(VOL)颜色
+    technicalIndicator: {
+      bar: {
+        upColor: '#2EBD85',
+        downColor: '#F6465D',
+        noChangeColor: '#2EBD85'
+      }
+    },
+    // ✅ 重点:隐藏坐标轴线,只保留文字
+    xAxis: {
+      axisLine: { show: false },
+      tickLine: { show: false },
+      tickText: { color: textColor, size: 10, paddingTop: 8 }
+    },
+    yAxis: {
+      type: 'normal',
+      position: 'right',
+      inside: true,
+      axisLine: { show: false },
+      tickLine: { show: false },
+      tickText: { color: textColor, size: 10, paddingLeft: 8 }
+    },
+    separator: { size: 0 } // 去掉指标和K线之间的分割线
+  })
+
+  // 4. 创建副图指标 (VOL)
+  chartInstance.createTechnicalIndicator('VOL', false, { id: 'pane_1', heightRatio: 0.2 })
+
+  // 5. 加载数据并设置缩放
+  chartInstance.applyNewData(generateData())
+  if (chartInstance.setDataSpace) {
+  chartInstance.setDataSpace(7)
+}
+  // chartInstance.setBarSpace(7) // 设置蜡烛宽度
+})
+
+onUnmounted(() => {
+  if (chartInstance) {
+    klinecharts.dispose('k-line-chart')
+  }
+})
+</script>
+
+<style scoped>
+/* --- 布局容器 --- */
+.page-container {
+  width: 100%;
+  max-width: 375px;
+  margin: 0 auto;
+  background-color: #fff;
+  /* 使用系统字体,还原原生质感 */
+  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Roboto, Arial, sans-serif;
+  color: #333;
+  /* 防止横向滚动条 */
+  overflow-x: hidden;
+}
+
+/* 🔥🔥 核心修改:定义一个公共的左右内边距
+   给 header, market-info, time-tabs, chart-wrapper 都加上
+*/
+.header,
+.market-info,
+.time-tabs,
+.chart-wrapper {
+  padding-left: 15px;
+  padding-right: 15px;
+  /* 关键:确保 padding 不会撑大 width: 100% */
+  box-sizing: border-box;
+}
+
+/* --- 1. 头部 --- */
+.header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+ /* padding-top: 12px;*/
+  padding-bottom: 12px;
+}
+.title {
+  font-size: 18px;
+  font-weight: 600;
+  display: inline-block;
+  margin-left: 10px;
+}
+.icon-menu, .icon-more {
+  font-size: 18px;
+  cursor: pointer;
+}
+
+/* --- 2. 行情信息 --- */
+.market-info {
+  display: flex;
+  justify-content: space-between;
+  padding-bottom: 10px;
+}
+
+.price-block .current-price {
+  font-size: 20px;
+  font-weight: 600;
+  line-height: 1.2;
+  color: #111;
+  /* 稍微调整一下字间距,防止数字太紧 */
+  letter-spacing: -0.5px;
+}
+.sub-info {
+  font-size: 12px;
+  margin-top: 4px;
+  font-weight: 500;
+}
+.sub-info .fiat {
+  color: #999;
+  margin-right: 8px;
+}
+.sub-info .percent.up {
+  color: #2EBD85;
+}
+
+/* 统计网格 */
+.stat-grid {
+  display: grid;
+  grid-template-columns: 1fr 1fr; /* 保持两列 */
+  column-gap: 12px;
+  row-gap: 6px;
+  text-align: right;
+
+}
+.stat-item {
+  display: flex;
+  flex-direction: column;
+
+}
+.stat-item .label {
+  font-size: 11px;
+  color: #999;
+  /* 稍微缩小字体 */
+  transform: scale(0.9);
+  transform-origin: right bottom;
+  white-space: nowrap; /* 防止文字换行 */
+}
+.stat-item .value {
+  font-size: 11px;
+  color: #333;
+  font-family: "DIN", -apple-system, sans-serif; /* 如果有数字字体更好 */
+}
+
+/* --- 3. Tabs --- */
+.time-tabs {
+  display: flex;
+  align-items: center;
+  /*gap: 5px;*/
+  justify-content: space-between;
+  /*//padding-top: 8px;*/
+  /*padding-bottom: 8px;*/
+  /* 你的截图中似乎没有底边框,这里保持干净 */
+}
+.tab-item {
+  font-size: 14px;
+  color: #929AA5;
+  padding: 4px 10px; /* 稍微减小内边距,适应 15px 的两侧挤压 */
+  border-radius: 6px;
+  cursor: pointer;
+  font-weight: 500;
+  transition: all 0.2s;
+}
+.tab-item.active {
+  background-color: #F6465D;
+  color: #fff;
+}
+.tab-item.icon {
+  color: #929AA5;
+  font-size: 12px;
+}
+.triangle {
+  font-size: 8px;
+}
+
+/* --- 4. 图表容器 --- */
+.chart-wrapper {
+  width: 100%;
+  height: 275px;
+  /*margin-top: 5px;*/
+  /* 🔥 这里加了 padding 后,K线图就会自动往里缩,左右留出白边 */
+}
+.kline-container {
+  width: 100%;
+  height: 100%;
+}
+</style>

+ 368 - 0
src/views/bitcoin/lever/TradeSeconds.vue

@@ -0,0 +1,368 @@
+<template>
+  <div class="page-container">
+    <header class="header">
+      <div class="left" style="display: flex; align-items: center;">
+        <img class="fc333333" src="@/assets/icon/bitcoin/menu.svg" alt="">
+        <h1 class="title">BTCUSDT</h1>
+      </div>
+      <div class="right">
+        <img src="@/assets/icon/bitcoin/den.svg" alt="" @click="showFunctions = true">
+      </div>
+    </header>
+
+    <section class="market-info">
+      <div class="price-block">
+        <div class="fs16" style="margin-bottom: 2px;">实时价格</div>
+        <div class="current-price">1,125,158.00</div>
+        <div class="sub-info ">
+          <span class="fiat fs14 ">≈35,458.00</span>
+          <span class="percent up fs14">+1.42%</span>
+        </div>
+      </div>
+
+      <div class="stat-grid">
+        <div class="stat-item">
+          <span class="label">24h 最高价</span>
+          <span class="value">78,776.76</span>
+        </div>
+        <div class="stat-item">
+          <span class="label">24h 成交量 (BTC)</span>
+          <span class="value">78,776.76</span>
+        </div>
+        <div class="stat-item">
+          <span class="label">24h 最低价</span>
+          <span class="value">78,776.76</span>
+        </div>
+        <div class="stat-item">
+          <span class="label">24h 成交额 (BTC)</span>
+          <span class="value">78,776.76</span>
+        </div>
+      </div>
+    </section>
+
+    <nav class="time-tabs">
+      <div
+        v-for="tab in tabs"
+        :key="tab"
+        class="tab-item"
+        :class="{ active: currentTab === tab }"
+        @click="switchPeriod(tab)"
+      >
+        {{ tab }}
+      </div>
+      <div class="tab-item icon">更多 <span class="triangle">◢</span></div>
+      <div class="tab-item icon">
+        <img src="@/assets/icon/bitcoin/lishidingdan.svg" alt="">
+      </div>
+    </nav>
+
+    <div class="chart-wrapper">
+      <div id="k-line-chart" class="kline-container"></div>
+    </div>
+    <ChooseThisCycle></ChooseThisCycle>
+<!--    <MarketPriceAndPlan></MarketPriceAndPlan>-->
+    <div style="margin-bottom: 20px">
+      <sellOrder  ></sellOrder>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { onMounted, onUnmounted, ref } from 'vue'
+// ✅ 使用 namespace 引入,防止报错
+import * as klinecharts from 'klinecharts'
+import MarketPriceAndPlan from'./components/MarketPriceAndPlan.vue'
+import ChooseThisCycle from'./components/ChooseThisCycle.vue'
+import sellOrder from '@/views/bitcoin/components/sellOrder.vue';
+
+
+// --- 状态管理 ---
+const currentTab = ref('24h')
+const tabs = ['1h', '6h', '24h', '1w', '1m']
+let chartInstance = null
+
+// --- 数据生成逻辑 ---
+const generateData = (baseVal = 3812.74) => {
+  const data = []
+  let baseTime = new Date().getTime()
+  let basePrice = baseVal
+  for (let i = 0; i < 80; i++) {
+    const change = (Math.random() - 0.5) * 30
+    const close = basePrice + change
+    const open = basePrice + (Math.random() - 0.5) * 10
+    const high = Math.max(open, close) + Math.random() * 10
+    const low = Math.min(open, close) - Math.random() * 10
+    const volume = Math.random() * 100 + 50
+
+    data.push({ timestamp: baseTime, open, high, low, close, volume })
+    baseTime += 60 * 60 * 1000 // 1h 间隔
+    basePrice = close + (Math.random() * 2) // 稍微向上的趋势
+  }
+  return data
+}
+
+// --- 切换周期逻辑 ---
+const switchPeriod = (period) => {
+  currentTab.value = period
+  if (chartInstance) {
+    // 模拟数据刷新
+    const randomStart = 3800 + Math.random() * 100
+    chartInstance.applyNewData(generateData(randomStart))
+  }
+}
+
+// --- 初始化与配置 ---
+onMounted(() => {
+  const chartDOM = document.getElementById('k-line-chart')
+  if (!chartDOM) return
+
+  // 1. 初始化图表
+  chartInstance = klinecharts.init(chartDOM)
+  if (!chartInstance) return
+
+  // 2. 样式常量
+  const targetBlue = '#4A6EF5' // 截图中的蓝色虚线颜色
+  const gridColor = '#F2F4F6'  // 极淡的网格线
+  const textColor = '#929AA5'  // 灰色文字
+
+  // 3. 核心配置 (setStyleOptions)
+  chartInstance.setStyleOptions({
+    grid: {
+      show: true,
+      horizontal: {
+        show: true,
+        size: 1,
+        color: gridColor,
+        style: 'dash',
+        dashValue: [5, 5]
+      },
+      vertical: { show: false }
+    },
+    candle: {
+      type: 'candle_solid',
+      bar: {
+        upColor: '#2EBD85',
+        downColor: '#F6465D',
+        noChangeColor: '#2EBD85'
+      },
+      // ✅ 重点:蓝色价格指示线配置
+      priceMark: {
+        show: true,
+        high: { show: false },
+        low: { show: false },
+        last: {
+          show: true,
+          // 强制无论涨跌都显示蓝色
+          upColor: targetBlue,
+          downColor: targetBlue,
+          line: { show: true, style: 'dash', dashValue: [4, 3] },
+          text: {
+            show: true,
+            color: '#FFFFFF',
+            size: 11,
+            paddingLeft: 4,
+            paddingRight: 4,
+            borderRadius: 2
+          }
+        }
+      },
+      tooltip: {
+        // 只有按压时才显示十字光标
+        showRule: 'follow_cross',
+        showType: 'rect',
+        dataSource: 'none', // 隐藏浮层数据,保持清爽
+        crosshair: {
+          show: true,
+          horizontal: { line: { style: 'dash', color: textColor } },
+          vertical: { line: { style: 'dash', color: textColor } }
+        }
+      }
+    },
+    // ✅ 重点:技术指标(VOL)颜色
+    technicalIndicator: {
+      bar: {
+        upColor: '#2EBD85',
+        downColor: '#F6465D',
+        noChangeColor: '#2EBD85'
+      }
+    },
+    // ✅ 重点:隐藏坐标轴线,只保留文字
+    xAxis: {
+      axisLine: { show: false },
+      tickLine: { show: false },
+      tickText: { color: textColor, size: 10, paddingTop: 8 }
+    },
+    yAxis: {
+      type: 'normal',
+      position: 'right',
+      inside: true,
+      axisLine: { show: false },
+      tickLine: { show: false },
+      tickText: { color: textColor, size: 10, paddingLeft: 8 }
+    },
+    separator: { size: 0 } // 去掉指标和K线之间的分割线
+  })
+
+  // 4. 创建副图指标 (VOL)
+  chartInstance.createTechnicalIndicator('VOL', false, { id: 'pane_1', heightRatio: 0.2 })
+
+  // 5. 加载数据并设置缩放
+  chartInstance.applyNewData(generateData())
+  if (chartInstance.setDataSpace) {
+  chartInstance.setDataSpace(7)
+}
+  // chartInstance.setBarSpace(7) // 设置蜡烛宽度
+})
+
+onUnmounted(() => {
+  if (chartInstance) {
+    klinecharts.dispose('k-line-chart')
+  }
+})
+</script>
+
+<style scoped>
+/* --- 布局容器 --- */
+.page-container {
+  width: 100%;
+  max-width: 375px;
+  margin: 0 auto;
+  background-color: #fff;
+  /* 使用系统字体,还原原生质感 */
+  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Roboto, Arial, sans-serif;
+  color: #333;
+  /* 防止横向滚动条 */
+  overflow-x: hidden;
+}
+
+/* 🔥🔥 核心修改:定义一个公共的左右内边距
+   给 header, market-info, time-tabs, chart-wrapper 都加上
+*/
+.header,
+.market-info,
+.time-tabs,
+.chart-wrapper {
+  padding-left: 15px;
+  padding-right: 15px;
+  /* 关键:确保 padding 不会撑大 width: 100% */
+  box-sizing: border-box;
+}
+
+/* --- 1. 头部 --- */
+.header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+ /* padding-top: 12px;*/
+  padding-bottom: 12px;
+}
+.title {
+  font-size: 18px;
+  font-weight: 600;
+  display: inline-block;
+  margin-left: 10px;
+}
+.icon-menu, .icon-more {
+  font-size: 18px;
+  cursor: pointer;
+}
+
+/* --- 2. 行情信息 --- */
+.market-info {
+  display: flex;
+  justify-content: space-between;
+  padding-bottom: 10px;
+}
+
+.price-block .current-price {
+  font-size: 20px;
+  font-weight: 600;
+  line-height: 1.2;
+  color: #111;
+  /* 稍微调整一下字间距,防止数字太紧 */
+  letter-spacing: -0.5px;
+}
+.sub-info {
+  font-size: 12px;
+  margin-top: 4px;
+  font-weight: 500;
+}
+.sub-info .fiat {
+  color: #999;
+  margin-right: 8px;
+}
+.sub-info .percent.up {
+  color: #2EBD85;
+}
+
+/* 统计网格 */
+.stat-grid {
+  display: grid;
+  grid-template-columns: 1fr 1fr; /* 保持两列 */
+  column-gap: 12px;
+  row-gap: 6px;
+  text-align: right;
+
+}
+.stat-item {
+  display: flex;
+  flex-direction: column;
+
+}
+.stat-item .label {
+  font-size: 11px;
+  color: #999;
+  /* 稍微缩小字体 */
+  transform: scale(0.9);
+  transform-origin: right bottom;
+  white-space: nowrap; /* 防止文字换行 */
+}
+.stat-item .value {
+  font-size: 11px;
+  color: #333;
+  font-family: "DIN", -apple-system, sans-serif; /* 如果有数字字体更好 */
+}
+
+/* --- 3. Tabs --- */
+.time-tabs {
+  display: flex;
+  align-items: center;
+  /*gap: 5px;*/
+  justify-content: space-between;
+  /*//padding-top: 8px;*/
+  /*padding-bottom: 8px;*/
+  /* 你的截图中似乎没有底边框,这里保持干净 */
+}
+.tab-item {
+  font-size: 14px;
+  color: #929AA5;
+  padding: 4px 10px; /* 稍微减小内边距,适应 15px 的两侧挤压 */
+  border-radius: 6px;
+  cursor: pointer;
+  font-weight: 500;
+  transition: all 0.2s;
+}
+.tab-item.active {
+  background-color: #F6465D;
+  color: #fff;
+}
+.tab-item.icon {
+  color: #929AA5;
+  font-size: 12px;
+}
+.triangle {
+  font-size: 8px;
+}
+
+/* --- 4. 图表容器 --- */
+.chart-wrapper {
+  width: 100%;
+  height: 275px;
+  /*margin-top: 5px;*/
+  /* 🔥 这里加了 padding 后,K线图就会自动往里缩,左右留出白边 */
+}
+.kline-container {
+  width: 100%;
+  height: 100%;
+}
+</style>

+ 272 - 0
src/views/bitcoin/lever/components/ChooseThisCycle.vue

@@ -0,0 +1,272 @@
+<template>
+  <div class="trade-panel">
+    <h3 class="section-title">选择周期</h3>
+
+    <div class="cycle-grid">
+      <div
+        v-for="(item, index) in cycles"
+        :key="index"
+        class="cycle-card"
+        :class="{ active: selectedCycleIndex === index }"
+        @click="selectedCycleIndex = index"
+      >
+        <div class="card-inner">
+          <div class="time">{{ item.time }}</div>
+          <div class="rate">{{ item.rate }}</div>
+        </div>
+      </div>
+    </div>
+
+    <div class="amount-input-box">
+      <span class="label">数量</span>
+      <div class="input-wrapper">
+        <input
+          type="number"
+          v-model="amount"
+          placeholder="请输入数量"
+        />
+        <span class="unit">USDT</span>
+      </div>
+    </div>
+
+    <div class="quick-amount-grid">
+      <div
+        v-for="val in quickAmounts"
+        :key="val"
+        class="amount-btn"
+        :class="{ active: Number(amount) === val }"
+        @click="amount = val"
+      >
+        {{ val }}
+      </div>
+    </div>
+
+    <div class="balance-row">
+      可用 215.0508 USDT <span class="wallet-icon"><img src="@/assets/icon/bitcoin/qianbao1.svg" alt="" class="fs12"></span>
+    </div>
+
+    <button class="buy-btn" @click="handleBuy">
+      购买
+    </button>
+  </div>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+
+// --- 数据配置 ---
+const selectedCycleIndex = ref(0)
+const amount = ref(1000) // 默认金额
+
+const cycles = [
+  { time: '20秒', rate: '12%' },
+  { time: '180秒', rate: '20%' },
+  { time: '360秒', rate: '30%' },
+  { time: '900秒', rate: '40%' },
+  { time: '1800秒', rate: '60%' },
+  { time: '3600秒', rate: '90%' },
+]
+
+const quickAmounts = [50, 100, 500, 1000, 10000, 50000, 100000]
+
+// --- 方法 ---
+const handleBuy = () => {
+  const cycle = cycles[selectedCycleIndex.value]
+  console.log(`下单: 周期=${cycle.time}, 金额=${amount.value}`)
+}
+</script>
+
+<style scoped>
+/* 基础容器配置 */
+.trade-panel {
+  width: 100%;
+  max-width: 375px; /* 设计稿宽度 */
+  margin: 0 auto;
+  padding: 15px;
+  box-sizing: border-box;
+  background-color: #fff;
+  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Roboto, Arial, sans-serif;
+  color: #333;
+}
+
+/* 1. 标题 */
+.section-title {
+  font-size: 16px;
+  font-weight: 600;
+  margin: 0 0 12px 0;
+  color: #333;
+}
+
+/* 2. 周期选择网格 */
+.cycle-grid {
+  display: grid;
+  grid-template-columns: repeat(4, 1fr); /* 4列等宽 */
+  gap: 8px;
+  margin-bottom: 20px;
+}
+
+.cycle-card {
+  /* 基础样式 (未选中) */
+  background-color: #F7F8FA;
+  border-radius: 6px;
+  overflow: hidden; /* 确保圆角生效 */
+  cursor: pointer;
+  text-align: center;
+  height: 64px;
+  display: flex;
+  flex-direction: column;
+  /* 预留边框位置,防止选中时跳动 */
+  border: 1px solid transparent;
+  box-sizing: border-box;
+}
+
+.card-inner {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  width: 100%;
+}
+
+.cycle-card .time {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 13px;
+  color: #666;
+  /* 未选中时上下背景色一致 */
+}
+
+.cycle-card .rate {
+  height: 26px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 12px;
+  color: #999;
+  background-color: rgba(0,0,0,0.02); /* 微微深一点的底色 */
+}
+
+/* 🔥 周期选中态 (核心还原) */
+.cycle-card.active {
+  border-color: #2979FF; /* 外部蓝色边框 */
+  background-color: #fff; /* 边框内的白色间隙(如果需要) */
+}
+
+.cycle-card.active .time {
+  background-color: #DC3545; /* 上半部分深红 */
+  color: #fff;
+  font-weight: 500;
+}
+
+.cycle-card.active .rate {
+  background-color: #F5848E; /* 下半部分浅红 */
+  color: #fff;
+}
+
+/* 3. 数量输入框 */
+.amount-input-box {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  background-color: #F7F8FA;
+  height: 44px;
+  padding: 0 12px;
+  border-radius: 4px;
+  margin-bottom: 12px;
+}
+
+.amount-input-box .label {
+  font-size: 14px;
+  font-weight: 600;
+  color: #333;
+}
+
+.input-wrapper {
+  display: flex;
+  align-items: center;
+  flex: 1;
+  justify-content: flex-end;
+}
+
+.input-wrapper input {
+  border: none;
+  background: transparent;
+  outline: none;
+  text-align: right;
+  font-size: 14px;
+  color: #999; /* 这里模仿截图的灰色数字 1000 */
+  width: 100%;
+  padding-right: 6px;
+  font-family: inherit;
+}
+/* 聚焦时文字变黑 */
+.input-wrapper input:focus {
+  color: #333;
+}
+
+.input-wrapper .unit {
+  font-size: 14px;
+  color: #111;
+  font-weight: 500;
+}
+
+/* 4. 快捷金额网格 */
+.quick-amount-grid {
+  display: grid;
+  grid-template-columns: repeat(5, 1fr); /* 5列等宽 */
+  gap: 8px;
+  margin-bottom: 15px;
+}
+
+.amount-btn {
+  height: 32px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: #F7F8FA;
+  border-radius: 4px;
+  font-size: 12px;
+  color: #333;
+  cursor: pointer;
+  transition: all 0.2s;
+}
+
+/* 金额选中态 */
+.amount-btn.active {
+  background-color: #DC3545; /* 红色背景 */
+  color: #fff;
+}
+
+/* 5. 余额 */
+.balance-row {
+  font-size: 12px;
+  color: #333;
+  display: flex;
+  align-items: center;
+  margin-bottom: 15px;
+}
+.wallet-icon {
+  margin-left: 4px;
+  color: #DC3545;
+  font-size: 14px;
+}
+
+/* 6. 购买按钮 */
+.buy-btn {
+  width: 100%;
+  height: 40px;
+  background-color: #DC3545;
+  color: #fff;
+  border: none;
+  border-radius: 24px;
+  font-size: 16px;
+  font-weight: 500;
+  cursor: pointer;
+  box-shadow: 0 4px 10px rgba(220, 53, 69, 0.2);
+  margin: 0 auto;
+}
+.buy-btn:active {
+  opacity: 0.9;
+}
+</style>

+ 126 - 0
src/views/bitcoin/lever/components/KLineChart.vue

@@ -0,0 +1,126 @@
+<template>
+  <div class="kline-wrapper">
+    <!-- 时间周期 -->
+    <div class="chart-header">
+      <div class="time-intervals">
+        <span class="active">15分</span>
+        <span>1小时</span>
+        <span>4小时</span>
+        <span>日线</span>
+      </div>
+    </div>
+
+    <div ref="chartContainer" class="chart-container"></div>
+
+    <!-- 指标切换 -->
+    <div class="chart-footer">
+      <span class="indicator-btn" @click="setMainIndicator('MA')">MA</span>
+      <span class="indicator-btn" @click="setMainIndicator('BOLL')">BOLL</span>
+      <span class="divider">|</span>
+      <span class="indicator-btn" @click="setSubIndicator('VOL')">VOL</span>
+      <span class="indicator-btn" @click="setSubIndicator('MACD')">MACD</span>
+      <span class="indicator-btn" @click="setSubIndicator('KDJ')">KDJ</span>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { onMounted, onUnmounted, ref } from 'vue'
+import { init, dispose } from 'klinecharts'
+
+const chartContainer = ref(null)
+let chartObj = null
+
+// 生成 mock 数据
+function getMockDataList() {
+  const dataList = []
+  let ts = Date.now()
+  let price = 40000
+
+  for (let i = 0; i < 500; i++) {
+    const timestamp = ts - (500 - i) * 60 * 1000 * 15
+    const random = (Math.random() - 0.5) * 200
+    const open = price
+    const close = price + random
+    const high = Math.max(open, close) + Math.random() * 50
+    const low = Math.min(open, close) - Math.random() * 50
+    const volume = Math.random() * 1000 + 500
+
+    dataList.push({ timestamp, open, high, low, close, volume })
+    price = close
+  }
+
+  return dataList
+}
+
+onMounted(() => {
+  if (!chartContainer.value) {
+    console.error('找不到图表容器')
+    return
+  }
+
+  // 初始化 v8 图表
+  chartObj = init(chartContainer.value)
+
+  console.log('chartObj 实例:', chartObj)
+
+  if (!chartObj) {
+    console.error('图表初始化失败')
+    return
+  }
+
+  // 设置主图 & 副图指标(v8 用 createIndicator)
+  chartObj.createIndicator('MA', false, { id: 'candle_pane' })
+  chartObj.createIndicator('VOL', false, { id: 'pane_1' })
+
+  // v8 的方法是 applyNewData(不是 applyData)
+  const data = getMockDataList()
+  chartObj.applyNewData(data)
+})
+
+onUnmounted(() => {
+  if (chartObj) dispose(chartContainer.value)
+})
+
+// 切换主图指标
+function setMainIndicator(name) {
+  chartObj.createIndicator(name, false, { id: 'candle_pane' })
+}
+
+// 切换副图指标
+function setSubIndicator(name) {
+  chartObj.createIndicator(name, false, { id: 'pane_1' })
+}
+</script>
+
+<style scoped>
+.kline-wrapper {
+  display: flex;
+  flex-direction: column;
+  width: 100%;
+}
+
+.chart-header, .chart-footer {
+  display: flex;
+  padding: 10px 15px;
+  background: #fff;
+}
+
+.time-intervals span, .indicator-btn {
+  font-size: 12px;
+  color: #666;
+  margin-right: 15px;
+  cursor: pointer;
+}
+
+.time-intervals span.active {
+  font-weight: bold;
+  color: #333;
+}
+
+.chart-container {
+  width: 100%;
+  height: 450px;
+  background: #fff;
+}
+</style>

+ 483 - 0
src/views/bitcoin/lever/components/MarketPriceAndPlan.vue

@@ -0,0 +1,483 @@
+<template>
+  <div class="trade-container">
+    <div class="trade-tabs">
+      <span
+        class="tab"
+        :class="{ active: tradeType === 'market' }"
+        @click="tradeType = 'market'"
+      >
+        市价
+      </span>
+      <span
+        class="tab"
+        :class="{ active: tradeType === 'plan' }"
+        @click="tradeType = 'plan'"
+      >
+        计划
+      </span>
+    </div>
+
+    <div v-if="tradeType === 'plan'" class="plan-price-input">
+      <input type="number" placeholder="请输入价格" />
+    </div>
+
+    <div class="section-container" :class="{ 'mt-20': tradeType === 'plan' }">
+      <div class="section-label" v-if="tradeType === 'market'">杠杆倍数</div>
+      <div class="grid-row">
+        <div
+          v-for="lev in leverages"
+          :key="lev"
+          class="tag-btn"
+          :class="{ active: currentLeverage === lev }"
+          @click="selectLeverage(lev)"
+        >
+          {{ lev }}X
+        </div>
+
+        <div class="tag-btn" @click="openLeverageModal">更多</div>
+      </div>
+    </div>
+
+    <div class="input-group" :class="{ focused: isInputFocused }">
+      <span class="prefix">本金</span>
+      <input
+        type="number"
+        placeholder="1000"
+        v-model="amount"
+        @focus="isInputFocused = true"
+        @blur="isInputFocused = false"
+      />
+      <span class="suffix">USDT</span>
+    </div>
+
+    <div class="grid-row mt-10">
+      <div
+        v-for="amt in quickAmounts"
+        :key="amt"
+        class="tag-btn light"
+        :class="{ active: Number(amount) === amt }"
+        @click="amount = amt"
+      >
+        {{ amt }}
+      </div>
+      <div class="tag-btn light">更多</div>
+    </div>
+
+    <div class="balance-row">
+      可用 215.0508 USDT <span class="wallet-icon"><img src="@/assets/icon/bitcoin/qianbao1.svg" alt=""></span>
+    </div>
+
+    <div class="action-buttons">
+      <button class="btn-long">
+        <div class="main-text">买入(做多)</div>
+        <div class="sub-text">预计开仓 0.008 BTC</div>
+      </button>
+      <button class="btn-short">
+        <div class="main-text">卖出(做空)</div>
+        <div class="sub-text">预计开仓 0.008 BTC</div>
+      </button>
+    </div>
+
+    <sellOrder v-bind:tradeType="'plan'" ></sellOrder>
+
+    <div >
+      <assetlessState v-if="isassetlessState"></assetlessState>
+    </div>
+
+    <div v-if="showModal" class="modal-mask" @click="showModal = false">
+      <div class="modal-content" @click.stop>
+        <div class="drag-handle"></div>
+        <h3 class="modal-title">调整保证金</h3>
+
+        <div class="stepper-box">
+          <button class="step-btn" @click="adjustIndex(-1)">—</button>
+          <div class="step-value">{{ leverageMarks[sliderIndex] }}x</div>
+          <button class="step-btn" @click="adjustIndex(1)">+</button>
+        </div>
+
+        <div class="slider-container">
+          <div class="start-marker"></div>
+
+          <input
+            type="range"
+            min="0"
+            :max="leverageMarks.length - 1"
+            step="1"
+            v-model="sliderIndex"
+            class="custom-range"
+            :style="sliderStyle"
+          />
+
+          <div class="slider-marks">
+            <span
+              v-for="(mark, index) in leverageMarks"
+              :key="mark"
+              :class="{ active: index === Number(sliderIndex) }"
+            >
+              {{ mark }}
+            </span>
+          </div>
+        </div>
+
+        <button class="confirm-btn" @click="confirmLeverage">确认</button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import {ref, computed, defineAsyncComponent} from 'vue'
+
+const assetlessState = defineAsyncComponent(() => import("@/views/bitcoin/components/assetlessState.vue"));
+
+
+// --- 状态管理 ---
+const tradeType = ref('market')
+const currentLeverage = ref(50) // 当前实际生效的杠杆
+const amount = ref('')
+const isInputFocused = ref(false)
+const showModal = ref(false)
+
+// 首页显示的固定选项
+const leverages = [20, 50, 100, 1000]
+// 快捷金额
+const quickAmounts = [50, 100, 500, 1000]
+
+// 🔥🔥 修改点3:弹窗内的固定阶梯数组 (1, 50, 100, 500, 1000)
+const leverageMarks = [1, 50, 100, 500, 1000]
+
+// 弹窗内的滑块索引 (0 ~ 4)
+const sliderIndex = ref(0)
+
+// --- 方法 ---
+
+// 1. 直接选择杠杆 (不弹窗)
+const selectLeverage = (val) => {
+  currentLeverage.value = val
+}
+
+// 2. 打开更多弹窗
+const openLeverageModal = () => {
+  // 尝试在阶梯数组中找到当前杠杆的位置
+  const idx = leverageMarks.indexOf(currentLeverage.value)
+
+  // 如果当前杠杆(比如20x)不在弹窗数组里,默认让滑块停在第1个(索引0,即1x)或者第2个
+  // 这里逻辑设定为:如果找不到,就默认归零
+  sliderIndex.value = idx !== -1 ? idx : 0
+
+  showModal.value = true
+}
+
+// 步进器调整
+const adjustIndex = (delta) => {
+  let newIndex = Number(sliderIndex.value) + delta
+  if (newIndex < 0) newIndex = 0
+  if (newIndex > leverageMarks.length - 1) newIndex = leverageMarks.length - 1
+  sliderIndex.value = newIndex
+}
+
+// 确认选择
+const confirmLeverage = () => {
+  currentLeverage.value = leverageMarks[sliderIndex.value]
+  showModal.value = false
+}
+
+// 进度条背景颜色计算
+const sliderStyle = computed(() => {
+  const maxIndex = leverageMarks.length - 1
+  const val = Number(sliderIndex.value)
+  const percentage = (val / maxIndex) * 100
+  return {
+    background: `linear-gradient(to right, #F6465D 0%, #F6465D ${percentage}%, #F2F4F6 ${percentage}%, #F2F4F6 100%)`
+  }
+})
+</script>
+
+<style scoped>
+/* 样式部分保持不变,直接复用之前的 CSS 即可 */
+/* 全局容器配置 */
+.trade-container {
+  width: 100%;
+  max-width: 375px;
+  margin: 0 auto;
+  padding: 15px;
+  box-sizing: border-box;
+  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Roboto, sans-serif;
+  color: #333;
+  background-color: #fff;
+  position: relative;
+}
+
+/* Tabs */
+.trade-tabs {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 15px;
+}
+.tab {
+  font-size: 16px;
+  color: #999;
+  font-weight: 500;
+  cursor: pointer;
+  padding-bottom: 4px;
+  transition: all 0.2s;
+}
+.tab.active {
+  color: #111;
+  font-weight: 600;
+}
+
+/* 计划委托输入框 */
+.plan-price-input {
+  width: 100%;
+  height: 44px;
+  background-color: #F7F8FA;
+  border-radius: 4px;
+  display: flex;
+  align-items: center;
+  padding: 0 12px;
+  box-sizing: border-box;
+  margin-bottom: 12px;
+}
+.plan-price-input input {
+  width: 100%;
+  border: none;
+  background: transparent;
+  outline: none;
+  font-size: 14px;
+  color: #333;
+}
+
+/* 间距与布局 */
+.mt-20 { margin-top: 12px; }
+.mt-10 { margin-top: 10px; }
+.section-label {
+  font-size: 12px;
+  color: #999;
+  margin-bottom: 8px;
+}
+.grid-row {
+  display: grid;
+  grid-template-columns: repeat(5, 1fr);
+  gap: 8px;
+  margin-bottom: 12px;
+}
+
+/* 按钮样式 */
+.tag-btn {
+  height: 32px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: #F7F8FA;
+  border-radius: 4px;
+  font-size: 12px;
+  color: #333;
+  cursor: pointer;
+  transition: all 0.2s;
+}
+
+.tag-btn.active {
+  background-color: #F6465D !important;
+  color: #fff !important;
+  font-weight: 500;
+}
+.tag-btn.light {
+  background-color: #F7F8FA;
+  color: #333;
+}
+
+/* 输入框组 */
+.input-group {
+  display: flex;
+  align-items: center;
+  height: 44px;
+  background-color: #F7F8FA;
+  border-radius: 4px;
+  padding: 0 12px;
+  border: 1px solid transparent;
+  transition: all 0.2s;
+}
+.input-group.focused {
+  background-color: #fff;
+  border-color: #2979FF;
+  box-shadow: 0 0 0 1px rgba(41, 121, 255, 0.1);
+}
+.prefix, .suffix { font-size: 14px; color: #111; font-weight: 500; }
+.suffix { font-size: 12px; }
+.input-group input {
+  flex: 1;
+  border: none;
+  background: transparent;
+  outline: none;
+  text-align: right;
+  padding: 0 10px;
+  font-size: 14px;
+  color: #333;
+}
+
+/* 余额与操作按钮 */
+.balance-row {
+  margin-top: 15px;
+  font-size: 12px;
+  color: #666;
+  display: flex;
+  align-items: center;
+}
+.wallet-icon { margin-left: 4px; color: #F6465D; }
+
+.action-buttons { display: flex; gap: 12px; margin-top: 15px; }
+.btn-long, .btn-short {
+  flex: 1;
+  border: none;
+  height: 60px;
+  border-radius: 6px;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  cursor: pointer;
+}
+.btn-long { background-color: #2EBD85; }
+.btn-short { background-color: #F6465D; }
+.main-text { font-size: 16px; font-weight: 600; margin-bottom: 2px; }
+.sub-text { font-size: 10px; opacity: 0.9; font-weight: 400; }
+
+/* Modal 弹窗 */
+.modal-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  height: 100vh;
+  background-color: rgba(0, 0, 0, 0.4);
+  z-index: 999;
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-end;
+}
+.modal-content {
+  background-color: #fff;
+  width: 100%;
+  max-width: 375px;
+  margin: 0 auto;
+  border-radius: 16px 16px 0 0;
+  padding: 10px 20px 30px;
+  box-sizing: border-box;
+  animation: slideUp 0.3s ease-out;
+}
+@keyframes slideUp {
+  from { transform: translateY(100%); }
+  to { transform: translateY(0); }
+}
+.drag-handle {
+  width: 40px;
+  height: 4px;
+  background-color: #E0E0E0;
+  border-radius: 2px;
+  margin: 0 auto 15px;
+}
+.modal-title {
+  font-size: 16px;
+  font-weight: 600;
+  margin-bottom: 20px;
+}
+
+/* 步进器 */
+.stepper-box {
+  display: flex;
+  align-items: center;
+  background-color: #F7F8FA;
+  border-radius: 8px;
+  height: 48px;
+  margin-bottom: 30px;
+}
+.step-btn {
+  width: 60px;
+  height: 100%;
+  border: none;
+  background: transparent;
+  font-size: 24px;
+  color: #999;
+  cursor: pointer;
+}
+.step-value {
+  flex: 1;
+  text-align: center;
+  font-size: 18px;
+  font-weight: 600;
+  color: #333;
+}
+
+/* Slider 容器与样式 */
+.slider-container {
+  position: relative;
+  margin-bottom: 40px;
+  padding: 0 12px;
+}
+
+/* 起始点的固定圆圈 */
+.start-marker {
+  position: absolute;
+  left: 12px;
+  top: 50%;
+  transform: translateY(-50%);
+  width: 24px;
+  height: 24px;
+  background: #fff;
+  border: 2px solid #F6465D;
+  border-radius: 50%;
+  z-index: 1;
+  box-sizing: border-box;
+}
+
+.custom-range {
+  -webkit-appearance: none;
+  width: 100%;
+  height: 6px;
+  border-radius: 3px;
+  outline: none;
+  position: relative;
+  z-index: 2;
+  background: transparent;
+}
+
+.custom-range::-webkit-slider-thumb {
+  -webkit-appearance: none;
+  width: 24px;
+  height: 24px;
+  border-radius: 50%;
+  background: #fff;
+  border: 2px solid #F6465D;
+  cursor: pointer;
+  box-shadow: 0 2px 6px rgba(0,0,0,0.15);
+  margin-top: -1px;
+  box-sizing: border-box;
+}
+
+/* 刻度文字 */
+.slider-marks {
+  display: flex;
+  justify-content: space-between;
+  margin-top: 10px;
+  color: #999;
+  font-size: 12px;
+}
+.slider-marks span.active {
+  color: #333;
+  font-weight: 600;
+}
+
+.confirm-btn {
+  width: 100%;
+  height: 48px;
+  background-color: #F6465D;
+  color: #fff;
+  border: none;
+  border-radius: 24px;
+  font-size: 16px;
+  font-weight: 600;
+  cursor: pointer;
+}
+</style>

+ 425 - 0
src/views/bitcoin/lever/yii.vue

@@ -0,0 +1,425 @@
+<template>
+  <div class="trade-container">
+    <div class="trade-tabs">
+      <span class="tab active">市价</span>
+      <span class="tab">计划</span>
+    </div>
+
+    <div class="section-label">杠杆倍数</div>
+    <div class="grid-row">
+      <div
+        v-for="lev in leverages"
+        :key="lev"
+        class="tag-btn"
+        :class="{ active: currentLeverage === lev }"
+        @click="selectLeverage(lev)"
+      >
+        {{ lev }}X
+      </div>
+      <div class="tag-btn" @click="showModal = true">更多</div>
+    </div>
+
+    <div class="input-group" :class="{ focused: isInputFocused }">
+      <span class="prefix">本金</span>
+      <input
+        type="number"
+        placeholder="请输入价格"
+        v-model="amount"
+        @focus="isInputFocused = true"
+        @blur="isInputFocused = false"
+      />
+      <span class="suffix">USDT</span>
+    </div>
+
+    <div class="grid-row mt-10">
+      <div
+        v-for="amt in quickAmounts"
+        :key="amt"
+        class="tag-btn light"
+        @click="amount = amt"
+      >
+        {{ amt }}
+      </div>
+      <div class="tag-btn light">更多</div>
+    </div>
+
+    <div class="balance-row">
+      可用 215.0508 USDT <span class="wallet-icon">👛</span>
+    </div>
+
+    <div class="action-buttons">
+      <button class="btn-long">
+        <div class="main-text">买入(做多)</div>
+        <div class="sub-text">预计开仓 0.008 BTC</div>
+      </button>
+      <button class="btn-short">
+        <div class="main-text">卖出(做空)</div>
+        <div class="sub-text">预计开仓 0.008 BTC</div>
+      </button>
+    </div>
+
+    <div v-if="showModal" class="modal-mask" @click="showModal = false">
+      <div class="modal-content" @click.stop>
+        <div class="drag-handle"></div>
+
+        <h3 class="modal-title">调整保证金</h3>
+
+        <div class="stepper-box">
+          <button class="step-btn" @click="adjustLeverage(-1)">—</button>
+          <div class="step-value">{{ tempLeverage }}x</div>
+          <button class="step-btn" @click="adjustLeverage(1)">+</button>
+        </div>
+
+        <div class="slider-container">
+          <input
+            type="range"
+            min="1"
+            max="1000"
+            v-model="tempLeverage"
+            class="custom-range"
+            :style="sliderStyle"
+          />
+          <div class="slider-marks">
+            <span>1</span>
+            <span>50</span>
+            <span>100</span>
+            <span>500</span>
+            <span>1000</span>
+          </div>
+        </div>
+
+        <button class="confirm-btn" @click="confirmLeverage">确认</button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed } from 'vue'
+
+// --- 状态管理 ---
+const currentLeverage = ref(50) // 当前选中的杠杆
+const tempLeverage = ref(20)    // 弹窗中临时的杠杆
+const amount = ref('')          // 输入金额
+const isInputFocused = ref(false)
+const showModal = ref(false)
+
+const leverages = [20, 50, 100, 1000]
+const quickAmounts = [50, 100, 500, 1000]
+
+// --- 方法 ---
+const selectLeverage = (val) => {
+  currentLeverage.value = val
+  tempLeverage.value = val // 同步到弹窗
+}
+
+const adjustLeverage = (delta) => {
+  let val = parseInt(tempLeverage.value) + delta
+  if (val < 1) val = 1
+  if (val > 1000) val = 1000
+  tempLeverage.value = val
+}
+
+const confirmLeverage = () => {
+  currentLeverage.value = tempLeverage.value
+  showModal.value = false
+}
+
+// --- 计算属性:动态生成 Slider 的红色进度条背景 ---
+const sliderStyle = computed(() => {
+  const min = 1
+  const max = 1000
+  const val = tempLeverage.value
+  // 计算百分比: (val - min) / (max - min) * 100
+  const percentage = ((val - min) / (max - min)) * 100
+  return {
+    background: `linear-gradient(to right, #F6465D 0%, #F6465D ${percentage}%, #F2F4F6 ${percentage}%, #F2F4F6 100%)`
+  }
+})
+</script>
+
+<style scoped>
+/* 全局容器配置 */
+.trade-container {
+  width: 100%;
+  max-width: 375px;
+  margin: 0 auto;
+  padding: 15px; /* 这里的 padding 对应之前要求的安全距离 */
+  box-sizing: border-box;
+  font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Roboto, sans-serif;
+  color: #333;
+  background-color: #fff;
+  position: relative; /* 为弹窗定位做准备 */
+}
+
+/* 1. Tabs */
+.trade-tabs {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 15px;
+}
+.tab {
+  font-size: 16px;
+  color: #999;
+  font-weight: 500;
+  cursor: pointer;
+}
+.tab.active {
+  color: #111;
+  font-weight: 600;
+}
+
+/* 2. Grid 按钮组 */
+.section-label {
+  font-size: 12px;
+  color: #999;
+  margin-bottom: 8px;
+}
+.grid-row {
+  display: grid;
+  grid-template-columns: repeat(5, 1fr); /* 5列等分 */
+  gap: 8px;
+  margin-bottom: 15px;
+}
+.mt-10 {
+  margin-top: 10px;
+}
+
+.tag-btn {
+  height: 32px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: #F7F8FA;
+  border-radius: 4px;
+  font-size: 12px;
+  color: #333;
+  cursor: pointer;
+  transition: all 0.2s;
+}
+/* 选中状态 - 红色 (还原图1) */
+.tag-btn.active {
+  background-color: #F6465D; /* 截图中的红 */
+  color: #fff;
+  font-weight: 500;
+}
+/* 浅色按钮 (还原图2下方的金额按钮) */
+.tag-btn.light {
+  background-color: #F7F8FA;
+  color: #333;
+}
+
+/* 3. 输入框组 (还原图2的蓝色边框) */
+.input-group {
+  display: flex;
+  align-items: center;
+  height: 44px;
+  background-color: #F7F8FA; /* 默认灰色背景 */
+  border-radius: 4px;
+  padding: 0 12px;
+  border: 1px solid transparent; /* 预留边框位置 */
+  transition: all 0.2s;
+}
+/* 聚焦时的样式 - 还原图2 */
+.input-group.focused {
+  background-color: #fff;
+  border-color: #2979FF; /* 截图中的亮蓝色 */
+  box-shadow: 0 0 0 1px rgba(41, 121, 255, 0.1); /* 可选:微弱的光晕 */
+}
+
+.prefix, .suffix {
+  font-size: 14px;
+  color: #111;
+  font-weight: 500;
+  white-space: nowrap;
+}
+.suffix {
+  font-size: 12px;
+}
+
+.input-group input {
+  flex: 1;
+  border: none;
+  background: transparent;
+  outline: none;
+  text-align: right;
+  padding: 0 10px;
+  font-size: 14px;
+  color: #333;
+}
+.input-group input::placeholder {
+  color: #CCC;
+  text-align: left; /* placeholder靠左,输入内容靠右 */
+}
+
+/* 5. 余额行 */
+.balance-row {
+  margin-top: 15px;
+  font-size: 12px;
+  color: #666;
+  display: flex;
+  align-items: center;
+}
+.wallet-icon {
+  margin-left: 4px;
+  color: #F6465D;
+}
+
+/* 6. 底部大按钮 */
+.action-buttons {
+  display: flex;
+  gap: 12px;
+  margin-top: 15px;
+}
+.btn-long, .btn-short {
+  flex: 1;
+  border: none;
+  height: 60px; /* 增加高度以容纳两行字 */
+  border-radius: 6px;
+  color: #fff;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  cursor: pointer;
+}
+.btn-long { background-color: #2EBD85; }
+.btn-short { background-color: #F6465D; }
+
+.main-text {
+  font-size: 16px;
+  font-weight: 600;
+  margin-bottom: 2px;
+}
+.sub-text {
+  font-size: 10px;
+  opacity: 0.9;
+  font-weight: 400;
+}
+
+/* ========================================= */
+/* 7. Modal 弹窗样式 (核心还原) */
+/* ========================================= */
+.modal-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  height: 100vh;
+  background-color: rgba(0, 0, 0, 0.4);
+  z-index: 999;
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-end; /* 底部对齐 */
+}
+
+.modal-content {
+  background-color: #fff;
+  width: 100%;
+  max-width: 375px;
+  margin: 0 auto; /* 适配 PC 居中 */
+  border-radius: 16px 16px 0 0;
+  padding: 10px 20px 30px;
+  box-sizing: border-box;
+  animation: slideUp 0.3s ease-out;
+}
+
+@keyframes slideUp {
+  from { transform: translateY(100%); }
+  to { transform: translateY(0); }
+}
+
+.drag-handle {
+  width: 40px;
+  height: 4px;
+  background-color: #E0E0E0;
+  border-radius: 2px;
+  margin: 0 auto 15px;
+}
+
+.modal-title {
+  font-size: 16px;
+  font-weight: 600;
+  margin-bottom: 20px;
+}
+
+/* 步进器 */
+.stepper-box {
+  display: flex;
+  align-items: center;
+  background-color: #F7F8FA;
+  border-radius: 8px;
+  height: 48px;
+  margin-bottom: 30px;
+}
+.step-btn {
+  width: 60px;
+  height: 100%;
+  border: none;
+  background: transparent;
+  font-size: 24px;
+  color: #999;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.step-value {
+  flex: 1;
+  text-align: center;
+  font-size: 18px;
+  font-weight: 600;
+  color: #333;
+}
+
+/* 自定义 Slider (核心难点) */
+.slider-container {
+  position: relative;
+  margin-bottom: 40px;
+  padding: 0 10px;
+}
+
+.custom-range {
+  -webkit-appearance: none;
+  width: 100%;
+  height: 6px;
+  border-radius: 3px;
+  outline: none;
+  /* 背景色通过 inline-style 动态设置渐变 */
+}
+
+/* 滑块样式 (Thumb) */
+.custom-range::-webkit-slider-thumb {
+  -webkit-appearance: none;
+  appearance: none;
+  width: 24px;
+  height: 24px;
+  border-radius: 50%;
+  background: #fff;
+  border: 2px solid #F6465D; /* 截图中的红圈白底滑块 */
+  cursor: pointer;
+  box-shadow: 0 2px 6px rgba(0,0,0,0.1);
+  margin-top: -1px; /* 微调对齐 */
+}
+
+/* 刻度标签 */
+.slider-marks {
+  display: flex;
+  justify-content: space-between;
+  margin-top: 10px;
+  color: #666;
+  font-size: 12px;
+}
+
+.confirm-btn {
+  width: 100%;
+  height: 48px;
+  background-color: #F6465D;
+  color: #fff;
+  border: none;
+  border-radius: 24px;
+  font-size: 16px;
+  font-weight: 600;
+  cursor: pointer;
+}
+</style>

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio