Browse Source

注册按日

ith5 5 tháng trước cách đây
mục cha
commit
b33f2e66d4

+ 53 - 19
src/components/sa-table/index.vue

@@ -466,12 +466,18 @@ const getResponseData = () => {
 }
 
 const __summary = ({ data }) => {
-  if (options.value.showSummary && isArray(options.value.summary)) {
+  console.log('__summary 被调用,当前 options.summary:', options.value.summary)
+
+  if (options.value.showSummary && isArray(options.value.summary) && options.value.summary.length > 0) {
     const summary = options.value.summary
     let summaryData = {}
     let summaryPrefixText = {}
     let summarySuffixText = {}
     let length = data.length || 0
+
+    console.log('__summary 被调用,summary 配置:', summary)
+    console.log('tableData.totalRow:', tableData.totalRow)
+
     summary.map((item) => {
       if (item.action && item.action === 'text') {
         summaryData[item.dataIndex] = item.text
@@ -479,29 +485,36 @@ const __summary = ({ data }) => {
         summaryData[item.dataIndex] = 0
         summaryPrefixText[item.dataIndex] = item?.prefixText ?? ''
         summarySuffixText[item.dataIndex] = item?.suffixText ?? ''
-        data.map((record) => {
-          if (record[item.dataIndex]) {
-            if (item.action && item.action === 'sum') {
-              summaryData[item.dataIndex] += parseFloat(record[item.dataIndex])
-            }
-            if (item.action && item.action === 'avg') {
-              summaryData[item.dataIndex] += parseFloat(record[item.dataIndex]) / length
-            }
-            if (item.action && item.action === 'totalRow') {
-              summaryData[item.dataIndex] = tableData.totalRow[item.dataIndex]
-              console.log('summaryData====>', summaryData)
-            }
+
+        if (item.action && item.action === 'totalRow') {
+          // 检查 totalRow 数据是否存在
+          if (tableData.totalRow && typeof tableData.totalRow === 'object') {
+            summaryData[item.dataIndex] = tableData.totalRow[item.dataIndex] || 0
+            console.log(`totalRow[${item.dataIndex}]:`, tableData.totalRow[item.dataIndex])
+          } else {
+            console.log('tableData.totalRow 不存在或格式不正确:', tableData.totalRow)
+            summaryData[item.dataIndex] = 0
           }
-        })
+        } else {
+          data.map((record) => {
+            if (record[item.dataIndex]) {
+              if (item.action && item.action === 'sum') {
+                summaryData[item.dataIndex] += parseFloat(record[item.dataIndex])
+              }
+              if (item.action && item.action === 'avg') {
+                summaryData[item.dataIndex] += parseFloat(record[item.dataIndex]) / length
+              }
+            }
+          })
+        }
       }
     })
 
-    // for (let i in summaryData) {
-    //   if (/^\d+(\.\d+)?$/.test(summaryData[i])) {
-    //     summaryData[i] = summaryPrefixText[i] + tool.groupSeparator(summaryData[i].toFixed(2)) + summarySuffixText[i]
-    //   }
-    // }
+    console.log('最终 summaryData:', summaryData)
     return [summaryData]
+  } else {
+    console.log('__summary 被调用,但 summary 配置为空或无效')
+    return []
   }
 }
 
@@ -592,6 +605,27 @@ const handleShowHideColumn = (checked, column, index) => {
   columns.value[index].show = checked
 }
 
+// 监听 columns 变化
+watch(
+  () => props.columns,
+  (newColumns) => {
+    if (newColumns && Array.isArray(newColumns)) {
+      columns.value = newColumns
+      console.log('sa-table columns updated:', columns.value)
+    }
+  },
+  { deep: true }
+)
+
+// 监听 options.summary 变化
+watch(
+  () => options.value.summary,
+  (newSummary) => {
+    console.log('sa-table options.summary updated:', newSummary)
+  },
+  { deep: true }
+)
+
 // 初始化
 const init = async () => {
   // 设置 组件id

+ 129 - 165
src/views/v1/advert/agentSite/index.vue

@@ -5,26 +5,17 @@
       :options="options"
       :columns="columns"
       :searchForm="searchForm"
-      @selectionChange="selectChange"
-    >
+      @selectionChange="selectChange">
       <!-- 搜索区 tableSearch -->
       <template #tableSearch>
         <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-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-input v-model="searchForm.agent_name" placeholder="请输入渠道名称" allow-clear />
           </a-form-item>
         </a-col>
         <a-col :sm="8" :xs="24">
@@ -34,66 +25,33 @@
               :options="authOptions"
               placeholder="请选择负责人"
               allow-search
-              allow-clear
-            />
+              allow-clear />
           </a-form-item>
         </a-col>
         <a-col :sm="8" :xs="24">
           <a-form-item label="广告位ID" field="id">
-            <a-input
-              v-model="searchForm.id"
-              placeholder="请输入广告位ID"
-              allow-clear
-            />
+            <a-input v-model="searchForm.id" placeholder="请输入广告位ID" allow-clear />
           </a-form-item>
         </a-col>
         <a-col :sm="8" :xs="24">
           <a-form-item label="广告位名称" field="name">
-            <a-input
-              v-model="searchForm.name"
-              placeholder="请输入广告位名称"
-              allow-clear
-            />
+            <a-input v-model="searchForm.name" placeholder="请输入广告位名称" allow-clear />
           </a-form-item>
         </a-col>
       </template>
 
       <template #tableBeforeButtons>
-        <a-button
-          type="primary"
-          @click="addApk"
-          :disabled="selecteds.length === 0"
-        >
-          APK打包
-        </a-button>
-        <a-button
-          type="primary"
-          status="warning"
-          @click="addGdt"
-          :disabled="selecteds.length === 0"
+        <a-button type="primary" @click="addApk" :disabled="selecteds.length === 0"> APK打包 </a-button>
+        <a-button type="primary" status="warning" @click="addGdt" :disabled="selecteds.length === 0"
           >广点通分包</a-button
         >
 
-        <a-button
-          type="primary"
-          status="success"
-          @click="addKs"
-          :disabled="selecteds.length === 0"
-          >快手分包</a-button
-        >
-        <a-button
-          type="primary"
-          status="danger"
-          @click="addTt"
-          :disabled="selecteds.length === 0"
-          >头条推送</a-button
-        >
+        <a-button type="primary" status="success" @click="addKs" :disabled="selecteds.length === 0">快手分包</a-button>
+        <a-button type="primary" status="danger" @click="addTt" :disabled="selecteds.length === 0">头条推送</a-button>
       </template>
 
       <template #operationAfterExtend="{ record }">
-        <a-button size="mini" type="text" @click="addLinkDebug(record)"
-          ><icon-bug />联调</a-button
-        >
+        <a-button size="mini" type="text" @click="addLinkDebug(record)"><icon-bug />联调</a-button>
       </template>
       <!-- Table 自定义渲染 -->
     </sa-table>
@@ -118,37 +76,43 @@
 </template>
 
 <script setup>
-import { onMounted, ref, reactive } from "vue";
-import { Message, Modal } from "@arco-design/web-vue";
-import advertCommonApi from "../../api/advert/common";
-import editForm from "./edit.vue";
-import addApkForm from "../../advert/gamePackageLog/edit.vue";
-import api from "../../api/advert/agentSite";
-import ksPacForm from "./ks_pac.vue";
-import gdtPacForm from "./gdt_pac.vue";
-import ttPacForm from "./tt_pac.vue";
-import linkDebugForm from "./link-debug-form.vue";
+import { onMounted, ref, reactive } from 'vue'
+import { Message, Modal } from '@arco-design/web-vue'
+import advertCommonApi from '../../api/advert/common'
+import editForm from './edit.vue'
+import addApkForm from '../../advert/gamePackageLog/edit.vue'
+import api from '../../api/advert/agentSite'
+import ksPacForm from './ks_pac.vue'
+import gdtPacForm from './gdt_pac.vue'
+import ttPacForm from './tt_pac.vue'
+import linkDebugForm from './link-debug-form.vue'
+import { useUserStore } from '@/store'
+
+const userStore = useUserStore()
+
 // 引用定义
-const crudRef = ref();
-const viewRef = ref();
-const addApkRef = ref();
-const mediaOptions = ref([]);
-const agentOptions = ref([]);
-const authOptions = ref([]);
-const editRef = ref();
-const ksPacRef = ref();
-const gdtPacRef = ref();
-const ttPacRef = ref();
-const selecteds = ref([]);
-const linkDebugRef = ref();
+const crudRef = ref()
+const viewRef = ref()
+const addApkRef = ref()
+const mediaOptions = ref([])
+const agentOptions = ref([])
+const authOptions = ref([])
+const editRef = ref()
+const ksPacRef = ref()
+const gdtPacRef = ref()
+const ttPacRef = ref()
+const selecteds = ref([])
+const linkDebugRef = ref()
 
 // 搜索表单
 const searchForm = ref({
-  media_id: "",
-  agent_id: "",
-  auth_id: "",
-  name: "",
-});
+  media_id: '',
+  agent_id: '',
+
+  //默认当前登录的负责人
+  auth_id: userStore.user.id,
+  name: '',
+})
 
 // SaTable 基础配置
 const options = reactive({
@@ -156,194 +120,194 @@ const options = reactive({
   rowSelection: { showCheckedAll: true },
   add: {
     show: false,
-    auth: ["/v1/advert/AgentSite/save"],
+    auth: ['/v1/advert/AgentSite/save'],
     func: async () => {
-      editRef.value?.open();
+      editRef.value?.open()
     },
   },
   edit: {
     show: true,
-    auth: ["/v1/advert/AgentSite/update"],
+    auth: ['/v1/advert/AgentSite/update'],
     func: async (record) => {
-      editRef.value?.open("edit");
-      editRef.value?.setFormData(record);
+      editRef.value?.open('edit')
+      editRef.value?.setFormData(record)
     },
   },
   delete: {
     show: false,
-    auth: ["/v1/advert/AgentSite/destroy"],
+    auth: ['/v1/advert/AgentSite/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: "广告位ID", dataIndex: "id", width: 120 },
-  { title: "广告位名称", dataIndex: "name", width: 180 },
-  { title: "媒体类型", dataIndex: "media_name", width: 180 },
-  { title: "渠道ID", dataIndex: "agent_id", width: 180 },
-  { title: "渠道名", dataIndex: "agent_name", width: 180 },
-  { title: "负责人", dataIndex: "auth_name", width: 180 },
-]);
+  { title: '广告位ID', dataIndex: 'id', width: 120 },
+  { title: '广告位名称', dataIndex: 'name', width: 180 },
+  { title: '媒体类型', dataIndex: 'media_name', width: 180 },
+  { title: '渠道ID', dataIndex: 'agent_id', width: 180 },
+  { title: '渠道名', dataIndex: 'agent_name', width: 180 },
+  { title: '负责人', dataIndex: 'auth_name', width: 180 },
+])
 
 // 获取媒体列表Options
 const getMediaOptions = async () => {
-  const res = await advertCommonApi.getMediaOptionsApi();
+  const res = await advertCommonApi.getMediaOptionsApi()
   if (res.code == 200) {
-    mediaOptions.value = res.data;
+    mediaOptions.value = res.data
   }
-};
+}
 
 // 获取渠道列表Options
 const getAgentOptions = async () => {
-  const res = await advertCommonApi.getAgentOptionsApi();
+  const res = await advertCommonApi.getAgentOptionsApi()
   if (res.code == 200) {
-    agentOptions.value = res.data;
+    agentOptions.value = res.data
   }
-};
+}
 
 // 获取后台归属人列表
 const getAuthList = async () => {
-  const res = await advertCommonApi.getAuthOptionsApi();
+  const res = await advertCommonApi.getAuthOptionsApi()
   if (res.code == 200) {
-    authOptions.value = res.data;
+    authOptions.value = res.data
   }
-};
+}
 
 // 选中数据
-const selectChange = (val) => (selecteds.value = val);
+const selectChange = (val) => (selecteds.value = val)
 
 // 获取广告位详情
 const getAdvertSiteDetail = async () => {
-  let id = selecteds.value[0];
-  const res = await api.read(id);
+  let id = selecteds.value[0]
+  const res = await api.read(id)
   if (res.code == 200) {
-    return res.data;
+    return res.data
   }
-  return null;
-};
+  return null
+}
 
 // 打包新增
 const addApk = async () => {
-  let data = [];
-  let tableData = crudRef.value?.getTableData();
+  let data = []
+  let tableData = crudRef.value?.getTableData()
   for (let i = 0; i < selecteds.value.length; i++) {
-    let id = selecteds.value[i];
-    let row = tableData.find((item) => item.id == id);
+    let id = selecteds.value[i]
+    let row = tableData.find((item) => item.id == id)
     data.push({
       site_id: row.id, // 广告位
       agent_id: row.agent_id, // 渠道
-    });
+    })
   }
 
