|
|
@@ -3,7 +3,7 @@
|
|
|
<div class="nav-bar">
|
|
|
<div class="nav-left" @click="$router.back()">
|
|
|
<div>
|
|
|
- <VanIcon size="18" name="arrow-left"/>
|
|
|
+ <VanIcon size="18" name="arrow-left" />
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="nav-title">计算器</div>
|
|
|
@@ -24,8 +24,7 @@
|
|
|
:key="index"
|
|
|
class="tab-item"
|
|
|
:class="{ active: currentTab === index }"
|
|
|
- @click="currentTab = index"
|
|
|
- >
|
|
|
+ @click="currentTab = index">
|
|
|
{{ tab }}
|
|
|
<div class="active-bar" v-if="currentTab === index"></div>
|
|
|
</div>
|
|
|
@@ -41,22 +40,21 @@
|
|
|
<button
|
|
|
class="dir-btn long"
|
|
|
:class="{ active: direction === 'long' }"
|
|
|
- @click="direction = 'long'"
|
|
|
- >
|
|
|
- 买入(做多)
|
|
|
+ @click="direction = 'long'">
|
|
|
+ 买入
|
|
|
</button>
|
|
|
<button
|
|
|
class="dir-btn short"
|
|
|
:class="{ active: direction === 'short' }"
|
|
|
- @click="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="hyu">当前资金费率
|
|
|
+ <div class="rate-label" @click="hyu">
|
|
|
+ 当前资金费率
|
|
|
<VanIcon name="question-o" />
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -71,16 +69,10 @@
|
|
|
</div>
|
|
|
|
|
|
<div class="slider-area">
|
|
|
- <LeverageSlider
|
|
|
- v-model="leverage"
|
|
|
- :marks="leverageMarks"
|
|
|
- :color="themeColor"
|
|
|
- />
|
|
|
+ <LeverageSlider v-model="leverage" :marks="leverageMarks" :color="themeColor" />
|
|
|
</div>
|
|
|
|
|
|
- <div class="leverage-tip">
|
|
|
- 当前杠杆倍数最高可持有头寸 1,800,000,000 USDT
|
|
|
- </div>
|
|
|
+ <div class="leverage-tip">当前杠杆倍数最高可持有头寸 1,800,000,000 USDT</div>
|
|
|
</div>
|
|
|
|
|
|
<div class="form-group">
|
|
|
@@ -165,8 +157,11 @@
|
|
|
<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">
|
|
|
+ <div style="display: flex; align-items: center">
|
|
|
+ <div
|
|
|
+ class="remove-btn"
|
|
|
+ @click="removeRow(idx)"
|
|
|
+ v-if="avgPriceList.length > 1">
|
|
|
<span>-</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
@@ -197,9 +192,15 @@
|
|
|
<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 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">
|
|
|
@@ -227,280 +228,511 @@
|
|
|
|
|
|
<div class="footer-btns">
|
|
|
<button class="btn-reset" @click="reset">重置</button>
|
|
|
- <button class="btn-calc" :style="{ background: themeColor }" @click="calculate">计算</button>
|
|
|
+ <button class="btn-calc" :style="{ background: themeColor }" @click="calculate">
|
|
|
+ 计算
|
|
|
+ </button>
|
|
|
</div>
|
|
|
<div>
|
|
|
- <ProfitAndLossPrompt
|
|
|
- v-model:visible="showModal"
|
|
|
- ></ProfitAndLossPrompt>
|
|
|
+ <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 hyu = () => {
|
|
|
- console.log("kkkkkkk")
|
|
|
- showModal.value = true;
|
|
|
-}
|
|
|
-
|
|
|
-// 状态定义
|
|
|
-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)
|
|
|
- };
|
|
|
+ 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 hyu = () => {
|
|
|
+ console.log("kkkkkkk");
|
|
|
+ showModal.value = true;
|
|
|
+ };
|
|
|
+
|
|
|
+ // 状态定义
|
|
|
+ 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;
|
|
|
}
|
|
|
- }
|
|
|
-};
|
|
|
|
|
|
-// 其他辅助函数
|
|
|
-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;
|
|
|
-};
|
|
|
+ // 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 很重要,为了防止底部内容被固定的 footer 遮挡,保留它 */
|
|
|
- padding-bottom: 90px;
|
|
|
- color: #333;
|
|
|
- z-index: 200;
|
|
|
-
|
|
|
- /* 删掉了 position: fixed/top/left */
|
|
|
-
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- width: 100%;
|
|
|
-}
|
|
|
-/* 导航 & 头部 */
|
|
|
-.nav-bar { display: flex; justify-content: space-between; align-items: center;
|
|
|
- height: 44px; padding: 0 16px;
|
|
|
- /* 新增以下 3 行,实现吸顶效果 */
|
|
|
- position: sticky;
|
|
|
- top: 0;
|
|
|
- background: #fff; /* 防止透明背景导致内容重叠 */
|
|
|
- z-index: 100;
|
|
|
-}
|
|
|
-.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: 0px 15px;
|
|
|
- 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>
|
|
|
+ * {
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
+
|
|
|
+ .calculator-page {
|
|
|
+ font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", sans-serif;
|
|
|
+ background: #fff;
|
|
|
+ min-height: 100vh;
|
|
|
+ /* 这里的 padding-bottom: 90px 很重要,为了防止底部内容被固定的 footer 遮挡,保留它 */
|
|
|
+ padding-bottom: 90px;
|
|
|
+ color: #333;
|
|
|
+ z-index: 200;
|
|
|
+
|
|
|
+ /* 删掉了 position: fixed/top/left */
|
|
|
+
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ width: 100%;
|
|
|
+ }
|
|
|
+ /* 导航 & 头部 */
|
|
|
+ .nav-bar {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ height: 44px;
|
|
|
+ padding: 0 16px;
|
|
|
+ /* 新增以下 3 行,实现吸顶效果 */
|
|
|
+ position: sticky;
|
|
|
+ top: 0;
|
|
|
+ background: #fff; /* 防止透明背景导致内容重叠 */
|
|
|
+ z-index: 100;
|
|
|
+ }
|
|
|
+ .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: 0px 15px;
|
|
|
+ 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>
|