Переглянути джерело

Merge branch 'mtp_v6' of http://47.101.159.18:3000/Muchinfo/MTP2.0_WEB into mtp_v6

li.shaoyi 3 роки тому
батько
коміт
2b00ace0db

+ 7 - 1
src/common/components/firstMenu/index.vue

@@ -1,6 +1,12 @@
 <template>
     <div class="first-menu">
-        <a-menu class="a-menu_container" theme="dark" v-model:selectedKeys="current" @click="menuClick" mode="horizontal">
+        <a-menu
+            class="a-menu_container"
+            theme="dark"
+            v-model:selectedKeys="current"
+            @click="menuClick"
+            mode="horizontal"
+        >
             <a-menu-item :key="String(index)" v-for="(item, index) in list">{{ item[value] }}</a-menu-item>
         </a-menu>
         <div class="menu_right">

+ 15 - 1
src/common/constants/enumCommon.ts

@@ -121,6 +121,20 @@ export enum TradeMode {
     quote99 = 99,
 }
 
+// 仓单类型
+export enum AuctionwrType {
+    noWr = 1, // 无仓单
+    hasWr = 2, // 有仓单
+    noLimite = 3, // 有无仓单均可
+}
+//挂牌方式 1:一口价 2:浮动价 3:贸易圈 4:协议指定
+export enum ListingMode {
+    fix = 1,  // 一口价
+    float = 2, // 浮动价
+    blocs = 3, // 贸易圈
+    designate = 4, // 协议指定
+}
+
 // 协议类型
 export enum AgreementType {
     register = 1,   // 注册
@@ -142,4 +156,4 @@ export enum UserType {
 export enum ApplyType {
     my = 1, // 我的申请
     counterpart, // 对方申请
-}
+}

+ 38 - 3
src/common/setup/table/tableQuote.ts

@@ -1,8 +1,9 @@
+import { getGoodsDecimalplaceByGoodsCode, getQuoteDayInfoByCode } from '@/services/bus/goods';
 import { QueryQuoteDayRsp } from '@/services/go/quote/interface';
 import { addSubscribeQuotation, removeSubscribeQuotation } from '@/services/socket/quota';
 import TimerUtils from '@/utils/timer/timerUtil';
 import { v4 } from 'uuid';
-import { onBeforeUnmount, onMounted, Ref, ref, watchEffect, nextTick } from "vue";
+import { nextTick, onBeforeUnmount, onMounted, Ref, ref, watchEffect } from "vue";
 
 /**
  * 订阅商品行情
@@ -225,7 +226,21 @@ export function handleQuotePriceColor(value: number, presettle: number) {
     }
     return result
 }
+// 外部行情 获取某个值
+export function getQuoteValue_out(goodscode: string, val: keyof QueryQuoteDayRsp) {
+    const obj = getQuoteDayInfoByCode(goodscode)
+    return obj ? obj[val] : '--'
+}
 
+// 外部行情  处理行情价格颜色
+export function handleQuotePriceColor_out(goodscode: string, val: keyof QueryQuoteDayRsp) {
+    const obj = getQuoteDayInfoByCode(goodscode)
+    let result = ''
+    if (obj) {
+        result = handleQuotePriceColor(obj[val] as number, obj.presettle)
+    }
+    return result
+}
 // 涨跌额/涨跌 最新价 - 昨结价
 export function quoteChange<T>(record: T, decimalplace = 2) {
     type Key = keyof T;
@@ -255,7 +270,26 @@ export function quoteAmplitude<T>(record: T, decimalplace = 2) {
     }
     return '--';
 }
-
+// 外部行情 幅度(最新价 - 昨结价) / 昨结价) *  100 %
+export function quoteAmplitude_out(goodscode: string) {
+    const obj = getQuoteDayInfoByCode(goodscode)
+    let result = '--'
+    // const decimalplace = getGoodsDecimalplaceByGoodsCode(goodscode)
+    if (obj) {
+        result = quoteAmplitude(obj, 2)
+    }
+    return result
+}
+// 外部行情 涨跌 最新价 - 昨结价
+export function quoteChange_out(goodscode: string) {
+    const obj = getQuoteDayInfoByCode(goodscode)
+    let result = '--'
+    const decimalplace = getGoodsDecimalplaceByGoodsCode(goodscode)
+    if (obj) {
+        result = quoteChange(obj, decimalplace)
+    }
+    return result
+}
 // 振幅 (最高价 - 最低价 ) / 最新价  * 100 %
 export function quoteAmplituOfVibration(record: QueryQuoteDayRsp, decimalplace = 2) {
     const { highest, lowest, last } = record
@@ -271,4 +305,5 @@ export function quoteAmplituOfVibration(record: QueryQuoteDayRsp, decimalplace =
 // 处理 空值  或者 0的时候,显示 --  的情况,
 export function handleNoneValue(value: number | string) {
     return value ? value : '--'
-}
+}
+

+ 3 - 3
src/layout/components/menu.vue

@@ -104,10 +104,10 @@ export default defineComponent({
           secondeIndex = 0;
         for (let i = 0; i < list.length; i++) {
           for (let j = 0; j < list[i].children.length; j++) {
-            if (matched[1].name === 'dymanicMarket') {
+            debugger
+            if (matched[1].name === 'marketSpot') {
               // 处理动态市场 刷新问题
-              const code = 'market-' + route.query.id
-              if (code === list[i].children[j].code) {
+              if (list[i].children[j].code === 'market_spot') {
                 firstIndex = i;
                 secondeIndex = j;
                 break

+ 14 - 16
src/layout/components/top.vue

@@ -16,17 +16,17 @@
   </a-layout>
 </template>
 <script lang="ts">
-import { defineComponent, ref, provide } from 'vue';
-
 import CapitalInfo from '@/common/components/capitalInfo/index.vue';
+import Drawer from '@/common/components/drawer/index.vue';
 import SecondMenu from '@/common/components/secondeMenu/index.vue';
+import { getHasBottom } from '@/common/setup/order/orderData';
+import { OperationTabMenu } from '@/services/go/commonService/interface';
+import { defineComponent, provide, ref } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
-import Drawer from '@/common/components/drawer/index.vue';
 import Header from './header.vue';
-import Menu from './menu.vue';
 import Main from './main.vue';
-import { OperationTabMenu } from '@/services/go/commonService/interface';
-import { getHasBottom } from '@/common/setup/order/orderData';
+import Menu from './menu.vue';
+
 
 export default defineComponent({
   name: 'layout-top',
@@ -65,15 +65,14 @@ export default defineComponent({
 
       if (temp === 'home') {
         // 第一次进入项目
-        if (value?.children.length) {
+        if (value?.code === 'market_spot') {
+          // 现货市场
+          router.push({ name: 'marketSpot' });
+          return
+        } else if (value?.children.length) {
           // 默认第一个tab页
           name = value.children[0].code;
           index.value = ['0'];
-        } else if (value?.code.includes('market-')) {
-          // 动态市场
-          const param = value.code.split('-')
-          router.push({ name: 'dymanicMarket', query: { id: param[1] } });
-          return
         } else {
           router.push({ name: '404' });
           return;
@@ -82,10 +81,9 @@ export default defineComponent({
         // 这里处理页面刷新,还原 导航栏数据
         const i = value.children.findIndex((e) => e.code === temp);
         if (i === -1) {
-          if (value?.code.includes('market-')) {
-            // 动态市场
-            const param = value.code.split('-')
-            router.push({ name: 'dymanicMarket', query: { id: param[1] } });
+          if (value?.code === 'market_spot') {
+            // 现货市场
+            router.push({ name: 'marketSpot' });
             return
           } else if (value?.children.length) {
             // 切换左边菜单栏

+ 4 - 4
src/router/index.ts

@@ -38,10 +38,10 @@ const routes: Array<RouteRecordRaw> = [
                 component: () => import('@/views/home.vue'),
             },
             {
-                path: '/dymanicMarket/',
-                name: 'dymanicMarket',
-                component: () => import('@/views/market/index.vue'),
-                props: route => ({ id: route.query.id })
+                path: '/market-spot/',
+                name: 'marketSpot',
+                component: () => import('@/views/market/market-spot/index.vue'),
+                // props: route => ({ id: route.query.id })
             },
         ],
     },

+ 6 - 0
src/services/bus/goods.ts

@@ -209,4 +209,10 @@ export function getGoodsQuoteList(exchangeId?: number): GoodsQuote[] {
         }
         return item;
     })
+}
+
+// 通过 goodscode 获取商品小数位
+export function getGoodsDecimalplaceByGoodsCode(goodscode: string) {
+    const obj = getGoodsByCode(goodscode)
+    return obj ? obj.decimalplace : 1
 }

+ 1 - 2
src/services/bus/index.ts

@@ -40,8 +40,7 @@ export async function globalDataRefresh(): Promise<string> {
                 // token校验成功 马上轮询
                 checkTokenLoop();
                 await LoginQuery()
-                await Promise.all([GetErmcpGoods(), GetPCMenus(), QueryTableDefine(), QueryDeliveryGoodsDetail(), getTaAccount(), queryMarketRun()])
-                await queryTjmdMarketSection()
+                await Promise.all([GetErmcpGoods(), GetPCMenus(), QueryTableDefine(), QueryDeliveryGoodsDetail(), getTaAccount(), queryMarketRun(), queryTjmdMarketSection()])
                 const marketInfo = getMarketByTradeMode(TradeMode.WarehouseReceiptTrade);
                 if (marketInfo) {
                     await queryWrMarketTradeConfig({ marketid: marketInfo.marketid })

+ 1 - 2
src/services/bus/login.ts

@@ -29,8 +29,7 @@ export const login = async (logidCode: string, password: string, byteArr: Uint8A
         // localstorage 缓存登录信息,处理页面刷新
         setLoginData(loginData);
         await LoginQuery()
-        await Promise.all([GetErmcpGoods(), GetPCMenus(), QueryTableDefine(), getServerTime(), QueryDeliveryGoodsDetail(), getTaAccount(), queryMarketRun()])
-        await queryTjmdMarketSection()
+        await Promise.all([GetErmcpGoods(), GetPCMenus(), QueryTableDefine(), getServerTime(), QueryDeliveryGoodsDetail(), getTaAccount(), queryMarketRun(), queryTjmdMarketSection()])
         const marketInfo = getMarketByTradeMode(TradeMode.WarehouseReceiptTrade);
         if (marketInfo) {
             await queryWrMarketTradeConfig({ marketid: marketInfo.marketid })

+ 0 - 53
src/services/go/Tjmd/index.ts

@@ -1,7 +1,5 @@
 import APP from '@/services';
 import { commonSearch_go } from "@/services/go";
-import { localStorageUtil } from '@/utils/storage';
-import { OperationTabMenu } from '../commonService/interface';
 import * as type from './interface';
 
 /**
@@ -40,64 +38,13 @@ export function queryTjmdTransferApply(req: type.QueryTjmdTransferApplyReq): Pro
     });
 }
 
-function addMarketToMenu(markets: type.TjmdMarketSection[]) {
-    // 菜单JSON配置数据
-    const menus = localStorageUtil.getItem('menus')
-    const list = (menus ? menus : []) as OperationTabMenu[];
-    // 处理 市场配置
-    // 一开始市场是配置在菜单JSON里的,但后面修改为根据接口返回市场信息
-    // 此处为了兼容以前代码,如果在菜单json里没有找到市场配置,则创建一个新的市场配置
-    // 后续 应该根据服务返回,而不是前端在json里配置
-    let marketMenu = list.find(el => el.code === "market")
-    let hasMarketMenu = true
-    if (!marketMenu) {
-        hasMarketMenu = false
-        marketMenu = {
-            auth: [],
-            children: [],
-            code: "market",
-            component: "Layout",
-            path: "/market",
-            remark: "",
-            sort: 1,
-            title: "市场",
-            url: "",
-        }
-    }
-    // 市场板块
-    const marketsSection = markets.map(({ marketsectionname, marketsectionid, remark }) => {
-        return {
-            auth: [],
-            children: [],
-            code: `market-${marketsectionid}`, // code: (market- + 市场板块的id)
-            component: "Layout",
-            path: `market-${marketsectionid}`,
-            remark,
-            sort: 1,
-            title: marketsectionname,
-            url: "",
-        }
-    })
-    marketMenu.children = [...marketMenu.children, ...marketsSection]
-
-    // 菜单jsonm 没有 配置市场
-    if (!hasMarketMenu) {
-        list.unshift(marketMenu)
-    }
-    localStorageUtil.setItem('menus', list)
-    APP.set('menus', list);
-}
-
 
 /**
  * 查询市场板块  /Tjmd/QueryTjmdMarketSection
  */
 export function queryTjmdMarketSection(): Promise<string> {
     return commonSearch_go('/Tjmd/QueryTjmdMarketSection', {}).then(res => {
-        addMarketToMenu(res)
         console.log('查询市场板块:  ', res)
-        const list = localStorageUtil.getItem('menus');
-        console.log('菜单', list)
         APP.set('marketsSection', res);
         return 'ok'
     }).catch((err) => {

+ 0 - 33
src/views/market/index.vue

@@ -1,33 +0,0 @@
-<template>
-  <div class="home">
-    市场
-  </div>
-</template>
-
-<script lang="ts">
-import { defineComponent } from 'vue';
-
-export default defineComponent({
-    components: {},
-    props: {
-      id: {
-        type: String,
-        default: ''
-      }
-    },
-    setup(props) {
-        console.log(props.id)
-        return {};
-    },
-});
-</script>
-
-<style lang="less">
-.home {
-    .withus {
-        cursor: pointer;
-        margin-top: 35px;
-        padding-bottom: 25px;
-    }
-}
-</style>

+ 231 - 0
src/views/market/market-spot/compoments/goods-chart/chart/index.less

@@ -0,0 +1,231 @@
+.chart-container {
+    [theme='light'] & {
+        --bgcolor            : #fff;
+        --tab-border-color   : #dae5ec;
+        --tab-checked-color  : #0866b8;
+        --tab-checked-bgcolor: #d4e0ff;
+        --slider-border-color: #b2c4dd;
+        --slider-bgcolor     : #edf2f7;
+        --slider-button-color: #b2c4dd;
+        --row-border-color   : #dae5ec;
+        --row-title-color    : #acb8c0;
+        --row-content-color  : #3c454b;
+        --tik-title-bgcolor  : #ECF2F5;
+        --tik-title-color    : #7A8A94;
+    }
+
+    display         : flex;
+    width           : 100%;
+    height          : calc(100% - 41px);
+    background-color: var(--bgcolor, #0e0e0f);
+
+    .chart-content {
+        display       : flex;
+        flex-direction: column;
+        flex          : 1;
+        height        : 100%;
+
+        &__main {
+            flex: 1;
+        }
+
+        &__header {
+            padding: 4px 0;
+        }
+
+        &__tabs {
+            &:last-child:not(:first-child) {
+                margin-left: 20px;
+            }
+
+            display         : inline-block;
+            background-color: transparent;
+            line-height     : normal;
+            border-bottom   : 0;
+            border          : 1px solid var(--tab-border-color, #22292c);
+            border-radius   : 1.02px;
+            border-right    : 0;
+            overflow        : hidden;
+            margin-top      : 0;
+
+            .ant-menu-item {
+                height       : 22px;
+                line-height  : 22px;
+                color        : #7a8a94;
+                border-bottom: 0;
+                border-right : 1px solid var(--tab-border-color, #22292c);
+                margin-top   : 0;
+                top          : 0;
+                padding      : 0 16px;
+
+                &::after {
+                    border: 0 !important;
+                }
+
+                &-active,
+                &-selected {
+                    color           : var(--tab-checked-color, #0866b8);
+                    background-color: var(--tab-checked-bgcolor, #0e2f4c);
+                }
+            }
+        }
+    }
+
+    .chart-slider {
+        display         : flex;
+        justify-content : center;
+        align-items     : center;
+        width           : 6px;
+        border-left     : 1px solid var(--slider-border-color, #33393d);
+        border-right    : 1px solid var(--slider-border-color, #33393d);
+        background-color: var(--slider-bgcolor, #0e0e0f);
+
+        &__button {
+            width           : 2px;
+            height          : 30px;
+            font-size       : 0;
+            background-color: var(--slider-button-color, #3c454b);
+            border-radius   : 1px;
+        }
+    }
+
+    .chart-tips {
+        display       : flex;
+        flex-direction: column;
+        width         : 300px;
+        height        : 100%;
+
+        &__nav {
+            display        : flex;
+            justify-content: center;
+            align-items    : center;
+
+            .content {
+                &:first-child:not(:last-child) {
+                    margin-right: 16px;
+                }
+
+                &--left {
+                    font-size: 16px;
+                    color    : var(--row-content-color, #ACB8C0);
+                }
+
+                &--right {
+                    font-size: 24px;
+                    color    : #fc9618;
+                }
+            }
+        }
+
+        &__last {
+            display        : flex;
+            justify-content: center;
+            align-items    : center;
+            padding        : 16px 0;
+
+            .content {
+                &--left {
+                    font-size   : 24px;
+                    margin-right: 16px;
+                }
+
+                &--right {
+                    display       : flex;
+                    flex-direction: column;
+                    align-items   : flex-start;
+                }
+            }
+        }
+
+        &__volume {
+            .ant-row {
+                border-top: 1px solid var(--row-border-color, #171B1D);
+                padding   : 8px;
+
+                .ant-col {
+                    text-align: left;
+
+                    &:first-child {
+                        color: var(--row-title-color, #3c454b);
+                    }
+
+                    &:last-child {
+                        color     : var(--row-title-color, #acb8c0);
+                        text-align: right;
+                    }
+                }
+            }
+        }
+
+        &__tik {
+            flex          : 1;
+            display       : flex;
+            flex-direction: column;
+            overflow-y    : auto;
+
+            .ant-row {
+                padding: 0 8px;
+
+                .ant-col {
+                    text-align: right;
+
+                    &:first-child {
+                        text-align: left;
+                    }
+                }
+            }
+
+            .row-header {
+                h4 {
+                    text-align      : left;
+                    line-height     : 30px;
+                    color           : var(--tik-title-color, #7A8A94);
+                    background-color: var(--tik-title-bgcolor, #171B1D);
+                    padding         : 0 8px;
+                }
+
+                .ant-row {
+                    .ant-col {
+                        color: var(--row-title-color, #3c454b);
+                    }
+                }
+            }
+
+            .row-content {
+                flex      : 1;
+                overflow-y: auto;
+
+                .ant-row {
+                    margin-top: 4px;
+
+                    .ant-col {
+                        color: var(--row-content-color, #ACB8C0);
+                    }
+                }
+            }
+        }
+
+        &__info {
+            border-top: 1px solid var(--row-border-color, #171B1D);
+            padding   : 8px 8px 8px 0;
+
+            .ant-row {
+                margin-top: 4px;
+
+                .ant-col {
+                    text-align: left;
+
+                    &:nth-child(odd) {
+                        color       : var(--row-title-color, #3c454b);
+                        padding-left: 8px;
+                    }
+
+                    &:nth-child(even) {
+                        color     : var(--row-content-color, #ACB8C0);
+                        text-align: right;
+                    }
+                }
+            }
+        }
+    }
+}

+ 256 - 0
src/views/market/market-spot/compoments/goods-chart/chart/index.vue

@@ -0,0 +1,256 @@
+<template>
+  <!-- 交易图表  -->
+  <div class="chart-container">
+    <div class="chart-content">
+      <div class="chart-content__header">
+        <a-menu class="chart-content__tabs" v-model:selectedKeys="activeCycleName" mode="horizontal" @click="changeCycleType">
+          <a-menu-item v-for="item in chartType" :key="item.name">{{ item.label }}</a-menu-item>
+        </a-menu>
+        <a-menu class="chart-content__tabs" v-model:selectedKeys="activeSeriesType" mode="horizontal" v-if="activeCycleType !== CycleType.time">
+          <a-menu-item key="MACD">MACD</a-menu-item>
+          <a-menu-item key="VOL">VOL</a-menu-item>
+          <a-menu-item key="KDJ">KDJ</a-menu-item>
+          <a-menu-item key="CCI">CCI</a-menu-item>
+        </a-menu>
+      </div>
+      <echart-time class="chart-content__main" :quote-data="selectedRow" @change="getHistoryTikDatas" v-if="activeCycleType === CycleType.time"></echart-time>
+      <echart-kline class="chart-content__main" :quote-data="selectedRow" :cycle-type="activeCycleType" :series-type="activeSeriesType[0]" v-else></echart-kline>
+      <div class="chart-content__footer"></div>
+    </div>
+    <div class="chart-slider">
+      <div class="chart-slider__button"></div>
+    </div>
+    <div class="chart-tips" v-if="showExchange">
+      <div>
+        <div class="chart-tips__nav">
+          <div class="content content--left">{{ selectedRow.goodscode }}</div>
+          <div class="content content--right">{{ selectedRow.goodsname }}</div>
+        </div>
+        <div class="chart-tips__last">
+          <div :class="['content content--left', handleQuotePriceColor(selectedRow.last, selectedRow.presettle)]">{{ handleNoneValue(selectedRow.last) }}</div>
+          <div class="content content--right">
+            <span :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">{{ quoteChange(selectedRow) }}</span>
+            <span :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">{{ quoteAmplitude(selectedRow) }}</span>
+          </div>
+        </div>
+        <div class="chart-tips__volume">
+          <a-row>
+            <a-col :span="8">卖一</a-col>
+            <a-col :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.ask) }}</a-col>
+            <a-col :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.askvolume) }}</a-col>
+          </a-row>
+          <a-row>
+            <a-col :span="8">买一</a-col>
+            <a-col :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.bid) }}</a-col>
+            <a-col :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.bidvolume) }}</a-col>
+          </a-row>
+        </div>
+      </div>
+      <div class="chart-tips__tik">
+        <div class="row-header">
+          <h4>分时成交</h4>
+          <a-row>
+            <a-col :span="8">时间</a-col>
+            <a-col :span="8">价格</a-col>
+            <a-col :span="8">现量</a-col>
+          </a-row>
+        </div>
+        <div class="row-content">
+          <a-row v-for="(item, index) in tradedList" :key="index + '11'">
+            <a-col :span="8">{{ formatTime(item.TS, 'hm') }}</a-col>
+            <a-col :class="handleQuotePriceColor(item.PE, selectedRow.presettle)" :span="8">{{ item.PE }}</a-col>
+            <a-col :class="handleQuotePriceColor(item.Vol, selectedRow.presettle)" :span="8">{{ item.Vol }}</a-col>
+          </a-row>
+        </div>
+      </div>
+      <div class="chart-tips__info">
+        <a-row>
+          <a-col :span="4">最新</a-col>
+          <a-col :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.last) }}</a-col>
+          <a-col :span="4">均价</a-col>
+          <a-col :class="handleQuotePriceColor(selectedRow.averageprice, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.averageprice) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">涨跌</a-col>
+          <a-col :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)" :span="8">{{ quoteChange(selectedRow) }}</a-col>
+          <a-col :span="4">今开</a-col>
+          <a-col :class="handleQuotePriceColor(selectedRow.opened, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.opened) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">涨幅</a-col>
+          <a-col :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)" :span="8">{{ quoteAmplitude(selectedRow) }}</a-col>
+          <a-col :span="4">最高</a-col>
+          <a-col :class="handleQuotePriceColor(selectedRow.highest, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.highest) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">总量</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.totalvolume) }}</a-col>
+          <a-col :span="4">最低</a-col>
+          <a-col :class="handleQuotePriceColor(selectedRow.lowest, selectedRow.presettle)" :span="8">{{ handleNoneValue(selectedRow.lowest) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">金额</a-col>
+          <a-col :span="8" style="color: #0d96ff">{{ changeUnit(selectedRow.totalturnover) }}</a-col>
+          <a-col :span="4">量比</a-col>
+          <a-col :span="8">{{ '--' }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">涨停</a-col>
+          <a-col class="red1" :span="8">{{ handleNoneValue(selectedRow.limitup) }}</a-col>
+          <a-col :span="4">跌停</a-col>
+          <a-col class="green" :span="8">{{ handleNoneValue(selectedRow.limitdown) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">外盘</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.totalbidvolume) }}</a-col>
+          <a-col :span="4">内盘</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.totalaskvolume) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">持仓</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.holdvolume) }}</a-col>
+          <a-col :span="4">结算</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.settle) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">仓差</a-col>
+          <a-col :span="8">{{ '--' }}</a-col>
+          <a-col :span="4">昨结</a-col>
+          <a-col :span="8">{{ handleNoneValue(selectedRow.presettle) }}</a-col>
+        </a-row>
+        <a-row>
+          <a-col :span="4">日增</a-col>
+          <a-col :span="8">{{ '--' }}</a-col>
+          <a-col :span="4">开平</a-col>
+          <a-col :span="8">{{ '--' }}</a-col>
+        </a-row>
+      </div>
+      <div @click="watchMore" class="watchMore">
+        <strong>查看更多</strong>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent } from '@/common/export/commonTable';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { PropType, ref, watch } from 'vue';
+import { QueryQuoteDayRsp, QueryHistoryTikDatasRsp, CycleType } from '@/services/go/quote/interface';
+import { QueryHistoryTikDatas } from '@/services/go/quote';
+import { formatTime } from '@/common/methods';
+import { changeUnit } from '@/utils/qt/common';
+import { ComponentType } from '@/views/market/spot_trade/spot_trade_order_transaction/setup';
+import { EchartKline, EchartTime } from '@/common/components/echart';
+import { handleQuotePriceColor, quoteChange, handleNoneValue, quoteAmplitude } from '@/common/setup/table/tableQuote';
+import moment from 'moment';
+
+export default defineComponent({
+    emits: ['cancel', 'update'],
+    name: 'stock-exchange',
+    components: {
+        EchartKline,
+        EchartTime,
+    },
+    props: {
+        selectedRow: {
+            type: Object as PropType<QueryQuoteDayRsp>,
+            default: {},
+        },
+        showExchange: {
+            type: Boolean,
+            default: true,
+        },
+    },
+    setup(props, context) {
+        const { visible, cancel } = _closeModal(context),
+            activeCycleName = ref<string[]>(['time']),
+            activeCycleType = ref<CycleType>(CycleType.time),
+            activeSeriesType = ref<string[]>(['MACD']),
+            tradedList = ref<QueryHistoryTikDatasRsp[]>([]);
+
+        function watchMore() {
+            context.emit('update', ComponentType.marketContent);
+        }
+
+        // 周期类型
+        const chartType = [
+            { label: '分时', name: 'time', value: CycleType.time },
+            { label: '1分钟', name: 'minutes', value: CycleType.minutes },
+            { label: '5分钟', name: 'minutes5', value: CycleType.minutes5 },
+            { label: '30分钟', name: 'minutes30', value: CycleType.minutes30 },
+            { label: '60分钟', name: 'minutes60', value: CycleType.minutes60 },
+            { label: '4小时', name: 'Hours4', value: CycleType.Hours4 },
+            { label: '日 K', name: 'days', value: CycleType.days },
+        ];
+
+        // 切换图表周期类型
+        const changeCycleType = (e: { key: string }) => {
+            activeCycleType.value = chartType.find((item) => item.name === e.key)!.value;
+        };
+
+        // Tik列表
+        const getHistoryTikDatas = (startTime: string, endTime: string) => {
+            const param = {
+                goodsCode: props.selectedRow.goodscode.toUpperCase(),
+                count: 20,
+                startTime: moment(startTime).format('YYYY-MM-DD HH:mm:ss'),
+                endTime: moment(endTime).format('YYYY-MM-DD HH:mm:ss'),
+            };
+            QueryHistoryTikDatas(param).then((res) => {
+                tradedList.value = res;
+            });
+        };
+
+        // 监听行情变化刷Tik列表
+        watch(
+            () => props.selectedRow.last,
+            () => {
+                if (tradedList.value.length > 19) {
+                    // 移除列表最后一条记录
+                    tradedList.value.pop();
+                }
+                // 向列表开头添加新纪录
+                tradedList.value.unshift({
+                    AV: 0,
+                    Ask: 0,
+                    BV: 0,
+                    Bid: 0,
+                    HI: 0,
+                    HV: 0,
+                    PE: props.selectedRow.last,
+                    TDR: 0,
+                    TK: 0,
+                    TS: props.selectedRow.lasttime,
+                    TT: 0,
+                    Vol: props.selectedRow.lastvolume,
+                });
+            }
+        );
+
+        return {
+            cancel,
+            visible,
+            chartType,
+            tradedList,
+            CycleType,
+            activeCycleName,
+            activeCycleType,
+            activeSeriesType,
+            changeUnit,
+            watchMore,
+            formatTime,
+            quoteChange,
+            handleNoneValue,
+            quoteAmplitude,
+            handleQuotePriceColor,
+            changeCycleType,
+            getHistoryTikDatas,
+        };
+    },
+});
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 163 - 0
src/views/market/market-spot/compoments/goods-chart/index.vue

@@ -0,0 +1,163 @@
+<template>
+  <!-- 买卖大厅 -->
+  <div class="buy-sell-market">
+    <div class="buy-sell-market-title">
+      <a class="backIcon" @click="cancelAction">
+        <LeftOutlined />
+      </a>
+      <div class="titleBtn">
+        <div class="name">{{ selectedRow.goodscode }} {{ selectedRow.goodsname }}</div>
+        <div class="arrowRightIcon"></div>
+      </div>
+      <div class="inlineBar">
+        <div class="valNums bdf1 ml10">
+          <!-- 最新价 -->
+          <div class="firstNum start" :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">{{ selectedRow.last }}</div>
+          <div class="lastNum start">
+            <!-- 涨跌值 -->
+            <div :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">{{ quoteChange(selectedRow, selectedRow.decimalplace) }}</div>
+            <!-- 涨跌幅 -->
+            <div class="ml20" :class="handleQuotePriceColor(selectedRow.last, selectedRow.presettle)">{{ quoteAmplitude(selectedRow, selectedRow.decimalplace) }}</div>
+          </div>
+        </div>
+        <div class="priceBar ml20">
+          <div class="inlineBar start">
+            <div class="greenBar">
+              <div class="numBlock ml15">
+                <div class="first grey">卖价</div>
+                <div class="last" :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)">{{ selectedRow.ask }}</div>
+              </div>
+              <div class="numBlock">
+                <div class="first grey">卖量</div>
+                <div class="last" :class="handleQuotePriceColor(selectedRow.ask, selectedRow.presettle)">{{ selectedRow.askvolume }}</div>
+              </div>
+            </div>
+          </div>
+          <div class="inlineBar start">
+            <div class="redBar">
+              <div class="numBlock">
+                <div class="first grey">买价</div>
+                <div class="last" :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)">{{ selectedRow.bid }}</div>
+              </div>
+              <div class="numBlock">
+                <div class="first grey">买量</div>
+                <div class="last" :class="handleQuotePriceColor(selectedRow.bid, selectedRow.presettle)">{{ selectedRow.bidvolume }}</div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="btn-list">
+        <a-button class="operBtn" @click="openComponent({ code: 'trade' })">交易</a-button>
+      </div>
+    </div>
+    <!-- 交易图表 -->
+    <Chart v-if="showComponentsId === ComponentType.chart" @update="changeComponent" :selectedRow="selectedRow" />
+    <!-- 成交明细 -->
+    <StockExchange :selectedRow="selectedRow" v-if="showComponentsId === ComponentType.tradeDetail" />
+    <component :is="componentId" v-if="componentId" :selectedRow="selectedRow" @cancel="closeComponent"></component>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, defineAsyncComponent } from '@/common/export/commonTable';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { handleQuotePriceColor, handleSubcriteOnDemandQuote, quoteAmplitude, quoteAmplituOfVibration, quoteChange } from '@/common/setup/table/tableQuote';
+import { QueryQuoteDayRsp } from '@/services/go/quote/interface';
+import { LeftOutlined } from '@ant-design/icons-vue';
+import { PropType, ref } from 'vue';
+import Chart from './chart/index.vue';
+import { ComponentType } from './setup';
+import StockExchange from './stock-exchange/index.vue';
+import { handleModalComponent } from '@/common/setup/asyncComponent';
+
+export default defineComponent({
+  emits: ['cancel', 'update'],
+  name: 'buy-sell-market',
+  props: {
+    selectedRow: {
+      type: Object as PropType<QueryQuoteDayRsp>,
+      default: () => ({}),
+    },
+  },
+  components: {
+    Chart,
+    LeftOutlined,
+    StockExchange,
+    trade: defineAsyncComponent(() => import('@/views/market/futures/compoments/futures-trade/index.vue')), // 期货交易
+  },
+  setup(props, context) {
+    const loading = ref<boolean>(false);
+    const { visible, cancel } = _closeModal(context);
+
+    const showComponentsId = ref<ComponentType>(ComponentType.chart);
+
+    const { componentId, closeComponent, openComponent } = handleModalComponent(() => { }, ref({}));
+
+    // 切换组件
+    function changeComponent(type: ComponentType) {
+      showComponentsId.value = type;
+    }
+    // 返回上层组件
+    function cancelAction() {
+      if (showComponentsId.value === ComponentType.chart) {
+        cancel();
+      } else {
+        showComponentsId.value = ComponentType.chart;
+      }
+    }
+    return {
+      cancel,
+      visible,
+      changeComponent,
+      ComponentType,
+      showComponentsId,
+      cancelAction,
+      handleSubcriteOnDemandQuote,
+      handleQuotePriceColor,
+      quoteChange,
+      quoteAmplitude,
+      quoteAmplituOfVibration,
+      componentId,
+      closeComponent,
+      openComponent,
+    };
+  },
+});
+</script>
+<style lang="less">
+.valNums {
+    .flex;
+    flex-direction: column;
+    padding-left: 20px;
+    .firstNum {
+        font-size: 18px;
+        line-height: 18px;
+        font-weight: 400;
+    }
+    .lastNum {
+        margin-top: 2px;
+        display: inline-flex;
+        font-size: 12px;
+        line-height: 12px;
+        font-weight: 300;
+    }
+}
+.inlineBar {
+    display: inline-flex;
+}
+.priceBar {
+    .flex;
+    flex-direction: column;
+    height: 32px;
+    .greenBar,
+    .redBar {
+        height: 16px;
+        line-height: 16px;
+    }
+}
+.start {
+    align-self: flex-start !important;
+    align-items: flex-start !important;
+}
+</style>

+ 4 - 0
src/views/market/market-spot/compoments/goods-chart/setup.ts

@@ -0,0 +1,4 @@
+export enum ComponentType {
+    chart,
+    tradeDetail,
+}

+ 94 - 0
src/views/market/market-spot/compoments/goods-chart/stock-exchange/index.vue

@@ -0,0 +1,94 @@
+<template>
+  <!-- 成交明细  -->
+  <a-row>
+    <a-col :span="8">
+      <a-table :columns="columnsList" class="srcollYTable" :pagination="false" :loading="loading" :rowKey="(record,index)=>index" ref="tableRef" :data-source="tableList[0]">
+      </a-table>
+    </a-col>
+    <a-col :span="8">
+      <a-table :columns="columnsList" class="srcollYTable" :pagination="false" :loading="loading" :rowKey="(record,index)=>index" ref="tableRef" :data-source="tableList[1]">
+      </a-table>
+    </a-col>
+    <a-col :span="8">
+      <a-table :columns="columnsList" class="srcollYTable" :pagination="false" :loading="loading" :rowKey="(record,index)=>index" ref="tableRef" :data-source="tableList[2]">
+      </a-table>
+    </a-col>
+  </a-row>
+</template>
+
+<script lang="ts">
+import { defineAsyncComponent, defineComponent } from '@/common/export/commonTable';
+import { _closeModal } from '@/common/setup/modal/modal';
+import { PropType, ref } from 'vue';
+
+import { QueryHistoryTikDatasRsp, QueryQuoteDayRsp } from '@/services/go/quote/interface';
+import { QueryDeliveryRelationRsp } from '@/services/go/delivery/interface';
+import { QueryHistoryTikDatas } from '@/services/go/quote';
+import { formatTime } from '@/common/methods';
+
+const columnsList = [
+  { title: '时间', key: 'TS', dataIndex: 'TS', align: 'center' },
+  { title: '成交价', key: 'Vol', dataIndex: 'Vol', align: 'center' },
+  { title: '成交量', key: 'PE', dataIndex: 'PE', align: 'center' },
+];
+
+export default defineComponent({
+  emits: ['cancel', 'update'],
+  name: 'stock-exchange',
+  props: {
+    selectedRow: {
+      type: Object as PropType<QueryQuoteDayRsp>,
+      default: {},
+    },
+  },
+
+  setup(props, context) {
+    const loading = ref<boolean>(false);
+    const { visible, cancel } = _closeModal(context);
+    const param = {
+      goodsCode: props.selectedRow.goodscode,
+    };
+    const tableList = ref<QueryHistoryTikDatasRsp[][]>([]);
+    QueryHistoryTikDatas(param).then((res) => {
+      res.forEach((el) => (el.TS = formatTime(el.TS)));
+      tableList.value = getHisList(res);
+    });
+    function getHisList(list: QueryHistoryTikDatasRsp[]) {
+      const len = list.length;
+      const result: QueryHistoryTikDatasRsp[][] = [[], [], []];
+      if (len) {
+        if (len === 1) {
+          result[0] = list;
+        } else if (len === 2) {
+          result[0].push(list[0]);
+          result[1].push(list[1]);
+        } else {
+          const temp = Math.floor(len / 3);
+          result[0] = list.slice(0, temp);
+          result[1] = list.slice(temp, 2 * temp);
+          result[2] = list.slice(temp * 2, temp * 3);
+          const last = len - temp;
+          if (last) {
+            if (last === 1) {
+              result[0].push(list[len - 1]);
+            } else {
+              result[0].push(list[len - 2]);
+              result[1].push(list[len - 1]);
+            }
+          }
+        }
+      }
+      return result;
+    }
+    return {
+      cancel,
+      visible,
+      tableList,
+      columnsList,
+      loading,
+    };
+  },
+});
+</script>
+<style lang="less">
+</style>

+ 229 - 0
src/views/market/market-spot/compoments/spot_trade_order_transaction/index.vue

@@ -0,0 +1,229 @@
+<template>
+    <!--订单交易 商品掉期-->
+    <div class="topTableHeight">
+        <div class="filterTable">
+            <div class="filter-custom-table">
+                <a-select
+                    class="conditionSelect"
+                    :style="{ width: '180px', maxHeight: '400px', overflow: 'auto' }"
+                    @change="goodsChange"
+                    placeholder="全部标的合约"
+                >
+                    <a-select-option
+                        v-for="item in getRefGoodsList()"
+                        :value="item"
+                        :key="item"
+                    >{{ item }}</a-select-option>
+                </a-select>
+                <!-- <a-button class="btnDeafault"
+                @click="search(true)"
+                style="width: 80px">筛选</a-button>-->
+            </div>
+        </div>
+        <a-table
+            :columns="columns"
+            :class="['srcollYTable', isBottom ? 'secondTabTable' : 'secondTabTableNoBottom', goodsList.length ? 'noPlaceHolder' : 'hasPlaceHolder']"
+            :scroll="{ x: '100%', y: isBottom ? 'calc(100vh- 407px)' : 'calc(100vh - 167px)' }"
+            :pagination="false"
+            :loading="loading"
+            :expandedRowKeys="expandedRowKeys"
+            :customRow="Rowclick"
+            rowKey="refgoodscode"
+            ref="tableRef"
+            :data-source="goodsList"
+        >
+            <!-- <template #totalturnover="{ text }">
+        <span>{{changeUnit(text)}}</span>
+            </template>-->
+            <!-- 涨跌 -->
+            <template #change="{ record }">
+                <span
+                    :class="handleQuotePriceColor_out(record.refgoodscode, 'last')"
+                >{{ quoteChange_out(record.refgoodscode) }}</span>
+            </template>
+            <!-- 幅度 -->
+            <template #amplitude="{ record }">
+                <span
+                    :class="handleQuotePriceColor_out(record.refgoodscode, 'last')"
+                >{{ quoteAmplitude_out(record.refgoodscode) }}</span>
+            </template>
+            <!-- 振幅 -->
+            <template #vibration="{ record }">
+                <span>{{ quoteAmplituOfVibration(record, record.decimalplace) }}</span>
+            </template>
+            <template #index="{ index }">
+                <span>{{ index + 1 }}</span>
+            </template>
+            <!-- 买价 -->
+            <!-- <template #bid="{ record }">
+        <span :class="handleQuotePriceColor_out(record.refgoodscode, 'bid')">
+          {{getQuoteValue_out(record.refgoodscode, 'bid')}}</span>
+            </template>-->
+            <!-- 卖价 -->
+            <!-- <template #ask="{  record }">
+        <span :class="handleQuotePriceColor_out(record.refgoodscode, 'ask')">
+          {{getQuoteValue_out(record.refgoodscode, 'ask')}}</span>
+            </template>-->
+            <!-- 最新价 -->
+            <template #last="{ record }">
+                <span
+                    :class="handleQuotePriceColor_out(record.refgoodscode, 'last')"
+                >{{ getQuoteValue_out(record.refgoodscode, 'last') }}</span>
+            </template>
+            <!-- 开盘 -->
+            <template #opened="{ record }">
+                <span
+                    :class="handleQuotePriceColor_out(record.refgoodscode, 'opened')"
+                >{{ getQuoteValue_out(record.refgoodscode, 'opened') }}</span>
+            </template>
+            <!-- 结算 -->
+            <template #settle="{ record }">
+                <span
+                    :class="handleQuotePriceColor_out(record.refgoodscode, 'settle')"
+                >{{ getQuoteValue_out(record.refgoodscode, 'settle') }}</span>
+            </template>
+            <!-- 昨结算 -->
+            <template #presettle="{ record }">
+                <span>{{ getQuoteValue_out(record.refgoodscode, 'presettle') }}</span>
+            </template>
+            <!-- 最低价 -->
+            <template #lowest="{ record }">
+                <span
+                    :class="handleQuotePriceColor_out(record.refgoodscode, 'lowest')"
+                >{{ getQuoteValue_out(record.refgoodscode, 'lowest') }}</span>
+            </template>
+            <!-- 最高价 -->
+            <template #highest="{ record }">
+                <span
+                    :class="handleQuotePriceColor_out(record.refgoodscode, 'highest')"
+                >{{ getQuoteValue_out(record.refgoodscode, 'highest') }}</span>
+            </template>
+        </a-table>
+        <!-- 右键 -->
+        <contextMenu :contextMenu="contextMenu" @cancel="closeContext" :list="btnList"></contextMenu>
+        <component
+            :is="componentId"
+            v-if="componentId"
+            :selectedRow="selectedRow"
+            @cancel="closeComponent"
+        ></component>
+    </div>
+</template>
+
+<script lang="ts">
+import { getShowBottomValue } from '@/common/config/constrolBottom';
+import { contextMenu, defineComponent } from '@/common/export/commonTable';
+import { handleTableEventAndData } from '@/common/setup/table/compose';
+import { TableParam } from '@/common/setup/table/interface';
+import { getQuoteValue_out, handleQuotePriceColor_out, handleSubcriteOnDemandQuote, quoteAmplitude_out, quoteAmplituOfVibration, quoteChange_out } from '@/common/setup/table/tableQuote';
+import { QueryQuoteDayRsp } from '@/services/go/quote/interface';
+import { QueryQuoteGoodsListRsp } from '@/services/go/Tjmd/interface';
+import { columnsList, getBtnList, useSwapList } from './setup';
+
+export default defineComponent({
+    name: 'spot_trade_order_transaction_swap',
+    components: {
+        contextMenu,
+        // BuyAndSell: defineAsyncComponent(() => import('./components/buy-sell-market/index.vue')),
+        // PostBuying: defineAsyncComponent(() => import('./components/post_buying/index.vue')),
+        // Detail: defineAsyncComponent(() => import('./components/detail/index.vue')),
+    },
+    setup() {
+        const isBottom = getShowBottomValue();
+        const { loading, goodsList, getRefGoodsList, filterGoodsList } = useSwapList();
+
+        const param: TableParam = {
+            columnsList,
+            queryFn: () => { },
+            clickName: 'BuyAndSell',
+        };
+
+        // 行情按需订阅
+        let stopSubcribe = handleSubcriteOnDemandQuote<QueryQuoteGoodsListRsp>(goodsList, 'refgoodscode');
+        // 过滤标的合约
+        function goodsChange(value: string) {
+            filterGoodsList(value);
+            // 停止上次订阅
+            stopSubcribe();
+            // 重新发起订阅
+            stopSubcribe = handleSubcriteOnDemandQuote<QueryQuoteGoodsListRsp>(goodsList, 'refgoodscode');
+        }
+        return {
+            isBottom,
+            ...handleTableEventAndData<QueryQuoteDayRsp>(param),
+            btnList: getBtnList(true),
+            handleQuotePriceColor_out,
+            quoteChange_out,
+            quoteAmplitude_out,
+            quoteAmplituOfVibration,
+            getRefGoodsList,
+            goodsList,
+            loading,
+            goodsChange,
+            getQuoteValue_out,
+        };
+    },
+});
+</script>
+<style lang="less">
+.noData {
+    .position(absolute, 28px, 0, 0, 0);
+}
+.filter-custom-table {
+    display: inline-flex;
+    padding-top: 4px;
+    height: 34px;
+    .conditionSelect:first-child {
+        margin-right: 10px;
+    }
+    .btnDeafault.ant-btn,
+    .operBtn.ant-btn {
+        height: 26px !important;
+        line-height: 26px !important;
+    }
+
+    .ant-select-single:not(.ant-select-customize-input)
+        + .ant-select-single:not(.ant-select-customize-input),
+    .ant-select + .ant-space.ant-space-vertical {
+        margin-left: 10px;
+    }
+    .ant-select-single:not(.ant-select-customize-input) {
+        height: 26px;
+        line-height: 26px !important;
+        .ant-select-selector {
+            height: 26px;
+            border-color: @m-grey46 !important;
+            background: @m-grey47;
+            .rounded-corners(3px);
+            .ant-select-selection-item {
+                line-height: 26px;
+            }
+            .ant-select-selection-search {
+                height: 26px;
+                .ant-select-selection-search-input {
+                    height: 26px;
+                    line-height: 27px !important;
+                }
+            }
+            .ant-select-selection-placeholder {
+                line-height: 26px;
+            }
+        }
+    }
+
+    .allDatePicker.ant-calendar-picker {
+        height: 26px !important;
+        border: 1px solid @m-grey46 !important;
+        .ant-calendar-picker-input.ant-input {
+            height: 26px;
+            line-height: 26px;
+            &::placeholder {
+                color: @m-grey10 !important;
+            }
+        }
+    }
+    .conditionSelect + .conditionSelect {
+        margin-left: 10px;
+    }
+}
+</style>

+ 103 - 0
src/views/market/market-spot/compoments/spot_trade_order_transaction/setup.ts

@@ -0,0 +1,103 @@
+import { BtnListType } from "@/common/components/btnList/interface"
+import { TradeMode } from "@/common/constants/enumCommon"
+import { initData } from "@/common/methods"
+import { queryTableList } from "@/common/setup/table"
+import { getMarketIdsByTradeMode } from "@/services/bus/market"
+import { getUserAccountType } from "@/services/bus/user"
+import { queryQuoteGoodsList } from "@/services/go/Tjmd"
+import { QueryQuoteGoodsListReq, QueryQuoteGoodsListRsp } from "@/services/go/Tjmd/interface"
+import { ref } from "vue"
+
+const refGoods = ref<QueryQuoteGoodsListRsp[]>([])
+
+export function findItemGoods(goodscode: string) {
+    return refGoods.value.find(el => el.goodscode === goodscode)!
+}
+
+const { loading, queryTable } = queryTableList<QueryQuoteGoodsListRsp>();
+
+export function getSwapList() {
+    // 组装 参数
+    const marketids = getMarketIdsByTradeMode(TradeMode.DiaoQi)
+    const param: QueryQuoteGoodsListReq = {
+        usertype: getUserAccountType(),
+    }
+    if (marketids) {
+        param.marketids = marketids
+    }
+    return queryTable(queryQuoteGoodsList, param)
+}
+
+// 获取 商品掉期 商品列表
+export const useSwapList = () => {
+    // 行情商品
+    const goodsList = ref<QueryQuoteGoodsListRsp[]>([])
+    initData(() => {
+        // 开始查询 商品掉期
+        getSwapList().then(res => {
+            refGoods.value = res
+            goodsList.value = res
+        })
+    })
+    // 获取标记商品列表
+    function getRefGoodsList(): string[] {
+        const result = new Set<string>(['全部标的合约'])
+        refGoods.value.forEach(el => {
+            result.add(el.refgoodsname)
+        })
+        return [...result]
+    }
+    // 过滤标的合约
+    function filterGoodsList(value: string) {
+        if (value === '全部标的合约') {
+            goodsList.value = refGoods.value
+        } else {
+            goodsList.value = refGoods.value.filter(goods => goods.refgoodsname === value)
+        }
+    }
+
+    return { loading, goodsList, getRefGoodsList, filterGoodsList, refGoods }
+}
+
+export const columnsList = [
+    { title: '序号', key: 'index', width: 80 },
+    { title: '代码', key: 'goodscode' },
+    { title: '名称', key: 'goodsname' },
+
+    { title: '标的合约', key: 'refgoodsname' },
+
+    // { title: '买价', key: 'bid' },
+    // { title: '买量', key: 'bidvolume' },
+    // { title: '卖价', key: 'ask' },
+    // { title: '卖量', key: 'askvolume' },
+
+    { title: '当前价', key: 'last' },
+    { title: '涨跌', key: 'change' }, // 最新价 - 昨结价
+    { title: '幅度', key: 'amplitude' }, // (最新价 - 昨结价) / 100 %
+    { title: '开盘', key: 'opened' },
+    { title: '最高', key: 'highest' },
+    { title: '最低', key: 'lowest' },
+
+    { title: '结算', key: 'settle' },
+
+    { title: '昨结算', key: 'presettle' },
+
+    // { title: '振幅', key: 'vibration' }, // (最高价 - 最低价 ) / 最新价  * 100 %
+    // { title: '总量', key: 'totalvolume' },
+    // { title: '现量', key: 'lastvolume' },
+    // { title: '持仓量', key: 'holdvolume' },
+    // { title: '日增', key: 'holdincrement' },
+    // { title: '金额', key: 'totalturnover' },
+];
+
+// 获取按钮列表
+export function getBtnList(isBuyAndSell: boolean) {
+    const btnList: BtnListType[] = [
+        { lable: '挂牌', code: 'PostBuying', className: 'operBtn' },
+        // { lable: '详情', code: 'Detail', className: 'btnDeafault' },
+    ];
+    if (isBuyAndSell) {
+        btnList.push({ lable: '买卖大厅', code: 'BuyAndSell', className: 'btnDeafault' })
+    }
+    return btnList
+}

+ 192 - 0
src/views/market/market-spot/compoments/spot_trade_reference_market/index.vue

@@ -0,0 +1,192 @@
+<template>
+    <!--参考行情-->
+    <div class="topTableHeight topTableHeight_379">
+        <a-table
+            :columns="columns"
+            :class="['srcollYTable', isBottom ? '' : 'srcollYTableNoBottom', goodsList.length ? 'noPlaceHolder' : 'hasPlaceHolder']"
+            :scroll="{ x: '100%', y: isBottom ? 'calc(100vh - 378px)' : 'calc(100vh - 138px)' }"
+            :pagination="false"
+            :loading="loading"
+            :expandedRowKeys="expandedRowKeys"
+            :customRow="Rowclick"
+            rowKey="goodscode"
+            ref="tableRef"
+            :data-source="goodsList"
+        >
+            <template #totalturnover="{ text }">
+                <span>{{ changeUnit(text) }}</span>
+            </template>
+            <!-- 买量 -->
+            <template #bidvolume="{ text }">
+                <span>{{ handleNoneValue(text) }}</span>
+            </template>
+            <!-- 卖量 -->
+            <template #askvolume="{ text }">
+                <span>{{ handleNoneValue(text) }}</span>
+            </template>
+            <!-- 开盘价 -->
+            <template #opened="{ record, text }">
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
+            </template>
+            <!-- 涨跌 -->
+            <template #change="{ record }">
+                <span
+                    :class="handleQuotePriceColor(record.last, record.presettle)"
+                >{{ quoteChange(record, record.decimalplace) }}</span>
+            </template>
+            <!-- 幅度 -->
+            <template #amplitude="{ record }">
+                <span
+                    :class="handleQuotePriceColor(record.last, record.presettle)"
+                >{{ quoteAmplitude(record, record.decimalplace) }}</span>
+            </template>
+            <!-- 振幅 -->
+            <template #vibration="{ record, text }">
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ quoteAmplituOfVibration(record, record.decimalplace) }}</span>
+            </template>
+            <template #index="{ index }">
+                <span>{{ index + 1 }}</span>
+            </template>
+            <!-- 买价 -->
+            <template #bid="{ text, record }">
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
+            </template>
+            <!-- 卖价 -->
+            <template #ask="{ text, record }">
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
+            </template>
+            <!-- 最新价 -->
+            <template #last="{ text, record }">
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
+            </template>
+            <!-- 最低价 -->
+            <template #lowest="{ text, record }">
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
+            </template>
+            <!-- 最高价 -->
+            <template #highest="{ text, record }">
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
+            </template>
+            <!-- 昨结价 -->
+            <template #preclose="{ text, record }">
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
+            </template>
+        </a-table>
+        <component
+            :is="componentId"
+            v-if="componentId"
+            :enumName="name"
+            :selectedRow="selectedRow"
+            @cancel="closeComponent"
+        ></component>
+    </div>
+</template>
+
+<script lang="ts">
+import { getShowBottomValue } from '@/common/config/constrolBottom';
+import { TradeMode } from '@/common/constants/enumCommon';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { contextMenu, defineComponent, queryTableList } from '@/common/export/commonTable';
+import { handleTableColums } from '@/common/setup/table/clolumn';
+import { handleTableEventAndData } from '@/common/setup/table/compose';
+import { TableParam } from '@/common/setup/table/interface';
+import { handleNoneValue, handleQuotePriceColor, handleSubcriteOnDemandQuote, quoteAmplitude, quoteAmplituOfVibration, quoteChange } from '@/common/setup/table/tableQuote';
+import { getQutoGoodsByTradeMode } from '@/services/bus/goods';
+import { QueryDeliveryRelationRsp } from '@/services/go/delivery/interface';
+import { QueryQuoteDayRsp } from '@/services/go/quote/interface';
+import { queryOrderQuote } from '@/services/go/wrtrade';
+import { QueryOrderQuoteReq } from '@/services/go/wrtrade/interface';
+import { changeUnit } from '@/utils/qt/common';
+import { defineAsyncComponent, ref } from 'vue';
+
+const columnsList = [
+    { title: '序号', key: 'index', width: 80 },
+    { title: '代码', key: 'goodscode' },
+    { title: '名称', key: 'goodsname' },
+    { title: '买价', key: 'bid' },
+    { title: '买量', key: 'bidvolume' },
+    { title: '卖价', key: 'ask' },
+    { title: '卖量', key: 'askvolume' },
+    { title: '最新价', key: 'last' },
+    { title: '涨跌', key: 'change' }, // 最新价 - 昨结价
+    { title: '幅度', key: 'amplitude' }, // (最新价 - 昨结价) / 100 %
+    { title: '开盘价', key: 'opened' },
+    { title: '昨收价', key: 'preclose' },
+    { title: '昨结价', key: 'presettle' },
+    { title: '最低价', key: 'lowest' },
+    { title: '最高价', key: 'highest' },
+    { title: '振幅', key: 'vibration' }, // (最高价 - 最低价 ) / 最新价  * 100 %
+    { title: '总量', key: 'totalvolume' },
+    { title: '现量', key: 'lastvolume' },
+    { title: '持仓量', key: 'holdvolume' },
+    // { title: '日增', key: 'holdincrement' },
+    // { title: '金额', key: 'totalturnover' },
+];
+
+export default defineComponent({
+    name: EnumRouterName.spot_trade_reference_market,
+    components: {
+        contextMenu,
+        chart: defineAsyncComponent(() => import('../goods-chart/index.vue')),
+    },
+    setup() {
+        const isBottom = getShowBottomValue();
+        // 表头
+        const { columns } = handleTableColums(columnsList);
+        // 表格列表数据
+        const { loading, tableList, queryTable } = queryTableList<QueryDeliveryRelationRsp>();
+        const tableRef = ref<any>(null);
+        // 行情商品
+        const goodsList = getQutoGoodsByTradeMode(TradeMode.quote99);
+        // 行情按需订阅
+        handleSubcriteOnDemandQuote<QueryQuoteDayRsp>(goodsList);
+        // 获取列表数据
+        const queryTableAction = () => {
+            const param: QueryOrderQuoteReq = {
+                wrpricetype: 1,
+                haswr: 1,
+            };
+            queryTable(queryOrderQuote, param);
+        };
+        const param: TableParam = {
+            columnsList,
+            queryFn: queryTableAction,
+            clickName: 'chart'
+        };
+        return {
+            isBottom,
+            ...handleTableEventAndData(param),
+            loading,
+            tableList,
+            goodsList,
+            tableRef,
+            columns,
+            changeUnit,
+            handleQuotePriceColor,
+            quoteChange,
+            quoteAmplitude,
+            quoteAmplituOfVibration,
+            handleNoneValue,
+        };
+    },
+});
+
+</script>
+<style lang="less">
+</style>

+ 120 - 0
src/views/market/market-spot/compoments/warehouse_receipt_trade/index.vue

@@ -0,0 +1,120 @@
+<template>
+    <!-- 仓单贸易 -->
+    <div class="topTableHeight">
+        <!-- <Filter :enumName="name" @search="search" @buy="buyOpen" /> -->
+        <a-table
+            :columns="columns"
+            :class="['srcollYTable', isBottom ? 'condSecondTabTable' : 'condSecondTabTableNoBottom', tableList.length ? 'noPlaceHolder' : 'hasPlaceHolder']"
+            :scroll="{ x: '100%', y: isBottom ? 'calc(100vh- 443px)' : 'calc(100vh - 196px)' }"
+            :pagination="false"
+            :loading="loading"
+            :expandedRowKeys="expandedRowKeys"
+            :customRow="Rowclick"
+            :rowKey="(record, index) => index"
+            :data-source="tableList"
+        ></a-table>
+        <!-- 右键 -->
+        <contextMenu :contextMenu="contextMenu" @cancel="closeContext" :list="firstBtn"></contextMenu>
+        <component
+            :is="componentId"
+            v-if="componentId"
+            :enumName="name"
+            :selectedRow="selectedRow"
+            @cancel="closeComponent"
+        ></component>
+    </div>
+</template>
+
+<script lang="ts">
+// import Filter from '../../components/filter/index.vue';
+import { getShowBottomValue } from '@/common/config/constrolBottom';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { ComposeTableParam, contextMenu, defineComponent, queryTableList } from '@/common/export/commonTable';
+import { queryOrderQuote } from '@/services/go/wrtrade';
+import { QueryOrderQuoteReq, WrOrderQuote } from '@/services/go/wrtrade/interface';
+import Bus from '@/utils/eventBus/index';
+import { handleComposeTable } from '@/views/market/spot_trade/setup';
+
+export default defineComponent({
+    name: EnumRouterName.warehouse_receipt_trade_price,
+    components: {
+        contextMenu,
+        // Filter,
+        // [ModalEnum.spot_trade_warehouse_detail]: defineAsyncComponent(() => import('../../components/detail/index.vue')),
+        // [ModalEnum.spot_trade_warehouse_post_buying]: defineAsyncComponent(() => import('../../components/post_buying/index.vue')),
+        // buyAndSell: defineAsyncComponent(() => import('../../components/buy-sell-market/index.vue')),
+        // postBuying: defineAsyncComponent(() => import('../../components/post_buying/index.vue')),
+    },
+    setup() {
+        const isBottom = getShowBottomValue();
+        // 表格列表数据
+        const { loading, tableList, queryTable } = queryTableList<WrOrderQuote>();
+        // 获取列表数据
+        const queryTableAction = () => {
+            const param: QueryOrderQuoteReq = {
+                wrpricetype: 1,
+                haswr: 1,
+            };
+            queryTable(queryOrderQuote, param);
+        };
+        Bus.$on('spotTrade', queryTableAction);
+        // 表格通用逻辑
+        const param: ComposeTableParam = {
+            queryFn: queryTableAction,
+            menuType: EnumRouterName.warehouse_receipt_trade_price,
+            tableName: 'table_pcweb_spot_trade_warehouse_price',
+            tableFilterKey: [],
+            isDetail: false,
+        };
+        const {
+            contextMenu,
+            openContext,
+            closeContext, // 右键
+            columns,
+            registerColumn,
+            updateColumn, // 表头
+            expandedRowKeys,
+            selectedRow,
+            Rowclick, // 表格折腾面板数据与单击、双击事件
+            componentId,
+            closeComponent, // 控制异步组件
+            firstBtn, // 表格按钮
+        } = handleComposeTable<WrOrderQuote>(param);
+        function search(value: Object) {
+            const param: QueryOrderQuoteReq = {
+                wrpricetype: 1,
+                haswr: 1,
+            };
+            Object.assign(param, value);
+            queryTable(queryOrderQuote, param);
+        }
+        function buyOpen(value: any, goods: any) {
+            componentId.value = 'postBuying';
+            selectedRow.value = value;
+        }
+
+        return {
+            isBottom,
+            contextMenu,
+            openContext,
+            closeContext, // 右键
+            columns,
+            registerColumn,
+            updateColumn, // 表头
+            expandedRowKeys,
+            selectedRow,
+            Rowclick, // 表格折腾面板数据与单击、双击事件
+            componentId,
+            closeComponent, // 控制异步组件
+            firstBtn, // 表格按钮
+            name: EnumRouterName.warehouse_receipt_trade_price,
+            loading,
+            tableList,
+            search,
+            buyOpen,
+        };
+    },
+});
+</script>
+<style lang="less">
+</style>

+ 71 - 0
src/views/market/market-spot/index.vue

@@ -0,0 +1,71 @@
+<template>
+  <div class="topTableHeight">
+    <FristMenu :list="marketsSetion" :value="'marketsectionname'" @selectMenu="selectSection" />
+    <component :is="componentId" v-if="componentId"></component>
+    <ThirdMenu :list="markets" :value="'marketname'" @selectMenu="onSelectMarket" />
+  </div>
+</template>
+
+<script lang="ts">
+import FristMenu from '@/common/components/firstMenu/index.vue';
+import ThirdMenu from '@/common/components/thirdMenu/index.vue';
+import { TradeMode } from '@/common/constants/enumCommon';
+import { contextMenu, defineAsyncComponent, defineComponent } from '@/common/export/commonTable';
+import { initData } from '@/common/methods';
+import APP from '@/services';
+import { TjmdMarketSection, TjmdMarketSectionConfig } from '@/services/go/Tjmd/interface';
+import { ref } from 'vue';
+
+export default defineComponent({
+  components: {
+    FristMenu,
+    ThirdMenu,
+    contextMenu,
+    // 仓单贸易
+    [TradeMode.WarehouseReceiptTrade]: defineAsyncComponent(() => import('./compoments/warehouse_receipt_trade/index.vue')),
+    // 参考行情
+    [TradeMode.quote99]: defineAsyncComponent(() => import('./compoments/spot_trade_reference_market/index.vue')),
+    // 掉期贸易
+    [TradeMode.DiaoQi]: defineAsyncComponent(() => import('./compoments/spot_trade_order_transaction/index.vue')),
+  },
+  setup() {
+    // 市场板块
+    const marketsSetion = APP.getRef('marketsSection')
+    // 市场
+    const markets = ref<TjmdMarketSectionConfig[]>([])
+    // 选中的市场
+    const selctedMarket = ref<TjmdMarketSectionConfig | null>(null)
+    const componentId = ref<string>('')
+    initData(() => {
+      if (marketsSetion.value.length) {
+        selectSection(marketsSetion.value[0])
+      }
+    })
+    // 切换市场板块
+    function selectSection(value: TjmdMarketSection) {
+      markets.value = value.mlist
+      const index = marketsSetion.value.findIndex((el: TjmdMarketSection) => el.marketsectionid === value.marketsectionid)
+      if (index !== -1 && value.mlist.length) {
+        onSelectMarket(index, value.mlist[0])
+      }
+    }
+    // 切换市场
+    function onSelectMarket(index: number, value: TjmdMarketSectionConfig) {
+      selctedMarket.value = value
+      componentId.value = value.trademode.toString()
+    }
+
+    return { marketsSetion, selectSection, markets, onSelectMarket, componentId };
+  },
+});
+</script>
+
+<style lang="less">
+.home {
+  .withus {
+    cursor: pointer;
+    margin-top: 35px;
+    padding-bottom: 25px;
+  }
+}
+</style>

+ 28 - 0
src/views/market/market-spot/setup.ts

@@ -0,0 +1,28 @@
+import { initData } from '@/common/methods';
+import APP from '@/services';
+import { TjmdMarketSection, TjmdMarketSectionConfig } from '@/services/go/Tjmd/interface';
+import { ref } from 'vue';
+
+export const useMarketsSection = () => {
+    // 市场板块
+    const marketsSetion = APP.getRef('marketsSection')
+    // 市场
+    const markets = ref<TjmdMarketSectionConfig[]>([])
+    // 选中的市场
+    const selctedMarket = ref<TjmdMarketSectionConfig | null>(null)
+    initData(() => {
+        if (marketsSetion.value.length) {
+            markets.value = marketsSetion.value[0].mlist
+        }
+    })
+    // 切换市场板块
+    function selectSection(value: TjmdMarketSection) {
+        markets.value = [...value.mlist, ...value.mlist]
+    }
+    // 切换市场
+    function onSelectMarket(value: TjmdMarketSectionConfig) {
+        selctedMarket.value = value
+    }
+
+    return { marketsSetion, selectSection, markets, onSelectMarket, selctedMarket }
+}

+ 79 - 24
src/views/market/spot_trade/spot_trade_reference_market/index.vue

@@ -1,67 +1,120 @@
 <template>
     <!--参考行情-->
-    <div class="topTableHeight">
-        <a-table :columns="columns" :class="['srcollYTable', isBottom ? '' : 'srcollYTableNoBottom', goodsList.length ? 'noPlaceHolder' : 'hasPlaceHolder']" :scroll="{ x: '100%', y: isBottom ? 'calc(100vh - 378px)' : 'calc(100vh - 138px)' }" :pagination="false" :loading="loading" :expandedRowKeys="expandedRowKeys" :customRow="Rowclick" rowKey="goodscode" ref="tableRef" :data-source="goodsList">
+    <div class="topTableHeight topTableHeight_379">
+        <a-table
+            :columns="columns"
+            :class="['srcollYTable', isBottom ? '' : 'srcollYTableNoBottom', goodsList.length ? 'noPlaceHolder' : 'hasPlaceHolder']"
+            :scroll="{ x: '100%', y: isBottom ? 'calc(100vh - 378px)' : 'calc(100vh - 138px)' }"
+            :pagination="false"
+            :loading="loading"
+            :expandedRowKeys="expandedRowKeys"
+            :customRow="Rowclick"
+            rowKey="goodscode"
+            ref="tableRef"
+            :data-source="goodsList"
+        >
             <template #totalturnover="{ text }">
                 <span>{{ changeUnit(text) }}</span>
             </template>
+            <!-- 买量 -->
+            <template #bidvolume="{ text }">
+                <span>{{ handleNoneValue(text) }}</span>
+            </template>
+            <!-- 卖量 -->
+            <template #askvolume="{ text }">
+                <span>{{ handleNoneValue(text) }}</span>
+            </template>
+            <!-- 开盘价 -->
+            <template #opened="{ record, text }">
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
+            </template>
             <!-- 涨跌 -->
             <template #change="{ record }">
-                <span>{{ quoteChange(record, record.decimalplace) }}</span>
+                <span
+                    :class="handleQuotePriceColor(record.last, record.presettle)"
+                >{{ quoteChange(record, record.decimalplace) }}</span>
             </template>
             <!-- 幅度 -->
             <template #amplitude="{ record }">
-                <span>{{ quoteAmplitude(record, record.decimalplace) }}</span>
+                <span
+                    :class="handleQuotePriceColor(record.last, record.presettle)"
+                >{{ quoteAmplitude(record, record.decimalplace) }}</span>
             </template>
             <!-- 振幅 -->
-            <template #vibration="{ record }">
-                <span>{{ quoteAmplituOfVibration(record, record.decimalplace) }}</span>
+            <template #vibration="{ record, text }">
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ quoteAmplituOfVibration(record, record.decimalplace) }}</span>
             </template>
             <template #index="{ index }">
                 <span>{{ index + 1 }}</span>
             </template>
             <!-- 买价 -->
             <template #bid="{ text, record }">