-  addApkRef.value?.open();
-  addApkRef.value?.setBatchData(data);
-};
+  addApkRef.value?.open()
+  addApkRef.value?.setBatchData(data)
+}
 
 // 广点通分包
 const addGdt = async () => {
-  let tableData = crudRef.value?.getTableData();
+  let tableData = crudRef.value?.getTableData()
   for (let i = 0; i < selecteds.value.length; i++) {
     // media_id 必须都是1, 否则不给打包
-    let row = tableData.find((item) => item.id == selecteds.value[i]);
+    let row = tableData.find((item) => item.id == selecteds.value[i])
     if (row.media_id != 2) {
       Modal.error({
-        title: "提示",
+        title: '提示',
         content: `广告位ID:${row.id},媒体类型不是广点通,不能分包!`,
-      });
+      })
 
-      return;
+      return
     }
   }
-  let data = [];
+  let data = []
   for (let i = 0; i < selecteds.value.length; i++) {
-    let row = tableData.find((item) => item.id == selecteds.value[i]);
+    let row = tableData.find((item) => item.id == selecteds.value[i])
     data.push({
       site_id: row.id, // 广告位
       agent_id: row.agent_id, // 渠道
-    });
+    })
   }
 
-  gdtPacRef.value?.open();
-  gdtPacRef.value?.setBatchData(data);
-};
+  gdtPacRef.value?.open()
+  gdtPacRef.value?.setBatchData(data)
+}
 
 // 快手分包
 const addKs = async () => {
-  let tableData = crudRef.value?.getTableData();
+  let tableData = crudRef.value?.getTableData()
   for (let i = 0; i < selecteds.value.length; i++) {
-    let row = tableData.find((item) => item.id == selecteds.value[i]);
+    let row = tableData.find((item) => item.id == selecteds.value[i])
     if (row.media_id != 3) {
       Modal.error({
-        title: "提示",
+        title: '提示',
         content: `广告位ID:${row.id},媒体类型不是快手,不能分包!`,
-      });
-      return false;
+      })
+      return false
     }
   }
