|
|
@@ -0,0 +1,527 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <div class="gva-search-box">
|
|
|
+ <div class="gva-btn-list">
|
|
|
+ <el-form ref="searchForm" :inline="true" :model="searchInfo">
|
|
|
+ <el-form-item label="任务Id">
|
|
|
+ <el-input v-model="searchInfo.task_id" placeholder="任务ID" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="负责人">
|
|
|
+ <el-input v-model="searchInfo.director_name" placeholder="负责人" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="日期" prop="date">
|
|
|
+ <el-date-picker
|
|
|
+ v-model="searchInfo.date"
|
|
|
+ size="default"
|
|
|
+ type="daterange"
|
|
|
+ unlink-panels
|
|
|
+ range-separator="至"
|
|
|
+ start-placeholder="开始日期"
|
|
|
+ end-placeholder="结束日期"
|
|
|
+ :disabled-date="disabledDate"
|
|
|
+ :shortcuts="shortcuts"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ icon="search"
|
|
|
+ @click="onSubmit"
|
|
|
+ >查询</el-button
|
|
|
+ >
|
|
|
+ <el-button size="small" icon="refresh" @click="onReset"
|
|
|
+ >重置</el-button
|
|
|
+ >
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="gva-table-box" style="padding: 0">
|
|
|
+ <el-table
|
|
|
+ :data="tableData"
|
|
|
+ border
|
|
|
+ style="width: 100%; cursor: pointer"
|
|
|
+ stripe
|
|
|
+ align="center"
|
|
|
+ header-align="center"
|
|
|
+ size="mini"
|
|
|
+ :default-sort="{ prop: 'task_id', order: 'ascending' }"
|
|
|
+ v-loading="loading"
|
|
|
+ >
|
|
|
+ <el-table-column type="index" label="#" min-width="10" fixed="left" />
|
|
|
+ <el-table-column
|
|
|
+ fixed="left"
|
|
|
+ prop="task_id"
|
|
|
+ label="任务ID"
|
|
|
+ min-width="80"
|
|
|
+ sortable
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ fixed="left"
|
|
|
+ prop="task_name"
|
|
|
+ label="任务名称"
|
|
|
+ min-width="100"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ fixed="left"
|
|
|
+ prop="director_name"
|
|
|
+ label="负责人"
|
|
|
+ min-width="80"
|
|
|
+ sortable
|
|
|
+ />
|
|
|
+ <el-table-column label="留存账号" align="center">
|
|
|
+ <el-table-column prop="num_could_pay" align="center" label="能付费">
|
|
|
+ <template #default="scope">
|
|
|
+ {{ scope.row.num_account_lc }}
|
|
|
+ <!-- <br /> -->
|
|
|
+ <el-divider style="margin: 0" />
|
|
|
+ {{ scope.row.num_could_pay }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="num_frozen"
|
|
|
+ label="封号数"
|
|
|
+ min-width="60"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="num_pull_account"
|
|
|
+ label="下发账号"
|
|
|
+ min-width="70"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="num_start_script"
|
|
|
+ label="脚本启动"
|
|
|
+ min-width="70"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="num_start_simulator"
|
|
|
+ label="模拟器启动"
|
|
|
+ min-width="80"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="num_ip"
|
|
|
+ label="查询IP"
|
|
|
+ min-width="60"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="num_start_game"
|
|
|
+ label="启动游戏"
|
|
|
+ min-width="70"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="num_login_success"
|
|
|
+ label="账号登录"
|
|
|
+ min-width="70"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="num_into_game"
|
|
|
+ label="进入游戏"
|
|
|
+ min-width="70"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column label="活跃成功" align="center">
|
|
|
+ <el-table-column
|
|
|
+ prop="num_new_success"
|
|
|
+ label="新增成功"
|
|
|
+ min-width="70"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="num_lc_success"
|
|
|
+ label="留存成功"
|
|
|
+ min-width="70"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ prop="num_pay_success"
|
|
|
+ label="付费成功"
|
|
|
+ min-width="70"
|
|
|
+ align="center"
|
|
|
+ />
|
|
|
+ <el-table-column label="订单数" align="center">
|
|
|
+ <el-table-column label="付费成功" align="center">
|
|
|
+ <el-table-column
|
|
|
+ prop="num_order_pay,num_pay"
|
|
|
+ align="center"
|
|
|
+ label="成功率"
|
|
|
+ sortable
|
|
|
+ :sort-method="sortBySuccess1"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ {{ scope.row.step6 }}
|
|
|
+ <el-divider style="margin: 0" />
|
|
|
+ {{ scope.row.rate_pay_success }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="下发账号" align="center">
|
|
|
+ <el-table-column label="脚本启动" align="center">
|
|
|
+ <el-table-column
|
|
|
+ prop="num_pull_account,num_start_script"
|
|
|
+ align="center"
|
|
|
+ label="成功率"
|
|
|
+ sortable
|
|
|
+ :sort-method="sortBySuccess2"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ {{ scope.row.step2 }}
|
|
|
+ <el-divider style="margin: 0" />
|
|
|
+ {{ Math.round(scope.row.rate2 * 10000) / 100 + "%" }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="脚本启动" align="center">
|
|
|
+ <el-table-column label="进入游戏" align="center">
|
|
|
+ <el-table-column
|
|
|
+ prop="num_into_game,num_start_game"
|
|
|
+ label="成功率"
|
|
|
+ align="center"
|
|
|
+ sortable
|
|
|
+ :sort-method="sortBySuccess3"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ {{ scope.row.num_start_script }}
|
|
|
+ <el-divider style="margin: 0 5px" direction="vertical" />{{
|
|
|
+ scope.row.num_into_game
|
|
|
+ }}
|
|
|
+ <el-divider style="margin: 0" />
|
|
|
+ {{ Math.round(scope.row.rate3 * 10000) / 100 + "%" }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="脚本启动" align="center">
|
|
|
+ <el-table-column label="活跃成功" align="center">
|
|
|
+ <el-table-column
|
|
|
+ prop="num_start_script,num_active"
|
|
|
+ label="成功率"
|
|
|
+ align="center"
|
|
|
+ sortable
|
|
|
+ :sort-method="sortBySuccess4"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ {{ scope.row.num_start_script }}
|
|
|
+ <el-divider style="margin: 0 5px" direction="vertical" />{{
|
|
|
+ scope.row.num_active
|
|
|
+ }}
|
|
|
+ <el-divider style="margin: 0" />
|
|
|
+ {{ Math.round(scope.row.rate4 * 10000) / 100 + "%" }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="下发付费" align="center">
|
|
|
+ <el-table-column label="付费成功" align="center">
|
|
|
+ <el-table-column
|
|
|
+ prop="num_start_script,num_new_success,num_lc_success"
|
|
|
+ label="成功率"
|
|
|
+ align="center"
|
|
|
+ sortable
|
|
|
+ :sort-method="sortBySuccess5"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ {{ scope.row.num_pull_pay }}
|
|
|
+ <el-divider style="margin: 0 5px" direction="vertical" />{{
|
|
|
+ scope.row.num_pay_success
|
|
|
+ }}
|
|
|
+ <el-divider style="margin: 0" />
|
|
|
+ {{ Math.round(scope.row.rate5 * 10000) / 100 + "%" }}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table-column>
|
|
|
+ <!-- <el-table-column
|
|
|
+ fixed="right"
|
|
|
+ label="操作"
|
|
|
+ width="60"
|
|
|
+ align="center"
|
|
|
+ header-align="center"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ type="primary"
|
|
|
+ plain
|
|
|
+ @click="showSevenTab(scope.row)"
|
|
|
+ >7天</el-button
|
|
|
+ >
|
|
|
+ </template>
|
|
|
+ </el-table-column> -->
|
|
|
+ </el-table>
|
|
|
+ <div class="gva-pagination">
|
|
|
+ <el-pagination
|
|
|
+ :current-page="page"
|
|
|
+ :page-size="pageSize"
|
|
|
+ :page-sizes="[10, 20, 30, 50, 100]"
|
|
|
+ :total="total"
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
+ @size-change="handleSizeChange"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ name: "data_abnormal_rate",
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { queryAbnormalRate } from "@/api/data_abnormal_rate";
|
|
|
+import { useUserStore } from "@/pinia/modules/user";
|
|
|
+import { toSQLLine } from "@/utils/stringFun";
|
|
|
+import { ref } from "vue";
|
|
|
+import dayjs from "dayjs";
|
|
|
+import { ElMessage } from "element-plus";
|
|
|
+
|
|
|
+const page = ref(1);
|
|
|
+const total = ref(0);
|
|
|
+const pageSize = ref(100);
|
|
|
+const tableData = ref([]);
|
|
|
+let spanArr = [];
|
|
|
+const searchInfo = ref({});
|
|
|
+const userStore = useUserStore();
|
|
|
+const loading = ref(false);
|
|
|
+
|
|
|
+const disabledDate = (time) => {
|
|
|
+ return time.getTime() > Date.now();
|
|
|
+};
|
|
|
+
|
|
|
+const shortcuts = [
|
|
|
+ {
|
|
|
+ text: "今日",
|
|
|
+ value: () => {
|
|
|
+ const end = new Date();
|
|
|
+ const start = new Date();
|
|
|
+ return [start, end];
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: "最近一周",
|
|
|
+ value: () => {
|
|
|
+ const end = new Date();
|
|
|
+ const start = new Date();
|
|
|
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 7);
|
|
|
+ return [start, end];
|
|
|
+ },
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: "最近一月",
|
|
|
+ value: () => {
|
|
|
+ const end = new Date();
|
|
|
+ const start = new Date();
|
|
|
+ start.setTime(start.getTime() - 3600 * 1000 * 24 * 30);
|
|
|
+ return [start, end];
|
|
|
+ },
|
|
|
+ },
|
|
|
+];
|
|
|
+
|
|
|
+const getSpanArr = (data) => {
|
|
|
+ spanArr = [];
|
|
|
+ var pos = 0;
|
|
|
+ for (var i = 0; i < data.length; i++) {
|
|
|
+ if (i === 0) {
|
|
|
+ spanArr.push(1);
|
|
|
+ pos = 0;
|
|
|
+ } else {
|
|
|
+ if (data[i].pc_code === data[i - 1].pc_code) {
|
|
|
+ spanArr[pos] += 1;
|
|
|
+ spanArr.push(0);
|
|
|
+ } else {
|
|
|
+ spanArr.push(1);
|
|
|
+ pos = i;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 分页
|
|
|
+const handleSizeChange = (val) => {
|
|
|
+ pageSize.value = val;
|
|
|
+ getTableData();
|
|
|
+};
|
|
|
+const onReset = () => {
|
|
|
+ searchInfo.value = {};
|
|
|
+};
|
|
|
+const handleCurrentChange = (val) => {
|
|
|
+ page.value = val;
|
|
|
+ getTableData();
|
|
|
+};
|
|
|
+
|
|
|
+// 排序
|
|
|
+const sortChange = ({ prop, order }) => {
|
|
|
+ if (prop) {
|
|
|
+ if (prop === "id") {
|
|
|
+ prop = "id";
|
|
|
+ }
|
|
|
+ searchInfo.value.orderKey = toSQLLine(prop);
|
|
|
+ searchInfo.value.desc = order === "descending";
|
|
|
+ }
|
|
|
+ getTableData();
|
|
|
+};
|
|
|
+
|
|
|
+// 搜索
|
|
|
+const onSubmit = () => {
|
|
|
+ loading.value = true;
|
|
|
+ page.value = 1;
|
|
|
+ pageSize.value = 10;
|
|
|
+
|
|
|
+ if (typeof searchInfo.value.task_id != "undefined") {
|
|
|
+ searchInfo.value.task_id = Number(searchInfo.value.task_id);
|
|
|
+ }
|
|
|
+ if (typeof searchInfo.value.date != "undefined") {
|
|
|
+ searchInfo.value.date[0] = dayjs(searchInfo.value.date[0]).format(
|
|
|
+ "YYYY-MM-DD"
|
|
|
+ );
|
|
|
+ searchInfo.value.date[1] = dayjs(searchInfo.value.date[1]).format(
|
|
|
+ "YYYY-MM-DD"
|
|
|
+ );
|
|
|
+ }
|
|
|
+ if (
|
|
|
+ typeof searchInfo.value.date != "undefined" &&
|
|
|
+ searchInfo.value.date[0] != searchInfo.value.date[1] &&
|
|
|
+ searchInfo.value.date[1] == dayjs(new Date()).format("YYYY-MM-DD")
|
|
|
+ ) {
|
|
|
+ ElMessage({
|
|
|
+ message: "今日数据只可单独查询,已去掉今日数据",
|
|
|
+ type: "warning",
|
|
|
+ offset: 150,
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ // console.log(searchInfo.value);
|
|
|
+
|
|
|
+ getTableData();
|
|
|
+ loading.value = false;
|
|
|
+};
|
|
|
+
|
|
|
+// 查询
|
|
|
+const getTableData = async () => {
|
|
|
+ ElMessage({
|
|
|
+ message: "查询中,请稍等",
|
|
|
+ type: "success",
|
|
|
+ offset: 50,
|
|
|
+ });
|
|
|
+ const table = await queryAbnormalRate({
|
|
|
+ page: page.value,
|
|
|
+ pageSize: pageSize.value,
|
|
|
+ ...searchInfo.value,
|
|
|
+ });
|
|
|
+ if (table.code === 0) {
|
|
|
+ tableData.value = [];
|
|
|
+ const data = table.data.list;
|
|
|
+ if (data) {
|
|
|
+ data.forEach((e) => {
|
|
|
+ let rate2 = 0;
|
|
|
+ let rate3 = 0;
|
|
|
+ let rate4 = 0;
|
|
|
+ let rate5 = 0;
|
|
|
+ if (e.num_pull_account != 0) {
|
|
|
+ rate2 = e.num_start_script / e.num_pull_account;
|
|
|
+ }
|
|
|
+ if (e.num_start_script != 0) {
|
|
|
+ rate3 = e.num_into_game / e.num_start_script;
|
|
|
+ rate4 = (e.num_new_success + e.num_lc_success) / e.num_start_script;
|
|
|
+ }
|
|
|
+ if (e.num_pull_pay != 0) {
|
|
|
+ rate5 = e.num_pay_success / e.num_pull_pay;
|
|
|
+ }
|
|
|
+ let obj1 = {
|
|
|
+ task_id: e.task_id,
|
|
|
+ task_name: e.task_name,
|
|
|
+ director_name: e.director_name,
|
|
|
+ new_date: e.new_date,
|
|
|
+ num_frozen: e.num_frozen,
|
|
|
+ num_pull_account: e.num_pull_account,
|
|
|
+ num_start_simulator: e.num_start_simulator,
|
|
|
+ num_ip: e.num_ip,
|
|
|
+ num_start_script: e.num_start_script,
|
|
|
+ num_start_game: e.num_start_game,
|
|
|
+ num_login_success: e.num_login_success,
|
|
|
+ num_into_game: e.num_into_game,
|
|
|
+ num_new_success: e.num_new_success,
|
|
|
+ num_lc_success: e.num_lc_success,
|
|
|
+ num_pay_success: e.num_pay_success,
|
|
|
+ rate_all_step: Math.round(e.rate_all_step * 10000) / 100 + "%",
|
|
|
+ step2: e.num_pull_account + " | " + e.num_start_script,
|
|
|
+ num_active: e.num_new_success + e.num_lc_success,
|
|
|
+ num_pull_pay: e.num_pull_pay,
|
|
|
+ num_account_lc: e.num_account_lc,
|
|
|
+ num_could_pay: e.num_could_pay,
|
|
|
+ num_order_pay: e.num_order_pay,
|
|
|
+ num_pay: e.num_pay,
|
|
|
+ step6: e.num_order_pay + " | " + e.num_pay,
|
|
|
+ rate_pay_success: e.rate_pay_success,
|
|
|
+ rate2: rate2,
|
|
|
+ rate3: rate3,
|
|
|
+ rate4: rate4,
|
|
|
+ rate5: rate5,
|
|
|
+ };
|
|
|
+ tableData.value.push(obj1);
|
|
|
+ });
|
|
|
+ getSpanArr(table.data.list);
|
|
|
+ }
|
|
|
+ // console.log(tableData);
|
|
|
+ total.value = table.data.total;
|
|
|
+ page.value = table.data.page;
|
|
|
+ pageSize.value = table.data.pageSize;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+getTableData();
|
|
|
+
|
|
|
+function sortBySuccess1(obj1, obj2) {
|
|
|
+ let str1 = obj1.rate_pay_success;
|
|
|
+ let str2 = obj2.rate_pay_success;
|
|
|
+ // let arr1 = str1.split("/");
|
|
|
+ // let arr2 = str2.split("/");
|
|
|
+ return str1.replace("%", "") - str2.replace("%", "");
|
|
|
+}
|
|
|
+function sortBySuccess2(obj1, obj2) {
|
|
|
+ let num1 = obj1.rate2;
|
|
|
+ let num2 = obj2.rate2;
|
|
|
+ return num1 - num2;
|
|
|
+}
|
|
|
+function sortBySuccess3(obj1, obj2) {
|
|
|
+ let num1 = obj1.rate3;
|
|
|
+ let num2 = obj2.rate3;
|
|
|
+ return num1 - num2;
|
|
|
+}
|
|
|
+function sortBySuccess4(obj1, obj2) {
|
|
|
+ let num1 = obj1.rate4;
|
|
|
+ let num2 = obj2.rate4;
|
|
|
+ return num1 - num2;
|
|
|
+}
|
|
|
+function sortBySuccess5(obj1, obj2) {
|
|
|
+ let num1 = obj1.rate5;
|
|
|
+ let num2 = obj2.rate5;
|
|
|
+ return num1 - num2;
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.button-box {
|
|
|
+ padding: 10px 20px;
|
|
|
+ .el-button {
|
|
|
+ float: right;
|
|
|
+ }
|
|
|
+}
|
|
|
+.warning {
|
|
|
+ color: #dc143c;
|
|
|
+}
|
|
|
+</style>
|