李凌
2025-10-15 7fc6bfe900790ec7c92bce85d5b20a95fbc06e65
src/components/Transform/perpetual-open/index.vue
@@ -36,7 +36,124 @@
      </div>
      <div class="pt-30 pb-20">
        <div class="flex justify-between">
          <div class="w-440 flex flex-col">
          <div>
            <div class="w-290 flex justify-between text-grey font-22">
              <div>
                <div>{{ $t("价格") }}</div>
                <div class="mt-4">{{ queryType === 'cryptos' ? '(USDT)' : '(USD)' }}</div>
              </div>
              <div class="text-right items-end justify-end">
                <div class="">{{ $t("数量") }}</div>
                <div class="mt-4">{{
                    queryType === 'cryptos' ?
                        `(${symbol_data.toUpperCase() || "--"})` : '(USD)'
                  }}
                </div>
              </div>
            </div>
            <div class="deep-div">
              <!-- <div v-if="showType == 0 || showType == 2" class="w-290 flex justify-between pt-1  font-26"
                v-for="(item, index) in redData" :key="item + index" @click="onQuickPrice(item.price)" :style="{
                  background:
                    `linear-gradient(to right,${THEME == 'dark' ? '#131A2E' : '#fff'
                    } 0%` +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(246,70,93,.1) ' +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(246,70,93,.1) 100%)',
                }"> -->
              <div v-show="(showType == 0 || showType == 2)" class="w-290 flex justify-between pt-1 font-26"
                   v-for="(item, index) in redData" :key="item + index" @click="onQuickPrice(item.price)" :style="{
                  background:
                    `linear-gradient(to right,${$store.state.vant.theme == 'dark' ? '#131A2E' : '#fff'
                    } 0%` +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(246,70,93,.1) ' +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(246,70,93,.1) 100%)'
                }">
                <div class="text-red">{{ item.price }}</div>
                <div class="text-right textColor" v-if="symbol == 'shib'">
                  {{ fixDate(item.amount, $i18n) || "--" }}
                </div>
                <div class="text-right textColor" v-else>
                  {{ item.amount || "--" }}
                </div>
              </div>
            </div>
            <div class="w-290 text-red pt-5 font-34 font-700 text-center">
              {{ price || '--' }}
            </div>
            <div class="pb-5 font-20 text-center">
              ≈ {{
                ((price *
                    currency.rate).toFixed(price.toString().split('.')[1] ?
                    price.toString().split('.')[1].length : 2)) || '--'
              }}
            </div>
            <div class="deep-div">
              <!-- <div v-if="showType == 0 || showType == 1" class="w-290 flex justify-between pt-1 font-26"
                v-for="(item, index) in greenData" :key="index" @click="onQuickPrice(item.price)" :style="{
                  background:
                    `linear-gradient(to right,${THEME == 'dark' ? '#131A2E' : '#fff'
                    } 0%` +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(94,186,137,.1) ' +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(94,186,137,.1) 100%)',
                }"> -->
              <div v-if="showType == 0 || showType == 1" class="w-290 flex justify-between pt-1 font-26"
                   v-for="(item, index) in greenData" :key="index" @click="onQuickPrice(item.price)" :style="{
                  background:
                    `linear-gradient(to right,${$store.state.vant.theme == 'dark' ? '#131A2E' : '#fff'
                    } 0%` +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(94,186,137,.1) ' +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(94,186,137,.1) 100%)',
                }">
                <div class="text-green">{{ item.price }}</div>
                <div class="text-right textColor" v-if="symbol_data == 'shib'">
                  {{ fixDate(item.amount, $i18n) || "--" }}
                </div>
                <div class="text-right textColor" v-else>
                  {{ item.amount || "--" }}
                </div>
              </div>
            </div>
            <div class="flex k-select-box">
              <div class=" mb-22 select-box pl-5 pr-5" style="position: relative">
                <div class="flex justify-between items-center w-full h-70" @click="selectArryBtn">
                  <!-- <img src="@/assets/image/public/warn.png" alt="warn-icon" class="w-25 h-25 pl-20"/> -->
                  <div class="pl-16 font-28 textColor" style="width: 80%">
                    {{ dataArrTitle }}
                  </div>
                  <img src="../../../assets/image/public/grey-select.png" alt="select-icon" class="w-22 h-11 mr-10"/>
                </div>
                <div class="option-box" v-show="arryIsShow">
                  <div class="font-28" v-for="(item, index) in selectDataArry" :key="index"
                       @click="selectItemArry(item)">
                    {{ item.name }}
                  </div>
                </div>
              </div>
              <div @click="isSelectShow = true">
                <img src="../../../assets/image/selectIcon.png" alt="warn-icon" class="w-36 h-30 ml-10"/>
              </div>
            </div>
          </div>
          <div style="margin-left: 20px" class="w-440 flex flex-col">
            <template v-if="selectIndex == 1">
              <div class="flex items-center h-66 greyBg textColor">
                <p class="font-28 flex-1 flex items-center justify-center h-66 "
