li.shaoyi 2 лет назад
Родитель
Сommit
988cd8e76d

+ 1 - 1
.env.gstj

@@ -2,4 +2,4 @@ VUE_APP_ENV = 'gstj'
 VUE_APP_NAME = 甘肃碳交
 VUE_APP_ROOT = src/packages/gstj/
 VUE_APP_OEM = oem/gstj/
-VUE_APP_TRADE_CHANNEL = http
+VUE_APP_TRADE_CHANNEL = ws

+ 1 - 1
.env.mobile

@@ -1,4 +1,4 @@
 VUE_APP_ENV = 'mobile'
 VUE_APP_NAME = 多元世纪
 VUE_APP_ROOT = src/packages/mobile/
-VUE_APP_TRADE_CHANNEL = http
+VUE_APP_TRADE_CHANNEL = ws

+ 1 - 1
.env.qdhs

@@ -2,4 +2,4 @@ VUE_APP_ENV = 'qdhs'
 VUE_APP_NAME = 青岛海商
 VUE_APP_ROOT = src/packages/qdhs/
 VUE_APP_OEM = oem/qdhs/
-VUE_APP_TRADE_CHANNEL = http
+VUE_APP_TRADE_CHANNEL = ws

+ 1 - 1
.env.sbyj

@@ -2,4 +2,4 @@ VUE_APP_ENV = 'sbyj'
 VUE_APP_NAME = 水贝亿爵
 VUE_APP_ROOT = src/packages/sbyj/
 VUE_APP_OEM = oem/sbyj/
-VUE_APP_TRADE_CHANNEL = http
+VUE_APP_TRADE_CHANNEL = ws

+ 1 - 1
.env.tc

@@ -2,4 +2,4 @@ VUE_APP_ENV = 'tc'
 VUE_APP_NAME = 探茶
 VUE_APP_ROOT = src/packages/tc/
 VUE_APP_OEM = oem/tc/
-VUE_APP_TRADE_CHANNEL = http
+VUE_APP_TRADE_CHANNEL = ws

+ 2 - 2
app/package.json

