Browse Source

ltv按月

ith5 5 months ago
parent
commit
67a8c017bb

+ 10 - 0
src/views/v1/api/gameLog/channelAnalysis.js

@@ -64,5 +64,15 @@ export default {
       method: 'get',
       params
     })
+  },
+  /**
+   * LTVM
+   */
+  getLtvMDataList(params = {}) {
+    return request({
+      url: '/v1/gameLog/channelAnalysis/getLtvmDataList',
+      method: 'get',
+      params
+    })
   }
 }

+ 52 - 70
src/views/v1/center/qxSwitch/edit.vue

@@ -7,38 +7,20 @@
     :mask-closable="false"
     :ok-loading="loading"
     @cancel="close"
-    @before-ok="submit"
-  >
+    @before-ok="submit">
     <!-- 表单信息 start -->
-    <a-form
-      ref="formRef"
-      :model="formData"
-      :rules="rules"
-      :auto-label-width="true"
-    >
+    <a-form ref="formRef" :model="formData" :rules="rules" :auto-label-width="true">
       <a-form-item label="包名" field="package_name">
         <a-input v-model="formData.package_name" placeholder="请输入包名" />
       </a-form-item>
-      <a-form-item label="咨询允许获得" field="qx">
-        <sa-switch
-          v-model="formData.qx"
-          checkedText="开启"
-          uncheckedText="关闭"
-        />
+      <a-form-item label="咨询允许获得权限" field="qx">
+        <sa-switch v-model="formData.qx" checkedText="开启" uncheckedText="关闭" />
       </a-form-item>
       <a-form-item label="隐私弹窗" field="ystc">
-        <sa-switch
-          v-model="formData.ystc"
-          checkedText="开启"
-          uncheckedText="关闭"
-        />
+        <sa-switch v-model="formData.ystc" checkedText="开启" uncheckedText="关闭" />
       </a-form-item>
       <a-form-item label="登录框同意勾选文案" field="init">
-        <sa-switch
-          v-model="formData.init"
-          checkedText="开启"
-          uncheckedText="关闭"
-        />
+        <sa-switch v-model="formData.init" checkedText="开启" uncheckedText="关闭" />
       </a-form-item>
     </a-form>
     <!-- 表单信息 end -->
@@ -46,94 +28,94 @@
 </template>
 
 <script setup>
-import { ref, reactive, computed } from "vue";
-import tool from "@/utils/tool";
-import { Message, Modal } from "@arco-design/web-vue";
-import api from "../../api/center/qxSwitch";
+import { ref, reactive, computed } from 'vue'
+import tool from '@/utils/tool'
+import { Message, Modal } from '@arco-design/web-vue'
+import api from '../../api/center/qxSwitch'
 
-const emit = defineEmits(["success"]);
+const emit = defineEmits(['success'])
 // 引用定义
-const visible = ref(false);
-const loading = ref(false);
-const formRef = ref();
-const mode = ref("");
+const visible = ref(false)
+const loading = ref(false)
+const formRef = ref()
+const mode = ref('')
 
 let title = computed(() => {
-  return "权限开关" + (mode.value == "add" ? "-新增" : "-编辑");
-});
+  return '权限开关' + (mode.value == 'add' ? '-新增' : '-编辑')
+})
 
 // 表单初始值
 const initialFormData = {
   id: null,
-  package_name: "",
+  package_name: '',
   qx: 1,
   ystc: 1,
   init: 1,
-};
+}
 
 // 表单信息
-const formData = reactive({ ...initialFormData });
+const formData = reactive({ ...initialFormData })
 
 // 验证规则
 const rules = {
-  package_name: [{ required: true, message: "包名必需填写" }],
-  qx: [{ required: true, message: "咨询允许获得必需填写" }],
-  ystc: [{ required: true, message: "隐私弹窗必需填写" }],
-  init: [{ required: true, message: "登录框同意勾选文案必需填写" }],
-};
+  package_name: [{ required: true, message: '包名必需填写' }],
+  qx: [{ required: true, message: '咨询允许获得权限必需填写' }],
+  ystc: [{ required: true, message: '隐私弹窗必需填写' }],
+  init: [{ required: true, message: '登录框同意勾选文案必需填写' }],
+}
 
 // 打开弹框
-const open = async (type = "add") => {
-  mode.value = type;
+const open = async (type = 'add') => {
+  mode.value = type
   // 重置表单数据
-  Object.assign(formData, initialFormData);
-  formRef.value.clearValidate();
-  visible.value = true;
-  await initPage();
-};
+  Object.assign(formData, initialFormData)
+  formRef.value.clearValidate()
+  visible.value = true
+  await initPage()
+}
 
 // 初始化页面数据
