Browse Source

添加数据收集
修改币对筛选器
修改收益率问题

DESKTOP-NE65RNK\Citrus_limon 1 year ago
parent
commit
f7357a70c6

+ 1 - 1
.env.development

@@ -1,6 +1,6 @@
 VITE_APP_ENV = development
 
 VITE_API_BASE_URL = "https://4lapi.skyfffire.com"
-# VITE_API_BASE_URL = "http://t4lapi.skyfffire.com"
+# VITE_API_BASE_URL = "https://t4lapi.skyfffire.com"
 # VITE_API_BASE_URL = "http://192.168.1.5:18888"
 # VITE_API_BASE_URL = "http://183.249.84.29:18888"

+ 1 - 1
.env.test

@@ -1,3 +1,3 @@
 VITE_APP_ENV = test
 
-VITE_API_BASE_URL = "http://t4lapi.skyfffire.com"
+VITE_API_BASE_URL = "https://t4lapi.skyfffire.com"

+ 9 - 0
src/api/index.ts

@@ -572,3 +572,12 @@ export const get_menu_all = (params: any, callback: any) => {
     if (data) callback && callback(data);
   });
 };
+
+
+
+// 数据收集-数据交易日志
+export const get_acquire_log = (params: any, callback: any) => {
+  return http.request("/api/acquireULog/getYK", "get", params).then((data) => {
+    if (data) callback && callback(data);
+  });
+};

+ 4 - 1
src/assets/css/index.scss

@@ -9,6 +9,9 @@
   --primary-color: rgb(28, 175, 131);
   --danger-color: #ff5722;
 }
+.danger-color{
+  color: var(--danger-color);
+}
 * {
   padding: 0;
   margin: 0;
@@ -119,7 +122,7 @@ body,
 }
 .custom-loading {
   .layui-loading-spinning {
-    background-color: rgba(0, 0, 0, 0.5);
+    background-color: rgba(255, 255, 255, 0.5);
   }
 }
 

+ 3 - 1
src/main.ts

