DESKTOP-NE65RNK\Citrus_limon 6 miesięcy temu
rodzic
commit
ab1b348b6f

+ 0 - 68
src/api/index.ts

@@ -195,74 +195,6 @@ export const get_arbitrage_robot_detail_balance = (params: any, callback: any) =
   });
 };
 
-// CTA机器人管理
-// 机器人管理-CTA列表
-export const get_cta_robot_list = (params: any, callback: any) => {
-  return http.request("/cta/transaction_config/getPage", "get", params).then((data) => {
-    if (data) callback && callback(data);
-  });
-};
-// 机器人管理-添加CTA
-export const add_cta_robot = (params: any, callback: any) => {
-  return http.request("/cta/transaction_config/save", "post", params).then((data) => {
-    if (data) callback && callback(data);
-  });
-};
-// 机器人管理-修改CTA
-export const update_cta_robot = (params: any, callback: any) => {
-  return http.request("/cta/transaction_config/update", "post", params).then((data) => {
-    if (data) callback && callback(data);
-  });
-};
-// 机器人管理-删除CTA
-export const delete_cta_robot = (params: any, callback: any) => {
-  return http.request("/cta/transaction_config/delete", "post", params).then((data) => {
-    if (data) callback && callback(data);
-  });
-};
-// 机器人管理-修改CTA状态
-export const set_cta_robot_status = (params: any, callback: any) => {
-  return http.request("/cta/transaction_config/status", "post", params).then((data) => {
-    if (data) callback && callback(data);
-  });
-};
-// 机器人管理-获取CTA账户余额
-export const refresh_cta_robot_balance = (params: any, callback: any) => {
-  return http.request("/cta/transaction_config/refreshBalance", "get", params).then((data) => {
-    if (data) callback && callback(data);
-  });
-};
-// 机器人管理-CTA机器复位本金
-export const restoration_cta_robot_balance = (params: any, callback: any) => {
-  return http.request("/cta/transaction_config/restoration", "post", params).then((data) => {
-    if (data) callback && callback(data);
-  });
-};
-// 机器人管理-CTA机器详情
-export const get_cta_robot_detail = (params: any, callback: any) => {
-  return http.request("/cta/transaction_config/detail", "get", params).then((data) => {
-    if (data) callback && callback(data);
-  });
-};
-// 机器人管理-CTA机器订单列表
-export const get_cta_robot_order_list = (params: any, callback: any) => {
-  return http.request("/cta/statistics/order/getPage", "get", params).then((data) => {
-    if (data) callback && callback(data);
-  });
-};
-// 机器人管理-CTA机器日志
-export const get_cta_robot_error_log = (params: any, callback: any) => {
-  return http.request("/cta/errorLog/getPage", "get", params).then((data) => {
-    if (data) callback && callback(data);
-  });
-};
-// 机器人管理-CTA机器利润
-export const get_cta_robot_profit = (params: any, callback: any) => {
-  return http.request("/cta/statistics/profitLossAndTradeVolume", "get", params).then((data) => {
-    if (data) callback && callback(data);
-  });
-};
-
 // 策略管理
 // 策略管理-策略列表
 export const get_strategy_list = (params: any, callback: any) => {

+ 0 - 12
src/router/routes.ts

@@ -46,12 +46,6 @@ const routes: Array<RouteRecordRaw> = [
         component: () => import("@/views/bot/arbitrage/index.vue"),
         meta: { title: "套利机器人管理", keepAlive: true },
       },
-      {
-        path: "/bot/cta",
-        name: "BotCta",
-        component: () => import("@/views/bot/cta/index.vue"),
-        meta: { title: "CTA机器人管理", keepAlive: true },
-      },
       {
         path: "/exchange/manage",
         name: "ExchangeManage",
@@ -219,12 +213,6 @@ const routes: Array<RouteRecordRaw> = [
     name: "BotArbitrageDetail",
     component: () => import("@/views/bot/arbitrage/detail.vue"),
     meta: { title: "套利机器人详情", keepAlive: false },
-  },
-  {
-    path: "/bot/cta/detail/:id",
-    name: "BotCtaDetail",
-    component: () => import("@/views/bot/cta/detail.vue"),
-    meta: { title: "CTA机器人详情", keepAlive: false },
   }
 ];
 

+ 0 - 40
src/views/bot/cta/components/InfoLayer.vue

@@ -1,40 +0,0 @@
-<template>
-  <lay-layer :title="modelConfig.title" v-model="modelConfig.visible" area="auto">
-    <div class="width-1000 custom-layer" style="padding: 20px">
-      <div class="content">
-        {{ modelParams.text }}
-      </div>
-    </div>
-  </lay-layer>
-</template>
-
-<script lang="ts" setup>
-import { ref, reactive } from "vue";
-
-interface ModelConfig {
-  title: string;
-  visible: boolean;
-  isUpdate: boolean;
-  loading: boolean;
-}
-interface ModelParams {
-  text?: string;
-}
-
-let modelParams = ref<ModelParams>({});
-let modelConfig: ModelConfig = reactive({ title: "", visible: false, isUpdate: false, loading: false });
-
-const show = (params?: any) => {
-  modelConfig.visible = true;
-  modelConfig.title = "数据详情";
-  modelParams.value = { text: params };
-};
-
-defineExpose({ show });
-</script>
-<style lang="scss" scoped>
-.content {
-  word-wrap: break-word;
-  padding: 10px;
-}
-</style>

+ 0 - 84
src/views/bot/cta/components/Logs.vue

@@ -1,84 +0,0 @@
-<template>
-  <lay-layer :title="modelConfig.title" v-model="modelConfig.visible" area="auto">
-    <div class="width-1000 custom-layer" style="padding: 20px">
-      <div class="table-wp">
-        <lay-table :page="tablePage" :columns="columns" resize :data-source="dataSource" :loading="modelConfig.tableLoading" @change="handleCurrentChange">
-          <template v-slot:status="{ row }">
-            {{ row.status ? "启用" : "禁用" }}
-          </template>
-        </lay-table>
-      </div>
-    </div>
-  </lay-layer>
-</template>
-
-<script lang="ts" setup>
-import { ref, reactive } from "vue";
-import { get_cta_robot_error_log } from "@/api/index";
-
-interface ModelConfig {
-  title: string;
-  visible: boolean;
-  isUpdate: boolean;
-  loading: boolean;
-  tableLoading: boolean;
-}
-
-let modelConfig: ModelConfig = reactive({ title: "", visible: false, isUpdate: false, loading: false, tableLoading: true });
-
-interface FormItem {
-  pageNum?: Number;
-  pageSize?: Number;
-  id?: number;
-}
-
-let modelParams: FormItem = reactive({ pageNum: 1, pageSize: 20 });
-
-interface TablePage {
-  current: number;
-  limit: number;
-  total: number;
-}
-const tablePage: TablePage = reactive({ current: 1, limit: 20, total: 0, limits: [20, 50, 100, 200, 500] });
-const columns = ref([
-  { title: "错误类型", key: "title" },
-  { title: "请求参数", key: "paramsStr", ellipsisTooltip: true },
-  { title: "错误结果", key: "errorLos", ellipsisTooltip: true },
-]);
-let dataSource = ref([]);
-
-const show = (params?: any) => {
-  modelConfig.visible = true;
-  modelConfig.title = "数据详情";
-  dataSource = ref([]);
-  modelParams = { ...modelParams, id: params.id };
-  getCtaRobotErrorLog();
-};
-
-const getCtaRobotErrorLog = () => {
-  let params = { ...modelParams };
-  modelConfig.tableLoading = true;
-  get_cta_robot_error_log(params, (data: any) => {
-    modelConfig.tableLoading = false;
-    if (data.code == 200) {
-      dataSource.value = data.data.list;
-      tablePage.total = data.data.total;
-    }
-  });
-};
-
-// 分页设置
-const handleCurrentChange = (val: any) => {
-  modelParams.pageNum = val.current;
-  modelParams.pageSize = val.limit;
-  getCtaRobotErrorLog();
-};
-
-defineExpose({ show });
-</script>
-<style lang="scss" scoped>
-.content {
-  word-wrap: break-word;
-  padding: 10px;
-}
-</style>

+ 0 - 179
src/views/bot/cta/components/Update.vue

@@ -1,179 +0,0 @@
-<template>
-  <lay-layer :title="modelConfig.title" v-model="modelConfig.visible" area="auto" :btn="operator">
-    <div class="width-800 custom-layer" style="padding: 20px">
-      <lay-form :model="modelParams" ref="modelFormRef" required>
-        <lay-row space="10">
-          <lay-col md="12" sm="12" xs="24">
-            <lay-form-item label="名称" prop="name">
-              <lay-input v-model="modelParams.name" placeholder="机器人名称" />
-            </lay-form-item>
-          </lay-col>
-          <lay-col md="12" sm="12" xs="24">
-            <lay-form-item label="币对" prop="symbol">
-              <lay-input v-model="modelParams.symbol" placeholder="交易币对" />
-            </lay-form-item>
-          </lay-col>
-          <lay-col md="12" sm="12" xs="24">
-            <lay-form-item label="服务器" prop="serverId">
-              <lay-select v-model="modelParams.serverId" :show-search="true">
-                <lay-select-option v-for="item in serverList" :value="item.id" :label="item.value" placeholder="选择服务器" />
-              </lay-select>
-            </lay-form-item>
-          </lay-col>
-          <lay-col md="12" sm="12" xs="24">
-            <lay-form-item label="交易所" prop="exchange">
-              <lay-select v-model="modelParams.exchange" :show-search="true">
-                <lay-select-option v-for="(key, value) in INDICATOR_EXCHANG_TYPE" :value="key" :label="value" placeholder="选择交易所" />
-              </lay-select>
-            </lay-form-item>
-          </lay-col>
-          <lay-col md="12" sm="12" xs="24">
-            <lay-form-item label="账户" prop="accountId">
-              <lay-select v-model="modelParams.accountId" :show-search="true">
-                <lay-select-option v-for="item in apikeyList" :value="item.value" :label="item.label" placeholder="选择账户" />
-              </lay-select>
-            </lay-form-item>
-          </lay-col>
-          <lay-col md="12" sm="12" xs="24">
-            <lay-form-item label="资金比例" prop="fundRatio">
-              <lay-input v-model="modelParams.fundRatio" placeholder="资金比例" />
-            </lay-form-item>
-          </lay-col>
-          <lay-col md="12" sm="12" xs="24">
-            <lay-form-item label="止损比例" prop="stopLoss">
-              <lay-input v-model="modelParams.stopLoss" placeholder="账户止损比例" />
-            </lay-form-item>
-          </lay-col>
-          <lay-col md="24" sm="24" xs="24">
-            <lay-form-item label="平仓方式" prop="closeType">
-              <lay-radio-group name="action" v-model="modelParams.closeType">
-                <!-- <lay-radio value="1">止盈止损</lay-radio> -->
-                <lay-radio value="2">时间平仓</lay-radio>
-              </lay-radio-group>
-            </lay-form-item>
-          </lay-col>
-          <lay-col md="12" sm="12" xs="24">
-            <lay-form-item label="平仓时间(s)" prop="clockTime">
-              <lay-input v-model="modelParams.clockTime" placeholder="平仓时间(s)" />
-              <div class="input-hint">平仓时间:{{ formatTime(parseInt(modelParams.clockTime || "0") > 0 ? modelParams.clockTime : 0) }}</div>
-            </lay-form-item>
-          </lay-col>
-        </lay-row>
-      </lay-form>
-    </div>
-  </lay-layer>
-</template>
-
-<script lang="ts" setup>
-import { ref, reactive, getCurrentInstance } from "vue";
-import { formatTime } from "@/utils/index";
-import { add_cta_robot, update_cta_robot, get_server_select, get_apikey_select } from "@/api";
-import { INDICATOR_EXCHANG_TYPE } from "@/utils/enum";
-
-const { proxy }: any = getCurrentInstance();
-
-const modelFormRef = ref();
-
-interface ModelConfig {
-  title: string;
-  visible: boolean;
-  isUpdate: boolean;
-  loading: boolean;
-}
-interface ModelParams {
-  id?: number;
-  name?: string;
-  symbol?: string;
-  fundRatio?: number;
-  exchange?: string;
-  serverId?: number;
-  accountId?: number;
-  stopLoss?: number;
-  closeType?: string;
-  clockTime?: string;
-}
-
-let modelParams = ref<ModelParams>({});
-let modelConfig: ModelConfig = reactive({ title: "", visible: false, isUpdate: false, loading: false });
-
-let handleResult = reactive<{ resolve?: any; reject?: any }>({});
-
-let serverList = ref();
-let apikeyList = ref();
-
-const show = async (params?: any) => {
-  const accountId = params.configList?.find((item: any) => item.code == "account")?.val;
-  serverList.value = [];
-  apikeyList.value = [];
-  get_server_list();
-  get_apikey(accountId);
-  modelConfig.visible = true;
-  modelConfig.isUpdate = !!params;
-  modelParams.value = modelConfig.isUpdate ? { ...params, closeType: "2" } : { closeType: "2", clockTime: 86400 };
-  modelConfig.title = !!params ? "编辑机器人" : "添加机器人";
-  return new Promise(async (resolve, reject) => {
-    handleResult.resolve = resolve;
-    handleResult.reject = reject;
-  });
-};
-// 获取服务器列表
-const get_server_list = () => {
-  const params = {};
-  get_server_select(params, (data: any) => {
-    serverList.value = data.data;
-  });
-};
-// 获取APIKEY参数下拉
-const get_apikey = (id: any) => {
-  const params = {};
-  get_apikey_select(params, (data: any) => {
-    apikeyList.value = data.data.filter((item: any) => item.inUseNum < 1 || item.id == id).map((item: any) => ({ label: item.value, value: item.id }));
-  });
-};
-const operator = reactive([
-  {
-    text: "确认",
-    callback: () => {
-      modelFormRef.value.validate((isValidate: boolean) => {
-        if (isValidate) {
-          modelConfig.loading = true;
-          const params = { ...modelParams.value, symbol: modelParams.value.symbol?.toLocaleUpperCase() };
-          if (modelConfig.isUpdate) {
-            update_cta_robot(params, (data: any) => {
-              modelConfig.loading = false;
-              if (data.code == 200) {
-                proxy.$message("编辑成功!");
-                modelConfig.visible = false;
-                handleResult.resolve(true);
-              }
-            });
-          } else {
-            add_cta_robot(params, (data: any) => {
-              modelConfig.loading = false;
-              if (data.code == 200) {
-                proxy.$message("添加成功!");
-                modelConfig.visible = false;
-                handleResult.resolve(true);
-              }
-            });
-          }
-        }
-      });
-    },
-  },
-  {
-    text: "取消",
-    callback: () => {
-      modelConfig.visible = false;
-      handleResult.resolve(false);
-    },
-  },
-]);
-defineExpose({ show });
-</script>
-
-<style lang="scss" scoped>
-.operator-wp {
-  padding-left: 110px;
-}
-</style>

+ 0 - 403
src/views/bot/cta/detail.vue

@@ -1,403 +0,0 @@
-<template>
-  <div class="container-wp">
-    <div class="robot-info-header">
-      <lay-space>
-        <span class="robot-name">{{ robotDetail.name }}</span>
-        <lay-tag size="sm">
-          <span class="robot-status" v-if="robotDetail.status">
-            <lay-badge type="dot" theme="blue" ripple />
-            <span>{{ ROBOT_STATUS[robotDetail.status] }}</span>
-          </span>
-          <span class="robot-status" v-else-if="!robotDetail.status">
-            <lay-badge type="dot" />
-            <span>{{ ROBOT_STATUS[robotDetail.status] }}</span>
-          </span>
-        </lay-tag>
-      </lay-space>
-    </div>
-
-    <lay-card class="custom-card">
-      <template v-slot:title>
-        <span class="card-title">收益图</span>
-        <span class="card-subtitle">(近3天)</span>
-      </template>
-      <template v-slot:extra>
-        <lay-button class="card-button" border="red" @click="handleShowLogs()">错误日志</lay-button>
-      </template>
-      <template v-slot:body>
-        <div class="profit-chart" ref="profitChartRef"></div>
-      </template>
-    </lay-card>
-    <lay-card class="custom-card">
-      <template v-slot:title>
-        <span class="card-title">订单列表</span>
-      </template>
-
-      <template v-slot:body>
-        <lay-table :page="ordersPage" :columns="orderColumns" size="sm" resize :data-source="ordersList" :loading="pageConfig.ordersLoading" @change="handleCurrentChange">
-          <template v-slot:text="{ row }">
-            {{ row.text }}
-          </template>
-          <template v-slot:symbol="{ row }">
-            {{ JSON.parse(row.resJson).symbol.split(":")[0] }}
-          </template>
-          <template v-slot:price="{ row }">
-            {{ JSON.parse(row.resJson).price }}
-          </template>
-          <template v-slot:average="{ row }">
-            {{ JSON.parse(row.resJson).average }}
-          </template>
-          <template v-slot:side="{ row }">
-            {{ JSON.parse(row.resJson).side }}
-          </template>
-          <template v-slot:sideType="{ row }">
-            {{ JSON.parse(row.resJson).reduceOnly ? "平仓" : "开仓" }}
-          </template>
-          <template v-slot:amount="{ row }">
-            {{ JSON.parse(row.resJson).amount }}
-          </template>
-          <template v-slot:timestamp="{ row }">
-            {{ formatDate(JSON.parse(row.resJson).timestamp) }}
-          </template>
-          <template v-slot:resJson="{ row }">
-            <span @click="showInfoLayer(row.resJson)">{{ row.resJson }}</span>
-          </template>
-        </lay-table>
-      </template>
-    </lay-card>
-  </div>
-  <InfoLayer ref="infoLayerRef" />
-  <Logs ref="logsRef" />
-</template>
-<script lang="ts" setup name="BotCtaDetail">
-import { ref, reactive, onMounted, onUnmounted, shallowRef } from "vue";
-import { useRoute } from "vue-router";
-import { formatDate } from "@/utils/index";
-import * as echarts from "echarts";
-import Decimal from "decimal.js";
-import dayjs from "dayjs";
-import InfoLayer from "./components/InfoLayer.vue";
-import Logs from "./components/Logs.vue"
-import { get_cta_robot_detail, get_cta_robot_order_list, get_cta_robot_profit } from "@/api";
-
-const ROBOT_STATUS: any = reactive({
-  0: "已停止",
-  1: "运行中",
-});
-
-// const apiList = ref(window.sessionStorage.getItem("_4L_API_LIST"));
-
-const profitChartRef = ref();
-const infoLayerRef = ref();
-const logsRef = ref();
-
-const route = useRoute();
-
-interface PageConfig {
-  detailLoading: boolean;
-  ordersLoading: boolean;
-  profitLoading: boolean;
-}
-interface Order {
-  time?: string;
-  text?: string;
-}
-
-let pageConfig: PageConfig = reactive({
-  detailLoading: true,
-  ordersLoading: true,
-  profitLoading: true,
-});
-
-interface OrderItem {
-  pageNum?: Number;
-  pageSize?: Number;
-  name?: String;
-  symbol?: String;
-  robotState?: String;
-}
-const ordersParams: OrderItem = reactive({ pageNum: 1, pageSize: 50 });
-
-interface OrderPage {
-  current: number;
-  limit: number;
-  total: number;
-}
-const ordersPage: OrderPage = reactive({ current: 1, limit: 50, total: 0, limits: [20, 50, 100, 200, 500] });
-
-const orderColumns = ref([
-  { title: "订单号", key: "id", width: 150 },
-  { title: "币对", key: "symbol", customSlot: "symbol", align: "center" },
-  { title: "价格", key: "price", customSlot: "price", align: "center" },
-  { title: "成交均价", key: "average", customSlot: "average", align: "center" },
-  { title: "方向", key: "side", customSlot: "side", align: "center" },
-  { title: "类型", key: "sideType", customSlot: "sideType", align: "center" },
-  { title: "数量", key: "amount", customSlot: "amount", align: "center" },
-  { title: "订单时间", key: "timestamp", customSlot: "timestamp", align: "center" },
-  { title: "源数据", key: "resJson", customSlot: "resJson", ellipsisTooltip: true, align: "center" },
-]);
-
-let ordersList = ref<Array<Order>>();
-let robotDetail = ref<any>({});
-let profitList = ref([]);
-let profitChart = shallowRef();
-let predictorChart = shallowRef();
-let timer = ref();
-
-// 获取机器人详情
-const getCtaRobotDetail = () => {
-  const params = { id: route.params.id };
-  pageConfig.detailLoading = true;
-  get_cta_robot_detail(params, (data: any) => {
-    pageConfig.detailLoading = false;
-    if (data.code == 200) {
-      robotDetail.value = data.data;
-      document.title = data.data.name;
-      getCtaRobotOrderList();
-      getProfitInfo(data.data.id);
-    }
-  });
-};
-
-const getCtaRobotOrderList = () => {
-  const params = { ...ordersParams, tId: route.params.id };
-  pageConfig.ordersLoading = true;
-  get_cta_robot_order_list(params, (data: any) => {
-    pageConfig.ordersLoading = false;
-    if (data.code == 200) {
-      ordersList.value = data.data.list;
-      ordersPage.total = data.data.total;
-    }
-  });
-};
-
-// 分页设置
-const handleCurrentChange = (val: any) => {
-  ordersParams.pageNum = val.current;
-  ordersParams.pageSize = val.limit;
-  getCtaRobotOrderList();
-};
-const getProfitInfo = (id: number) => {
-  const params = { tId: id, startTime: +dayjs().subtract(72, "hour"), endTime: +dayjs() };
-  pageConfig.profitLoading = true;
-  get_cta_robot_profit(params, (data: any) => {
-    pageConfig.profitLoading = false;
-    if (data.code == 200) {
-      profitList.value = data.data;
-
-      let balance = new Decimal(0);
-      const sData = data.data.map((item: any) => {
-        balance = new Decimal(item.profitLoss).add(balance);
-        return [
-          formatDate(item.timestamp),
-          balance.toString(),
-          item.symbol.split(":")[0],
-          item.openSide,
-          item.openPrice,
-          item.openSize,
-          item.openTradeVolume,
-          item.closedSide,
-          item.closedPrice,
-          item.closedSize,
-          item.closedTradeVolume,
-          item.profitLoss,
-        ];
-      });
-      const xData = sData.map((item: any) => item[0]);
-      const yMinData = Math.min(...sData.map((item: any) => item[1]));
-
-      !profitChart.value
-        ? initProfitChart(data.data)
-        : profitChart.value.setOption({
-            xAxis: {
-              type: "category",
-              boundaryGap: false,
-              data: xData,
-            },
-            yAxis: {
-              type: "value",
-              boundaryGap: [0, "100%"],
-              min: yMinData,
-              splitNumber: 5,
-            },
-            series: {
-              name: "Balance",
-              type: "line",
-              areaStyle: {},
-              lineStyle: {
-                width: 1,
-              },
-              data: sData,
-            },
-          });
-    }
-  });
-};
-
-// 请求机器人日志
-const handleShowLogs = () => {
-  const params = { id: route.params.id };
-  logsRef.value.show(params)
-};
-
-// const handlePageInfo = (data: any) => {
-//   let infoList = data;
-//   let result = infoList.map((item: string) => {
-//     return { time: item.slice(0, 18), text: item.slice(19).trim() };
-//   });
-//   return result;
-// };
-
-const showInfoLayer = (data: any) => {
-  infoLayerRef.value.show(data);
-};
-
-const initProfitChart = (data: any) => {
-  if (profitChart.value != null && !profitChart.value.isDisposed()) echarts.dispose(profitChart.value);
-
-  profitChart.value = echarts.init(profitChartRef.value);
-
-  window.removeEventListener("resize", () => profitChart.value.resize());
-  window.addEventListener("resize", () => profitChart.value.resize());
-
-  let balance = new Decimal(0);
-  const sData = data.map((item: any) => {
-    balance = new Decimal(item.profitLoss).add(balance);
-    return [
-      formatDate(item.timestamp),
-      balance.toString(),
-      item.symbol.split(":")[0],
-      item.openSide,
-      item.openPrice,
-      item.openSize,
-      item.openTradeVolume,
-      item.closedSide,
-      item.closedPrice,
-      item.closedSize,
-      item.closedTradeVolume,
-      item.profitLoss,
-    ];
-  });
-  const xData = sData.map((item: any) => item[0]);
-  const yMinData = Math.min(...sData.map((item: any) => item[1]));
-
-  const profitChartOption = {
-    tooltip: {
-      trigger: "axis",
-      axisPointer: {
-        type: "cross",
-      },
-      formatter: (params: any) => {
-        let info = params[0];
-        return `${info.marker}${info.seriesName}<br/>
-        时间:${info.value[0]} <br/>
-        币对:${info.value[2]}<br/>
-        总体收益:${info.value[1]}<br/>
-        单笔收益:${info.value[11]}<br/>
-        开仓方向:${info.value[3]}<br/>
-        开仓价格:${info.value[4]}&nbsp;&nbsp;&nbsp;&nbsp;开仓数量:${info.value[5]}&nbsp;&nbsp;&nbsp;&nbsp;开仓价值:${info.value[6]}<br/>
-        平仓方向:${info.value[7]}<br/>
-        平仓价格:${info.value[8]}&nbsp;&nbsp;&nbsp;&nbsp;平仓数量:${info.value[9]}&nbsp;&nbsp;&nbsp;&nbsp;平仓价值:${info.value[10]}<br/>
-        `;
-      },
-    },
-    dataZoom: [
-      {
-        start: 0,
-        end: 100,
-      },
-      {
-        type: "inside",
-        start: 0,
-        end: 100,
-      },
-    ],
-    xAxis: {
-      type: "category",
-      boundaryGap: false,
-      data: xData,
-    },
-    yAxis: {
-      type: "value",
-      boundaryGap: [0, "100%"],
-      min: yMinData,
-      splitNumber: 5,
-    },
-    series: {
-      name: "Balance",
-      type: "line",
-      areaStyle: {},
-      data: sData,
-    },
-  };
-  profitChart.value.setOption(profitChartOption);
-};
-
-timer.value = setInterval(() => {
-  getProfitInfo(robotDetail.value.id);
-  // getLogsInfo();
-}, 10000);
-
-// getLogsInfo();
-
-onMounted(() => {
-  getCtaRobotDetail();
-});
-
-onUnmounted(() => {
-  window.removeEventListener("resize", () => profitChart.value.resize());
-  clearInterval(timer.value);
-  predictorChart.value.dispose();
-});
-</script>
-
-<style lang="scss" scoped>
-.height-1200 {
-  height: 1200px;
-}
-.card-body-wp {
-  text-align: center;
-  .chart {
-    height: 100%;
-    width: 100%;
-  }
-}
-.card-button {
-  padding: 2px 18px;
-}
-.ellipsis-2 {
-  display: -webkit-box;
-  -webkit-box-orient: vertical;
-  overflow: hidden;
-  line-break: anywhere;
-  line-clamp: 2; /* 控制显示的行数 */
-  -webkit-line-clamp: 2; /* 控制显示的行数 */
-}
-.container-wp {
-  min-height: 100%;
-  padding: 20px 40px;
-  background-color: rgb(244, 246, 247);
-}
-.profit-chart {
-  height: 300px;
-}
-.predictor-chart {
-  height: 1200px;
-}
-.robot-info-header {
-  min-width: 1352px;
-  background-color: white;
-  padding: 16px 24px;
-  margin-bottom: 20px;
-  .robot-name {
-    font-size: 14px;
-    font-weight: bold;
-  }
-  .robot-status {
-    span {
-      font-size: 12px;
-      padding-left: 4px;
-    }
-  }
-}
-</style>

+ 0 - 338
src/views/bot/cta/index.vue

@@ -1,338 +0,0 @@
-<template>
-  <lay-card class="custom-card">
-    <template v-slot:title>
-      <span class="card-title">CTA机器人管理</span>
-    </template>
-    <template v-slot:extra>
-      <lay-button class="card-button" @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="name">
-            <lay-input v-model="pageParams.name" />
-          </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>
-          <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="'red'" size="xs" @click="handleStatus(selectedKeys, 'STOP')">停机</lay-button> -->
-            <lay-button border="green" size="xs" @click="handleRrestoration(selectedKeys)">复位余额</lay-button>
-          </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 class="normal-color" @click="jumpDetail(row)">{{ row.name }}</span>
-          </template>
-          <template v-slot:earningRate="{ row }">
-            <span :class="{ 'primary-color': row.nowAmount - row.startAmount > 0, 'danger-color': row.nowAmount - row.startAmount < 0 }">
-              {{ (((row.nowAmount - row.startAmount) / (row.startAmount || 1)) * 100).toFixed(2) || 0 }}%
-            </span>
-          </template>
-          <template v-slot:startAmount="{ row }">
-            {{ row.startAmount.toFixed(2) || 0 }}
-          </template>
-          <template v-slot:nowAmount="{ row }">
-            {{ row.nowAmount.toFixed(2) || 0 }}
-          </template>
-          <template v-slot:configs="{ row }">
-            <lay-tooltip :content="`资金比例:${row.fundRatio * 100}%;账户止损比例:${row.stopLoss * 100}%`">
-              <div class="ellipsis-2" @click="handleUpdate(row)">
-                {{ `资金比例:${row.fundRatio * 100}%;账户止损比例:${row.stopLoss * 100}%` }}
-              </div>
-            </lay-tooltip>
-          </template>
-          <template v-slot:status="{ row }">
-            <lay-space v-if="row.status">
-              <lay-badge type="dot" theme="blue" ripple />
-              <span>{{ ROBOT_STATUS[row.status] }}</span>
-            </lay-space>
-            <lay-space v-else-if="!row.status">
-              <lay-badge type="dot" />
-              <span>{{ ROBOT_STATUS[row.status] }}</span>
-            </lay-space>
-          </template>
-          <template v-slot:updateTime="{ row }">
-            <span>{{ timeConverts(row.updateTime) }}</span>
-          </template>
-          <template v-slot:operator="{ row }">
-            <lay-space>
-              <TableButton :text="row.status ? '关机' : '开机'" :type="row.status ? 'danger' : 'primary'" @click="handleStatus(row)" />
-              <TableButton text="编辑" @click="handleUpdate(row)" />
-              <TableButton text="更新余额" @click="refreshBalance(row)" />
-              <TableButton v-if="!row.status" type="danger" 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="'red'" size="xs" @click="handleStatus(selectedKeys, 'STOP')">停机</lay-button> -->
-            <lay-button border="green" size="xs" @click="handleRrestoration(selectedKeys)">复位余额</lay-button>
-          </lay-space>
-        </div>
-      </div>
-    </template>
-  </lay-card>
-  <Update ref="updateRef" />
-</template>
-
-<script lang="ts" setup name="BotCta">
-import { ref, reactive, getCurrentInstance, onActivated, onDeactivated } from "vue";
-import Update from "./components/Update.vue";
-import TableButton from "@/components/TableButton.vue";
-import { timeConverts } from "@/utils/index";
-import { get_cta_robot_list, delete_cta_robot, set_cta_robot_status, refresh_cta_robot_balance, restoration_cta_robot_balance } from "@/api";
-
-const ROBOT_STATUS: any = reactive({
-  0: "已停止",
-  1: "运行中",
-});
-
-const { proxy }: any = getCurrentInstance();
-const updateRef = ref();
-
-// const apiList = ref(window.sessionStorage.getItem("_4L_API_LIST"));
-
-interface PageConfig {
-  loading: boolean;
-  requestLoading: boolean;
-}
-
-let pageConfig: PageConfig = reactive({
-  loading: false,
-  requestLoading: false,
-});
-
-interface FormItem {
-  pageNum?: Number;
-  pageSize?: Number;
-  name?: String;
-  symbol?: String;
-  robotState?: 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: "名称", key: "name", customSlot: "name", ellipsisTooltip: true },
-  { title: "账户", key: "accountName", ellipsisTooltip: true },
-  { title: "币对", key: "symbol", align: "center", ellipsisTooltip: true },
-  { title: "初始余额", width: "100px", key: "startAmount", customSlot: "startAmount",align: "center" },
-  { title: "当前余额", width: "100px", key: "nowAmount", customSlot: "nowAmount",align: "center" },
-  { title: "收益", width: "80px", key: "earningRate", customSlot: "earningRate", align: "center" },
-  { title: "配置信息", width: "240px", key: "configs", customSlot: "configs" },
-  { title: "状态", width: "90px", key: "status", customSlot: "status", align: "center" },
-  { title: "IP", width: "120px", key: "serverName", ellipsisTooltip: true },
-  // { 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: "200px",
-    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 exchangeList = ref();
-let refreshAsBotInterval = ref();
-
-// 请求机器人列表
-const getPageInfo = (isSearch?: boolean, isRefresh?: boolean) => {
-  if (isSearch) {
-    pageParams.pageNum = 1;
-    selectedKeys.value = [];
-    pageConfig.requestLoading = false;
-  }
-  if (pageConfig.requestLoading) return;
-
-  pageConfig.requestLoading = true;
-  pageConfig.loading = true && !isRefresh;
-  get_cta_robot_list(pageParams, (data: any) => {
-    pageConfig.requestLoading = false;
-    pageConfig.loading = false && !isRefresh;
-    if (data.code == 200) {
-      dataSource.value = data.data.list;
-      tablePage.total = data.data.total;
-      // handleShowInfo(data.data);
-    }
-  });
-};
-getPageInfo();
-
-const jumpDetail = (info: any) => {
-  window.open(`/bot/cta/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 handleStatus = async (value: any) => {
-  let result = await proxy.$waitingConfirm(`是否确认${value.status ? "关机" : "开机"}?`);
-  if (!result) return;
-  let params = {
-    id: value.id,
-    status: value.status ? 0 : 1,
-  };
-  pageConfig.loading = true;
-  set_cta_robot_status(params, (data: any) => {
-    pageConfig.loading = false;
-    if (data.code == 200) {
-      proxy.$message(`修改成功!`);
-      getPageInfo();
-    }
-  });
-};
-
-const handleUpdate = async (value?: any) => {
-  const result = await updateRef.value.show(value);
-  if (result) getPageInfo();
-};
-
-const handleRrestoration = async (value?: any) => {
-  let result = await proxy.$waitingConfirm("是否确认复位机器人余额?");
-  if (!result) return;
-  let params = value;
-  pageConfig.loading = true;
-  await restoration_cta_robot_balance(params, (data: any) => {
-    pageConfig.loading = false;
-    if (data.code == 200) {
-      proxy.$message(`更新成功!`);
-      getPageInfo();
-    }
-  });
-};
-
-// 更新余额
-const refreshBalance = async (value?: any) => {
-  let result = await proxy.$waitingConfirm("是否确认更新该机器人余额?");
-  if (!result) return;
-  let params = { id: value.id };
-  pageConfig.loading = true;
-  await refresh_cta_robot_balance(params, (data: any) => {
-    pageConfig.loading = false;
-    if (data.code == 200) {
-      proxy.$message(`更新成功!`);
-      getPageInfo();
-    }
-  });
-};
-
-// 删除机器人
-const handleDelete = async (value: any) => {
-  let result = await proxy.$waitingConfirm("是否确认删除该机器人?");
-  if (!result) return;
-  let params = [value.id];
-  pageConfig.loading = true;
-  delete_cta_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();
-};
-
-const startInterval = () => {
-  clearInterval(refreshAsBotInterval.value);
-  refreshAsBotInterval.value = setInterval(() => {
-    getPageInfo(false, true);
-  }, 10000);
-};
-startInterval();
-const closeInterval = () => {
-  clearInterval(refreshAsBotInterval.value);
-};
-onActivated(() => {
-  startInterval();
-});
-onDeactivated(() => {
-  closeInterval();
-  document.title = "4L CAPITAL";
-});
-</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;
-  line-clamp: 2; /* 控制显示的行数 */
-  -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>