lxf
2025-05-18 4702be083e8b554eb3037f0ecc0b4ba1d04c2406
src/components/trade-head/index.vue
@@ -1,310 +1,366 @@
<template>
    <!-- 永续合约,交割合约公共头部 -->
    <div>
        <div class="contract-header ">
            <div class="pl-30 pr-30">
                <div class="flex justify-between pt-45">
                    <div class="flex">
                        <img v-if="isReturn" :src="require(`@/assets/theme/${theme}/image/icon_back.png`)"
                            class="w-40 h-40 back mr-50" alt=""
                            @click="kineType ? $router.push(`/trade/${symbol}`) : $router.push(`/perpetualContract/${symbol}`)">
                        <img :src="require(`@/assets/theme/${theme}/image/convert.png`)" alt="convert-img" class="w-35 h-35"
                            @click="onSidebar" />
                        <div class="flex flex-col pl-21" @click="onSidebar">
                            <div class="font-35 textColor">{{ symbolname || '--' }}</div>
                        </div>
                        <div v-if="range" class="pl-30" :class="{ 'text-green': range > 0, 'text-red': range <= 0 }">{{
                            range > 0 ? '+' : '' }}{{ range || '--' }}%</div>
                    </div>
                    <div class="flex items-center" v-if="islevel">
                        <img @click="changeModel()" class="w-32 h-35"
                            :src="require(`@/assets/theme/${theme}/image/sun.png`)" alt="" />
                        <img :src="require(`@/assets/image/icon-star${collected === '1' ? '_active' : ''}.png`)"
                            class="w-30 h-30 mr-10 ml-20" @click="onCollect" />
                        <img src="@/assets/image/public/record.png" class="w-32 h-35 ml-20" @click="openRecord()" />
                    </div>
                    <img v-if="isTrade" :src="require(`@/assets/theme/${theme}/image/kline.png`)" class="w-44 h-44 right"
                        alt="" @click="$router.push(`/trendDetails/${symbol}?kineType=trade`)">
                </div>
  <!-- 永续合约,交割合约公共头部 -->
  <div>
    <div class="contract-header">
      <div class="pl-30 pr-30">
        <div class="flex justify-between pt-45">
          <div class="flex">
            <img
              v-if="isReturn"
              :src="require(`@/assets/theme/${theme}/image/icon_back.png`)"
              class="w-40 h-40 back mr-50"
              alt=""
              @click="
                kineType
                  ? $router.push(`/trade/${symbol}`)
                  : $router.push(`/perpetualContract/${symbol}`)
              "
            />
            <img
              :src="require(`@/assets/theme/${theme}/image/convert.png`)"
              alt="convert-img"
              class="w-35 h-35"
              @click="onSidebar"
            />
            <div class="flex flex-col pl-21" @click="onSidebar">
              <div class="font-35 textColor">{{ symbolname || "--" }}</div>
            </div>
            <div
              v-if="range"
              class="pl-30"
              :class="{ 'text-green': range > 0, 'text-red': range <= 0 }"
            >
              {{ range > 0 ? "+" : "" }}{{ range || "--" }}%
            </div>
          </div>
          <div class="flex items-center" v-if="islevel">
            <img
              @click="changeModel()"
              class="w-32 h-35"
              :src="require(`@/assets/theme/${theme}/image/sun.png`)"
              alt=""
            />
            <img
              :src="
                require(`@/assets/image/icon-star${
                  collected === '1' ? '_active' : ''
                }.png`)
              "
              class="w-30 h-30 mr-10 ml-20"
              @click="onCollect"
            />
            <img
              src="@/assets/image/public/record.png"
              class="w-32 h-35 ml-20"
              @click="openRecord()"
            />
          </div>
          <img
            v-if="isTrade"
            :src="require(`@/assets/theme/${theme}/image/kline.png`)"
            class="w-44 h-44 right"
            alt=""
            @click="$router.push(`/trendDetails/${symbol}?kineType=trade`)"
          />
        </div>
        <!-- 左侧边弹出菜单 -->
        <van-popup class="popup" round v-model="show" close-icon-position="top-left" position="left" @closed="onClose">
            <div class="pl-42 pr-40">
                <div class="flex justify-between mb-42 mt-53">
                    <div class="flex items-center text-grey">
                        <div class="mr-12">{{ $t('名称') }}</div>
                    </div>
                    <div class="flex text-grey">
                        <div class="flex items-center">
                            <div>{{ $t('最新价格') }}</div>
                        </div>
                        <div class="flex items-center">
                            <div class="mr-12">/24H{{ $t('涨跌') }}</div>
                        </div>
                    </div>
                </div>
                <div class="flex justify-between mb-50" v-for="item in list" :key="item.name" @click="onRoute(item)">
                    <div>
                        <div class="font-700 textColor">{{ item.name || '--' }}</div>
                        <div v-if="!kineType" class="text-grey mt-10">{{ title }}</div>
                    </div>
                    <div class="text-right">
                        <div class="textColor">{{ item.close || '--' }}</div>
                        <div class="mt-10" :class="item.change_ratio > 0 ? 'text-green' : 'text-red'">
                            {{ item.change_ratio || (item.change_ratio === 0 ? 0 : '--') }}%
                        </div>
                    </div>
                </div>
            </div>
        </van-popup>
      </div>
    </div>
    <!-- 左侧边弹出菜单 -->
    <van-popup
      class="popup"
      round
      v-model="show"
      close-icon-position="top-left"
      position="left"
      @closed="onClose"
    >
      <div class="pl-42 pr-40">
        <div class="flex justify-between mb-42 mt-53">
          <div class="flex items-center text-grey">
            <div class="mr-12">{{ $t("名称") }}</div>
          </div>
          <div class="flex text-grey">
            <div class="flex items-center">
              <div>{{ $t("最新价格") }}</div>
            </div>
            <div class="flex items-center">
              <div class="mr-12">/24H{{ $t("涨跌") }}</div>
            </div>
          </div>
        </div>
        <div
          class="flex justify-between mb-50"
          v-for="item in list"
          :key="item.name"
          @click="onRoute(item)"
        >
          <div>
            <div class="font-700 textColor">{{ item.name || "--" }}</div>
            <div v-if="!kineType" class="text-grey mt-10">{{ title }}</div>
          </div>
          <div class="text-right">
            <div class="textColor">{{ item.close || "--" }}</div>
            <div
              class="mt-10"
              :class="item.change_ratio > 0 ? 'text-green' : 'text-red'"
            >
              {{ item.change_ratio || (item.change_ratio === 0 ? 0 : "--") }}%
            </div>
          </div>
        </div>
      </div>
    </van-popup>
  </div>