-                <span :class="handleQuotePriceColor(text, record.presettle)">{{ text }}</span>
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
             </template>
             <!-- 卖价 -->
             <template #ask="{ text, record }">
-                <span :class="handleQuotePriceColor(text, record.presettle)">{{ text }}</span>
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
             </template>
             <!-- 最新价 -->
             <template #last="{ text, record }">
-                <span :class="handleQuotePriceColor(text, record.presettle)">{{ text }}</span>
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
             </template>
             <!-- 最低价 -->
             <template #lowest="{ text, record }">
-                <span :class="handleQuotePriceColor(text, record.presettle)">{{ text }}</span>
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
             </template>
             <!-- 最高价 -->
             <template #highest="{ text, record }">
-                <span :class="handleQuotePriceColor(text, record.presettle)">{{ text }}</span>
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
+            </template>
+            <!-- 昨结价 -->
+            <template #preclose="{ text, record }">
+                <span
+                    :class="handleQuotePriceColor(text, record.presettle)"
+                >{{ handleNoneValue(text) }}</span>
             </template>
         </a-table>
         <!-- 右键 -->
         <!-- <contextMenu :contextMenu="contextMenu" @cancel="closeContext" :list="firstBtn"></contextMenu> -->
-        <component :is="componentId" v-if="componentId" :enumName="name" :selectedRow="selectedRow" @cancel="closeComponent"></component>
+        <component
+            :is="componentId"
+            v-if="componentId"
+            :enumName="name"
+            :selectedRow="selectedRow"
+            @cancel="closeComponent"
+        ></component>
     </div>
 </template>
 
 <script lang="ts">
