diff --git a/api/tcpConnection.js b/api/tcpConnection.js
index ffe9d88..4c5c426 100644
--- a/api/tcpConnection.js
+++ b/api/tcpConnection.js
@@ -19,7 +19,7 @@ const TCP_CONFIG = {
*/
class TCPConnection {
constructor() {
- this.isConnected = false;
+ this.channelConnections = new Map(); // 存储每个channel的连接状态
this.connectionCallbacks = [];
this.messageCallbacks = [];
}
@@ -30,9 +30,11 @@ class TCPConnection {
* @param {Function} callback - 连接状态回调函数
*/
connect(config = {}, callback = null) {
- // 如果已经连接,先断开现有连接
- if (this.isConnected) {
- console.log('检测到现有TCP连接,先断开...');
+ const channel = config.channel || TCP_CONFIG.channel;
+
+ // 如果该channel已经连接,先断开现有连接
+ if (this.channelConnections.get(channel)) {
+ console.log(`检测到channel ${channel}现有TCP连接,先断开...`);
this.disconnect(config);
// 等待断开完成后再连接
setTimeout(() => {
@@ -73,20 +75,20 @@ class TCPConnection {
*/
if (result.status == '0') {
// TCP连接成功
- this.isConnected = true;
- console.log('TCP连接成功');
- this._notifyConnectionCallbacks('connected', result);
+ this.channelConnections.set(connectionConfig.channel, true);
+ console.log(`TCP连接成功 - Channel ${connectionConfig.channel}`);
+ this._notifyConnectionCallbacks('connected', result, connectionConfig.channel);
} else if (result.status == '1') {
// TCP断开连接
- this.isConnected = false;
- console.log('TCP断开连接');
- this._notifyConnectionCallbacks('disconnected', result);
+ this.channelConnections.set(connectionConfig.channel, false);
+ console.log(`TCP断开连接 - Channel ${connectionConfig.channel}`);
+ this._notifyConnectionCallbacks('disconnected', result, connectionConfig.channel);
}
if (result.receivedMsg) {
// 服务器返回字符串
console.log('收到字符串消息:', result.receivedMsg);
- this._notifyMessageCallbacks('string', result.receivedMsg);
+ this._notifyMessageCallbacks('string', result.receivedMsg, null, connectionConfig.channel);
}
// if (result.receivedHexMsg) {
@@ -117,8 +119,10 @@ class TCPConnection {
* @param {Object} config - 发送配置 {channel, charsetname}
*/
send(message, config = {}) {
- if (!this.isConnected) {
- console.warn('TCP未连接,无法发送消息');
+ const channel = config.channel || '1';
+
+ if (!this.channelConnections.get(channel)) {
+ console.warn(`TCP Channel ${channel}未连接,无法发送消息`);
return false;
}
@@ -148,13 +152,14 @@ class TCPConnection {
* @param {Object} config - 断开配置 {channel}
*/
disconnect(config = {}) {
+ const channel = config.channel || TCP_CONFIG.channel;
const disconnectConfig = {
- channel: config.channel || TCP_CONFIG.channel
+ channel: channel
};
TCPSocket.disconnect(disconnectConfig);
- this.isConnected = false;
- console.log('TCP连接已断开', disconnectConfig);
+ this.channelConnections.set(channel, false);
+ console.log(`TCP连接已断开 - Channel ${channel}`, disconnectConfig);
}
/**
@@ -201,20 +206,29 @@ class TCPConnection {
/**
* 获取连接状态
- * @returns {Boolean} 连接状态
+ * @param {String} channel - 要检查的channel,如果不指定则返回所有channel的连接状态
+ * @returns {Boolean|Object} 连接状态
*/
- getConnectionStatus() {
- return this.isConnected;
+ getConnectionStatus(channel = null) {
+ if (channel) {
+ return this.channelConnections.get(channel) || false;
+ }
+ // 返回所有channel的连接状态
+ const allConnections = {};
+ for (const [ch, status] of this.channelConnections) {
+ allConnections[ch] = status;
+ }
+ return allConnections;
}
/**
* 通知连接状态回调
* @private
*/
- _notifyConnectionCallbacks(status, result) {
+ _notifyConnectionCallbacks(status, result, channel) {
this.connectionCallbacks.forEach(callback => {
try {
- callback(status, result);
+ callback(status, result, channel);
} catch (error) {
console.error('连接状态回调执行错误:', error);
}
@@ -225,10 +239,10 @@ class TCPConnection {
* 通知消息回调
* @private
*/
- _notifyMessageCallbacks(type, message, parsedArray = null) {
+ _notifyMessageCallbacks(type, message, parsedArray = null, channel = null) {
this.messageCallbacks.forEach(callback => {
try {
- callback(type, message, parsedArray);
+ callback(type, message, parsedArray, channel);
} catch (error) {
console.error('消息回调执行错误:', error);
}
diff --git a/pages/home/home.vue b/pages/home/home.vue
index bd32e6b..92f54cf 100644
--- a/pages/home/home.vue
+++ b/pages/home/home.vue
@@ -82,24 +82,37 @@
我的自选
添加自选股
+
+
-
+
+
- {{item.name}}
- {{item.code}}
+ {{item.name || item.stock_name}}
+ {{item.code || item.stock_code}}
- {{item.price}}
- {{item.change > 0 ? '+' : ''}}{{item.change}}%
+ {{item.price || item.current_price}}
+
+ {{(item.change_percent || item.change || item.change_amount || 0) > 0 ? '+' : ''}}{{(parseFloat(item.change_percent || item.change || item.change_amount || 0)).toFixed(2)}}%
+
-
+
@@ -222,6 +235,9 @@ export default {
tcpMessages: [],
lastSentMessage: '',
+ // 我的自选TCP连接状态
+ myStocksTcpConnected: false,
+
// TCP监听器引用,用于移除监听器
connectionListener: null,
messageListener: null,
@@ -235,6 +251,15 @@ export default {
type: ''
},
+ // 我的自选TCP股票数据存储
+ myStocksTcpData: {
+ count: 0,
+ data: {},
+ stock_count: 0,
+ timestamp: '',
+ type: ''
+ },
+
// TCP数据缓存机制,用于处理分片数据
tcpDataCache: {
isCollecting: false, // 是否正在收集数据片段
@@ -247,6 +272,18 @@ export default {
isWaitingSecondPart: false // 是否正在等待后半部分数据
},
+ // 我的自选TCP数据缓存机制,用于处理分片数据
+ myStocksTcpDataCache: {
+ isCollecting: false, // 是否正在收集数据片段
+ expectedCount: 0, // 期望的数据总数
+ collectedData: {}, // 已收集的数据对象(用于对象级拼接)
+ timestamp: '', // 数据时间戳
+ type: '', // 数据类型
+ // 字符串片段缓存
+ firstPartData: '', // 前半部分数据字符串
+ isWaitingSecondPart: false // 是否正在等待后半部分数据
+ },
+
// 当前显示的3个股票数据(用于MarketOverview组件)
currentStockInfoList: [
{
@@ -270,7 +307,10 @@ export default {
change_value: 0,
change_percent: 0
}
- ]
+ ],
+
+ // 我的自选处理后的股票信息列表
+ myStocksInfoList: []
}
},
@@ -297,22 +337,50 @@ export default {
// 初始化TCP连接监听器
this.initTcpListeners()
- // 页面渲染完成后自动连接TCP
+ // 页面渲染完成后自动连接两个TCP连接
this.$nextTick(() => {
console.log('页面渲染完成,开始自动连接TCP服务器...')
- this.connectTcp()
+ // 延迟一小段时间确保页面完全加载后再连接
+ setTimeout(() => {
+ // 连接今日市场概览TCP(channel 1)
+ console.log('连接今日市场概览TCP(channel 1)...')
+ this.connectTcp()
+
+ // 稍微延迟后连接我的自选TCP(channel 2)
+ setTimeout(() => {
+ console.log('连接我的自选TCP(channel 2)...')
+ this.connectMyStocksTcp()
+ }, 500)
+ }, 1000)
})
},
// 页面销毁前的清理工作
onUnload() {
- // 自动关闭TCP连接
+ // 自动关闭主TCP连接
if (this.tcpConnected) {
- console.log('页面销毁,自动关闭TCP连接')
- tcpConnection.disconnect()
+ console.log('页面销毁,自动关闭主TCP连接')
+ tcpConnection.disconnect({
+ ip: '192.168.1.9',
+ port: '8080',
+ channel: '1',
+ charsetname: 'UTF-8'
+ })
this.tcpConnected = false
}
+ // 自动关闭我的自选TCP连接
+ if (this.myStocksTcpConnected) {
+ console.log('页面销毁,自动关闭我的自选TCP连接')
+ tcpConnection.disconnect({
+ ip: '192.168.1.9',
+ port: '8080',
+ channel: '2',
+ charsetname: 'UTF-8'
+ })
+ this.myStocksTcpConnected = false
+ }
+
// 清理防抖定时器
if (this.debounceTimer) {
clearTimeout(this.debounceTimer)
@@ -338,43 +406,79 @@ export default {
// 初始化TCP监听器
initTcpListeners() {
// 创建连接状态监听器并保存引用
- this.connectionListener = (status, result) => {
- this.tcpConnected = (status === 'connected')
- console.log('TCP连接状态变化:', status, this.tcpConnected)
+ this.connectionListener = (status, result, channel) => {
+ console.log('TCP连接状态变化:', status, 'channel:', channel)
- // 显示连接状态提示
- uni.showToast({
- title: status === 'connected' ? '连接服务器成功' : '服务器连接断开',
- icon: status === 'connected' ? 'success' : 'none',
- duration: 1000
- })
-
- // 连接成功后自动发送股票数据请求命令
- if (status === 'connected') {
- console.log('TCP连接成功,自动发送股票数据请求...')
- // 延迟一小段时间确保连接稳定后再发送命令
- setTimeout(() => {
- this.sendTcpMessage()
- }, 500)
+ // 根据channel更新对应的连接状态
+ if (channel === '1') {
+ // 主TCP连接
+ this.tcpConnected = (status === 'connected')
+ console.log('主TCP连接状态:', this.tcpConnected)
+
+ // 显示连接状态提示
+ uni.showToast({
+ title: status === 'connected' ? '主连接服务器成功' : '主服务器连接断开',
+ icon: status === 'connected' ? 'success' : 'none',
+ duration: 1000
+ })
+
+ // 连接成功后自动发送股票数据请求命令
+ if (status === 'connected') {
+ console.log('主TCP连接成功,自动发送股票数据请求...')
+ // 延迟一小段时间确保连接稳定后再发送命令
+ setTimeout(() => {
+ this.sendTcpMessage()
+ }, 500)
+ }
+ } else if (channel === '2') {
+ // 我的自选TCP连接
+ this.myStocksTcpConnected = (status === 'connected')
+ console.log('我的自选TCP连接状态:', this.myStocksTcpConnected)
+
+ // 显示连接状态提示
+ uni.showToast({
+ title: status === 'connected' ? '我的自选连接成功' : '我的自选连接断开',
+ icon: status === 'connected' ? 'success' : 'none',
+ duration: 1000
+ })
+
+ // 连接成功后自动发送我的自选股票数据请求
+ if (status === 'connected') {
+ console.log('我的自选TCP连接成功,自动发送自选股票数据请求...')
+ // 延迟一小段时间确保连接稳定后再发送命令
+ setTimeout(() => {
+ this.sendMyStocksTcpMessage()
+ }, 500)
+ }
}
}
// 创建消息监听器并保存引用
- this.messageListener = (type, message, parsedArray) => {
+ this.messageListener = (type, message, parsedArray, channel) => {
const messageObj = {
type: type,
content: message,
parsedArray: parsedArray,
+ channel: channel,
timestamp: new Date().toLocaleTimeString(),
direction: 'received'
}
- console.log("0000")
this.tcpMessages.push(messageObj)
- // console.log('收到TCP消息:', messageObj)
- console.log('home开始调用parseStockData',messageObj)
+ console.log('收到TCP消息:', messageObj)
+ console.log('消息来源channel:', channel)
- // 解析股票数据
- this.parseStockData(message)
+ // 根据channel调用相应的数据处理方法
+ if (channel === '1') {
+ // 主TCP连接 - 今日市场概览数据
+ // console.log('处理今日市场概览数据')
+ this.parseStockData(message)
+ } else if (channel === '2') {
+ // 我的自选TCP连接 - 我的自选数据
+ console.log('处理我的自选数据')
+ this.parseMyStocksData(message)
+ } else {
+ console.warn('未知的channel:', channel)
+ }
}
// 注册监听器
@@ -384,11 +488,11 @@ export default {
// 连接TCP服务器
connectTcp() {
- console.log('开始连接TCP服务器...')
+ // console.log('开始连接TCP服务器...')
// 先断开现有连接(如果存在)
if (this.tcpConnected) {
- console.log('检测到现有连接,先断开...')
+ // console.log('检测到现有连接,先断开...')
this.disconnectTcp()
// 等待断开完成后再连接
setTimeout(() => {
@@ -402,7 +506,7 @@ export default {
// 执行TCP连接
performTcpConnect() {
- console.log('执行TCP连接...')
+ // console.log('执行TCP连接...')
tcpConnection.connect(
{
ip: '192.168.1.9',
@@ -415,7 +519,7 @@ export default {
// 断开TCP连接
disconnectTcp() {
- console.log('断开TCP连接...')
+ // console.log('断开TCP连接...')
tcpConnection.disconnect(
{
ip: '192.168.1.9',
@@ -427,6 +531,321 @@ export default {
this.tcpConnected = false
},
+ // 连接我的自选TCP服务器
+ connectMyStocksTcp() {
+ console.log('开始连接我的自选TCP服务器...')
+
+ // 先断开现有连接(如果存在)
+ if (this.myStocksTcpConnected) {
+ console.log('检测到我的自选现有连接,先断开...')
+ this.disconnectMyStocksTcp()
+ // 等待断开完成后再连接
+ setTimeout(() => {
+ this.performMyStocksTcpConnect()
+ }, 500)
+ } else {
+ // 直接连接
+ this.performMyStocksTcpConnect()
+ }
+ },
+
+ // 执行我的自选TCP连接
+ performMyStocksTcpConnect() {
+ console.log('执行我的自选TCP连接...')
+ tcpConnection.connect(
+ {
+ ip: '192.168.1.9',
+ port: '8080',
+ channel: '2', // 我的自选使用channel 2
+ charsetname: 'UTF-8' // 默认UTF-8,可选GBK
+ }
+ )
+ },
+
+ // 断开我的自选TCP连接
+ disconnectMyStocksTcp() {
+ console.log('断开我的自选TCP连接...')
+ tcpConnection.disconnect(
+ {
+ ip: '192.168.1.9',
+ port: '8080',
+ channel: '2', // 我的自选使用channel 2
+ charsetname: 'UTF-8' // 默认UTF-8,可选GBK
+ }
+ )
+ this.myStocksTcpConnected = false
+ },
+
+ // 解析我的自选TCP股票数据
+ parseMyStocksData(message) {
+ try {
+ console.log('进入parseMyStocksData, message类型:', typeof message, '长度:', message.length)
+
+ // 第一步:检查数据状态(完整、前半部分、后半部分)
+ const dataStatus = this.getMyStocksDataStatus(message)
+
+ let completeMessage = ''
+
+ switch (dataStatus) {
+ case 'complete':
+ // 完整数据,直接处理
+ console.log('我的自选:检测到完整数据,直接处理')
+ completeMessage = message
+ break
+
+ case 'first_part':
+ // 前半部分数据,缓存并等待后半部分
+ console.log('我的自选:检测到前半部分数据,开始缓存')
+ this.cacheMyStocksFirstPartData(message)
+ return // 等待后半部分数据
+
+ case 'second_part':
+ // 后半部分数据,检查是否有缓存的前半部分
+ if (this.myStocksTcpDataCache.isWaitingSecondPart) {
+ console.log('我的自选:检测到后半部分数据,开始拼接')
+ completeMessage = this.concatenateMyStocksDataParts(message)
+ } else {
+ console.log('我的自选:收到后半部分数据,但没有缓存的前半部分,跳过处理')
+ return
+ }
+ break
+
+ case 'invalid':
+ default:
+ console.log('我的自选:数据格式无效,跳过处理')
+ return
+ }
+
+ // 第二步:解析完整的JSON数据
+ let parsedMessage
+ try {
+ console.log('我的自选:开始解析完整JSON数据,长度:', completeMessage.length)
+ parsedMessage = JSON.parse(completeMessage)
+ console.log('我的自选:JSON解析成功,解析后类型:', typeof parsedMessage, parsedMessage)
+ } catch (parseError) {
+ console.error('我的自选:JSON解析失败:', parseError.message)
+ // 清空字符串片段缓存
+ this.clearMyStocksStringFragmentCache()
+ return
+ }
+
+ // 第三步:检查是否是股票数据类型
+ if (!((parsedMessage.type === 'batch_data_chunk' || parsedMessage.type === 'batch_realtime_data') && parsedMessage.data)) {
+ console.log('我的自选:不是batch_data_chunk或batch_realtime_data类型的消息,跳过处理')
+ return
+ }
+
+ console.log('我的自选:开始处理股票数据')
+
+ // 第四步:验证数据完整性(对象级别的完整性检查)
+ // 注意:batch_data_chunk类型的数据不需要验证完整性,直接处理
+ if (parsedMessage.type === 'batch_data_chunk') {
+ console.log('我的自选:batch_data_chunk类型数据,跳过完整性验证,直接处理')
+ this.processCompleteMyStocksData(parsedMessage)
+ } else {
+ const isDataComplete = this.validateMyStocksDataIntegrity(parsedMessage)
+
+ if (isDataComplete) {
+ // 数据完整,直接处理
+ console.log('我的自选:对象级数据完整,直接处理')
+ this.processCompleteMyStocksData(parsedMessage)
+ } else {
+ // 数据不完整,需要拼接(对象级别的拼接)
+ console.log('我的自选:对象级数据不完整,开始拼接处理')
+
+ // 将当前数据合并到缓存中
+ this.mergeMyStocksDataToCache(parsedMessage)
+
+ // 检查缓存中的数据是否已经完整
+ if (this.isMyStocksCacheDataComplete()) {
+ console.log('我的自选:缓存数据已完整,开始处理')
+ const completeData = this.getCompleteMyStocksDataFromCache()
+ this.processCompleteMyStocksData(completeData)
+ } else {
+ console.log('我的自选:缓存数据仍不完整,等待更多数据片段')
+ }
+ }
+ }
+ } catch (error) {
+ console.error('我的自选:解析TCP股票数据失败:', error.message)
+ console.error('我的自选:错误详情:', error)
+ // 发生错误时清空所有缓存
+ this.clearMyStocksStringFragmentCache()
+ if (this.myStocksTcpDataCache.isCollecting) {
+ console.log('我的自选:发生错误,清空对象级数据缓存')
+ this.myStocksTcpDataCache.isCollecting = false
+ this.myStocksTcpDataCache.expectedCount = 0
+ this.myStocksTcpDataCache.collectedData = {}
+ this.myStocksTcpDataCache.timestamp = ''
+ this.myStocksTcpDataCache.type = ''
+ }
+ }
+ },
+
+ // 验证我的自选数据完整性
+ validateMyStocksDataIntegrity(parsedMessage) {
+ if (!parsedMessage.count || !parsedMessage.data) {
+ return false
+ }
+
+ const dataObjectCount = Object.keys(parsedMessage.data).length
+ const expectedCount = parsedMessage.count
+
+ console.log(`我的自选数据完整性验证: 期望${expectedCount}个对象,实际${dataObjectCount}个对象`)
+ return dataObjectCount === expectedCount
+ },
+
+ // 检查我的自选数据状态(完整数据、前半部分数据、后半部分数据)
+ getMyStocksDataStatus(message) {
+ if (typeof message !== 'string') {
+ return 'invalid'
+ }
+
+ const trimmedMessage = message.trim()
+ const startsWithBrace = trimmedMessage.startsWith('{')
+ const endsWithBrace = trimmedMessage.endsWith('}')
+
+ if (startsWithBrace && endsWithBrace) {
+ // 以{开头,以}结尾 - 完整数据
+ console.log('我的自选:检测到完整数据格式')
+ return 'complete'
+ } else if (startsWithBrace && !endsWithBrace) {
+ // 以{开头,不以}结尾 - 前半部分数据
+ console.log('我的自选:检测到前半部分数据')
+ return 'first_part'
+ } else if (!startsWithBrace && endsWithBrace) {
+ // 不以{开头,以}结尾 - 后半部分数据
+ console.log('我的自选:检测到后半部分数据')
+ return 'second_part'
+ } else {
+ // 其他情况 - 无效数据
+ console.log('我的自选:检测到无效数据格式')
+ return 'invalid'
+ }
+ },
+
+ // 缓存我的自选前半部分数据
+ cacheMyStocksFirstPartData(message) {
+ this.myStocksTcpDataCache.firstPartData = message.trim()
+ this.myStocksTcpDataCache.isWaitingSecondPart = true
+ console.log('我的自选:已缓存前半部分数据,长度:', this.myStocksTcpDataCache.firstPartData.length)
+ },
+
+ // 拼接我的自选前后两部分数据
+ concatenateMyStocksDataParts(secondPartMessage) {
+ const completeMessage = this.myStocksTcpDataCache.firstPartData + secondPartMessage.trim()
+ console.log('我的自选:数据拼接完成,完整数据长度:', completeMessage.length)
+
+ // 清空缓存
+ this.clearMyStocksStringFragmentCache()
+
+ return completeMessage
+ },
+
+ // 清空我的自选字符串片段缓存
+ clearMyStocksStringFragmentCache() {
+ this.myStocksTcpDataCache.firstPartData = ''
+ this.myStocksTcpDataCache.isWaitingSecondPart = false
+ console.log('我的自选:字符串片段缓存已清空')
+ },
+
+ // 合并我的自选数据到缓存中
+ mergeMyStocksDataToCache(parsedMessage) {
+ // 如果是第一次收集数据,初始化缓存
+ if (!this.myStocksTcpDataCache.isCollecting) {
+ this.myStocksTcpDataCache.isCollecting = true
+ this.myStocksTcpDataCache.expectedCount = parsedMessage.count
+ this.myStocksTcpDataCache.collectedData = {}
+ this.myStocksTcpDataCache.timestamp = parsedMessage.timestamp
+ this.myStocksTcpDataCache.type = parsedMessage.type
+ console.log('我的自选:开始收集数据片段,期望总数:', parsedMessage.count)
+ }
+
+ // 合并新数据到缓存中
+ if (parsedMessage.data) {
+ Object.assign(this.myStocksTcpDataCache.collectedData, parsedMessage.data)
+ console.log('我的自选:数据片段已合并,当前已收集:', Object.keys(this.myStocksTcpDataCache.collectedData).length, '个对象')
+ }
+ },
+
+ // 检查我的自选缓存数据是否完整
+ isMyStocksCacheDataComplete() {
+ const collectedCount = Object.keys(this.myStocksTcpDataCache.collectedData).length
+ const expectedCount = this.myStocksTcpDataCache.expectedCount
+
+ console.log(`我的自选缓存数据检查: 已收集${collectedCount}个,期望${expectedCount}个`)
+ return collectedCount === expectedCount && collectedCount > 0
+ },
+
+ // 获取我的自选完整的缓存数据并清空缓存
+ getCompleteMyStocksDataFromCache() {
+ const completeData = {
+ count: this.myStocksTcpDataCache.expectedCount,
+ data: { ...this.myStocksTcpDataCache.collectedData },
+ stock_count: this.myStocksTcpDataCache.expectedCount,
+ timestamp: this.myStocksTcpDataCache.timestamp,
+ type: this.myStocksTcpDataCache.type
+ }
+
+ // 清空缓存
+ this.myStocksTcpDataCache.isCollecting = false
+ this.myStocksTcpDataCache.expectedCount = 0
+ this.myStocksTcpDataCache.collectedData = {}
+ this.myStocksTcpDataCache.timestamp = ''
+ this.myStocksTcpDataCache.type = ''
+
+ console.log('我的自选:获取完整数据并清空缓存,数据对象数:', Object.keys(completeData.data).length)
+ return completeData
+ },
+
+ // 处理我的自选完整的股票数据
+ processCompleteMyStocksData(completeData) {
+ console.log("我的自选:开始更新我的自选TCP股票数据存储")
+
+ // 更新我的自选TCP股票数据存储
+ this.myStocksTcpData = {
+ count: completeData.count || 0,
+ data: completeData.data || {},
+ stock_count: completeData.stock_count || 0,
+ timestamp: completeData.timestamp || '',
+ type: completeData.type || ''
+ }
+
+ // 获取所有股票的数据用于显示
+ const stockCodes = Object.keys(completeData.data)
+ const newMyStocksInfoList = []
+
+ // 只处理前3条股票数据
+ const maxStocks = Math.min(3, stockCodes.length)
+ for (let i = 0; i < maxStocks; i++) {
+ const stockCode = stockCodes[i]
+
+ // 检查数据结构
+ if (completeData.data[stockCode] && Array.isArray(completeData.data[stockCode]) && completeData.data[stockCode].length > 0) {
+ const stockData = completeData.data[stockCode][0] // 取第一条数据
+ console.log('遍历的数据:', stockCode, stockData)
+
+ if (stockData && stockData.current_price !== undefined) {
+ // 直接使用返回的数据,不重新计算
+ newMyStocksInfoList.push({
+ stock_code: stockCode,
+ stock_name: stockData.stock_name || '未知股票',
+ current_price: parseFloat(stockData.current_price).toFixed(2),
+ change: stockData.change || '0.00%',
+ change_value: stockData.change_value || 0,
+ change_percent: parseFloat(stockData.change) || 0
+ })
+ }
+ }
+ }
+
+ // 更新我的自选股票信息列表
+ if (newMyStocksInfoList.length > 0) {
+ this.myStocksInfoList = newMyStocksInfoList
+ console.log('我的自选:股票数据更新成功,共', newMyStocksInfoList.length, '个股票:', this.myStocksInfoList)
+ }
+ },
+
// 发送TCP消息
sendTcpMessage() {
// 构造要发送的消息对象
@@ -442,7 +861,7 @@ export default {
// 发送消息
const success = tcpConnection.send(messageData)
if (success) {
- console.log('home发送TCP消息:', messageData)
+ // console.log('home发送TCP消息:', messageData)
uni.showToast({
title: '服务器连接成功',
icon: 'success',
@@ -451,6 +870,30 @@ export default {
}
},
+ // 发送我的自选TCP消息
+ sendMyStocksTcpMessage() {
+ // 构造要发送的消息对象 - 我的自选股票数据请求
+ const messageData = {"command": "batch_real_time", "stock_codes": ["SH.000001","SH.000002","SH.000003"]}
+
+ // 发送消息到channel 2(我的自选TCP连接)
+ const success = tcpConnection.send(messageData, { channel: '2' })
+ if (success) {
+ console.log('我的自选:发送TCP消息成功:', messageData)
+ uni.showToast({
+ title: '我的自选数据请求已发送',
+ icon: 'success',
+ duration: 1500
+ })
+ } else {
+ console.error('我的自选:发送TCP消息失败')
+ uni.showToast({
+ title: '我的自选连接失败',
+ icon: 'error',
+ duration: 1500
+ })
+ }
+ },
+
// 清空消息记录
clearTcpMessages() {
@@ -481,7 +924,7 @@ export default {
const dataObjectCount = Object.keys(parsedMessage.data).length
const expectedCount = parsedMessage.count
- console.log(`数据完整性验证: 期望${expectedCount}个对象,实际${dataObjectCount}个对象`)
+ // console.log(`数据完整性验证: 期望${expectedCount}个对象,实际${dataObjectCount}个对象`)
return dataObjectCount === expectedCount
},
@@ -497,19 +940,19 @@ export default {
if (startsWithBrace && endsWithBrace) {
// 以{开头,以}结尾 - 完整数据
- console.log('检测到完整数据格式')
+ // console.log('检测到完整数据格式')
return 'complete'
} else if (startsWithBrace && !endsWithBrace) {
// 以{开头,不以}结尾 - 前半部分数据
- console.log('检测到前半部分数据')
+ // console.log('检测到前半部分数据')
return 'first_part'
} else if (!startsWithBrace && endsWithBrace) {
// 不以{开头,以}结尾 - 后半部分数据
- console.log('检测到后半部分数据')
+ // console.log('检测到后半部分数据')
return 'second_part'
} else {
// 其他情况 - 无效数据
- console.log('检测到无效数据格式')
+ // console.log('检测到无效数据格式')
return 'invalid'
}
@@ -519,13 +962,13 @@ export default {
cacheFirstPartData(message) {
this.tcpDataCache.firstPartData = message.trim()
this.tcpDataCache.isWaitingSecondPart = true
- console.log('已缓存前半部分数据,长度:', this.tcpDataCache.firstPartData.length)
+ // console.log('已缓存前半部分数据,长度:', this.tcpDataCache.firstPartData.length)
},
// 拼接前后两部分数据
concatenateDataParts(secondPartMessage) {
const completeMessage = this.tcpDataCache.firstPartData + secondPartMessage.trim()
- console.log('数据拼接完成,完整数据长度:', completeMessage.length)
+ // console.log('数据拼接完成,完整数据长度:', completeMessage.length)
// 清空缓存
this.clearStringFragmentCache()
@@ -537,7 +980,7 @@ export default {
clearStringFragmentCache() {
this.tcpDataCache.firstPartData = ''
this.tcpDataCache.isWaitingSecondPart = false
- console.log('字符串片段缓存已清空')
+ // console.log('字符串片段缓存已清空')
},
// 合并数据到缓存中
@@ -549,13 +992,13 @@ export default {
this.tcpDataCache.collectedData = {}
this.tcpDataCache.timestamp = parsedMessage.timestamp
this.tcpDataCache.type = parsedMessage.type
- console.log('开始收集数据片段,期望总数:', parsedMessage.count)
+ // console.log('开始收集数据片段,期望总数:', parsedMessage.count)
}
// 合并新数据到缓存中
if (parsedMessage.data) {
Object.assign(this.tcpDataCache.collectedData, parsedMessage.data)
- console.log('数据片段已合并,当前已收集:', Object.keys(this.tcpDataCache.collectedData).length, '个对象')
+ // console.log('数据片段已合并,当前已收集:', Object.keys(this.tcpDataCache.collectedData).length, '个对象')
}
},
@@ -564,7 +1007,7 @@ export default {
const collectedCount = Object.keys(this.tcpDataCache.collectedData).length
const expectedCount = this.tcpDataCache.expectedCount
- console.log(`缓存数据检查: 已收集${collectedCount}个,期望${expectedCount}个`)
+ // console.log(`缓存数据检查: 已收集${collectedCount}个,期望${expectedCount}个`)
return collectedCount === expectedCount && collectedCount > 0
},
@@ -585,14 +1028,14 @@ export default {
this.tcpDataCache.timestamp = ''
this.tcpDataCache.type = ''
- console.log('获取完整数据并清空缓存,数据对象数:', Object.keys(completeData.data).length)
+ // console.log('获取完整数据并清空缓存,数据对象数:', Object.keys(completeData.data).length)
return completeData
},
// 解析TCP股票数据
parseStockData(message) {
try {
- console.log('进入parseStockData, message类型:', typeof message, '长度:', message.length)
+ // console.log('进入parseStockData, message类型:', typeof message, '长度:', message.length)
// 第一步:检查数据状态(完整、前半部分、后半部分)
const dataStatus = this.getDataStatus(message)
@@ -602,41 +1045,41 @@ export default {
switch (dataStatus) {
case 'complete':
// 完整数据,直接处理
- console.log('检测到完整数据,直接处理')
+ // console.log('检测到完整数据,直接处理')
completeMessage = message
break
case 'first_part':
// 前半部分数据,缓存并等待后半部分
- console.log('检测到前半部分数据,开始缓存')
+ // console.log('检测到前半部分数据,开始缓存')
this.cacheFirstPartData(message)
return // 等待后半部分数据
case 'second_part':
// 后半部分数据,检查是否有缓存的前半部分
if (this.tcpDataCache.isWaitingSecondPart) {
- console.log('检测到后半部分数据,开始拼接')
+ // console.log('检测到后半部分数据,开始拼接')
completeMessage = this.concatenateDataParts(message)
} else {
- console.log('收到后半部分数据,但没有缓存的前半部分,跳过处理')
+ // console.log('收到后半部分数据,但没有缓存的前半部分,跳过处理')
return
}
break
case 'invalid':
default:
- console.log('数据格式无效,跳过处理')
+ // console.log('数据格式无效,跳过处理')
return
}
// 第二步:解析完整的JSON数据
let parsedMessage
try {
- console.log('开始解析完整JSON数据,长度:', completeMessage.length)
+ // console.log('开始解析完整JSON数据,长度:', completeMessage.length)
parsedMessage = JSON.parse(completeMessage)
- console.log('JSON解析成功,解析后类型:', typeof parsedMessage, parsedMessage)
+ // console.log('JSON解析成功,解析后类型:', typeof parsedMessage, parsedMessage)
} catch (parseError) {
- console.error('JSON解析失败:', parseError.message)
+ // console.error('JSON解析失败:', parseError.message)
// 清空字符串片段缓存
this.clearStringFragmentCache()
return
@@ -644,48 +1087,48 @@ export default {
// 第三步:检查是否是股票数据类型
if (!((parsedMessage.type === 'batch_data_chunk' || parsedMessage.type === 'batch_realtime_data') && parsedMessage.data)) {
- console.log('不是batch_data_chunk或batch_realtime_data类型的消息,跳过处理')
+ // console.log('不是batch_data_chunk或batch_realtime_data类型的消息,跳过处理')
return
}
- console.log('开始处理股票数据')
+ // console.log('开始处理股票数据')
// 第四步:验证数据完整性(对象级别的完整性检查)
// 注意:batch_data_chunk类型的数据不需要验证完整性,直接处理
if (parsedMessage.type === 'batch_data_chunk') {
- console.log('batch_data_chunk类型数据,跳过完整性验证,直接处理')
+ // console.log('batch_data_chunk类型数据,跳过完整性验证,直接处理')
this.processCompleteStockData(parsedMessage)
} else {
const isDataComplete = this.validateDataIntegrity(parsedMessage)
if (isDataComplete) {
// 数据完整,直接处理
- console.log('对象级数据完整,直接处理')
+ // console.log('对象级数据完整,直接处理')
this.processCompleteStockData(parsedMessage)
} else {
// 数据不完整,需要拼接(对象级别的拼接)
- console.log('对象级数据不完整,开始拼接处理')
+ // console.log('对象级数据不完整,开始拼接处理')
// 将当前数据合并到缓存中
this.mergeDataToCache(parsedMessage)
// 检查缓存中的数据是否已经完整
if (this.isCacheDataComplete()) {
- console.log('缓存数据已完整,开始处理')
+ // console.log('缓存数据已完整,开始处理')
const completeData = this.getCompleteDataFromCache()
this.processCompleteStockData(completeData)
} else {
- console.log('缓存数据仍不完整,等待更多数据片段')
+ // console.log('缓存数据仍不完整,等待更多数据片段')
}
}
}
} catch (error) {
- console.error('解析TCP股票数据失败:', error.message)
- console.error('错误详情:', error)
+ // console.error('解析TCP股票数据失败:', error.message)
+ // console.error('错误详情:', error)
// 发生错误时清空所有缓存
this.clearStringFragmentCache()
if (this.tcpDataCache.isCollecting) {
- console.log('发生错误,清空对象级数据缓存')
+ // console.log('发生错误,清空对象级数据缓存')
this.tcpDataCache.isCollecting = false
this.tcpDataCache.expectedCount = 0
this.tcpDataCache.collectedData = {}
@@ -697,7 +1140,7 @@ export default {
// 处理完整的股票数据
processCompleteStockData(completeData) {
- console.log("开始更新TCP股票数据存储")
+ // console.log("开始更新TCP股票数据存储")
// 更新TCP股票数据存储
this.tcpStockData = {
@@ -741,7 +1184,7 @@ export default {
// 更新当前显示的股票信息列表
if (newStockInfoList.length > 0) {
this.currentStockInfoList = newStockInfoList
- console.log('股票数据更新成功,共', newStockInfoList.length, '个股票:', this.currentStockInfoList)
+ // console.log('股票数据更新成功,共', newStockInfoList.length, '个股票:', this.currentStockInfoList)
}
},
@@ -750,13 +1193,13 @@ export default {
if (this.connectionListener) {
tcpConnection.removeConnectionListener(this.connectionListener)
this.connectionListener = null
- console.log('已移除TCP连接状态监听器')
+ // console.log('已移除TCP连接状态监听器')
}
if (this.messageListener) {
tcpConnection.removeMessageListener(this.messageListener)
this.messageListener = null
- console.log('已移除TCP消息监听器')
+ // console.log('已移除TCP消息监听器')
}
}
}
@@ -1405,4 +1848,32 @@ export default {
color: #333;
word-break: break-all;
}
+
+/* 我的自选TCP控制样式 */
+.my-stocks-tcp-control {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ margin-top: 8px;
+ padding: 8px 12px;
+ background-color: #f8f9fa;
+ border-radius: 8px;
+ border: 1px solid #e9ecef;
+}
+
+.tcp-buttons {
+ display: flex;
+ gap: 6px;
+}
+
+.my-stocks-tcp-control .tcp-btn {
+ flex: none;
+ min-width: 50px;
+ height: 28px;
+ border-radius: 4px;
+ font-size: 11px;
+ border: none;
+ color: white;
+ font-weight: bold;
+}
\ No newline at end of file