Browse Source

开放平台接入说明

cynthia-qin 1 month ago
parent
commit
3b030ae81c

+ 4 - 2
src/components/SideMenu.vue

@@ -2,7 +2,6 @@
   <div class="left-nav">
     <el-menu
       default-active="1-1"
-      :unique-opened="true"
       class="el-menu-vertical-demo">
       <el-sub-menu index="1">
         <template #title>
@@ -203,7 +202,7 @@ const selectWorker = (worker: Worker) => {
 <style scoped lang="less">
 .left-nav {
   // width: 280px;
-  // height: 100vh;
+  height: 100vh;
   // border-right: 0px solid #e4e7ed;
   // padding: 20px;
   // overflow: auto;
@@ -219,4 +218,7 @@ const selectWorker = (worker: Worker) => {
     }
   }
 }
+.el-menu-vertical-demo {
+  height: 100%;
+}
 </style>

+ 8 - 1
src/router/index.ts

@@ -129,11 +129,18 @@ const router = createRouter({
         {
           path: "openplatform",
           name: "openplatform",
+          redirect: "/kmplatform/openplatform/queue/0",
           meta: {
             title: "开放平台",
           },
           component: OpenPlatform,
-          children: [],
+          children: [
+             {
+                  path: "queue/:id",
+                  name: "platformText",
+                  component: () => import("@/views/KMPlatform/OpenPlatform/platformText.vue"),
+                },
+          ],
         },
         {
           path: "kgpermission",

+ 44 - 4
src/views/KMPlatform/OpenPlatform/OpenPlatform.vue

@@ -1,11 +1,51 @@
 <template>
-  <div class="open-platform">
-    开放平台
-  </div>
+    <el-container class="main-container">
+    <el-container>
+      <el-aside class="main-aside">
+           <!-- 开放平台 -->
+    <el-menu
+      default-active="1-1"
+      :unique-opened="true"
+      class="el-menu-open-platform">
+        <el-sub-menu index="1">
+        <template #title>
+          <i class="el-icon-location"></i>
+          <span>API文档</span>
+        </template>
+        <el-menu-item-group>
+          <!-- <el-menu-item index="1-1"  >简介</el-menu-item> -->
+          <el-menu-item index="1-1"  @click="handlePath('0')">API概览</el-menu-item>
+        </el-menu-item-group>
+        <el-sub-menu index="1-3">
+            <template #title>相关接口</template>
+            <el-menu-item index="1-3-1" @click="handlePath('1')">实体查询</el-menu-item>
+            <el-menu-item index="1-3-2" @click="handlePath('2')">实体关系查询</el-menu-item>
+          </el-sub-menu>
+      </el-sub-menu>
+    </el-menu>
+      </el-aside>
+      <el-main class="content-area">
+        <!-- 主要内容区域 -->
+        <router-view v-slot="{ Component }">
+          <component :is="Component" />
+        </router-view>
+      </el-main>
+    </el-container>
+  </el-container>
 </template>
 
 <script setup>
+import { ref } from 'vue';
+import { useRouter } from 'vue-router';
+const router = useRouter();
+const handlePath = (id) => {
+    router.push({ name: 'platformText', params: { id: id } });
+};
 
 </script>
 
-<style lang="less" scoped></style>
+<style lang="less" scoped>
+.el-menu-open-platform {
+  height: 100%;
+}
+</style>

+ 454 - 0
src/views/KMPlatform/OpenPlatform/platformText.vue

@@ -0,0 +1,454 @@
+<template>
+  <div v-if="queueId === '0'">
+    <el-card class="api-doc-card">
+      <template #header>
+        <div class="card-header">
+          <span>API 接入说明</span>
+        </div>
+      </template>
+      <p>欢迎使用我们的开放平台 API!为方便开发者快速集成,请遵循以下核心接入规范:</p>
+      <!-- 使用 model-value 绑定展开项数组 -->
+      <el-collapse v-model="activeNames">
+        <el-collapse-item title="传输协议" name="1">
+          <p>所有 API 请求均通过 HTTP(S) 协议进行。</p>
+        </el-collapse-item>
+        <el-collapse-item title="数据格式" name="2">
+          <p>请求与响应数据统一采用 JSON 格式。</p>
+        </el-collapse-item>
+        <el-collapse-item title="请求方法" name="3">
+          <p>主要使用 POST 方法提交请求。</p>
+        </el-collapse-item>
+        <el-collapse-item title="认证方式" name="4">
+          <p>调用 API 需在请求头中进行身份认证。</p>
+          <p>使用标准的 Bearer Token 认证。</p>
+          <p>在 Authorization 头中携带由启真科技分配的 API_KEY。</p>
+        </el-collapse-item>
+        <el-collapse-item title="请求头要求" name="5">
+          <p>必需头信息:</p>
+          <el-table :data="headers" border style="width: 100%">
+            <el-table-column prop="paramName" label="参数名" />
+            <el-table-column prop="type" label="类型" />
+            <el-table-column prop="required" label="必填" />
+            <el-table-column prop="description" label="说明" />
+          </el-table>
+        </el-collapse-item>
+        <el-collapse-item title="POST 请求示例" name="6">
+          <el-alert
+            title="POST 请求示例"
+            type="info"
+            show-icon
+            :closable="false"
+          >
+            <div class="code-container">
+              <!-- 使用 v-html 指令渲染格式化后的代码 -->
+              <pre><code ref="codeElement" v-html="formattedPostExample" style="color: #333;"></code></pre>
+              <!-- <el-icon class="copy-icon" @click="copyCode">
+                <DocumentCopy />
+              </el-icon> -->
+            </div>
+          </el-alert>
+        </el-collapse-item>
+      </el-collapse>
+    </el-card>
+  </div>
+  <div v-if="queueId === '1'">
+    <el-card class="api-doc-card">
+      <template #header>
+        <div class="card-header">
+          <span>实体搜索 (Entity Search)</span>
+        </div>
+      </template>
+      <p>接口描述:根据给定的实体名称,执行向量相似性搜索,返回匹配的实体详情列表。结果按匹配度(相似度)由高到低排序,并支持分页查询。</p>
+      <p class="mx-10">请求方式:POST</p>
+      <p>请求地址:/v1/knowledge/nodes/paginated_search</p>
+
+      <h3>请求参数 (Request Body - JSON)</h3>
+      <el-table :data="requestParams" border style="width: 100%">
+        <el-table-column prop="fieldName" label="字段名" />
+        <el-table-column prop="name" label="名称" />
+        <el-table-column prop="type" label="类型" />
+        <el-table-column prop="required" label="必填" />
+        <el-table-column prop="description" label="描述" />
+        <el-table-column prop="defaultValue" label="默认值" />
+      </el-table>
+
+      <h3>请求示例</h3>
+      <pre><code>{{ requestExample }}</code></pre>
+
+      <h3>响应结果 (Response - JSON)</h3>
+      <el-table :data="responseParams" border style="width: 100%">
+        <el-table-column prop="fieldName" label="字段名" />
+        <el-table-column prop="name" label="名称" />
+        <el-table-column prop="type" label="类型" />
+        <el-table-column prop="description" label="描述" />
+      </el-table>
+
+      <!-- <h3>data 结构说明</h3>
+      <p>data 是一个数组,通常包含一个元素。</p>
+      <p class="mx-10">该元素的 key 固定为 "nodes"。</p>
+      <p>该元素的 value 是一个数组,包含了匹配到的实体节点列表。</p> -->
+
+      <h3>节点对象 (Node Object) 结构 (位于 data[0].value 数组中)</h3>
+      <el-table :data="nodeObjectParams" border style="width: 100%">
+        <el-table-column prop="propertyKey" label="属性 Key" />
+        <el-table-column prop="propertyName" label="属性名" />
+        <el-table-column prop="type" label="类型" />
+        <el-table-column prop="description" label="描述" />
+      </el-table>
+
+      <h3>响应示例</h3>
+      <pre><code>{{ responseExample }}</code></pre>
+    </el-card>
+  </div>
+  <div v-if="queueId === '2'">
+    <el-card class="api-doc-card">
+      <template #header>
+        <div class="card-header">
+          <span>实体关系查询 (Entity Relationships)</span>
+        </div>
+      </template>
+      <p>接口描述:根据指定的源节点ID,获取与其关联的所有关系及目标节点信息。</p>
+      <p class="mx-10">请求方式:GET</p>
+      <p>请求地址:/v1/knowledge/nodes/{srcId}/relationships</p>
+
+      <h3>路径参数</h3>
+      <el-table :data="pathParams" border style="width: 100%">
+        <el-table-column prop="paramName" label="参数名" />
+        <el-table-column prop="type" label="类型" />
+        <el-table-column prop="required" label="必填" />
+        <el-table-column prop="description" label="说明" />
+      </el-table>
+
+      <h3>响应结构 (Response - JSON)</h3>
+      <!-- <h4>顶层字段</h4> -->
+      <el-table :data="topLevelResponseParams" border style="width: 100%">
+        <el-table-column prop="fieldName" label="字段名" />
+        <el-table-column prop="name" label="名称" />
+        <el-table-column prop="type" label="类型" />
+        <el-table-column prop="description" label="描述" />
+      </el-table>
+
+      <h3>数据层级说明</h3>
+      <!-- <h4 class="mx-20 text-bold ">1.data 结构:</h4>
+       <ul style="margin-left: 20px;">
+        <li class="mx-10">包含一个固定键值对的对象数组</li>
+        <li class="mx-10">第一层key 固定为 "relationships"。</li>
+        <li class="mx-10">value 是一个数组,包含了所有关系对象。</li>
+       </ul> -->
+
+      <h4 class="mx-20 text-bold ">节点对象 (Node Object) 结构 (位于 data[0].value 数组中)</h4>
+      <el-table :data="relationshipObjectParams" border style="width: 100%">
+        <el-table-column prop="propertyKey" label="属性 Key" />
+        <el-table-column prop="propertyName" label="属性名" />
+        <el-table-column prop="type" label="类型" />
+        <el-table-column prop="description" label="描述" />
+      </el-table>
+
+      <!-- <h4 class="mx-20 text-bold ">3.目标节点 (Destination Node)</h4>
+      <el-table :data="destinationNodeParams" border style="width: 100%">
+        <el-table-column prop="propertyKey" label="属性 Key" />
+        <el-table-column prop="propertyName" label="属性名" />
+        <el-table-column prop="type" label="类型" />
+        <el-table-column prop="description" label="描述" />
+      </el-table> -->
+
+      <h3>响应示例</h3>
+      <pre><code>{{ responseExampleRelationship }}</code></pre>
+    </el-card>
+  </div>
+</template>
+<script setup>
+import { ref, watch } from 'vue';
+import { useRoute } from 'vue-router';
+import { ElMessage } from 'element-plus';
+import { DocumentCopy } from '@element-plus/icons-vue';
+
+const route = useRoute();
+let queueId = ref(route.params.id || '0'); // 默认值为 '0',表示简介
+watch(() => route.params.id, (newId) => {
+  queueId.value = newId || '0';
+});
+
+const headers = ref([
+  {
+    paramName: 'Content-Type',
+    type: 'string',
+    required: '是',
+    description: '固定为 application/json。',
+  },
+  {
+    paramName: 'Authorization',
+    type: 'string',
+    required: '是',
+    description: '格式为 Bearer {API_KEY},其中 {API_KEY} 由启真科技分配。',
+  },
+  {
+    paramName: 'request-id',
+    type: 'string',
+    required: '是',
+    description: '用于请求追踪和双方日志查询,强烈建议使用唯一标识符 (如 UUID v4 格式)。',
+  },
+]);
+
+const postExample = ref(`POST /your-api-endpoint HTTP/1.1
+Host: api.yourplatform.com
+Content-Type: application/json
+Authorization: Bearer your_api_key_here
+request-id: 9b501e56-8026-4d7d-96cc-4594742acd71
+
+{
+  ... // 具体请求体参数请参考对应接口的详细文档
+}`);
+
+// 定义一个包含所有折叠项 name 的数组
+const activeNames = ref(['1', '2', '3', '4', '5', '6']);
+
+// 格式化代码,区分请求头和请求内容
+const formattedPostExample = ref(postExample.value.replace(/(POST.*?\n.*?\n)/s, '<span class="request-header">$1</span>'));
+
+const codeElement = ref(null);
+
+const copyCode = () => {
+  if (codeElement.value) {
+    // 提取纯文本内容进行复制
+    const text = codeElement.value.textContent;
+    navigator.clipboard.writeText(text).then(() => {
+      ElMessage.success('复制成功');
+    }).catch(() => {
+      ElMessage.error('复制失败');
+    });
+  }
+};
+// 请求参数
+const requestParams = ref([
+  { fieldName: 'name', name: '节点名称', type: 'string', required: '是', description: '要搜索的实体名称,系统将基于此进行向量相似度计算。', defaultValue: '无' },
+  { fieldName: 'category', name: '节点类型', type: 'string', required: '否', description: '(可选)按节点类型过滤结果。', defaultValue: '无' },
+  { fieldName: 'distance', name: '相似度阈值', type: 'Float', required: '否', description: '向量计算的距离阈值。仅返回相似度小于等于此值的实体 (0=完全相等, 2=完全不相关)。值越小,匹配度要求越高。', defaultValue: '1.45' },
+  { fieldName: 'pageNo', name: '页码', type: 'int', required: '否', description: '指定要获取的结果页码(从 1 开始计数)。', defaultValue: '1' },
+  { fieldName: 'limit', name: '每页记录数', type: 'int', required: '否', description: '指定每页返回的最大实体数量。', defaultValue: '系统默认' }
+]);
+
+// 请求示例
+const requestExample = ref(`{
+    "name": "感冒",
+    "pageNo": 1,
+    "limit": 10
+}`);
+
+// 响应参数
+const responseParams = ref([
+  { fieldName: 'success', name: '请求状态', type: 'Boolean', description: 'true 表示请求成功处理;false 表示发生错误。' },
+  { fieldName: 'errorCode', name: '错误码', type: 'string', description: '请求失败时返回的错误代码。成功时为 null。' },
+  { fieldName: 'errorMsg', name: '错误信息', type: 'string', description: '请求失败时返回的错误描述信息。成功时为 null。' },
+  { fieldName: 'requestId', name: '请求唯一ID', type: 'string', description: '对应请求头中的 request-id,用于追踪请求。' },
+  { fieldName: 'data', name: '响应数据', type: 'Array<Object>', description: '成功时返回的数据对象数组。主要包含实体节点列表 (nodes)。' },
+  { fieldName: 'data.key', name: '响应数据', type:'string', description: '第一层级key为nodes,即节点列表属性' },
+  { fieldName: 'data.value', name: '响应数据', type: 'Array<Object>', description: '第一层级value为nodes的值,即节点列表属性的值' }
+]);
+
+// 节点对象参数
+const nodeObjectParams = ref([
+  { propertyKey: 'id', propertyName: '节点编号', type: 'Array<Number>', description: '节点的唯一标识符。' },
+  { propertyKey: 'name', propertyName: '节点名称', type: 'Array<String>', description: '节点的名称。' },
+  { propertyKey: 'category', propertyName: '节点类型', type: 'Array<String>', description: '节点的类别。' },
+  { propertyKey: 'props', propertyName: '节点属性', type: 'Array<Object>', description: '节点的扩展属性集合。' }
+]);
+
+// 响应示例
+const responseExample = ref(`{
+    "success": true,
+    "errorCode": null,
+    "errorMsg": null,
+    "requestId": "9b501e56-8026-4d7d-96cc-4594742acd71", // 对应请求ID
+    "data": [
+        {
+            "key": "nodes", // 数据块标识,表示内容是节点列表
+            "value": [ // 节点列表数组
+                [ // 第一个节点对象 (由 key-value 对数组组成)
+                    {
+                        "key": "id",
+                        "value": [ 2322946 ] // 节点ID
+                    },
+                    {
+                        "key": "name",
+                        "value": [ "感冒" ] // 节点名称
+                    },
+                    {
+                        "key": "category",
+                        "value": [ "病因" ] // 节点类型
+                    },
+                    {
+                        "key": "props",
+                        "value": [] // 节点属性 (本例为空数组)
+                    }
+                ]
+                // ... 其他节点对象会按顺序排列在此处
+            ]
+        }
+    ]
+}`);
+// 路径参数
+const pathParams = ref([
+  { paramName: 'srcId', type: 'string', required: '是', description: '源节点的唯一标识符' }
+]);
+
+// 顶层响应参数
+const topLevelResponseParams = ref([
+  { fieldName: 'success', name: '请求状态', type: 'Boolean', description: 'true 表示请求成功;false 表示失败' },
+  { fieldName: 'errorCode', name: '错误码', type: 'string', description: '失败时返回的错误代码,成功时为 null' },
+  { fieldName: 'errorMsg', name: '错误信息', type: 'string', description: '失败时返回的错误描述,成功时为 null' },
+  { fieldName: 'requestId', name: '请求唯一ID', type: 'string', description: '对应请求头中的 request-id,用于日志追踪' },
+  { fieldName: 'data', name: '响应数据', type: 'Array<Object>', description: '包含关系列表的数据对象' },
+  { fieldName: 'data.key', name: '响应数据', type: 'string', description: '第一层级key为relationships,即关系列表' },
+  { fieldName: 'data.value', name: '响应数据', type: 'Array<Object>', description: '第一层级value为relationships的值,即节点列表的值' }
+]);
+
+// 关系对象参数
+const relationshipObjectParams = ref([
+  { propertyKey: 'id', propertyName: '关系编号', type: 'Array<Number>', description: '关系的唯一标识符' },
+  { propertyKey: 'name', propertyName: '关系名称', type: 'Array<String>', description: '关系的语义名称' },
+  { propertyKey: 'category', propertyName: '关系类型', type: 'Array<String>', description: '关系的分类' },
+  { propertyKey: 'props', propertyName: '关系属性', type: 'Array<Object>', description: '关系的扩展属性集合' },
+  { propertyKey: 'destNode', propertyName: '目标节点', type: 'Array<Object>', description: '关联的目标节点信息' }
+]);
+
+// 目标节点参数
+const destinationNodeParams = ref([
+  { propertyKey: 'id', propertyName: '节点编号', type: 'Array<Number>', description: '目标节点的唯一标识符' },
+  { propertyKey: 'name', propertyName: '节点名称', type: 'Array<String>', description: '目标节点的名称' },
+  { propertyKey: 'category', propertyName: '节点类型', type: 'Array<String>', description: '目标节点的分类' },
+  { propertyKey: 'props', propertyName: '节点属性', type: 'Array<Object>', description: '目标节点的扩展属性' }
+]);
+
+// 实体关系查询响应示例
+const responseExampleRelationship = ref(`{
+    "success": true,
+    "errorCode": null,
+    "errorMsg": null,
+    "requestId": "9b501e56-8026-4d7d-96cc-4594742acd71", // 请求追踪ID
+    "data": [
+        {
+            "key": "relationships", // 固定标识关系列表
+            "value": [ // 关系对象数组
+                [ // 第一条关系
+                    {
+                        "key": "name",
+                        "value": [ "常伴随的症状" ] // 关系名称
+                    },
+                    {
+                        "key": "props",
+                        "value": [] // 关系属性(空)
+                    },
+                    {
+                        "key": "destNode", // 目标节点
+                        "value": [ 
+                            {
+                                "key": "category",
+                                "value": [ "症状" ] // 节点类型
+                            },
+                            {
+                                "key": "id",
+                                "value": [ 1256383 ] // 节点ID
+                            },
+                            {
+                                "key": "name",
+                                "value": [ "乏力" ] // 节点名称
+                            },
+                            {
+                                "key": "props",
+                                "value": [] // 节点属性(空)
+                            }
+                        ]
+                    }
+                ],
+                [ // 第二条关系(结构同上)
+                    {
+                        "key": "name",
+                        "value": [ "常伴随的症状" ]
+                    },
+                    {
+                        "key": "props",
+                        "value": []
+                    },
+                    {
+                        "key": "destNode",
+                        "value": [ ... ] // 其他目标节点
+                    }
+                ]
+            ]
+        }
+    ]
+}`);
+
+
+</script>
+<style lang="less" scoped>
+// .api-doc-card {
+//   margin-top: 20px;
+// }
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  font-size: 22px;
+  font-weight: bold;
+}
+h3 {
+  margin-top: 20px;
+  margin-bottom: 10px;
+  font-size: 18px;
+  font-weight: bold;
+}
+
+pre {
+  background-color: #f9fafc;
+  padding: 10px;
+  border-radius: 4px;
+  overflow-x: auto;
+}
+
+code {
+  font-family: 'Courier New', Courier, monospace;
+}
+.code-container {
+  position: relative;
+}
+.copy-icon {
+  position: absolute;
+  top: 10px;
+  right: 10px;
+  z-index: 1;
+  cursor: pointer;
+  font-size: 18px;
+  color: #606266;
+}
+.copy-icon:hover {
+  color: #409eff;
+}
+.code-container pre code {
+  display: block;
+}
+
+.code-container pre code span.request-header {
+  color: #1890ff; /* 请求头颜色 */
+}
+
+.code-container pre code span.request-body {
+  color: #333; /* 请求内容颜色 */
+}
+.el-button {
+  position: absolute;
+  top: 10px;
+  right: 10px;
+  z-index: 1;
+}
+.mx-10 {
+    margin:10px 0
+}
+.mx-20 {
+    margin:20px 0
+}
+.text-bold {
+    font-weight: bold;
+}
+</style>