-  let data = [];
+  let data = []
   for (let i = 0; i < selecteds.value.length; i++) {
-    let row = tableData.find((item) => item.id == selecteds.value[i]);
+    let row = tableData.find((item) => item.id == selecteds.value[i])
     data.push({
       site_id: row.id, // 广告位
       agent_id: row.agent_id, // 渠道
-    });
+    })
   }
 
-  ksPacRef.value?.open();
-  ksPacRef.value?.setBatchData(data);
-};
+  ksPacRef.value?.open()
+  ksPacRef.value?.setBatchData(data)
+}
 
 // 头条推送(新)
 const addTt = async () => {
-  let tableData = crudRef.value?.getTableData();
+  let tableData = crudRef.value?.getTableData()
   for (let i = 0; i < selecteds.value.length; i++) {
-    let row = tableData.find((item) => item.id == selecteds.value[i]);
+    let row = tableData.find((item) => item.id == selecteds.value[i])
     if (row.media_id != 1) {
       Modal.error({
-        title: "提示",
+        title: '提示',
         content: `广告位ID:${row.id},媒体类型不是头条,不能推送!`,
-      });
-      return false;
+      })
+      return false
     }
   }
-  let siteIds = [];
+  let siteIds = []
   for (let i = 0; i < selecteds.value.length; i++) {
-    let row = tableData.find((item) => item.id == selecteds.value[i]);
-    siteIds.push(row.id);
+    let row = tableData.find((item) => item.id == selecteds.value[i])
+    siteIds.push(row.id)
   }
 
