foreign-admin-ui/src/stores/modules/transaction.ts

132 lines
3.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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,
}
})