-const initPage = async () => {};
+const initPage = async () => {}
 
 // 设置数据
 const setFormData = async (data) => {
   for (const key in formData) {
     if (data[key] != null && data[key] != undefined) {
-      formData[key] = data[key];
+      formData[key] = data[key]
     }
   }
-};
+}
 
 // 数据保存
 const submit = async (done) => {
-  const validate = await formRef.value?.validate();
+  const validate = await formRef.value?.validate()
   if (!validate) {
-    loading.value = true;
-    let data = { ...formData };
-    let result = {};
-    if (mode.value === "add") {
+    loading.value = true
+    let data = { ...formData }
+    let result = {}
+    if (mode.value === 'add') {
       // 添加数据
-      data.id = undefined;
-      result = await api.save(data);
+      data.id = undefined
+      result = await api.save(data)
     } else {
       // 修改数据
-      result = await api.update(data.id, data);
+      result = await api.update(data.id, data)
     }
     if (result.code === 200) {
-      Message.success("操作成功");
-      emit("success");
-      done(true);
+      Message.success('操作成功')
+      emit('success')
+      done(true)
     }
     // 防止连续点击提交
     setTimeout(() => {
-      loading.value = false;
-    }, 500);
+      loading.value = false
+    }, 500)
   }
-  done(false);
-};
+  done(false)
+}
 
 // 关闭弹窗
-const close = () => (visible.value = false);
+const close = () => (visible.value = false)
 
-defineExpose({ open, setFormData });
+defineExpose({ open, setFormData })
 </script>

+ 39 - 51
src/views/v1/center/qxSwitch/index.vue

@@ -1,20 +1,11 @@
 <template>
   <div class="ma-content-block">
-    <sa-table
-      ref="crudRef"
-      :options="options"
-      :columns="columns"
-      :searchForm="searchForm"
-    >
+    <sa-table ref="crudRef" :options="options" :columns="columns" :searchForm="searchForm">
       <!-- 搜索区 tableSearch -->
       <template #tableSearch>
         <a-col :sm="8" :xs="24">
           <a-form-item label="包名" field="package_name">
-            <a-input
-              v-model="searchForm.package_name"
-              placeholder="请输入包名"
-              allow-clear
-            />
+            <a-input v-model="searchForm.package_name" placeholder="请输入包名" allow-clear />
           </a-form-item>
         </a-col>
       </template>
@@ -25,24 +16,21 @@
           checkedText="开启"
           uncheckedText="关闭"
           v-model="record.qx"
-          @change="changeStatus($event, record, 'qx')"
-        />
+          @change="changeStatus($event, record, 'qx')" />
       </template>
       <template #ystc="{ record }">
         <sa-switch
           checkedText="开启"
           uncheckedText="关闭"
           v-model="record.ystc"
-          @change="changeStatus($event, record, 'ystc')"
-        />
+          @change="changeStatus($event, record, 'ystc')" />
       </template>
       <template #init="{ record }">
         <sa-switch
           checkedText="开启"
           uncheckedText="关闭"
           v-model="record.init"
-          @change="changeStatus($event, record, 'init')"
-        />
+          @change="changeStatus($event, record, 'init')" />
       </template>
     </sa-table>
 
@@ -52,32 +40,32 @@
 </template>
 
 <script setup>
-import { onMounted, ref, reactive } from "vue";
-import { Message } from "@arco-design/web-vue";
-import EditForm from "./edit.vue";
-import api from "../../api/center/qxSwitch";
+import { onMounted, ref, reactive } from 'vue'
+import { Message } from '@arco-design/web-vue'
+import EditForm from './edit.vue'
+import api from '../../api/center/qxSwitch'
 
 // 引用定义
-const crudRef = ref();
-const editRef = ref();
-const viewRef = ref();
+const crudRef = ref()
+const editRef = ref()
+const viewRef = ref()
 
 // 搜索表单
 const searchForm = ref({
-  package_name: "",
-});
+  package_name: '',
+})
 
 // 修改状态
 const changeStatus = async (status, record, field) => {
   const response = await api.update(record.id, {
     ...record,
     [field]: status,
-  });
+  })
   if (response.code === 200) {
-    Message.success(response.message);
-    crudRef.value.refresh();
+    Message.success(response.message)
+    crudRef.value.refresh()
   }
