modify recommend page

This commit is contained in:
simple321vip
2022-12-28 21:25:22 +08:00
parent ab326d5cbb
commit b23d35c29b
15 changed files with 527 additions and 226 deletions
-1
View File
@@ -75,4 +75,3 @@ export default [
},
},
] as MockMethod[]
// /auth/api/v1/author/blog/content
+134
View File
@@ -0,0 +1,134 @@
import { MockMethod } from 'vite-plugin-mock'
export default [
{
url: '/trader/api/v1/exchanges',
method: 'get',
response: ({ body, query }) => {
return {
"exchanges": [
"CFFEX",
"SHFE",
"CZCE",
// "DCE",
// "INE",
// "GFEX"
]
}
}
},
{
url: '/trader/api/v1/subscribe/vt_symbols',
method: 'get',
response: ({ body, query }) => {
return {
"vt_symbols": [
"RM301.CZCE",
"RM303.CZCE",
]
}
}
},
{
url: '/trader/api/v1/vt_symbols',
method: 'get',
response: ({ body, query }) => {
return {
"vt_symbols": {
"CFFEX": [],
"SHFE": [],
"CZCE": ["RM301.CZCE", "RM303.CZCE", "RM305.CZCE",],
}
}
}
},
{
url: '/trader/api/v1/ticks',
method: 'get',
response: ({ body, query }) => {
return {
"ticks": [
{
"ask_price_1": 3159.0,
"ask_price_2": 0,
"ask_price_3": 0,
"ask_price_4": 0,
"ask_price_5": 0,
"bid_price_1": 3156.0,
"bid_price_2": 0,
"bid_price_3": 0,
"bid_price_4": 0,
"bid_price_5": 0,
"exchange": "CZCE",
"high_price": 3167.0,
"last_price": 3156.0,
"last_volume": 0,
"limit_down": 2900.0,
"limit_up": 3406.0,
"low_price": 3156.0,
"name": "\u83dc\u7c951\u6708",
"open_interest": 10099.0,
"open_price": 3160.0,
"pre_close": 3160.0,
"symbol": "RM301",
"turnover": 4149080.0,
"volume": 1313
},
{
"ask_price_1": 3094.0,
"ask_price_2": 0,
"ask_price_3": 0,
"ask_price_4": 0,
"ask_price_5": 0,
"bid_price_1": 3093.0,
"bid_price_2": 0,
"bid_price_3": 0,
"bid_price_4": 0,
"bid_price_5": 0,
"exchange": "CZCE",
"high_price": 3104.0,
"last_price": 3093.0,
"last_volume": 0,
"limit_down": 2839.0,
"limit_up": 3333.0,
"low_price": 3084.0,
"name": "\u83dc\u7c953\u6708",
"open_interest": 136677.0,
"open_price": 3088.0,
"pre_close": 3087.0,
"symbol": "RM303",
"turnover": 12512136.0,
"volume": 4044
},
{
"ask_price_1": 0.0,
"ask_price_2": 0,
"ask_price_3": 0,
"ask_price_4": 0,
"ask_price_5": 0,
"bid_price_1": 0.0,
"bid_price_2": 0,
"bid_price_3": 0,
"bid_price_4": 0,
"bid_price_5": 0,
"exchange": "CZCE",
"high_price": 0,
"last_price": 0,
"last_volume": 0,
"limit_down": 2684.0,
"limit_up": 3560.0,
"low_price": 0,
"name": "\u666e\u9ea65\u6708",
"open_interest": 0.0,
"open_price": 0,
"pre_close": 0,
"symbol": "PM305",
"turnover": 0.0,
"volume": 0
}
]
}
}
},
] as MockMethod[]
+25
View File
@@ -449,6 +449,16 @@
"picomatch": "^2.0.4"
}
},
"aplayer": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/aplayer/-/aplayer-1.10.1.tgz",
"integrity": "sha512-HAfyxgCUTLAqtYlxzzK9Fyqg6y+kZ9CqT1WfeWE8FSzwspT6oBqWOZHANPHF3RGTtC33IsyEgrfthPDzU5r9kQ==",
"requires": {
"balloon-css": "^0.5.0",
"promise-polyfill": "7.1.0",
"smoothscroll": "0.4.0"
}
},
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
@@ -491,6 +501,11 @@
"@babel/types": "^7.9.6"
}
},
"balloon-css": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/balloon-css/-/balloon-css-0.5.2.tgz",
"integrity": "sha512-zheJpzwyNrG4t39vusA67v3BYg1HTVXOF8cErPEHzWK88PEOFwgo6Ea9VHOgOWNMgeuOtFVtB73NE2NWl9uDyQ=="
},
"binary-extensions": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
@@ -1450,6 +1465,11 @@
"asap": "~2.0.3"
}
},
"promise-polyfill": {
"version": "7.1.0",
"resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-7.1.0.tgz",
"integrity": "sha512-P6NJ2wU/8fac44ENORsuqT8TiolKGB2u0fEClPtXezn7w5cmLIjM/7mhPlTebke2EPr6tmqZbXvnX0TxwykGrg=="
},
"pug": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/pug/-/pug-3.0.2.tgz",
@@ -1673,6 +1693,11 @@
"object-inspect": "^1.9.0"
}
},
"smoothscroll": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/smoothscroll/-/smoothscroll-0.4.0.tgz",
"integrity": "sha512-sggQ3U2Un38b3+q/j1P4Y4fCboCtoUIaBYoge+Lb6Xg1H8RTIif/hugVr+ErMtIDpvBbhQfTjtiTeYAfbw1ZGQ=="
},
"sortablejs": {
"version": "1.14.0",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.14.0.tgz",
+1
View File
@@ -13,6 +13,7 @@
"@element-plus/icons-vue": "^1.1.4",
"@types/node": "^17.0.23",
"axios": "^0.26.1",
"aplayer": "^1.10.1",
"clipboard": "^2.0.10",
"copy-to-clipboard": "^3.3.1",
"echarts": "^5.3.2",
+11 -11
View File
@@ -1,10 +1,10 @@
import { trader_service } from '../utils/request'
import { service } from '../utils/request'
"CTA strategy"
"query account"
const get_accounts = () => {
return trader_service({
return service({
url: '/trader/api/v1/accounts',
method: 'GET',
})
@@ -12,7 +12,7 @@ const get_accounts = () => {
"get contract"
const get_contract = (symbol: string) => {
return trader_service({
return service({
url: '/trader/api/v1/contract/' + symbol,
method: 'GET',
})
@@ -20,7 +20,7 @@ const get_contract = (symbol: string) => {
"get tick"
const get_tick = (symbol: string) => {
return trader_service({
return service({
url: '/trader/api/v1/tick/' + symbol,
method: 'GET',
})
@@ -28,7 +28,7 @@ const get_tick = (symbol: string) => {
"get ticks"
const get_ticks = () => {
return trader_service({
return service({
url: '/trader/api/v1/ticks',
method: 'GET',
})
@@ -36,16 +36,16 @@ const get_ticks = () => {
"send_order"
const send_order = (data: any) => {
return trader_service({
return service({
url: '/trader/api/v1/order',
method: 'POST',
data: data
})
}
"get tick"
"subscribe tick"
const subscribe = (symbol: string) => {
return trader_service({
return service({
url: '/trader/api/v1/subscribe/' + symbol,
method: 'GET',
})
@@ -53,7 +53,7 @@ const subscribe = (symbol: string) => {
"get subscribe vt_symbols"
const get_subscribe_vt_symbols = () => {
return trader_service({
return service({
url: '/trader/api/v1/subscribe/vt_symbols',
method: 'GET',
})
@@ -61,7 +61,7 @@ const get_subscribe_vt_symbols = () => {
"get all vt_symbols"
const get_vt_symbols = () => {
return trader_service({
return service({
url: '/trader/api/v1/vt_symbols',
method: 'GET',
})
@@ -69,7 +69,7 @@ const get_vt_symbols = () => {
"get exchanges"
const get_exchanges = () => {
return trader_service({
return service({
url: '/trader/api/v1/exchanges',
method: 'GET',
})
+14 -14
View File
@@ -1,10 +1,10 @@
import { trader_service } from '../utils/request'
import { service } from '../utils/request'
"CTA strategy"
"strategy file list"
const get_strategy_files = () => {
return trader_service({
return service({
url: '/trader/api/v1/strategy_file',
method: 'GET',
})
@@ -12,7 +12,7 @@ const get_strategy_files = () => {
"strategy file list"
const get_strategy_load_files = () => {
return trader_service({
return service({
url: '/trader/api/v1/strategy_file/load',
method: 'GET',
})
@@ -22,7 +22,7 @@ const get_strategy_load_files = () => {
const upload_strategy_file = (file: any) => {
const formData = new FormData();
formData.append("file", file)
return trader_service({
return service({
url: '/trader/api/v1/strategy_file',
method: 'POST',
data: formData,
@@ -34,7 +34,7 @@ const upload_strategy_file = (file: any) => {
"load a strategy file"
const load_strategy_file = (file_name: string) => {
return trader_service({
return service({
url: '/trader/api/v1/strategy_file/' + file_name,
method: 'PUT',
})
@@ -42,7 +42,7 @@ const load_strategy_file = (file_name: string) => {
"unload a strategy file"
const unload_strategy_file = (class_name: string) => {
return trader_service({
return service({
url: '/trader/api/v1/strategy_file/' + class_name,
method: 'PATCH',
})
@@ -50,7 +50,7 @@ const unload_strategy_file = (class_name: string) => {
"remove a strategy file"
const remove_strategy_file = (file_name: string) => {
return trader_service({
return service({
url: '/trader/api/v1/strategy_file/' + file_name,
method: 'DELETE',
})
@@ -59,7 +59,7 @@ const remove_strategy_file = (file_name: string) => {
"get strategy list"
const get_strategies = () => {
return trader_service({
return service({
url: '/trader/api/v1/strategies',
method: 'GET',
})
@@ -67,7 +67,7 @@ const get_strategies = () => {
"create a strategy"
const create_strategy = (ruleForm: any) => {
return trader_service({
return service({
url: '/trader/api/v1/strategy/' + ruleForm.strategy_name,
method: 'POST',
data: ruleForm
@@ -76,7 +76,7 @@ const create_strategy = (ruleForm: any) => {
"init a strategy"
const init_strategy = (strategy_name: string) => {
return trader_service({
return service({
url: '/trader/api/v1/strategy/init/' + strategy_name,
method: 'PUT',
})
@@ -84,7 +84,7 @@ const init_strategy = (strategy_name: string) => {
"start a strategy"
const start_strategy = (strategy_name: string) => {
return trader_service({
return service({
url: '/trader/api/v1/strategy/' + strategy_name,
method: 'PUT',
})
@@ -92,7 +92,7 @@ const start_strategy = (strategy_name: string) => {
"stop a strategy"
const stop_strategy = (strategy_name: string) => {
return trader_service({
return service({
url: '/trader/api/v1/strategy/' + strategy_name,
method: 'PATCH',
})
@@ -100,7 +100,7 @@ const stop_strategy = (strategy_name: string) => {
"remove a strategy"
const remove_strategy = (strategy_name: string) => {
return trader_service({
return service({
url: '/trader/api/v1/strategy/' + strategy_name,
method: 'DELETE',
})
@@ -108,7 +108,7 @@ const remove_strategy = (strategy_name: string) => {
"get a strategy status"
const get_strategy_status = (strategy_name: string) => {
return trader_service({
return service({
url: '/trader/api/v1/strategy/status/' + strategy_name,
method: 'GET',
})
+146
View File
@@ -0,0 +1,146 @@
<template>
<div class="mainPage" ref="playerRef"></div>
</template>
<script setup lang="ts">
import APlayer from 'aplayer';
import 'aplayer/dist/APlayer.min.css';
import { reactive, nextTick, onBeforeUnmount, getCurrentInstance, onMounted, ref } from 'vue'
const playerRef = ref()
const currentInstance = getCurrentInstance()
const state = reactive({
instance: null
})
// APlayer歌曲信息
class Audio {
// 音频艺术家
// artist: String;
// 音频名称
// name: String;
// 音频链接
// url: String;
// 音频封面
// cover: String;
// 歌词
// lrc: String;
// constructor(artist, name, url, cover, lrc) {
// this.artist = artist;
// this.name = name;
// this.url = url;
// this.cover = cover;
// this.lrc = lrc;
// }
}
const props = defineProps({
// 开启吸底模式
fixed: {
type: Boolean,
default: false
},
// 开启迷你模式
mini: {
type: Boolean,
default: false
},
// 音频自动播放
autoplay: {
type: Boolean,
default: false
},
// 主题色
theme: {
type: String,
default: 'rgba(255,255,255,0.2)'
},
// 音频循环播放
loop: {
type: String,
default: 'all' //'all' | 'one' | 'none'
},
// 音频循环顺序
order: {
type: String,
default: 'random' //'list' | 'random'
},
// 预加载
preload: {
type: String,
default: 'auto' //'auto' | 'metadata' | 'none'
},
// 默认音量
volume: {
type: Number,
default: 0.7,
validator: (value: number) => {
return value >= 0 && value <= 1;
}
},
// 歌曲服务器(netease-网易云, tencent-qq音乐, kugou-酷狗, xiami-小米音乐, baidu-百度音乐)
songServer: {
type: String,
default: 'netease' //'netease' | 'tencent' | 'kugou' | 'xiami' | 'baidu'
},
// 播放类型(song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家)
songType: {
type: String,
default: 'playlist'
},
// 歌的id
songId: {
type: String,
default: '19723756'
},
// 互斥,阻止多个播放器同时播放,当前播放器播放时暂停其他播放器
mutex: {
type: Boolean,
default: true
},
// 传递歌词方式
lrcType: {
type: Number,
default: 3
},
// 列表是否默认折叠
listFolded: {
type: Boolean,
default: true
},
// 列表最大高度
listMaxHeight: {
type: String,
default: '100px'
},
// 存储播放器设置的 localStorage key
storageName: {
type: String,
default: 'aplayer-setting'
}
})
onMounted(() => {
let str = {
server: props.songServer,
type: props.songType,
id: props.songId
}
// 销毁
onBeforeUnmount(() => {
})
})
</script>
<style lang='scss' scoped>
.mainPage {
@include wh(100%, auto);
background: #FCFCFC;
border: 1px solid #E0E0E0;
border-radius: 4px;
}
</style>
+63 -13
View File
@@ -1,19 +1,69 @@
import { defineStore } from 'pinia'
import { Tables } from './table'
import { defineStore, acceptHMRUpdate } from 'pinia'
import { authorize } from '../api/user'
import { getToken, setToken, resetToken, setTenant, getTenant } from '../utils/auth'
import { Tenant } from '../entity/index'
interface Record {
isFolder: boolean
path: string
records: Set<Record>
}
/**
* skeleton
*
*
*/
export const tenantStore = defineStore({
id: 'cloud',
state: () => ({
cloud: new Set<Record>(),
}),
export const cloudStore = defineStore({
id: 'cloudStore',
state: () => {
return {
tableData: 1,
showDocument: false,
tableSize: 12
}
},
getters: {
},
actions: {
logout() {
this.$patch({
})
resetToken()
// we could do other stuff like redirecting the user
},
}
})
/**
* Attempt to login a user
* @param {string} user_id
* @param {string} user_password
*/
async login(tenant: any, token: string) {
try {
await authorize({
tenant_id: tenant.tenant_id, token: token
})
setToken(token)
setTenant(tenant)
} catch {
Promise.resolve("authorize error")
}
},
async reflush() {
if (getToken()) {
const tenant = <Tenant>(JSON.parse(getTenant() as string))
const token = <string>getToken()
this.$patch({
})
}
}
},
})
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(tenantStore, import.meta.hot))
}
+28
View File
@@ -1,4 +1,5 @@
import { acceptHMRUpdate, defineStore } from "pinia"
import { get_vt_symbols, get_exchanges, get_subscribe_vt_symbols } from '../api/capital'
export const strategyStore = defineStore({
id: 'strategy',
@@ -8,6 +9,33 @@ export const strategyStore = defineStore({
subscribe_vt_symbols: [],
exchanges: []
}),
actions: {
async select_exchanges() {
if (this.exchanges.length == 0) {
get_exchanges().then(res => {
this.$patch({ exchanges: res.data.exchanges })
})
}
},
async select_vt_symbols() {
if (this.vt_symbols.size == 0) {
get_vt_symbols().then(res => {
let keys = Object.keys(res.data.vt_symbols)
keys.forEach(key => {
this.vt_symbols.set(key, res.data.vt_symbols[key])
})
})
}
},
async select_subscribe_vt_symbols() {
if (this.subscribe_vt_symbols.length == 0) {
get_subscribe_vt_symbols().then(res => {
this.$patch({ subscribe_vt_symbols: res.data.vt_symbols })
})
}
}
}
})
if (import.meta.hot) {
+3 -3
View File
@@ -37,9 +37,9 @@ export const tenantStore = defineStore({
},
/**
* Attempt to login a user
* @param {string} user_id
* @param {string} user_password
* Attempt to login a tenant
* @param {object} tenant
* @param {string} token
*/
async login(tenant: any, token: string) {
+2 -58
View File
@@ -2,7 +2,7 @@ import axios from 'axios'
import router from '../router'
import { getToken, getTenant, resetToken } from '../utils/auth'
// violin-book
// violin-wiki
const service = axios.create(
{
baseURL: import.meta.env.VITE_APP_URL as string,
@@ -10,14 +10,6 @@ const service = axios.create(
}
)
// violin-trader
const trader_service = axios.create(
{
baseURL: import.meta.env.VITE_APP_URL2 as string,
timeout: 5000
}
)
service.interceptors.request.use(
config => {
if (typeof getToken() === 'string') {
@@ -47,52 +39,4 @@ service.interceptors.response.use(
}
)
trader_service.interceptors.request.use(
config => {
if (typeof getToken() === 'string') {
(config as any).headers['Authorization'] = 'Bearer' + getToken()
}
const tenant = getTenant()
if (typeof tenant === 'string') {
(config as any).headers['id'] = JSON.parse(tenant).id
}
return config
},
error => {
console.log(error)
return Promise.reject(error)
}
)
// service.interceptors.response.use(
// response => {
// if (response.headers['content-dispostion']
// && response.headers['content-dispostion'].split(';')[0] === 'attachment') {
// return response
// } else {
// return response.data
// }
// },
// async error => {
// if (error.code === 'ECONNABORTED') {
// const error = {
// message: '通信タイムアウト'
// }
// return Promise.reject(error)
// } else if (!error.response) {
// const error = {
// message: 'サーバーエラー'
// }
// return Promise.reject(error)
// } else if (error.response && error.response.status && (error.response.status === 403 || error.response.status === 403)) {
// } else {
// return Promise.reject(error.response.data)
// }
// }
// )
export { service, trader_service }
export { service }
+33 -33
View File
@@ -64,14 +64,10 @@
<el-input v-model="blogTypes[checkedBlogIndex].blogs[checkedIndex].title" @keyup.enter.native="saveTitle"
@blur="saveTitle">
</el-input>
<div style="width: 60px;">
<!-- <span v-if="!updated">已保存</span>
<span v-if="updated">更新中</span> -->
</div>
</div>
<div :style="cWholeStyle">
<md-editor theme="light" v-model="current_blog.content" @save="saveContent" :style="{ height: innerHeight }" />
<md-editor theme="light" v-model="current_blog.content" @save="saveContent" @upload-img="onUploadImg"
:style="{ height: innerHeight }" />
</div>
</div>
@@ -140,20 +136,20 @@ import {
import { copy } from '../../utils/copyutil'
import draggable from "vuedraggable"
type Blog = {
bid: string,
btId: string,
title: string,
blog_prex: string,
autosave_control: string,
content: string,
interface Blog {
bid: string
btId: string
title: string
blog_prex: string
autosave_control: string
content: string
order: number
}
type BlogType = {
btId: string,
btName: string,
blogs: Blog[],
interface BlogType {
btId: string
btName: string
blogs: Blog[]
order: number
}
const blogTypes = reactive<BlogType[]>([])
@@ -173,22 +169,7 @@ let current_blog = reactive({
content: "",
})
/*
draggable 对CSS样式没有什么要求万物皆可拖拽
:list="state.list" //需要绑定的数组
animation="300" //动画效果
@start="onStart" //拖拽开始的事件
@end="onEnd" //拖拽结束的事件
*/
const state = reactive({
modules: {
group1: [
]
},
})
// 関数定義
// FUNCTION DEFINITION
/**
* Blog一覧取得
*/
@@ -544,6 +525,25 @@ window.addEventListener('keydown', async function (event) {
}
})
const onUploadImg = async (files: FileList, callback: (urls: string[]) => void) => {
const res = await Promise.all(
Array.from(files).map((file) => {
return new Promise((resolve, reject) => {
const formData = new FormData()
formData.append('img', file)
onUploadImg(formData,)
})
})
)
callback(res.map((item: any) => item.data.data))
}
const onUploadProcess = (e: number) => {
if (e == 100) {
setTimeout(() => { }, 1000)
}
}
// サイズ調整部分
//拖拽开始的事件
const id = ref("")
+9 -6
View File
@@ -45,15 +45,22 @@
</Contextmenu>
<!-- aplayer -->
</template>
<script setup lang="ts">
import { reactive, toRaw } from 'vue';
import { defineAsyncComponent, reactive, toRaw } from 'vue';
import { getFileList } from '../../api/cloud'
import { Contextmenu, ContextmenuDivider, ContextmenuItem } from "v-contextmenu";
import { computed, getCurrentInstance, onBeforeUnmount, onMounted, ref } from "vue";
import { ElTable } from 'element-plus'
// -- IMPORT --
const currentInstance = getCurrentInstance()
// -- INTERFACE OR TYPE DEFINITION --
interface DirContext {
size: number
@@ -83,10 +90,6 @@ const isSelect = ref(true)
const selection = ref()
const isRightClick = ref(false)
// -- IMPORT DATA --
const currentInstance = getCurrentInstance()
let url = ""
// -- KEYBOARD AND MOUSE EVENT --
const rowMouseEnter = (row: any, column: any, cell: any, event: any) => {
@@ -199,7 +202,7 @@ const handleRowStyle = ({ row, rowIndex }: any) => {
}
// INITIALIZE DATA QUERY
getFileList(url).then(response => {
getFileList("").then(response => {
response.data.forEach((element: any) => {
const dirContext: DirContext = {
+3 -56
View File
@@ -1,64 +1,11 @@
<template>
<div class="about" ref="bookmarks" id="bookmarks" :style="{
width: '600px',
height: '400px'
}"></div>
width: '600px',
height: '400px'
}"></div>
</template>
<script setup lang="ts">
import * as echarts from 'echarts'
import { onMounted, ref } from 'vue';
import { get_vt_symbols, get_exchanges, get_subscribe_vt_symbols } from '../../api/capital';
import { get_strategy_load_files } from '../../api/cta_strategy'
import { h } from 'vue'
import { ElMessage } from 'element-plus'
import { strategyStore } from '../../store/strategy';
const store = strategyStore()
onMounted(() => {
})
const init = () => {
get_vt_symbols().then(res => {
let map = new Map()
let keys = Object.keys(res.data.vt_symbols)
keys.forEach(key => {
map.set(key, res.data.vt_symbols[key])
})
store.$patch({ vt_symbols: map })
}).catch(error => {
ElMessage({
message: h('p', null, [
h('i', { style: 'color: teal' }, "读取vt_symbols失败"),
]),
})
})
get_subscribe_vt_symbols().then(res => {
store.$patch({ subscribe_vt_symbols: res.data.vt_symbols })
}).catch(error => {
ElMessage({
message: h('p', null, [
h('i', { style: 'color: teal' }, "读取vt_symbols失败"),
]),
})
})
get_exchanges().then(res => {
store.$patch({ exchanges: res.data.exchanges })
}).catch(error => {
ElMessage({
message: h('p', null, [
h('i', { style: 'color: teal' }, "读取exchanges失败"),
]),
})
})
}
// init process
init()
</script>
+55 -31
View File
@@ -5,14 +5,14 @@
<el-row>
<el-col :span="4">
<el-select v-model="exchange" placeholder="select a exchange">
<el-option v-for="ex in exchanges" :value="ex" />
<el-option v-for="ex in store.exchanges" :value="ex" />
</el-select>
</el-col>
<el-col :span="1">
</el-col>
<el-col :span="4">
<el-select v-model="vt_symbol" placeholder="select a vt_symbol">
<el-option v-for="symbol in vt_symbols" :value="symbol" />
<el-option v-for="symbol in store.vt_symbols.get(exchange)" :value="symbol" />
</el-select>
</el-col>
<el-col :span="1">
@@ -43,30 +43,27 @@
</template>
<script setup lang="ts">
import { ref, h, onMounted, onUnmounted, reactive, watch } from 'vue'
import { ref, h, onMounted, onUnmounted, reactive } from 'vue'
import { ElMessage } from 'element-plus'
import { get_ticks, subscribe } from '../../api/capital'
import { strategyStore } from '../../store/strategy'
type TickData = {
symbol: string,
exchange: string,
name: string,
last_price: number,
volume: number,
open_price: number,
high_price: number,
low_price: number,
import * as echarts from 'echarts'
interface TickData {
symbol: string
exchange: string
name: string
last_price: number
volume: number
open_price: number
high_price: number
low_price: number
}
const store = strategyStore()
const vt_symbol = ref<string>()
const vt_symbols = reactive<string[]>([])
const exchange = ref<string>()
const exchanges = reactive<string[]>([])
store.exchanges.forEach(exchange => {
exchanges.push(exchange)
})
const timer = ref(0)
@@ -101,21 +98,48 @@ const on_ticks = () => {
})
}
watch(exchange, (newVal, oldVal) => {
vt_symbols.length = 0
// let sp_vt_symbol: [] = store.vt_symbols.get(vt_symbol.value)
// sp_vt_symbol.forEach((record: string) => {
// vt_symbols.push(record)
// })
})
onMounted(() => {
clearInterval(timer.value)
timer.value = window.setInterval(on_ticks, 3000);
})
onUnmounted(() => {
window.clearInterval(timer.value);
})
/**
* AUTO INVOKE FUNCTION
*/
(() => {
onMounted(() => {
clearInterval(timer.value)
timer.value = window.setInterval(on_ticks, 3000);
})
onUnmounted(() => {
window.clearInterval(timer.value)
})
store.select_subscribe_vt_symbols()
.catch(error => {
ElMessage({
message: h('p', null, [
h('i', { style: 'color: teal' }, "读取vt_symbols失败"),
]),
})
})
store.select_vt_symbols()
.catch((error) => {
ElMessage({
message: h('p', null, [
h('i', { style: 'color: teal' }, "读取vt_symbols失败"),
]),
})
})
store.select_exchanges()
.catch((error) => {
ElMessage({
message: h('p', null, [
h('i', { style: 'color: teal' }, "读取exchanges失败"),
]),
})
})
})()
</script>