1
admin
2026-01-31 732c30b33f782c2d2ebb62eacda2fb7a453a7ecd
src/page/trading/TradeNew.vue
@@ -1,81 +1,131 @@
<template>
  <div class="trade_new">
    <tab-head></tab-head>
    <tab-head>
      <!-- <van-popover v-model="showPopover" trigger="click" :actions="actions" @select="onSelect" slot="left">
        <template #reference>
          <van-button type="primary">{{ $t("一键平仓") }}</van-button>
        </template>
</van-popover> -->
    </tab-head>
    <div class="order_tabs">
      <van-tabs v-model="active" swipe-threshold="1">
        <van-tab :title="$t('hj160')" name=""></van-tab>
        <van-tab :title="$t('美股指数')" name="US"></van-tab>
        <van-tab :title="$t('hksi')" name="HK"></van-tab>
        <van-tab :title="$t('tsi')" name="TW"></van-tab>
        <van-tab :title="$t('ni')" name="IN"></van-tab>
        <van-tab :title="$t('日股指数')" name="JP"></van-tab>
        <van-tab :title="$t('hj109')" name="GaDan"></van-tab>
        <!-- <van-tab :title="$t('hksi')" name="HK"></van-tab>
        <van-tab :title="$t('tsi')" name="TW"></van-tab> -->
      </van-tabs>
    </div>
    <van-row class="list_head">
      <van-col span="8" class="flex-start head_item">
        {{ $t("hj313") }}/{{ $t("Worth") }}
      </van-col>
      <van-col span="8" class="flex-start head_item">
        {{ $t("sl") }}/{{ $t("Profit") }}
      </van-col>
      <van-col span="8" class="flex-end head_item">
        {{ $t("Cost") }}/{{ $t("Current") }}
      </van-col>
    </van-row>
    <!-- 挂单列表 -->
    <div v-if="active == 'GaDan'">
    <van-row class="list_item" v-for="i in list" :key="i.id" @click="toDetails(i)">
      <van-col span="8" class="item_n">
        <div class="flex-start">
          <span class="i_icon">{{ i.stockGid }}</span>
          <span class="i_hint">{{ i.stockSpell }}</span>
        </div>
        <div class="i_name">
          {{ (i.orderNum * i.now_price).toFixed(2) }}
        </div>
      </van-col>
      <van-col span="8" class="item_n">
        <p class="flex-start">{{ i.orderNum }}</p>
        <p class="flex-start i_name" :style="{
          color:
            i.profitAndLose > 0 ? 'green' : i.profitAndLose < 0 ? 'red' : ''
        }">
          {{ i.profitAndLose }} ({{ i.profitAndLoseParent }})
        </p>
      </van-col>
      <van-col span="8" class="item_n">
        <div class="flex-end" style="margin-bottom: .15em;">
          <span>{{ i.buyOrderPrice }}</span>
        </div>
        <div class="flex-end">
          <span>{{ i.now_price }}</span>
        </div>
      </van-col>
      <van-col span="24" class="flex-start transaction_type">
        <span>{{ types[i.positionType] }}</span>
      </van-col>
      <van-col span="24" class="flex-between-start item_card" v-if="i.positionType == 4">
        <div class="card_label">
          <p>{{ $t("建仓成本") }}</p>
          <p>{{ i.orderTotalPrice }}</p>
        </div>
        <div class="card_label">
          <p>{{ $t("pcje") }}</p>
          <p>{{ i.sellOrderTotalPrice }}</p>
        </div>
        <div class="card_label">
          <p>{{ $t("预期收益") }}</p>
          <p>{{ i.profitAndLose }}</p>
        </div>
      </van-col>
    </van-row>
      <van-row class="list_head">
        <van-col span="14" class="flex-start head_item">
          {{ $t("hj313") }}/{{ $t("Worth") }}
        </van-col>
        <van-col span="3" class="flex-center head_item">
          {{ $t("sl") }}
        </van-col>
        <van-col span="3" class="flex-center head_item">
          {{ $t("Cost") }}
        </van-col>
      </van-row>
      <van-row class="list_item" v-for="i in list" :key="i.id">
        <van-col span="14" class="item_n">
          <div class="flex-start">
            <span class="i_icon">{{ i.stockGid }}</span>
            <span class="i_hint">{{ i.stockName }}</span>
          </div>
          <div class="i_name">
            {{ (i.buyNum * i.targetPrice).toFixed(2) }}
          </div>
        </van-col>
        <van-col span="3" class="item_n">
          <p class="flex-center">{{ i.buyNum }}</p>
        </van-col>
        <van-col span="3" class="item_n">
          <div class="flex-center" style="margin-bottom: .15em;">
            <span>{{ i.targetPrice }}</span>
          </div>
        </van-col>
        <van-col span="4" class="item_n">
          <div class="flex-center delete-btn-wrapper">
            <van-icon name="delete" size="0.5rem" color="#ee0a24" @click.stop="handleDelete(i)" />
          </div>
        </van-col>
      </van-row>
    </div>
    <!-- 正常持仓列表 -->
    <div v-else>
      <van-row class="list_head">
        <van-col span="8" class="flex-start head_item">
          {{ $t("hj313") }}/{{ $t("Worth") }}
        </van-col>
        <van-col span="8" class="flex-start head_item">
          {{ $t("sl") }}/{{ $t("Profit") }}
        </van-col>
        <van-col span="8" class="flex-end head_item">
          {{ $t("Cost") }}/{{ $t("Current") }}
        </van-col>
      </van-row>
      <van-row class="list_item" v-for="i in list" :key="i.id" @click="toDetails(i)">
        <van-col span="8" class="item_n">
          <div class="flex-start">
            <span class="i_icon">{{ i.stockGid }}</span>
            <span class="i_hint">{{ i.stockSpell }}</span>
          </div>
          <div class="i_name">
            {{ (i.orderNum * i.now_price).toFixed(2) }}
          </div>
        </van-col>
        <van-col span="8" class="item_n">
          <p class="flex-start">{{ i.orderNum }}</p>
          <p class="flex-start i_name" :style="{
            color:
              i.profitAndLose > 0 ? 'green' : i.profitAndLose < 0 ? 'red' : ''
          }">
            {{ i.profitAndLose }} ({{ i.profitAndLoseParent }})
          </p>
        </van-col>
        <van-col span="8" class="item_n">
          <div class="flex-end" style="margin-bottom: .15em;">
            <span>{{ i.buyOrderPrice }}</span>
          </div>
          <div class="flex-end">
            <span>{{ i.now_price }}</span>
          </div>
        </van-col>
        <van-col span="24" class="flex-start transaction_type">
          <span>{{ types[i.positionType] }}</span>
        </van-col>
        <van-col span="24" class="flex-between-start item_card" v-if="i.positionType == 4">
          <div class="card_label">
            <p>{{ $t("建仓成本") }}</p>
            <p>{{ i.orderTotalPrice }}</p>
          </div>
          <div class="card_label">
            <p>{{ $t("pcje") }}</p>
            <p>{{ i.sellOrderTotalPrice }}</p>
          </div>
          <div class="card_label">
            <p>{{ $t("预期收益") }}</p>
            <p>{{ i.profitAndLose }}</p>
          </div>
        </van-col>
      </van-row>
    </div>
    <!-- 无数据时显示 -->
    <div class="no_data flex-center" v-show="!list || list.length == 0">
      <img src="@/assets/img/zhaobudao2.png" alt="" />
    </div>
    <n-pagination :pageNo.sync="pageNum" :pageSize="pageSize" :total="total"></n-pagination>
    <n-pagination :pageNo.sync="pageNum" :pageSize="pageSize" :total="currentTotal" v-if="active != 'GaDan'"></n-pagination>
  </div>
