Browse Source

feat:优化APIHUB弹窗中显示效果

microrain 5 months ago
parent
commit
0f4ed3787c
2 changed files with 190 additions and 2 deletions
  1. 107 1
      src/views/apihub/component/test.vue
  2. 83 1
      src/views/apihub/component/view.vue

+ 107 - 1
src/views/apihub/component/test.vue

@@ -2,7 +2,15 @@
   <el-dialog class="api-test" v-model="showDialog" title="测试API" width="800px" :close-on-click-modal="false" :close-on-press-escape="false">
     <el-descriptions :column="2" border>
       <el-descriptions-item label="API名称" :span="2">{{ apiData.name }}</el-descriptions-item>
-      <el-descriptions-item label="API路径" :span="2">{{ apiData.path }}</el-descriptions-item>
+      <el-descriptions-item label="API路径" :span="2">
+        <div class="api-path-container">
+            <span class="domain">{{ originUrl }}/apihub/</span>
+            <span class="path">{{ apiData.path }}</span>
+          <el-tooltip content="复制API完整路径" placement="top">
+            <el-icon class="copy-icon" @click="copyApiPath"><CopyDocument /></el-icon>
+          </el-tooltip>
+        </div>
+      </el-descriptions-item>
       <el-descriptions-item label="请求方法">
         <el-tag :type="getMethodTagType(apiData.method)" size="small">{{ apiData.method }}</el-tag>
       </el-descriptions-item>
@@ -49,10 +57,14 @@
 <script lang="ts" setup>
 import { ref, reactive, watch } from "vue";
 import apiHub from "/@/api/modules/apiHub";
+import { ElMessage } from "element-plus";
+import { CopyDocument } from "@element-plus/icons-vue";
+import getOrigin from "/@/utils/origin";
 
 const showDialog = ref(false);
 const loading = ref(false);
 const activeTab = ref("data");
+const originUrl: string = getOrigin("");
 
 // API数据
 const apiData = reactive<any>({
@@ -191,6 +203,21 @@ const runTest = async () => {
     });
 };
 
+// 复制API完整路径
+const copyApiPath = () => {
+  // 实现复制功能
+  const fullPath = `${originUrl}/apihub/${apiData.path}`;
+
+  // 使用Clipboard API复制到剪贴板
+  navigator.clipboard.writeText(fullPath)
+    .then(() => {
+      ElMessage.success('已复制API完整路径到剪贴板');
+    })
+    .catch(() => {
+      ElMessage.error('复制失败,请手动复制');
+    });
+};
+
 // 打开对话框
 const open = async (row: any) => {
   // 清空数据
@@ -243,12 +270,26 @@ defineExpose({ open });
   background-color: #f5f7fa;
   border-radius: 4px;
 }
+/* 深色主题下的样式 */
+[data-theme='dark'] .test-placeholder {
+  text-align: center;
+  color: #e4e3e3;
+  padding: 20px;
+  background-color: #424040;
+  border-radius: 4px;
+}
 
 .result-container {
   margin-top: 15px;
   border: 1px solid #e4e7ed;
   border-radius: 4px;
 }
+/* 深色主题下的样式 */
+[data-theme='dark'] .result-container {
+  margin-top: 15px;
+  border: 1px solid #575656;
+  border-radius: 4px;
+}
 
 .result-json {
   background-color: #f5f7fa;
@@ -260,4 +301,69 @@ defineExpose({ open });
   max-height: 300px;
   overflow: auto;
 }
+/* 深色主题下的样式 */
+[data-theme='dark'] .result-json {
+  background-color: #3c3b3b;
+  color: #ffffff;
+  padding: 10px;
+  font-family: monospace;
+  white-space: pre-wrap;
+  word-break: break-all;
+  margin: 0;
+  max-height: 300px;
+  overflow: auto;
+}
+
+
+.el-empty{
+  height: 120px;
+}
+
+.api-path-container {
+  display: inline-block;
+  text-decoration: none;
+  color: black; /* 设置整体文字颜色 */
+  align-items: center; /* 垂直居中对齐 */
+}
+/* 深色主题下的样式 */
+[data-theme='dark'] .api-path-container {
+  display: inline-block;
+  text-decoration: none;
+  color: #fff; /* 设置整体文字颜色 */
+}
+.api-path-container .domain {
+  background-color: #eee; /* 设置域名部分的背景颜色 */
+  color: black; /* 设置域名部分的文字颜色 */
+  padding: 2px 4px; /* 添加一些内边距 */
+  display: inline-block;
+  border-radius: 15px; /* 增加圆角 */
+}
+/* 深色主题下的样式 */
+[data-theme='dark'] .api-path-container .domain{
+  background-color: #3c3b3b; /* 设置域名部分的背景颜色 */
+  color: white; /* 设置域名部分的文字颜色 */
+  padding: 2px 4px; /* 添加一些内边距 */
+  display: inline-block;
+  border-radius: 15px; /* 增加圆角 */
+}
+.api-path-container .path {
+  display: inline-block;
+}
+
+
+.copy-icon {
+  cursor: pointer;
+  color: var(--el-color-primary);
+  transition: all 0.2s;
+  font-size: 24px;
+  margin-left: 8px;
+  padding: 4px;
+  border-radius: 4px;
+}
+
+.copy-icon:hover {
+  transform: scale(1.1);
+  color: var(--el-color-primary-dark-2);
+  background-color: var(--el-color-primary-light-9);
+}
 </style>

