lxf
2025-07-07 93f9b248dd0eecbaa77006e5146c58c831d89d8e
style
10 files modified
227 ■■■■ changed files
src/components/Transform/contract-futrue/index.vue 38 ●●●● patch | view | raw | blame | history
src/components/Transform/contract-header/index.vue 32 ●●●● patch | view | raw | blame | history
src/components/Transform/list-quotation/index.vue 72 ●●●●● patch | view | raw | blame | history
src/components/Transform/perpetual-open/index.vue 2 ●●● patch | view | raw | blame | history
src/components/Transform/trade-order-area/index.vue 6 ●●●● patch | view | raw | blame | history
src/config/index.js 4 ●●●● patch | view | raw | blame | history
src/router/index.js 2 ●●● patch | view | raw | blame | history
src/views/cryptos/PerpetualContract/index.vue 46 ●●●● patch | view | raw | blame | history
src/views/cryptos/index.vue 21 ●●●● patch | view | raw | blame | history
src/views/news/index.vue 4 ●●●● patch | view | raw | blame | history
src/components/Transform/contract-futrue/index.vue
@@ -3,7 +3,9 @@
    <div class="contact-futrue">
      <div class="font-24 text-grey mb-24">{{ $t('交割时间') }}</div>
      <ul class="flex flex-wrap w-full">
        <li v-for="(item, index) in initFutrue.para" v-if="initFutrue.para" :key="item.uuid"
        <!-- v-if="initFutrue.para" -->
        <!-- initFutrue: {{ initFutrue.para }} -->
        <li v-for="(item, index) in initFutrue.para"  v-if="initFutrue.para" :key="item.uuid"
          class="h-92 flex items-center mb-22" @click="onSelect(item, index)">
          <p class="w-95 h-full flex justify-center items-center font-22 flex-1"
            :class="active === item.para_id ? 'bg-light-blue text-white' : 'delivery_left_tab_background textColor'"