-import { EnumRouterName } from '@/common/constants/enumRouterName';
-import { queryTableList, BtnList, contextMenu, defineAsyncComponent, defineComponent, ModalEnum, ComposeTableParam } from '@/common/export/commonTable';
-import { QueryOrderQuoteReq } from '@/services/go/wrtrade/interface';
-import { queryOrderQuote } from '@/services/go/wrtrade';
-import { handleComposeTable } from '@/views/market/spot_trade/setup';
-import { ref } from 'vue';
-import { handleSubcriteOnDemandQuote, handleQuotePriceColor, quoteChange, quoteAmplitude, quoteAmplituOfVibration } from '@/common/setup/table/tableQuote';
-import { QueryDeliveryRelationRsp } from '@/services/go/delivery/interface';
-import { getGoodsListByTrade, getQutoGoodsByTradeMode } from '@/services/bus/goods';
+import { getShowBottomValue } from '@/common/config/constrolBottom';
 import { TradeMode } from '@/common/constants/enumCommon';
+import { EnumRouterName } from '@/common/constants/enumRouterName';
+import { ComposeTableParam, contextMenu, defineAsyncComponent, defineComponent, queryTableList } from '@/common/export/commonTable';
 import { handleTableColums } from '@/common/setup/table/clolumn';
+import { handleNoneValue, handleQuotePriceColor, handleSubcriteOnDemandQuote, quoteAmplitude, quoteAmplituOfVibration, quoteChange } from '@/common/setup/table/tableQuote';
+import { getQutoGoodsByTradeMode } from '@/services/bus/goods';
+import { QueryDeliveryRelationRsp } from '@/services/go/delivery/interface';
 import { QueryQuoteDayRsp } from '@/services/go/quote/interface';
+import { queryOrderQuote } from '@/services/go/wrtrade';
+import { QueryOrderQuoteReq } from '@/services/go/wrtrade/interface';
 import { changeUnit } from '@/utils/qt/common';
-import { getShowBottomValue } from '@/common/config/constrolBottom';
+import { handleComposeTable } from '@/views/market/spot_trade/setup';
+import { ref } from 'vue';
 
 const columnsList = [
     { title: '序号', key: 'index', width: 80 },
@@ -83,8 +136,8 @@ const columnsList = [
     { title: '总量', key: 'totalvolume' },
     { title: '现量', key: 'lastvolume' },
     { title: '持仓量', key: 'holdvolume' },
-    { title: '日增', key: 'holdincrement' },
-    { title: '金额', key: 'totalturnover' },
+    // { title: '日增', key: 'holdincrement' },
+    // { title: '金额', key: 'totalturnover' },
 ];
 
 export default defineComponent({
@@ -136,9 +189,11 @@ export default defineComponent({
             quoteChange,
             quoteAmplitude,
             quoteAmplituOfVibration,
+            handleNoneValue,
         };
     },
 });
+
 </script>
 <style lang="less">
 </style>