-};
+}
 
 // SaTable 基础配置
 const options = reactive({
@@ -85,51 +73,51 @@ const options = reactive({
   rowSelection: { showCheckedAll: true },
   add: {
     show: true,
-    auth: ["/v1/center/QxSwitch/save"],
+    auth: ['/v1/center/QxSwitch/save'],
     func: async () => {
-      editRef.value?.open();
+      editRef.value?.open()
     },
   },
   edit: {
     show: true,
-    auth: ["/v1/center/QxSwitch/update"],
+    auth: ['/v1/center/QxSwitch/update'],
     func: async (record) => {
-      editRef.value?.open("edit");
-      editRef.value?.setFormData(record);
+      editRef.value?.open('edit')
+      editRef.value?.setFormData(record)
     },
   },
   delete: {
     show: true,
-    auth: ["/v1/center/QxSwitch/destroy"],
+    auth: ['/v1/center/QxSwitch/destroy'],
     func: async (params) => {
-      const resp = await api.destroy(params);
+      const resp = await api.destroy(params)
       if (resp.code === 200) {
-        Message.success(`删除成功!`);
-        crudRef.value?.refresh();
+        Message.success(`删除成功!`)
+        crudRef.value?.refresh()
       }
     },
   },
-});
+})
 
 // SaTable 列配置
 const columns = reactive([
-  { title: "包名", dataIndex: "package_name", width: 180 },
-  { title: "咨询允许获得", dataIndex: "qx", width: 180 },
-  { title: "隐私弹窗", dataIndex: "ystc", width: 180 },
-  { title: "登录框同意勾选文案", dataIndex: "init", width: 180 },
-]);
+  { title: '包名', dataIndex: 'package_name', width: 180 },
+  { title: '咨询允许获得权限', dataIndex: 'qx', width: 180 },
+  { title: '隐私弹窗', dataIndex: 'ystc', width: 180 },
+  { title: '登录框同意勾选文案', dataIndex: 'init', width: 180 },
+])
 
 // 页面数据初始化
-const initPage = async () => {};
+const initPage = async () => {}
 
 // SaTable 数据请求
 const refresh = async () => {
-  crudRef.value?.refresh();
-};
+  crudRef.value?.refresh()
+}
 
 // 页面加载完成执行
 onMounted(async () => {
-  initPage();
-  refresh();
-});
+  initPage()
+  refresh()
+})
 </script>

+ 273 - 0
src/views/v1/gameLog/ltvm/index.vue

