1
lxf
2025-07-15 59269b6839c57aeb0d547dfd6da38157180483fd
src/views/cryptos/Trade/index.vue
@@ -15,21 +15,73 @@
      </div> -->
      <trade-head :isReturn="true" :backFunc="() => $router.push('/')" :symbolName="symbolName" :symbol="symbol"
        :price="price" :range="range" :isTrade="true" @update-coin="onUpdate" @data="quote = $event" />
         <div class="chart-index" style="margin-top: 30px;">
            <k-line-charts v-if="symbol" :update-key="updateKey" :update-data="quote" :symbol="symbol"
               :showBottom="true" />
         </div>
      <div class="trade-buy-sell flex justify-between px-30 py-30">
        <trade-order-area :symbol="symbol" :symbolName="symbolName" :init-open="initOpen" :init-close="initClose"
            <!-- <trade-order-area :symbol="symbol" :symbolName="symbolName" :init-open="initOpen" :init-close="initClose"
          :price="price" @ordered="onOrdered" />
        <keep-alive>
          <cryptos-trade-deep-data :selectValue="selectValue" @getList="getList" :showType="showType" :symbol="symbol"
            v-if="symbol" :price="price" class="w-290 ml-30" />
        </keep-alive>
        </keep-alive> -->
            <!-- <trade-order-area :symbol="symbol" :symbolName="symbolName" :init-open="initOpen" :init-close="initClose"
        :price="price" @ordered="onOrdered" /> -->
            <div class="btns" style="margin-top:20px;">
               <div class="tbns_mc" @click="showPopupclick('close')">{{$t('卖出')}}</div>
               <div class="tbns_mr" @click="showPopupclick('open')">{{$t('买入')}}</div>
      </div>
      <div class="flex k-select-box">
         </div>
            <van-popup v-model:show="showPopup"  :round="true">
              <div class="popup-content" style="padding: 20px;">
               <trade-order-area  ref="TradeOrderArea" :symbol="symbol" :symbolName="symbolName" :init-open="initOpen" :init-close="initClose"
               :price="price" @ordered="onOrdered"  />
              </div>
            </van-popup>
         <div class="ws_box">
            <div class="ws_box_box">
               <div class="ws_box_box_box">
                  <div class="ws_box_box_box_top">
                     <img class="ws_box_box_box_top_img" src="../../../assets/img/icon-dollar.png"/>
                     <div class="ws_box_box_box_top_txt">{{$t('开')}}</div>
                  </div>
                  <div class="ws_box_box_box_btn">{{quote.open}}</div>
               </div>
               <div class="ws_box_box_box">
                  <div class="ws_box_box_box_top">
                     <img class="ws_box_box_box_top_img" src="../../../assets/img/icon-arrow-up.png"/>
                     <div class="ws_box_box_box_top_txt">{{$t('高')}}</div>
                  </div>
                  <div class="ws_box_box_box_btn">{{quote.high}}</div>
               </div>
            </div>
            <div class="ws_box_box" style="padding-bottom: 10px;">
               <div class="ws_box_box_box">
                  <div class="ws_box_box_box_top">
                     <img class="ws_box_box_box_top_img" src="../../../assets/img/icon-arrow-down.png"/>
                     <div class="ws_box_box_box_top_txt">{{$t('低')}}</div>
                  </div>
                  <div class="ws_box_box_box_btn">{{quote.low}}</div>
               </div>
               <div class="ws_box_box_box">
                  <div class="ws_box_box_box_top">
                     <img class="ws_box_box_box_top_img" src="../../../assets/img/icon-foldline.png"/>
                     <div class="ws_box_box_box_top_txt">{{$t('24h成交量')}}</div>
                  </div>
                  <div class="ws_box_box_box_btn">{{quote.amount}}</div>
               </div>
            </div>
         </div>
         <!-- <div class="flex k-select-box">
        <div class="mt-20 mb-22 select-box" style="position:relative;">
          <div class=" flex justify-between  items-center w-full h-70" @click="selectBtn">
            <!-- <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%;color: #333;">{{ title }}</div>
            <img src="../../../assets/image/public/grey-select.png" alt="select-icon" class="w-22 h-11 mr-20" />
                  <img src="../../../assets/image/public/grey-select.png" alt="select-icon"
                     class="w-22 h-11 mr-20" />
          </div>
          <div class="option-box" v-show="isShow">
            <div class="font-28" v-for="(item, index) in sortList" :key="index" @click="selectItem(item)">{{
@@ -41,8 +93,8 @@
        <div class="ml-10" @click="isSelectShow = true">
          <img src="../../../assets/image/selectIcon.png" alt="warn-icon" class="w-36 h-30" />
        </div>
      </div>
      <div class="h-16 diviLine"></div>
         </div> -->
         <!-- <div class="h-16 diviLine"></div>
      <div>
        <div class="flex justify-between border-b-color items-center">
          <div class="flex  pl-30">
@@ -58,14 +110,14 @@
          <img src="../../../assets/image/public/record.png" alt="record-img" class="w-64 h-35 pr-30 "
            @click="goHistory" />
        </div>
      </div>
         </div> -->
      <div class="py-20 px-20" v-if="tabType == '1'">
        <entrust-item v-for="item in entrustList" :key="item.order_no" :entrust="item" state="submitted"
          @cancelOrder="cancelOrder" />
      </div>
      <div class="py-20 px-20" v-else-if="tabType == '2'">
        <history-item unit="USDT" v-for="item in entrustList" :key="item.order_no" :coinPrice="coinPrice" :entrust="item"
          :state="item.state" @cancelOrder="cancelOrder" />
            <history-item unit="USDT" v-for="item in entrustList" :key="item.order_no" :coinPrice="coinPrice"
               :entrust="item" :state="item.state" @cancelOrder="cancelOrder" />
      </div>
      <div class="py-20 px-20" v-else>
        <div class="mb-20 border-b">
@@ -73,8 +125,7 @@
          <ul>
            <li v-for="item in pairsList" :key="item.symbol" class="flex justify-between py-10">
              <div class="flex items-center">
                <img
                  :src="item.symbol ? `${HOST_URL}/symbol/${item.symbol_data}.png` : handleImage('../../../assets/loading-default.png')"
                        <img :src="item.symbol ? `${HOST_URL}/symbol/${item.symbol_data}.png` : handleImage('../../../assets/loading-default.png')"
                  class="w-52 h-52 rounded-full mr-16" />
                <p class="flex flex-col">
                  <strong class="font-28 textColor mb-6">{{ item.symbol.toUpperCase() }}</strong>
@@ -95,8 +146,7 @@
          <ul>
            <li v-for="item in no_zeroList" :key="item.symbol" class="flex justify-between py-10">
              <div class="flex items-center">
                <img
                  :src="item.symbol ? `${HOST_URL}/symbol/${item.symbol_data}.png` : handleImage('../../../assets/loading-default.png')"
                        <img :src="item.symbol ? `${HOST_URL}/symbol/${item.symbol_data}.png` : handleImage('../../../assets/loading-default.png')"
                  class="w-52 h-52 rounded-full mr-16" />
                <p class="flex flex-col">
                  <strong class="font-28 textColor mb-6">{{ item.symbol.toUpperCase() }}</strong>
@@ -127,11 +177,14 @@
        <k-line-charts :update-key="updateKey" :update-data="quote" :symbol="symbol" v-if="symbol && showCharts"
          :showBottom="false" />
      </div> -->
      <div class="fixed-box">
         <!-- <div class="fixed-box">
        <div class="flex justify-between items-center px-30 py-20" @click.stop="handleClickShowKlineChart()">
          <span class="font-30  textColor2" style="">{{ symbol.toUpperCase() }}&nbsp;&nbsp;{{ $t('k线图表') }}</span>
          <van-icon class="textColor font-28" :name="showCharts ? 'arrow-down' : 'arrow-up'"></van-icon>
        </div>
      <div class="kline-container flex" v-if="showKlineChart">
      </div> -->
        <!-- <section class="indicator-index-container" v-if="showKlineChart">
          <div class="indicator-index-box">
            <div class="flex-l">
@@ -153,14 +206,8 @@
            </ul>
          </div>
        </section> -->
        <div class="kline-container flex" v-if="showKlineChart">
          <div class="chart-index">
            <!-- <fx-kline :height="500" :symbol="symbol" :isShowsolid="true" :chartType="chartType" v-if="symbol" @data="onData"
            :key="`${symbol}-${timeValue}`" /> -->
            <k-line-charts :update-key="updateKey" :update-data="quote" :symbol="symbol" :showBottom="true" />
          </div>
        </div>
      </div>
         <!-- </div> -->
      <van-action-sheet class="action-sheet" v-model:show="isSelectShow" @select="onSelect" :actions="actions"
        :cancel-text="$t('取消')" close-on-click-action @cancel="onCancel" />
@@ -179,16 +226,44 @@
import fxKline from '@/components/fx-kline/index.vue'
import Axios from '@/service/trading'
import { _getHomeList } from '@/service/home.api'
import { Popup, Swipe, SwipeItem, Circle, Icon, showSuccessToast, showFailToast } from 'vant';
import { mapActions, mapGetters } from 'vuex'
import { SET_COIN_LIST } from '@/store/const.store'
import { WS_URL, HOST_URL } from '@/config'
   import {
      _getHomeList
   } from '@/service/home.api'
   import {
      Popup,
      Swipe,
      SwipeItem,
      Circle,
      Icon,
      showSuccessToast,
      showFailToast
   } from 'vant';
   import {
      mapActions,
      mapGetters
   } from 'vuex'
   import { ref } from 'vue';
   import {
      SET_COIN_LIST
   } from '@/store/const.store'
   import {
      WS_URL,
      HOST_URL
   } from '@/config'
import TradeApi from "@/service/trading.js";
import { getStorage, handleImage } from '@/utils/utis'
import { useQuotesStore } from '@/store/quotes.store'
import { SET_STAGE } from '@/store/types.store';
import { _getExchangeRate } from '@/service/cryptos.api'
   import {
      getStorage,
      handleImage
   } from '@/utils/utis'
   import {
      useQuotesStore
   } from '@/store/quotes.store'
   import {
      SET_STAGE
   } from '@/store/types.store';
   import {
      _getExchangeRate
   } from '@/service/cryptos.api'
const quotesStore = useQuotesStore()
export default {
  name: "TradePage",
@@ -223,10 +298,12 @@
    }
    return {
      HOST_URL,
            showPopup:false,
      quote: {},
      showCharts: false,
      updateKey: 1,
      initTimer: null,
            currentType:null,
      keyIndex: 0,
      timeout: null,
      timer: null, // 底部持仓等的公用定时器
@@ -250,7 +327,7 @@
      curTab: '', // 当前委托还是持有仓位
      selectIndex: 1, // 当前tab
      initFutrue: {}, /// 交割合约
      show: false, // popup
            show: true, // popup
      entrustList: [], //当前委托订单
      tabType: 1,
      no_zeroList: [], //其他非0资产数组
@@ -259,28 +336,103 @@
      isShow: false,
      title: 1,
      isSelectShow: false,
      actions: [{ name: this.$t('默认'), value: 0, className: 'actions-active' }, { name: this.$t('展示买单'), value: 1, className: "" }, { name: this.$t('展示卖单'), value: 2, className: '' }],
            actions: [{
               name: this.$t('默认'),
               value: 0,
               className: 'actions-active'
            }, {
               name: this.$t('展示买单'),
               value: 1,
               className: ""
            }, {
               name: this.$t('展示卖单'),
               value: 2,
               className: ''
            }],
      showType: 0,
      sortList: [],
      selectValue: 0,
      coinPrice: 0,
      type: 'cryptos',
      filterOne: [
        { name: this.$t('分时'), paramsValue: 'timeSharing', seconds: 1 * 60 * 1000, index: 0, },
        { name: '1' + this.$t('天'), paramsValue: '1day', seconds: 1 * 24 * 60 * 60 * 1000, index: 1, },
        { name: '1' + this.$t('周'), paramsValue: '1week', seconds: 7 * 24 * 60 * 60 * 1000, index: 2, },
        { name: '1' + this.$t('月'), paramsValue: '1mon', seconds: 30 * 24 * 60 * 60 * 1000, index: 3, },
        { name: '5' + this.$t('天'), paramsValue: '5day', seconds: 5 * 24 * 60 * 60 * 1000, index: 4, },
        { name: this.$t('season'), paramsValue: '1quarter', seconds: 3 * 30 * 24 * 60 * 60 * 1000, index: 5, },
        { name: this.$t('Year'), paramsValue: '1year', seconds: 12 * 30 * 24 * 60 * 60 * 1000, index: 6, },
            filterOne: [{
                  name: this.$t('分时'),
                  paramsValue: 'timeSharing',
                  seconds: 1 * 60 * 1000,
                  index: 0,
               },
               {
                  name: '1' + this.$t('天'),
                  paramsValue: '1day',
                  seconds: 1 * 24 * 60 * 60 * 1000,
                  index: 1,
               },
               {
                  name: '1' + this.$t('周'),
                  paramsValue: '1week',
                  seconds: 7 * 24 * 60 * 60 * 1000,
                  index: 2,
               },
               {
                  name: '1' + this.$t('月'),
                  paramsValue: '1mon',
                  seconds: 30 * 24 * 60 * 60 * 1000,
                  index: 3,
               },
               {
                  name: '5' + this.$t('天'),
                  paramsValue: '5day',
                  seconds: 5 * 24 * 60 * 60 * 1000,
                  index: 4,
               },
               {
                  name: this.$t('season'),
                  paramsValue: '1quarter',
                  seconds: 3 * 30 * 24 * 60 * 60 * 1000,
                  index: 5,
               },
               {
                  name: this.$t('Year'),
                  paramsValue: '1year',
                  seconds: 12 * 30 * 24 * 60 * 60 * 1000,
                  index: 6,
               },
      ],
      filterTwo: [
        { name: '120' + this.$t('分'), paramsValue: '120min', seconds: 2 * 60 * 60 * 1000, index: 7, },
        { name: '60' + this.$t('分'), paramsValue: '60min', seconds: 1 * 60 * 60 * 1000, index: 8, },
        { name: '30' + this.$t('分'), paramsValue: '30min', seconds: 30 * 60 * 1000, index: 9, },
        { name: '15' + this.$t('分'), paramsValue: '15min', seconds: 15 * 60 * 1000, index: 10, },
        { name: '5' + this.$t('分'), paramsValue: '5min', seconds: 5 * 60 * 1000, index: 11, },
        { name: '1' + this.$t('分'), paramsValue: '1min', seconds: 1 * 60 * 1000, index: 12, },
            filterTwo: [{
                  name: '120' + this.$t('分'),
                  paramsValue: '120min',
                  seconds: 2 * 60 * 60 * 1000,
                  index: 7,
               },
               {
                  name: '60' + this.$t('分'),
                  paramsValue: '60min',
                  seconds: 1 * 60 * 60 * 1000,
                  index: 8,
               },
               {
                  name: '30' + this.$t('分'),
                  paramsValue: '30min',
                  seconds: 30 * 60 * 1000,
                  index: 9,
               },
               {
                  name: '15' + this.$t('分'),
                  paramsValue: '15min',
                  seconds: 15 * 60 * 1000,
                  index: 10,
               },
               {
                  name: '5' + this.$t('分'),
                  paramsValue: '5min',
                  seconds: 5 * 60 * 1000,
                  index: 11,
               },
               {
                  name: '1' + this.$t('分'),
                  paramsValue: '1min',
                  seconds: 1 * 60 * 1000,
                  index: 12,
               },
      ],
      showKlineChart: false,
      chartType: '',
@@ -294,6 +446,7 @@
      timer3: null
    }
  },
  async created() {
    if (this.$route.query.type) {
      this.type = this.$route.query.type
@@ -302,12 +455,22 @@
    this.getExchangeRate()
  },
  methods: {
         onReady(){
            if (this.$refs.TradeOrderArea) {
                  this.$refs.TradeOrderArea.changeTab();
            }
         },
    handleImage,
    ...mapActions('home', [SET_COIN_LIST]),
    onUpdate(symbol) { // 更新
      this.symbol = symbol
      this.closeSocket()
      this.init(symbol)
         },
         showPopupclick(e){
            this.showPopup = !this.showPopup
            // this.currentType = e
            this.$refs.TradeOrderArea.changeTab(e);
    },
    getExchangeRate() {
      _getExchangeRate({}).then((res) => {
@@ -318,9 +481,16 @@
      this.showKlineChart = !this.showKlineChart
    },
    handleClickSelectTime(params) {
      const { paramsValue, seconds, index } = params;
            const {
               paramsValue,
               seconds,
               index
            } = params;
      this.timeLabelActive = index;
      quotesStore[SET_STAGE]({ stage: paramsValue, seconds })
            quotesStore[SET_STAGE]({
               stage: paramsValue,
               seconds
            })
      this.onSelectTime(paramsValue)
    },
    onSelectTime(evt) {
@@ -378,7 +548,7 @@
      if (data && data.length) {
        const cur = data[0]
        this.price = cur.close
        this.range = cur.change_ratio_str || cur.changeRatioStr
               this.range = cur.change_ratio || cur.changeRatio
        this.quote = cur
        this.updateKey++
      }
@@ -390,8 +560,13 @@
      }
      this.socket = new WebSocket(`${WS_URL}/1/${this.symbol}`)
      this.socket.onmessage = (evt) => {
        const { data } = evt
        const { code, data: _data } = JSON.parse(data)
               const {
                  data
               } = evt
               const {
                  code,
                  data: _data
               } = JSON.parse(data)
        if (code / 1 === 0) {
          this.handleQoutes(_data)
        }
@@ -451,8 +626,11 @@
      }).then((res) => {
        console.log(res);
      }).catch((error) => {
        if (error.code === 'ECONNABORTED') { showFailToast(this.$t('网络超时!')); }
        else if (error.msg !== undefined) { showFailToast(this.$t(error.msg)); }
               if (error.code === 'ECONNABORTED') {
                  showFailToast(this.$t('网络超时!'));
               } else if (error.msg !== undefined) {
                  showFailToast(this.$t(error.msg));
               }
      });
    },
    getOrderList() {
@@ -528,7 +706,11 @@
    }
  },
  beforeRouteEnter(to, from, next) {
    let { params: { symbol } } = to
         let {
            params: {
               symbol
            }
         } = to
    // console.log('to', to)
    // let catchTradeSymbol = getStorage('tradeSymbol') || null
    // if (catchTradeSymbol != null) {
@@ -558,11 +740,75 @@
    this.clearTimer()
  }
}
</script>
<style lang="scss" scoped>
   .ws_box_box_box_btn{
      font-size: 35px;
      font-weight: bold;
      padding-bottom: 20px;
   }
   .ws_box_box_box_top_img{
      width: 30px;
      height: 30px;
      margin-right: 10px;
   }
   .ws_box_box_box_top{
      display: flex;
      align-items: center;
      font-size: 30px;
      font-weight: bold;
      color: #8c8883;
   }
   .ws_box_box_box{
      width: 50%;
      display: flex;
      flex-direction: column;
      padding-top: 40px;
      padding-left: 40px;
   }
   .ws_box_box{
      display: flex;
   }
   .ws_box{
      display: flex;
      flex-direction: column;
      background-color: #F6F7F9;
      border-radius:24px;
      color:#333;
      margin:30px;
   }
@import "@/assets/init.scss";
   .tbns_mr {
      font-weight: bold;
      font-size: 35px;
      text-align:center;
      background-color: #3A7FF6;
      color: #fff;
      width: 350px;
      line-height: 100px;
      height: 100px;
      border-radius: 50px;
   }
   .tbns_mc {
      font-weight: bold;
      font-size: 35px;
      text-align:center;
      background-color: #DE5D57;
      color: #fff;
      width: 350px;
      line-height: 100px;
      height: 100px;
      border-radius: 50px;
   }
   .btns {
      display: flex;
      justify-content: space-between;
      align-items: center;
      // margin: 10px;
      width: 100%;
   }
#cryptos {
  :v-deep(.px-4) {
@@ -586,7 +832,7 @@
  //}
  :deep(.action-sheet .van-popup) {
    height: 100%;
    width: 670px;
         width: 770px;
  }
  .no_touch {
@@ -814,7 +1060,9 @@
.diviLine{
  background-color: #f5f5f5;
}
.textColor2, .textColor{
   .textColor2,
   .textColor {
  color: #fff;
}
</style>