Sfoglia il codice sorgente

市场模型接口

zhaoen 5 mesi fa
parent
commit
1638a50edf

+ 12 - 6
src/router/index.ts

@@ -74,10 +74,15 @@ export const constantRoutes: RouteRecordRaw[] = [
         meta: { title: '首页', icon: 'dashboard', affix: true }
       },
       {
-        path: '/market',
-        component: () => import('@/views/market/index.vue'),
+        path: '/modelMarket',
+        component: () => import('@/views/modelMarket/index.vue'),
         name:'Market',
-        meta: {title: '市场模型', icon: 'dashboard', affix: true}
+        meta: {title: '市场模型', icon: 'dashboard', affix: true},
+        children:[
+          {
+            path:''
+          }
+        ]
       },
       {
         path: '/modleServiceProvide',
@@ -113,7 +118,8 @@ export const constantRoutes: RouteRecordRaw[] = [
         path: '/promptWordList',
         component: () => import('@/views/promptWordList/index.vue'),
         name:'PromptWordList',
-        meta: {title: '提示词列表', icon: 'dashboard', affix: true}
+        meta: {title: '提示词列表', icon: 'dashboard', affix: true},
+
       },
       {
         path: '/promptPermissionsManagmant',
@@ -125,12 +131,12 @@ export const constantRoutes: RouteRecordRaw[] = [
   },
   {
     path: '/modeldetailed',
-    component: () => import('@/views/modeldetailed/index.vue'),
+    component: () => import('@/views/modelMarket/components/modeldetailed.vue'),
     name:'ModelDetailed',
   },
   {
     path: '/editPromptWord',
-    component: () => import('@/views/editPromptWord/index.vue'),
+    component: () => import('@/views/promptWordList/components/editPromptWord.vue'),
     name:'EditPromptWord',
   },
   {

+ 2 - 2
src/views/market/addModel.vue → src/views/modelMarket/components/addModel.vue

@@ -18,7 +18,7 @@ const DEFAULT_FORM: modelConfigForm = {
   modelType: '',
   modelVersion: '',
   status: false,
-  priority: null,
+  priority: undefined,
   description: '',
   apiKey: '',
   baseUrl: ''
@@ -61,7 +61,7 @@ const submit = () =>{
       }else {
         const  res = await editModel(baseInfoForm.value)
         if(res.code===0){
-          proxy?.$modal.msgSuccess('新增成功')
+          proxy?.$modal.msgSuccess('编辑成功')
           emit("update:dialogVisible",false)
         }
       }

+ 520 - 0
src/views/modelMarket/components/modeldetailed.vue

@@ -0,0 +1,520 @@
+<template>
+  <div class="model-detail-root">
+    <!-- 面包屑导航 -->
+    <el-breadcrumb separator="/" class="model-breadcrumb">
+      <el-breadcrumb-item>市场模型</el-breadcrumb-item>
+      <el-breadcrumb-item>模型详情</el-breadcrumb-item>
+    </el-breadcrumb>
+    <div class="model-top-right-btns">
+      <el-button type="plain" size="small" @click="returnModel" class="custom-button">
+        <el-icon ><ArrowLeft /></el-icon>
+        返回列表
+      </el-button>
+      <el-button type="plain" size="small" class="custom-button">
+        <el-icon><Refresh /></el-icon>
+        刷新
+      </el-button>
+      <el-button type="primary" size="small" class="custom-button" @click = "handleModelAdd">
+        <el-icon><Edit /></el-icon>
+        编辑
+      </el-button>
+      <el-button type="danger" size="small" class="custom-button">
+        <el-icon><SwitchButton /></el-icon>
+        禁用
+      </el-button>
+    </div>
+
+    <!-- 顶部信息区(单卡片,左右分布) -->
+    <el-card class="model-top-card" shadow="never">
+      <div class="model-top-flex">
+        <!-- 左侧基本信息 -->
+        <div class="model-top-left">
+          <div class="model-top-title">基本信息</div>
+          <div class="model-top-row">
+            <span class="model-top-label">模型名称:</span>
+            <span class="model-top-value">{{model?.modelName}}</span>
+          </div>
+          <div class="model-top-row">
+            <span class="model-top-label">模型类型:</span>
+            <span class="model-top-value">{{model?.modelType}}</span>
+          </div>
+          <div class="model-top-row">
+            <span class="model-top-label">模型版本:</span>
+            <span class="model-top-value">{{model?.modelVersion}}</span>
+          </div>
+          <div class="model-top-row">
+            <span class="model-top-label">状态:</span>
+            <el-tag type="success" size="small" v-if="model?.status===1">启用</el-tag>
+            <el-tag type="warning" size="small" v-else-if="model?.status === 0">测试中</el-tag>
+          </div>
+          <div class="model-top-row">
+            <span class="model-top-label">API地址:</span>
+            <a class="model-top-link" :href="model.baseUrl" target="_blank">{{model?.baseUrl}}</a>
+          </div>
+          <div class="model-top-row">
+            <span class="model-top-label">描述:</span>
+            <span class="model-top-value">{{model?.description}}</span>
+          </div>
+        </div>
+        <!-- 右侧服务信息和按钮 -->
+        <div class="model-top-right">
+          <div class="model-top-right-info">
+            <div style="display: flex"><span class="model-top-label">服务商:</span>&nbsp&nbspOpenAI</div>
+            <div style="display: flex"><span class="model-top-label">优先级:</span>&nbsp&nbsp{{model?.priority}}</div>
+            <div style="display: flex"><span class="model-top-label">创建时间:</span>&nbsp&nbsp{{model?.createTime}}</div>
+            <div style="display: flex"><span class="model-top-label">更新时间:</span>&nbsp&nbsp{{model?.updateTime}}</div>
+          </div>
+
+        </div>
+      </div>
+    </el-card>
+
+    <!-- 参数配置 -->
+    <el-card class="model-section-card">
+      <div class="model-section-title">
+        <span>参数配置</span>
+        <el-button type="primary" size="small" class="model-btn-add">+ 添加参数</el-button>
+      </div>
+      <el-table :data="model.parameters" class="model-param-table" border header-cell-class-name="model-th" cell-class-name="model-td">
+        <el-table-column prop="paramName" label="参数名称" align="center" min-width="120" />
+        <el-table-column prop="paramType" label="参数类型" align="center" min-width="120" />
+        <el-table-column prop="defaultValue" label="默认值" align="center" min-width="100" />
+        <el-table-column prop="isRequired" label="是否必需" align="center" min-width="100" />
+        <el-table-column prop="description" label="描述" min-width="200" />
+        <el-table-column label="操作" align="center" min-width="100">
+          <template #default="scope">
+            <el-button @click="handleParamEdit(scope.$index, scope.row)" type="text" size="small">编辑</el-button>
+            <el-button @click="handleParamDelete(scope.$index, scope.row)" type="text" size="small">删除</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+    <!-- 抽屉 -->
+    <el-drawer
+
+      v-model="drawerVisible"
+      direction="rtl"
+      size="40%"
+      class="drawer-style"
+    >
+      <template #header="{close,titleId,titleClass}">
+        <h2 :id="titleId" style="color:#000000">编辑参数</h2>
+      </template>
+      <div >
+        <h4>模型</h4>
+        <el-card class="model-card" style=" background:#F5F5F5;">
+          GPT-4 (OpenAI)<br/>
+          <span style="color: #777777">版本: gpt-4-1106-preview</span>
+        </el-card>
+
+        <h4>快速添加参数模板</h4>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-card class="center-content" style="height: 150px;background: #FAFAFA" >
+              <div>OpenAI Chat模板</div>
+              <div style="color: #777777">6个参数</div>
+            </el-card>
+          </el-col>
+
+          <el-col :span="12">
+            <el-card class="center-content"style="background: #FAFAFA">
+              <div>OpenAI Embedding模板</div>
+              <div style="color: #777777">三个参数</div>
+            </el-card>
+          </el-col>
+        </el-row>
+
+        <h4>参数列表</h4>
+        <div v-for="(item, index) in tempModel.parameters" :key="index" class="parameter-card">
+          <el-card shadow="never" style="background-color: #FAFAFA" >
+            <div class="card-content">
+              <div class="param-name">{{ item.paramName }} <span style="color: #777777">{{item.paramType}}</span></div>
+              <div class="actions" style="display: flex">
+                <el-button @click="handleModelParamAdd(index, item)" type="text" size="small" ></el-button>
+                <el-button @click="handleModelParamDelete(index, item)" type="text" size="small" style="margin-left:auto" ><el-icon color="red"><DeleteFilled /></el-icon></el-button>
+              </div>
+            </div>
+          </el-card>
+        </div>
+        <el-card style="display: flex;justify-content: center; align-items: center; flex-direction: column;" :body-style="{padding:'1px'}">
+          <el-button @click="addParameter" type="plain" >添加参数</el-button>
+        </el-card>
+
+
+        <div style="text-align: right; margin-top: 20px;">
+          <el-button @click="drawerVisible = false">取消</el-button>
+          <el-button @click="saveEdit" type="primary">保存</el-button>
+        </div>
+      </div>
+
+    </el-drawer>
+
+    <!-- 调用统计 -->
+    <el-row :gutter="20" class="model-stat-row">
+      <el-col :span="6" v-for="(item, idx) in statList" :key="item.label">
+        <el-card class="model-stat-card" shadow="never">
+          <div class="model-stat-label">{{ item.label }}</div>
+          <div class="model-stat-value">{{ item.value }}</div>
+          <div :class="['model-stat-trend', item.trend > 0 ? 'up' : 'down']">
+            <span v-if="item.trend > 0">↑ {{ item.trend }}% 较上月</span>
+            <span v-else>↓ {{ Math.abs(item.trend) }}% 较上月</span>
+          </div>
+        </el-card>
+      </el-col>
+      <div class="model-stat-select">
+        <el-select v-model="statRange" size="small" style="width: 80px">
+          <el-option label="本月" value="month" />
+          <el-option label="本年" value="year" />
+        </el-select>
+      </div>
+    </el-row>
+
+    <!-- 调用趋势 -->
+    <el-card class="model-section-card model-chart-section">
+      <div class="model-chart-title">调用趋势</div>
+      <div id="callTrendChart" style="width: 100%; height: 320px;"></div>
+      <div class="model-chart-footer">调用趋势曲线数据</div>
+    </el-card>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, onMounted } from 'vue'
+import * as echarts from 'echarts'
+import { ArrowLeft, Refresh } from '@element-plus/icons-vue';
+import { useRoute,useRouter } from 'vue-router';
+import { ModelConfigVo} from '@/api/modelConfig/types'
+import {toggleStatus} from '@/api/modelConfig/index.js'
+
+const route = useRoute()
+const router = useRouter()
+const model = ref<ModelConfigVo>(route.query.model)
+model.value = {
+  modelName: "GPT-4",
+  modelType:"大语言模型(LLM)",
+  modelVersion:"gpt-4-1106-preview",
+  baseUrl:"https://api.openai.com/v1/chat/completions",
+  apiKey: "",
+  status:1,
+  priority:10,
+  description:"GPT-4是OpenAI最先进的大型语言模型,在各种专业和学术基准上表现最佳。相比GPT-3.5,GPT-4在创造性写作、编码和解决复杂问题方面表现出显著提升,能更好地遵循用户意图,理解和生成更长的内容。",
+  createTime:"2025-05-15 10:30:15",
+  updateTime:"2025-06-20 14:45:30",
+  parameters: [
+      { paramName: 'temperature', paramType: 'NUMBER', defaultValue: '0.7', isRequired: '否', description: '控制生成文本的随机性,值越小结果越随机' },
+      { paramName: 'max_tokens', paramType: 'NUMBER', defaultValue: '1024', isRequired: '否', description: '生成文本的最大令牌数' },
+      { paramName: 'top_p', paramType: 'NUMBER', defaultValue: '0.95', isRequired: '否', description: '核采样阈值,控制模型选择词的概率分布' },
+      { paramName: 'frequency_penalty', paramType: 'NUMBER', defaultValue: '0', isRequired: '否', description: '减少重复词组的出现概率' },
+      { paramName: 'presence_penalty', paramType: 'NUMBER', defaultValue: '0', isRequired: '否', description: '增加新话题出现的概率' },
+      { paramName: 'stream', paramType: 'BOOLEAN', defaultValue: 'false', isRequired: '否', description: '是否启用流式输出' }
+  ]
+
+}
+//临时抽屉数据
+const tempModel = ref<ModelConfigVo>(model)
+
+
+// 统计卡片数据
+const statList = ref([
+  { label: '调用次数', value: '156,783', trend: 12.5 },
+  { label: '平均响应时间', value: '1.68s', trend: -0.2 },
+  { label: '成功率', value: '99.87%', trend: 0.05 },
+  { label: 'Token消耗', value: '5.6M', trend: 18.3 }
+])
+
+// 其他响应式数据
+const statRange = ref('month')
+const drawerVisible = ref(false)
+const currentRowIndex = ref(-1)
+
+// 生命周期钩子
+onMounted(() => {
+  initCallTrendChart()
+
+})
+
+// 方法
+const handleModelAdd = () => {
+  drawerVisible.value = true
+}
+
+const handleModelParamDelete = (index,item) =>{
+  tempModel.parameters.splice(index,1)
+}
+
+const handleParamDelete = (index) => {
+  model.parameters.value.splice(index, 1)
+}
+
+const saveEdit = () => {
+  tableData.value[currentRowIndex.value] = { ...currentRow.value }
+  drawerVisible.value = false
+}
+
+const returnModel = () => {
+  router.push('/modelMarket')
+}
+
+const initCallTrendChart = () => {
+  const callTrendChart = echarts.init(document.getElementById('callTrendChart'))
+  const option = {
+    tooltip: {},
+    xAxis: {
+      type: 'category',
+      data: ['1月', '2月', '3月', '4月', '5月', '6月'],
+      axisLine: { lineStyle: { color: '#e5e6eb' } },
+      axisLabel: { color: '#888' },
+    },
+    yAxis: {
+      type: 'value',
+      axisLine: { lineStyle: { color: '#e5e6eb' } },
+      splitLine: { lineStyle: { color: '#f0f0f0' } },
+      axisLabel: { color: '#888' },
+    },
+    series: [
+      {
+        data: [120, 200, 150, 80, 70, 110],
+        type: 'bar',
+        name: '调用次数',
+        itemStyle: { color: '#409EFF', borderRadius: [4, 4, 0, 0] },
+        barWidth: 24,
+      },
+    ],
+    grid: { left: 40, right: 20, top: 30, bottom: 30 },
+  }
+  callTrendChart.setOption(option)
+}
+
+
+</script>
+<style scoped>
+.actions{
+  display: flex;
+}
+.drawer-style{
+
+  header.el-drawer__header{
+    margin-bottom: 0 !important;
+  }
+}
+:deep(header.el-drawer__header){
+  margin-bottom: 0 !important;
+}
+/* 确保图标靠右对齐 */
+
+.parameter-card {
+  margin-bottom: 0;
+}
+
+.card-content {
+  display: flex;
+  justify-content: space-between;
+  width: 100%;
+}
+
+.param-name {
+  font-size: 14px;
+  color: #606266;
+}
+.center-content {
+
+  display: flex;
+  justify-content: center; /* 水平居中 */
+  align-items: center; /* 垂直居中 */
+  height: 100%; /* 确保容器有足够的高度 */
+}
+.model-detail-root {
+  background: #f7f8fa;
+  min-height: 100vh;
+  padding: 0 24px 24px 24px;
+}
+.model-breadcrumb {
+  margin: 18px 0 8px 0;
+}
+.model-top-card {
+  border-radius: 10px;
+  border: 1px solid #e5e6eb;
+  background: #fff;
+  box-shadow: none;
+  padding: 0 32px 0 32px;
+  margin-bottom: 24px;
+}
+.model-top-flex {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  align-items: flex-start;
+  min-height: 160px;
+  padding: 24px 0 18px 0;
+}
+.model-top-left {
+  flex: 1.5;
+  display: flex;
+  flex-direction: column;
+  justify-content: flex-start;
+}
+.model-top-title {
+  font-size: 16px;
+  font-weight: 600;
+  margin-bottom: 12px;
+}
+.model-top-row {
+  display: flex;
+  align-items: center;
+  font-size: 13px;
+  margin-bottom: 4px;
+  gap: 8px;
+}
+.model-top-label {
+  color: #888;
+  min-width: 80px;
+  margin-right: 2px;
+
+}
+.model-top-value {
+  color: #222;
+  margin-right: 24px;
+  word-break: break-all;
+}
+.model-top-link {
+  color: #409eff;
+  text-decoration: underline;
+}
+.model-top-right {
+  flex: 1;
+  display: flex;
+  flex-direction: row;
+  align-items: flex-start;
+  justify-content: space-between;
+  min-width: 360px;
+  margin-left: 32px;
+  margin-right: 32px;
+  gap: 32px;
+}
+.model-top-right-info {
+  color: #222;
+  font-size: 13px;
+  margin-bottom: 0;
+  text-align: left;
+  display: flex;
+  flex-direction: column;
+  align-items: flex-start;
+  justify-content: center;
+  flex: 1;
+  min-width: 180px;
+}
+.model-top-right-btns {
+  display: flex;
+  flex-direction: row;
+  gap:0.1px;
+  margin-top: 0;
+  align-items: flex-start;
+  justify-content: flex-end;
+}
+.model-section-card {
+  border-radius: 10px;
+  border: 1px solid #e5e6eb;
+  background: #fff;
+  box-shadow: none;
+  margin-top: 24px;
+  padding: 0 0 18px 0;
+}
+.model-section-title {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 0 24px;
+  font-size: 15px;
+  font-weight: 500;
+  height: 48px;
+  background: #fff;
+  border-bottom: 1px solid #f0f0f0;
+}
+.model-btn-add {
+  min-width: 90px;
+  margin-top: 0;
+  align-self: flex-start;
+}
+.model-param-table {
+  margin: 0 24px 0 24px;
+  font-size: 13px;
+  --el-table-border-color: #e5e6eb;
+  --el-table-header-bg-color: #f7f8fa;
+  --el-table-header-text-color: #888;
+  --el-table-row-hover-bg-color: #f5f7fa;
+}
+.model-th {
+  background: #f7f8fa !important;
+  color: #888 !important;
+  font-weight: 500 !important;
+  height: 38px !important;
+}
+.model-td {
+  height: 38px !important;
+  padding: 0 8px !important;
+}
+.model-stat-row {
+  margin-top: 24px;
+  margin-bottom: 0;
+  position: relative;
+}
+.model-stat-card {
+  border-radius: 10px;
+  border: 1px solid #e5e6eb;
+  background: #fff;
+  box-shadow: none;
+  min-height: 100px;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: flex-start;
+  padding: 18px 0 12px 24px;
+}
+.model-stat-label {
+  color: #888;
+  font-size: 13px;
+  margin-bottom: 2px;
+}
+.model-stat-value {
+  font-size: 22px;
+  font-weight: 600;
+  color: #222;
+  margin: 2px 0 2px 0;
+}
+.model-stat-trend {
+  font-size: 12px;
+  margin-top: 2px;
+}
+.model-stat-trend.up {
+  color: #67c23a;
+}
+.model-stat-trend.down {
+  color: #f56c6c;
+}
+.model-stat-select {
+  position: absolute;
+  right: 24px;
+  top: 0;
+}
+.model-chart-section {
+  margin-top: 24px;
+  padding: 0 0 18px 0;
+}
+.model-chart-title {
+  font-size: 15px;
+  font-weight: 500;
+  color: #222;
+  margin-bottom: 8px;
+  padding-left: 24px;
+  padding-top: 18px;
+}
+.model-chart-footer {
+  color: #bfbfbf;
+  font-size: 12px;
+  text-align: right;
+  margin-top: 8px;
+  padding-right: 24px;
+}
+
+</style>

+ 15 - 14
src/views/market/index.vue → src/views/modelMarket/index.vue

@@ -66,7 +66,7 @@
         </el-button>
       </el-col>
       <el-col :span="1">
-        <el-button @click="handleExport"><el-icon><Download /></el-icon>导出</el-button>
+        <el-button @click="handleExport"><el-icon><Download/></el-icon>导出</el-button>
       </el-col>
     </el-row>
     <div class="content">
@@ -180,28 +180,29 @@
 </template>
 
 <script setup lang="ts">
-import addModel from './addModel.vue'
+import addModel from './components/addModel.vue'
 import { useRouter } from 'vue-router'
 import {onMounted} from 'vue';
 import {getModelByType,queryModelByNameType,deleteModel,queryModelList,toggleStatus,exportModel} from '@/api/modelConfig/index'
 import { ModelConfigVo} from '@/api/modelConfig/types'
-
 const router = useRouter()
-const addOrEdit = ref("新增")
-const serviceOption = ref(["OpenAI"])
-const modelNameOption = ref(["模型1","模型2"])
-const modelTypeOption = ref(["类型1","类型2"])
-const modelStateOption = ref(["全部","开启","关闭"])
+
+
+const addOrEdit = ref<string>("新增")
+const serviceOption = ref<string[]>(["OpenAI"])
+const modelNameOption = ref<string[]>(["模型1","模型2"])
+const modelTypeOption = ref<string[]>(["类型1","类型2"])
+const modelStateOption = ref<string[]>(["全部","开启","关闭"])
 const modelData = ref<ModelConfigVo[]>()
 const model = ref<ModelConfigVo>()
-const pageSize = ref(10)
-const selectedRows = ref([])
+const pageSize = ref<number>(10)
+const selectedRows = ref<ModelConfigVo[]>([])
 
-const modelInfo = ref(null)
+const modelInfo = ref<ModelConfigVo>(null)
 
-const modelName = ref(null)
-const modelType = ref(null)
-const service = ref(null)
+const modelName = ref<string>()
+const modelType = ref<string>()
+const service = ref<string>()
 const modelStatus = ref(null)
 const dialogVisible = ref(false)
 //test enabled

+ 23 - 14
src/views/modeldetailed/index.vue

@@ -6,18 +6,22 @@
             <el-breadcrumb-item>模型详情</el-breadcrumb-item>
         </el-breadcrumb>
         <div class="model-top-right-btns">
-            <el-button type="plain" size="small" class="custom-button">
-                <el-icon><Refresh /></el-icon>
-                刷新
-            </el-button>
-            <el-button type="primary" size="small" class="custom-button">
-                <el-icon><Edit /></el-icon>
-                编辑
-            </el-button>
-            <el-button type="danger" size="small" class="custom-button">
-                <el-icon><SwitchButton /></el-icon>
-                禁用
-            </el-button>
+          <el-button type="plain" size="small" @click="returnModel" class="custom-button">
+            <el-icon ><ArrowLeft /></el-icon>
+            返回列表
+          </el-button>
+          <el-button type="plain" size="small" class="custom-button">
+            <el-icon><Refresh /></el-icon>
+            刷新
+          </el-button>
+          <el-button type="primary" size="small" class="custom-button">
+            <el-icon><Edit /></el-icon>
+            编辑
+          </el-button>
+          <el-button type="danger" size="small" class="custom-button">
+            <el-icon><SwitchButton /></el-icon>
+            禁用
+          </el-button>
         </div>
 
         <!-- 顶部信息区(单卡片,左右分布) -->
@@ -178,12 +182,13 @@
 <script setup lang="ts">
 import { ref, onMounted } from 'vue'
 import * as echarts from 'echarts'
-import { Refresh } from "@element-plus/icons-vue"
-import { useRoute } from 'vue-router';
+import { ArrowLeft, Refresh } from '@element-plus/icons-vue';
+import { useRoute,useRouter } from 'vue-router';
 import { ModelConfigVo} from '@/api/modelConfig/types'
 import {toggleStatus} from '@/api/modelConfig/index.js'
 
 const route = useRoute()
+const router = useRouter()
 const model = ref<ModelConfigVo>(route.query.model)
 
 // 表格数据
@@ -232,6 +237,10 @@ const saveEdit = () => {
   drawerVisible.value = false
 }
 
+const returnModel = () => {
+  router.push('/modelMarket')
+}
+
 const initCallTrendChart = () => {
   const callTrendChart = echarts.init(document.getElementById('callTrendChart'))
   const option = {

+ 309 - 0
src/views/promptWordList/components/editPromptWord.vue

@@ -0,0 +1,309 @@
+<script setup lang="ts">
+import {useRouter} from 'vue-router';
+import {ref} from 'vue'
+const router = useRouter();
+
+const templateType = ref("用户提示词")
+const status = ref<boolean>()
+const activeName = ref()
+
+const returnList = () => {
+  router.push('/promptWordList')
+}
+</script>
+
+<template>
+  <div class="wrapper">
+    <div class="title-row">
+      <h3>编辑提示词</h3>
+      <el-button @click="returnList" style="align-self: center">返回列表</el-button>
+    </div>
+    <h5>基本信息</h5>
+    <div class="msg">
+      <div class="col">
+        <div class="label">模板名称</div>
+        <el-input />
+      </div>
+      <div class="col">
+        <div class="label">模板类型</div>
+        <el-radio-group v-model="templateType">
+          <el-radio value="用户提示词">用户提示词</el-radio>
+          <el-radio value="系统提示词">系统提示词</el-radio>
+        </el-radio-group>
+      </div>
+    </div>
+    <div class="msg">
+      <div class="col">
+        <div class="label">分类</div>
+        <el-select >
+          <el-option/>
+        </el-select>
+      </div>
+      <div class="col">
+        <div class="label">状态</div>
+        <el-switch v-model="status"/>
+      </div>
+    </div>
+    <el-row>
+      <div class="label">描述</div>
+      <el-input type="textarea"></el-input>
+    </el-row>
+    <h5>内容编辑</h5>
+    <el-tabs v-model="activeName">
+      <el-tab-pane label="默认(中文)">
+        <div class="box-content">
+          <div class="header">
+            <div class="title">提示词内容</div>
+            <div>
+              <span>格式化</span>
+              <span>全屏编辑</span>
+            </div>
+          </div>
+          <div class="main">
+            <el-input type="textarea"/>
+          </div>
+          <div class="footer">
+            <div class="title">可用变量:</div>
+            <span>{创作类型}</span>
+            <span>{用户输入}</span>
+            <span>{主题}</span>
+            <span>{风格}</span>
+            <span>{字数}</span>
+            <span>{情感}</span>
+          </div>
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="英文"></el-tab-pane>
+      <el-tab-pane label="日文"></el-tab-pane>
+      <el-tab-pane label="+添加语言"></el-tab-pane>
+    </el-tabs>
+    <div class="title-row">
+      <h5>模型选项</h5>
+      <div style="align-self: center">
+        <el-button>更换选项</el-button>
+        <el-button>解绑</el-button>
+      </div>
+    </div>
+    <div class="option-content">
+      <div>创意写作选项</div>
+      <div class="title-row" style="padding: 5px 0">
+        <div style="display:flex;gap: 10px;font-size: 12px">
+          <div>
+            <span>模型名称:  </span>
+            <span>gpt-4</span>
+          </div>
+          <div>
+            <span>温度参数:  </span>
+            <span>0.8</span>
+          </div>
+          <div>
+            <span>最大token数:  </span>
+            <span>2000</span>
+          </div>
+          <div>
+            <span>系统提示词:  </span>
+            <span>creative-writing-system</span>
+          </div>
+        </div>
+        <div style="color:#619dff; font-size: 12px;">creative-writing</div>
+      </div>
+    </div>
+    <div class="title-row">
+      <h5>权限设置</h5>
+      <el-button>添加权限</el-button>
+    </div>
+    <el-table
+      empty-text="暂无数据"
+      height="300px"
+      style="width: 100%"
+    >
+      <el-table-column label="用户/角色"/>
+      <el-table-column label="类型"/>
+      <el-table-column label="权限"/>
+      <el-table-column label="操作">
+        <template #default="scope">
+          <span style="color: #ff6cab;font-size: 12px">删除</span>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="title-row">
+      <h5>版本历史</h5>
+      <el-button style="align-self: center">查看</el-button>
+    </div>
+    <div class="title-row" style="padding: 5px 0">
+      <div class="history-msg">
+        <div class="now">当前</div>
+        <span>v1.5</span>
+        <span>2025-7-15 14:30</span>
+        <span>更新人:admin</span>
+        <span>变更原因:优化创作指引,增加情感基调参数</span>
+      </div>
+      <div class="history-operate">
+        <span>查看</span>
+      </div>
+    </div>
+    <div class="title-row" style="padding: 5px 0">
+      <div class="history-msg">
+        <span>v1.4</span>
+        <span>2025-7-15 14:30</span>
+        <span>更新人:system</span>
+        <span>变更原因:增加字数,限制参数</span>
+      </div>
+      <div class="history-operate">
+        <span>查看</span>
+        <span>对比</span>
+        <span>回滚</span>
+      </div>
+    </div>
+    <div class="title-row">
+      <h5>预览/测试</h5>
+      <el-button style="align-self: center" type="primary">发送测试请求</el-button>
+    </div>
+    <div class="label">变量设置</div>
+    <div class="render-section">
+      <div class="left">
+        <el-input model-value="创作类型"/>
+        <el-input/>
+        <el-input model-value="用户输入"/>
+        <el-input/>
+        <el-input model-value="主题"/>
+        <el-input/>
+        <el-input model-value="风格"/>
+        <el-input/>
+        <el-input model-value="字数"/>
+        <el-input/>
+        <el-input model-value="情感"/>
+        <el-input/>
+      </div>
+      <div class="right">
+        <el-input type="textarea" style="height: 100%"></el-input>
+      </div>
+    </div>
+
+    <div class="title-row">
+      <div>
+        <el-button type="danger">删除</el-button>
+        <el-button >复制</el-button>
+      </div>
+      <div>
+        <el-button>取消</el-button>
+        <el-button type="primary">保存</el-button>
+      </div>
+    </div>
+  </div>
+
+</template>
+
+<style scoped lang="scss">
+.render-section{
+  display: flex;
+  justify-content: space-between;
+  .left{
+    width: 48%;
+    display: flex;
+    flex-wrap: wrap;
+    gap:10px;
+    :deep(.el-input){
+      width: 47%;
+    }
+  }
+  .right{
+    width: 48%;
+    height: 100%;
+    :deep(.el-textarea__inner){
+      height:300px;
+    }
+  }
+}
+
+.option-content{
+  margin-left: 15px;
+  font-size: 14px;
+  span:nth-child(2n+1){
+    color:#999999;
+  }
+}
+.history-msg{
+  font-size:12px;
+  .now{
+    padding: 0 10px;
+    display:inline;
+    color: #b7eb8f;
+    background-color: #f6ffed;
+  }
+  span{
+    padding-right: 7px;
+  }
+  span:nth-child(2){
+    color:#999999;
+  }
+  span:nth-child(3){
+    color:#999999;
+  }
+}
+.history-operate{
+  font-size:12px;
+  display: flex;
+  gap:5px;
+  color: #619dff
+}
+.title-row{
+  display:flex;
+  justify-content: space-between;
+  padding:15px 0;
+}
+.label{
+  color:#999999;
+  font-size:12px;
+}
+.box-content{
+  border:1px solid #d9d9d9;
+  .header{
+    border:1px solid #d9d9d9;
+    display: flex;
+    justify-content: space-between;
+    .title{
+      font-size: 14px;
+      padding: 2px 5px 5px;
+    }
+    span{
+      color:#619dff;
+      font-size: 12px;
+      padding-right: 5px;
+    }
+  }
+  .main{
+    :deep(.el-textarea__inner){
+      min-height: 100px !important;
+    }
+  }
+  .footer{
+    border:1px solid #d9d9d9;
+    display: flex;
+    font-size: 12px;
+    gap:10px;
+    .title{
+      color:#999999;
+    }
+    span{
+      color:#619dff;
+    }
+  }
+}
+.msg{
+  display: flex;
+  gap:10px;
+  padding:15px 0;
+  .col {
+    display: flex;
+    flex-direction: column;
+    flex:1;
+  }
+}
+
+.wrapper{
+  margin:1px auto;
+  width:90%;
+}
+
+</style>

+ 2 - 2
src/views/promptWordList/index.vue

@@ -80,11 +80,11 @@ const doDelete = async (id) => {
       message:'删除成功',
       type:'success'
     })
-    fetchTemplatePage()
+    await fetchTemplatePage()
   }
 }
 const edit = () =>{
-  router.push('/editPromptWord')
+  router.push('/EditPromptWord')
 }
 </script>