zhaoen před 5 měsíci
rodič
revize
2daa66ffe6

+ 6 - 0
src/router/index.ts

@@ -85,6 +85,12 @@ export const constantRoutes: RouteRecordRaw[] = [
         name:'ModleServiceProvide',
         meta: {title: '模型服务商管理', icon: 'dashboard', affix: true}
       },
+      {
+        path: '/modleServiceProvideDetail',
+        component: () => import('@/views/modleServiceProvideDetail/index.vue'),
+        name:'ModleServiceProvideDetail',
+        meta: {title: '模型服务商详情', icon: 'dashboard', affix: true}
+      },
       {
         path:'/dashboard',
         component: () => import('@/views/dashboard/index.vue'),

+ 73 - 0
src/views/modleServiceProvideDetail/components/BasicInfo.vue

@@ -0,0 +1,73 @@
+<template>
+  <el-card class="box-card" shadow="never">
+      <h3>基本信息</h3>
+
+      <el-descriptions :column="2"  border >
+          <el-descriptions-item label="服务商名称">{{ serviceProviderName }}</el-descriptions-item>
+          <el-descriptions-item label="服务商编码">{{ serviceProviderCode }}</el-descriptions-item>
+        <el-descriptions-item label="官方认证">
+          <el-tag v-if="officialCertification" type="success">
+            <el-icon name="Select"></el-icon> 是
+          </el-tag>
+          <el-tag v-else type="info">
+            <el-icon name="CloseBold"></el-icon> 否
+          </el-tag>
+        </el-descriptions-item>
+
+        <el-descriptions-item label="状态">
+          <el-tag :type="status === '启用' ? 'success' : 'danger'">
+            {{ status === '启用' ? '启用' : '禁用' }}
+          </el-tag>
+        </el-descriptions-item>
+          <el-descriptions-item label="模型种类">{{ serviceProviderType }}</el-descriptions-item>
+          <el-descriptions-item label="描述">{{ description }}</el-descriptions-item>
+          <el-descriptions-item label="创建时间">{{ createTime }}</el-descriptions-item>
+          <el-descriptions-item label="更新时间">{{ updateTime }}</el-descriptions-item>
+          <el-descriptions-item label="创建人">{{ createdBy }}</el-descriptions-item>
+          <el-descriptions-item label="排序值">{{ sort }}</el-descriptions-item>
+      </el-descriptions>
+
+      <h3>附加信息</h3>
+    <el-descriptions :column="1" border>
+      <el-descriptions-item label="联系方式">{{ contactInfo.contact }}</el-descriptions-item>
+      <el-descriptions-item label="官网">{{ contactInfo.website }}</el-descriptions-item>
+      <el-descriptions-item label="API文档URL">{{ contactInfo.apiDocUrl }}</el-descriptions-item>
+      <el-descriptions-item label="定价页面URL">{{ contactInfo.pricingUrl }}</el-descriptions-item>
+      <el-descriptions-item label="备注">{{ contactInfo.remark }}</el-descriptions-item>
+    </el-descriptions>
+  </el-card>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+
+// 示例数据
+const serviceProviderName = "OpenAI"
+const serviceProviderType = "API服务"
+const status = "启用"
+const createTime = "2023-05-18 14:59:13"
+const updateTime = "2023-05-18 14:59:13"
+const createdBy = "admin"
+const sort = 0
+const serviceProviderCode = "openai"
+const officialCertification = true
+const description = "Openai"
+
+const contactInfo = {
+  contact: "contact@example.com",
+  website: "https://openai.com",
+  apiDocUrl: "https://openai.com/docs",
+  pricingUrl: "https://openai.com/pricing",
+  description: "OpenAI is an AI research and deployment company. Our mission is to ensure that artificial general intelligence benefits all of humanity.",
+  remark: "内部备注:无特殊说明"
+}
+
+
+</script>
+
+<style scoped>
+.box-card {
+  margin-bottom: 20px;
+}
+
+</style>

+ 152 - 0
src/views/modleServiceProvideDetail/components/CallStatistics.vue

@@ -0,0 +1,152 @@
+<template>
+  <div class="service-provider-detail">
+    <!-- 调用统计 -->
+    <el-card class="box-card" shadow="never">
+      <template #header>
+        <span>调用统计</span>
+      </template>
+      <el-row :gutter="20">
+        <el-col :span="6">
+          <el-statistic title="总调用量" :value="totalInvocations" />
+        </el-col>
+        <el-col :span="6">
+          <el-statistic title="平均响应时间" :value="averageResponseTime" value-style="color: #4caf50">
+            <template #suffix>s</template>
+          </el-statistic>
+        </el-col>
+        <el-col :span="6">
+          <el-statistic title="成功率" :value="successRate" value-style="color: #4caf50">
+            <template #suffix>%</template>
+          </el-statistic>
+        </el-col>
+        <el-col :span="6">
+          <el-statistic title="总费用" :value="totalCost" value-style="color: #ff9800">
+            <template #prefix>$</template>
+          </el-statistic>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 调用趋势图 -->
+    <el-card class="box-card" shadow="never">
+      <template #header>
+        <span>调用趋势图</span>
+      </template>
+      <div ref="trendChart" class="chart-container"></div>
+    </el-card>
+
+    <!-- 模型调用分布 + 热门模型排行 -->
+    <el-row :gutter="20">
+      <el-col :span="12">
+        <el-card class="box-card" shadow="never">
+          <template #header>
+            <span>模型调用分布</span>
+          </template>
+          <div ref="pieChart" class="chart-container"></div>
+        </el-card>
+      </el-col>
+      <el-col :span="12">
+        <el-card class="box-card" shadow="never">
+          <template #header>
+            <span>热门模型排行</span>
+          </template>
+          <el-table :data="modelRankList" border style="width: 100%">
+            <el-table-column prop="rank" label="排名" width="80" align="center" />
+            <el-table-column prop="modelName" label="模型" />
+            <el-table-column prop="invocationCount" label="调用次数" align="center" />
+            <el-table-column prop="percentage" label="占比" align="center">
+              <template #default="scope">
+                {{ scope.row.percentage }}%
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+import * as echarts from 'echarts'
+import { ref, onMounted } from 'vue'
+
+// 调用统计数据
+const totalInvocations = 458032
+const averageResponseTime = 1.45
+const successRate = 99.92
+const totalCost = 14.5
+
+// 排行榜数据
+const modelRankList = [
+  { rank: 1, modelName: 'GPT-3', invocationCount: 4500, percentage: 45 },
+  { rank: 2, modelName: 'GPT-4', invocationCount: 3200, percentage: 32 },
+  { rank: 3, modelName: 'DALL·E', invocationCount: 2800, percentage: 14 },
+  { rank: 4, modelName: 'Claude', invocationCount: 1900, percentage: 7 },
+  { rank: 5, modelName: 'Llama', invocationCount: 1500, percentage: 2 }
+]
+
+// 折线图:调用趋势
+const trendChart = ref(null)
+const trendData = {
+  dates: ['7/1', '7/5', '7/10', '7/15', '7/20'],
+  values: [12000, 15000, 13500, 18000, 20000]
+}
+
+// 饼图:模型调用分布
+const pieChart = ref(null)
+const pieData = [
+  { name: 'GPT-3', value: 45 },
+  { name: 'GPT-4', value: 32 },
+  { name: 'DALL·E', value: 14 },
+  { name: 'Claude', value: 7 },
+  { name: 'Llama', value: 2 }
+]
+
+// 初始化折线图
+const initTrendChart = () => {
+  const chart = echarts.init(trendChart.value)
+  chart.setOption({
+    tooltip: { trigger: 'axis' },
+    xAxis: { type: 'category', data: trendData.dates },
+    yAxis: { type: 'value' },
+    series: [{ data: trendData.values, type: 'line', smooth: true, color: '#409EFF' }]
+  })
+}
+
+// 初始化饼图
+const initPieChart = () => {
+  const chart = echarts.init(pieChart.value)
+  chart.setOption({
+    tooltip: { trigger: 'item' },
+    legend: { show: false },
+    series: [{
+      type: 'pie',
+      radius: '70%',
+      data: pieData,
+      emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' } },
+      color: ['#409EFF', '#67C23A', '#F56C6C', '#E6A23C', '#909399']
+    }]
+  })
+}
+
+// 挂载后初始化图表
+onMounted(() => {
+  initTrendChart()
+  initPieChart()
+})
+</script>
+
+<style scoped>
+.service-provider-detail {
+  padding: 20px;
+}
+
+.box-card {
+  margin-bottom: 20px;
+}
+
+.chart-container {
+  width: 100%;
+  height: 300px;
+}
+</style>

+ 36 - 0
src/views/modleServiceProvideDetail/components/ConfigHistory.vue

@@ -0,0 +1,36 @@
+<script setup lang="ts">
+const apiConfig = {
+  defaultApiUrl: "https://api.openai.com/v1",
+  authType: "API_KEY",
+  requestHeaderKey: "Authorization",
+  requestHeaderValuePrefix: "Bearer",
+  extraConfig: "{ timeout: 5000, proxy: 'http://proxy.example.com' }",
+  timeOut:'30',
+  reTry:'3'
+}
+// 格式化 JSON
+const formattedExtraConfig = computed(() => {
+  return JSON.stringify(apiConfig.extraConfig, null, 2)
+})
+</script>
+
+<template>
+  <h3>API配置</h3>
+  <el-descriptions :column="2" border>
+    <el-descriptions-item label="默认API地址">{{ apiConfig.defaultApiUrl }}</el-descriptions-item>
+    <el-descriptions-item label="认证方式">{{ apiConfig.authType }}</el-descriptions-item>
+    <el-descriptions-item label="请求头Key">{{ apiConfig.requestHeaderKey }}</el-descriptions-item>
+    <el-descriptions-item label="拓展配置">
+  <pre style="white-space: pre-wrap; word-break: break-word; background: #f5f7fa; padding: 10px; border-radius: 4px;">
+    {{ formattedExtraConfig }}
+  </pre>
+    </el-descriptions-item>
+    <el-descriptions-item label="请求头Value前缀">{{ apiConfig.requestHeaderValuePrefix }}</el-descriptions-item>
+    <el-descriptions-item label="请求超时时间">{{ apiConfig.timeOut }}</el-descriptions-item>
+    <el-descriptions-item label="重试次数">{{ apiConfig.reTry }}</el-descriptions-item>
+  </el-descriptions>
+</template>
+
+<style scoped lang="scss">
+
+</style>

+ 96 - 0
src/views/modleServiceProvideDetail/components/ModleList.vue

@@ -0,0 +1,96 @@
+<template>
+  <div class="related-models-container">
+    <div class="table-header">
+      <h3>关联模型</h3>
+      <el-button type="primary" @click="handleAddModel">添加模型</el-button>
+    </div>
+
+    <el-table :data="relatedModels" stripe style="width: 100%">
+      <el-table-column prop="modelName" label="模型编码"></el-table-column>
+      <el-table-column prop="modelName" label="模型名称"></el-table-column>
+      <el-table-column prop="modelVersion" label="版本号"></el-table-column>
+      <el-table-column prop="modelName" label="模型种类"></el-table-column>
+      <el-table-column prop="status" label="状态">
+        <template #default="scope">
+          <el-tag :type="scope.row.status === '启用' ? 'success' : 'danger'">
+            {{ scope.row.status }}
+          </el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column prop="createTime" label="创建时间"></el-table-column>
+      <el-table-column label="操作" width="150">
+        <template #default="scope">
+          <el-button size="small" @click="handleView(scope.row)">查看</el-button>
+          <el-button size="small" type="primary" @click="handleEdit(scope.row)">编辑</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <div class="table-footer">
+      <el-pagination
+        layout="prev, pager, next"
+        :total="total"
+        :page-size="pageSize"
+        @current-change="handlePageChange"
+      />
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import { ElMessage } from 'element-plus'
+
+// 表格数据
+const relatedModels = [
+  { modelName: "DALL·E", modelVersion: "v1", modelId: "1234567890", status: "启用", createTime: "2023-05-18 14:59:13" },
+  { modelName: "GPT-3", modelVersion: "v3", modelId: "0987654321", status: "启用", createTime: "2023-05-18 14:59:13" }
+]
+
+// 分页数据
+const total = ref(100) // 总数据条数(可动态获取)
+const pageSize = 10
+const currentPage = ref(1)
+
+// 分页切换
+const handlePageChange = (page: number) => {
+  currentPage.value = page
+  // 这里可以请求新一页的数据
+  ElMessage.info(`切换到第 ${page} 页`)
+}
+
+// 按钮操作
+const handleAddModel = () => {
+  ElMessage.success('点击了添加模型')
+  // 这里可以打开弹窗或跳转到添加页面
+}
+
+const handleView = (row: any) => {
+  ElMessage.info(`查看模型:${row.modelName}`)
+  // 跳转或打开查看弹窗
+}
+
+const handleEdit = (row: any) => {
+  ElMessage.warning(`编辑模型:${row.modelName}`)
+  // 跳转编辑页或打开编辑弹窗
+}
+</script>
+
+<style scoped lang="scss">
+.related-models-container {
+  padding: 20px;
+}
+
+.table-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 10px;
+}
+
+.table-footer {
+  margin-top: 20px;
+  display: flex;
+  justify-content: flex-end;
+}
+</style>

