浏览代码

✨ feat(pushReport): 增加批量推送

dodo hold 1 年之前
父节点
当前提交
d4cd11bb12
共有 1 个文件被更改,包括 159 次插入15 次删除
  1. 159 15
      src/views/site/pushReport.vue

+ 159 - 15
src/views/site/pushReport.vue

@@ -74,6 +74,12 @@
                             </template>
                             新增数据
                         </a-button>
+                        <a-button type="success" :disabled="selectedRowKeys.length === 0" @click="onBatchPush">
+                            <template #icon>
+                                <icon-upload />
+                            </template>
+                            批量推送 ({{ selectedRowKeys.length }})
+                        </a-button>
                     </a-space>
                 </a-col>
                 <a-col :span="12" style="
@@ -134,7 +140,12 @@
 
             <a-table row-key="id" :loading="loading" :pagination="pagination"
                 :columns="(cloneColumns as TableColumnData[])" :data="renderData" :bordered="{ headerCell: true }"
-                :size="size" @page-change="onPageChange" :scroll="{ x: 1700, y: tableHeight }">
+                :size="size" @page-change="onPageChange" :scroll="{ x: 1700, y: tableHeight }" 
+                v-model:selectedKeys="selectedRowKeys"
+                :row-selection="{
+                    type: 'checkbox',
+                    showCheckedAll: true
+                }">
                 <template #index="{ record }">
                     {{ record.id }}
                 </template>
@@ -173,29 +184,29 @@
                     </div>
                 </template>
                 <template #request_metrics="{ record }">
-                    <div>请求量: <template v-if="record.req_count == 0">-</template><a-tag v-else color="green">{{ record.req_count }}</a-tag></div>
-                    <div>DP转链: <template v-if="record.dp_transition_succ_count == 0">-</template><a-tag v-else color="green">{{ record.dp_transition_succ_count }}</a-tag></div>
-                    <div>商业转链: <template v-if="record.transition_succ_count == 0">-</template><a-tag v-else color="green">{{ record.transition_succ_count }}</a-tag></div>
+                    <div>请求量: <template v-if="record.req_count == 0 || record.req_count == null">-</template><a-tag v-else color="green">{{ record.req_count }}</a-tag></div>
+                    <div>DP转链: <template v-if="record.dp_transition_succ_count == 0 || record.dp_transition_succ_count == null">-</template><a-tag v-else color="green">{{ record.dp_transition_succ_count }}</a-tag></div>
+                    <div>商业转链: <template v-if="record.transition_succ_count == 0 || record.transition_succ_count == null">-</template><a-tag v-else color="green">{{ record.transition_succ_count }}</a-tag></div>
                 </template>
                 <template #expose_metrics="{ record }">
-                    <div>曝光PV: <template v-if="record.expose_count == 0">-</template><a-tag v-else color="green">{{ record.expose_count }}</a-tag></div>
-                    <div>曝光UV: <template v-if="record.expose_user_count == 0">-</template><a-tag v-else color="green">{{ record.expose_user_count }}</a-tag></div>
+                    <div>曝光PV: <template v-if="record.expose_count == 0 || record.expose_count == null">-</template><a-tag v-else color="green">{{ record.expose_count }}</a-tag></div>
+                    <div>曝光UV: <template v-if="record.expose_user_count == 0 || record.expose_user_count == null">-</template><a-tag v-else color="green">{{ record.expose_user_count }}</a-tag></div>
                 </template>
                 <template #click_metrics="{ record }">
-                    <div>点击PV: <template v-if="record.click_count == 0">-</template><a-tag v-else color="green">{{ record.click_count }}</a-tag></div>
-                    <div>点击UV: <template v-if="record.click_user_count == 0">-</template><a-tag v-else color="green">{{ record.click_user_count }}</a-tag></div>
+                    <div>点击PV: <template v-if="record.click_count == 0 || record.click_count == null">-</template><a-tag v-else color="green">{{ record.click_count }}</a-tag></div>
+                    <div>点击UV: <template v-if="record.click_user_count == 0 || record.click_user_count == null">-</template><a-tag v-else color="green">{{ record.click_user_count }}</a-tag></div>
                 </template>
                 <template #app_metrics="{ record }">