@@ -20,6 +22,9 @@
</template>
<script>
import { _futrueOrderInit } from "@/service/trade.api.js";
import { getStorage } from '@/utils'
export default {
  name: 'ContractFutrue',
  props: {
@@ -33,20 +38,43 @@
  data() {
    return {
      active: '',
      // initFutrue: {},
      m_initFutrue: {},
      initParam: [] // 初始化参数
    }
  },
  created() {
    if (this.initFutrue.para.length > 0) {
      this.active = this.initFutrue.para[0].para_id || ''
      this.$emit('paraId', { id: this.active, index: 0 })
        console.log('this.initFutrue', this.initFutrue)
        // this._initParam();
        if (this.initFutrue.para.length > 0) {
          this.active = this.initFutrue.para[0].para_id || ''
          this.$emit('paraId', { id: this.active, index: 0 })
        }
  },
  watch: {
    '$route.query.symbol'(newVal, oldVal) {
      if (newVal !== oldVal) {
        this._initParam();
      }
    }
  },
  methods: {
    onSelect(item, index) { // 选中
      this.active = item.para_id
      this.$emit('paraId', { id: this.active, index })
    }
    },
    _initParam(){ // 初始化参数
    // if (type === 'futrue' || !type) {
      // const symbol = getStorage('symbol')
      _futrueOrderInit('USDSGD').then(data => {
            // this.m_initFutrue = data
            if (this.initFutrue.para.length < 0) {
              this.initFutrue = data
            }
          console.log('this.initFutrue', this.initFutrue)
        })
    // }
    },
  }
}
</script>
src/components/Transform/contract-header/index.vue
@@ -13,7 +13,7 @@
            </div>
            <div class="pl-10 w-160  font-28" :class="{ 'text-green': range > 0, 'text-red': range <= 0 }">{{ range > 0 ?
              '+' : '' }}{{ range || '--' }}%</div>
            <img src="@/assets/image/kline.png" class="w-44 h-44 right" alt="" @click="klineJump()">
            <!-- <img src="@/assets/image/kline.png" class="w-44 h-44 right" alt="" @click="klineJump()"> -->
          </div>
          <!-- <div class="flex items-center">
                        <img src="../../assets/image/public/k-line.png" alt="line-img" class="w-38 h-35"
@@ -25,9 +25,9 @@
          <!-- <button class="tabBtn w-368 h-74 lh-74 border-none  rounded"
            :class="selectIndex == 1 ? 'select-active' : 'no-select'" @click="changeTab(1)">
            {{ $t('永续合约') }}</button> -->
          <button class="tabBtn w-368 h-74 lh-74 border-none  rounded"
          <!-- <button class="tabBtn w-368 h-74 lh-74 border-none  rounded"
            :class="selectIndex == 2 ? 'select-one-active' : 'no-select'" @click="changeTab(2)">
            {{ queryType == 'cryptos' ? $t('交割合约') : $t('期货交易') }}</button>
            {{ queryType == 'cryptos' ? $t('交割合约') : $t('期货交易') }}</button> -->
        </div>
      </div>
    </div>
@@ -36,7 +36,7 @@
      <div class="pl-42 border-b-color pt-48 pb-48">
        <div class="textColor">
          <span class="font-bold font-45 mr-12">{{ title }} {{ $t('合约') }}</span>
          <span class="font-30">/{{ queryType == 'cryptos' ? 'USDT'  : 'USD'}} </span>
          <span class="font-30">/{{ 'USD'}} </span>
        </div>
      </div>
      <div class="pl-42 pr-40 font-28">
@@ -56,7 +56,7 @@
        <div class="flex justify-between mb-50" v-for="item in list" :key="item.name" @click="onRoute(item)">
          <div>
            <div class="textColor font-28">{{ item.name }}</div>
            <div class="text-grey mt-10 font-28">{{ selectIndex == 1 ? $t('永续') : $t('交割') }}</div>
            <!-- <div class="text-grey mt-10 font-28">{{ selectIndex == 1 ? $t('永续') : $t('交割') }}</div> -->
          </div>
          <div class="text-right">
            <div class="textColor font-28">{{ item.close }}</div>
@@ -73,6 +73,7 @@
import { Popup } from "vant";
import { mapGetters } from "vuex";
import { _getHomeList } from "@/service/home.api";
import { useQuotesStore } from '@/store/quotes.store';
import { THEME } from '@/config/theme'
import { setStorage } from '@/utils/utis'
export default {
@@ -112,6 +113,9 @@
  },
  computed: {
    ...mapGetters({ coinList: 'home/coinList' }),
    ...mapGetters({
      myCoinList: 'qoutes/coinList'
    }),
    title() {
      return [this.$t('永续'), this.$t('交割')][this.selectIndex - 1]
    }
@@ -141,7 +145,8 @@
  methods: {
    onRoute(item) {
      if (this.$route.params.symbol !== item.symbol) {
        this.$router.push(`/cryptos/perpetualContract/${item.symbol}?type=${this.queryType}`)
        // this.$router.push(`/cryptos/perpetualContract/${item.symbol}?selectIndex=${this.selectIndex}`)
        // debugger
        this.$emit('update-coin', item.symbol)
        setStorage('symbol', item.symbol)
        this.$forceUpdate()
@@ -149,7 +154,17 @@
      this.show = false
    },
    onSidebar() { // 侧边栏打开
      this.coins = this.coinList.map(item => item.symbol)
      // console.log('侧边栏打开: ', this.selectIndex)
      if (this.selectIndex == 2) {
        const quotesData = JSON.parse(localStorage.getItem('qoutes'));
        this.coins = quotesData.coins || [];
        this.coins = quotesData.coins.map(item => item.symbol)
      } else {
        this.coins = this.coinList.map(item => item.symbol);
      }
      // quotesStore.coins
      console.log(this.coins, 11111)
      this.show = true
      this.fetchList()
@@ -166,6 +181,7 @@
          this.fetchList()
        }, 1000)
      })
    },
    onClose() {
      if (this.timeout) {
@@ -188,7 +204,7 @@
      // }
    },
    klineJump() {
      this.$router.push(`/cryptos/trendDetails/${this.symbol}?type=${this.queryType}`)
      this.$router.push(`/cryptos/trendDetails/${this.symbol}?type=${this.queryType}&selectIndex=${this.selectIndex}`)
    },
    changeTab(index) {
      this.$emit('tab', index)
src/components/Transform/list-quotation/index.vue
@@ -19,17 +19,17 @@
      <!-- 热门 -->
      <div class="flex items-end justify-between" style="margin: 14px 0;">
        <div class="block text-22 font-medium" >{{$t('Market')}}</div>
        <div class="relative text-13">
          <!-- <div class="flex px-10 justify-between rounded-full bg-black text-white min-w-100 box-border">
            <div class="block">貨幣</div>
            <div class="i-material-symbols:arrow-drop-down-rounded"></div>
          </div> -->
          <!-- <div class="px-9 py-10 bg-black text-white flex flex-col absolute min-w-100 box-border top-25 rounded-11 leading-28" style="display: none;">
            <div>貨幣</div>
            <div>數字貨幣</div>
            <div>期貨</div>
            <div>收藏</div>
          </div> -->
        <div class="relative text-13" @click="toggleDropdown">
          <div class="flex px-20 justify-between rounded-full bg-black text-white min-w-100 box-border">
            <div class="block">{{ $t(topTitle) }}</div>
            <van-icon name="play" style="align-content:center;transform: rotate(90deg);"/>
          </div>
          <div class="px-16 py-20 bg-black text-white flex flex-col absolute min-w-100 box-border top-25 rounded-11 leading-28" style="z-index:999;margin-top: 0.8rem;" v-show="isTopShow">
            <div @click="changeType('币币交易', 1)">{{ $t('币币交易') }}</div>
            <div @click="changeType('外汇交割', 2)">{{ $t('外汇交割') }}</div>
            <!-- <div>期貨</div>
            <div>收藏</div> -->
          </div>
        </div>
      </div>
@@ -62,10 +62,10 @@
                    currency.rate).toFixed(2) || '--' }}</p>
              </li>
              <li class="right flex items-center justify-end">
                <p class="w-153 font-31 h-71 bg-green text-white border-0 text-center btn" v-if="item.change_ratio_str > 0">
                  +{{ item.change_ratio_str || (item.change_ratio_str === 0 ? 0 : '--') }}%</p>
                <p class="w-153 font-31 h-71 bg-green text-white border-0 text-center btn" v-if="item.change_ratio_str > 0 || item.change_ratio > 0">
                  +{{ item.change_ratio || (item.change_ratio_str === 0 ? 0 : '--') }}%</p>
                <p class="w-153 font-31 h-71 bg-red text-white border-0 text-center btn" v-else>
                  {{ item.change_ratio_str || (item.change_ratio_str === 0 ? 0 : '--') }}%</p>
                  {{ item.change_ratio || (item.change_ratio_str === 0 ? 0 : '--') }}%</p>
              </li>
            </ul>
          </van-cell>