@@ -0,0 +1,273 @@
+<template>
+  <div class="ma-content-block">
+    <sa-table ref="crudRef" :options="options" :columns="columns" :searchForm="searchForm">
+      <!-- 搜索区 tableSearch -->
+      <template #tableSearch>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="游戏" field="game_id">
+            <game-select v-model="searchForm.game_id" multiple />
+          </a-form-item>
+        </a-col>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="注册日期" field="reg_date">
+            <a-range-picker class="w-full" v-model="searchForm.reg_date" :show-time="false" mode="month" />
+          </a-form-item>
+        </a-col>
+
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="渠道ID" field="agent_id">
+            <a-input v-model="searchForm.agent_id" placeholder="请输入渠道ID" allow-clear />
+          </a-form-item>
+        </a-col>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="渠道名称" field="agent_name">
+            <a-input v-model="searchForm.agent_name" placeholder="请输入渠道名称" allow-clear />
+          </a-form-item>
+        </a-col>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="广告位ID" field="site_id">
+            <a-input v-model="searchForm.site_id" placeholder="请输入广告位ID" allow-clear />
+          </a-form-item>
+        </a-col>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="广告名称" field="site_name">
+            <a-input v-model="searchForm.site_name" placeholder="请输入广告名称" allow-clear />
+          </a-form-item>
+        </a-col>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="负责人" field="auth_id">
+            <auth-select v-model="searchForm.auth_id" />
+          </a-form-item>
+        </a-col>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="媒体类型" field="media_id">
+            <media-select v-model="searchForm.media_id" />
+          </a-form-item>
+        </a-col>
+        <a-col :sm="8" :xs="24">
+          <a-form-item label="展示类型" field="data_type">
+            <a-select v-model="searchForm.data_type" placeholder="请选择展示类型" :allow-clear="false">
+              <a-option value="recovery">回本率</a-option>
+              <a-option value="remount">实际回本率</a-option>
+              <a-option value="ltv">LTV</a-option>
+              <a-option value="pay_num">付费人数</a-option>
+              <a-option value="pay_total">付费总额</a-option>
+              <a-option value="pay_rate">付费率</a-option>
+              <a-option value="arpu"> 付费ARPU </a-option>
+            </a-select>
+          </a-form-item>
+        </a-col>
+      </template>
+
+      <!-- Table 自定义渲染 -->
+    </sa-table>
+  </div>
+</template>
+
+<script setup>
+import { onMounted, ref, reactive } from 'vue'
+import api from '../../api/gameLog/channelAnalysis'
+import dayjs from 'dayjs'
+import GameSelect from '@/components/game-select/index.vue'
+import MediaSelect from '@/components/media-select/index.vue'
+
+import AuthSelect from '@/components/auth-select/index.vue'
+
+// 引用定义
+const crudRef = ref()
+const gameList = ref([])
+
+// 搜索表单
+const searchForm = ref({
+  game_id: '',
+  media_id: '',
+  auth_id: '',
+  agent_id: '',
+  agent_name: '',
+  site_name: '',
+  site_id: '',
+  reg_date: [],
+  data_type: 'recovery',
+})
+
+// SaTable 基础配置
+const options = reactive({
+  api: api.getLtvMDataList,
+  pk: 'tmonth',
+  rowSelection: { showCheckedAll: true },
+  showSort: false,
+  showSummary: true,
+  summary: [
+    {
+      action: 'totalRow',
+      dataIndex: 'tmonth',
+    },
+    {
+      suffixText: '元',
+      action: 'totalRow',
+      dataIndex: 'cost',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'reg_total',
+    },
+
+    {
+      action: 'totalRow',
+      dataIndex: 'reg_cost',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm0',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm1',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm2',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm3',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm4',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm5',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm6',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm7',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm8',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm9',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm10',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm11',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm12',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm13',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm14',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm15',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm16',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm17',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm18',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm19',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm20',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm21',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm22',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm23',
+    },
+    {
+      action: 'totalRow',
+      dataIndex: 'm24',
+    },
+  ],
+
+  operationColumn: false,
+})
+
+// SaTable 列配置
+const columns = reactive([
+  { title: '日期', dataIndex: 'tmonth', width: 130, fixed: 'left' },
+  { title: '消耗金额', dataIndex: 'cost', width: 100 },
+
+  { title: '注册数', dataIndex: 'reg_total', width: 80 },
+  { title: '注册成本', dataIndex: 'reg_cost', width: 100 },
+  { title: '累计', dataIndex: 'm0', width: 80 },
+  { title: '1', dataIndex: 'm1', width: 80 },
+  { title: '2', dataIndex: 'm2', width: 80 },
+  { title: '3', dataIndex: 'm3', width: 80 },
+  { title: '4', dataIndex: 'm4', width: 80 },
+  { title: '5', dataIndex: 'm5', width: 80 },
+  { title: '6', dataIndex: 'm6', width: 80 },
+  { title: '7', dataIndex: 'm7', width: 80 },
+  { title: '8', dataIndex: 'm8', width: 80 },
+  { title: '9', dataIndex: 'm9', width: 80 },
+  { title: '10', dataIndex: 'm10', width: 80 },
+  { title: '11', dataIndex: 'm11', width: 80 },
+  { title: '12', dataIndex: 'm12', width: 80 },
+  { title: '13', dataIndex: 'm13', width: 80 },
+  { title: '14', dataIndex: 'm14', width: 80 },
+  { title: '15', dataIndex: 'm15', width: 80 },
+  { title: '16', dataIndex: 'm16', width: 80 },
+  { title: '17', dataIndex: 'm17', width: 80 },
+  { title: '18', dataIndex: 'm18', width: 80 },
+  { title: '19', dataIndex: 'm19', width: 80 },
+  { title: '20', dataIndex: 'm20', width: 80 },
+  { title: '21', dataIndex: 'm21', width: 80 },
+  { title: '22', dataIndex: 'm22', width: 80 },
+  { title: '23', dataIndex: 'm23', width: 80 },
+  { title: '24', dataIndex: 'm24', width: 80 },
+])
+
+// 页面数据初始化
+const initPage = () => {
+  searchForm.value.reg_date = [dayjs().format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD')]
+}
+
+// SaTable 数据请求
+const refresh = async () => {
+  crudRef.value?.refresh()
+}
+
+// 页面加载完成执行
+onMounted(async () => {
+  initPage()
+  refresh()
+})
+</script>