-                    <div>唤端PV: <template v-if="record.app_open_count == 0">-</template><a-tag v-else color="green">{{ record.app_open_count }}</a-tag></div>
-                    <div>唤端UV: <template v-if="record.app_open_user_count == 0">-</template><a-tag v-else color="green">{{ record.app_open_user_count }}</a-tag></div>
+                    <div>唤端PV: <template v-if="record.app_open_count == 0 || record.app_open_count == null">-</template><a-tag v-else color="green">{{ record.app_open_count }}</a-tag></div>
+                    <div>唤端UV: <template v-if="record.app_open_user_count == 0 || record.app_open_user_count == null">-</template><a-tag v-else color="green">{{ record.app_open_user_count }}</a-tag></div>
                 </template>
                 <template #order_metrics="{ record }">
-                    <div>订单PV: <template v-if="record.order_count == 0">-</template><a-tag v-else color="green">{{ record.order_count }}</a-tag></div>
-                    <div>订单UV: <template v-if="record.order_user_count == 0">-</template><a-tag v-else color="green">{{ record.order_user_count }}</a-tag></div>
+                    <div>订单PV: <template v-if="record.order_count == 0 || record.order_count == null">-</template><a-tag v-else color="green">{{ record.order_count }}</a-tag></div>
+                    <div>订单UV: <template v-if="record.order_user_count == 0 || record.order_user_count == null">-</template><a-tag v-else color="green">{{ record.order_user_count }}</a-tag></div>
                 </template>
                 <template #income_metrics="{ record }">
-                    <div>GMV: <template v-if="record.gmv == 0">-</template><a-tag v-else color="green">{{ record.gmv }}元</a-tag></div>
-                    <div>预估收入: <template v-if="record.income == 0">-</template><a-tag v-else color="green">{{ record.income }}元</a-tag></div>
+                    <div>GMV: <template v-if="record.gmv == 0 || record.gmv == null">-</template><a-tag v-else color="green">{{ record.gmv }}元</a-tag></div>
+                    <div>预估收入: <template v-if="record.income == 0 || record.income == null">-</template><a-tag v-else color="green">{{ record.income }}元</a-tag></div>
                 </template>
                 <template #settlement="{ record }">
                     <a-tag :color="record.is_settlement ? 'green' : 'orange'" bordered>
@@ -329,6 +340,43 @@
                 </a-row>
             </a-form>
         </a-modal>
+
+        <a-modal 
+            v-model:visible="batchPushModalVisible"
+            :title="batchPushModalLoading ? '推送中' : '推送完成'"
+            :mask-closable="false"
+            :closable="!batchPushModalLoading"
+            @before-ok="handleBatchPushComplete"
+            ok-text="完成"
+            :ok-button-props="{ disabled: batchPushModalLoading }"
+            :cancel-button-props="{ disabled: true }">
+            <div style="text-align: center; padding: 20px 0;">
+                <div v-if="batchPushModalLoading">
+                    <a-spin />
+                    <div style="margin-top: 15px; font-size: 16px;">
+                        {{ batchPushProgress }}/{{ batchPushTotal }}条数据已处理
+                    </div>
+                    <div style="margin-top: 10px;">
+                        成功:<span style="color: #00b42a; font-weight: bold;">{{ batchPushSuccess }}</span>
+                        失败:<span style="color: #f53f3f; font-weight: bold;">{{ batchPushFail }}</span>
+                    </div>
+                    <div style="margin-top: 20px; color: #86909c;">
+                        处理中,请稍候...
+                    </div>
+                </div>
+                <div v-else>
+                    <a-result status="success" title="推送完成">
+                        <template #subtitle>
+                            <div>
+                                共处理 {{ batchPushTotal }} 条数据,
+                                成功:<span style="color: #00b42a; font-weight: bold;">{{ batchPushSuccess }}</span>
+                                失败:<span style="color: #f53f3f; font-weight: bold;">{{ batchPushFail }}</span>
+                            </div>
+                        </template>
+                    </a-result>
+                </div>
+            </div>
+        </a-modal>
     </div>
 </template>
 