@@ -57,7 +174,8 @@
                <div class="option-box" v-show="isShow">
                  <div class="font-30" v-for="item in selectData" :key="item.type" @click="selectItem(item)">{{
                    item.title
                  }}</div>
                    }}
                  </div>
                </div>
              </div>
            </template>
@@ -122,9 +240,34 @@
              <!-- 张数输入 -->
              <!-- <amount-slider ref="sliderRef" :maxAmount="maxUSDT" @getAmount="getAmount"
                :propsAmount="form.amount"></amount-slider> -->
              <div class="btns_box">
                <div :class="bfbindex == index ? 'btns_box_boxs' : 'btns_box_box'" @click="bfbclick(item, index)"
                  v-for="(item, index) in bfblist" :key="index">{{ item.name }}%</div>
              <!--              <div class="btns_box">-->
              <!--                <div :class="bfbindex == index ? 'btns_box_boxs' : 'btns_box_box'" @click="bfbclick(item, index)"-->
              <!--                  v-for="(item, index) in bfblist" :key="index">{{ item.name }}%</div>-->
              <!--              </div>-->
              <div style="margin: 0 10px">
                <div @click="handleClick"
                     @touchstart="handleTouchStart"
                     @touchmove="handleTouchMove"
                     @touchend="handleTouchEnd"   style="width: 100%;height:20px;position: relative" class="flex-centerY progress-bar">
                  <div
                      style="position: absolute;left: 0;width: 100%;height:2px;margin-top: 1px;border-radius: 90px;background: #f1f1f1">
                    <div class="progress-in flex flex-position-end-to-start" :style="{width:progressRate+'%'}" >
                      <div class="progress-icon"></div>
                    </div>
                  </div>
                  <div v-for="(item, index) in bfblist" class="progress-i flex"
                       :style="{flex:index==bfblist.length-1?0:1}"
                       :class="{'flex-position-end-to-start':index==bfblist.length-1}">
                    <div class="progress-icon1" @click.stop="bfbclick(parseInt(item.name))" ></div>
                  </div>
                </div>
                <div style="width: 100%;position: relative;margin-top: 10px" class="flex-centerY">
                  <div v-for="(item, index) in bfblist" @click="bfbclick(parseInt(item.name))" class="progress-i flex"
                       :style="{flex:index==bfblist.length-1?0:1}"
                       :class="{'flex-position-end-to-start':index==bfblist.length-1}">
                    {{ item.name }}%
                  </div>
                </div>
              </div>
            </template>
            <template v-if="selectIndex == 1 && userInfo.token">
@@ -145,8 +288,10 @@
              </div> -->
              <div class="flex justify-between mt-30">
                <div class="text-grey">{{ $t("建仓手续费") }}</div>
                <div class="textColor">{{ reserve(userInfo.perpetual_contracts_status === '1' ?
                  initData.fee * (form.amount / 1) : initData.fee * (form.amount / 1) * form.lever_rate, 6) }}
                <div class="textColor">{{
                    reserve(userInfo.perpetual_contracts_status === '1' ?
                        initData.fee * (form.amount / 1) : initData.fee * (form.amount / 1) * form.lever_rate, 6)
                  }}
                  {{ queryType === 'cryptos' ? 'USDT' : 'USD' }}
                </div>
              </div>