</template>
@@ -84,6 +134,7 @@
import tabHead from "@/components/tabHead.vue";
import * as api from "@/axios/api";
import nPagination from "@/components/nPagination.vue";
import { Notify, Dialog } from "vant";
export default {
  components: {
@@ -95,25 +146,60 @@
      pageNum: 1,
      pageSize: 15,
      total: 1,
      list: [],
      // 为每个tab使用独立的list变量
      lists: {
        '': [],      // 默认tab
        'US': [],    // 美股指数
        'JP': [],    // 日股指数
        'GaDan': []  // 挂单
      },
      // 为每个tab使用独立的total变量
      totals: {
        '': 1,
        'US': 1,
        'JP': 1,
        'GaDan': 0
      },
      active: "",
      types: {
        0: this.$t("日内"),
        2: "IPO",
        3: this.$t("hj621"),
        4: "AI"
      }
      },
      actions: [{ text: '确定', key: '1' }, { text: '取消', key: '2' }],
      showPopover: false,
    };
  },
  computed: {
    // 当前tab对应的list
    list() {
      return this.lists[this.active] || [];
    },
    // 当前tab对应的total
    currentTotal() {
      return this.totals[this.active] || 0;
    }
  },
  watch: {
    pageNum() {
      this.getList();
      this.creatTimer();
    },
    active() {
    active(val) {
      this.pageNum = 1;
      this.getList();
      this.creatTimer();
      // 清空当前tab的数据
      if (this.lists[val]) {
        this.lists[val] = [];
      }
      if (val == 'GaDan') {
        this.stopTimer()
        this.getList2();
      }
      else {
        this.getList();
        this.creatTimer();
      }
    }
  },
  created() {
@@ -124,18 +210,35 @@
    this.stopTimer();
  },
  methods: {
    // 获取数据
    // 获取持仓数据
    async getList() {
      const currentActive = this.active;
      let data = await api.getchicang({
        state: 0,
        stockType: this.active,
        stockType: currentActive,
        pageNum: this.pageNum,
        pageSize: this.pageSize
      });
      if (data.status === 0) {
        this.list = data.data.list;
        this.total = data.data.total;
        // 只有当active没有变化时才更新数据,防止数据错乱
        if (this.active === currentActive) {
          this.lists[currentActive] = data.data.list || [];
          this.totals[currentActive] = data.data.total || 0;
          this.total = data.data.total || 0;
        }
      }
    },
    // 获取挂单数据
    async getList2() {
      const currentActive = this.active;
      let data = await api.getGdOrderList();
      if (data.status === 0) {
        // 只有当active没有变化时才更新数据,防止数据错乱
        if (this.active === currentActive && currentActive === 'GaDan') {
          this.lists['GaDan'] = data.data || [];
        }
      }
    },
    // 跳转详情
@@ -158,6 +261,44 @@
      times = setInterval(() => {
        this.getList();
      }, 3000);
    },
    // 一键平仓确认弹框
    onSelect(action) {
      if (action.key == 1) this.oneClose();
    },
    // 一键平仓
    async oneClose() {
      const res = await api.allsell();
      if (res.status === 0) {
        Notify({ type: "success", message: res.msg });
      } else {
        Notify({ type: "danger", message: res.msg });
      }
    },
    // 删除挂单
    handleDelete(item) {
      Dialog.confirm({
        title: this.$t("提示"),
        message: this.$t("确认删除") + "?",
        confirmButtonText: this.$t("qr"),
        cancelButtonText: this.$t("qx")
      }).then(async () => {
        // 用户确认后执行删除
        try {
          const data = await api.delGuaDan({ id: item.id });
          if (data.status === 0) {
            Notify({ type: "success", message: data.msg || this.$t("hj137") });
            // 刷新挂单列表
            this.getList2();
          } else {
            Notify({ type: "danger", message: data.msg || this.$t("获取数据失败") });
          }
        } catch (error) {
          Notify({ type: "danger", message: this.$t("获取数据失败") });
        }
      }).catch(() => {
        // 用户取消,不做任何操作
      });
    }
  }
};
@@ -280,6 +421,16 @@
      }
    }
    .delete-btn-wrapper {
      width: 100%;
      height: 100%;
      cursor: pointer;
      &:hover {
        opacity: 0.8;
      }
    }
    .edit {
      width: 100%;
      height: 100%;