132 lines
3.5 KiB
TypeScript
132 lines
3.5 KiB
TypeScript
import { defineStore } from 'pinia'
|
||
import { ref } from 'vue'
|
||
import { MQTTClient } from '@/utils/mqttClient'
|
||
import { useUserStore } from './user'
|
||
import { useOrderPositionStore } from '@/stores/modules/orderPosition.ts'
|
||
|
||
// ============================================================
|
||
// 类型声明
|
||
// ============================================================
|
||
|
||
/** 持仓单项数据结构(根据实际业务接口调整字段) */
|
||
export interface PositionItem {
|
||
id: string
|
||
code: string
|
||
name?: string
|
||
volume?: number
|
||
direction?: number // 1-做多, 2-做空
|
||
open_price?: number
|
||
current_price?: number
|
||
profit?: number
|
||
take_profit?: number
|
||
stop_loss?: number
|
||
open_time?: string
|
||
[key: string]: any
|
||
}
|
||
|
||
/** 用户信息最小化类型(用于类型断言) */
|
||
interface UserInfo {
|
||
redis_key: string
|
||
token: string
|
||
account_id: string
|
||
}
|
||
|
||
/** Vite 环境变量扩展(如项目已有 env.d.ts 可忽略) */
|
||
declare const __VITE_MQTT_TRANSACTION_HOST__: string
|
||
|
||
// ============================================================
|
||
// Store 定义
|
||
// ============================================================
|
||
|
||
export const useTransactionStore = defineStore('transaction', () => {
|
||
// ------------------ 依赖注入 ------------------
|
||
const mqttClient = new MQTTClient()
|
||
const userStore = useUserStore()
|
||
const orderStore = useOrderPositionStore()
|
||
|
||
// ------------------ 状态 ------------------
|
||
/** 持仓列表 */
|
||
const positionList = ref<PositionItem[]>([])
|
||
|
||
// ------------------ 初始化 ------------------
|
||
|
||
/**
|
||
* 初始化行情 MQTT 连接
|
||
* 建立连接 → 订阅主题 → 注册消息回调
|
||
*/
|
||
const initMarketConditionsMQTT = async (): Promise<void> => {
|
||
const { redis_key, token } = userStore.userInfo as UserInfo
|
||
|
||
await mqttClient.connect(import.meta.env.VITE_MQTT_TRANSACTION_HOST as string, {
|
||
username: `${redis_key}`,
|
||
password: `${token}`,
|
||
})
|
||
|
||
await subscribeTheme()
|
||
}
|
||
|
||
/**
|
||
* 订阅主题并注册消息处理器
|
||
* 仅保留持仓列表推送(POSITION_FLOATING_BACK)
|
||
*/
|
||
const subscribeTheme = async (): Promise<void> => {
|
||
const { id } = userStore.userInfo as UserInfo
|
||
|
||
if (mqttClient.isConnected) {
|
||
const topic = `push/${id}`
|
||
await mqttClient.subscribe([topic])
|
||
|
||
mqttClient.onTopicMessages({
|
||
[topic]: (_topic: string, msg: string): void => {
|
||
console.log(_topic, msg)
|
||
|
||
const [type, data] = msg.split('|')
|
||
switch (type) {
|
||
case 'POSITION_FLOATING_BACK': {
|
||
// 持仓列表回调:交由 orderStore 处理
|
||
orderStore.handlePositionOrderList(data)
|
||
break
|
||
}
|
||
default:
|
||
break
|
||
}
|
||
},
|
||
})
|
||
} else {
|
||
setTimeout(subscribeTheme, 30)
|
||
}
|
||
}
|
||
|
||
// ------------------ 持仓列表 ------------------
|
||
|
||
/**
|
||
* 向服务端请求持仓列表
|
||
* 服务端通过 POSITION_FLOATING_BACK 推送结果
|
||
*/
|
||
const getPositionList = (account_id: string): void => {
|
||
|
||
if (mqttClient.isConnected) {
|
||
console.log('持仓 POSITION 持仓列表数据', `POSITION::${account_id}`)
|
||
mqttClient.publish('server/trade', `POSITION::${account_id}`)
|
||
} else {
|
||
setTimeout(getPositionList, 30)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 关闭订阅,清空数组
|
||
* */
|
||
const disconnect = () => {
|
||
mqttClient.disconnect()
|
||
positionList.value = []
|
||
}
|
||
|
||
// ------------------ 暴露 ------------------
|
||
return {
|
||
mqttClient,
|
||
positionList,
|
||
initMarketConditionsMQTT,
|
||
getPositionList,
|
||
}
|
||
})
|