-  ttPacRef.value?.open();
-  ttPacRef.value?.setSiteIds(siteIds.join(","));
-};
+  ttPacRef.value?.open()
+  ttPacRef.value?.setSiteIds(siteIds.join(','))
+}
 
 // 联调
 const addLinkDebug = async (record) => {
-  linkDebugRef.value?.open();
-  linkDebugRef.value?.setFormData(record);
-};
+  linkDebugRef.value?.open()
+  linkDebugRef.value?.setFormData(record)
+}
 
 // 页面数据初始化
 const initPage = async () => {
-  await getMediaOptions();
-  await getAgentOptions();
-  await getAuthList();
-};
+  await getMediaOptions()
+  await getAgentOptions()
+  await getAuthList()
+}
 
 // SaTable 数据请求
 const refresh = async () => {
-  crudRef.value?.refresh();
-};
+  crudRef.value?.refresh()
+}
 
 // 页面加载完成执行
 onMounted(async () => {
-  initPage();
-  refresh();
-});
+  initPage()
+  refresh()
+})
 </script>

+ 14 - 0
src/views/v1/api/gameLog/analyse.js

@@ -0,0 +1,14 @@
+import { request } from '@/utils/request.js'
+
+/**
+ *运营分析 API接口
+ */
+export default {
+  getRegDayDataList(params = {}) {
+    return request({
+      url: '/v1/gameLog/analyse/getRegDayDataList',
+      method: 'get',
+      params
+    })
+  }
+}

