0510航天交易所ui仿制,代码使用的jiem
lxf
2025-06-21 6234b223acd62ffb719f29fe52067c5d1cadb1f7
6.21修改
4 files modified
439 ■■■■■ changed files
src/components/ex-nav/index.vue 1 ●●●● patch | view | raw | blame | history
src/components/perpetual-position-list/index.vue 5 ●●●●● patch | view | raw | blame | history
src/i18n/en-US/index.js 11 ●●●● patch | view | raw | blame | history
src/page/deliveryContract/hold.vue 422 ●●●● patch | view | raw | blame | history
src/components/ex-nav/index.vue
@@ -236,6 +236,7 @@
  color: #606664;
  line-height: 1.25rem;
  text-align: center;
  height: 4rem;
}
.nav_txt.nav_txt2 {
  font-size: 2.1rem;
src/components/perpetual-position-list/index.vue
@@ -28,8 +28,9 @@
                >{{ item.name }} {{ $t("永续") }}</span
              >
              <span class="text-grey font-28 font-400 ml-17 mr-17"
                >{{ $t("全仓") }} {{ item.lever_rate }}x</span
              >
                >{{ $t("全仓") }}
                <!-- {{ item.lever_rate }}x -->
              </span>
            </div>
            <img
              v-if="item.direction == 'buy'"
src/i18n/en-US/index.js
@@ -86,7 +86,12 @@
  '在线出售广告': `Sell Ads Online`,
  '在线广告': `Online advertising`,
  '更多数据': `More data`,
  '高级认证': `Advanced Certification`,
  '高级认证': `Entry-level certification`,
  '个人头像': 'Profile picture',
  '提币地址管理': 'Withdrawal address management',
  '登录密码': 'Login password',
  '修改': 'Modify',
  '已绑定': 'Bound',
  '身份': `Identity`,
  '手机': `Cell phone`,
  '30日成单数': `30 days into the number of singles`,
@@ -689,8 +694,8 @@
  '认证中心': 'Certification Center',
  '个人中心': 'Personal center',
  '查看当前功能': 'View current features',
  '进阶认证': 'Advanced Certification',
  '公证认证': 'Notary certification',
  '进阶认证': 'Entry-level certification',
  '公证认证': 'Advanced Certification',
  '要求': 'Require',
  '个人信息': 'Personal information',
  '政府发行的身份证': 'Government-issued ID',
src/page/deliveryContract/hold.vue
@@ -1,217 +1,255 @@
<template>
    <!-- 持有仓位列表 -->
    <div>
        <!--        <div class="flex justify-between" v-if="listData.length">-->
        <!--            <div class="flex" @click.stop="changeIcon">-->
        <!--                <img v-show="!iconShow" src="../../assets/image/public/grey-rounded.png" alt="" class="w-38 h-38"/>-->
        <!--                <img v-show="iconShow" src="../../assets/image/public/blue-rounded.png" alt="" class="w-38 h-38"/>-->
        <!--                <div class="ml-37">{{ $t('隐藏其它合约') }}</div>-->
        <!--            </div>-->
        <!--        </div>-->
        <div class="" v-for="item in listData" :key="item.order_no">
            <div class="flex justify-between pt-44 pb-44">
                <div class="flex flex-col">
                    <div class="flex items-center">
                        <div class="pl-10 pr-11 pt-5 pb-5 text-white open-btn"
                            :class="item.direction == 'buy' ? ' bg-green' : 'bg-red'">
                            {{ item.direction == 'buy' ? $t('开多') : $t('开空') }}
                        </div>
                        <div class="ml-22 font-31 font-600">
                            <span class="textColor">{{ item.name }} {{ $t('交割') }}</span>
                            <span class="text-grey font-28 font-400 ml-17 mr-17">{{ $t('全仓') }} {{ item.lever_rate
                            }}x</span>
                        </div>
                        <img v-if="item.direction == 'buy'" src="../../assets/image/public/green-leverage.png" alt=""
                            class="w-32 h-32" />
                        <img v-else src="../../assets/image/public/red-leverage.png" alt="" class="w-32 h-32" />
                    </div>
                </div>
  <!-- 持有仓位列表 -->
  <div>
    <!--        <div class="flex justify-between" v-if="listData.length">-->
    <!--            <div class="flex" @click.stop="changeIcon">-->
    <!--                <img v-show="!iconShow" src="../../assets/image/public/grey-rounded.png" alt="" class="w-38 h-38"/>-->
    <!--                <img v-show="iconShow" src="../../assets/image/public/blue-rounded.png" alt="" class="w-38 h-38"/>-->
    <!--                <div class="ml-37">{{ $t('隐藏其它合约') }}</div>-->
    <!--            </div>-->
    <!--        </div>-->
    <div class="" v-for="item in listData" :key="item.order_no">
      <div class="flex justify-between pt-44 pb-44">
        <div class="flex flex-col">
          <div class="flex items-center">
            <div
              class="pl-10 pr-11 pt-5 pb-5 text-white open-btn"
              :class="item.direction == 'buy' ? ' bg-green' : 'bg-red'"
            >
              {{ item.direction == "buy" ? $t("开多") : $t("开空") }}
            </div>
            <div class="flex justify-between">
                <div class="fexl-1">
                    <div class="text-grey">{{ $t('购买价') }}(USDT)</div>
                    <div class="mt-20 textColor">{{ item.open_price }}</div>
                </div>
                <div>
                    <div class="text-grey text-right">{{ $t('现价') }}</div>
                    <div class="mt-20 text-right" :class="item.close_price > item.open_price ? 'text-green' : 'text-red'">
                        <!-- {{ item.close_price }} -->
                        {{newprice}}
                        </div>
                </div>
            <div class="ml-22 font-31 font-600">
              <span class="textColor">{{ item.name }} {{ $t("交割") }}</span>
              <span class="text-grey font-28 font-400 ml-17 mr-17"
                >{{ $t("全仓") }} {{ item.lever_rate }}x</span
              >
            </div>
            <div class="flex pt-40 pb-40">
                <div class="flex-1">
                    <div class="text-grey">{{ $t('方向') }}</div>
                    <div class="mt-20" :class="item.direction === 'buy' ? 'text-green' : 'text-red'">{{ item.direction ===
                        'buy' ? $t('开多') : $t('开空') }}</div>
                </div>
                <div class="flex-1">
                    <div class="text-grey text-center">{{ $t('数量') }}</div>
                    <div class="mt-20 text-center textColor">{{ item.volume }}</div>
                </div>
                <div class="flex-1 flex flex-col items-end">
                    <div class="text-grey">{{ $t('盈亏') }}</div>
                    <div class="mt-20" :class="item.profit / 1 > 0 ? 'text-green' : 'text-red'">
                        {{ item.profit / 1 > 0 ? '+' + item.profit : item.profit }}
                    </div>
                </div>
            </div>
            <div class="flex pb-32">
                <div class="flex-1">
                    <div class="text-grey">{{ $t('剩余时间') }}</div>
                    <div class="mt-20 textColor">{{ fomatTime(item.remain_time) }}</div>
                </div>
                <div class="flex-1">
                    <div class="text-grey  text-center">{{ $t('交割时间') }}</div>
                    <div class="mt-20  text-center textColor">{{ item.time_num + item.time_unit }}</div>
                </div>
                <div class="flex-1">
                    <div class="text-grey text-right">{{ $t('操作') }}</div>
                    <div class="mt-20 colorMain text-right" @click="goDetail(item)">{{ $t('详情') }}</div>
                </div>
            </div>
            <div class="w-full h-1 bgDark"></div>
            <img
              v-if="item.direction == 'buy'"
              src="../../assets/image/public/green-leverage.png"
              alt=""
              class="w-32 h-32"
            />
            <img
              v-else
              src="../../assets/image/public/red-leverage.png"
              alt=""
              class="w-32 h-32"
            />
          </div>
        </div>
        <div class="text-grey text-center py-300" v-if="!listData.length && $route.name == 'perpetualContract'">{{
            $t('您目前没有持仓') }}</div>
        <van-popup v-model="show">
            <popup-delivery :showBtns="true" :price="price" :detailData="detailData" :key="detailData.order_no"
                @close="onClose" :symbol="symbol" />
        </van-popup>
      </div>
      <div class="flex justify-between">
        <div class="fexl-1">
          <div class="text-grey">{{ $t("购买价") }}(USDT)</div>
          <div class="mt-20 textColor">{{ item.open_price }}</div>
        </div>
        <div>
          <div class="text-grey text-right">{{ $t("现价") }}</div>
          <div
            class="mt-20 text-right"
            :class="
              item.close_price > item.open_price ? 'text-green' : 'text-red'
            "
          >
            <!-- {{ item.close_price }} -->
            {{ newprice }}
          </div>
        </div>
      </div>
      <div class="flex pt-40 pb-40">
        <div class="flex-1">
          <div class="text-grey">{{ $t("方向") }}</div>
          <div
            class="mt-20"
            :class="item.direction === 'buy' ? 'text-green' : 'text-red'"
          >
            {{ item.direction === "buy" ? $t("开多") : $t("开空") }}
          </div>
        </div>
        <div class="flex-1">
          <div class="text-grey text-center">{{ $t("数量") }}</div>
          <div class="mt-20 text-center textColor">{{ item.volume }}</div>
        </div>
        <div class="flex-1 flex flex-col items-end">
          <div class="text-grey">{{ $t("盈亏") }}</div>
          <div
            class="mt-20"
            :class="item.profit / 1 > 0 ? 'text-green' : 'text-red'"
          >
            {{ item.profit / 1 > 0 ? "+" + item.profit : item.profit }}
          </div>
        </div>
      </div>
      <div class="flex pb-32">
        <div class="flex-1">
          <div class="text-grey">{{ $t("剩余时间") }}</div>
          <div class="mt-20 textColor">{{ fomatTime(item.remain_time) }}</div>
        </div>
        <div class="flex-1">
          <div class="text-grey text-center">{{ $t("交割时间") }}</div>
          <div class="mt-20 text-center textColor">
            {{ item.time_num + item.time_unit }}
          </div>
        </div>
        <div class="flex-1">
          <div class="text-grey text-right">{{ $t("操作") }}</div>
          <div class="mt-20 colorMain text-right" @click="goDetail(item)">
            {{ $t("详情") }}
          </div>
        </div>
      </div>
      <div class="w-full h-1 bgDark"></div>
    </div>
    <div
      class="text-grey text-center py-300"
      v-if="!listData.length && $route.name == 'perpetualContract'"
    >
      {{ $t("您目前没有持仓") }}
    </div>
    <van-popup v-model="show">
      <popup-delivery
        :showBtns="true"
        :price="price"
        :detailData="detailData"
        :key="detailData.order_no"
        @close="onClose"
        :symbol="symbol"
      />
    </van-popup>
  </div>
</template>
<script>
import PopupDelivery from '@/components/popup-delivery'
import { WS_URL } from '@/config'
import { Popup } from 'vant';
import PopupDelivery from "@/components/popup-delivery";
import { WS_URL } from "@/config";
import { Popup } from "vant";
import { _futrueOrderDetail } from "@/API/trade.api";
export default {
    name: "deliveryHoldList",
    data() {
        return {
            sockets: {
                quotes: null, // 行情
                deep: null /// 深度
            },
            show: false,
            newprice:"",
            iconShow: false,
            detailData: {},
  name: "deliveryHoldList",
  data() {
    return {
      sockets: {
        quotes: null, // 行情
        deep: null, /// 深度
      },
      show: false,
      newprice: "",
      iconShow: false,
      detailData: {},
    };
  },
  components: {
    [Popup.name]: Popup,
    PopupDelivery,
  },
  props: {
    listData: {
      type: Array,
      default() {
        return [];
      },
    },
    symbol: {
      type: String,
      default: "",
    },
    price: {
      type: [Number, String],
      default: "0.00",
    },
  },
  deactivated() {
    this.closeSocket();
  },
  mounted() {
    this.fetchDeepData();
  },
  methods: {
    closeSocket() {
      this.sockets.deep.close();
      // this.sockets.quotes && this.sockets.quotes.close()
      // this.sockets.deep && this.sockets.deep.close()
      this.sockets.quotes = null;
      this.sockets.deep = null;
    },
    fetchDeepData() {
      this.startDeepSocket(); // socket
    },
    startDeepSocket() {
      this.sockets.deep = new WebSocket(`${WS_URL}/3/${this.symbol}`);
      this.sockets.deep.onmessage = (evt) => {
        const { data } = evt;
        const { code, data: _data } = JSON.parse(data);
        // console.log(_data.bids[0].price);
        this.newprice = _data.asks[0].price;
      };
    },
    clearTimeout() {
      clearTimeout(this.timeout);
      this.timeout = null;
    },
    //合约时间结束后显示详情
    handleTimeEnd(order) {
      _futrueOrderDetail(order).then((data) => {
        this.clearTimeout();
        this.detailData = data;
        if (data.state !== "created") {
          this.timeout = setTimeout(() => {
            this.handleTimeEnd(order);
          }, 1000);
        }
      });
    },
    components: {
        [Popup.name]: Popup,
        PopupDelivery
    fomatTime(time) {
      let arr = time.split(":");
      let day = Math.floor(arr[0] / 24);
      let hour = arr[0] % 24 >= 10 ? arr[0] % 24 : "0" + (arr[0] % 24);
      console.log(hour);
      let min = arr[1] >= 10 ? arr[1] : "0" + arr[1];
      let sec = arr[2] >= 10 ? arr[2] : "0" + arr[2];
      if (day >= 1) {
        return day + this.$t("天") + " " + hour + ":" + min + ":" + sec;
      } else {
        return hour + ":" + min + ":" + sec;
      }
    },
    props: {
        listData: {
            type: Array,
            default() {
                return []
            }
        },
        symbol: {
            type: String,
            default: ''
        },
        price: {
            type: [Number, String],
            default: '0.00'
        },
    changeIcon() {
      this.iconShow = !this.iconShow;
    },
    deactivated(){
          this.closeSocket()
    },
    mounted (){
          this.fetchDeepData()
    },
    methods: {
        closeSocket() {
                  this.sockets.deep.close()
            // this.sockets.quotes && this.sockets.quotes.close()
            // this.sockets.deep && this.sockets.deep.close()
            this.sockets.quotes = null
            this.sockets.deep = null
        },
        fetchDeepData() {
                this.startDeepSocket() // socket
        },
        startDeepSocket() {
            this.sockets.deep = new WebSocket(`${WS_URL}/3/${this.symbol}`)
            this.sockets.deep.onmessage = (evt) => {
                const { data } = evt
                const { code, data: _data } = JSON.parse(data)
                    // console.log(_data.bids[0].price);
                    this.newprice = _data.asks[0].price
            }
        },
        clearTimeout() {
            clearTimeout(this.timeout)
            this.timeout = null
        },
        //合约时间结束后显示详情
        handleTimeEnd(order) {
            _futrueOrderDetail(order).then(data => {
                this.clearTimeout()
                this.detailData = data
                if (data.state !== 'created') {
                    this.timeout = setTimeout(() => {
                        this.handleTimeEnd(order)
                    }, 1000)
                }
            })
        },
        fomatTime(time) {
            let arr = time.split(':')
            let day = Math.floor(arr[0] / 24)
            let hour = arr[0] % 24 >= 10 ? arr[0] % 24 : '0' + arr[0] % 24
            console.log(hour)
            let min = arr[1] >= 10 ? arr[1] : '0' + arr[1]
            let sec = arr[2] >= 10 ? arr[2] : '0' + arr[2]
            if (day >= 1) {
                return day + this.$t('天') + ' ' + hour + ':' + min + ':' + sec
            } else {
                return hour + ':' + min + ':' + sec
            }
        },
        changeIcon() {
            this.iconShow = !this.iconShow;
        },
        goDetail(item) {
            this.detailData = item
            this.show = true
            // 当前数据是定时轮询地数据, 不必拿最新地数据了
            // _futrueOrderDetail(item.order_no).then(data => {
            //     this.detailData = data
            //      this.show = true
            // })
            // this.$router.push({
            //     path:"/orderDetail?order_no=" + item.order_no
            // });
        },
        onClose() { // 关闭
            this.show = false
        }
    }
}
    goDetail(item) {
      this.detailData = item;
      this.show = true;
      // 当前数据是定时轮询地数据, 不必拿最新地数据了
      // _futrueOrderDetail(item.order_no).then(data => {
      //     this.detailData = data
      //      this.show = true
      // })
      // this.$router.push({
      //     path:"/orderDetail?order_no=" + item.order_no
      // });
    },
    onClose() {
      // 关闭
      this.show = false;
    },
  },
};
</script>
<style lang="scss" scoped>
.border-b-color {
    @include themify() {
        border-bottom: 1px solid themed("border_color");
    }
  @include themify() {
    border-bottom: 1px solid themed("border_color");
  }
}
::v-deep .van-popup {
    @include themify() {
        background: themed("input_background1");
    }
  @include themify() {
    background: themed("input_background1");
  }
}
.open-btn {
    border-radius: 10px;
  border-radius: 10px;
}
</style>