@@ -359,7 +407,7 @@ const generateFormModel = () => {
         status: -1,
         is_settlement: -1,
         report_date: dayjs().format('YYYY-MM-DD'),
-        sort: 'id',
+        sort: 'report_date',
         order: 'descending',
     };
 };
@@ -640,6 +688,10 @@ const fetchData = async (
         renderData.value = data.list;
         pagination.current = data.page;
         pagination.total = data.count;
+        
+        // Clear selection when data is refreshed
+        selectedRowKeys.value = [];
+        selectedRows.value = [];
 
         // Recalculate table height after data is loaded
         nextTick(() => {
@@ -1018,6 +1070,78 @@ const calculateTableHeight = () => {
     // Subtract header(64px), breadcrumb(40px), padding(40px), search area, table header(56px), pagination(56px)
     tableHeight.value = vh - searchHeight - 380;
 };
+
+// Add after renderData declaration
+const selectedRowKeys = ref<(string | number)[]>([]);
+const selectedRows = ref<PushDataReportRecord[]>([]);
+
+// 在 setup 中添加这些变量用于跟踪批量推送进度
+const batchPushModalVisible = ref(false);
+const batchPushProgress = ref(0);
+const batchPushTotal = ref(0);
+const batchPushSuccess = ref(0);
+const batchPushFail = ref(0);
+const batchPushModalLoading = ref(false);
+
+// 修改的批量推送函数
+const onBatchPush = async () => {
+    if (selectedRowKeys.value.length === 0) {
+        Message.warning('请选择要推送的数据');
+        return;
+    }
+
+    Modal.confirm({
+        title: '批量推送确认',
+        content: `确定要推送 ${selectedRowKeys.value.length} 条数据吗?推送过程中请勿关闭页面。`,
+        onOk: async () => {
+            // 重置进度变量
+            batchPushProgress.value = 0;
+            batchPushTotal.value = selectedRowKeys.value.length;
+            batchPushSuccess.value = 0;
+            batchPushFail.value = 0;
+            batchPushModalLoading.value = true;
+            batchPushModalVisible.value = true;
+            
+            // 处理每条数据
+            for (let i = 0; i < selectedRowKeys.value.length; i += 1) {
+                const id = Number(selectedRowKeys.value[i]);
+                try {
+                    // eslint-disable-next-line no-await-in-loop
+                    const response = await pushReport(id);
+                    if (response.data && response.data.success) {
+                        batchPushSuccess.value += 1;
+                    } else {
+                        batchPushFail.value += 1;
+                    }
+                } catch (error) {
+                    batchPushFail.value += 1;
+                }
+                
+                // 更新进度
+                batchPushProgress.value = i + 1;
+                
+                // 使用 nextTick 确保界面刷新
+                // eslint-disable-next-line no-await-in-loop
+                await nextTick();
+            }
+            
+            // 任务完成
+            batchPushModalLoading.value = false;
+        },
+        onCancel: () => {
+            // 用户取消操作
+        }
+    });
+};
+
+// 修改函数类型定义
+const handleBatchPushComplete = (done: () => void) => {
+    // 清空选择并刷新数据
+    selectedRowKeys.value = [];
+    selectedRows.value = [];
+    search();
+    done(); // 关闭对话框
+};
 </script>
 
 <script lang="ts">
@@ -1096,4 +1220,24 @@ export default {
         }
     }
 }
+
+:deep(.arco-checkbox) {
+  z-index: 1;
+  pointer-events: auto !important;
+}
+
+:deep(.arco-table-th-item .arco-checkbox),
+:deep(.arco-table-td .arco-checkbox) {
+  pointer-events: auto !important;
+}
+
+:deep(.arco-modal-body) {
+  font-size: 14px;
+  line-height: 1.5;
+}
+
+:deep(.arco-modal-title) {
+  font-weight: bold;
+  color: var(--color-text-1);
+}
 </style>