@@ -21,8 +21,10 @@ app.config.globalProperties.$waitingConfirm = (
   }
 ) => {
   return new Promise((resolve) => {
-    layer.confirm(msg, {
+    layer.open({
       title: title,
+      isHtmlFragment: true,
+      content: `<div style="padding: 20px; min-width: 260px">${msg}</div>`,
       btn: [
         {
           text: type.confirmButtonText,

+ 6 - 0
src/router/routes.ts

@@ -124,6 +124,12 @@ const routes: Array<RouteRecordRaw> = [
         component: () => import("@/views/records/user/index.vue"),
         meta: { title: "用户日志", keepAlive: true },
       },
+      {
+        path: "/debug/deeebug",
+        name: "DebugDeeebug",
+        component: () => import("@/views/debug/deeebug/index.vue"),
+        meta: { title: "数据收集", keepAlive: true },
+      },
     ],
   },
   {

+ 2 - 2
src/views/bot/manage/components/BatchUpdate.vue

@@ -192,11 +192,11 @@ const strategyProgramHandleChange = (e: any) => {
 };
 
 const handleStringInput = (code: string, value: any) => {
-  if (code == "pair") modelParams.value.robotConfigs.ref_pair = value;
+  if (code == "pair") modelParams.value.robotConfigs.ref_pair = value.trim();
 };
 const handleNmberInput = (code: string, value: any) => {
   if (code == "lever_rate") {
-    modelParams.value.robotConfigs.stop_loss = new Decimal(value).dividedBy(100) > new Decimal(0.06) ? 0.06 : new Decimal(value).dividedBy(100);
+    modelParams.value.robotConfigs.stop_loss = new Decimal(value.trim()).dividedBy(100) > new Decimal(0.06) ? 0.06 : new Decimal(value.trim()).dividedBy(100);
   }
 };
 

+ 2 - 2
src/views/bot/manage/components/Update.vue

@@ -211,11 +211,11 @@ const strategyProgramHandleChange = (e: any) => {
 };
 
 const handleStringInput = (code: string, value: any) => {
-  if (code == "pair") modelParams.value.robotConfigs.ref_pair = value;
+  if (code == "pair") modelParams.value.robotConfigs.ref_pair = value.trim();
 };
 const handleNmberInput = (code: string, value: any) => {
   if (code == "lever_rate") {
-    modelParams.value.robotConfigs.stop_loss = new Decimal(value).dividedBy(100) > new Decimal(0.06) ? 0.06 : new Decimal(value).dividedBy(100);
+    modelParams.value.robotConfigs.stop_loss = new Decimal(value.trim()).dividedBy(100) > new Decimal(0.06) ? 0.06 : new Decimal(value.trim()).dividedBy(100);
   }
 };
 

+ 10 - 4
src/views/bot/manage/index.vue

@@ -246,7 +246,10 @@ let exchangeList = ref();
 
 // 请求机器人列表
 const getPageInfo = (isSearch?: boolean) => {
-  if (isSearch) pageParams.pageNum = 1;
+  if (isSearch) {
+    pageParams.pageNum = 1;
+    selectedKeys.value = [];
+  }
   pageConfig.loading = true;
   get_robot_list(pageParams, (data: any) => {
     pageConfig.loading = false;
@@ -301,13 +304,16 @@ const handleShowInfo = (info: any) => {
 const handleTransfersRobot = async (ids: any) => {
   if (ids.length == 0) return proxy.$message(`请先选择要移交机器!`, 7);
   const result = await transfersRef.value.show(ids);
-  if (result) getPageInfo();
+  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) getPageInfo();
+  if (result) {
+    selectedKeys.value = [];
+    getPageInfo();
+  }
 };
 // 批量修改
 const handleBatchUpdate = async (ids: any) => {
@@ -364,7 +370,7 @@ const handleCopyParams = async (ids: any) => {
 
 // 保命方法
 const handleSurviveRobot = async () => {
-  let result = await proxy.$waitingConfirm("是否确认要执行保命操作?");
+  let result = await proxy.$waitingConfirm(`<div>保命把<span class="danger-color">所有机器人</span>杠杆调整成<span class="danger-color">0.1</span>,是否确认要执行保命操作?</div>`);
   if (!result) return;
 
   const params = {};

+ 95 - 0
src/views/debug/deeebug/index.vue

@@ -0,0 +1,95 @@
+<template>
+  <lay-card class="custom-card">
+    <template v-slot:title>
+      <span class="card-title">数据收集</span>
+    </template>
+
+    <template v-slot:body>
+      <div class="custom-form-layout">
+        <lay-form class="form-wp" :model="pageParams" mode="inline" size="sm">
+          <div class="form-button-wp">
+            <lay-button @click="getPageInfo()">刷新</lay-button>
+          </div>
+        </lay-form>
+      </div>
+      <div>
+        <lay-table :page="tablePage" :columns="columns" resize :data-source="dataSource" :loading="pageConfig.loading" />
+      </div>
+    </template>
+  </lay-card>
+</template>
+
+<script lang="ts" setup name="DebugDeeebug">
+import { ref, reactive } from "vue";
+import { get_acquire_log } from "@/api";
+
+interface PageConfig {
+  loading: boolean;
+}
+
+let pageConfig: PageConfig = reactive({
+  loading: false,
+});
+
+interface FormItem {
+  startTime?: Number;
+  endTime?: Number;
+}
+const pageParams: FormItem = reactive({ startTime: +new Date() - 1000 * 60 * 60 * 4, endTime: +new Date() });
+
+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: "机器人ID", key: "robotId" },
+  { title: "币对", key: "pair" },
+  { title: "变动前", key: "beforeU" },
+  { title: "变动后", key: "afterU" },
+  { title: "盈亏", key: "changeU" },
+  { title: "创建时间", key: "creationTime" },
+]);
+let dataSource = ref<any>([]);
+
+// 请求数据列表
+const getPageInfo = () => {
+  //   if (isSearch) pageParams.pageNum = 1;
+  pageConfig.loading = true;
+  get_acquire_log(pageParams, (data: any) => {
+    pageConfig.loading = false;
+    if (data.code == 200) {
+      dataSource.value = [...data.data["+"], ...data.data["-"]].sort((a, b) => {
+        return +new Date(b.creationTime) - +new Date(a.creationTime);
+      });
+      //   tablePage.total = dataSource.value.length;
+    }
+  });
+};
+getPageInfo();
+
+// // 分页设置
+// const handleCurrentChange = (val: any) => {
+//   dataShowSource.value = [...dataSortSource.value.slice((val.current - 1) * val.limit, val.current * val.limit)];
+// };
+
+// // 排序
+// const handleSortChange = (key: any, sort: any) => {
+//   sortInfo.value = { key, sort };
+//   if (!sort) {
+//     dataSortSource.value = [...dataSource.value];
+//     dataShowSource.value = [...dataSource.value.slice((tablePage.current - 1) * tablePage.limit, tablePage.current * tablePage.limit)];
+//     return;
+//   }
+//   dataSortSource.value = [...dataSource.value].sort((a: any, b: any) => {
+//     let maxA = -9999999;
+//     let maxB = -9999999;
+//     Object.values(a[key]).map((item) => (maxA = Number(item) > maxA ? Number(item) : maxA));
+//     Object.values(b[key]).map((item) => (maxB = Number(item) > maxB ? Number(item) : maxB));
+//     return maxA - maxB;
+//   });
+//   if (sort == "desc") dataSortSource.value.reverse();
+//   dataShowSource.value = [...dataSortSource.value.slice((tablePage.current - 1) * tablePage.limit, tablePage.current * tablePage.limit)];
+// };
+</script>

+ 0 - 1
src/views/indicator/sybmol_filter/index.vue

@@ -164,7 +164,6 @@ const getIaExchanges = () => {
     pageConfig.loading = false;
     if (data.code == 200) {
       iaExchanges.value = data.data;
-      pageParams.exchanges = data.data;
     }
   });
 };

+ 4 - 1
src/views/server/manage/index.vue

@@ -121,7 +121,10 @@ let selectedKeys = ref([]);
 
 // 请求交易所列表
 const getPageInfo = (isSearch?: boolean) => {
-  if (isSearch) pageParams.pageNum = 1;
+  if (isSearch) {
+    pageParams.pageNum = 1;
+    selectedKeys.value = [];
+  }
   pageConfig.loading = true;
   get_server_list(pageParams, (data: any) => {
     pageConfig.loading = false;

+ 181 - 87
src/views/statistic/balance_user/index.vue

@@ -4,31 +4,39 @@
       <span class="card-title">资金曲线-按用户</span>
     </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="rangeTime">
-            <lay-date-picker v-model="pageParams.rangeTime" range type="datetime" :placeholder="['开始日期', '结束日期']" />
-          </lay-form-item>
-          <lay-form-item label="统计间隔" prop="granularity">
-            <lay-input v-model="pageParams.granularity" />
-          </lay-form-item>
-          <div class="form-button-wp">
-            <lay-button @click="getUserBalanceData()">查询</lay-button>
-          </div>
-          <lay-form-item>
-            <lay-button-group>
-              <lay-button type="default" @click="handleRangeTime(1)">本日</lay-button>
-              <lay-button type="default" @click="handleRangeTime(2)">本周</lay-button>
-              <lay-button type="default" @click="handleRangeTime(3)">本月</lay-button>
-            </lay-button-group>
-          </lay-form-item>
-        </lay-form>
-      </div>
-      <div>
-        <lay-loading :loading="pageConfig.loading">
+      <lay-loading class="custom-loading" :loading="pageConfig.loading">
+        <div class="custom-form-layout">
+          <lay-form class="form-wp" :model="pageParams" mode="inline" size="sm">
+            <lay-form-item label="查询时间" prop="rangeTime">
+              <lay-date-picker v-model="pageParams.rangeTime" range type="datetime" :placeholder="['开始日期', '结束日期']" />
+            </lay-form-item>
+            <lay-form-item label="统计间隔" prop="granularity">
+              <lay-input v-model="pageParams.granularity" />
+            </lay-form-item>
+            <div class="form-button-wp">
+              <lay-button @click="getUserBalanceData()">查询</lay-button>
+            </div>
+            <lay-form-item>
+              <lay-button-group>
+                <lay-button type="default" @click="handleRangeTime(1)">本日</lay-button>
+                <lay-button type="default" @click="handleRangeTime(2)">本周</lay-button>
+                <lay-button type="default" @click="handleRangeTime(3)">本月</lay-button>
+                <lay-button type="default" @click="handleRangeTime(4)">上月</lay-button>
+              </lay-button-group>
+            </lay-form-item>
+            <lay-form-item>
+              <lay-button-group>
+                <lay-button type="default" @click="initChart(balanceData, 1)">按收益率</lay-button>
+                <lay-button type="default" @click="initChart(balanceData, 2)">按收益</lay-button>
+                <lay-button type="default" @click="initChart(balanceData, 3)">按资金</lay-button>
+              </lay-button-group>
+            </lay-form-item>
+          </lay-form>
+        </div>
+        <div>
           <div class="chart" ref="balanceChartRef"></div>
-        </lay-loading>
-      </div>
+        </div>
+      </lay-loading>
     </template>
   </lay-card>
 </template>
@@ -39,7 +47,7 @@ import * as echarts from "echarts";
 import dayjs from "dayjs";
 import isoWeek from "dayjs/plugin/isoWeek";
 import Decimal from "decimal.js";
-import { get_user_balance, get_user_list_all } from "@/api";
+import { get_user_balance } from "@/api";
 
 dayjs.extend(isoWeek);
 
@@ -60,32 +68,63 @@ let pageConfig: PageConfig = reactive({
 const pageParams: FormItem = reactive({ rangeTime: [dayjs().subtract(24, "hour").format("YYYY-MM-DD HH:mm:ss"), dayjs().format("YYYY-MM-DD HH:mm:ss")], granularity: 60 });
 
 let balanceChart = shallowRef();
-let userList = ref();
+let balanceData = ref();
+let earningsRateData = ref<Array<any>>([]);
+let earningsData = ref<Array<any>>([]);
+let totalBalanceData = ref<Array<any>>([]);
 
 const getUserBalanceData = () => {
+  balanceData.value = [];
+  earningsRateData.value = [];
+  earningsData.value = [];
+  totalBalanceData.value = [];
   const params = {
     startTime: +dayjs(pageParams.rangeTime[0]),
     endTime: +dayjs(pageParams.rangeTime[1]),
     granularity: pageParams.granularity,
   };
   pageConfig.loading = true;
-  get_user_balance(params, (data: any) => {
+  get_user_balance(params, async (data: any) => {
     pageConfig.loading = false;
     if (data.code == 200) {
-      initChart(data.data);
+      balanceData.value = data.data;
+      await handleBalanceData(data.data);
+      initChart(balanceData.value, 1);
     }
   });
 };
 getUserBalanceData();
 
-// 获取用户列表
-const getUserList = () => {
-  const params = {};
-  get_user_list_all(params, (data: any) => {
-    userList.value = data.data;
+const handleBalanceData = (data: any) => {
+  return new Promise((resolve: any) => {
+    // 过滤无效数据
+    balanceData.value = { ...data, userList: data.userList.filter((item: any) => item.balance.length > 0) };
+    balanceData.value.userList.map((item: any) => {
+      let earningList: any = [];
+      let earningRateList: any = [];
+      let lastBalance = 0;
+      let transferBalance = 0;
+      item.balance.map((items: any) => {
+        const isTransfer = new Decimal(items || 0)
+          .minus(lastBalance || 0)
+          .mod(50)
+          .toNumber();
+        if (!isTransfer && items != lastBalance) transferBalance += items - lastBalance;
+        lastBalance = items;
+        let totalBalance = item.balance[0] + transferBalance;
+        let earning = new Decimal(items || 0).minus(totalBalance || 0);
+        let earningRate = earning.div(totalBalance || 1).mul(100);
+        earningList.push(earning.toNumber());
+        earningRateList.push(earningRate.toNumber());
+      });
+
+      earningsData.value.push({ name: item.name, type: "line", stack: item.name, data: earningList });
+      earningsRateData.value.push({ name: item.name, type: "line", stack: item.name, data: earningRateList });
+      totalBalanceData.value.push({ name: item.name, type: "line", stack: item.name, data: item.balance });
+    });
+    resolve(true);
   });
 };
-getUserList();
 
 const handleRangeTime = (type: number) => {
   switch (type) {
@@ -98,75 +137,130 @@ const handleRangeTime = (type: number) => {
     case 3:
       pageParams.rangeTime = [`${dayjs().startOf("month").hour(10).minute(0).second(0).millisecond(0)}`, `${dayjs()}`];
       break;
+    case 4:
+      let upMonthTime = +dayjs().startOf("month") - 1;
+      pageParams.rangeTime = [`${dayjs(upMonthTime).startOf("month").hour(10).minute(0).second(0).millisecond(0)}`, `${dayjs().startOf("month").hour(10).minute(0).second(0).millisecond(0)}`];
+      break;
   }
   getUserBalanceData();
 };
 
-const initChart = (data: any) => {
+const initChart = (data: any, type: number) => {
+  if (balanceChart.value != null && !balanceChart.value.isDisposed()) echarts.dispose(balanceChart.value);
   balanceChart.value = echarts.init(balanceChartRef.value);
 
   window.removeEventListener("resize", () => balanceChart.value.resize());
   window.addEventListener("resize", () => balanceChart.value.resize());
 
   const xData = data.timeList.map((item: any) => dayjs(item * 1).format("MM-DD HH:mm"));
-  const sData = data.userList.filter((item: any) => item.balance.length > 0);
-  const legendData = sData.map((item: any) => item.name);
-  let yMax = -9999999;
-  let yMin = 9999999;
-  const seriesData = sData.map((item: any) => {
-    const balanceList = item.balance.map((items: any) => {
-      let percent = new Decimal(items || 0)
-        .minus(item.balance[0] || 0)
-        .div(item.balance[0] || 1)
-        .mul(100)
-        .add(100)
-        .toNumber();
-      yMax = percent > yMax ? percent : yMax;
-      yMin = percent < yMin ? percent : yMin;
-      return percent;
-    });
-    return { name: item.name, type: "line", data: balanceList };
-  });
-
-  const balanceChartOption = {
-    tooltip: {
-      trigger: "axis",
-      formatter: (value: any) => {
-        const axisLabel = `${value[0].axisValueLabel}`;
-        const info = value.map((item: any) => `${item.marker}${item.seriesName}: ${item.data.toFixed(2)}%`);
-        return `${axisLabel}<br/>${info.join("<br/>")}`;
+  const legendData = data.userList.map((item: any) => item.name);
+  if (type == 1) {
+    const earningsRateOption = {
+      tooltip: {
+        trigger: "axis",
+        formatter: (value: any) => {
+          const axisLabel = `${value[0].axisValueLabel}`;
+          const info = value.map((item: any) => `${item.marker}${item.seriesName}: ${item.data.toFixed(2)}%`);
+          return `${axisLabel}<br/>${info.join("<br/>")}`;
+        },
       },
-    },
-    toolbox: {
-      feature: {
-        dataZoom: {},
-        brush: {
-          type: ["rect", "clear"],
+      toolbox: {
+        feature: {
+          dataZoom: {},
+          brush: {
+            type: ["rect", "clear"],
+          },
         },
       },
-    },
-    legend: {
-      data: legendData,
-      top: "bottom",
-    },
-    xAxis: {
-      type: "category",
-      data: xData,
-    },
-    yAxis: {
-      type: "value",
-      max: yMax + 1,
-      min: yMin - 1,
-      axisLabel: {
+      legend: {
+        data: legendData,
+        top: "bottom",
+      },
+      xAxis: {
+        type: "category",
+        data: xData,
+      },
+      yAxis: {
+        type: "value",
+        min: "dataMin",
+        axisLabel: {
+          formatter: (value: any) => {
+            return `${value.toFixed(2)}%`;
+          },
+        },
+      },
+      series: earningsRateData.value,
+    };
+    balanceChart.value.setOption(earningsRateOption);
+  }
+  if (type == 2) {
+    const earningsOption = {
+      tooltip: {
+        trigger: "axis",
         formatter: (value: any) => {
-          return `${value.toFixed(2)}%`;
+          const axisLabel = `${value[0].axisValueLabel}`;
+          const info = value.map((item: any) => `${item.marker}${item.seriesName}: ${item.data}`);
+          return `${axisLabel}<br/>${info.join("<br/>")}`;
         },
       },
-      scale: true,
-    },
-    series: seriesData,
-  };
-  balanceChart.value.setOption(balanceChartOption);
+      toolbox: {
+        feature: {
+          dataZoom: {},
+          brush: {
+            type: ["rect", "clear"],
+          },
+        },
+      },
+      legend: {
+        data: legendData,
+        top: "bottom",
+      },
+      xAxis: {
+        type: "category",
+        data: xData,
+      },
+      yAxis: {
+        type: "value",
+        min: "dataMin",
+      },
+      series: earningsData.value,
+    };
+    balanceChart.value.setOption(earningsOption);
+  }
+  if (type == 3) {
+    const earningsOption = {
+      tooltip: {
+        trigger: "axis",
+        formatter: (value: any) => {
+          const axisLabel = `${value[0].axisValueLabel}`;
+          const info = value.map((item: any) => `${item.marker}${item.seriesName}: ${item.data}`);
+          return `${axisLabel}<br/>${info.join("<br/>")}`;
+        },
+      },
+      toolbox: {
+        feature: {
+          dataZoom: {},
+          brush: {
+            type: ["rect", "clear"],
+          },
+        },
+      },
+      legend: {
+        data: legendData,
+        top: "bottom",
+      },
+      xAxis: {
+        type: "category",
+        data: xData,
+      },
+      yAxis: {
+        type: "value",
+        min: "dataMin",
+      },
+      series: totalBalanceData.value,
+    };
+    balanceChart.value.setOption(earningsOption);
+  }
 };
 
 onUnmounted(() => {