@@ -82,9 +82,9 @@
                    }}</span>
                    <!-- <span class="font-24 text-grey" style="position: relative; top: 1px">
                      {{ item.name && item.name.replace(item.symbol.toUpperCase(), '') || '--' }}</span> -->
                    <span class="font-24 text-grey" style="position: relative; top: 1px">
                    <!-- <span class="font-24 text-grey" style="position: relative; top: 1px">
                      /USDT
                    </span>
                    </span> -->
                  </span>
                  <span class="font-24 text-grey text-left">{{ $t('成交量') + ' ' + (item.amount * 1).toFixed(2) }}</span>
                </p>
@@ -99,10 +99,10 @@
                  {{ (item.volume * 1).toFixed(2) }}
                </div>
                <template v-else>
                  <p class="w-153 font-31 h-71 bg-green text-white border-0 text-center btn" v-if="item.change_ratio_str > 0">
                    +{{ item.change_ratio_str }}%</p>
                  <p class="w-153 font-31 h-71 bg-green text-white border-0 text-center btn" v-if="item.change_ratio_str > 0 || item.change_ratio > 0">
                    +{{ item.change_ratio || item.change_ratio_str }}%</p>
                  <p class="w-153 font-31 h-71 bg-red text-white border-0 text-center btn" v-else>
                    {{ item.change_ratio_str || (item.change_ratio_str === 0 ? 0 : '--') }}%</p>
                    {{ item.change_ratio || (item.change_ratio_str === 0 ? 0 : '--') }}%</p>
                </template>
              </li>
            </ul>