@@ -1,6 +1,6 @@
 {
-  "name": "trading",
-  "version": "1.0.24",
+  "name": "trading-beta",
+  "version": "1.0.25",
   "main": "main.js",
   "dependencies": {
     "electron-updater": "^6.1.4",

+ 2 - 2
oem/gstj/config/appconfig.json

@@ -1,8 +1,8 @@
 {
   "appId": "com.muchinfo.gstj",
   "appName": "甘肃碳交",
-  "version": "1.0.14",
-  "versionCode": "100014",
+  "version": "1.0.15",
+  "versionCode": "100015",
   "apiUrl": "http://192.168.31.204:8080/cfg?key=test_204",
   "tradeChannel": "http",
   "modules": [

+ 4 - 4
oem/qxst/config/appconfig.json

@@ -1,10 +1,10 @@
 {
   "appId": "com.muchinfo.qxst",
-  "appName": "贵数字化中心",
-  "version": "1.0.24",
-  "versionCode": "100024",
+  "appName": "贵茶数字化",
+  "version": "1.0.25",
+  "versionCode": "100025",
   "apiUrl": "http://192.168.31.204:8080/cfg?key=test_204",
-  "tradeChannel": "ws",
+  "tradeChannel": "http",
   "modules": [
     "register"
   ],

+ 3 - 3
oem/sbyj/config/appconfig.json

@@ -1,10 +1,10 @@
 {
   "appId": "com.muchinfo.sbyj",
   "appName": "水贝亿爵",
-  "version": "1.0.0",
-  "versionCode": "100000",
+  "version": "1.0.2",
+  "versionCode": "100002",
   "apiUrl": "http://192.168.31.171:8080/cfg?key=test_171",
-  "tradeChannel": "http",
+  "tradeChannel": "ws",
   "modules": [
     "register",
     "delivery"

+ 3 - 3
oem/sbyj/manifest.json

@@ -2,12 +2,12 @@
     "@platforms" : [ "android", "iPhone", "iPad" ],
     "id" : "H5E4A9458",
     /*应用的标识*/
-    "name" : "水贝亿爵演示版",
+    "name" : "水贝亿爵",
     /*应用名称,程序桌面图标名称*/
     "version" : {
-        "name" : "1.0.0",
+        "name" : "1.0.2",
         /*应用版本名称*/
-        "code" : 100000
+        "code" : 100002
     },
     "description" : "",
     /*应用描述信息*/

+ 2 - 2
oem/zrwyt/config/appconfig.json

@@ -1,8 +1,8 @@
 {
   "appId": "com.muchinfo.zrwyt",
   "appName": "中融文遗通",
-  "version": "1.0.11",
-  "versionCode": "100011",
+  "version": "1.0.12",
+  "versionCode": "100012",
   "apiUrl": "http://192.168.31.204:8080/cfg?key=test_204",
   "tradeChannel": "ws",
   "modules": [

+ 1 - 3
src/components/base/hqchart/index.vue

@@ -35,14 +35,12 @@ const chartRef = shallowRef()
 const globalStore = useGlobalStore()
 
 const resource = Chart.JSChart.GetResource()
-resource.FrameLogo.Text = ''
+resource.FrameLogo.Text = null
 
 // https://blog.csdn.net/jones2000/article/details/104122774
 Chart.JSConsole.Chart.Log = () => ({})
 Chart.JSConsole.Complier.Log = () => ({})
 
-console.log(Chart)
-
 const setChartStyle = (defaultTheme?: keyof typeof AppTheme) => {
     const jsChart = Chart.JSChart
     const hqChartStyle = Chart.HQChartStyle

+ 59 - 27
src/packages/mobile/components/modules/chart/historydata.ts

@@ -20,37 +20,48 @@ export interface NetworkFilterData {
     }
 }
 
-// https://blog.csdn.net/jones2000/article/details/100557649
-export interface HistoryMinuteData {
+export interface ReqeustData {
     name?: string; // 股票名称
     symbol: string; // 股票代码
-    data: number[][]; // 分钟数据
+    data: (number | null)[][]; // 分钟数据
 }
 
-export type NetworkFilterCallback = (historyMinuteData: HistoryMinuteData) => void
+export type NetworkFilterCallback = (reqeustData: ReqeustData) => void
 
-export function useHistoryData(goodsCode: string) {
+export function useHistoryData(goodsCode: string, cycleType = ChartCycleType.Minutes) {
     const historyData = shallowRef<Model.HistoryDatasRsp[]>([])
 
     const state = reactive({
         loading: false,
-        cycleType: ChartCycleType.Minutes
+        symbol: '',
+        cycleType
     })
 
+    // K线图网路协议
+    const networkProtocol = {
+        historyData: 'KLineChartContainer::RequestHistoryData', // 分钟全量数据下载
+        historyMinuteData: 'KLineChartContainer::ReqeustHistoryMinuteData' // 日线全量数据下载
+    }
+
     const networkFilter = (data: NetworkFilterData, callback: NetworkFilterCallback) => {
         data.PreventDefault = true
         switch (data.Name) {
-            // 历史分钟数据
-            case 'KLineChartContainer::ReqeustHistoryMinuteData':
+            case networkProtocol.historyData:
                 getHistoryData().then(() => {
                     callback({
-                        symbol: data.Request.Data.symbol,
-                        data: handleChartData(historyData.value)
+                        symbol: state.symbol,
+                        data: handleChartData(networkProtocol.historyData, historyData.value)
                     })
                 })
                 break
-            // 历史数据
-            case 'KLineChartContainer::RequestHistoryData':
+            case networkProtocol.historyMinuteData:
+                state.symbol = data.Request.Data.symbol
+                getHistoryData().then(() => {
+                    callback({
+                        symbol: state.symbol,
+                        data: handleChartData(networkProtocol.historyMinuteData, historyData.value)
+                    })
+                })
                 break
         }
     }
@@ -69,25 +80,43 @@ export function useHistoryData(goodsCode: string) {
     }
 
     // 处理图表数据
-    const handleChartData = (data: Model.HistoryDatasRsp[]) => {
+    const handleChartData = (protocol: string, data: Model.HistoryDatasRsp[]) => {
         return data.map((e, i) => {
             const date = Number(moment(e.ts).format('YYYYMMDD'))
             const time = Number(moment(e.ts).format('HHmm'))
             const preclose = data[i - 1] // 上一个收盘价
             const close = preclose ? preclose.c : e.c
-
-            return [
-                date, // 日期
-                close, // 前收盘
-                e.o, // 开盘价
-                e.h, // 最高
-                e.l, // 最低
-                e.c, // 收盘
-                e.tv, // 成交量
-                e.tt, // 成交金额
-                time, // 时间
-                e.hv // 持仓量
-            ]
+            switch (protocol) {
+                // https://blog.csdn.net/jones2000/article/details/100557649
+                case networkProtocol.historyData:
+                    return [
+                        date, // 日期
+                        close, // 前收盘
+                        e.o, // 开盘价
+                        e.h, // 最高
+                        e.l, // 最低
+                        e.c, // 收盘
+                        e.tv, // 成交量
+                        e.tt, // 成交金额
+                        e.hv // 持仓量
+                    ]
+                // https://blog.csdn.net/jones2000/article/details/100557649
+                case networkProtocol.historyMinuteData:
+                    return [
+                        date, // 日期
+                        close, // 前收盘
+                        e.o, // 开盘价
+                        e.h, // 最高
+                        e.l, // 最低
+                        e.c, // 收盘
+                        e.tv, // 成交量
+                        e.tt, // 成交金额
+                        time, // 时间
+                        e.hv // 持仓量
+                    ]
+                default:
+                    return []
+            }
         })
     }
 
@@ -166,7 +195,10 @@ export function useHistoryData(goodsCode: string) {
             }
 
             const lastValue = historyData.value.slice(-1)
-            return handleChartData(lastValue)
+            if (state.cycleType === ChartCycleType.Day) {
+                return handleChartData(networkProtocol.historyData, lastValue)
+            }
+            return handleChartData(networkProtocol.historyMinuteData, lastValue)
         }
         return []
     }

+ 38 - 0
src/packages/mobile/components/modules/chart/index.less

@@ -0,0 +1,38 @@
+.hqchart {
+
+    /*tooltip的外层样式*/
+    .jschart-tooltip {
+        box-shadow: 0px 1px 4px 0px rgba(0, 0, 0, 0.23);
+        border: solid 1px rgba(200, 210, 219, 0.92);
+        padding: 7px 20px 15px 13px;
+        box-sizing: border-box;
+        position: relative;
+        display: none;
+        z-index: 9;
+    }
+
+    /*tooltip的内层样式*/
+    .tooltip {
+        &-title {
+            color: #2b3645;
+            font-size: 12px;
+            text-align: center;
+            display: block;
+            line-height: 24px;
+        }
+
+        &-con {
+            color: #2b3645;
+            font-size: 12px;
+            line-height: 24px;
+        }
+
+        &-num {
+            font-size: 12px;
+            line-height: 24px;
+            text-align: right;
+            display: inline-block;
+            width: 90px;
+        }
+    }
+}

+ 34 - 2
src/packages/mobile/components/modules/chart/index.vue

@@ -1,8 +1,40 @@
 <template>
-    <MLine />
+    <div class="hqchart">
+        <Tabs class="app-tabs--info" :data-list="dataList" :data-index="1" @change="changePeriod" />
+        <MLine v-bind="{ symbol, goodscode }" v-if="cycletype === ChartCycleType.Time" />
+        <KLine v-bind="{ symbol, goodscode, cycletype }" v-else />
+    </div>
 </template>
 
 <script lang="ts" setup>
+import { shallowRef, onMounted, onUnmounted } from 'vue'
+import { ChartCycleType, getChartCycleTypeList } from '@/constants/chart'
+import quoteSocket from '@/services/websocket/quote'
+import Tabs from '@/components/base/tabs/index.vue'
 import KLine from './kline.vue'
 import MLine from './mline.vue'
-</script>
+
+const props = defineProps({
+    goodscode: {
+        type: String,
+        default: 'XAUUSD'
+    }
+})
+
+const subscribe = quoteSocket.createSubscribe()
+const symbol = '600000.sh' // 股票代码
+const cycletype = shallowRef(ChartCycleType.Minutes) // 图表周期类型
+const dataList = getChartCycleTypeList()
+
+// 切换周期
+const changePeriod = (index: number) => {
+    cycletype.value = dataList[index].value
+}
+
+onMounted(() => subscribe.start(props.goodscode))
+onUnmounted(() => subscribe.stop())
+</script>
+
+<style lang="less">
+@import './index.less';
+</style>

+ 62 - 42
src/packages/mobile/components/modules/chart/kline.vue

@@ -1,41 +1,65 @@
 <template>
     <HQChart width="1000px" height="500px" default-theme="Dark" @ready="onReady" />
-    <ul>
-        <li @click="changePeriod(4)">1分钟</li>
-        <li @click="changePeriod(5)">5分钟</li>
-    </ul>
-    <ul>
-        <li @click="changeIndex('VOL')">VOL</li>
-        <li @click="changeIndex('MACD')">MACD</li>
-        <li @click="changeIndex('KDJ')">KDJ</li>
-        <li @click="changeIndex('CCI')">CCI</li>
-    </ul>
+    <Tabs class="app-tabs--info" :data-list="tabs" @change="changeIndex" />
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, onMounted, onUnmounted } from 'vue'
+import { shallowRef, watch, computed } from 'vue'
 import { ChartCycleType } from '@/constants/chart'
 import { useFuturesStore } from '@/stores'
 import { useHistoryData, NetworkFilterData, NetworkFilterCallback } from './historydata'
-import quoteSocket from '@/services/websocket/quote'
 import HQChart from '@/components/base/hqchart/index.vue'
+import Tabs from '@/components/base/tabs/index.vue'
 
 const props = defineProps({
-    goodsCode: {
+    symbol: {
         type: String,
-        default: 'XAUUSD'
+        required: true
+    },
+    goodscode: {
+        type: String,
+        required: true
+    },
+    cycletype: {
+        type: Number,
+        required: true
     }
 })
 
-const { cycleType, networkFilter, updateLastData } = useHistoryData(props.goodsCode)
+const { cycleType, networkFilter, updateLastData } = useHistoryData(props.goodscode, props.cycletype)
 const { quoteWatch } = useFuturesStore()
-const chartSymbol = '600000.sh' // 股票代码(必填)
 const chartInstance = shallowRef() // 图表实例
-const subscribe = quoteSocket.createSubscribe()
+
+const tabs = [
+    { label: 'VOL', value: 'VOL' },
+    { label: 'MACD', value: 'MACD' },
+    { label: 'KDJ', value: 'KDJ' },
+    { label: 'CCI', value: 'CCI' }
+]
+
+// 图表周期
+const period = computed(() => {
+    switch (props.cycletype) {
+        case ChartCycleType.Day:
+            return 0
+        case ChartCycleType.Minutes:
+            return 4
+        case ChartCycleType.Minutes5:
+            return 5
+        case ChartCycleType.Minutes30:
+            return 7
+        case ChartCycleType.Minutes60:
+            return 8
+        case ChartCycleType.Hours4:
+            return 12
+        default:
+            return -1
+    }
+})
 
 // https://blog.csdn.net/jones2000/article/details/90272733
 const chartOption = {
-    Symbol: chartSymbol,
+    Symbol: props.symbol,
     Type: '历史K线图',
     IsAutoUpdate: false,
     IsApiPeriod: true, // 每次切换周期请求接口数据
@@ -46,6 +70,11 @@ const chartOption = {
         { Index: 'VOL' }
     ],
     IsShowCorssCursorInfo: true,
+    // https://blog.csdn.net/jones2000/article/details/97682466
+    CorssCursorInfo: {
+        Left:0,
+        Right:2,
+    },
     Border: {
         Left: 1,
         Right: 1, //右边间距
@@ -57,8 +86,11 @@ const chartOption = {
         // [30001-32000) 秒周期
         // 0=日线 1=周线 2=月线 3=年线 9=季线  [40001-50000) 自定义日线
         // 4=1分钟 5=5分钟 6=15分钟 7=30分钟 8=60分钟 11=120分钟 12=240分钟 [20001-30000) 自定义分钟
-        Period: 4,
+        Period: period.value,
         PageSize: 50,
+        // 最后数据和右边框空白间距,空白的宽度=RightSpaceCount*k线宽度
+        RightSpaceCount: 2,
+        // https://blog.csdn.net/jones2000/article/details/104443471
         IsShowTooltip: true,
     },
     KLineTitle:
@@ -82,27 +114,10 @@ const chartOption = {
     ]
 }
 
-// 切换周期
-const changePeriod = (period: number) => {
-    switch (period) {
-        case 1:
-            cycleType.value = ChartCycleType.Week
-            break
-        case 4:
-            cycleType.value = ChartCycleType.Minutes
-            break
-        case 5:
-            cycleType.value = ChartCycleType.Minutes5
-            break
-    }
-    //chartInstance.value.ChangeSymbol(chartSymbol) // 切换股票
-    chartInstance.value.ChangePeriod(period) // 切换周期
-}
-
 // 切换指标
-const changeIndex = (name: string) => {
+const changeIndex = (index: number) => {
     // ChangeIndex(windowIndex, indexName, option)
-    chartInstance.value.ChangeIndex(1, name)
+    chartInstance.value.ChangeIndex(1, tabs[index].value)
 }
 
 const onReady = (chart: unknown) => {
@@ -110,18 +125,23 @@ const onReady = (chart: unknown) => {
     chartInstance.value.SetOption(chartOption)
 }
 
-quoteWatch(props.goodsCode, (q) => {
+quoteWatch(props.goodscode, (q) => {
     const data = updateLastData(q)
     const { JSChartContainer } = chartInstance.value ?? {}
     // 在 SetOption 之后才会出现 JSChartContainer 属性
     if (JSChartContainer && data.length) {
         JSChartContainer.RecvMinuteRealtimeDataV2({
-            symbol: chartSymbol,
+            symbol: props.symbol,
             data
         })
     }
 })
 
-onMounted(() => subscribe.start(props.goodsCode))
-onUnmounted(() => subscribe.stop())
+watch(() => props.cycletype, (val) => {
+    cycleType.value = val
+    if (period.value > -1) {
+        // 切换周期
+        chartInstance.value.ChangePeriod(period.value)
+    }
+})
 </script>

+ 91 - 95
src/packages/mobile/components/modules/chart/minutedata.ts

@@ -1,6 +1,5 @@
-import { reactive, toRefs, shallowRef } from 'vue'
+import { reactive, shallowRef, toRefs } from 'vue'
 import { queryTSData } from '@/services/api/quote'
-import { useFuturesStore } from '@/stores'
 import moment from 'moment'
 
 // https://blog.csdn.net/jones2000/article/details/100181279
@@ -21,16 +20,16 @@ export interface NetworkFilterData {
 }
 
 // https://blog.csdn.net/jones2000/article/details/100149703
-export interface HistoryMinuteData {
+export interface RequestData {
     name?: string; // 股票名称
     symbol: string; // 股票代码
     yclose: number; // 昨收
-    open: number; // 当日开盘价
-    high: number; // 当日最高价
-    low: number; // 当日最低价
-    vol: number; // 当日成交量
-    amount: number; // 当日成交金额
-    price: number; // 最新价/收盘价
+    open?: number; // 当日开盘价
+    high?: number; // 当日最高价
+    low?: number; // 当日最低价
+    vol?: number; // 当日成交量
+    amount?: number; // 当日成交金额
+    price?: number; // 最新价/收盘价
     yclearing?: number; // 结算价
     date: number; // 交易日期
     time: number; // 最新的交易时间
@@ -48,7 +47,7 @@ export interface MinuteData {
     amount: number; // 成交金额
     date: number; // 交易日期 格式:yyyymmdd 如20191011=>2019-10-11
     time: number; // 交易时间 格式:hhmm 如930 就是9:30
-    avprice: number; // 均价
+    avprice?: number; // 均价
     increase?: number; // 涨幅
     risefall?: number; // 涨跌
     lead?: number; // 领先指标(指数才有)
@@ -56,34 +55,37 @@ export interface MinuteData {
     yclearing?: number; // 昨结算价(期货才有)
 }
 
-export type NetworkFilterCallback = (historyMinuteData: { stock: HistoryMinuteData[] }) => void
+export type NetworkFilterCallback = (requestData: { stock: RequestData[] }) => void
 
 export function useMinuteData(goodsCode: string) {
-    const futuresStore = useFuturesStore()
-    const quote = futuresStore.getGoodsQuote(goodsCode)
-    const historyData = shallowRef<Model.TSDataRsp>()
+    const tsData = shallowRef<Model.TSDataRsp>()
 
     const state = reactive({
         loading: false,
+        symbol: ''
+    })
+
+    // 获取历史行情
+    const getTSDataAsync = queryTSData({
+        data: {
+            goodsCode,
+        }
+    }).then((res) => {
+        tsData.value = res.data
+        return res
     })
 
     const networkFilter = (data: NetworkFilterData, callback: NetworkFilterCallback) => {
         data.PreventDefault = true
         if (data.Name === 'MinuteChartContainer::RequestMinuteData') {
-            getTSData().then((res) => {
-                const { opened = 0, highest = 0, lowest = 0, totalvolume = 0, totalturnover = 0, last = 0 } = quote.value ?? {}
-                const lastItem=res.data.historyDatas[res.data.historyDatas.length-1]
+            getTSDataAsync.then((res) => {
+                const [lastItem] = res.data.historyDatas.slice(-1)
+                state.symbol = data.Request.Data.symbol[0]
                 callback({
                     stock: [
                         {
-                            symbol: data.Request.Data.symbol[0],
+                            symbol: state.symbol,
                             yclose: res.data.preSettle,
-                            open: opened,
-                            high: highest,
-                            low: lowest,
-                            vol: totalvolume,
-                            amount: totalturnover,
-                            price: last,
                             date: Number(moment(lastItem.ts).format('YYYYMMDD')),
                             time: Number(moment(lastItem.ts).format('HHmm')),
                             minute: res.data.historyDatas.map((e) => ({
@@ -95,7 +97,6 @@ export function useMinuteData(goodsCode: string) {
                                 amount: e.tt,
                                 date: Number(moment(e.ts).format('YYYYMMDD')),
                                 time: Number(moment(e.ts).format('HHmm')),
-                                avprice: totalturnover/totalvolume
                             }))
                         }
                     ]
@@ -104,86 +105,81 @@ export function useMinuteData(goodsCode: string) {
         }
     }
 
-    // 获取历史行情
-    const getTSData = () => {
-        return queryTSData({
-            data: {
-                goodsCode,
-            }
-        })
-    }
-
-    // 处理图表数据
-    const handleChartData = (data: Model.HistoryDatasRsp[]) => {
-        return data.map((e, i) => {
-            const date = Number(moment(e.ts).format('YYYYMMDD'))
-            const time = Number(moment(e.ts).format('HHmm'))
-            const preclose = data[i - 1] // 上一个收盘价
-            const close = preclose ? preclose.c : e.c
-
-            return [
-                date, // 日期
-                close, // 前收盘
-                e.o, // 开盘价
-                e.h, // 最高
-                e.l, // 最低
-                e.c, // 收盘
-                e.tv, // 成交量
-                e.tt, // 成交金额
-                time, // 时间
-                e.hv // 持仓量
-            ]
-        })
-    }
-
     // 更新最新数据
     const updateLastData = (q: Partial<Model.QuoteDayRsp>) => {
         const { last, lasttime } = q
-        // if (last && lasttime) {
-        //     const lastIndex = historyData.value.length - 1 // 历史数据最后索引位置
-        //     const cycleMilliseconds = getCycleMilliseconds()
+        if (tsData.value && last && lasttime) {
+            const { preSettle, historyDatas } = tsData.value
+            const lastIndex = historyDatas.length - 1 // 历史数据最后索引位置
+            const cycleMilliseconds = 60 * 1000 // 一分钟毫秒数
+
+            const oldTime = lastIndex === -1 ? moment(lasttime) : moment(historyDatas[lastIndex].ts) // 历史行情最后时间
+            const diffTime = moment(lasttime).valueOf() - oldTime.valueOf() // 计算时间差
 
-        //     const oldTime = lastIndex === -1 ? moment(lasttime) : moment(historyData.value[lastIndex].ts) // 历史行情最后时间
-        //     const diffTime = moment(lasttime).valueOf() - oldTime.valueOf() // 计算时间差
+            // 判断时间差是否大于周期时间
+            if (lastIndex === -1 || diffTime > cycleMilliseconds) {
+                // 新增分时数据
+                historyDatas.push({
+                    o: last,
+                    h: last,
+                    l: last,
+                    c: last,
+                    tv: q.lastvolume ?? 0,
+                    tt: q.Lastturnover ?? 0,
+                    hv: q.holdvolume ?? 0,
+                    s: q.settle ?? 0,
+                    ts: lasttime,
+                    f: false
+                })
+            } else {
+                // 更新列表中最后一条记录的数据
+                const record = historyDatas[lastIndex]
+                if (record.l > last) {
+                    record.l = last // 更新最低价
+                }
+                if (record.h < last) {
+                    record.h = last // 更新最高价
+                }
+                record.c = last // 更新收盘价
+                record.tv = q.lastvolume ?? record.tv
+                record.tt = q.Lastturnover ?? record.tt
+                record.hv = q.holdvolume ?? record.hv
+                record.s = q.settle ?? record.s
+            }
 
-        //     // 判断时间差是否大于周期时间
-        //     if (lastIndex === -1 || diffTime > cycleMilliseconds) {
-        //         historyData.value.push({
-        //             o: last,
-        //             h: last,
-        //             l: last,
-        //             c: last,
-        //             tv: q.lastvolume ?? 0,
-        //             tt: q.Lastturnover ?? 0,
-        //             hv: q.holdvolume ?? 0,
-        //             s: q.settle ?? 0,
-        //             ts: lasttime,
-        //             f: false
-        //         })
-        //     } else {
-        //         // 更新列表中最后一条记录的数据
-        //         const record = historyData.value[lastIndex]
-        //         if (record.l > last) {
-        //             record.l = last // 更新最低价
-        //         }
-        //         if (record.h < last) {
-        //             record.h = last // 更新最高价
-        //         }
-        //         record.c = last // 更新收盘价
-        //         record.tv = q.lastvolume ?? record.tv
-        //         record.tt = q.Lastturnover ?? record.tt
-        //         record.hv = q.holdvolume ?? record.hv
-        //         record.s = q.settle ?? record.s
-        //     }
+            const lastValue = historyDatas.slice(-1)
+            const date = Number(moment(lasttime).format('YYYYMMDD'))
+            const time = Number(moment(lasttime).format('HHmm'))
 
-        //     const lastValue = historyData.value.slice(-1)
-        //     return handleChartData(lastValue)
-        // }
-        return []
+            return {
+                dataType: 1, // 增量数据标识
+                stock: [
+                    {
+                        symbol: state.symbol,
+                        date,
+                        yclose: preSettle,
+                        // 单条分钟数据格式 0=日期 1=时间 2=开 3=高 4=低 5=收 6=均价 7=量 8=金额 9=涨幅 10=涨跌 11=领先指标
+                        minute: lastValue.map((e) => [
+                            date,
+                            time,
+                            e.o,
+                            e.h,
+                            e.l,
+                            e.c,
+                            null,
+                            e.tv,
+                            e.tt
+                        ])
+                    }
+                ]
+            }
+        }
+        return undefined
     }
 
     return {
         ...toRefs(state),
+        getTSDataAsync,
         networkFilter,
         updateLastData
     }

+ 99 - 26
src/packages/mobile/components/modules/chart/mline.vue

@@ -3,65 +3,138 @@
 </template>
 
 <script lang="ts" setup>
-import { shallowRef, onMounted, onUnmounted } from 'vue'
+import { shallowRef } from 'vue'
+import { Chart } from 'hqchart'
 import { useFuturesStore } from '@/stores'
 import { useMinuteData, NetworkFilterData, NetworkFilterCallback } from './minutedata'
-import quoteSocket from '@/services/websocket/quote'
+import moment from 'moment'
 import HQChart from '@/components/base/hqchart/index.vue'
 
 const props = defineProps({
-    goodsCode: {
+    symbol: {
         type: String,
-        default: 'XAUUSD'
+        required: true
+    },
+    goodscode: {
+        type: String,
+        required: true
     }
 })
 
-const { networkFilter, updateLastData } = useMinuteData(props.goodsCode)
+const { getTSDataAsync, networkFilter, updateLastData } = useMinuteData(props.goodscode)
 const { quoteWatch } = useFuturesStore()
-const chartSymbol = '600000.sh' // 股票代码(必填)
 const chartInstance = shallowRef() // 图表实例
-const subscribe = quoteSocket.createSubscribe()
 
-// https://blog.csdn.net/jones2000/article/details/90272733
+// https://blog.csdn.net/jones2000/article/details/90319619
 const chartOption = {
-    Symbol: chartSymbol,
+    Symbol: props.symbol,
     Type: '分钟走势图',
     IsAutoUpdate: false,
     NetworkFilter: (data: NetworkFilterData, callback: NetworkFilterCallback) => networkFilter(data, callback),
     IsShowCorssCursorInfo: true,
-    Border: {
-        Left: 1,
-        Right: 1, //右边间距
-        Top: 25,
-        Bottom: 25,
-    },
+    DayCount: 1,
     Windows: [
     ],
     MinuteLine: {
+        IsShowAveragePrice: false, // 不显示均线
     },
     MinuteLineTitle:
     {
         IsShowName: false, // 不显示股票名称
-    }
+    },
+    Frame: [
+        {
+            Custom: [
+                {
+                    Type: 0,
+                    Position: 'right',
+                }
+            ]
+        },
+        // {
+        //     Height: 0 // 第2个成交量图高度设置0隐藏掉
+        // }
+    ]
 }
 
 const onReady = (chart: unknown) => {
     chartInstance.value = chart
-    chartInstance.value.SetOption(chartOption)
+    getTSDataAsync.then(({ data: { runSteps } }) => {
+        // https://blog.csdn.net/jones2000/article/details/105587559
+        const minuteTimeStringData = Chart.JSChart.GetMinuteTimeStringData()
+        const minuteCoordinateData = Chart.JSChart.GetMinuteCoordinateData()
+
+        // 替换交易时间段
+        minuteTimeStringData.CreateSHSZData = () => {
+            // 交易时间段
+            const timeSplit = runSteps.reduce<{ Start: number; End: number; }[]>((pre, cur) => {
+                pre.push({
+                    Start: Number(moment(cur.start).format('HHmm')),
+                    End: Number(moment(cur.end).format('HHmm'))
+                })
+                return pre
+            }, [])
+            return minuteTimeStringData.CreateTimeData(timeSplit)
+        }
+
+        // 替换X轴刻度信息
+        minuteCoordinateData.GetSHSZData = () => {
+            const minutes: number[] = minuteTimeStringData.CreateSHSZData()
+
+            const timeSplit = (count: number) => {
+                const result: (string | number)[][] = []
+                const add = (index: number) => {
+                    const m = minutes[index].toString()
+                    const t = moment(m.padStart(4, '0'), 'HHmm').format('HH:mm')
+                    // 0=数据索引 1=暂时未用到 2=线段和字颜色 3=刻度显示的文字
+                    result.push([index, 1, 'RGB(200,200,200)', t])
+                }
+                if (minutes.length) {
+                    const n = count - 1
+                    // 根据段数进行分割
+                    const range = Math.trunc(minutes.length / n)
+                    for (let i = 0; i < count; i++) {
+                        if (i === 0) {
+                            add(i)
+                        } else if (i === n) {
+                            add(minutes.length - 1)
+                        } else {
+                            add(i * range)
+                        }
+                    }
+                }
+                return result
+            }
+
+            return {
+                //完整模式
+                Full: timeSplit(9),
+                //简洁模式
+                Simple: timeSplit(5),
+                //最小模式     
+                Min: timeSplit(3),
+                Count: minutes.length,
+                //中心的位置
+                MiddleCount: Math.trunc(minutes.length / 2),
+                //根据页面的宽度 返回不同的显示刻度
+                GetData: function (width: number) {
+                    if (width < 200) return this.Min
+                    else if (width < 450) return this.Simple
+                    return this.Full
+                }
+            }
+        }
+
+        chartInstance.value.SetOption(chartOption)
+    })
 }
 
-quoteWatch(props.goodsCode, (q) => {
+quoteWatch(props.goodscode, (q) => {
     const data = updateLastData(q)
     const { JSChartContainer } = chartInstance.value ?? {}
     // 在 SetOption 之后才会出现 JSChartContainer 属性
-    if (JSChartContainer && data.length) {
-        // JSChartContainer.RecvMinuteRealtimeDataV2({
-        //     symbol: chartSymbol,
-        //     data
-        // })
+    if (JSChartContainer && data) {
+        JSChartContainer.RecvMinuteData(data)
     }
 })
-
-onMounted(() => subscribe.start(props.goodsCode))
-onUnmounted(() => subscribe.stop())
 </script>

+ 2 - 2
src/packages/mobile/views/order/position/components/presale/list/Index.vue

@@ -64,7 +64,7 @@
 import { shallowRef, defineAsyncComponent } from 'vue'
 import { Button } from 'vant'
 import { fullloading, dialog } from '@/utils/vant'
-import { parsePercent } from '@/filters'
+import { parsePercent,handleRequestBigNumber } from '@/filters'
 import { useComponent } from '@/hooks/component'
 import { PayStatus, getPayStatusName } from '@/constants/order'
 import { useRequest } from '@/hooks/request'
@@ -117,7 +117,7 @@ const depositPayment = (row: Model.MineCpTradePreSaleResultsRsp) => {
                     Header: {
                         MarketID: row.marketid
                     },
-                    TradeID: row.tradeid
+                    TradeID: handleRequestBigNumber(row.tradeid)
                 }
             }).then(() => {
                 hideLoading('提交成功')

+ 3 - 2
src/packages/pc/views/footer/presell/presellposition/deposit/index.vue

@@ -12,8 +12,9 @@
 <script lang="ts" setup>
 import { ref, PropType } from 'vue'
 import { ElMessage } from 'element-plus'
-import AppDrawer from '@pc/components/base/drawer/index.vue'
+import { handleRequestBigNumber } from '@/filters'
 import { makeUpDeposit } from '@/services/api/trade'
+import AppDrawer from '@pc/components/base/drawer/index.vue'
 
 const props = defineProps({
     selectedRow: {
@@ -39,7 +40,7 @@ const onMakeUpDeposit = () => {
             Header: {
                 MarketID: props.selectedRow.marketid
             },
-            TradeID: props.selectedRow.tradeid
+            TradeID: handleRequestBigNumber(props.selectedRow.tradeid)
         }
     }).then(() => {
         ElMessage.success('提交成功')

+ 5 - 1
src/packages/sbyj/views/order/list/components/market-order-delivery/index.vue

@@ -38,6 +38,7 @@
 import { shallowRef, PropType, onMounted, computed, reactive } from 'vue'
 import { CellGroup, Cell, Button, Stepper, Field, Form, FormInstance, FieldRule, RadioGroup, Radio } from 'vant'
 import { fullloading } from '@/utils/vant'
+import { handleRequestBigNumber } from '@/filters'
 import AppModal from '@/components/base/modal/index.vue'
 import { marketOrderDeliveryApply } from '@/services/api/trade'
 import { getGoodsUnitName } from '@/constants/unit'
@@ -96,7 +97,10 @@ const onSubmit = () => {
     const { tHDetailEx } = props.selectedRow ?? {}
 
     formData.BuyOrSell = tHDetailEx.buyOrSell
-    formData.HoldDetails = [{ TradeID: tHDetailEx.tradeID, DeliveryQty: orderQty.value }] // 交收接口要的是数量不是手数,所以不用除以agreeunit
+    formData.HoldDetails = [{
+        TradeID: handleRequestBigNumber(tHDetailEx.tradeID),
+        DeliveryQty: orderQty.value // 交收接口要的是数量不是手数,所以不用除以agreeunit
+    }]
 
     fullloading((hideLoading) => {
         marketOrderDeliveryApply({ data: formData }).then(() => {

+ 1 - 1
src/types/model/presale.d.ts

@@ -82,7 +82,7 @@ declare namespace Model {
         starttime: string; // 预售开始时间
         tradeamount: number; // 成交金额\转让定金
         tradedate: string; // 交易日(yyyyMMdd)
-        tradeid: number; // 成交单号(101+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
+        tradeid: string; // 成交单号(101+Unix秒时间戳(10位)+2位(MarketServiceID)+xxxx)
         tradeqty: number; // 成交数量
         transferdeposit: number; // 转让定金
         transferdepositratio: number; // 转让定金比例(49)

+ 2 - 2
src/types/proto/trade.d.ts

@@ -543,7 +543,7 @@ declare global {
         /** 补足定金请求 */
         interface MakeUpDepositReq {
             Header?: IMessageHead; // 消息头
-            TradeID: number; // 成交单号,必填
+            TradeID: string | Long; // 成交单号,必填
             UserID: number; // 用户ID,必填
             AccountID: number; // 交易账号,必填
             ClientSerialNo: string; // 客户端流水号
@@ -651,7 +651,7 @@ declare global {
 
         // 持仓明细
         interface MarketOrderHoldDetails {
-            TradeID?: string; // 成交单号,必填
+            TradeID?: string | Long; // 成交单号,必填
             DeliveryQty?: number; // 交收数量,必填
         }