@@ -174,27 +319,27 @@
            <template v-if="userInfo.token">
              <template v-if="selectIndex == 1">
                <div class="w-full h-80 lh-80 bg-green flex text-white mt-70" v-if="currentType == 'long'"
                <div class=" flex-center text-white " style="margin-top: 10px" v-if="currentType == 'long'"
                  @click="order('long')">
                  <div class="font-34 relative text-center" style="flex-grow:1;" v-if="selectIndex == 1">
                  <div class="long flex-center" style="flex-grow:1;padding: 20px" v-if="selectIndex == 1">
                    {{ $t('开多') }}
                    <!-- <span class="right-word font-22 text-center">{{
                      $t("看涨")
                      }}</span> -->
                  </div>
                  <div class="font-34 relative text-center" style="flex-grow:1;" v-else>
                  <div class="long flex-center" style="flex-grow:1;padding: 20px" v-else>
                    {{ $t('做多买入') }}
                  </div>
                </div>
                <div class="w-full h-80 lh-80 bg-red flex text-white mt-70" v-if="currentType == 'short'"
                <div class="flex-center text-white " v-if="currentType == 'short'"
                  @click="order('short')">
                  <div class="relative font-34 text-center" style="flex-grow:1;" v-if="selectIndex == 1">
                  <div class="short flex-center" style="flex-grow:1;padding: 20px" v-if="selectIndex == 1">
                    {{ $t('开空') }}
                    <!-- <span class="right-word font-22 text-center">{{
                      $t("看跌")
                      }}</span> -->
                  </div>
                  <div class="relative font-34 text-center" style="flex-grow:1;" v-else>
                  <div class="short flex-center" style="flex-grow:1;padding: 20px" v-else>
                    {{ $t('做空买入') }}
                  </div>
                </div>