+ 74 - 0
src/views/modleServiceProvideDetail/index.vue

@@ -0,0 +1,74 @@
+<template>
+  <div class="service-provider-detail">
+
+    <el-tabs  tab-position="top" v-model="activeTab" type="card">
+      <el-tab-pane label="基本信息" name="info1">
+        <BasicInfo v-model="formData.info1" />
+      </el-tab-pane>
+      <el-tab-pane label="模型列表" name="info2">
+        <ModleList v-model="formData.info2" />
+      </el-tab-pane>
+      <el-tab-pane label="配置历史" name="info3">
+        <ConfigHistory v-model="formData.info3" />
+      </el-tab-pane>
+      <el-tab-pane label="调用统计" name="info4">
+        <CallStatistics v-model="formData.info4" />
+      </el-tab-pane>
+    </el-tabs>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import BasicInfo from "@/views/modleServiceProvideDetail/components/BasicInfo.vue";
+import ModleList from "@/views/modleServiceProvideDetail/components/ModleList.vue";
+import ConfigHistory from "@/views/modleServiceProvideDetail/components/ConfigHistory.vue";
+import CallStatistics from "@/views/modleServiceProvideDetail/components/CallStatistics.vue";
+
+const activeTab = 'info1'
+const formData = ref({
+  info1: { name: '', desc: '' },
+  info2: { phone: '', email: '' },
+  info3: { address: '', remark: '' },
+  info4: { address: '', remark: '' }
+})
+// 示例数据
+const serviceProviderName = "OpenAI"
+const serviceProviderType = "API服务"
+const status = "启用"
+const createTime = "2023-05-18 14:59:13"
+const updateTime = "2023-05-18 14:59:13"
+const createdBy = "admin"
+const sort = 0
+
+const apiConfig = {
+  defaultApiUrl: "https://api.openai.com/v1",
+  authType: "API_KEY",
+  requestHeaderKey: "Authorization",
+  requestHeaderValuePrefix: "Bearer",
+  extraConfig: "{ timeout: 5000, proxy: 'http://proxy.example.com' }"
+}
+
+const contactInfo = {
+  contact: "contact@example.com",
+  website: "https://openai.com",
+  apiDocUrl: "https://openai.com/docs",
+  pricingUrl: "https://openai.com/pricing",
+  description: "OpenAI is an AI research and deployment company. Our mission is to ensure that artificial general intelligence benefits all of humanity.",
+  remark: "内部备注:无特殊说明"
+}
+
+const relatedModels = [
+  { modelName: "DALL·E", modelVersion: "v1", modelId: "1234567890", status: "启用", createTime: "2023-05-18 14:59:13" },
+  { modelName: "GPT-3", modelVersion: "v3", modelId: "0987654321", status: "启用", createTime: "2023-05-18 14:59:13" }
+]
+</script>
+
+<style scoped>
+.service-provider-detail {
+  padding: 20px;
+}
+.box-card {
+  margin-bottom: 20px;
+}
+</style>