+ 83 - 1
src/views/apihub/component/view.vue

@@ -2,7 +2,15 @@
   <el-dialog class="api-view" v-model="showDialog" title="API详情" width="800px" :close-on-click-modal="false" :close-on-press-escape="false">
     <el-descriptions :column="2" border>
       <el-descriptions-item label="API名称" :span="2">{{ apiData.name }}</el-descriptions-item>
-      <el-descriptions-item label="API路径" :span="2">{{ originUrl }}/apihub/{{ apiData.path }}</el-descriptions-item>
+      <el-descriptions-item label="API路径" :span="2">
+        <div class="api-path-container">
+          <span class="domain">{{ originUrl }}/apihub/</span>
+          <span class="path">{{ apiData.path }}</span>
+          <el-tooltip content="复制API完整路径" placement="top">
+            <el-icon class="copy-icon" @click="copyApiPath"><CopyDocument /></el-icon>
+          </el-tooltip>
+        </div>
+      </el-descriptions-item>
       <el-descriptions-item label="请求方法">
         <el-tag :type="getMethodTagType(apiData.method)" size="small">{{ apiData.method }}</el-tag>
       </el-descriptions-item>
@@ -61,6 +69,8 @@
 <script lang="ts" setup>
 import { ref, reactive } from "vue";
 import getOrigin from "/@/utils/origin";
+import { CopyDocument } from "@element-plus/icons-vue";
+import { ElMessage } from "element-plus";
 
 const emit = defineEmits(["test"]);
 const showDialog = ref(false);
@@ -111,6 +121,21 @@ const testApi = () => {
   emit("test", apiData);
 };
 
+// 复制API完整路径
+const copyApiPath = () => {
+  // 实现复制功能
+  const fullPath = `${originUrl}/apihub/${apiData.path}`;
+
+  // 使用Clipboard API复制到剪贴板
+  navigator.clipboard.writeText(fullPath)
+      .then(() => {
+        ElMessage.success('已复制API完整路径到剪贴板');
+      })
+      .catch(() => {
+        ElMessage.error('复制失败,请手动复制');
+      });
+};
+
 // 打开对话框
 const open = async (row: any) => {
   // 清空数据
@@ -154,4 +179,61 @@ defineExpose({ open });
   white-space: pre-wrap;
   word-break: break-all;
 }
+/* 深色主题下的样式 */
+[data-theme='dark'] .code-block {
+  background-color: #2f3030;
+  border: 1px solid #575656;
+  border-radius: 4px;
+  padding: 10px;
+  font-family: monospace;
+  white-space: pre-wrap;
+  word-break: break-all;
+}
+
+
+.api-path-container {
+  display: inline-block;
+  text-decoration: none;
+  color: black; /* 设置整体文字颜色 */
+  align-items: center; /* 垂直居中对齐 */
+}
+/* 深色主题下的样式 */
+[data-theme='dark'] .api-path-container {
+  display: inline-block;
+  text-decoration: none;
+  color: #fff; /* 设置整体文字颜色 */
+}
+.api-path-container .domain {
+  background-color: #eee; /* 设置域名部分的背景颜色 */
+  color: black; /* 设置域名部分的文字颜色 */
+  padding: 2px 4px; /* 添加一些内边距 */
+  display: inline-block;
+  border-radius: 15px; /* 增加圆角 */
+}
+/* 深色主题下的样式 */
+[data-theme='dark'] .api-path-container .domain{
+  background-color: #3c3b3b; /* 设置域名部分的背景颜色 */
+  color: white; /* 设置域名部分的文字颜色 */
+  padding: 2px 4px; /* 添加一些内边距 */
+  display: inline-block;
+  border-radius: 15px; /* 增加圆角 */
+}
+.api-path-container .path {
+  display: inline-block;
+}
+.copy-icon {
+  cursor: pointer;
+  color: var(--el-color-primary);
+  transition: all 0.2s;
+  font-size: 24px;
+  margin-left: 8px;
+  padding: 4px;
+  border-radius: 4px;
+}
+
+.copy-icon:hover {
+  transform: scale(1.1);
+  color: var(--el-color-primary-dark-2);
+  background-color: var(--el-color-primary-light-9);
+}
 </style>