+ 129 - 0
src/views/v1/gameLog/regDay/index.vue

@@ -0,0 +1,129 @@
+<template>
+  <div class="ma-content-block">
+    <sa-table ref="crudRef" :options="options" :columns="columns" :searchForm="searchForm" @search="handleRequestData">
+      <!-- 搜索区 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="date" />
+          </a-form-item>
+        </a-col>
+      </template>
+
+      <!-- Table 自定义渲染 -->
+    </sa-table>
+  </div>
+</template>
+
+<script setup>
+import { onMounted, ref, reactive, nextTick } from 'vue'
+import api from '../../api/gameLog/analyse'
+import dayjs from 'dayjs'
+import commonApi from '../../api/common'
+import GameSelect from '@/components/game-select/index.vue'
+
+// 引用定义
+const crudRef = ref()
+const gameList = ref([])
+
+// 搜索表单
+const searchForm = ref({
+  game_id: '',
+  media_id: '',
+  auth_id: '',
+  agent_id: '',
+  site_id: '',
+  reg_date: [],
+})
+
+// SaTable 基础配置
+const options = reactive({
+  api: api.getRegDayDataList,
+  pk: 'id',
+  rowSelection: { showCheckedAll: true },
+  showSummary: true,
+  operationColumn: false,
+  showSort: false,
+  summary: [],
+})
+
+// SaTable 列配置
+const columns = ref([])
+
+// 页面数据初始化
+const initPage = async () => {
+  searchForm.value.reg_date = [dayjs().format('YYYY-MM-DD'), dayjs().format('YYYY-MM-DD')]
+  await getGameList()
+}
+
+// 获取游戏列表
+const getGameList = async () => {
+  const res = await commonApi.getGameListTreeApi()
+  if (res.code === 200) {
+    gameList.value = res.data
+  }
+}
+// SaTable 数据请求
+const refresh = async () => {
+  crudRef.value?.refresh()
+}
+
+const handleRequestData = () => {
+  // 使用 nextTick 确保在 DOM 更新后再获取数据
+  nextTick(() => {
+    const res = crudRef.value.getResponseData()
+    console.log('完整的响应数据:', res)
+    console.log('totalRow 数据:', res?.totalRow)
+
+    // 重新添加动态列,并为每一列添加合计配置
+    if (res && res.columns && Array.isArray(res.columns)) {
+      columns.value = res.columns
+      console.log('columns updated:', columns.value)
+
+      // 动态生成 summary 配置,dataIndex 与 columns 保持一致
+      if (Array.isArray(res.columns)) {
+        // 只对数值类型的列添加合计
+        const numericColumns = res.columns.filter((col) => {
+          // 排除日期、文本等非数值列
+          const excludeFields = ['reg_date', 'date', 'time', 'name', 'title', 'description', 'game_id', 'game_name']
+          return !excludeFields.includes(col.dataIndex)
+        })
+
+        // 清空并重新设置 summary 配置
+        options.summary.length = 0
+        numericColumns.forEach((col) => {
+          options.summary.push({
+            action: 'totalRow',
+            dataIndex: col.dataIndex,
+          })
+        })
+
+        console.log('summary config:', options.summary)
+        console.log(
+          'numeric columns:',
+          numericColumns.map((col) => col.dataIndex)
+        )
+        console.log('options.summary length:', options.summary.length)
+      }
+    }
+  })
+}
+
+// 页面加载完成执行
+onMounted(async () => {
+  await initPage()
+  // 设置一些默认列,以防API没有返回列信息
+  if (columns.value.length === 0) {
+    columns.value = [
+      { title: '注册日期', dataIndex: 'reg_date', width: 120 },
+      { title: '注册数', dataIndex: 'reg_count', width: 100 },
+    ]
+  }
+  refresh()
+})
+</script>