# 数据订单 API 前端开发指南 > **模块说明**: 数据订单 API 提供数据需求订单的创建、分析、审批、驳回、完成等全生命周期管理功能。当用户在数据服务列表中找不到所需数据时,可以发起数据订单,系统会通过 LLM 提取实体并检测业务领域图谱的连通性。 > > **基础路径**: `/api/dataservice` --- ## 目录 - [功能概述](#功能概述) - [业务流程](#业务流程) - [通用说明](#通用说明) - [响应格式](#响应格式) - [错误码说明](#错误码说明) - [订单状态说明](#订单状态说明) - [Axios 配置](#axios-配置) - [接口列表](#接口列表) 1. [获取数据订单列表](#1-获取数据订单列表) 2. [获取数据订单详情](#2-获取数据订单详情) 3. [创建数据订单](#3-创建数据订单) 4. [分析数据订单](#4-分析数据订单) 5. [审批通过订单](#5-审批通过订单) 6. [驳回订单](#6-驳回订单) 7. [完成订单](#7-完成订单) 8. [删除订单](#8-删除订单) - [API 模块封装](#api-模块封装) - [完整页面示例](#完整页面示例) - [常见问题](#常见问题) --- ## 功能概述 数据订单功能允许用户: 1. **提交数据需求**: 描述需要什么样的数据 2. **智能分析**: 系统通过 LLM 自动提取业务领域和数据字段 3. **连通性检测**: 在业务领域图谱中检测实体间的关联关系 4. **审批流程**: 支持人工审批、驳回和补充信息 5. **结果追踪**: 关联生成的数据产品和数据流 --- ## 业务流程 ``` ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 待处理 │───>│ 分析中 │───>│ 加工中/ │───>│ 已完成 │ │ (pending) │ │ (analyzing) │ │ 待人工处理 │ │ (completed) │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ │ │ │ v v v ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ 已驳回 │ │ 待补充 │ │ 已更新 │ │ (rejected) │ │(need_supple)│ │ (updated) │ └─────────────┘ └─────────────┘ └─────────────┘ ``` **典型流程:** 1. 用户创建订单 → `pending` 2. 触发分析 → `analyzing` 3. 分析完成后: - 如果可连通 → `processing` (可自动提交数据任务) - 如果不可连通 → `need_supplement` 或 `manual_review` 4. 审批通过 → `processing` 5. 完成 → `completed` --- ## 通用说明 ### 响应格式 所有接口返回统一的 JSON 格式: ```json { "code": 200, "message": "操作成功", "data": { ... } } ``` | 字段 | 类型 | 说明 | |------|------|------| | `code` | number | 状态码,200 表示成功,其他表示失败 | | `message` | string | 操作结果描述信息 | | `data` | object \| array \| null | 返回的数据内容 | ### 错误码说明 | 状态码 | 说明 | 常见场景 | |--------|------|----------| | 200 | 成功 | 操作成功完成 | | 400 | 请求参数错误 | 缺少必填字段、参数格式错误、驳回原因为空 | | 404 | 资源不存在 | 数据订单 ID 不存在 | | 500 | 服务器内部错误 | 数据库连接失败、LLM 调用失败、图谱查询异常 | ### 订单状态说明 | 状态值 | 中文标签 | 说明 | 可执行操作 | |--------|----------|------|------------| | `pending` | 待处理 | 订单刚创建,等待分析 | 分析、删除 | | `analyzing` | 分析中 | 正在进行 LLM 提取和图谱分析 | - | | `processing` | 加工中 | 审批通过,正在生成数据流/数据产品 | 完成 | | `completed` | 已完成 | 订单处理完成 | 删除 | | `rejected` | 已驳回 | 订单被驳回 | 删除 | | `need_supplement` | 待补充 | 需要用户补充信息 | 更新、分析 | | `manual_review` | 待人工处理 | 需要人工审核 | 审批、驳回 | | `updated` | 已更新 | 用户已更新订单信息 | 分析 | ### Axios 配置 建议的 Axios 全局配置: ```javascript // src/utils/request.js import axios from 'axios' import { ElMessage } from 'element-plus' const request = axios.create({ baseURL: process.env.VUE_APP_API_BASE_URL || 'http://localhost:5050', timeout: 60000, // 分析接口可能需要较长时间 headers: { 'Content-Type': 'application/json' } }) // 响应拦截器 request.interceptors.response.use( response => { const res = response.data if (res.code !== 200) { ElMessage.error(res.message || '请求失败') return Promise.reject(new Error(res.message || 'Error')) } return res }, error => { ElMessage.error(error.message || '网络错误') return Promise.reject(error) } ) export default request ``` --- ## 接口列表 --- ### 1. 获取数据订单列表 分页获取数据订单列表,支持搜索和状态过滤。 #### 请求信息 | 项目 | 说明 | |------|------| | **URL** | `GET /api/dataservice/orderlist` | | **Method** | GET | | **Content-Type** | - | #### 请求参数 (Query String) | 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | `page` | integer | 否 | 1 | 页码 | | `page_size` | integer | 否 | 20 | 每页数量 | | `search` | string | 否 | "" | 搜索关键词(匹配标题、描述) | | `status` | string | 否 | - | 状态过滤,见[订单状态说明](#订单状态说明) | #### 响应数据 ```json { "code": 200, "message": "获取数据订单列表成功", "data": { "list": [ { "id": 1, "order_no": "DO202412260001", "title": "员工与部门关联数据", "description": "需要获取员工信息和所属部门的关联数据,包括部门层级", "extracted_domains": ["员工", "部门", "组织架构"], "extracted_fields": ["员工ID", "姓名", "部门ID", "部门名称"], "extraction_purpose": "用于人力资源分析报表", "graph_analysis": { "matched_domains": 3, "matched_fields": 4, "connection_score": 0.85 }, "can_connect": true, "connection_path": { "nodes": ["员工", "部门"], "relationships": ["属于"] }, "status": "completed", "status_label": "已完成", "reject_reason": null, "result_product_id": 15, "result_dataflow_id": 28, "created_by": "张三", "created_at": "2024-12-26T09:00:00", "updated_at": "2024-12-26T14:30:00", "processed_by": "admin", "processed_at": "2024-12-26T14:30:00" } ], "pagination": { "page": 1, "page_size": 20, "total": 45, "total_pages": 3 } } } ``` #### 数据订单字段说明 | 字段 | 类型 | 说明 | |------|------|------| | `id` | integer | 订单唯一 ID | | `order_no` | string | 订单编号,格式: DO + YYYYMMDD + 4位序列号 | | `title` | string | 订单标题 | | `description` | string | 需求描述 | | `extracted_domains` | array \| null | LLM 提取的业务领域列表 | | `extracted_fields` | array \| null | LLM 提取的数据字段列表 | | `extraction_purpose` | string \| null | LLM 提取的数据用途 | | `graph_analysis` | object \| null | 图谱连通性分析结果 | | `can_connect` | boolean \| null | 是否可在图谱中连通 | | `connection_path` | object \| null | 连通路径详情 | | `status` | string | 订单状态 | | `status_label` | string | 状态中文标签 | | `reject_reason` | string \| null | 驳回原因(仅状态为 rejected 时有值) | | `result_product_id` | integer \| null | 生成的数据产品 ID | | `result_dataflow_id` | integer \| null | 生成的数据流 ID | | `created_by` | string | 创建人 | | `created_at` | string | 创建时间(ISO 8601 格式) | | `updated_at` | string | 更新时间 | | `processed_by` | string \| null | 处理人 | | `processed_at` | string \| null | 处理时间 | #### Vue 接入示例 ```vue ``` --- ### 2. 获取数据订单详情 根据 ID 获取单个数据订单的详细信息。 #### 请求信息 | 项目 | 说明 | |------|------| | **URL** | `GET /api/dataservice/orders/{order_id}` | | **Method** | GET | | **Content-Type** | - | #### 路径参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `order_id` | integer | 是 | 数据订单 ID | #### 响应数据 ```json { "code": 200, "message": "获取数据订单详情成功", "data": { "id": 1, "order_no": "DO202412260001", "title": "员工与部门关联数据", "description": "需要获取员工信息和所属部门的关联数据,包括部门层级结构,用于生成人力资源分析报表。", "extracted_domains": ["员工", "部门", "组织架构"], "extracted_fields": ["员工ID", "姓名", "部门ID", "部门名称", "上级部门"], "extraction_purpose": "用于人力资源分析报表", "graph_analysis": { "matched_domains": [ { "name": "员工", "node_id": "domain_001", "match_score": 1.0 }, { "name": "部门", "node_id": "domain_002", "match_score": 1.0 } ], "matched_fields": [ { "name": "员工ID", "field_id": "field_001", "domain": "员工" }, { "name": "部门ID", "field_id": "field_002", "domain": "部门" } ], "connection_analysis": { "paths_found": 2, "shortest_path_length": 1 } }, "can_connect": true, "connection_path": { "nodes": ["员工", "部门"], "relationships": ["属于"], "path_detail": [ { "from": "员工", "to": "部门", "relation": "属于", "common_fields": ["部门ID"] } ] }, "status": "completed", "status_label": "已完成", "reject_reason": null, "result_product_id": 15, "result_dataflow_id": 28, "created_by": "张三", "created_at": "2024-12-26T09:00:00", "updated_at": "2024-12-26T14:30:00", "processed_by": "admin", "processed_at": "2024-12-26T14:30:00" } } ``` #### 错误响应 **订单不存在 (404):** ```json { "code": 404, "message": "数据订单不存在", "data": null } ``` #### Vue 接入示例 ```vue ``` --- ### 3. 创建数据订单 创建新的数据需求订单。 #### 请求信息 | 项目 | 说明 | |------|------| | **URL** | `POST /api/dataservice/neworder` | | **Method** | POST | | **Content-Type** | application/json | #### 请求体参数 | 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | `title` | string | 是 | - | 订单标题,最大 200 字符 | | `description` | string | 是 | - | 需求描述,详细说明需要什么数据 | | `created_by` | string | 否 | "user" | 创建人标识 | #### 请求示例 ```json { "title": "员工与部门关联数据", "description": "需要获取员工信息和所属部门的关联数据,包括:\n1. 员工基本信息(ID、姓名、入职日期)\n2. 部门信息(部门ID、部门名称)\n3. 部门层级关系\n\n用途:生成人力资源分析报表", "created_by": "张三" } ``` #### 响应数据 ```json { "code": 200, "message": "创建数据订单成功", "data": { "id": 1, "order_no": "DO202412260001", "title": "员工与部门关联数据", "description": "需要获取员工信息和所属部门的关联数据...", "extracted_domains": null, "extracted_fields": null, "extraction_purpose": null, "graph_analysis": null, "can_connect": null, "connection_path": null, "status": "pending", "status_label": "待处理", "reject_reason": null, "result_product_id": null, "result_dataflow_id": null, "created_by": "张三", "created_at": "2024-12-26T09:00:00", "updated_at": "2024-12-26T09:00:00", "processed_by": null, "processed_at": null } } ``` #### 错误响应 **缺少必填字段 (400):** ```json { "code": 400, "message": "缺少必填字段: title", "data": null } ``` **请求体为空 (400):** ```json { "code": 400, "message": "请求数据不能为空", "data": null } ``` #### Vue 接入示例 ```vue ``` --- ### 4. 分析数据订单 触发 LLM 实体提取和业务领域图谱连通性分析。 #### 请求信息 | 项目 | 说明 | |------|------| | **URL** | `POST /api/dataservice/orders/{order_id}/analyze` | | **Method** | POST | | **Content-Type** | application/json | #### 路径参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `order_id` | integer | 是 | 数据订单 ID | #### 请求体 无需请求体。 #### 响应数据 分析成功后返回更新后的订单数据: ```json { "code": 200, "message": "数据订单分析完成", "data": { "id": 1, "order_no": "DO202412260001", "title": "员工与部门关联数据", "description": "...", "extracted_domains": ["员工", "部门", "组织架构"], "extracted_fields": ["员工ID", "姓名", "部门ID", "部门名称"], "extraction_purpose": "用于人力资源分析报表", "graph_analysis": { "matched_domains": [ { "name": "员工", "node_id": "domain_001", "match_score": 1.0 }, { "name": "部门", "node_id": "domain_002", "match_score": 1.0 } ], "matched_fields": 4, "unmatched_domains": ["组织架构"], "connection_analysis": { "paths_found": 2, "shortest_path_length": 1 } }, "can_connect": true, "connection_path": { "nodes": ["员工", "部门"], "relationships": ["属于"], "common_fields": ["部门ID"] }, "status": "processing", "status_label": "加工中", "updated_at": "2024-12-26T09:15:00" } } ``` **分析结果说明:** | 结果 | 说明 | 后续状态 | |------|------|----------| | `can_connect: true` | 所有实体都能在图谱中连通 | `processing` (可自动生成数据流) | | `can_connect: false` | 存在无法连通的实体 | `need_supplement` 或 `manual_review` | #### 错误响应 **订单不存在:** ```json { "code": 404, "message": "数据订单不存在", "data": null } ``` **分析失败:** ```json { "code": 500, "message": "分析数据订单失败: LLM 服务调用超时", "data": null } ``` #### Vue 接入示例 ```javascript const analyzeOrder = async (orderId) => { try { // 显示分析中提示 const loadingInstance = ElLoading.service({ text: '正在分析订单,可能需要几秒钟...', background: 'rgba(0, 0, 0, 0.7)' }) const res = await request.post(`/api/dataservice/orders/${orderId}/analyze`) loadingInstance.close() // 根据分析结果显示不同提示 if (res.data.can_connect) { ElMessage.success('分析完成,实体可连通!') } else { ElMessage.warning('分析完成,部分实体无法连通,需要补充信息或人工处理') } // 刷新订单详情 fetchDetail(orderId) return res.data } catch (error) { ElMessage.error(error.message || '分析失败') throw error } } ``` --- ### 5. 审批通过订单 审批通过数据订单,将状态更新为 `processing`。 #### 请求信息 | 项目 | 说明 | |------|------| | **URL** | `POST /api/dataservice/orders/{order_id}/approve` | | **Method** | POST | | **Content-Type** | application/json | #### 路径参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `order_id` | integer | 是 | 数据订单 ID | #### 请求体参数 | 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | `processed_by` | string | 否 | "admin" | 处理人标识 | #### 请求示例 ```json { "processed_by": "管理员A" } ``` #### 响应数据 ```json { "code": 200, "message": "数据订单审批通过", "data": { "id": 1, "order_no": "DO202412260001", "status": "processing", "status_label": "加工中", "processed_by": "管理员A", "processed_at": "2024-12-26T10:00:00", "updated_at": "2024-12-26T10:00:00" } } ``` #### 错误响应 **订单状态不允许审批 (400):** ```json { "code": 400, "message": "当前状态不允许审批操作", "data": null } ``` #### Vue 接入示例 ```javascript const approveOrder = async (orderId) => { try { await ElMessageBox.confirm( '确定要审批通过该订单吗?通过后将开始生成数据流。', '审批确认', { type: 'warning' } ) const res = await request.post(`/api/dataservice/orders/${orderId}/approve`, { processed_by: currentUser.value.name }) ElMessage.success('审批通过') fetchOrders() // 刷新列表 return res.data } catch (error) { if (error !== 'cancel') { ElMessage.error(error.message || '审批失败') } } } ``` --- ### 6. 驳回订单 驳回数据订单,需要提供驳回原因。 #### 请求信息 | 项目 | 说明 | |------|------| | **URL** | `POST /api/dataservice/orders/{order_id}/reject` | | **Method** | POST | | **Content-Type** | application/json | #### 路径参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `order_id` | integer | 是 | 数据订单 ID | #### 请求体参数 | 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | `reason` | string | 是 | - | 驳回原因 | | `processed_by` | string | 否 | "admin" | 处理人标识 | #### 请求示例 ```json { "reason": "需求描述不够清晰,请补充具体需要的数据字段和业务场景", "processed_by": "管理员A" } ``` #### 响应数据 ```json { "code": 200, "message": "数据订单已驳回", "data": { "id": 1, "order_no": "DO202412260001", "status": "rejected", "status_label": "已驳回", "reject_reason": "需求描述不够清晰,请补充具体需要的数据字段和业务场景", "processed_by": "管理员A", "processed_at": "2024-12-26T10:00:00", "updated_at": "2024-12-26T10:00:00" } } ``` #### 错误响应 **驳回原因为空 (400):** ```json { "code": 400, "message": "驳回原因不能为空", "data": null } ``` #### Vue 接入示例 ```vue ``` --- ### 7. 完成订单 将订单标记为完成,可关联生成的数据产品和数据流。 #### 请求信息 | 项目 | 说明 | |------|------| | **URL** | `POST /api/dataservice/orders/{order_id}/complete` | | **Method** | POST | | **Content-Type** | application/json | #### 路径参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `order_id` | integer | 是 | 数据订单 ID | #### 请求体参数 | 参数名 | 类型 | 必填 | 默认值 | 说明 | |--------|------|------|--------|------| | `product_id` | integer | 否 | null | 生成的数据产品 ID | | `dataflow_id` | integer | 否 | null | 生成的数据流 ID | | `processed_by` | string | 否 | "system" | 处理人标识 | #### 请求示例 ```json { "product_id": 15, "dataflow_id": 28, "processed_by": "system" } ``` #### 响应数据 ```json { "code": 200, "message": "数据订单已完成", "data": { "id": 1, "order_no": "DO202412260001", "status": "completed", "status_label": "已完成", "result_product_id": 15, "result_dataflow_id": 28, "processed_by": "system", "processed_at": "2024-12-26T14:30:00", "updated_at": "2024-12-26T14:30:00" } } ``` #### Vue 接入示例 ```javascript const completeOrder = async (orderId, productId = null, dataflowId = null) => { try { const res = await request.post(`/api/dataservice/orders/${orderId}/complete`, { product_id: productId, dataflow_id: dataflowId, processed_by: 'system' }) ElMessage.success('订单已完成') return res.data } catch (error) { ElMessage.error(error.message || '操作失败') throw error } } ``` --- ### 8. 删除订单 删除数据订单记录。 #### 请求信息 | 项目 | 说明 | |------|------| | **URL** | `DELETE /api/dataservice/orders/{order_id}` | | **Method** | DELETE | | **Content-Type** | - | #### 路径参数 | 参数名 | 类型 | 必填 | 说明 | |--------|------|------|------| | `order_id` | integer | 是 | 数据订单 ID | #### 响应数据 ```json { "code": 200, "message": "删除数据订单成功", "data": {} } ``` #### 错误响应 **订单不存在 (404):** ```json { "code": 404, "message": "数据订单不存在", "data": null } ``` #### Vue 接入示例 ```javascript const deleteOrder = async (orderId) => { try { await ElMessageBox.confirm( '确定要删除该订单吗?此操作不可恢复。', '删除确认', { type: 'warning', confirmButtonClass: 'el-button--danger' } ) await request.delete(`/api/dataservice/orders/${orderId}`) ElMessage.success('删除成功') // 从列表中移除 orderList.value = orderList.value.filter(o => o.id !== orderId) } catch (error) { if (error !== 'cancel') { ElMessage.error(error.message || '删除失败') } } } ``` --- ## API 模块封装 建议将所有数据订单 API 封装到独立模块: ```javascript // src/api/dataOrder.js import request from '@/utils/request' const BASE_URL = '/api/dataservice' export const dataOrderApi = { /** * 获取数据订单列表 * @param {Object} params - 查询参数 * @param {number} params.page - 页码 * @param {number} params.page_size - 每页数量 * @param {string} params.search - 搜索关键词 * @param {string} params.status - 状态过滤 */ getOrders(params) { return request.get(`${BASE_URL}/orderlist`, { params }) }, /** * 获取数据订单详情 * @param {number} orderId - 订单 ID */ getOrderDetail(orderId) { return request.get(`${BASE_URL}/orders/${orderId}`) }, /** * 创建数据订单 * @param {Object} data - 订单数据 * @param {string} data.title - 订单标题 * @param {string} data.description - 需求描述 * @param {string} [data.created_by] - 创建人 */ createOrder(data) { return request.post(`${BASE_URL}/neworder`, data) }, /** * 分析数据订单 * @param {number} orderId - 订单 ID */ analyzeOrder(orderId) { return request.post(`${BASE_URL}/orders/${orderId}/analyze`) }, /** * 审批通过订单 * @param {number} orderId - 订单 ID * @param {string} [processedBy] - 处理人 */ approveOrder(orderId, processedBy = 'admin') { return request.post(`${BASE_URL}/orders/${orderId}/approve`, { processed_by: processedBy }) }, /** * 驳回订单 * @param {number} orderId - 订单 ID * @param {string} reason - 驳回原因 * @param {string} [processedBy] - 处理人 */ rejectOrder(orderId, reason, processedBy = 'admin') { return request.post(`${BASE_URL}/orders/${orderId}/reject`, { reason, processed_by: processedBy }) }, /** * 完成订单 * @param {number} orderId - 订单 ID * @param {Object} [options] - 可选参数 * @param {number} [options.productId] - 数据产品 ID * @param {number} [options.dataflowId] - 数据流 ID * @param {string} [options.processedBy] - 处理人 */ completeOrder(orderId, options = {}) { return request.post(`${BASE_URL}/orders/${orderId}/complete`, { product_id: options.productId, dataflow_id: options.dataflowId, processed_by: options.processedBy || 'system' }) }, /** * 删除订单 * @param {number} orderId - 订单 ID */ deleteOrder(orderId) { return request.delete(`${BASE_URL}/orders/${orderId}`) } } export default dataOrderApi ``` --- ## 完整页面示例 以下是一个完整的数据订单管理页面示例: ```vue ``` --- ## 常见问题 ### Q1: 分析接口超时怎么办? **A**: 分析接口涉及 LLM 调用,可能需要较长时间。建议: 1. 设置较长的 `timeout`(如 60 秒) 2. 显示 loading 状态给用户 3. 后端可能需要优化 LLM 调用效率 ### Q2: 什么情况下订单会变成 `need_supplement`? **A**: 当 LLM 提取的实体在业务领域图谱中无法完全匹配时,订单会变成 `need_supplement` 状态,提示用户补充更多信息。 ### Q3: 如何判断订单是否可以自动生成数据流? **A**: 当 `can_connect` 为 `true` 时,表示所有实体都能在图谱中连通,理论上可以自动生成数据流。但具体实现取决于后端数据流生成逻辑。 ### Q4: 订单编号的格式是什么? **A**: 格式为 `DO` + `YYYYMMDD` + `4位序列号`,例如 `DO202412260001`。每天的序列号从 `0001` 开始递增。 ### Q5: 可以修改已提交的订单吗? **A**: 目前 API 不支持直接修改订单。如果需要修改,可以: 1. 删除原订单并创建新订单 2. 后续版本可能会增加编辑功能 --- ## 更新日志 | 版本 | 日期 | 说明 | |------|------|------| | 1.0.0 | 2024-12-29 | 初始版本,包含完整的数据订单 API 文档 |