@@ -132,6 +132,9 @@
      fixDate,
      HOST_URL,
      active: 0,
      isTopShow: false,
      topTitle: '币币交易',
      topValue: 1,
      type: 'left' //left 从左往右 right 从有王座
    }
  },
@@ -164,17 +167,32 @@
  },
  methods: {
    ...mapActions('home', [SET_CURRENCY]),
    changeType(tit, val){
      this.topTitle = tit
      this.topValue = val
      this.$emit('onfetchQList', val)
    },
    toggleDropdown(){
      if(this.isTopShow){
        this.isTopShow = false
      }else{
        this.isTopShow = true
      }
    },
    onItemClick(item) {
      if (this.tabActive == 2) { //现货
      if (this.topValue == 2) { //现货
        setStorage('symbol', item.symbol)
        this.$router.push({
          path: `/cryptos/trade/${item.symbol}`
           path: `/cryptos/perpetualContract/${item.symbol}`,
           query: { selectIndex: 2 }
        });
      } else {
        setStorage('symbol', item.symbol)
        // /cryptos/perpetualContract/btcusdt?selectIndex=2
        this.$router.push({
          path: `/cryptos/perpetualContract/${item.symbol}`,
          query: { selectIndex: 2 }
          path:`/cryptos/trade/${item.symbol}`,
          // path: `/cryptos/perpetualContract/${item.symbol}`,
          // query: { selectIndex: 2 }
        });
        //  this.$router.push({
        //   path: `/foreign/deliveryContract/${item.symbol}`,
@@ -305,4 +323,12 @@
.text-grey{
  // color: #8c8c8c;
}
#cryptos .list-quatation .van-cell{
  padding: 24px !important;
  border-radius: 1rem;
}
.list-quatation{
  margin: 0 20px;
}
</style>
src/components/Transform/perpetual-open/index.vue
@@ -45,7 +45,7 @@
                </div>
              </div>
            </template>
            <contract-futrue v-if="selectIndex == 2 && JSON.stringify(initFutrue.para) != '[]'" class="mb-20"
            <contract-futrue v-if="selectIndex == 2" class="mb-20"
              :initFutrue="initFutrue" @paraId="onParaId" />
            <div class="h-76 lh-76 greyBg mb-30 flex pr-20 justify-center rounded-lg textColor" v-if="selectIndex == 1">
              <input placeholder="" class="greyBg w-full pl-20  h-76 border-none text-left rounded-lg"
src/components/Transform/trade-order-area/index.vue
@@ -490,9 +490,9 @@
  right: 0;
  top: 90px;
  width: 100%;
  background-color: $grey_bg;
  background-color: #ebebeb;
  text-align: center;
  box-shadow: 0px 0px 3px 3px $grey_bg;
  // box-shadow: 0px 0px 3px 3px $grey_bg;
  border-radius: 4px;
  color: $text-color;
  z-index: 10;
@@ -503,7 +503,7 @@
}
.option-box>div:hover {
  background-color: $grey_bg;
  // background-color: $grey_bg;ss
}
.num-text-color {
src/config/index.js
@@ -34,8 +34,8 @@
export const defaultSeconds = 1 * 24 * 60 * 60 * 1000
// const ENV_DEV = 'zhapi.coinbtcs.com' // dev
const ENV_DEV = 'openapi.yanshiz.com' // dev
// const ENV_DEV = '192.168.10.18:8086' // dev
// const ENV_DEV = 'openapi.yanshiz.com' // dev
const ENV_DEV = '192.168.10.18:8086' // dev
// const ENV_PRO = 'qheufhj.site' //  app域名
src/router/index.js
@@ -6,7 +6,7 @@
  {
    path: '/',
    children: [
      { path: '', redirect: '/quotes' },
      { path: '', redirect: '/news/index' },
      {
        path: '/login',
        name: 'Login',
src/views/cryptos/PerpetualContract/index.vue
@@ -172,7 +172,7 @@
          </div>
        </section>
        <div class="mainBackground rounded-view" key="y">
          <PerpetualOpen class="pl-30 pr-30" :key="keyIndex + 'c'" :selectIndex="selectIndex" :symbol="symbol"
          <PerpetualOpen class="pl-30 pr-30" :key="symbol" :selectIndex="selectIndex" :symbol="symbol"
            :green-data="bids" :red-data="asks" :price="price" :init-open="initOpen" :init-close="initClose"
            :init-futrue="initFutrue" @ordered="onOrdered" @changeValueBack="changeValueBack">
          </PerpetualOpen>
@@ -228,7 +228,7 @@
import PerpetualOpen from '@/components/Transform/perpetual-open/index.vue'
import PerpetualOrder from '@/components/Transform/perpetual-order/index.vue'
import { _getDeepData, _initOpen, _initClose, _futrueOrderInit, _contractApplyOrderList, contractOrder, _futrueOrderList } from "@/service/trade.api";
import { _getDeepData, _initOpen, _initClose, _futrueOrderInit, _contractApplyOrderList, contractOrder, _futrueOrderList, _getKline } from "@/service/trade.api";
import { _getBalance } from '@/service/user.api'
import { _getHomeList } from '@/service/home.api'
import { Popup, Swipe, SwipeItem } from 'vant';
@@ -260,6 +260,15 @@
    }),
  },
  watch: {
  //   '$route.params.symbol': {
  //   immediate: true,
  //   handler(newVal) {
  //     if (newVal) {
  //       this.symbol = newVal
  //       this.onUpdate(newVal) // 重新初始化数据
  //     }
  //   }
  // },
    selectIndex(val) {
      showLength = 7
    },
@@ -359,12 +368,16 @@
      // this.balance = money
    })
  },
  methods: {
    ...mapActions('home', [SET_COIN_LIST]),
    onUpdate(symbol) { // 更新
      debugger
      this.currentType = 'long'
      this.symbol = symbol
      this.closeSocket()
      // this.clearTimer()
      this.symbol = symbol
      this.init(symbol)
    },
    changeCurrentType(type) {
@@ -547,16 +560,25 @@
      if (type === 'open' || type === 'long' || type === 'short' || !type) {
        let initFunTimer = null;
        let initFun = () => {
          _initOpen({ symbol: symbol }).then(data => {
            console.log(data, '22222222')
          _getKline(symbol, '1min').then(data => {
            this.initOpen = data
            clearTimeout(initFunTimer)
            initFunTimer = null
          }).catch(err => {
           }).catch(err => {
            initFunTimer = setTimeout(() => {
              initFun()
            }, 3000);
          })
          // _initOpen({ symbol: symbol }).then(data => {
          //   console.log(data, '22222222')
          //   this.initOpen = data
          //   clearTimeout(initFunTimer)
          //   initFunTimer = null
          // }).catch(err => {
          //   initFunTimer = setTimeout(() => {
          //     initFun()
          //   }, 3000);
          // })
        }
        initFun()
      }
@@ -616,7 +638,7 @@
        symbol: symbol,
        type: 'orders',
        page_no: 1,
        symbolType: 'cryptos'
        // symbolType: 'cryptos'
      }
      if (this.userInfo.token) {
        contractOrder(obj).then(data => {
@@ -637,12 +659,12 @@
    },
    fetchFutrueHoldList(symbol) { // 交割持仓
      if (this.userInfo.token) {
        _futrueOrderList(symbol, 'orders', 1, 'cryptos').then(data => {
        _futrueOrderList(symbol, 'orders', 1).then(data => {
          // this.futrueHold = data
          this.futrueHold = data.sort(this.sortData);
        })
        this.timer = setInterval(() => {
          _futrueOrderList(symbol, 'orders', 1, 'cryptos').then(data => {
          _futrueOrderList(symbol, 'orders', 1).then(data => {
            // if (typeof this.timer === 'string') {
            //   this.timer = null
            //   return
@@ -654,12 +676,16 @@
      }
    },
    fetchFutrueHistory(symbol) { // 交割历史持仓
      _futrueOrderList(symbol, 'hisorders', 1, 'cryptos').then(data => {
      _futrueOrderList(symbol, 'hisorders', 1 ).then(data => {
        this.futrueHistroy = data
        // this.clearTimeout()
      })
    },
    init(symbol) { // 初始化页面
      // 在清理一遍
      this.closeSocket()
      this.clearTimer()
      this.symbol = symbol
      this.fetchQoutes(symbol)
      this.fetchDeepData(symbol)
src/views/cryptos/index.vue
@@ -42,7 +42,7 @@
      </div>
    </div> -->
    <!-- <ex-hot :listData="hList"></ex-hot> -->
    <list-quatation :listData="qList" />
    <list-quatation :listData="qList" @onfetchQList="fetchQList"/>
    <van-popup v-model:show="item.showPopUp" style="border-radius:10px;" :close-on-click-overlay="false"
      v-for="item in popupNewsList" :key="item.id">
      <div class="w-350 p-20 box-border">
@@ -98,7 +98,7 @@
      currency: 'home/currency',
      coinArr: 'home/coinArr',
      hotArr: 'home/hotArr',
      userInfo: 'user/userInfo'
      userInfo: 'user/userInfo',
    }),
  },
  data() {
@@ -122,6 +122,7 @@
      unreadMsg_timer: null,
      unreadMsg_num: '',
      popupNewsList: [],
      getVal: 1,
    }
  },
  methods: {
@@ -132,8 +133,20 @@
        //console.log('\n *** \n'+unread_num*1+'\n *** \n')
      })
    },
    async fetchQList() { // 获取行情
      const list = await _getHomeList(this.coinArr.join(',')).catch(() => {
    async fetchQList(v) { // 获取行情
      let coninArr = ''
      if (v) { this.getVal = v }
      if(this.getVal == 2) {
        let arr = getStorage('qoutes').coins
        arr.map((item) => {
          coninArr += item.symbol + ','
        })
       }else{
        coninArr = this.coinArr.join(',')
      }
      console.log('fetchQList', v, coninArr)
      // if()
      const list = await _getHomeList(coninArr).catch(() => {
        //TODO: 轮询
        // this.timeout = setTimeout(() => {
        //   this.fetchQList()
src/views/news/index.vue
@@ -69,11 +69,11 @@
      </div>
      <div class="text-center">{{t('币币交易')}}</div>
    </div>
    <div class="flex-1 flex flex-col items-center" @click="goToPage('/cryptos/perpetualContract/btcusdt?selectIndex=2')">
    <div class="flex-1 flex flex-col items-center" @click="goToPage('/cryptos/perpetualContract/USDSGD?selectIndex=2')">
      <div class="w-40 h-40 rounded-full flex items-center justify-center">
        <img class="w-33 h-33" src="@/assets/c.jpg" draggable="false">
      </div>
      <div class="text-center">{{t('交割合约')}}</div>
      <div class="text-center">{{t('外汇交割')}}</div>
    </div>
    <div class="flex-1 flex flex-col items-center" @click="copyInviteLink">
      <div class="w-40 h-40 rounded-full flex items-center justify-center">