</template>
<script>
import { setStorage } from '@/utils/utis'
import { setStorage } from "@/utils/utis";
import { Popup } from "vant";
import { mapGetters, mapMutations } from "vuex";
import { _getHomeList, _collect, _deleteCollect, _checkIsInCollect } from "@/API/home.api";
import {
  _getHomeList,
  _collect,
  _deleteCollect,
  _checkIsInCollect,
} from "@/API/home.api";
export default {
    name: "contractHeader",
    props: {
        tabIndex: {
            type: String,
            default: null
        },
        backFunc: {
            type: Function,
            default: null
        },
        symbol: {
            type: String,
            default: ''
        },
      symbolname: {
          type: String,
          default: '--'
      },
        range: {
            type: String,
            defalult: ''
        },
        islevel: {
            type: Boolean,
            defalult: false
        },
        title: {
            type: String,
            defalult: '--'
        },
        isReturn: {
            type: Boolean,
            defalult: false
        },
        isTrade: {
            type: Boolean,
            defalult: false
        },
        kineType: {
            type: String,
            defalult: ''
        },
  name: "contractHeader",
  props: {
    tabIndex: {
      type: String,
      default: null,
    },
    components: {
        [Popup.name]: Popup,
    backFunc: {
      type: Function,
      default: null,
    },
    computed: {
        ...mapGetters({
            coinList: 'home/coinList',
            theme: 'home/theme'
        }),
    symbol: {
      type: String,
      default: "",
    },
    data() {
        const arr = []
        for (let i = 0; i < 10; i++) {
            arr.push({ id: i })
        }
        return {
            //   selectIndex2:this.selectIndex,
            show: false,
            timeout: null,
            collected: '0',
            // title: '',
            list: arr, //[
            // { name:"BTC/USDT",close:"22042.28",change_ratio:"2.21"},
            // { name:"XTZ/USDT",close:"1.568",change_ratio:"-7.1"},
            // { name:"ADA/USDT",close:"0.493085",change_ratio:"-4.08"},
            //]
        }
    symbolname: {
      type: String,
      default: "--",
    },
    watch: {
        symbol(val) {
            if (this.islevel) {
                this.$emit('changeLine', true)
            }
            if (this.islevel && this.$store.state.user.userInfo.token) {
                let symbol = this.$route.params.symbol;
                _checkIsInCollect(symbol).then(data => {
                    const { status } = data
                    this.collected = status
                })
            }
        }
    range: {
      type: String,
      defalult: "",
    },
    created() {
        // this.coins = this.coinList.map(item => item.symbol)
        // console.log('this.coins', this.coins)
        if (this.islevel && this.$store.state.user.userInfo.token) {
            let symbol = this.$route.params.symbol;
            _checkIsInCollect(symbol).then(data => {
                const { status } = data
                this.collected = status
            })
        }
    islevel: {
      type: Boolean,
      defalult: false,
    },
    methods: {
        ...mapMutations('home', ['SET_THEME']),
        onRoute(item) {
         setStorage('symbolname', item.name)
            if (this.islevel) {
                if (this.$route.params.symbol !== item.symbol) {
                    this.$router.push(`/trendDetails/${item.symbol}`)
                    if (this.kineType) {
                        setStorage('tradeSymbol', item.symbol)
                    } else {
                        setStorage('symbol', item.symbol)
                    }
                    this.$emit('update-coin', item.symbol)
                    this.onClose()
                    this.$forceUpdate()
                }
            } else {
                if (this.$route.params.symbol !== item.symbol) {
                    // this.$router.push(`/trade/${item.symbol}`)
               this.$router.push({
                 path: `/trade/${item.symbol}`,
                 query: { name: item.name }
               });
                    setStorage('tradeSymbol', item.symbol)
               setStorage('symbolname', item.name)
                    this.$emit('update-coin', item.symbol)
                    this.$forceUpdate()
                }
            }
            this.show = false
        },
        onSidebar() { // 侧边栏打开
            console.log(this.userInfo)
            this.coins = this.coinList.map(item => item.symbol)
            this.show = true
            this.fetchList()
        },
        fetchList() { // 获取行情
            _getHomeList(this.coins.join(',')).then(list => {
                // console.log(list)
                this.list = list
                if (this.timeout) {
                    clearTimeout(this.timeout)
                    this.timeout = null
                }
                this.timeout = setTimeout(() => {
                    this.fetchList()
                }, 1000)
            })
        },
        onClose() {
            if (this.timeout) {
                clearTimeout(this.timeout)
                this.timeout = null
            }
        },
        jump() {
            this.$router.push(`/trendDetails/${this.symbol}`)
        },
        changeTab(index) {
            this.$emit('tab', index)
            // this.selectIndex2 = index;
        },
        goBack() {
            if (this.backFunc) {
                this.backFunc()
            } else {
                this.$router.go(-1);
            }
        },
        goRouter(params) {
            this.$router.push(params);
        },
        onCollect() { // 收藏,取消收藏
            let _api = _collect
            if (this.collected === '1') {
                _api = _deleteCollect
            }
            _api(this.symbol).then((res) => {
                if (this.$store.state.user.userInfo.token) {
                    this.collected = this.collected === '1' ? '0' : '1'
                    if (this.collected === '1') {
                        this.$toast.success(this.$t('收藏成功'))
                    } else {
                        this.$toast.success(this.$t('取消收藏'))
                    }
                }
            })
        },
        goHistory() {
            const url = ((this.tabIndex * 1) == 1) ? 'perpetualHistory' : 'deliveryContractHistory'
            this.$router.push({
                path: `/${url}?symbol=${this.symbol}`
            });
        },
        changeModel() {
            let type = ''
            if (this.theme == 'light') {
                type = 'dark'
            } else {
                type = 'light'
            }
            this.SET_THEME(type)
        },
        //打开订单
        openRecord() {
            this.$emit('openRecord')
        }
    title: {
      type: String,
      defalult: "--",
    },
    isReturn: {
      type: Boolean,
      defalult: false,
    },
    isTrade: {
      type: Boolean,
      defalult: false,
    },
    kineType: {
      type: String,
      defalult: "",
    },
  },
  components: {
    [Popup.name]: Popup,
  },
  computed: {
    ...mapGetters({
      coinList: "home/coinList",
      theme: "home/theme",
    }),
  },
  data() {
    const arr = [];
    for (let i = 0; i < 10; i++) {
      arr.push({ id: i });
    }
}
    return {
      //   selectIndex2:this.selectIndex,
      show: false,
      timeout: null,
      collected: "0",
      // title: '',
      list: arr, //[
      // { name:"BTC/USDT",close:"22042.28",change_ratio:"2.21"},
      // { name:"XTZ/USDT",close:"1.568",change_ratio:"-7.1"},
      // { name:"ADA/USDT",close:"0.493085",change_ratio:"-4.08"},
      //]
    };
  },
  watch: {
    symbol(val) {
      if (this.islevel) {
        this.$emit("changeLine", true);
      }
      if (this.islevel && this.$store.state.user.userInfo.token) {
        let symbol = this.$route.params.symbol;
        _checkIsInCollect(symbol).then((data) => {
          const { status } = data;
          this.collected = status;
        });
      }
    },
  },
  created() {
    // this.coins = this.coinList.map(item => item.symbol)
    // console.log('this.coins', this.coins)
    if (this.islevel && this.$store.state.user.userInfo.token) {
      let symbol = this.$route.params.symbol;
      _checkIsInCollect(symbol).then((data) => {
        const { status } = data;
        this.collected = status;
      });
    }
  },
  methods: {
    ...mapMutations("home", ["SET_THEME"]),
    onRoute(item) {
      setStorage("symbolname", item.name);
      if (this.islevel) {
        if (this.$route.params.symbol !== item.symbol) {
          this.$router.push(`/trendDetails/${item.symbol}`);
          if (this.kineType) {
            setStorage("symbol", item.symbol);
          } else {
            setStorage("symbol", item.symbol);
          }
          this.$emit("update-coin", item.symbol);
          this.onClose();
          this.$forceUpdate();
        }
      } else {
        if (this.$route.params.symbol !== item.symbol) {
          // this.$router.push(`/trade/${item.symbol}`)
          this.$router.push({
            path: `/trade/${item.symbol}`,
            query: { name: item.name },
          });
          setStorage("symbol", item.symbol);
          setStorage("symbolname", item.name);
          this.$emit("update-coin", item.symbol);
          this.$forceUpdate();
        }
      }
      this.show = false;
    },
    onSidebar() {
      // 侧边栏打开
      console.log(this.userInfo);
      this.coins = this.coinList.map((item) => item.symbol);
      this.show = true;
      this.fetchList();
    },
    fetchList() {
      // 获取行情
      _getHomeList(this.coins.join(",")).then((list) => {
        // console.log(list)
        this.list = list;
        if (this.timeout) {
          clearTimeout(this.timeout);
          this.timeout = null;
        }
        this.timeout = setTimeout(() => {
          this.fetchList();
        }, 1000);
      });
    },
    onClose() {
      if (this.timeout) {
        clearTimeout(this.timeout);
        this.timeout = null;
      }
    },
    jump() {
      this.$router.push(`/trendDetails/${this.symbol}`);
    },
    changeTab(index) {
      this.$emit("tab", index);
      // this.selectIndex2 = index;
    },
    goBack() {
      if (this.backFunc) {
        this.backFunc();
      } else {
        this.$router.go(-1);
      }
    },
    goRouter(params) {
      this.$router.push(params);
    },
    onCollect() {
      // 收藏,取消收藏
      let _api = _collect;
      if (this.collected === "1") {
        _api = _deleteCollect;
      }
      _api(this.symbol).then((res) => {
        if (this.$store.state.user.userInfo.token) {
          this.collected = this.collected === "1" ? "0" : "1";
          if (this.collected === "1") {
            this.$toast.success(this.$t("收藏成功"));
          } else {
            this.$toast.success(this.$t("取消收藏"));
          }
        }
      });
    },
    goHistory() {
      const url =
        this.tabIndex * 1 == 1 ? "perpetualHistory" : "deliveryContractHistory";
      this.$router.push({
        path: `/${url}?symbol=${this.symbol}`,
      });
    },
    changeModel() {
      let type = "";
      if (this.theme == "light") {
        type = "dark";
      } else {
        type = "light";
      }
      this.SET_THEME(type);
    },
    //打开订单
    openRecord() {
      this.$emit("openRecord");
    },
  },
};
</script>
<style lang="scss" scoped>
// .contract-header{
//     background-color:#F5F5F5;
// }
.wallet-background {
    background-color: #E8E8E8;
  background-color: #e8e8e8;
}
.no-select {
    background-color: #e8e8e8;
    color: #868D9A;
  background-color: #e8e8e8;
  color: #868d9a;
}
// 弹出层样式
.popup {
    height: 100%;
    width: 670px;
  height: 100%;
  width: 670px;
    @include themify() {
        background: themed("main_background");
    }
  @include themify() {
    background: themed("main_background");
  }
}
.night {
    color: #fff;
  color: #fff;
}
</style>