@@ -227,121 +372,11 @@
              </div>
              <div class="h-80 lh-80 btnBackground flex text-white rounded-ban justify-center mt-50"
                @click="$router.push('/login')">
                {{ $t('logIn') }}</div>
                {{ $t('logIn') }}
            </div>
          </div>
          <div>
            <div class="w-290 flex justify-between text-grey font-22">
              <div>
                <div>{{ $t("价格") }}</div>
                <div class="mt-4">{{ queryType === 'cryptos' ? '(USDT)' : '(USD)' }}</div>
              </div>
              <div class="text-right items-end justify-end">
                <div class="">{{ $t("数量") }}</div>
                <div class="mt-4">{{ queryType === 'cryptos' ?
                  `(${symbol_data.toUpperCase() || "--"})` : '(USD)' }}</div>
              </div>
            </div>
            <div class="deep-div">
              <!-- <div v-if="showType == 0 || showType == 2" class="w-290 flex justify-between pt-1  font-26"
                v-for="(item, index) in redData" :key="item + index" @click="onQuickPrice(item.price)" :style="{
                  background:
                    `linear-gradient(to right,${THEME == 'dark' ? '#131A2E' : '#fff'
                    } 0%` +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(246,70,93,.1) ' +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(246,70,93,.1) 100%)',
                }"> -->
              <div v-show="(showType == 0 || showType == 2)" class="w-290 flex justify-between pt-1 font-26"
                v-for="(item, index) in redData" :key="item + index" @click="onQuickPrice(item.price)" :style="{
                  background:
                    `linear-gradient(to right,${$store.state.vant.theme == 'dark' ? '#131A2E' : '#fff'
                    } 0%` +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(246,70,93,.1) ' +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(246,70,93,.1) 100%)'
                }">
                <div class="text-red">{{ item.price }}</div>
                <div class="text-right textColor" v-if="symbol == 'shib'">
                  {{ fixDate(item.amount, $i18n) || "--" }}
                </div>
                <div class="text-right textColor" v-else>
                  {{ item.amount || "--" }}
                </div>
              </div>
            </div>
            <div class="w-290 text-red pt-5 font-34 font-700 text-center">
              {{ price || '--' }}
            </div>
            <div class="pb-5 font-20 text-center">
              ≈ {{ ((price *
                currency.rate).toFixed(price.toString().split('.')[1] ?
                  price.toString().split('.')[1].length : 2)) || '--' }}
            </div>
            <div class="deep-div">
              <!-- <div v-if="showType == 0 || showType == 1" class="w-290 flex justify-between pt-1 font-26"
                v-for="(item, index) in greenData" :key="index" @click="onQuickPrice(item.price)" :style="{
                  background:
                    `linear-gradient(to right,${THEME == 'dark' ? '#131A2E' : '#fff'
                    } 0%` +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(94,186,137,.1) ' +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(94,186,137,.1) 100%)',
                }"> -->
              <div v-if="showType == 0 || showType == 1" class="w-290 flex justify-between pt-1 font-26"
                v-for="(item, index) in greenData" :key="index" @click="onQuickPrice(item.price)" :style="{
                  background:
                    `linear-gradient(to right,${$store.state.vant.theme == 'dark' ? '#131A2E' : '#fff'
                    } 0%` +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(94,186,137,.1) ' +
                    (1 - item.amount / greenData[greenData.length - 1].amount) *
                    100 +
                    '%,rgba(94,186,137,.1) 100%)',
                }">
                <div class="text-green">{{ item.price }}</div>
                <div class="text-right textColor" v-if="symbol_data == 'shib'">
                  {{ fixDate(item.amount, $i18n) || "--" }}
                </div>
                <div class="text-right textColor" v-else>
                  {{ item.amount || "--" }}
                </div>
              </div>
            </div>
            <div class="flex k-select-box">
              <div class="mt-22 mb-22 select-box pl-5 pr-5" style="position: relative">
                <div class="flex justify-between items-center w-full h-70" @click="selectArryBtn">
                  <!-- <img src="@/assets/image/public/warn.png" alt="warn-icon" class="w-25 h-25 pl-20"/> -->
                  <div class="pl-16 font-28 textColor" style="width: 80%">
                    {{ dataArrTitle }}
                  </div>
                  <img src="../../../assets/image/public/grey-select.png" alt="select-icon" class="w-22 h-11 mr-10" />
                </div>
                <div class="option-box" v-show="arryIsShow">
                  <div class="font-28" v-for="(item, index) in selectDataArry" :key="index"
                    @click="selectItemArry(item)">
                    {{ item.name }}
                  </div>
                </div>
              </div>
              <div @click="isSelectShow = true">
                <img src="../../../assets/image/selectIcon.png" alt="warn-icon" class="w-36 h-30 ml-10" />
              </div>
            </div>
          </div>
        </div>
      </div>
      <van-popup v-model:show="show" class="rounded-2xl">
