Parcourir la source

切换深度-完成
切换倍数 -完成
下单确认-完成
设置止盈止损高级-完成
下单确定止盈止损-完成
止盈止损涨幅百分比-完成
止盈止损触发价格-完成

Hexinkui il y a 1 mois
Parent
commit
07b9dbc4a5

+ 44 - 11
src/views/bitcoin/Index.vue

@@ -169,9 +169,9 @@
          <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" @click="showLeverageModal = true">
             <span></span>
-            <span>USDT</span>
+            <span>{{ selectedLeverage }}X</span>
             <span>更多</span>
          </div>
 
@@ -199,7 +199,7 @@
          </div>
 
       </div>
-        <TakeProfitstopLoss v-show="!isEnabled"></TakeProfitstopLoss>
+        <TakeProfitsTopLoss v-show="!isEnabled"></TakeProfitsTopLoss>
 
         <div class="menu-content-rb pf400 fs14">
          <div class="menu-content-rb1 fs14 fc333333">
@@ -224,7 +224,7 @@
 
       </div>
 
-        <div class="menu-content-rb pf400 fs14">
+        <div class="menu-content-rb pf400 fs14" @click="showConfirm = true">
           <div class="pf400 fs16 fcFFFFFF">买入(做多)</div>
 
         </div>
@@ -252,13 +252,12 @@
 
       </div>
         <div class="menu-content-rb pf400 fs14">
-          <div class="pf400 fs16 fcFFFFFF">买入(做多)</div>
-
+          <div class="pf400 fs16 fcFFFFFF" @click="showConfirm = true">卖出(做空)</div>
         </div>
       </div>
     </div>
     <sellOrder></sellOrder>
-
+    <!--    //各种弹窗-->
     <div v-if="isassetlessState">
       <assetlessState></assetlessState>
     </div>
@@ -268,7 +267,21 @@
           v-model="currentDepth"
       ></ChooseThisDepth>
     </div>
+    <div>
+      <LeveragePopup
+          v-model:visible="showLeverageModal"
+          :initial-value="selectedLeverage"
+          @confirm="handleConfirm">
+      </LeveragePopup>
+    </div>
+    <div>
+      <OrderConfirmPopup
+          v-model:visible="showConfirm"
+          @confirm="onOrderConfirmed">
+      </OrderConfirmPopup>
+    </div>
   </div>
+
 </template>
 <script setup>
     import { Checkbox as VanCheckbox } from 'vant';
@@ -276,18 +289,19 @@
     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 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 isPickerVisible = ref(false); // 控制弹窗开关
     const currentDepth = ref('depth1'); // 当前选中的深度
-
-
     const depthMap = {
       'depth1': '深度1',
       'depth2': '深度2',
@@ -295,8 +309,27 @@
     };
     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>

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

