add element icon, add flask client, add strategy route, api modify
This commit is contained in:
+80
-36
@@ -1,69 +1,113 @@
|
|||||||
import { service2 } from '../utils/request'
|
import { trader_service } from '../utils/request'
|
||||||
|
|
||||||
"CTA strategy"
|
"CTA strategy"
|
||||||
|
|
||||||
"strategy list"
|
"strategy file list"
|
||||||
const get_strategy_list = () => {
|
const get_strategy_files = () => {
|
||||||
return service2({
|
return trader_service({
|
||||||
url: '/auth/api/v1/trader',
|
url: '/trader/api/v1/strategy_file',
|
||||||
|
method: 'GET',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
"upload a strategy file"
|
||||||
|
const upload_strategy_file = (file: any) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("file", file)
|
||||||
|
return trader_service({
|
||||||
|
url: '/trader/api/v1/strategy_file',
|
||||||
|
method: 'POST',
|
||||||
|
data: formData,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data',
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
"load a strategy file"
|
||||||
|
const load_strategy_file = (file_name: string) => {
|
||||||
|
return trader_service({
|
||||||
|
url: '/trader/api/v1/strategy_file/' + file_name,
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
"upload a strategy"
|
"unload a strategy file"
|
||||||
const upload_strategy = () => {
|
const unload_strategy_file = (class_name: string) => {
|
||||||
return service2({
|
return trader_service({
|
||||||
url: '/auth/api/v1/trader',
|
url: '/trader/api/v1/strategy_file/' + class_name,
|
||||||
method: 'PUT',
|
method: 'PATCH',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
"load a strategy"
|
"remove a strategy file"
|
||||||
const load_strategy = (strategy_id: string) => {
|
const remove_strategy_file = (file_name: string) => {
|
||||||
return service2({
|
return trader_service({
|
||||||
url: '/auth/api/v1/trader',
|
url: '/trader/api/v1/strategy_file/' + file_name,
|
||||||
method: 'PUT',
|
method: 'DELETE',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
"unload a strategy"
|
|
||||||
const unload_strategy = (strategy_id: string) => {
|
"get strategy list"
|
||||||
return service2({
|
const get_strategies = () => {
|
||||||
url: '/auth/api/v1/trader',
|
return trader_service({
|
||||||
method: 'PUT',
|
url: '/trader/api/v1/strategies',
|
||||||
|
method: 'GET',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
"create a strategy"
|
||||||
|
const create_strategy = () => {
|
||||||
|
return trader_service({
|
||||||
|
url: '/trader/api/v1/strategy',
|
||||||
|
method: 'POST',
|
||||||
|
data: {}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
"start a strategy"
|
"start a strategy"
|
||||||
const start_strategy = (strategy_id: string) => {
|
const start_strategy = (strategy_name: string) => {
|
||||||
return service2({
|
return trader_service({
|
||||||
url: '/auth/api/v1/trader',
|
url: '/trader/api/v1/strategy/' + strategy_name,
|
||||||
method: 'PUT',
|
method: 'PUT',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
"stop a strategy"
|
"stop a strategy"
|
||||||
const stop_strategy = (strategy_id: string) => {
|
const stop_strategy = (strategy_name: string) => {
|
||||||
return service2({
|
return trader_service({
|
||||||
url: '/auth/api/v1/trader',
|
url: '/trader/api/v1/strategy/' + strategy_name,
|
||||||
method: 'PUT',
|
method: 'PATCH',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
"remove a strategy"
|
"remove a strategy"
|
||||||
const remove_strategy = (strategy_id: string) => {
|
const remove_strategy = (strategy_name: string) => {
|
||||||
return service2({
|
return trader_service({
|
||||||
url: '/auth/api/v1/trader',
|
url: '/trader/api/v1/strategy/' + strategy_name,
|
||||||
method: 'PUT',
|
method: 'DELETE',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
"get a strategy status"
|
||||||
|
const get_strategy_status = (strategy_name: string) => {
|
||||||
|
return trader_service({
|
||||||
|
url: '/trader/api/v1/strategy/status/' + strategy_name,
|
||||||
|
method: 'GET',
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
get_strategy_list,
|
get_strategy_files,
|
||||||
upload_strategy,
|
upload_strategy_file,
|
||||||
load_strategy,
|
load_strategy_file,
|
||||||
unload_strategy,
|
unload_strategy_file,
|
||||||
|
remove_strategy_file,
|
||||||
|
get_strategies,
|
||||||
|
create_strategy,
|
||||||
start_strategy,
|
start_strategy,
|
||||||
stop_strategy,
|
stop_strategy,
|
||||||
remove_strategy
|
remove_strategy,
|
||||||
|
get_strategy_status
|
||||||
}
|
}
|
||||||
@@ -7,8 +7,16 @@ import router from './router'
|
|||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
const store = createPinia()
|
const store = createPinia()
|
||||||
|
|
||||||
|
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
|
||||||
|
|
||||||
let app = createApp(App)
|
let app = createApp(App)
|
||||||
|
|
||||||
|
|
||||||
|
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
|
||||||
|
app.component(key, component)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
app.use(router)
|
app.use(router)
|
||||||
app.use(ElementPlus)
|
app.use(ElementPlus)
|
||||||
app.use(store)
|
app.use(store)
|
||||||
|
|||||||
@@ -68,6 +68,20 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
name: 'trader'
|
name: 'trader'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/strategy',
|
||||||
|
component: () => import('../view/trader/cta_strategy_file.vue'),
|
||||||
|
meta: {
|
||||||
|
name: '策略文件管理'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/strategy_instance',
|
||||||
|
component: () => import('../view/trader/cta_strategy.vue'),
|
||||||
|
meta: {
|
||||||
|
name: '策略管理'
|
||||||
|
}
|
||||||
|
},
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const service = axios.create(
|
|||||||
)
|
)
|
||||||
|
|
||||||
// violin-trader
|
// violin-trader
|
||||||
const service2 = axios.create(
|
const trader_service = axios.create(
|
||||||
{
|
{
|
||||||
baseURL: import.meta.env.VITE_APP_URL2 as string,
|
baseURL: import.meta.env.VITE_APP_URL2 as string,
|
||||||
timeout: 5000
|
timeout: 5000
|
||||||
@@ -35,7 +35,7 @@ service.interceptors.request.use(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
service2.interceptors.request.use(
|
trader_service.interceptors.request.use(
|
||||||
config => {
|
config => {
|
||||||
if (typeof getToken() === 'string') {
|
if (typeof getToken() === 'string') {
|
||||||
(config as any).headers['Authorization'] = 'Bearer' + getToken()
|
(config as any).headers['Authorization'] = 'Bearer' + getToken()
|
||||||
@@ -82,4 +82,4 @@ service2.interceptors.request.use(
|
|||||||
// }
|
// }
|
||||||
// )
|
// )
|
||||||
|
|
||||||
export { service, service2 }
|
export { service, trader_service }
|
||||||
@@ -11,132 +11,141 @@
|
|||||||
<el-button type="primary" @click="doSearch">检索</el-button>
|
<el-button type="primary" @click="doSearch">检索</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<div class="tag_list">
|
</el-form> -->
|
||||||
<el-tag class="ml-2 click-icon" :type="item.clicked ? 'danger' : 'info'" v-for="(item) in bookmark_types"
|
|
||||||
@click="handleTags(item)">{{ item.bk_type_name }}</el-tag>
|
|
||||||
<el-button type="primary" @click="handleAddType" v-show="Tenant.account">增加</el-button>
|
|
||||||
<el-button type="primary" @click="handleManageType" v-show="Tenant.account">自定义</el-button>
|
|
||||||
</div>
|
|
||||||
</el-form>
|
|
||||||
<div class="create_dialog">
|
<div class="create_dialog">
|
||||||
<el-button type="primary" @click="handleInsert" v-show="Tenant.account">新建</el-button>
|
<el-button type="primary" @click="on_create">新建</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-table ref="multipleTableRef" :data="strategy_list" @selection-change="handleSelectionChange" style="width: 100%">
|
<el-table ref="multipleTableRef" :data="strategy_list" style="width: 100%">
|
||||||
<el-table-column type="selection" width="55" />
|
<el-table-column type="selection" width="55" />
|
||||||
<el-table-column type="index" label="index" width="80" />
|
<el-table-column type="index" label="index" width="80" />
|
||||||
<el-table-column prop="bk_type_name" label="分类" width="100" />
|
<el-table-column prop="strategy_name" label="策略名" width="200" />
|
||||||
<el-table-column prop="comment" label="名称" width="180" />
|
<el-table-column prop="class_name" label="策略类名" width="200" />
|
||||||
<el-table-column prop="facvion" label="图标" width="60" />
|
<el-table-column prop="vt_symbol" label="合约" width="100" />
|
||||||
<el-table-column class="click-icon" prop="url" label="url">
|
<el-table-column prop="status" label="状态" width="60">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<span style="cursor: pointer" @click="openUrl(scope.row.url)">{{ scope.row.url }}</span>
|
<el-icon v-if="scope.row.status == 0" :size="20">
|
||||||
|
<Cloudy />
|
||||||
|
</el-icon>
|
||||||
|
<el-icon v-if="scope.row.status == 1" :size="20" color="yellow">
|
||||||
|
<Sunrise />
|
||||||
|
</el-icon>
|
||||||
|
<el-icon v-if="scope.row.status == 2" :size="20" color="gold">
|
||||||
|
<Sunny />
|
||||||
|
</el-icon>
|
||||||
|
<el-icon v-if="scope.row.status == 3" :size="20" color="blue">
|
||||||
|
<Moon />
|
||||||
|
</el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作">
|
<el-table-column prop="url" label="开始" width="60">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-icon :size="20" @click="copyNumber(scope.row)" class="click-icon">
|
<span v-if="scope.row.status == 0" style="cursor: pointer" @click="on_remove(scope.row)">
|
||||||
<CopyDocument />
|
<el-icon :size="20" @click="on_start(scope.row)">
|
||||||
</el-icon>
|
<VideoPlay />
|
||||||
<el-button class="click-icon" size="small" @click="handleEdit(scope.$index, scope.row)"
|
</el-icon>
|
||||||
v-show="Tenant.account">编辑
|
</span>
|
||||||
</el-button>
|
</template>
|
||||||
<el-button size="small" type="danger" @click="handleDelete(scope.$index, scope.row)" v-show="Tenant.account">
|
</el-table-column>
|
||||||
删除
|
<el-table-column prop="url" label="停止" width="60">
|
||||||
</el-button>
|
<template #default="scope">
|
||||||
|
<span v-if="scope.row.status == 2" style="cursor: pointer" @click="on_remove(scope.row)">
|
||||||
|
<el-icon :size="20" @click="on_stop(scope.row)">
|
||||||
|
<VideoPause />
|
||||||
|
</el-icon>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="url" label="删除" width="60">
|
||||||
|
<template #default="scope">
|
||||||
|
<span v-if="scope.row.status == 0" style="cursor: pointer" @click="on_remove(scope.row)">
|
||||||
|
<el-icon :size="20" @click="on_remove(scope.row)">
|
||||||
|
<Delete />
|
||||||
|
</el-icon>
|
||||||
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
<div style="margin-top: 20px">
|
|
||||||
<el-button @click="toggleSelection([tableData[1], tableData[2]])">反选</el-button>
|
|
||||||
<el-button @click="toggleSelection()">清除</el-button>
|
|
||||||
</div> -->
|
|
||||||
|
|
||||||
<!-- <el-dialog v-model="dialogFormVisible" title="添加书签">
|
|
||||||
<bookmark_dialog :dialog_form="currentDialogData" :operate_code="operate" :types="bookmark_types"
|
|
||||||
@on-concel="closeDialog" @on-submit="doSubmit"></bookmark_dialog>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog v-model="dialogVisible">
|
|
||||||
<delete_dialog :delete_id="currentDialogData.bk_id" @on-submit="doDelete"></delete_dialog>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<el-dialog v-model="createTypeDialogVisible">
|
|
||||||
<createType_dialog @on-update="doUpdate"></createType_dialog>
|
|
||||||
</el-dialog> -->
|
|
||||||
|
|
||||||
<!-- <el-dialog v-model="typeDialogVisible">
|
|
||||||
<bookmarkType_dialog :delete_id="currentDialogData.bk_id" @on-submit="doDelete"></bookmarkType_dialog>
|
|
||||||
</el-dialog> -->
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import {
|
import {
|
||||||
get_strategy_list,
|
get_strategies,
|
||||||
upload_strategy,
|
create_strategy,
|
||||||
load_strategy,
|
|
||||||
unload_strategy,
|
|
||||||
start_strategy,
|
start_strategy,
|
||||||
stop_strategy,
|
stop_strategy,
|
||||||
remove_strategy
|
get_strategy_status,
|
||||||
} from '../../api/cta_strategy'
|
} from '../../api/cta_strategy'
|
||||||
|
import { genFileId } from 'element-plus'
|
||||||
|
import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus'
|
||||||
|
import { h } from 'vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
const upload = ref<UploadInstance>()
|
||||||
|
const handleExceed: UploadProps['onExceed'] = (files) => {
|
||||||
|
upload.value!.clearFiles()
|
||||||
|
const file = files[0] as UploadRawFile
|
||||||
|
file.uid = genFileId()
|
||||||
|
upload.value!.handleStart(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
type Strategy = {
|
type Strategy = {
|
||||||
strategy_id: string,
|
|
||||||
strategy_name: string,
|
strategy_name: string,
|
||||||
|
class_name: string,
|
||||||
|
vt_symbol: string,
|
||||||
|
setting: Object,
|
||||||
|
status: number,
|
||||||
}
|
}
|
||||||
|
|
||||||
const strategy_list = reactive<Strategy[]>([])
|
const strategy_list = reactive<Strategy[]>([])
|
||||||
|
|
||||||
const on_list = () => {
|
const on_list = () => {
|
||||||
get_strategy_list().then(res => {
|
get_strategies().then(res => {
|
||||||
|
strategy_list.length = 0
|
||||||
res.data.forEach((item: Strategy, index: number) => {
|
res.data.forEach((item: Strategy, index: number) => {
|
||||||
strategy_list.push(item)
|
strategy_list.push(item)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const on_upload = () => {
|
const on_create = () => {
|
||||||
upload_strategy().then(res => {
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const on_start = (row: any) => {
|
||||||
|
start_strategy(row.strategy_name).then(res => {
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const on_load = (strategy_id: string) => {
|
const on_stop = (row: any) => {
|
||||||
load_strategy(strategy_id).then(res => {
|
stop_strategy(row.strategy_name).then(res => {
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const on_unload = (strategy_id: string) => {
|
const on_remove = (row: any) => {
|
||||||
unload_strategy(strategy_id).then(res => {
|
stop_strategy(row.strategy_name).then(res => {
|
||||||
|
on_list()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const on_start = (strategy_id: string) => {
|
const on_status = (row: any) => {
|
||||||
start_strategy(strategy_id).then(res => {
|
get_strategy_status(row.strategy_name).then(res => {
|
||||||
|
row.status = res.data.status
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const on_stop = (strategy_id: string) => {
|
// init process
|
||||||
stop_strategy(strategy_id).then(res => {
|
on_list()
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const on_remove = (strategy_id: string) => {
|
|
||||||
remove_strategy(strategy_id).then(res => {
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
<template>
|
||||||
|
<div class="bookmark">
|
||||||
|
<el-upload ref="upload" class="upload-demo" action="http://localhost:5000/trader/api/v1/strategy_file" :limit="1"
|
||||||
|
:on-exceed="handleExceed" :auto-upload="false">
|
||||||
|
<template #trigger>
|
||||||
|
<el-button type="primary">select file</el-button>
|
||||||
|
</template>
|
||||||
|
<el-button class="ml-3" type="success" @click="on_upload">
|
||||||
|
upload to server
|
||||||
|
</el-button>
|
||||||
|
<template #tip>
|
||||||
|
<div class="el-upload__tip text-red">
|
||||||
|
limit 1 file, new file will cover the old file
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
|
||||||
|
<el-table ref="multipleTableRef" :data="strategy_file_list" style="width: 100%">
|
||||||
|
<el-table-column type="selection" width="55" />
|
||||||
|
<el-table-column type="index" label="index" width="80" />
|
||||||
|
<el-table-column prop="file_name" label="策略文件名" width="200" />
|
||||||
|
<el-table-column prop="class_name" label="策略类名" width="200" />
|
||||||
|
<el-table-column prop="status" label="状态" width="180" />
|
||||||
|
<el-table-column prop="facvion" label="图标" width="60" />
|
||||||
|
<el-table-column class="click-icon" prop="url" label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<span v-if="scope.row.status == 0" style="cursor: pointer" @click="on_load(scope.row)">{{ "加载图标" }}</span>
|
||||||
|
<span v-if="scope.row.status == 0" style="cursor: pointer" @click="on_remove(scope.row)">{{ "删除" }}</span>
|
||||||
|
<span v-if="scope.row.status == 2" style="cursor: pointer">{{ "加载中图标" }}</span>
|
||||||
|
<span v-if="scope.row.status == 1" style="cursor: pointer" @click="on_unload(scope.row)">{{
|
||||||
|
"卸载图标" }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
import {
|
||||||
|
get_strategy_files,
|
||||||
|
load_strategy_file,
|
||||||
|
unload_strategy_file,
|
||||||
|
remove_strategy_file
|
||||||
|
} from '../../api/cta_strategy'
|
||||||
|
import { genFileId } from 'element-plus'
|
||||||
|
import type { UploadInstance, UploadProps, UploadRawFile } from 'element-plus'
|
||||||
|
import { h } from 'vue'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
const upload = ref<UploadInstance>()
|
||||||
|
const handleExceed: UploadProps['onExceed'] = (files) => {
|
||||||
|
upload.value!.clearFiles()
|
||||||
|
const file = files[0] as UploadRawFile
|
||||||
|
file.uid = genFileId()
|
||||||
|
upload.value!.handleStart(file)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type StrategyFile = {
|
||||||
|
file_name: string,
|
||||||
|
class_name: string,
|
||||||
|
status: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const strategy_file_list = reactive<StrategyFile[]>([])
|
||||||
|
|
||||||
|
const on_list = () => {
|
||||||
|
get_strategy_files().then(res => {
|
||||||
|
strategy_file_list.length = 0
|
||||||
|
res.data.forEach((item: StrategyFile, index: number) => {
|
||||||
|
strategy_file_list.push(item)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const on_upload = () => {
|
||||||
|
|
||||||
|
upload.value!.submit()
|
||||||
|
on_list()
|
||||||
|
}
|
||||||
|
|
||||||
|
const on_load = (row: any) => {
|
||||||
|
row.status = 2
|
||||||
|
load_strategy_file(row.file_name).then(res => {
|
||||||
|
if (res.status == 200) {
|
||||||
|
row.status = 1
|
||||||
|
}
|
||||||
|
if (res.status == 500) {
|
||||||
|
row.status = 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const on_unload = (row: any) => {
|
||||||
|
unload_strategy_file(row.class_name).then(res => {
|
||||||
|
if (res.status == 200) {
|
||||||
|
row.status = 0
|
||||||
|
}
|
||||||
|
if (res.status == 500) {
|
||||||
|
row.status = 1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const on_remove = (row: any) => {
|
||||||
|
remove_strategy_file(row.file_name).then(res => {
|
||||||
|
on_list()
|
||||||
|
}).catch(error => {
|
||||||
|
ElMessage({
|
||||||
|
message: h('p', null, [
|
||||||
|
h('i', { style: 'color: teal' }, error),
|
||||||
|
]),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// init process
|
||||||
|
on_list()
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user