瀏覽代碼

✨ feat(报告): 增加请求量字段并优化登录时间显示

dodo hold 1 月之前
父節點
當前提交
4474271407

+ 3 - 0
src/api/deeplinkReport.ts

@@ -6,6 +6,7 @@ export interface DeeplinkDailyReportRecord {
     report_date: string;
     channel_name?: string;
     display_name?: string;
+    request_count: number;
     total_count: number;
     success_count: number;
     fail_count: number;
@@ -13,6 +14,7 @@ export interface DeeplinkDailyReportRecord {
 }
 
 export interface DeeplinkDailyReportSummary {
+    request_count: number;
     total_count: number;
     success_count: number;
     fail_count: number;
@@ -21,6 +23,7 @@ export interface DeeplinkDailyReportSummary {
 export interface DeeplinkDailyReportChannel {
     channel_name: string;
     display_name: string;
+    request_count: number;
     total_count: number;
     success_count: number;
     fail_count: number;

+ 1 - 1
src/api/jd.ts

@@ -36,7 +36,7 @@ export interface JdPoolRecord {
     description: string;
     floorId: string;
     last_time: Date;
-    login_time: Date;
+    login_time: Date | null;
     refpid: string;
     status: boolean;
     work_mode: boolean;

+ 1 - 1
src/api/pdd.ts

@@ -58,7 +58,7 @@ export interface PddPoolRecord {
     description: string;
     floorId: string;
     last_time: Date;
-    login_time: Date;
+    login_time: Date | null;
     refpid: string;
     status: boolean;
     cookie_status: boolean;

+ 2 - 1
src/api/taobao.ts

@@ -117,7 +117,7 @@ export interface TkPoolRecord {
     note: string;
     floorId: string;
     last_time: Date;
-    login_time: Date;
+    login_time: Date | null;
     nodeName: string;
     proxyStatus?: boolean | null;
     suspended_endpoint: string;
@@ -133,6 +133,7 @@ export interface TkPoolRecord {
     enable_sync_order: boolean;
     enable_deep_url: boolean;
     enable_promotionQuery: boolean;
+    enable_order_summary_cache: boolean;
     appkey: string;
     appSecret: string;
     open_pid: string;

+ 1 - 0
src/api/tracks.ts

@@ -42,6 +42,7 @@ export interface TrackHourlyReportRecord {
     hour: number;
     hour_label: string;
     event_count: number;
+    call_count: number;
 }
 
 export interface TrackListParams {

+ 19 - 7
src/views/jd/list.vue

@@ -376,15 +376,11 @@
                         >
                         <div
                             v-if="
-                                dayjs().diff(
-                                    dayjs(record.login_time),
-                                    'hours'
-                                ) < 48
+                                formatDateTime(record.login_time) !== '-' &&
+                                getLoginAgeHours(record.login_time) < 48
                             "
                         >
-                            登录:{{
-                                dayjs(record.login_time).format('MM-DD HH:mm')
-                            }}</div
+                            登录:{{ formatDateTime(record.login_time) }}</div
                         >
                     </div>
                 </template>
@@ -655,6 +651,22 @@
         return record.is_hide ? 'special-table-row' : '';
     };
 
+    const formatDateTime = (time?: Date | string | null) => {
+        if (!time || !dayjs(time).isValid()) {
+            return '-';
+        }
+
+        return dayjs(time).format('MM-DD HH:mm');
+    };
+
+    const getLoginAgeHours = (loginTime?: Date | string | null) => {
+        if (!loginTime || !dayjs(loginTime).isValid()) {
+            return Number.POSITIVE_INFINITY;
+        }
+
+        return dayjs().diff(dayjs(loginTime), 'hours');
+    };
+
     if (route.query.show_hide === '1') {
         formModel.value.show_hide = true;
     }

+ 18 - 1
src/views/site/deeplinkReport.vue

@@ -7,6 +7,7 @@
                     <div class="page-title">DP 请求报表</div>
                     <div class="page-subtitle">
                         Redis · {{ dateRangeText }} ·
+                        {{ formatNumber(summary.request_count) }} 次请求 ·
                         {{ formatNumber(summary.total_count) }} 次转链 ·
                         {{ channels.length }} 个渠道
                     </div>
@@ -43,7 +44,7 @@
                 :columns="columns"
                 :data="renderData"
                 :bordered="{ headerCell: true }"
-                :scroll="{ x: 520 }"
+                :scroll="{ x: 650 }"
                 :expanded-keys="expandedKeys"
                 hide-expand-button-on-empty
                 size="small"
@@ -71,6 +72,14 @@
                         </span>
                     </span>
                 </template>
+                <template #request_count="{ record }">
+                    <span
+                        class="number-cell"
+                        :class="{ highlight: record.row_type === 'daily' }"
+                    >
+                        {{ formatNumber(record.request_count) }}
+                    </span>
+                </template>
                 <template #total_count="{ record }">
                     <span
                         class="number-cell"
@@ -114,6 +123,7 @@
     ];
 
     const emptySummary = (): DeeplinkDailyReportSummary => ({
+        request_count: 0,
         total_count: 0,
         success_count: 0,
         fail_count: 0,
@@ -154,6 +164,13 @@
             slotName: 'report_date',
             width: 180,
         },
+        {
+            title: '请求量',
+            dataIndex: 'request_count',
+            slotName: 'request_count',
+            align: 'right',
+            width: 130,
+        },
         {
             title: '转链数',
             dataIndex: 'total_count',

+ 58 - 9
src/views/site/tracksReport.vue

@@ -302,12 +302,12 @@
                         }}</span>
                     </template>
                     <template #calls="{ record }">
-                        <span class="number-cell">{{
+                        <span v-if="!record.isAccountRow" class="number-cell">{{
                             formatNumber(record.calls)
                         }}</span>
                     </template>
                     <template #success="{ record }">
-                        <span class="number-cell">{{
+                        <span v-if="!record.isAccountRow" class="number-cell">{{
                             formatNumber(record.success)
                         }}</span>
                     </template>
@@ -355,6 +355,10 @@
                 <span class="hourly-unique">{{ selectedRow.unique_id }}</span>
             </div>
             <div class="hourly-metrics">
+                <div class="hourly-metric">
+                    <span>调用</span>
+                    <strong>{{ formatNumber(hourlySummary.calls) }}</strong>
+                </div>
                 <div class="hourly-metric">
                     <span>曝光</span>
                     <strong>{{ formatNumber(hourlySummary.expose) }}</strong>
@@ -665,6 +669,7 @@
     const hourlyLoading = ref(false);
     const selectedRow = ref<DimensionRow | null>(null);
     const hourlyXAxis = ref<string[]>([]);
+    const hourlyCalls = ref<number[]>([]);
     const hourlyExpose = ref<number[]>([]);
     const hourlyClick = ref<number[]>([]);
     const hourlyChartKey = ref(0);
@@ -1251,6 +1256,7 @@
         );
         const click = hourlyClick.value.reduce((sum, value) => sum + value, 0);
         return {
+            calls: selectedRow.value?.calls || 0,
             expose,
             click,
             ctr: expose > 0 ? (click / expose) * 100 : null,
@@ -1259,6 +1265,14 @@
 
     const hourlyChartOption = computed(() => {
         const series = [];
+        series.push({
+            name: '调用',
+            type: 'bar',
+            data: hourlyCalls.value,
+            barMaxWidth: 18,
+            itemStyle: { color: 'rgba(22, 93, 255, 0.45)' },
+        });
+
         if (!selectedRow.value || selectedRow.value.exposeTrackIds.length > 0) {
             series.push({
                 name: '曝光',
@@ -1280,7 +1294,7 @@
         }
 
         return {
-            color: ['#165dff', '#00b42a'],
+            color: ['rgba(22, 93, 255, 0.45)', '#165dff', '#00b42a'],
             tooltip: { trigger: 'axis' },
             legend: { right: 0, top: 0 },
             grid: {
@@ -1545,11 +1559,12 @@
             { length: 24 },
             (_, hour) => `${hour.toString().padStart(2, '0')}:00`
         );
+        hourlyCalls.value = Array(24).fill(0);
         hourlyExpose.value = Array(24).fill(0);
         hourlyClick.value = Array(24).fill(0);
 
         try {
-            const [exposeList, clickList] = await Promise.all([
+            const [exposeHourlyData, clickHourlyData] = await Promise.all([
                 fetchHourlyCounts(
                     reportRow.exposeTrackIds,
                     reportRow.date,
@@ -1561,8 +1576,9 @@
                     reportRow.scene
                 ),
             ]);
-            hourlyExpose.value = exposeList;
-            hourlyClick.value = clickList;
+            hourlyExpose.value = exposeHourlyData.eventCounts;
+            hourlyClick.value = clickHourlyData.eventCounts;
+            hourlyCalls.value = await fetchHourlyAccountCallCounts(reportRow);
             hourlyChartKey.value += 1;
         } catch {
             Message.error('小时数据加载失败');
@@ -1576,8 +1592,8 @@
         date: string,
         scene: string
     ) => {
-        const totals = Array(24).fill(0) as number[];
-        if (!trackIds.length) return totals;
+        const eventCounts = Array(24).fill(0) as number[];
+        if (!trackIds.length) return { eventCounts };
 
         const results = await Promise.all(
             trackIds.map((trackId) =>
@@ -1593,7 +1609,40 @@
             const list: TrackHourlyReportRecord[] = res?.data?.list || [];
             list.forEach((item) => {
                 if (item.hour >= 0 && item.hour < 24) {
-                    totals[item.hour] += Number(item.event_count || 0);
+                    eventCounts[item.hour] += Number(item.event_count || 0);
+                }
+            });
+        });
+
+        return { eventCounts };
+    };
+
+    const fetchHourlyAccountCallCounts = async (reportRow: DimensionRow) => {
+        const totals = Array(24).fill(0) as number[];
+        const accountRows = getAccountRows(reportRow);
+        const trackId = [
+            ...reportRow.exposeTrackIds,
+            ...reportRow.clickTrackIds,
+        ][0];
+
+        if (!trackId || !accountRows.length) return totals;
+
+        const results = await Promise.all(
+            accountRows.map((accountRow) =>
+                queryTrackHourlyReport({
+                    track_link_id: trackId,
+                    date: reportRow.date,
+                    scene: reportRow.scene,
+                    account_id: accountRow.accountId,
+                })
+            )
+        );
+
+        results.forEach((res: any) => {
+            const list: TrackHourlyReportRecord[] = res?.data?.list || [];
+            list.forEach((item) => {
+                if (item.hour >= 0 && item.hour < 24) {
+                    totals[item.hour] += Number(item.call_count || 0);
                 }
             });
         });

+ 77 - 36
src/views/taobao/list.vue

@@ -442,6 +442,38 @@
                     >
                         下探网址
                     </a-tag>
+                    <span style="margin: 0 5px">
+                        <a-tag
+                            v-if="record.enable_order_summary_cache"
+                            size="small"
+                            bordered
+                            color="purple"
+                            @click="
+                                changeAttr(
+                                    record.id,
+                                    'enable_order_summary_cache',
+                                    false
+                                )
+                            "
+                        >
+                            订单缓存
+                        </a-tag>
+                        <a-tag
+                            v-else
+                            size="small"
+                            bordered
+                            color="gray"
+                            @click="
+                                changeAttr(
+                                    record.id,
+                                    'enable_order_summary_cache',
+                                    true
+                                )
+                            "
+                        >
+                            订单缓存
+                        </a-tag>
+                    </span>
                 </template>
                 <template #time="{ record }">
                     <div style="color: gray">
@@ -455,41 +487,26 @@
                                 dayjs(record.last_time).format('MM-DD HH:mm')
                             }}</div
                         >
-                        <div
-                            v-if="
-                                dayjs().diff(
-                                    dayjs(record.login_time),
-                                    'hours'
-                                ) < 48
-                            "
-                        >
-                            登录:{{
-                                dayjs(record.login_time).format('MM-DD HH:mm')
-                            }}</div
-                        >
-                        <a-tooltip v-else>
-                            <template #content>
-                                <div
-                                    >登录:{{
-                                        dayjs(record.login_time).format(
-                                            'MM-DD HH:mm'
-                                        )
-                                    }}</div
-                                >
-                                <div>登录状态即将掉线,请尽快处理</div>
-                            </template>
-                            <div style="color: red">
-                                预计
-                                {{
-                                    72 -
-                                    dayjs().diff(
-                                        dayjs(record.login_time),
-                                        'hours'
-                                    )
-                                }}
-                                小时后掉线
-                            </div>
-                        </a-tooltip>
+                        <template v-if="formatDateTime(record.login_time) !== '-'">
+                            <div v-if="getLoginAgeHours(record.login_time) < 48">
+                                登录:{{ formatDateTime(record.login_time) }}</div
+                            >
+                            <a-tooltip v-else>
+                                <template #content>
+                                    <div
+                                        >登录:{{
+                                            formatDateTime(record.login_time)
+                                        }}</div
+                                    >
+                                    <div>登录状态即将掉线,请尽快处理</div>
+                                </template>
+                                <div style="color: red">
+                                    预计
+                                    {{ getLoginExpireHours(record.login_time) }}
+                                    小时后掉线
+                                </div>
+                            </a-tooltip>
+                        </template>
                     </div>
                 </template>
                 <template #operations="{ record }">
@@ -711,7 +728,7 @@
         {
             title: '分类',
             slotName: 'actions',
-            width: 400,
+            width: 480,
             align: 'center',
         },
         {
@@ -747,6 +764,30 @@
         return record.is_hide ? 'special-table-row' : '';
     };
 
+    const formatDateTime = (time?: Date | string | null) => {
+        if (!time || !dayjs(time).isValid()) {
+            return '-';
+        }
+
+        return dayjs(time).format('MM-DD HH:mm');
+    };
+
+    const getLoginAgeHours = (loginTime?: Date | string | null) => {
+        if (!loginTime || !dayjs(loginTime).isValid()) {
+            return Number.POSITIVE_INFINITY;
+        }
+
+        return dayjs().diff(dayjs(loginTime), 'hours');
+    };
+
+    const getLoginExpireHours = (loginTime?: Date | string | null) => {
+        if (!loginTime || !dayjs(loginTime).isValid()) {
+            return '-';
+        }
+
+        return 72 - dayjs().diff(dayjs(loginTime), 'hours');
+    };
+
     if (route.query.show_hide === '1') {
         formModel.value.show_hide = true;
     }