@@ -0,0 +1,300 @@
+<template>
+  <Teleport to="body">
+    <transition name="fade">
+      <div
+        v-if="visible"
+        class="mask"
+        @click="handleClose"
+      ></div>
+    </transition>
+
+    <transition name="slide-up">
+      <div v-if="visible" class="popup-container">
+        <div class="drag-handle-area">
+          <div class="drag-handle"></div>
+        </div>
+
+        <div class="popup-content">
+          <h3 class="title">切换倍数</h3>
+
+          <div class="stepper-box">
+            <button class="step-btn minus" @click="decrement" :disabled="currentIndex <= 0">
+              <span class="icon">−</span>
+            </button>
+            <div class="value-display">{{ currentValue }}x</div>
+            <button class="step-btn plus" @click="increment" :disabled="currentIndex >= marks.length - 1">
+              <span class="icon">+</span>
+            </button>
+          </div>
+
+          <div class="slider-container">
+            <div class="slider-track-bg"></div>
+            <div
+              class="slider-track-active"
+              :style="{ width: getProgressPercent + '%' }"
+            ></div>
+
+            <div
+              class="slider-thumb"
+              :style="{ left: getProgressPercent + '%' }"
+              @touchstart="startDrag"
+            >
+              <div class="inner-circle"></div>
+            </div>
+
+            <input
+              type="range"
+              min="0"
+              :max="marks.length - 1"
+              step="1"
+              v-model="currentIndex"
+              class="native-input"
+            />
+          </div>
+
+          <div class="slider-labels">
+            <span
+              v-for="(mark, index) in marks"
+              :key="mark"
+              :class="{ active: index === currentIndex }"
+            >
+              {{ mark }}x
+            </span>
+          </div>
+
+          <button class="confirm-btn" @click="confirmSelection">
+            确认
+          </button>
+        </div>
+      </div>
+    </transition>
+  </Teleport>
+</template>
+
+<script setup>
+import { ref, computed, watch } from 'vue';
+
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    default: false
+  },
+  initialValue: {
+    type: Number,
+    default: 50
+  }
+});
+
+const emit = defineEmits(['update:visible', 'confirm']);
+
+// 定义倍数阶梯 (非线性)
+const marks = [10, 50, 100, 500, 1000];
+
+// 当前选中的索引 (对应 marks 数组)
+const currentIndex = ref(1);
+
+// 监听弹窗打开,初始化数值
+watch(() => props.visible, (newVal) => {
+  if (newVal) {
+    const idx = marks.indexOf(props.initialValue);
+    currentIndex.value = idx !== -1 ? idx : 1; // 默认选中50x或传入值
+  }
+});
+
+// 计算当前显示的具体倍数值
+const currentValue = computed(() => marks[currentIndex.value]);
+
+// 计算进度条百分比
+const getProgressPercent = computed(() => {
+  return (currentIndex.value / (marks.length - 1)) * 100;
+});
+
+// 步进器逻辑
+const increment = () => {
+  if (currentIndex.value < marks.length - 1) currentIndex.value++;
+};
+const decrement = () => {
+  if (currentIndex.value > 0) currentIndex.value--;
+};
+
+// 关闭弹窗
+const handleClose = () => {
+  emit('update:visible', false);
+};
+
+// 确认选择
+const confirmSelection = () => {
+  emit('confirm', currentValue.value);
+  handleClose();
+};
+</script>
+
+<style scoped>
+/* 动画效果 */
+.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%); }
+
+/* 遮罩层 */
+.mask {
+  position: fixed;
+  top: 0; left: 0; right: 0; bottom: 0;
+  background: rgba(0, 0, 0, 0.5);
+  z-index: 998;
+}
+
+/* 弹窗容器 */
+.popup-container {
+  position: fixed;
+  bottom: 0; left: 0; right: 0;
+  background: #ffffff;
+  border-top-left-radius: 16px;
+  border-top-right-radius: 16px;
+  z-index: 999;
+  padding-bottom: env(safe-area-inset-bottom);
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
+}
+
+/* 拖拽条 */
+.drag-handle-area {
+  padding: 10px 0;
+  display: flex;
+  justify-content: center;
+}
+.drag-handle {
+  width: 40px;
+  height: 4px;
+  background: #E0E0E0;
+  border-radius: 2px;
+}
+
+.popup-content {
+  padding: 0 20px 20px 20px;
+}
+
+.title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #333;
+  margin: 0 0 20px 0;
+}
+
+/* 步进器样式 */
+.stepper-box {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  background: #F7F8FA;
+  border-radius: 8px;
+  padding: 5px;
+  margin-bottom: 30px;
+  height: 48px;
+}
+
+.step-btn {
+  border: none;
+  background: transparent;
+  width: 48px;
+  height: 100%;
+  font-size: 24px;
+  color: #999;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+.step-btn:disabled { opacity: 0.3; }
+.step-btn:active { opacity: 0.6; }
+
+.value-display {
+  font-size: 18px;
+  font-weight: 500;
+  color: #333;
+}
+
+/* 滑块样式核心 */
+.slider-container {
+  position: relative;
+  height: 30px; /* 增加触控区域 */
+  display: flex;
+  align-items: center;
+  margin-bottom: 10px;
+}
+
+.slider-track-bg {
+  position: absolute;
+  left: 0; right: 0;
+  height: 6px;
+  background: #F2F3F5;
+  border-radius: 3px;
+}
+
+.slider-track-active {
+  position: absolute;
+  left: 0;
+  height: 6px;
+  background: #E54755; /* 主红色 */
+  border-radius: 3px;
+  pointer-events: none;
+}
+
+.slider-thumb {
+  position: absolute;
+  width: 24px;
+  height: 24px;
+  background: #fff;
+  border: 2px solid #E54755;
+  border-radius: 50%;
+  transform: translateX(-50%); /* 居中对齐 */
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+  pointer-events: none; /* 让点击事件穿透到 input */
+  z-index: 2;
+}
+
+.inner-circle {
+  width: 0px; /* 图片中看起来是实心的或者空心的,这里做个空心白底红圈 */
+  height: 0px;
+}
+
+/* 原生 Input 覆盖在上面负责交互,但完全透明 */
+.native-input {
+  position: absolute;
+  width: 100%;
+  height: 100%;
+  opacity: 0;
+  cursor: pointer;
+  z-index: 3;
+  margin: 0;
+}
+
+/* 刻度标签 */
+.slider-labels {
+  display: flex;
+  justify-content: space-between;
+  color: #9FA2A8;
+  font-size: 12px;
+  margin-bottom: 30px;
+  padding: 0 2px; /* 微微修正对齐 */
+}
+
+/* 确认按钮 */
+.confirm-btn {
+  width: 100%;
+  height: 48px;
+  background: #E54755;
+  color: white;
+  border: none;
+  border-radius: 24px;
+  font-size: 16px;
+  font-weight: 600;
+  cursor: pointer;
+}
+.confirm-btn:active {
+  background: #D13E4A;
+}
+</style>

+ 283 - 0
src/views/bitcoin/components/OrderConfirmPopup.vue

@@ -0,0 +1,283 @@
+<template>
+  <Teleport to="body">
+    <transition name="fade">
+      <div v-if="visible" class="mask" @click="handleClose"></div>
+    </transition>
+
+    <transition name="slide-up">
+      <div v-if="visible" class="popup-container">
+        <div class="drag-handle-area"><div class="drag-handle"></div></div>
+
+        <div class="popup-content">
+          <h3 class="main-title">下单确认</h3>
+
+          <div class="token-header">
+            <div class="token-icon">
+              <span class="btc-symbol">₿</span>
+            </div>
+            <div class="token-info">
+              <div class="token-name">
+                BTC/USDT 永续
+              </div>
+              <div class="tags">
+                <span class="tag buy">买入</span>
+                <span class="tag leverage">逐仓 20X</span>
+              </div>
+            </div>
+          </div>
+
+          <div class="info-list">
+            <div class="info-row">
+              <span class="label">委托价格</span>
+              <span class="value">1000.05 USDT</span>
+            </div>
+            <div class="info-row">
+              <span class="label">数量</span>
+              <span class="value">10</span>
+            </div>
+            <div class="info-row">
+              <span class="label">金额</span>
+              <span class="value">0.30 USDT</span>
+            </div>
+            <div class="info-row">
+              <span class="label">类型</span>
+              <span class="value">限价</span>
+            </div>
+            <div class="info-row">
+              <span class="label">只减仓</span>
+              <span class="value">否</span>
+            </div>
+          </div>
+
+          <div class="tpsl-header" @click="toggleTpSl">
+            <span class="tpsl-title">止盈止损</span>
+            <span class="arrow" :class="{ expanded: isTpSlExpanded }">
+              <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
+                <path d="M6 9L12 15L18 9" stroke-linecap="round" stroke-linejoin="round"/>
+              </svg>
+            </span>
+          </div>
+
+          <div
+            class="tpsl-content-wrapper"
+            :class="{ show: isTpSlExpanded }"
+            ref="contentRef"
+            :style="contentStyle"
+          >
+            <div class="tpsl-inner">
+
+              <div class="strategy-block">
+                <div class="block-header">
+                  <span class="sub-title">止盈</span>
+                  <div class="right-action">
+                    <div>标记</div>
+                    <svg width="14" height="14" viewBox="0 0 28 28" fill="none" stroke="currentColor" stroke-width="3">
+                    <path d="M6 9L12 15L18 9" stroke-linecap="round" stroke-linejoin="round"/></svg>
+                  </div>
+                </div>
+                <div class="input-grid">
+                  <div class="input-box">
+                    <input type="number" placeholder="触发价(USDT)" />
+                  </div>
+                  <div class="input-box has-suffix">
+                    <input type="number" placeholder="盈亏" />
+                    <div class="suffix-select">USDT
+                       <svg width="14" height="14" viewBox="0 0 28 28" fill="none" stroke="currentColor" stroke-width="3">
+                    <path d="M6 9L12 15L18 9" stroke-linecap="round" stroke-linejoin="round"/></svg>
+                    </div>
+                  </div>
+                  <div class="input-box">
+                    <input type="number" placeholder="限价单(USDT)" />
+                  </div>
+                  <div class="toggle-btn">
+                    市价单
+                  </div>
+                </div>
+              </div>
+
+              <div class="strategy-block mt-15">
+                <div class="block-header">
+                  <span class="sub-title">止损</span>
+                  <div class="right-action">最新
+                     <svg width="14" height="14" viewBox="0 0 28 28" fill="none" stroke="currentColor" stroke-width="3">
+                    <path d="M6 9L12 15L18 9" stroke-linecap="round" stroke-linejoin="round"/></svg>
+                  </div>
+                </div>
+
+                <div class="input-grid">
+                  <div class="input-box">
+                    <input type="number" placeholder="触发价(USDT)" />
+                  </div>
+                  <div class="input-box has-suffix">
+                    <input type="number" placeholder="盈亏" />
+                    <div class="suffix-select">USDT
+                       <svg width="14" height="14" viewBox="0 0 28 28" fill="none" stroke="currentColor" stroke-width="3">
+                    <path d="M6 9L12 15L18 9" stroke-linecap="round" stroke-linejoin="round"/></svg>
+                    </div>
+                  </div>
+                  <div class="toggle-btn outline">
+                    市价
+                  </div>
+                  <div class="toggle-btn active-red">
+                    市价单
+                  </div>
+                </div>
+              </div>
+            </div>
+          </div>
+          <button class="confirm-btn" @click="handleConfirm">
+            确认
+          </button>
+        </div>
+      </div>
+    </transition>
+  </Teleport>
+</template>
+
+<script setup>
+import { ref, computed } from 'vue';
+
+const props = defineProps({
+  visible: Boolean
+});
+
+const emit = defineEmits(['update:visible', 'confirm']);
+
+// 折叠状态控制
+const isTpSlExpanded = ref(false);
+
+const toggleTpSl = () => {
+  isTpSlExpanded.value = !isTpSlExpanded.value;
+};
+
+// 计算高度用于 CSS transition (为了丝滑动画)
+// 实际项目中简单使用 v-if 也可以,但 height transition 体验更好
+const contentStyle = computed(() => {
+  return isTpSlExpanded.value
+    ? { maxHeight: '500px', opacity: 1, marginTop: '10px' }
+    : { maxHeight: '0px', opacity: 0, marginTop: '0px' };
+});
+
+const handleClose = () => {
+  emit('update:visible', false);
+};
+
+const handleConfirm = () => {
+  // 收集数据逻辑...
+  emit('confirm');
+  handleClose();
+};
+</script>
+
+<style lang="less" scoped>
+    /* 基础动画 */
+    .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%); }
+
+    /* 布局样式 */
+    .mask {
+      position: fixed; top: 0; left: 0; right: 0; bottom: 0;
+      background: rgba(0,0,0,0.6); z-index: 998;
+    }
+    .popup-container {
+      position: fixed; bottom: 0; left: 0; right: 0;
+      background: #fff; border-radius: 16px 16px 0 0;
+      z-index: 999; padding-bottom: calc(20px + env(safe-area-inset-bottom));
+      font-family: -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
+      max-height: 90vh; overflow-y: auto; /* 允许小屏滚动 */
+    }
+
+    /* 拖拽条 */
+    .drag-handle-area { padding: 10px 0; display: flex; justify-content: center; }
+    .drag-handle { width: 40px; height: 4px; background: #E0E0E0; border-radius: 2px; }
+
+    .popup-content { padding: 0 20px; }
+    .main-title { font-size: 18px; font-weight: 600; margin: 0 0 10px 0; color: #333; }
+
+    /* 币种信息 */
+    .token-header { display: flex; align-items: center; margin-bottom: 10px; }
+    .token-icon {
+      width: 32px; height: 32px; background: #F7931A; border-radius: 50%;
+      display: flex; align-items: center; justify-content: center; margin-right: 10px;
+    }
+    .btc-symbol { color: white; font-weight: bold; font-size: 20px; }
+    .token-name { font-size: 16px; font-weight: 600; color: #333; margin-bottom: 4px; }
+    .tags { display: flex; gap: 5px; }
+    .tag { font-size: 10px; padding: 1px 4px; border-radius: 2px; }
+    .tag.buy { background: #2EBD85; color: white; }
+    .tag.leverage { background: #EFF0F2; color: #999; }
+
+    /* 信息列表 */
+    .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; }
+
+    /* 止盈止损标题栏 */
+    .tpsl-header {
+      display: flex; justify-content: space-between; align-items: center;
+      padding: 10px 0; border-top: 1px solid #F5F5F5; cursor: pointer;
+    }
+    .tpsl-title { font-weight: 600; font-size: 15px; color: #333; text-underline-offset: 4px;
+      text-decoration-color: #333; }
+    .arrow { transition: transform 0.3s; color: #333; display: flex; }
+    .arrow.expanded { transform: rotate(180deg); }
+
+    /* 止盈止损 内容折叠区 */
+    .tpsl-content-wrapper {
+      overflow: hidden;
+      transition: max-height 0.3s ease-in-out, opacity 0.3s, margin-top 0.3s;
+    }
+    .strategy-block { margin-bottom: 10px; }
+    .mt-15 { margin-top: 15px; }
+    .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{
+        //display: block;
+        margin-top: 3px;
+        //text-align: center;
+      }
+    }
+    .tiny-arrow { font-size: 8px; color: #999; }
+
+    /* 输入框网格 (2列) */
+    .input-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
+
+    .input-box {
+      background: #F7F8FA; border-radius: 4px; height: 38px;
+      display: flex; align-items: center; padding: 0 10px;
+      position: relative;
+    }
+    .input-box input {
+      width: 100%; background: transparent; border: none; outline: none;
+      font-size: 13px; color: #333;
+    }
+    .input-box input::placeholder { color: #B0B3B8; }
+
+    .input-box.has-suffix input { padding-right: 50px; }
+    .suffix-select {
+      position: absolute; right: 10px; top: 0; bottom: 0;
+      display: flex; align-items: center; font-size: 12px; color: #333; font-weight: 500;
+      svg{
+        margin-top: 3px;
+      }
+    }
+
+    /* 按钮样式 */
+    .toggle-btn {
+      height: 40px; border-radius: 4px; display: flex; align-items: center; justify-content: center;
+      font-size: 13px; cursor: pointer; border: 1px solid #E0E0E0; background: #fff; color: #666;
+    }
+    .toggle-btn.outline { border-color: #666; color: #333; }
+    .toggle-btn.active-red { background: #E54755; border-color: #E54755; color: white; }
+
+    /* 确认按钮 */
+    .confirm-btn {
+      width: 100%; height: 48px; background: #E54755;
+      color: white; font-size: 16px; border: none; border-radius: 24px;
+      margin-top: 10px; font-weight: bold;
+    }
+    .confirm-btn:active { background: #D13E4A; }
+</style>

+ 360 - 0
src/views/bitcoin/components/TPSLSmartPopup.vue

@@ -0,0 +1,360 @@
+<template>
+  <Teleport to="body">
+    <transition name="fade">
+      <div v-if="visible" class="mask" @click="close"></div>
+    </transition>
+
+    <transition name="slide-up">
+      <div v-if="visible" class="popup-container" :class="directionClass">
+        <div class="drag-handle-area"><div class="drag-handle"></div></div>
+
+        <div class="popup-content">
+          <div class="header-title">设置止盈止损</div>
+
+          <div class="coin-info">
+            <div class="coin-icon">₿</div>
+            <span class="coin-name">BTC/USDT</span>
+          </div>
+
+          <div class="price-grid">
+            <div class="price-item"><div class="label">最新价格</div><div class="value">1000.05 USDT</div></div>
+            <div class="price-item center"><div class="label">委托价格</div><div class="value">10</div></div>
+            <div class="price-item right"><div class="label">委托数量</div><div class="value">10 BTC</div></div>
+          </div>
+
+          <div class="direction-switch">
+            <div class="switch-btn buy" :class="{ active: direction === 'buy' }" @click="direction = 'buy'">买入(做多)</div>
+            <div class="switch-btn sell" :class="{ active: direction === 'sell' }" @click="direction = 'sell'">卖出(做空)</div>
+          </div>
+
+          <div class="section-block">
+            <div class="section-header">
+              <span class="section-label">止盈</span>
+              <label class="checkbox-label">
+                <input type="checkbox" v-model="tpLimitMode" />
+                <span class="custom-check"></span>
+                限价委托
+              </label>
+            </div>
+
+            <div class="input-row">
+              <div class="input-group">
+<!--                <div class="prefix-label">触发价</div>-->
+                <input
+                  type="number"
+                  class="flex-input"
+                  placeholder="触发价"
+                  v-model="tpTriggerPrice"
+                />
+                <span class="unit-text" @click="showModal1 = true">{{selectedLabel1}}</span>
+                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
+                <path d="M6 9L12 15L18 9" stroke-linecap="round" stroke-linejoin="round"/>
+              </svg>
+              </div>
+
+              <div class="input-group">
+                <div class="suffix-select" @click="showModal = true">
+                  <span class="label-text">{{selectedLabel}}</span>
+                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
+                  <path d="M6 9L12 15L18 9" stroke-linecap="round" stroke-linejoin="round"/>
+                  </svg>
+                </div>
+                <div class="prefix-label">{{selectedUnit}}</div>
+              </div>
+            </div>
+
+            <div class="slider-wrapper">
+              <div class="slider-inner">
+                <div class="slider-track-bg"></div>
+                <div class="slider-start-point"></div>
+                <div class="slider-track-fill" :style="{ width: (tpPercent / 25 * 100) + '%' }"></div>
+                <div class="slider-thumb" :style="{ left: (tpPercent / 25 * 100) + '%' }"></div>
+                <input type="range" min="0" max="25" step="1" v-model.number="tpPercent" class="native-range" />
+                <div class="slider-ticks">
+                  <span v-for="tick in tpTicks" :key="tick" class="tick-label" :class="{ active: tpPercent >= tick }" :style="{ left: (tick / 25 * 100) + '%' }" @click="tpPercent = tick">{{ tick }}%</span>
+                </div>
+              </div>
+            </div>
+
+            <transition name="expand">
+              <div v-if="tpLimitMode" class="limit-input-box">
+                <div class="input-inner">
+                  <input type="number" placeholder="委托价" />
+                  <span class="unit">USDT</span></div>
+              </div>
+            </transition>
+          </div>
+
+          <div class="section-block">
+            <div class="section-header">
+              <span class="section-label">止损</span>
+              <label class="checkbox-label">
+                <input type="checkbox" v-model="slLimitMode" />
+                <span class="custom-check"></span>
+                限价委托
+              </label>
+            </div>
+
+            <div class="input-row">
+              <div class="input-group">
+<!--                <div class="prefix-label">触发价</div>-->
+                <input
+                  type="number"
+                  class="flex-input"
+                  placeholder="触发价"
+                  v-model="slTriggerPrice"
+                />
+                <span class="unit-text">标记</span>
+                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
+                <path d="M6 9L12 15L18 9" stroke-linecap="round" stroke-linejoin="round"/>
+              </svg>
+              </div>
+
+              <div class="input-group">
+
+                <div class="suffix-select">
+                  <span class="label-text">收益率</span>
+                  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3">
+                <path d="M6 9L12 15L18 9" stroke-linecap="round" stroke-linejoin="round"/>
+              </svg>
+                </div>
+                <div class="prefix-label">%</div>
+              </div>
+            </div>
+
+            <div class="slider-wrapper">
+              <div class="slider-inner">
+                <div class="slider-track-bg"></div>
+                <div class="slider-start-point"></div>
+                <div class="slider-track-fill" :style="{ width: (slPercent / 10 * 100) + '%' }"></div>
+                <div class="slider-thumb" :style="{ left: (slPercent / 10 * 100) + '%' }"></div>
+                <input type="range" min="0" max="10" step="1" v-model.number="slPercent" class="native-range" />
+                <div class="slider-ticks">
+                  <span v-for="tick in slTicks" :key="tick" class="tick-label" :class="{ active: slPercent >= tick }" :style="{ left: (tick / 10 * 100) + '%' }" @click="slPercent = tick">{{ tick }}%</span>
+                </div>
+              </div>
+            </div>
+
+            <transition name="expand">
+              <div v-if="slLimitMode" class="limit-input-box">
+                <div class="input-inner">
+                  <input id="1" type="number" placeholder="委托价" />
+                  <span class="unit">USDT</span>
+                </div>
+              </div>
+            </transition>
+          </div>
+
+          <button class="confirm-btn" @click="confirm">确认</button>
+        </div>
+      </div>
+    </transition>
+  </Teleport>
+  <div>
+    <priceLimit
+      v-model:visible="showModal"
+      :selected-id="currentId"
+      @confirm="handleConfirm"
+    >
+    </priceLimit>
+
+    <TriggerPrice
+       v-model:visible="showModal1"
+      :selected-id="currentId1"
+      @confirm="handleConfirm1"
+    ></TriggerPrice>
+  </div>
+</template>
+
+<script setup>
+import {ref, computed, defineAsyncComponent} from 'vue';
+const priceLimit = defineAsyncComponent(() => import("../components/priceLimit.vue"));
+const TriggerPrice = defineAsyncComponent(() => import("../components/TriggerPrice.vue"));
+    //最新价格
+    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 showModal = ref(false);
+
+// 定义状态用于存储
+const currentId = ref(1); // 默认选中第一个
+const selectedLabel = ref('涨跌幅'); // 默认值
+const selectedUnit = ref('%');      // 默认值
+
+// 回调函数:子组件选中后触发
+const handleConfirm = (item) => {
+  console.log('子组件返回的对象:', item);
+
+  // 保存ID用于下次打开时回显高亮
+  currentId.value = item.id;
+
+  // 核心需求:在这里将值“拆开”为两个字符串
+  selectedLabel.value = item.label; // 字符串1: "涨跌幅"
+  selectedUnit.value = item.unit;   // 字符串2: "%"
+};
+
+
+const props = defineProps({ visible: Boolean });
+const emit = defineEmits(['update:visible', 'confirm']);
+
+const direction = ref('buy');
+
+// 止盈数据
+const tpLimitMode = ref(false);
+const tpTriggerPrice = ref(''); // 新增:止盈触发价输入
+const tpPercent = ref(5);
+const tpTicks = [0, 5, 10, 15, 20, 25];
+
+// 止损数据
+const slLimitMode = ref(true);
+const slTriggerPrice = ref(''); // 新增:止损触发价输入
+const slPercent = ref(2);
+const slTicks = [0, 2, 4, 6, 8, 10];
+
+const directionClass = computed(() => direction.value === 'buy' ? 'theme-buy' : 'theme-sell');
+const close = () => emit('update:visible', false);
+const confirm = () => {
+  emit('confirm', {
+    direction: direction.value,
+    tp: { price: tpTriggerPrice.value, percent: tpPercent.value },
+    sl: { price: slTriggerPrice.value, percent: slPercent.value }
+  });
+  close();
+};
+</script>
+
+<style scoped>
+    .theme-buy { --primary-color: #2EBD85; }
+    .theme-sell { --primary-color: #F6465D; }
+
+    /* 基础布局 */
+    .mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.6); z-index: 998; }
+    .popup-container {
+      position: fixed; bottom: 0; left: 0; right: 0; background: #fff; border-radius: 16px 16px 0 0;
+      z-index: 999; padding-bottom: calc(20px + env(safe-area-inset-bottom));
+      font-family: -apple-system, BlinkMacSystemFont, Roboto, sans-serif; max-height: 90vh;
+      overflow-y: auto; color: #333;
+    }
+    .popup-content { padding: 0 20px; }
+
+    .drag-handle-area { padding: 10px 0; display: flex; justify-content: center; }
+    .drag-handle { width: 40px; height: 4px; background: #E0E0E0; border-radius: 2px; }
+    .header-title { font-size: 18px; font-weight: 600; margin-bottom: 15px; }
+
+    .coin-info { display: flex; align-items: center; gap: 8px; margin-bottom: 15px; }
+    .coin-icon { width: 20px; height: 20px; background: #F7931A; color: #fff; border-radius: 50%;
+      text-align: center; line-height: 20px; font-size: 12px; font-weight: bold; }
+    .price-grid { display: flex; justify-content: space-between; margin-bottom: 20px; }
+    .price-item .label { font-size: 12px; color: #999; }
+    .price-item .value { font-size: 14px; font-weight: 500; }
+
+    .direction-switch { display: flex; gap: 10px; margin-bottom: 20px; }
+    .switch-btn { flex: 1; height: 40px; display: flex; align-items: center; justify-content: center;
+      border-radius: 4px; font-size: 14px; font-weight: 600; cursor: pointer; background: #F7F8FA;
+      color: #999; transition: 0.2s; }
+    .theme-buy .switch-btn.buy.active { background: var(--primary-color); color: white; }
+    .theme-sell .switch-btn.sell.active { background: var(--primary-color); color: white; }
+
+    .section-block { margin-bottom: 25px; }
+    .section-header { display: flex; justify-content: space-between; align-items: center;
+      margin-bottom: 12px; }
+    .section-label { font-size: 15px; font-weight: 600; }
+    .checkbox-label { display: flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; }
+    .checkbox-label input { display: none; }
+    .custom-check { width: 16px; height: 16px; border: 1px solid #ccc; border-radius: 2px;
+      position: relative; }
+    .checkbox-label input:checked + .custom-check { background: var(--primary-color);
+      border-color: var(--primary-color); }
+    .checkbox-label input:checked + .custom-check::after { content: ''; position: absolute;
+      left: 5px; top: 1px; width: 4px; height: 8px; border: solid white; border-width: 0 2px 2px 0;
+      transform: rotate(45deg); }
+
+    /* ============ 输入框区域 ============ */
+    .input-row { display: flex; gap: 10px; margin-bottom: 15px; }
+    .input-group {
+      flex: 1; height: 40px; background: #F7F8FA; border-radius: 4px;
+      display: flex; align-items: center; justify-content: space-between; padding: 0 10px;
+      position: relative;
+      font-size: 12px;
+    }
+    .prefix-label { color: #999; font-size: 12px; white-space: nowrap; margin-right: 8px; }
+
+    /* 新增:flex 输入框样式 */
+    .flex-input {
+      flex: 1;
+      background: transparent;
+      border: none;
+      outline: none;
+      font-size: 12px;
+      font-weight: 500;
+      color: #333;
+      width: 100%; /* 确保填满剩余空间 */
+    }
+    .flex-input::placeholder { color: #B0B3B8; font-weight: 400; }
+    /* 隐藏 number input 的上下箭头 */
+    .flex-input::-webkit-outer-spin-button,
+    .flex-input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
+
+    .unit-text { font-size: 12px; color: #333; margin-left: 4px; font-weight: 500; }
+
+    .suffix-select { display: flex; align-items: center;  color: #333; }
+    .label-text { font-size: 12px; font-weight: 500; }
+    .icon-svg { width: 14px; height: 14px; color: #666; margin-left: 2px; }
+
+    /* ============ 滑块样式 ============ */
+    .slider-wrapper { padding: 0 15px; margin-top: 10px; box-sizing: border-box; }
+    .slider-inner { position: relative; height: 55px; width: 100%; }
+
+    .slider-track-bg { position: absolute; top: 12px; left: 0; right: 0; height: 6px;
+      background: #F0F0F0; border-radius: 3px; }
+    .slider-track-fill { position: absolute; top: 12px; left: 0; height: 6px;
+      background: var(--primary-color); border-radius: 3px; pointer-events: none; }
+    .slider-start-point, .slider-thumb { position: absolute; top: 15px; width: 24px;
+      height: 24px; background: #fff; border: 2px solid var(--primary-color); border-radius: 50%;
+      transform: translate(-50%, -50%); box-shadow: 0 2px 4px rgba(0,0,0,0.15); box-sizing: border-box; }
+    .slider-start-point { left: 0; z-index: 1; }
+    .slider-thumb { z-index: 2; pointer-events: none; }
+    .native-range { position: absolute; top: 0; left: 0; width: 100%; height: 40px;
+      opacity: 0; cursor: pointer; margin: 0; z-index: 3; -webkit-tap-highlight-color: transparent; }
+
+    .slider-ticks { position: absolute; top: 32px; left: 0; right: 0; height: 20px; }
+    .tick-label { position: absolute; transform: translateX(-50%); font-size: 12px;
+      color: #B0B3B8; cursor: pointer; white-space: nowrap; }
+    .tick-label.active { color: #333; font-weight: 500; }
+
+    .limit-input-box { overflow: hidden; margin-top: 8px; }
+    .input-inner { background: #F7F8FA; height: 44px; border-radius: 4px; display: flex;
+      align-items: center; padding: 0 12px; }
+    .input-inner .label { color: #999; font-size: 13px; margin-right: 10px; }
+    .input-inner input { flex: 1; border: none; background: transparent; outline: none; font-size: 14px; }
+    .input-inner .unit { color: #333; font-size: 13px; font-weight: 500; }
+
+    .expand-enter-active, .expand-leave-active { transition: all 0.3s ease-in-out; max-height: 60px;
+      opacity: 1; }
+    .expand-enter-from, .expand-leave-to { max-height: 0; opacity: 0; margin-top: 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%); }
+    .fade-enter-active, .fade-leave-active { transition: opacity 0.3s; }
+    .fade-enter-from, .fade-leave-to { opacity: 0; }
+
+    .confirm-btn { width: 100%; height: 48px; margin-top: 10px;
+      background: var(--primary-color); color: white; border: none; border-radius: 24px;
+      font-size: 16px; font-weight: 600; }
+</style>

+ 26 - 16
src/views/bitcoin/components/TakeProfitstopLoss.vue → src/views/bitcoin/components/TakeProfitsTopLoss.vue

@@ -1,17 +1,24 @@
 <script setup>
-import { Checkbox as VanCheckbox } from 'vant';
-import { Icon as VanIcon, } from 'vant';
-import { ref } from 'vue';
-
-// 1. 状态控制
-const isEnabled = ref(false); // 控制复选框选中状态,
-const takeProfit = ref('');  // 止盈价格
-const stopLoss = ref('');    // 止损价格
-
-// 点击“高级”的事件
-const handleAdvanced = () => {
-  console.log('点击了高级设置');
-};
+    import { Checkbox as VanCheckbox } from 'vant';
+    import { Icon as VanIcon, } from 'vant';
+    import {defineAsyncComponent, ref} from 'vue';
+    const TPSLSmartPopup = defineAsyncComponent(() => import('../components/TPSLSmartPopup.vue'));
+
+    // 1. 状态控制
+    const isEnabled = ref(false); // 控制复选框选中状态,
+    const takeProfit = ref('');  // 止盈价格
+    const stopLoss = ref('');    // 止损价格
+
+    // 点击“高级”的事件
+    const handleAdvanced = () => {
+      console.log('点击了高级设置');
+    };
+
+    //止盈止损高级设置
+    const showSmartTPSL = ref(false);
+    const handleConfirm1 = (data) => {
+      console.log('止盈止损设置:', data);
+    };
 </script>
 
 <template>
@@ -32,7 +39,7 @@ const handleAdvanced = () => {
       </div>
 
       <div v-if="isEnabled" class="right-action" @click="handleAdvanced">
-        <span class="fc333333">高级</span>
+        <span class="fc333333" @click="showSmartTPSL = true">高级</span>
         <van-icon style="font-weight: bold; margin-left: 5px;" name="arrow" size="12"/>
       </div>
     </div>
@@ -62,7 +69,10 @@ const handleAdvanced = () => {
 
       </div>
     </transition>
-
+    <TPSLSmartPopup
+        v-model:visible="showSmartTPSL"
+        @confirm="handleConfirm1"
+    ></TPSLSmartPopup>
   </div>
 </template>
 
@@ -92,7 +102,7 @@ const handleAdvanced = () => {
 }
 
 .label-text {
-  font-size: 14px;
+  font-size: 12px;
   color: #333;
   font-weight: 400;
 }

+ 162 - 0
src/views/bitcoin/components/TriggerPrice.vue

@@ -0,0 +1,162 @@
+<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="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>
+.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;
+}
+
+.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>

+ 169 - 0
src/views/bitcoin/components/priceLimit.vue

@@ -0,0 +1,169 @@
+<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="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 }}({{ 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>
+              </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: '涨跌幅',
+    unit: '%',
+    desc: '输入价格涨跌幅,系统会自动展示根据主单价格计算得出的止盈止损价格'
+  },
+  {
+    id: 2,
+    label: '收益率',
+    unit: '%',
+    desc: '输入收益率,系统会自动展示根据主单价格计算得出的止盈止损价格'
+  },
+  {
+    id: 3,
+    label: '收益额',
+    unit: 'USDT',
+    desc: '输入收益额,系统会自动展示根据主单价格计算得出的止盈止损价格'
+  }
+];
+
+const close = () => {
+  emit('update:visible', false);
+};
+
+const handleSelect = (item) => {
+  // 1. 触发 confirm 事件,把整个对象带回去
+  emit('confirm', item);
+  // 2. 关闭弹窗
+  close();
+};
+</script>
+
+<style>
+.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;
+}
+
+.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>