浏览代码

完善爬虫数据页面

jihuaqiang 1 月之前
父节点
当前提交
4aa42200e4
共有 7 个文件被更改,包括 241 次插入6 次删除
  1. 二进制
      public/favicon.ico
  2. 9 0
      public/index.html
  3. 0 1
      src/App.vue
  4. 1 0
      src/config.ts
  5. 39 0
      src/types/DataCrawing.ts
  6. 180 4
      src/views/DataCrawling/index.vue
  7. 12 1
      vue.config.js

二进制
public/favicon.ico


+ 9 - 0
public/index.html

@@ -7,6 +7,15 @@
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <title><%= htmlWebpackPlugin.options.title %></title>
   </head>
+  <style>
+    body {
+      margin: 0;
+      padding: 0;
+    }
+    div {
+      box-sizing: border-box;
+    }
+  </style>
   <body>
     <noscript>
       <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>

+ 0 - 1
src/App.vue

@@ -18,5 +18,4 @@ export default defineComponent({
 </script>
 
 <style scoped>
-
 </style>

+ 1 - 0
src/config.ts

@@ -1,2 +1,3 @@
 export const API_BASE_URL = "http://61.48.133.26:8001/api";
+export const DATA_CRAWLING_BASE_URL = "/api/crawling";
 // export const API_BASE_URL = "http://127.0.0.1:8001/api";

+ 39 - 0
src/types/DataCrawing.ts

@@ -0,0 +1,39 @@
+export enum KnowledgeType {
+    内容知识 = '内容知识',
+    工具知识 = '工具知识',
+}
+
+export enum QueryTypeEnum {
+    How = 'How',
+    What = 'What',
+    Pattern = 'Pattern',
+}
+
+export enum NeedStoreEnum {
+    不需要存储 = 0,
+    需要存储 = 1,
+}
+
+export enum TaskStatusEnum {
+    '待处理' = 0,
+    '处理中' = 1,
+    '已完成' = 2,
+    '失败' = 3,
+}
+
+export interface QueryTask {
+    query: string;
+    knowledgeType: KnowledgeType;
+    suggestTaskId: string;
+}
+
+export interface QuestionTask {
+    question: string;
+    task_id: string;
+    status: TaskStatusEnum;
+    queries: QueryTask[];
+    knowledgeType: KnowledgeType;
+    queryType: QueryTypeEnum;
+    need_store: NeedStoreEnum;
+
+}

+ 180 - 4
src/views/DataCrawling/index.vue

@@ -1,17 +1,193 @@
 <template>
-  <div>
-    <h1>数据爬取</h1>
+  <div class="app-container">
+    <div class="pagination-container" v-loading.fullscreen.lock="loading">
+        <div class="tasks-container">
+            <div class="tasks">
+                <div 
+                    class="task-item" 
+                    v-for="task in questionTasks" 
+                    :key="task.task_id"
+                    :class="{ 'task-item-selected': selectedTaskId === task.task_id }"
+                    @click="handleTaskClick(task.task_id)"
+                >
+                    <div class="task-question">{{ task.question }}</div>
+                </div>
+            </div>
+            <div class="pagination">
+                <el-pagination
+                    @current-change="handleCurrentChange"
+                    :current-page="pageNumber"
+                    :page-size="pageSize"
+                    :total="total"
+                    layout="prev, pager, next"
+                />
+            </div>
+        </div>
+        <div class="task-detail-container">
+            <div class="task-detail-id">{{ selectedTask?.task_id }}</div>
+            <div class="task-detail-status">{{ selectedTask?.status }}</div>
+            <div class="task-detail-created_at" v-for="query in selectedTask?.queries" :key="query.query">
+                {{ query.query }}
+            </div>
+        </div>
+    </div>
+    
   </div>
 </template>
 
 <script lang="ts">
-import { defineComponent } from 'vue';
+import { defineComponent, ref, watch } from 'vue';
+import { ElPagination } from 'element-plus';
+import { DATA_CRAWLING_BASE_URL } from "@/config";
+import axios from 'axios';
+import { QuestionTask } from '@/types/DataCrawing';
 
 export default defineComponent({
-  name: 'DataCrawling',
+    name: 'DataCrawling',
+    components: {
+        ElPagination,
+    },
+    setup() {
+        const questionTasks = ref<QuestionTask[]>([]);
+        const pageNumber = ref(1);
+        const pageSize = ref(10);
+        const total = ref(0);
+        const loading = ref(false);
+        const selectedTaskId = ref<string | null>(null);
+        const selectedTask = ref<QuestionTask | null>(null);
+        // 监听selectedTaskId变化
+        watch(selectedTaskId, (newVal) => {
+            selectedTask.value = questionTasks.value.find(task => task.task_id === newVal) || null;
+        });
+        const fetchData = async () => {
+            loading.value = true;
+            try {
+                const response = await axios.get(`${DATA_CRAWLING_BASE_URL}/tasks`, {
+                    params: {
+                        page_number: pageNumber.value,
+                        page_size: pageSize.value,
+                    },
+                });
+                console.log('Response:', response);
+                if (response && response.data) {
+                    questionTasks.value = response.data.tasks;
+                    total.value = response.data.total;
+                    selectedTaskId.value = response.data.tasks[0]?.task_id || null;
+                }
+            } catch (error) {
+                console.error('Error fetching data:', error);
+            } finally {
+                loading.value = false;
+            }
+        };
+        const handleCurrentChange = (newPage: number) => {
+            pageNumber.value = newPage;
+            fetchData();
+        };
+        const handleTaskClick = (taskId: string) => {
+            selectedTaskId.value = taskId;
+        };
+        fetchData();
+        return {
+            questionTasks,
+            pageNumber,
+            pageSize,
+            total,
+            handleCurrentChange,
+            loading,
+            selectedTaskId,
+            selectedTask,
+            handleTaskClick,
+        };
+    },
 });
 </script>
 
 <style scoped>
+.app-container {
+    min-height: calc(100vh - 71px);
+    background: rgba(138,147,228,0.1);
+    font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
+}
+.pagination-container {
+    box-sizing: border-box;
+    height: calc(100vh - 90px);
+    max-height: calc(100vh - 90px);
+    display: flex;
+    justify-content: center;
+    align-items: flex-start;
+    gap: 10px;
+}
+.tasks-container {
+    display: flex;
+    box-sizing: border-box;
+    padding-top: 20px;
+    flex-direction: column;
+    justify-content: space-between;
+    align-items: flex-start;
+    width: 30%;
+    height: 100%;
+    overflow-y: auto;
+}
 
+.task-detail-container {
+    box-sizing: border-box;
+    flex: 1;
+    padding: 20px;
+    margin-top: 20px;
+    margin-right: 20px;
+    height: calc(100vh - 110px);
+    max-height: calc(100vh - 110px);
+    overflow-y: auto;
+    background: white;
+    border-radius: 8px;
+    box-shadow: 0 4px 12px rgba(138, 147, 228, 0.15);
+    border: 1px solid #e2e8f0;
+}
+
+.pagination {
+    width: 80%;
+    padding: 0 10px 0 20px;
+}
+
+.tasks {
+    box-sizing: border-box;
+    width: 100%;
+    padding: 0 5px 0 20px;
+}
+
+.task-item {
+    box-sizing: border-box;
+    padding: 16px 20px;
+    margin-bottom: 12px;
+    background: white;
+    border-radius: 8px;
+    cursor: pointer;
+    transition: all 0.3s ease;
+    border: 2px solid transparent;
+    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
+}
+
+.task-item:hover {
+    border-color: rgba(138, 147, 228, 0.4);
+    box-shadow: 0 4px 12px rgba(138, 147, 228, 0.15);
+    transform: translateY(-2px);
+}
+
+.task-item-selected {
+    background: rgba(138, 147, 228, 0.3);
+    border-color: rgb(138, 147, 228);
+    box-shadow: 0 4px 12px rgba(138, 147, 228, 0.25);
+}
+
+.task-item-selected:hover {
+    background: rgba(138, 147, 228, 0.15);
+}
+
+.task-question {
+    font-size: 14px;
+    color: #333;
+    line-height: 1.6;
+    font-weight: 500;
+}
 </style>

+ 12 - 1
vue.config.js

@@ -1,4 +1,15 @@
 const { defineConfig } = require('@vue/cli-service')
 module.exports = defineConfig({
-  transpileDependencies: true
+  transpileDependencies: true,
+  devServer: {
+    proxy: {
+      '/api/crawling': {
+        target: 'http://8.219.186.16:8079',
+        changeOrigin: true,
+        pathRewrite: {
+          '^/api/crawling': ''
+        }
+      }
+    }
+  }
 })