|
|
@@ -0,0 +1,507 @@
|
|
|
+<template>
|
|
|
+ <lay-card class="custom-card">
|
|
|
+ <template v-slot:title>
|
|
|
+ <span class="card-title">机器人管理</span>
|
|
|
+ </template>
|
|
|
+ <template v-slot:extra>
|
|
|
+ <lay-button class="card-button" v-if="apiList?.includes('/robot/transfers')" @click="handleTransfersRobot(selectedKeys)">移交机器人</lay-button>
|
|
|
+ <lay-button class="card-button" v-if="apiList?.includes('/robot/copy')" @click="handleCopyRobot(selectedKeys)">复制机器人</lay-button>
|
|
|
+ <lay-button class="card-button" v-if="apiList?.includes('/robot/save')" @click="handleUpdate(0)">添加</lay-button>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ <template v-slot:body>
|
|
|
+ <div class="custom-form-layout">
|
|
|
+ <lay-form class="form-wp" :model="pageParams" mode="inline" size="sm">
|
|
|
+ <lay-form-item label="关键字" prop="textContent">
|
|
|
+ <lay-input v-model="pageParams.textContent" />
|
|
|
+ </lay-form-item>
|
|
|
+ <lay-form-item label="币对" prop="symbol">
|
|
|
+ <lay-input v-model="pageParams.symbol" />
|
|
|
+ </lay-form-item>
|
|
|
+ <lay-form-item label="状态" prop="robotState">
|
|
|
+ <lay-select v-model="pageParams.robotState" :show-search="true" allowClear>
|
|
|
+ <lay-select-option v-for="(value, key) of ROBOT_STATUS" :value="key" :label="value" />
|
|
|
+ </lay-select>
|
|
|
+ </lay-form-item>
|
|
|
+ <lay-form-item label="盘口" prop="exchange">
|
|
|
+ <lay-select v-model="pageParams.exchange" :show-search="true" allowClear>
|
|
|
+ <lay-select-option v-for="item in exchangeList" :value="item.code" :label="item.code" />
|
|
|
+ </lay-select>
|
|
|
+ </lay-form-item>
|
|
|
+ <lay-form-item label="所属人" prop="userName">
|
|
|
+ <lay-select v-model="pageParams.userName" :show-search="true" allowClear>
|
|
|
+ <lay-select-option v-for="item in userList" :value="item.value" :label="item.value" />
|
|
|
+ </lay-select>
|
|
|
+ </lay-form-item>
|
|
|
+ <div class="form-button-wp">
|
|
|
+ <lay-button @click="getPageInfo(true)">搜索</lay-button>
|
|
|
+ </div>
|
|
|
+ </lay-form>
|
|
|
+ </div>
|
|
|
+ <div class="custom-operator-wp padding-bottom-10">
|
|
|
+ <div class="custom-group collect-wp" v-html="collectInfo" />
|
|
|
+ <div class="custom-group">
|
|
|
+ <lay-space>
|
|
|
+ <lay-button v-if="apiList?.includes('/robot/submitStatus')" :border="'green'" size="xs" @click="handleStatus(selectedKeys, 'RUN')">开机</lay-button>
|
|
|
+ <lay-button v-if="apiList?.includes('/robot/submitStatus')" :border="'green'" size="xs" @click="handleStatus(selectedKeys, 'RESTART')">重启</lay-button>
|
|
|
+ <lay-button v-if="apiList?.includes('/robot/submitStatus')" :border="'red'" size="xs" @click="handleStatus(selectedKeys, 'STOP')">停机</lay-button>
|
|
|
+ <lay-button v-if="apiList?.includes('/robot/resetCapital')" :border="'green'" size="xs" @click="handleResetCapital(selectedKeys)">复位本金</lay-button>
|
|
|
+ </lay-space>
|
|
|
+ </div>
|
|
|
+ <div class="custom-group">
|
|
|
+ <lay-space>
|
|
|
+ <lay-button v-if="apiList?.includes('/robot/update')" :border="'green'" size="xs" @click="handleBatchUpdate(selectedKeys)">批量设置</lay-button>
|
|
|
+ <lay-button v-if="apiList?.includes('/robot/update')" :border="'green'" size="xs" @click="handleCopyParams(selectedKeys)">复制参数</lay-button>
|
|
|
+ </lay-space>
|
|
|
+ </div>
|
|
|
+ <div class="custom-group">
|
|
|
+ <lay-space>
|
|
|
+ <lay-tooltip position="bottom" content="把所有机器人杠杆调整成0.1,这样停机可以防止遗留仓位。">
|
|
|
+ <lay-button :border="'red'" size="xs" @click="handleSurviveRobot()"> 保命 </lay-button>
|
|
|
+ </lay-tooltip>
|
|
|
+ <lay-tooltip position="bottom" content="还原杠杆,可能会有的机器人没有开机成功,要检查下。">
|
|
|
+ <lay-button :border="'red'" size="xs" @click="handleRestoreRobot()"> 还原 </lay-button>
|
|
|
+ </lay-tooltip>
|
|
|
+ </lay-space>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <lay-table :page="tablePage" :columns="columns" resize id="id" :data-source="dataSource" v-model:selected-keys="selectedKeys" :loading="pageConfig.loading" @change="handleCurrentChange">
|
|
|
+ <template v-slot:name="{ row }">
|
|
|
+ <span v-if="apiList?.includes('/robot/findById')" class="normal-color" @click="jumpDetail(row)">{{ row.name }}</span>
|
|
|
+ <span v-else>{{ row.name }}</span>
|
|
|
+ </template>
|
|
|
+ <template v-slot:account="{ row }">
|
|
|
+ <span>{{ JSON.parse(row.configsJson || "{}").account }}</span>
|
|
|
+ </template>
|
|
|
+ <template v-slot:pair="{ row }">
|
|
|
+ <span>{{ JSON.parse(row.configsJson || "{}").pair }}</span>
|
|
|
+ </template>
|
|
|
+ <template v-slot:earningRate="{ row }">
|
|
|
+ <span :class="{ 'primary-color': row.earningRate > 0, 'danger-color': row.earningRate < 0 }">{{ row.earningRate || 0 }}%</span>
|
|
|
+ </template>
|
|
|
+ <template v-slot:status="{ row }">
|
|
|
+ <lay-space v-if="row.status == 'RUNNING'">
|
|
|
+ <lay-badge type="dot" theme="blue" ripple />
|
|
|
+ <span>{{ ROBOT_STATUS[row.status] }}</span>
|
|
|
+ </lay-space>
|
|
|
+ <lay-space v-else-if="row.status == 'ERROR'">
|
|
|
+ <lay-badge type="dot" />
|
|
|
+ <span>{{ ROBOT_STATUS[row.status] }}</span>
|
|
|
+ </lay-space>
|
|
|
+ <lay-space v-else>
|
|
|
+ <lay-badge type="dot" theme="orange" :ripple="row.status == 'STOPPED' ? false : true" />
|
|
|
+ <span>{{ ROBOT_STATUS[row.status] }}</span>
|
|
|
+ </lay-space>
|
|
|
+ </template>
|
|
|
+ <template v-slot:ip="{ row }">
|
|
|
+ {{ `${row.serverIp}:${row.callPort}` }}
|
|
|
+ </template>
|
|
|
+ <template v-slot:configs="{ row }">
|
|
|
+ <lay-tooltip :content="row.configs || ''">
|
|
|
+ <div class="ellipsis-2" @click="handleUpdate(row)">
|
|
|
+ <span class="danger-color" v-if="apiList?.includes('/robot/setAuto') && row.isAuto == 1">[自动调参]</span>{{ `${row.configs || ""}` }}
|
|
|
+ </div>
|
|
|
+ </lay-tooltip>
|
|
|
+ </template>
|
|
|
+ <template v-slot:lastReportTime="{ row }">
|
|
|
+ <span :class="{ 'danger-color': timeConverts(row.lastReportTime).indexOf('秒') == -1 }">{{ row.lastReportTime ? timeConverts(row.lastReportTime) : "未通讯" }}</span>
|
|
|
+ </template>
|
|
|
+ <template v-slot:posNum="{ row }">
|
|
|
+ <span :class="{ 'danger-color': row.posNum > 0 }">{{ row.posNum > 0 ? row.posNum : 0 }}</span>
|
|
|
+ </template>
|
|
|
+ <template v-slot:updateTime="{ row }">
|
|
|
+ <span>{{ timeConverts(row.updateTime) }}</span>
|
|
|
+ </template>
|
|
|
+ <template v-slot:operator="{ row }">
|
|
|
+ <lay-space>
|
|
|
+ <TableButton v-if="apiList?.includes('/robot/submitStatus') && ['STOPPED', 'STOP_PENDING', 'ERROR'].includes(row.status)" text="开机" @click="handleStatus([row.id], 'RUN')" />
|
|
|
+ <TableButton
|
|
|
+ v-if="apiList?.includes('/robot/submitStatus') && ['RUNNING', 'START_PENDING', 'RESTART_PENDING'].includes(row.status)"
|
|
|
+ text="停机"
|
|
|
+ @click="handleStatus([row.id], 'STOP')"
|
|
|
+ />
|
|
|
+ <TableButton v-if="apiList?.includes('/robot/update')" text="编辑" @click="handleUpdate(row)" />
|
|
|
+ <TableButton
|
|
|
+ v-if="apiList?.includes('/robot/submitStatus') && ['RUNNING', 'START_PENDING', 'RESTART_PENDING'].includes(row.status)"
|
|
|
+ text="重启"
|
|
|
+ @click="handleStatus([row.id], 'RESTART')"
|
|
|
+ />
|
|
|
+ <TableButton v-if="apiList?.includes('/robot/delete') && ['STOPPED', 'STOP_PENDING', 'ERROR'].includes(row.status)" text="删除" @click="handleDelete(row)" />
|
|
|
+
|
|
|
+ </lay-space>
|
|
|
+ </template>
|
|
|
+ </lay-table>
|
|
|
+ </div>
|
|
|
+ <div class="custom-operator-wp padding-top-10">
|
|
|
+ <div class="custom-group collect-wp" v-html="collectInfo" />
|
|
|
+ <div class="custom-group">
|
|
|
+ <lay-space>
|
|
|
+ <lay-button v-if="apiList?.includes('/robot/submitStatus')" :border="'green'" size="xs" @click="handleStatus(selectedKeys, 'RUN')">开机</lay-button>
|
|
|
+ <lay-button v-if="apiList?.includes('/robot/submitStatus')" :border="'green'" size="xs" @click="handleStatus(selectedKeys, 'RESTART')">重启</lay-button>
|
|
|
+ <lay-button v-if="apiList?.includes('/robot/submitStatus')" :border="'red'" size="xs" @click="handleStatus(selectedKeys, 'STOP')">停机</lay-button>
|
|
|
+ <lay-button v-if="apiList?.includes('/robot/resetCapital')" :border="'green'" size="xs" @click="handleResetCapital(selectedKeys)">复位本金</lay-button>
|
|
|
+ </lay-space>
|
|
|
+ </div>
|
|
|
+ <div class="custom-group">
|
|
|
+ <lay-space>
|
|
|
+ <lay-button v-if="apiList?.includes('/robot/update')" :border="'green'" size="xs" @click="handleBatchUpdate(selectedKeys)">批量设置</lay-button>
|
|
|
+ <lay-button v-if="apiList?.includes('/robot/update')" :border="'green'" size="xs" @click="handleCopyParams(selectedKeys)">复制参数</lay-button>
|
|
|
+ </lay-space>
|
|
|
+ </div>
|
|
|
+ <div class="custom-group">
|
|
|
+ <lay-space>
|
|
|
+ <lay-tooltip position="bottom" content="把所有机器人杠杆调整成0.1,这样停机可以防止遗留仓位。">
|
|
|
+ <lay-button :border="'red'" size="xs" @click="handleSurviveRobot()"> 保命 </lay-button>
|
|
|
+ </lay-tooltip>
|
|
|
+ <lay-tooltip position="bottom" content="还原杠杆,可能会有的机器人没有开机成功,要检查下。">
|
|
|
+ <lay-button :border="'red'" size="xs" @click="handleRestoreRobot()"> 还原 </lay-button>
|
|
|
+ </lay-tooltip>
|
|
|
+ </lay-space>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </lay-card>
|
|
|
+ <BatchUpdate ref="batchUpdateRef" />
|
|
|
+ <Update ref="updateRef" />
|
|
|
+ <Copy ref="copyRef" />
|
|
|
+ <Transfers ref="transfersRef" />
|
|
|
+ <Automate ref="automateRef" />
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" setup name="BotManage">
|
|
|
+import { ref, reactive, getCurrentInstance, onBeforeUnmount } from "vue";
|
|
|
+import BatchUpdate from "./components/BatchUpdate.vue";
|
|
|
+import Update from "./components/Update.vue";
|
|
|
+import Transfers from "./components/Transfers.vue";
|
|
|
+import Copy from "./components/Copy.vue";
|
|
|
+import Automate from "./components/Automate.vue";
|
|
|
+import TableButton from "@/components/TableButton.vue";
|
|
|
+import { timeConverts } from "@/utils/index";
|
|
|
+import { get_as_robot_list, delete_robot, set_robot_status, set_robot_reset_capital, update_robot_batch, survive_robot, restore_robot, get_user_list_all, get_exchange_list_all } from "@/api";
|
|
|
+
|
|
|
+const ROBOT_STATUS: any = reactive({
|
|
|
+ STOPPED: "已停止",
|
|
|
+ STOP_PENDING: "停止中",
|
|
|
+ RUNNING: "运行中",
|
|
|
+ START_PENDING: "启动中",
|
|
|
+ RESTART_PENDING: "重启中",
|
|
|
+ DOWNLOADING: "下载中",
|
|
|
+ ERROR: "错误",
|
|
|
+});
|
|
|
+
|
|
|
+const { proxy }: any = getCurrentInstance();
|
|
|
+const batchUpdateRef = ref();
|
|
|
+const updateRef = ref();
|
|
|
+const copyRef = ref();
|
|
|
+const transfersRef = ref();
|
|
|
+const automateRef = ref();
|
|
|
+
|
|
|
+const apiList = ref(window.sessionStorage.getItem("_4L_API_LIST"));
|
|
|
+
|
|
|
+interface PageConfig {
|
|
|
+ loading: boolean;
|
|
|
+}
|
|
|
+
|
|
|
+let pageConfig: PageConfig = reactive({
|
|
|
+ loading: false,
|
|
|
+});
|
|
|
+
|
|
|
+interface FormItem {
|
|
|
+ pageNum?: Number;
|
|
|
+ pageSize?: Number;
|
|
|
+ textContent?: String;
|
|
|
+ symbol?: String;
|
|
|
+ robotState?: String;
|
|
|
+ exchange?: String;
|
|
|
+ userName?: String;
|
|
|
+}
|
|
|
+const pageParams: FormItem = reactive({ pageNum: 1, pageSize: 50 });
|
|
|
+
|
|
|
+interface TablePage {
|
|
|
+ current: number;
|
|
|
+ limit: number;
|
|
|
+ total: number;
|
|
|
+}
|
|
|
+const tablePage: TablePage = reactive({ current: 1, limit: 50, total: 0, limits: [20, 50, 100, 200, 500] });
|
|
|
+const columns = ref([
|
|
|
+ { title: "选项", width: "44px", type: "checkbox" },
|
|
|
+ { title: "ID", width: "50px", key: "id" },
|
|
|
+ { title: "名称", width: "90px", key: "name", customSlot: "name", ellipsisTooltip: true },
|
|
|
+ { title: "账户", width: "90px", key: "account", customSlot: "account", ellipsisTooltip: true },
|
|
|
+ { title: "币对", width: "90px", key: "pair", customSlot: "pair", align: "center", ellipsisTooltip: true },
|
|
|
+ { title: "起始", width: "90px", key: "startAmount", align: "center" },
|
|
|
+ { title: "收益", width: "70px", key: "earningRate", customSlot: "earningRate", align: "center" },
|
|
|
+ { title: "状态", width: "90px", key: "status", customSlot: "status", align: "center" },
|
|
|
+ { title: "参数", key: "configs", customSlot: "configs" },
|
|
|
+ { title: "IP:编号", width: "120px", key: "ip", customSlot: "ip", ellipsisTooltip: true },
|
|
|
+ { title: "通讯", width: "80px", key: "lastReportTime", customSlot: "lastReportTime", align: "center" },
|
|
|
+ { title: "持仓信息", width: "80px", key: "posNum", customSlot: "posNum", align: "center", ellipsisTooltip: true },
|
|
|
+ { title: "修改", width: "90px", key: "updateTime", customSlot: "updateTime", align: "center" },
|
|
|
+ { title: "所属人", width: "80px", key: "userName", align: "center", ellipsisTooltip: true },
|
|
|
+ {
|
|
|
+ title: "操作",
|
|
|
+ width: "160px",
|
|
|
+ customSlot: "operator",
|
|
|
+ key: "operator",
|
|
|
+ ignoreExport: true,
|
|
|
+ },
|
|
|
+]);
|
|
|
+
|
|
|
+let dataSource = ref([]);
|
|
|
+let selectedKeys = ref([]);
|
|
|
+let collectInfo = ref(`[0/0] 利润:<span class="primary-color">0(0%)</span> 初始:<span class="primary-color">0</span> 现有:<span class="primary-color">0</span>`);
|
|
|
+let userList = ref();
|
|
|
+let exchangeList = ref();
|
|
|
+
|
|
|
+// 请求机器人列表
|
|
|
+const getPageInfo = (isSearch?: boolean) => {
|
|
|
+ if (isSearch) {
|
|
|
+ pageParams.pageNum = 1;
|
|
|
+ selectedKeys.value = [];
|
|
|
+ }
|
|
|
+ pageConfig.loading = true;
|
|
|
+ get_as_robot_list(pageParams, (data: any) => {
|
|
|
+ pageConfig.loading = false;
|
|
|
+ if (data.code == 200) {
|
|
|
+ dataSource.value = data.data.list;
|
|
|
+ tablePage.total = data.data.total;
|
|
|
+ handleShowInfo(data.data);
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+getPageInfo();
|
|
|
+
|
|
|
+// 获取用户列表
|
|
|
+const get_user_list = () => {
|
|
|
+ const params = {};
|
|
|
+ get_user_list_all(params, (data: any) => {
|
|
|
+ userList.value = data.data;
|
|
|
+ });
|
|
|
+};
|
|
|
+get_user_list();
|
|
|
+
|
|
|
+// 获取交易所列表
|
|
|
+const get_exchange_list = () => {
|
|
|
+ const params = {};
|
|
|
+ get_exchange_list_all(params, (data: any) => {
|
|
|
+ exchangeList.value = data.data;
|
|
|
+ });
|
|
|
+};
|
|
|
+get_exchange_list();
|
|
|
+
|
|
|
+let refreshInterval = setInterval(() => {
|
|
|
+ get_as_robot_list(pageParams, (data: any) => {
|
|
|
+ if (data.code == 200) {
|
|
|
+ dataSource.value = data.data.list;
|
|
|
+ tablePage.total = data.data.total;
|
|
|
+ handleShowInfo(data.data);
|
|
|
+ }
|
|
|
+ });
|
|
|
+}, 2000);
|
|
|
+
|
|
|
+const jumpDetail = (info: any) => {
|
|
|
+ window.open(`/bot/as/detail/${info.id}`);
|
|
|
+};
|
|
|
+
|
|
|
+const handleShowInfo = (info: any) => {
|
|
|
+ document.title = `[${info.runNum || 0}/${info.total || 0}] 利润:${info.income || 0}(${info.incomeRate || 0}%)
|
|
|
+ 初始:${info.startAmount || 0} 现有:${info.nowAmount || 0}`;
|
|
|
+ collectInfo.value = `[${info.runNum || 0}/${info.total || 0}] 利润:<span class="${info.income >= 0 ? "primary-color" : "danger-color"}">${info.income || 0}(${info.incomeRate || 0}%)</span>
|
|
|
+ 初始:<span class="primary-color">${info.startAmount || 0}</span> 现有:<span class="primary-color">${info.nowAmount || 0}</span>`;
|
|
|
+};
|
|
|
+
|
|
|
+const handleTransfersRobot = async (ids: any) => {
|
|
|
+ if (ids.length == 0) return proxy.$message(`请先选择要移交机器!`, 7);
|
|
|
+ const result = await transfersRef.value.show(ids);
|
|
|
+ if (result) getPageInfo(true);
|
|
|
+};
|
|
|
+
|
|
|
+const handleCopyRobot = async (ids: any) => {
|
|
|
+ if (ids.length > 1 || ids.length == 0) return proxy.$message(`请勾选1个要复制的机器!`, 7);
|
|
|
+ const result = await copyRef.value.show(ids[0]);
|
|
|
+ if (result) {
|
|
|
+ selectedKeys.value = [];
|
|
|
+ getPageInfo();
|
|
|
+ }
|
|
|
+};
|
|
|
+// 批量修改
|
|
|
+const handleBatchUpdate = async (ids: any) => {
|
|
|
+ if (ids.length == 0) return proxy.$message(`请先选择要设置机器!`, 7);
|
|
|
+ const botList = dataSource.value.filter((item: any) => ids.includes(item.id));
|
|
|
+ const runningBotList = botList.filter((item: any) => ["RUNNING", "START_PENDING"].includes(item.status));
|
|
|
+ if (runningBotList.length > 0) return proxy.$message(`请先停止正在运行的机器!`, 7);
|
|
|
+ const result = await batchUpdateRef.value.show(botList);
|
|
|
+ if (result) getPageInfo();
|
|
|
+};
|
|
|
+// 复制参数
|
|
|
+const handleCopyParams = async (ids: any) => {
|
|
|
+ if (ids.length == 0) return proxy.$message(`请先选择要复制参数机器!`, 7);
|
|
|
+ if (ids.length == 1) return proxy.$message(`请先至少选择两台机器!`, 7);
|
|
|
+ const firstBot: any = dataSource.value.find((item: any) => item.id == ids[0]);
|
|
|
+ const otherBot = dataSource.value.filter((item: any) => ids.includes(item.id) && item.id != ids[0]);
|
|
|
+ const result = await proxy.$waitingConfirm(`是否确认要把机器"${firstBot.name}"参数复制给"${otherBot.map((item: any) => item.name).join(",")}"?`);
|
|
|
+ if (!result) return;
|
|
|
+ const configs =
|
|
|
+ firstBot.configList?.filter((item: any) => {
|
|
|
+ delete item.deleted;
|
|
|
+ delete item.id;
|
|
|
+ delete item.robotId;
|
|
|
+ return ![4, 5].includes(item.valType);
|
|
|
+ }) || [];
|
|
|
+ const params = otherBot.map((item: any) => {
|
|
|
+ const botConfigs: any =
|
|
|
+ item.configList?.filter((item: any) => {
|
|
|
+ delete item.deleted;
|
|
|
+ delete item.id;
|
|
|
+ delete item.robotId;
|
|
|
+ return [4, 5].includes(item.valType);
|
|
|
+ }) || [];
|
|
|
+ return {
|
|
|
+ id: item.id,
|
|
|
+ name: item.name,
|
|
|
+ serverId: item.serverId,
|
|
|
+ strategyId: item.strategyId,
|
|
|
+ strategyProgramId: item.strategyProgramId,
|
|
|
+ callPort: item.callPort,
|
|
|
+ startAmount: item.startAmount,
|
|
|
+ remark: item.remark,
|
|
|
+ robotConfigs: [...configs, ...botConfigs],
|
|
|
+ };
|
|
|
+ });
|
|
|
+ update_robot_batch(params, (data: any) => {
|
|
|
+ pageConfig.loading = false;
|
|
|
+ if (data.code == 200) {
|
|
|
+ proxy.$message(`复制成功!`);
|
|
|
+ getPageInfo();
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 保命方法
|
|
|
+const handleSurviveRobot = async () => {
|
|
|
+ let result = await proxy.$waitingConfirm(`<div>保命把<span class="danger-color">所有机器人</span>杠杆调整成<span class="danger-color">0.1</span>,是否确认要执行保命操作?</div>`);
|
|
|
+ if (!result) return;
|
|
|
+
|
|
|
+ const params = {};
|
|
|
+ pageConfig.loading = true;
|
|
|
+ survive_robot(params, (data: any) => {
|
|
|
+ pageConfig.loading = false;
|
|
|
+ if (data.code == 200) {
|
|
|
+ proxy.$message(`执行成功!`);
|
|
|
+ getPageInfo();
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 还原方法
|
|
|
+const handleRestoreRobot = async () => {
|
|
|
+ let result = await proxy.$waitingConfirm("是否确认要执行还原操作?");
|
|
|
+ if (!result) return;
|
|
|
+
|
|
|
+ const params = {};
|
|
|
+ pageConfig.loading = true;
|
|
|
+ restore_robot(params, (data: any) => {
|
|
|
+ pageConfig.loading = false;
|
|
|
+ if (data.code == 200) {
|
|
|
+ proxy.$message(`执行成功!`);
|
|
|
+ getPageInfo();
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const handleResetCapital = async (ids: any) => {
|
|
|
+ if (ids.length == 0) return proxy.$message(`请先选择要复位本金机器!`, 7);
|
|
|
+ let result = await proxy.$waitingConfirm("是否确认要复位机器本金?");
|
|
|
+ if (!result) return;
|
|
|
+ const params = ids;
|
|
|
+ set_robot_reset_capital(params, (data: any) => {
|
|
|
+ if (data.code == 200) {
|
|
|
+ proxy.$message(`执行成功!`);
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const handleStatus = (ids: any, status: String) => {
|
|
|
+ if (ids.length == 0) return proxy.$message(`请先选择要执行命令机器!`, 7);
|
|
|
+ const params = { robotIds: ids, status };
|
|
|
+ set_robot_status(params, (data: any) => {
|
|
|
+ if (data.code == 200) {
|
|
|
+ proxy.$message(`执行成功!`);
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const handleUpdate = async (value?: any) => {
|
|
|
+ const result = await updateRef.value.show(value);
|
|
|
+ if (result) getPageInfo();
|
|
|
+};
|
|
|
+
|
|
|
+// 删除机器人
|
|
|
+const handleDelete = async (value: any) => {
|
|
|
+ let result = await proxy.$waitingConfirm("是否确认删除该机器人?");
|
|
|
+ if (!result) return;
|
|
|
+ let params = [value.id];
|
|
|
+ pageConfig.loading = true;
|
|
|
+ delete_robot(params, (data: any) => {
|
|
|
+ pageConfig.loading = false;
|
|
|
+ if (data.code == 200) {
|
|
|
+ proxy.$message(`删除成功!`);
|
|
|
+ getPageInfo();
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+// 分页设置
|
|
|
+const handleCurrentChange = (val: any) => {
|
|
|
+ pageParams.pageNum = val.current;
|
|
|
+ pageParams.pageSize = val.limit;
|
|
|
+ getPageInfo();
|
|
|
+};
|
|
|
+
|
|
|
+onBeforeUnmount(() => {
|
|
|
+ document.title = "4L CAPITAL";
|
|
|
+ clearInterval(refreshInterval);
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.custom-operator-wp {
|
|
|
+ .custom-group {
|
|
|
+ margin-right: 14px;
|
|
|
+ display: inline-block;
|
|
|
+ vertical-align: middle;
|
|
|
+ }
|
|
|
+ .collect-wp {
|
|
|
+ line-height: 24px;
|
|
|
+ padding: 0 4px;
|
|
|
+ border: 1px solid var(--normal-color);
|
|
|
+ color: var(--normal-color);
|
|
|
+ :deep(.primary-color) {
|
|
|
+ color: var(--primary-color);
|
|
|
+ }
|
|
|
+ :deep(.danger-color) {
|
|
|
+ color: var(--danger-color);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+.ellipsis-2 {
|
|
|
+ display: -webkit-box;
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
+ overflow: hidden;
|
|
|
+ line-break: anywhere;
|
|
|
+ -webkit-line-clamp: 2; /* 控制显示的行数 */
|
|
|
+}
|
|
|
+.custom-form-layout {
|
|
|
+ font-size: 12px !important;
|
|
|
+}
|
|
|
+.primary-color {
|
|
|
+ color: var(--primary-color);
|
|
|
+}
|
|
|
+.normal-color {
|
|
|
+ color: var(--normal-color);
|
|
|
+}
|
|
|
+.danger-color {
|
|
|
+ color: var(--danger-color);
|
|
|
+}
|
|
|
+</style>
|