@@ -371,6 +406,7 @@
import { _getHomeList } from "@/service/home.api";
import { _getContractBySymbolType } from "@/service/etf.api";
import { reserve } from "@/utils/utis";
export default {
  name: "perpetualPosition",
  components: {
@@ -538,10 +574,17 @@
  },
  data() {
    return {
      progressRate:0,
      progress: 30, // 初始进度
      isDragging: false, // 是否正在拖动
      barWidth: 0, // 进度条宽度
      startX: 0, // 触摸开始的X坐标
      startProgress: 0, // 触摸开始时的进度
      THEME,
      fixDate,
      bfbindex: null,
      bfblist: [
        {name: '0'},
        { name: '25' },
        { name: '50' },
        { name: '75' },
@@ -614,6 +657,7 @@
    this.title = this.$t('市价');
  },
  mounted() {
    this.barWidth = document.querySelector('.progress-bar').offsetWidth;
    this.getHomeList(this.$route.params.symbol);
    this.form.price = this.price
    this.getAsset()
@@ -622,10 +666,71 @@
    this.clearTimeout()
  },
  methods: {
    mousedown(event){
      // this.bfbclick(event.touches[0].)
      const x1=event.touches[0].pageX
      const x2=event.touches[0].clientX
      console.log(event.touches[0])
    } ,
    mousemove(event){
      console.log(event.touches[0])
    },
    // 处理点击事件
    handleClick(e) {
      if (this.isDragging) return;
      // 获取进度条的位置信息
      const barRect = document.querySelector('.progress-bar').getBoundingClientRect();
      // 计算点击位置相对于进度条的百分比
      const clickPosition = e.clientX - barRect.left;
      const newProgress = (clickPosition / barRect.width) * 100;
      // 更新进度,限制在0-100之间
      this.updateProgress(newProgress);
    },
    // 处理触摸开始事件
    handleTouchStart(e) {
      this.isDragging = true;
      const barRect = document.querySelector('.progress-bar').getBoundingClientRect();
      this.barWidth = barRect.width;
      this.startX = e.touches[0].clientX;
      this.startProgress = this.progressRate;
    },
    // 处理触摸移动事件
    handleTouchMove(e) {
      if (!this.isDragging) return;
      // 计算移动的距离
      const currentX = e.touches[0].clientX;
      const diffX = currentX - this.startX;
      // 根据移动距离计算新进度
      const percentageChange = (diffX / this.barWidth) * 100;
      const newProgress = this.startProgress + percentageChange;
      // 更新进度,限制在0-100之间
      this.updateProgress(newProgress);
    },
    // 处理触摸结束事件
    handleTouchEnd(e) {
      this.isDragging = false;
    },
    // 更新进度的通用方法
    updateProgress(value) {
      // 限制进度在0-100之间
      const clampedValue = Math.max(0, Math.min(100, value));
      this.bfbclick(clampedValue)
      // 可以在这里添加进度变化的回调逻辑
      // this.$emit('progress-change', this.progress);
    },
    reserve,
    bfbclick(e, i) {
      this.bfbindex = i
      e = parseInt(e.name)
    bfbclick(e) {
      this.progressRate = e
      const rate = e / 100; //如0.25
      this.form.amount = this.maxUSDT * rate
      var a = this.form.amount
@@ -907,11 +1012,13 @@
            this.form.session_token = data.session_token;
            this.openOrder(_order, emitFunc);
          }).catch((err) => {
            if (err.code == 'ECONNABORTED') { showToast(this.$t('网络超时!')); }
            else if (err.msg != undefined) { showToast(this.$t(err.msg)); }
          });
            if (err.code == 'ECONNABORTED') {
              showToast(this.$t('网络超时!'));
            } else if (err.msg != undefined) {
              showToast(this.$t(err.msg));
        }
        else {
          });
        } else {
          this.form.session_token = this.initFutrue.session_token;
          this.openOrder(_order, emitFunc);
        }
@@ -955,6 +1062,41 @@
<style lang="scss">
@import "@/assets/init.scss";
.progress-i {
  flex: 1;
  position: relative;
  color: #aaa;
  font-size: 0.8em;
}
.progress-in {
  height: 2px;
  position: relative;
  border-radius: 90px;
  background: #111;
  width: 0%;
  //transition: width 0.3s linear;
}
.progress-icon {
  width: 34px;
  height: 35px;
  border-radius: 90px;
  position: absolute;
  background: white;
  right:-18px;
  z-index: 99;
  top:-16px;
  border: #111 6px solid;
}
.progress-icon1 {
  width: 14px;
  height: 15px;
  border-radius: 90px;
  background: #111;
}
.btns_box_boxs {
  width: 23%;
@@ -1149,9 +1291,12 @@
    // background-color: $green;
    // background: url(@/assets/image/public/open-bg.png) no-repeat right center;
    // background-size: 100% 100%;
    color: white;
    background: #06CDA5;
    color: white !important;
    border-radius: 6px !important;
    background: #24c18d !important;
    font-size: 14px;
    font-size: 22px !important;
    height: 60px;
    // border-radius: 5rem;
  }
@@ -1159,9 +1304,11 @@
    // background-color: $green;
    // background: url(@/assets/image/public/close-bg.png) no-repeat left center;
    // background-size: 100% 100%;
    color: white;
    background: #F43368;
    color: white !important;
    border-radius: 6px !important;
    background: #f14b3f !important;
    font-size: 22px !important;
    height: 60px;
    // border-radius: 5rem;
  }
@@ -1201,6 +1348,6 @@
}
.deep-div {
  min-height: 370px;
  min-height: 200px;
}
</style>