Jelajahi Sumber

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

huangbin 4 tahun lalu
induk
melakukan
25d6102c20

+ 5 - 0
package-lock.json

@@ -49,6 +49,7 @@
                 "less-loader": "6.0.0",
                 "lint-staged": "^9.5.0",
                 "prettier": "^1.19.1",
+                "resize-observer-polyfill": "^1.5.1",
                 "typescript": "^4.2.3"
             }
         },
@@ -6163,6 +6164,7 @@
         },
         "node_modules/dns-packet": {
             "version": "1.3.4",
+            "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz",
             "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==",
             "dev": true,
             "dependencies": {
@@ -13759,6 +13761,7 @@
         },
         "node_modules/source-map-js": {
             "version": "0.6.2",
+            "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
             "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==",
             "engines": {
                 "node": ">=0.10.0"
@@ -21410,6 +21413,7 @@
         },
         "dns-packet": {
             "version": "1.3.4",
+            "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz",
             "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==",
             "dev": true,
             "requires": {
@@ -27513,6 +27517,7 @@
         },
         "source-map-js": {
             "version": "0.6.2",
+            "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
             "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug=="
         },
         "source-map-resolve": {

+ 1 - 0
package.json

@@ -50,6 +50,7 @@
         "less-loader": "6.0.0",
         "lint-staged": "^9.5.0",
         "prettier": "^1.19.1",
+        "resize-observer-polyfill": "^1.5.1",
         "typescript": "^4.2.3"
     }
 }

+ 8 - 6
src/common/components/capitalInfo/index.vue

@@ -19,27 +19,27 @@
         <tbody>
           <tr>
             <td>权益</td>
-            <td>{{showValue(tradeAccount.equity.toFixed(2))}}</td>
+            <td>{{showValue(formatAmount(tradeAccount.equity))}}</td>
           </tr>
           <tr>
             <td>余额</td>
-            <td>{{showValue(tradeAccount.currentbalance.toFixed(2))}}</td>
+            <td>{{showValue(formatAmount(tradeAccount.currentbalance))}}</td>
           </tr>
           <tr>
             <td>可用</td>
-            <td>{{showValue(tradeAccount.availableBalance.toFixed(2))}}</td>
+            <td>{{showValue(formatAmount(tradeAccount.availableBalance))}}</td>
           </tr>
           <tr>
             <td>占用</td>
-            <td>{{showValue(tradeAccount.usedmargin.toFixed(2))}}</td>
+            <td>{{showValue(formatAmount(tradeAccount.usedmargin))}}</td>
           </tr>
           <tr>
             <td>冻结</td>
-            <td>{{showValue(tradeAccount.freezeAmount.toFixed(2))}}</td>
+            <td>{{showValue(formatAmount(tradeAccount.freezeAmount))}}</td>
           </tr>
           <tr>
             <td>浮盈</td>
-            <td :class="{ 'up-quote-color': tradeAccount.positionProfitAndLoss > 0, 'down-quote-color': tradeAccount.positionProfitAndLoss < 0 } ">{{showValue(tradeAccount.positionProfitAndLoss.toFixed(2))}}</td>
+            <td :class="{ 'up-quote-color': tradeAccount.positionProfitAndLoss > 0, 'down-quote-color': tradeAccount.positionProfitAndLoss < 0 } ">{{showValue(formatAmount(tradeAccount.positionProfitAndLoss))}}</td>
           </tr>
           <tr>
             <td>风险率</td>
@@ -55,6 +55,7 @@
 import { defineComponent, ref } from 'vue';
 import { useTradeAccount } from '@/hooks/account'
 import { getPayCurrencyTypeEnumItemName } from '@/common/constants/enumsName';
+import { formatAmount } from '@/utils/number'
 
 export default defineComponent({
   name: 'capital-info',
@@ -75,6 +76,7 @@ export default defineComponent({
       showAction,
       tradeAccount,
       getPayCurrencyTypeEnumItemName,
+      formatAmount,
     };
   },
 });

+ 2 - 2
src/common/components/echart/echart-base/setup.ts

@@ -1,5 +1,5 @@
 import { onActivated, onDeactivated, onUnmounted, SetupContext, onMounted } from "vue";
-import { debounce } from "@/utils/time"
+import { _debounce } from "@/utils/time"
 import { getTheme, ThemeEnum } from '@/common/config/theme';
 import * as echarts from 'echarts'
 
@@ -60,7 +60,7 @@ export function useEchart(el: HTMLElement) {
 
     const onresize = () => {
         // 防抖函数待优化,同时调用多次timeoutId可能相同,导致后面的覆盖前面
-        debounce(() => {
+        _debounce(() => {
             // 重置图表大小
             echartMap.forEach((echart) => {
                 echart.resize && echart.resize();

+ 309 - 309
src/common/components/echart/echart-kline/index.vue

@@ -6,351 +6,351 @@
 import { defineComponent, PropType, ref, watch, watchEffect } from 'vue';
 import { QueryHistoryDatasRsp, QueryQuoteDayRsp, QueryHistoryDatas, CycleType } from '@/services/go/quote/interface';
 import { QueryHistoryDatas as queryHistoryDatas } from '@/services/go/quote';
-import { debounce } from '@/utils/time';
+import { _debounce } from '@/utils/time';
 import EchartBase from '../echart-base/index.vue';
 import { handleEchart, Source } from './setup';
 import moment from 'moment';
 
 export default defineComponent({
-    name: 'EchartKline',
-    components: {
-        EchartBase,
+  name: 'EchartKline',
+  components: {
+    EchartBase,
+  },
+  props: {
+    // 实时行情数据
+    quoteData: {
+      type: Object as PropType<QueryQuoteDayRsp>,
+      required: true,
     },
-    props: {
-        // 实时行情数据
-        quoteData: {
-            type: Object as PropType<QueryQuoteDayRsp>,
-            required: true,
-        },
-        // 周期类型
-        cycleType: {
-            type: Number as PropType<CycleType>,
-            required: true,
-        },
-        // 指标类型
-        seriesType: {
-            type: String,
-            default: 'MACD',
-        },
+    // 周期类型
+    cycleType: {
+      type: Number as PropType<CycleType>,
+      required: true,
     },
-    setup(props) {
-        const loading = ref(true);
-        const isEmpty = ref(false);
-        const historyIndexs: number[] = []; // 行情历史数据中所有非补充数据的索引位置(用于计算均线)
-        const { chartData, options, updateOptions, initOptions } = handleEchart();
+    // 指标类型
+    seriesType: {
+      type: String,
+      default: 'MACD',
+    },
+  },
+  setup(props) {
+    const loading = ref(true);
+    const isEmpty = ref(false);
+    const historyIndexs: number[] = []; // 行情历史数据中所有非补充数据的索引位置(用于计算均线)
+    const { chartData, options, updateOptions, initOptions } = handleEchart();
 
-        // 处理图表数据
-        const handleData = (rawData: QueryHistoryDatasRsp[]): void => {
-            const { source } = chartData.value;
-            source.length = 0;
-            historyIndexs.length = 0;
+    // 处理图表数据
+    const handleData = (rawData: QueryHistoryDatasRsp[]): void => {
+      const { source } = chartData.value;
+      source.length = 0;
+      historyIndexs.length = 0;
 
-            rawData.forEach((item, index) => {
-                const { o, c, h, l, ts, tv } = item;
-                source.push({
-                    date: moment(ts).format('YYYY-MM-DD HH:mm:ss'),
-                    open: o,
-                    close: c,
-                    lowest: l,
-                    highest: h,
-                    ma5: '-',
-                    ma10: '-',
-                    ma15: '-',
-                    vol: tv,
-                    macd: '-',
-                    dif: '-',
-                    dea: '-',
-                    k: '-',
-                    d: '-',
-                    j: '-',
-                    cci: '-',
-                });
-                if (!item.f) historyIndexs.push(index); // 排除补充数据
-            });
+      rawData.forEach((item, index) => {
+        const { o, c, h, l, ts, tv } = item;
+        source.push({
+          date: moment(ts).format('YYYY-MM-DD HH:mm:ss'),
+          open: o,
+          close: c,
+          lowest: l,
+          highest: h,
+          ma5: '-',
+          ma10: '-',
+          ma15: '-',
+          vol: tv,
+          macd: '-',
+          dif: '-',
+          dea: '-',
+          k: '-',
+          d: '-',
+          j: '-',
+          cci: '-',
+        });
+        if (!item.f) historyIndexs.push(index); // 排除补充数据
+      });
 
-            calcMA('ma5', 5);
-            calcMA('ma10', 10);
-            calcMA('ma15', 15);
-            calcMACD();
-            calcKDJ();
-            clacCCI();
-        };
+      calcMA('ma5', 5);
+      calcMA('ma10', 10);
+      calcMA('ma15', 15);
+      calcMACD();
+      calcKDJ();
+      clacCCI();
+    };
 
-        // 计算平均线
-        const calcMA = (key: keyof Source, count: number) => {
-            const { source } = chartData.value;
-            let result: Source[keyof Source] = '-';
+    // 计算平均线
+    const calcMA = (key: keyof Source, count: number) => {
+      const { source } = chartData.value;
+      let result: Source[keyof Source] = '-';
 
-            if (source.length >= count) {
-                // 均线起始位置
-                const startIndex = historyIndexs[count - 1];
-                for (let i = 0; i < source.length; i++) {
-                    if (startIndex !== undefined && i > startIndex) {
-                        const j = historyIndexs.findIndex((val) => val === i);
-                        // 判断是否补充数据
-                        if (j === -1) {
-                            result = source[i - 1][key]; // 取上个平均值
-                        } else {
-                            // 向后取MA数
-                            const maIndexs = historyIndexs.slice(j - (count - 1), j + 1);
-                            // 计算总价
-                            const total = maIndexs.reduce((sum, val) => sum + source[val].close, 0);
-                            // 计算均线
-                            result = (total / count).toFixed(2);
-                        }
-                    }
-                    (<typeof result>source[i][key]) = result;
-                }
+      if (source.length >= count) {
+        // 均线起始位置
+        const startIndex = historyIndexs[count - 1];
+        for (let i = 0; i < source.length; i++) {
+          if (startIndex !== undefined && i > startIndex) {
+            const j = historyIndexs.findIndex((val) => val === i);
+            // 判断是否补充数据
+            if (j === -1) {
+              result = source[i - 1][key]; // 取上个平均值
+            } else {
+              // 向后取MA数
+              const maIndexs = historyIndexs.slice(j - (count - 1), j + 1);
+              // 计算总价
+              const total = maIndexs.reduce((sum, val) => sum + source[val].close, 0);
+              // 计算均线
+              result = (total / count).toFixed(2);
             }
-        };
+          }
+          (<typeof result>source[i][key]) = result;
+        }
+      }
+    };
 
-        // 计算EMA
-        const calcEMA = (close: number[], n: number) => {
-            const ema: number[] = [],
-                a = 2 / (n + 1); // 平滑系数
-            for (let i = 0; i < close.length; i++) {
-                if (i === 0) {
-                    //第一个EMA(n)是前n个收盘价代数平均
-                    const result = close.slice(0, n).reduce((sum, val) => sum + val, 0) / n;
-                    ema.push(result);
-                } else {
-                    // EMA(n) = α × Close + (1 - α) × EMA(n - 1)
-                    const result = a * close[i] + (1 - a) * ema[i - 1];
-                    ema.push(result);
-                }
-            }
-            return ema;
-        };
+    // 计算EMA
+    const calcEMA = (close: number[], n: number) => {
+      const ema: number[] = [],
+        a = 2 / (n + 1); // 平滑系数
+      for (let i = 0; i < close.length; i++) {
+        if (i === 0) {
+          //第一个EMA(n)是前n个收盘价代数平均
+          const result = close.slice(0, n).reduce((sum, val) => sum + val, 0) / n;
+          ema.push(result);
+        } else {
+          // EMA(n) = α × Close + (1 - α) × EMA(n - 1)
+          const result = a * close[i] + (1 - a) * ema[i - 1];
+          ema.push(result);
+        }
+      }
+      return ema;
+    };
 
-        // 计算DEA
-        const calcDEA = (dif: number[]) => {
-            return calcEMA(dif, 9);
-        };
+    // 计算DEA
+    const calcDEA = (dif: number[]) => {
+      return calcEMA(dif, 9);
+    };
 
-        // 计算DIF
-        const calcDIF = (close: number[]) => {
-            const dif: number[] = [],
-                emaShort = calcEMA(close, 12),
-                emaLong = calcEMA(close, 26);
+    // 计算DIF
+    const calcDIF = (close: number[]) => {
+      const dif: number[] = [],
+        emaShort = calcEMA(close, 12),
+        emaLong = calcEMA(close, 26);
 
-            for (let i = 0; i < close.length; i++) {
-                const result = emaShort[i] - emaLong[i];
-                dif.push(result);
-            }
-            return dif;
-        };
+      for (let i = 0; i < close.length; i++) {
+        const result = emaShort[i] - emaLong[i];
+        dif.push(result);
+      }
+      return dif;
+    };
 
-        // 计算MACD
-        const calcMACD = () => {
-            const { source } = chartData.value,
-                close = source.map((item) => item.close),
-                dif = calcDIF(close),
-                dea = calcDEA(dif);
+    // 计算MACD
+    const calcMACD = () => {
+      const { source } = chartData.value,
+        close = source.map((item) => item.close),
+        dif = calcDIF(close),
+        dea = calcDEA(dif);
 
-            for (let i = 0; i < source.length; i++) {
-                source[i].dif = dif[i].toFixed(2);
-                source[i].dea = dea[i].toFixed(2);
-                source[i].macd = ((dif[i] - dea[i]) * 2).toFixed(2);
-            }
-        };
+      for (let i = 0; i < source.length; i++) {
+        source[i].dif = dif[i].toFixed(2);
+        source[i].dea = dea[i].toFixed(2);
+        source[i].macd = ((dif[i] - dea[i]) * 2).toFixed(2);
+      }
+    };
 
-        // 计算KDJ
-        const calcKDJ = () => {
-            const { source } = chartData.value;
-            for (let i = 0; i < source.length; i++) {
-                const item = source[i];
-                if (i < 8) {
-                    item.k = '-';
-                    item.d = '-';
-                    item.j = '-';
-                } else {
-                    let rsv = 50; // 如果最低价等于最高价,RSV默认值为50
-                    if (item.lowest !== item.highest) {
-                        const n9 = source.slice(i - 8, i + 1).map((item) => item.close), // 取前9个收盘价
-                            max = Math.max(...n9),
-                            min = Math.min(...n9);
-                        // 计算RSV
-                        rsv = ((item.close - min) / (max - min)) * 100;
-                    }
+    // 计算KDJ
+    const calcKDJ = () => {
+      const { source } = chartData.value;
+      for (let i = 0; i < source.length; i++) {
+        const item = source[i];
+        if (i < 8) {
+          item.k = '-';
+          item.d = '-';
+          item.j = '-';
+        } else {
+          let rsv = 50; // 如果最低价等于最高价,RSV默认值为50
+          if (item.lowest !== item.highest) {
+            const n9 = source.slice(i - 8, i + 1).map((item) => item.close), // 取前9个收盘价
+              max = Math.max(...n9),
+              min = Math.min(...n9);
+            // 计算RSV
+            rsv = ((item.close - min) / (max - min)) * 100;
+          }
 
-                    const yestK = Number(source[i - 1].k); // 取前一日K值
-                    const yestD = Number(source[i - 1].d); // 取前一日D值
+          const yestK = Number(source[i - 1].k); // 取前一日K值
+          const yestD = Number(source[i - 1].d); // 取前一日D值
 
-                    if (isNaN(yestK) || isNaN(yestD)) {
-                        // 如果前一日的K值或D值不存在则默认值为50
-                        item.k = '50';
-                        item.d = '50';
-                        item.j = '50';
-                    } else {
-                        const k = (2 / 3) * yestK + (1 / 3) * rsv,
-                            d = (2 / 3) * yestD + (1 / 3) * yestK,
-                            j = 3 * k - 2 * d;
+          if (isNaN(yestK) || isNaN(yestD)) {
+            // 如果前一日的K值或D值不存在则默认值为50
+            item.k = '50';
+            item.d = '50';
+            item.j = '50';
+          } else {
+            const k = (2 / 3) * yestK + (1 / 3) * rsv,
+              d = (2 / 3) * yestD + (1 / 3) * yestK,
+              j = 3 * k - 2 * d;
 
-                        item.k = k.toFixed(2);
-                        item.d = d.toFixed(2);
-                        item.j = j.toFixed(2);
-                    }
-                }
-            }
-        };
+            item.k = k.toFixed(2);
+            item.d = d.toFixed(2);
+            item.j = j.toFixed(2);
+          }
+        }
+      }
+    };
 
-        // 计算CCI
-        const clacCCI = () => {
-            const { source } = chartData.value;
-            for (let i = 0; i < source.length; i++) {
-                const item = source[i];
-                if (i < 13) {
-                    item.cci = '-';
-                } else {
-                    const tp = (item.close + item.lowest + item.highest) / 3, // (收盘价 + 最低价 + 最高价) / 3
-                        n14 = source.slice(i - 13, i + 1), // 取前14条数据
-                        ma = n14.reduce((sum, e) => sum + (e.close + e.lowest + e.highest) / 3, 0) / 14, // 计算前14条数据的(TP)价总和÷N
-                        md = n14.reduce((sum, e) => sum + Math.abs(ma - (e.close + e.lowest + e.highest) / 3), 0) / 14, // 计算前14条数据的(MA-TP)价总和÷N
-                        result = (tp - ma) / md / 0.015;
+    // 计算CCI
+    const clacCCI = () => {
+      const { source } = chartData.value;
+      for (let i = 0; i < source.length; i++) {
+        const item = source[i];
+        if (i < 13) {
+          item.cci = '-';
+        } else {
+          const tp = (item.close + item.lowest + item.highest) / 3, // (收盘价 + 最低价 + 最高价) / 3
+            n14 = source.slice(i - 13, i + 1), // 取前14条数据
+            ma = n14.reduce((sum, e) => sum + (e.close + e.lowest + e.highest) / 3, 0) / 14, // 计算前14条数据的(TP)价总和÷N
+            md = n14.reduce((sum, e) => sum + Math.abs(ma - (e.close + e.lowest + e.highest) / 3), 0) / 14, // 计算前14条数据的(MA-TP)价总和÷N
+            result = (tp - ma) / md / 0.015;
 
-                    item.cci = result.toFixed(2);
-                }
-            }
-        };
+          item.cci = result.toFixed(2);
+        }
+      }
+    };
 
-        // 更新图表K线数据
-        const updateChartData = () => {
-            const { source } = chartData.value,
-                lastIndex = source.length - 1, // 历史行情最后索引位置
-                lastTime = moment(source[lastIndex].date), // 历史行情最后时间
-                newTime = moment(props.quoteData.lasttime), // 实时行情最新时间
-                newPrice = props.quoteData.last; // 实时行情最新价
+    // 更新图表K线数据
+    const updateChartData = () => {
+      const { source } = chartData.value,
+        lastIndex = source.length - 1, // 历史行情最后索引位置
+        lastTime = moment(source[lastIndex].date), // 历史行情最后时间
+        newTime = moment(props.quoteData.lasttime), // 实时行情最新时间
+        newPrice = props.quoteData.last; // 实时行情最新价
 
-            let cycleMilliseconds = 60 * 1000; // 周期毫秒数
+      let cycleMilliseconds = 60 * 1000; // 周期毫秒数
 
-            switch (props.cycleType) {
-                case CycleType.minutes5:
-                    cycleMilliseconds *= 5;
-                    break;
-                case CycleType.minutes30:
-                    cycleMilliseconds *= 30;
-                    break;
-                case CycleType.minutes60:
-                    cycleMilliseconds *= 60;
-                    break;
-                case CycleType.hours2:
-                    cycleMilliseconds *= 2 * 60;
-                    break;
-                case CycleType.Hours4:
-                    cycleMilliseconds *= 4 * 60;
-                    break;
-                case CycleType.days:
-                    cycleMilliseconds *= 24 * 60;
-                    break;
-            }
+      switch (props.cycleType) {
+        case CycleType.minutes5:
+          cycleMilliseconds *= 5;
+          break;
+        case CycleType.minutes30:
+          cycleMilliseconds *= 30;
+          break;
+        case CycleType.minutes60:
+          cycleMilliseconds *= 60;
+          break;
+        case CycleType.hours2:
+          cycleMilliseconds *= 2 * 60;
+          break;
+        case CycleType.Hours4:
+          cycleMilliseconds *= 4 * 60;
+          break;
+        case CycleType.days:
+          cycleMilliseconds *= 24 * 60;
+          break;
+      }
 
-            const diffTime = newTime.valueOf() - lastTime.valueOf(); // 计算时间差
+      const diffTime = newTime.valueOf() - lastTime.valueOf(); // 计算时间差
 
-            if (diffTime > cycleMilliseconds * 2) {
-                // 时间间隔超过两个周期,重新请求历史数据
-            } else {
-                // 判断时间差是否大于周期时间
-                if (diffTime > cycleMilliseconds) {
-                    lastTime.add(cycleMilliseconds, 'ms');
-                    // 添加历史行情
-                    source.push({
-                        date: lastTime.format('YYYY-MM-DD HH:mm:ss'),
-                        open: newPrice,
-                        close: newPrice,
-                        lowest: newPrice,
-                        highest: newPrice,
-                        ma5: '-',
-                        ma10: '-',
-                        ma15: '-',
-                        vol: 0,
-                        macd: '-',
-                        dif: '-',
-                        dea: '-',
-                        k: '-',
-                        d: '-',
-                        j: '-',
-                        cci: '-',
-                    });
-                    historyIndexs.push(lastIndex + 1); // 添加历史行情索引
-                } else {
-                    const lastData = source[lastIndex];
-                    if (lastData.lowest > newPrice) {
-                        lastData.lowest = newPrice; //更新最低价
-                    }
-                    if (lastData.highest < newPrice) {
-                        lastData.highest = newPrice; //更新最高价
-                    }
-                    lastData.close = newPrice; //更新收盘价
-                }
+      if (diffTime > cycleMilliseconds * 2) {
+        // 时间间隔超过两个周期,重新请求历史数据
+      } else {
+        // 判断时间差是否大于周期时间
+        if (diffTime > cycleMilliseconds) {
+          lastTime.add(cycleMilliseconds, 'ms');
+          // 添加历史行情
+          source.push({
+            date: lastTime.format('YYYY-MM-DD HH:mm:ss'),
+            open: newPrice,
+            close: newPrice,
+            lowest: newPrice,
+            highest: newPrice,
+            ma5: '-',
+            ma10: '-',
+            ma15: '-',
+            vol: 0,
+            macd: '-',
+            dif: '-',
+            dea: '-',
+            k: '-',
+            d: '-',
+            j: '-',
+            cci: '-',
+          });
+          historyIndexs.push(lastIndex + 1); // 添加历史行情索引
+        } else {
+          const lastData = source[lastIndex];
+          if (lastData.lowest > newPrice) {
+            lastData.lowest = newPrice; //更新最低价
+          }
+          if (lastData.highest < newPrice) {
+            lastData.highest = newPrice; //更新最高价
+          }
+          lastData.close = newPrice; //更新收盘价
+        }
 
-                calcMA('ma5', 5);
-                calcMA('ma10', 10);
-                calcMA('ma15', 15);
-                calcMACD();
-                calcKDJ();
-                clacCCI();
+        calcMA('ma5', 5);
+        calcMA('ma10', 10);
+        calcMA('ma15', 15);
+        calcMACD();
+        calcKDJ();
+        clacCCI();
 
-                // 延迟图表更新,减少卡顿
-                debounce(() => {
-                    updateOptions(props.seriesType);
-                }, 1000);
-            }
-        };
+        // 延迟图表更新,减少卡顿
+        _debounce(() => {
+          updateOptions(props.seriesType);
+        }, 1000);
+      }
+    };
 
-        // 监听行情最新价推送
-        watch(
-            () => props.quoteData.last,
-            () => {
-                if (!loading.value) {
-                    updateChartData();
-                }
-            }
-        );
+    // 监听行情最新价推送
+    watch(
+      () => props.quoteData.last,
+      () => {
+        if (!loading.value) {
+          updateChartData();
+        }
+      }
+    );
 
-        // 监听指标类型
-        watch(
-            () => props.seriesType,
-            (val) => {
-                if (!loading.value) {
-                    updateOptions(val);
-                }
-            }
-        );
+    // 监听指标类型
+    watch(
+      () => props.seriesType,
+      (val) => {
+        if (!loading.value) {
+          updateOptions(val);
+        }
+      }
+    );
 
-        // 监听周期选择变化
-        watchEffect(() => {
-            loading.value = true;
-            const params: QueryHistoryDatas = {
-                cycleType: props.cycleType,
-                goodsCode: props.quoteData.goodscode.toUpperCase(),
-                count: 1440,
-            };
-            // 查询K线数据
-            queryHistoryDatas(params)
-                .then((res) => {
-                    if (res.length) {
-                        isEmpty.value = false;
-                        // 日期升序排序
-                        const kdata = res.sort((a, b) => moment(a.ts).valueOf() - moment(b.ts).valueOf());
-                        handleData(kdata);
-                    } else {
-                        isEmpty.value = true;
-                    }
-                    initOptions(props.seriesType);
-                })
-                .catch(() => {
-                    isEmpty.value = true;
-                })
-                .finally(() => {
-                    loading.value = false;
-                });
+    // 监听周期选择变化
+    watchEffect(() => {
+      loading.value = true;
+      const params: QueryHistoryDatas = {
+        cycleType: props.cycleType,
+        goodsCode: props.quoteData.goodscode.toUpperCase(),
+        count: 1440,
+      };
+      // 查询K线数据
+      queryHistoryDatas(params)
+        .then((res) => {
+          if (res.length) {
+            isEmpty.value = false;
+            // 日期升序排序
+            const kdata = res.sort((a, b) => moment(a.ts).valueOf() - moment(b.ts).valueOf());
+            handleData(kdata);
+          } else {
+            isEmpty.value = true;
+          }
+          initOptions(props.seriesType);
+        })
+        .catch(() => {
+          isEmpty.value = true;
+        })
+        .finally(() => {
+          loading.value = false;
         });
+    });
 
-        return {
-            loading,
-            isEmpty,
-            options,
-        };
-    },
+    return {
+      loading,
+      isEmpty,
+      options,
+    };
+  },
 });
 </script>

+ 2 - 2
src/common/components/echart/echart-timeline/index.vue

@@ -6,7 +6,7 @@
 import { defineComponent, ref, watch, PropType, onMounted, computed } from 'vue';
 import { QueryTSDataRsp, QueryQuoteDayRsp } from '@/services/go/quote/interface';
 import { QueryTSData } from '@/services/go/quote';
-import { debounce, getRangeTime } from '@/utils/time';
+import { _debounce, getRangeTime } from '@/utils/time';
 import { toDecimalFull } from '@/utils/number';
 import EchartBase from '../echart-base/index.vue';
 import { handleEchart } from './setup';
@@ -158,7 +158,7 @@ export default defineComponent({
       chartData.value.max = max;
 
       // 延迟图表更新,减少卡顿
-      debounce(() => {
+      _debounce(() => {
         updateOptions();
       }, 1000);
     };

+ 44 - 0
src/common/components/resize/index.vue

@@ -0,0 +1,44 @@
+<template>
+  <div ref="resize" class="resize">
+    <slot :scroll="scroll"></slot>
+  </div>
+</template>
+
+<script lang="ts">
+import { defineComponent, ref, onMounted } from 'vue';
+import { debounce } from '@/utils/time'
+import ResizeObserver from 'resize-observer-polyfill';
+
+export default defineComponent({
+  setup() {
+    // 表格滚动区域宽高
+    const scroll = ref({
+      x: '100%',
+      y: '100%',
+    })
+
+    const resize = ref<HTMLDivElement>()
+
+    onMounted(() => {
+      // 监听元素变化
+      const resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {
+        debounce(() => {
+          for (const entry of entries) {
+            const { left, top, width, height } = entry.contentRect;
+            console.log(left, top, width, height)
+            scroll.value.y = height + 'px';
+          }
+        })
+      });
+      if (resize.value) {
+        resizeObserver.observe(resize.value);
+      }
+    })
+
+    return {
+      scroll,
+      resize,
+    }
+  },
+})
+</script>

+ 3 - 1
src/hooks/account/index.ts

@@ -70,13 +70,15 @@ export function useTradeAccount() {
 
         const account = tradeAccountList.find((account) => account.accountid === accountId);
         if (account) {
-            tradePositionList.length = 0;
             tradeAccount.value = account;
             tradePositionList.push(...account.positionList);
             setSelectedAccount(account); // 为了兼容以前代码,待优化后期废除
 
             // 开始行情订阅
             stopSubcribe = subcriteGoodsQuote(account.positionList.map((e) => e.goodscode));
+        } else {
+            tradeAccount.value = undefined;
+            tradePositionList.length = 0;
         }
     }
 

+ 5 - 2
src/layout/components/bottom.vue

@@ -5,7 +5,7 @@
       <firstMenu :list="orderList" :value="'title'" @selectMenu="selectMenu">
         <div class="right-menu-content">
           <!-- 资金信息 -->
-          <a-select class="capitalSelect" style="width: 180px" @change="tradeAccountChange" v-model:value="selectedAccountId">
+          <a-select class="capitalSelect" style="width: 180px" placeholder="请选择账户" @change="tradeAccountChange" v-model:value="selectedAccountId">
             <a-select-option v-for="item in tradeAccountList" :value="item.accountid" :key="item.accountid">{{item.accountid}}</a-select-option>
           </a-select>
           <div class="conditionIcon icon iconfont icon-shouqi" @click="handleShowBottom"></div>
@@ -52,7 +52,7 @@ export default defineComponent({
     const { tradeAccountList, getTradeAccountList, tradeAccountChange } = useTradeAccount();
     const { orderList, componentId } = handleOrderData();
     const selectedAccount = getSelectedAccount();
-    const selectedAccountId = ref<number>(selectedAccount.accountid);
+    const selectedAccountId = ref(selectedAccount.accountid || undefined);
 
     // 资金变化,重新加载数据
     Bus.$on('moneyChangedNtf_UI', () => {
@@ -101,6 +101,9 @@ export default defineComponent({
         .ant-select-arrow {
             top: 15px;
         }
+        .ant-select-selection-placeholder {
+            color: @m-grey10;
+        }
     }
 }
 .layout-bottom-all {

+ 0 - 2
src/main.ts

@@ -8,10 +8,8 @@ import Antd, { message } from 'ant-design-vue';
 import { createApp } from 'vue';
 import App from './App.vue';
 import router from './router';
-import directive from "./views/market/futures/directive"; // 自定义指令集
 
 const app = createApp(App);
-app.use(directive);
 app.use(router);
 app.use(Antd).mount('#app');
 

+ 1 - 1
src/services/bus/goods.ts

@@ -149,7 +149,7 @@ export function getGoodsQuoteList(exchangeId?: number): GoodsQuote[] {
     }
 
     // 按照 goodscode 字母升序排序
-    goodsList = goodsList.filter((e) => e.goodsstatus === 3).sort((a, b) => a.goodscode.charCodeAt(0) - b.goodscode.charCodeAt(0));
+    goodsList = goodsList.filter((e) => e.goodsstatus === 3).sort((a, b) => a.goodscode.localeCompare(b.goodscode));
 
     return goodsList.map((el) => {
         const item: GoodsQuote = {

+ 1 - 1
src/services/proto/futures/index.ts

@@ -9,7 +9,7 @@ import { getLoginData } from '@/services/bus/login'
 export const channelOrderReq = (param: ChannelOrderReq): Promise<ChannelOrderRsp> => {
     return protoMiddleware<ChannelOrderReq>(param, 'ChannelOrderReq', 'ChannelOrderRsp', {
         AccountID: param.AccountID,
-        AccountID2: getLoginData().ClientID ?? 0,
+        AccountID2: getLoginData().ClientID,
         MarketID: param.MarketID,
         GoodsID: param.MarketID,
     })

+ 1 - 1
src/services/socket/login/interface/loginQuery.ts

@@ -29,7 +29,7 @@ export interface LoginResponse extends checkTokenRes {
 
 export interface checkTokenRes {
     AccountIDs: any[];
-    ClientID: any;
+    ClientID: LongType;
     Header: Header;
     LoginID: LongType;
     LoginUserType: number;

+ 5 - 3
src/services/socket/order/index.ts

@@ -2,9 +2,10 @@
 import { DelistingType, OperateType, OptionType, PriceType } from '@/common/constants/enumCommon';
 import APP from '@/services';
 import { getUserId } from '@/services/bus/user';
-import { geLoginID_number } from '@/services/bus/login';
+import { geLoginID_number, getLoginData } from '@/services/bus/login';
 import { OrderReq } from "@/services/socket/order/interface";
 import { buildProtoReq50, parseProtoRsp50, protoMiddleware } from '@/services/socket/protobuf/buildReq';
+import { SoleSearchParam } from '@/services/socket/protobuf/interface';
 import { Callback } from '@/utils/websocket/index';
 import moment from 'moment';
 import { v4 as uuidv4 } from 'uuid';
@@ -80,7 +81,7 @@ export const orderReq = (param: orderType.OrderReqType): Promise<string> => {
  */
 export const cancelOrderReq = (param: orderType.CancelOrderReq): Promise<string> => {
     return new Promise((resolve, reject) => {
-        const params = {
+        const params: SoleSearchParam = {
             protobufName: 'CancelOrderReq',
             funCodeName: 'CancelOrderReq',
             reqParams: {
@@ -93,8 +94,9 @@ export const cancelOrderReq = (param: orderType.CancelOrderReq): Promise<string>
                 OldOrderId: param.OldOrderId, // 原委托单号
                 AccountID: param.AccountID, // 交易账号
             },
-            headParam: {
+            Header: {
                 AccountID: param.AccountID,
+                AccountID2: getLoginData().ClientID,
                 MarketID: param.MarketID,
                 GoodsID: param.GoodsID,
             },

+ 18 - 6
src/utils/number/index.ts

@@ -22,15 +22,15 @@ export function getDecimalsNum(val: any, decimal = 2, maxCount = 6) {
 
 /**
  * 强制保留小数位,零位四舍五入取整
- * @param val 
- * @param decimal 需要保留小数位 默认2 
+ * @param value 
+ * @param decimal 保留小数位 默认2 
  * @returns 
  */
-export function toDecimalFull(val: number, decimal = 2) {
+export function toDecimalFull(value: number, decimal = 2) {
     if (decimal <= 0) {
-        return Math.round(val).toString();
+        return Math.round(value).toString();
     } else {
-        let str = val.toString();
+        let str = value.toString();
         const num = str.indexOf('.');
         if (num < 0) {
             // 小数位自动补零
@@ -43,6 +43,18 @@ export function toDecimalFull(val: number, decimal = 2) {
             }
             return str;
         }
-        return val.toFixed(decimal);
+        return value.toFixed(decimal);
     }
 }
+
+/**
+ * 数字转千位符金额
+ * @param value 金额数值
+ * @param decimal 保留小数位 默认2 
+ */
+export function formatAmount(value: number, decimal = 2) {
+    const reg = new RegExp('(\\d)(?=(\\d{3})+$)', 'ig');
+    const result = value.toFixed(decimal).toString().split('.');
+    result[0] = result[0].replace(reg, '$1,');
+    return result.join('.');
+}

+ 50 - 1
src/utils/time/index.ts

@@ -44,12 +44,13 @@ export function getRangeTime(val1: Time, val2: Time, type = 'YYYYMMDD', unit: un
 }
 
 /**
+ * ------------------------------------------------------------------待优化后期废除
  * 防抖(debounce)
  * @param fn 需要防抖的函数
  * @param wait 毫秒,防抖期限值
  * @returns
  */
-export function debounce(fn: () => void, wait: number, timer: keyof TimeoutTimerNames = 'debounce'): void {
+export function _debounce(fn: () => void, wait: number, timer: keyof TimeoutTimerNames = 'debounce'): void {
     return (function () {
         timerUtil.clearTimeout(timer);
         timerUtil.setTimeout(fn, wait, timer);
@@ -70,4 +71,52 @@ export function sortTime<T extends object>(arr: T[], key: keyof T, isUp = true)
         return isUp ? time1 - time2 : time2 - time1;
     });
     return result;
+}
+
+const debounceMap = new Map<string, number>();
+const throttleMap = new Map<string, number>();
+
+/**
+ * 函数防抖 (等待触发)
+ * @param callback 到期时间执行的回调
+ * @param ms 延迟毫秒数,默认100毫秒
+ * @param timeoutId 防抖ID
+ * @returns 
+ */
+export function debounce(callback: () => void, ms = 100, timeoutId = 'timer') {
+    const timer = window.setTimeout(() => {
+        debounceMap.delete(timeoutId);
+        callback();
+    }, ms)
+
+    if (debounceMap.has(timeoutId)) {
+        const t = debounceMap.get(timeoutId);
+        clearTimeout(t);
+    }
+
+    debounceMap.set(timeoutId, timer);
+}
+
+/**
+ * 函数节流 (间隔触发)
+ * @param callback 到期时间执行的回调
+ * @param ms 间隔毫秒数,默认100毫秒
+ * @param timeoutId 节流ID
+ * @returns 
+ */
+export function throttle<T>(callback: (event: T) => void, ms = 100, timeoutId = 'timer') {
+    if (!throttleMap.has(timeoutId)) {
+        throttleMap.set(timeoutId, 0);
+    }
+
+    let timer = throttleMap.get(timeoutId);
+
+    return function (params?: T) {
+        if (timer) return;
+        timer = window.setTimeout(() => {
+            timer = 0;
+            throttleMap.delete(timeoutId);
+            callback(params as T);
+        }, ms);
+    }
 }

+ 1 - 1
src/views/market/futures/compoments/futures-trade/index.vue

@@ -108,7 +108,7 @@ export default defineComponent({
     const selectedGoods = ref<GoodsQuote>(getGoods(props.selectedRow.goodsid));
 
     if (!selectedGoods.value) {
-      message.error('合约不存在,不能平仓!');
+      message.error('合约不存在,不能交易!');
       cancel();
     }
 

+ 0 - 14
src/views/market/futures/directive.ts

@@ -1,14 +0,0 @@
-
-import { App, Component } from 'vue';
-
-const install: Component = (app: App) => {
-    app.directive('resize', {
-        mounted(el, binding) {
-            debugger
-        },
-    })
-}
-
-export default {
-    install,
-}

+ 2 - 0
src/views/market/futures/index.vue

@@ -26,10 +26,12 @@ import { TableEventCB } from '@/common/setup/table/interface';
 import { getTableEvent } from '@/common/export/table';
 import { ContextMenuTemp } from '@/common/components/contextMenu/interface';
 import { BtnListType } from '@/common/components/btnList/interface';
+import MtpResize from '@/common/components/resize/index.vue'
 
 export default defineComponent({
   name: 'spot_trade_order_transaction_swap',
   components: {
+    MtpResize,
     ThridMenu,
     contextMenu,
     chart: defineAsyncComponent(() => import('../spot_trade/components/goods-chart/index.vue')),

+ 1 - 1
src/views/order/funding_information/components/funding_information_funding_summary/index.vue

@@ -15,7 +15,7 @@ import { handleComposeOrderTable } from '@/common/setup/table/compose';
 import { ComposeOrderTableParam } from '@/common/setup/table/interface';
 import { Taaccount } from '@/services/go/TaAccount/interface';
 import { getColumns } from './setup';
-import { useTradeAccount } from '@/hooks/account'
+import { useTradeAccount } from '@/hooks/account';
 
 export default defineComponent({
   name: enumOrderComponents.funding_information_funding_summary,

+ 9 - 4
src/views/order/funding_information/components/funding_information_funding_summary/setup.tsx

@@ -1,5 +1,6 @@
 import { Taaccount } from '@/services/go/TaAccount/interface';
 import { getTaacountStatus, getPayCurrencyTypeEnumItemName } from '@/common/constants/enumsName';
+import { formatAmount } from '@/utils/number';
 
 export function getColumns() {
     const columns = [
@@ -17,41 +18,45 @@ export function getColumns() {
         {
             title: '当前权益',
             key: 'equity',
-            customRender: ({ text }: { text: number }) => text.toFixed(2)
+            customRender: ({ text }: { text: number }) => formatAmount(text)
         },
         {
             title: '可用资金',
             key: 'availableBalance',
-            customRender: ({ text }: { text: number }) => text.toFixed(2)
+            customRender: ({ text }: { text: number }) => formatAmount(text)
         },
         {
             title: '占用资金',
             key: 'usedmargin',
+            customRender: ({ text }: { text: number }) => formatAmount(text)
         },
         {
             title: '冻结金额',
             key: 'freezeAmount',
-            customRender: ({ text }: { text: number }) => text.toFixed(2)
+            customRender: ({ text }: { text: number }) => formatAmount(text)
         },
         {
             title: '持仓盈亏',
             key: 'positionProfitAndLoss',
             customRender: ({ text }: { text: number }) => {
                 if (text === 0) return 0;
-                return handlePriceColor(text, text.toFixed(2));
+                return handlePriceColor(text, formatAmount(text));
             }
         },
         {
             title: '平仓盈亏',
             key: 'closepl',
+            customRender: ({ text }: { text: number }) => formatAmount(text)
         },
         {
             title: '入金',
             key: 'inamount',
+            customRender: ({ text }: { text: number }) => formatAmount(text)
         },
         {
             title: '出金',
             key: 'outamount',
+            customRender: ({ text }: { text: number }) => formatAmount(text)
         },
         {
             title: '状态',

File diff ditekan karena terlalu besar
+ 640 - 800
yarn.lock


Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini