浏览代码

市场模型接口 提示词列表

zhaoen 5 月之前
父节点
当前提交
b3fb001e9e

+ 1 - 1
.env.development

@@ -32,4 +32,4 @@ VITE_APP_CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e'
 VITE_APP_WEBSOCKET = false
 
 # sse 开关
-VITE_APP_SSE = true
+VITE_APP_SSE = false

+ 56 - 3
src/api/modelConfig/index.ts

@@ -1,13 +1,13 @@
 import request from '@/utils/request';
 import { AxiosPromise } from 'axios';
-import { modelConfigForm } from './types'
+import { modelConfigForm, ModelNameType, ModelList, ModelListVO } from './types';
 
 /**
  * 新增模型
  */
 export const addModel = (data:modelConfigForm) => {
   return request({
-    url:'/ai/ai/model/config',
+    url:'/ai/model/config',
     method: 'post',
     data:data
   })
@@ -17,8 +17,61 @@ export const addModel = (data:modelConfigForm) => {
  */
 export const editModel = (data:modelConfigForm) => {
   return request({
-    url:'/ai/ai/model/config',
+    url:'/ai/model/config',
     method: 'put',
     data:data
   })
 }
+
+/**
+ * 查询模型配置列表
+ */
+export const queryModelList = (data:ModelList) : AxiosPromise<ModelListVO> =>{
+  return request({
+    url:'/ai/model/config/list',
+    method: 'get',
+    data:data
+  })
+}
+
+/**
+ * 根据id删除模型
+ */
+export const deleteModel = (id:Number) => {
+  return request({
+    url:`/ai/model/config/${id}`,
+    method:'delete',
+  })
+}
+
+/**
+ * 根据模型类型和名称 查询模型配置列表
+ */
+export const queryModelByNameType = (data:ModelNameType):AxiosPromise<ModelListVO> => {
+  return request({
+    url:'/ai/model/config/getModelConfig',
+    method: 'get',
+    data:data
+  })
+}
+
+/**
+ * 根据模型名称 获取默认模型
+ */
+export const getModelByType = (data:string):AxiosPromise<ModelListVO> => {
+  return request({
+    url:'/ai/model/config/getDefaultModelConfig',
+    method: 'get',
+    data:data
+  })
+}
+/**
+ * 启用或禁用模型
+ */
+export const toggleStatus = (data:boolean,id:Number) => {
+  return request({
+    url:`/ai/model/config/toggle/${id}`,
+    method:'put',
+    data:data
+  })
+}

+ 158 - 0
src/api/modelConfig/types.ts

@@ -9,3 +9,161 @@ export interface modelConfigForm {
   priority:number | null,
   description:string
 }
+export interface ModelList {
+  apiKey?: string;
+  baseUrl?: string;
+  createdBy?: string;
+  createdTime?: Date;
+  description?: string;
+  id?: number;
+  modelName?: string;
+  modelType?: string;
+  modelVersion?: string;
+  parameters?: ModelParameterBo[];
+  priority?: number;
+  status?: number;
+  updatedBy?: string;
+  updatedTime?: Date;
+  [property: string]: any;
+}
+
+/**
+ * ModelParameterBo,AI模型参数BO
+ */
+export interface ModelParameterBo {
+  createdTime?: Date;
+  defaultValue?: string;
+  description?: string;
+  id?: number;
+  isRequired?: number;
+  modelConfigId?: number;
+  paramName?: string;
+  paramType?: string;
+  paramValue?: string;
+  updatedTime?: Date;
+  [property: string]: any;
+}
+
+export interface ModelNameType {
+  /**
+   * 模型名称
+   */
+  modelName: string;
+  /**
+   * 模型类型
+   */
+  modelType: string;
+  [property: string]: any;
+}
+
+export interface ModelType {
+  /**
+   * 模型类型
+   */
+  modelType: string;
+  [property: string]: any;
+}
+
+/**
+ * RListModelConfigVo,响应信息主体
+ */
+export interface ModelListVO {
+  /**
+   * 消息状态码
+   */
+  code?: number;
+  /**
+   * 数据对象
+   */
+  data?: ModelConfigVo[];
+  /**
+   * 消息内容
+   */
+  msg?: string;
+  [property: string]: any;
+}
+
+/**
+ * ModelConfigVo,AI模型配置VO
+ */
+export interface ModelConfigVo {
+  apiKey?: string;
+  baseUrl?: string;
+  /**
+   * 创建者
+   */
+  createBy?: number;
+  /**
+   * 创建部门
+   */
+  createDept?: number;
+  /**
+   * 创建时间
+   */
+  createTime?: Date;
+  definitionDescription?: string;
+  definitionModelCode?: string;
+  definitionModelName?: string;
+  definitionModelVersion?: string;
+  description?: string;
+  id?: number;
+  modelDefinitionId?: number;
+  modelName?: string;
+  modelType?: string;
+  modelVersion?: string;
+  parameters?: ModelParameterVo[];
+  /**
+   * 请求参数
+   */
+  params?: { [key: string]: any };
+  priority?: number;
+  status?: number;
+  /**
+   * 租户编号
+   */
+  tenantId?: string;
+  /**
+   * 更新者
+   */
+  updateBy?: number;
+  /**
+   * 更新时间
+   */
+  updateTime?: Date;
+  [property: string]: any;
+}
+
+/**
+ * ModelParameterVo,AI模型参数VO
+ */
+export interface ModelParameterVo {
+  createdTime?: Date;
+  defaultValue?: string;
+  description?: string;
+  id?: number;
+  isRequired?: number;
+  modelConfigId?: number;
+  paramName?: string;
+  paramType?: string;
+  paramValue?: string;
+  updatedTime?: Date;
+  [property: string]: any;
+}
+/**
+ * RModelConfigVo,响应信息主体
+ */
+export interface ModelVO {
+  /**
+   * 消息状态码
+   */
+  code?: number;
+  /**
+   * 数据对象
+   */
+  data?: ModelConfigVo;
+  /**
+   * 消息内容
+   */
+  msg?: string;
+  [property: string]: any;
+}

+ 13 - 7
src/router/index.ts

@@ -103,18 +103,19 @@ export const constantRoutes: RouteRecordRaw[] = [
         name:'Dashboard',
         meta: {title: '仪表盘', icon: 'dashboard', affix: true}
       },
-      {
-          path: '/modeldetailed',
-          component: () => import('@/views/modeldetailed/index.vue'),
-          name:'ModelDetailed',
-          meta: {title: '模型详细', icon: 'dashboard', affix: true}
-      },
       {
         path: '/promptwordManagmant',
         component: () => import('@/views/promptwordManagement/index.vue'),
         name:'PromptWordManagement',
         meta: {title: '提示词分类管理', icon: 'dashboard', affix: true}
-      },{
+      },
+      {
+        path: '/promptWordClassify',
+        component: () => import('@/views/promptWordClassify/index.vue'),
+        name:'PromptWordClassify',
+        meta: {title: '提示词列表', icon: 'dashboard', affix: true}
+      },
+      {
         path: '/promptPermissionsManagmant',
         component: () => import('@/views/promptpermission/index.vue'),
         name:'PromptPermissionManagement',
@@ -127,6 +128,11 @@ export const constantRoutes: RouteRecordRaw[] = [
     component: () => import('@/views/modeldetailed/index.vue'),
     name:'ModelDetailed',
   },
+  {
+    path: '/editPromptWord',
+    component: () => import('@/views/editPromptWord/index.vue'),
+    name:'EditPromptWord',
+  },
   {
     path: '/user',
     component: Layout,

+ 287 - 0
src/views/editPromptWord/index.vue

@@ -0,0 +1,287 @@
+<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('/promptWordClassify')
+}
+</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">
+        <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">
+      <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;
+  span{
+    padding-right: 5px;
+  }
+  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{
+    border:1px solid #d9d9d9;
+  }
+  .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>

+ 66 - 12
src/views/market/index.vue

@@ -42,7 +42,7 @@
       </el-col>
       <el-col :span="4">
         <el-form-item label="状态">
-          <el-select v-model="modelState" placeholder="全部">
+          <el-select v-model="modelStatus" placeholder="全部">
             <el-option
               v-for="item in modelStateOption"
               :label="item"
@@ -53,10 +53,10 @@
         </el-form-item>
       </el-col>
       <el-col :span="1" :offset="4" style="padding-left: 30px">
-        <el-button type="primary">搜索</el-button>
+        <el-button type="primary" @click="handleSearch">搜索</el-button>
       </el-col>
       <el-col :span="1" style="padding-left: 20px;margin-left:30px">
-        <el-button>重置</el-button>
+        <el-button @click="handleReset">重置</el-button>
       </el-col>
     </el-row>
     <el-row :gutter="20">
@@ -124,21 +124,35 @@
         :data="models"
         style="width: 100%"
         height="100%"
+        @selection-change="handleSelectionChange"
       >
         <el-table-column type="selection"/>
-        <el-table-column label="模型名称"></el-table-column>
-        <el-table-column lable="模型类型"></el-table-column>
-        <el-table-column label="模型版本"></el-table-column>
-        <el-table-column label="参数配置"></el-table-column>
-        <el-table-column label="状态"></el-table-column>
-        <el-table-column label="优先级"></el-table-column>
-        <el-table-column label="创建时间"></el-table-column>
+        <el-table-column label="模型名称" prop="modelName"></el-table-column>
+        <el-table-column lable="模型类型" prop="modelType"></el-table-column>
+        <el-table-column label="模型版本" prop="modelVersion"></el-table-column>
+        <el-table-column label="参数配置">
+          <template #default="scope">
+            <span>{{scope.parameters.length}}个参数</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="状态">
+          <template #default>
+            <div v-if="scope.status === 1" class="status enabled">
+              启用
+            </div>
+            <div v-else class="status testing">
+              测试中
+            </div>
+          </template>
+        </el-table-column>
+        <el-table-column label="优先级" prop="priority"></el-table-column>
+        <el-table-column label="创建时间" prop="createTime"></el-table-column>
         <el-table-column label="操作">
           <template #default="slot">
             <el-icon color="#1890ff" size="25px" class="icon-gap"><View /></el-icon>
             <el-icon color="#1890ff" size="25px" class="icon-gap" @click="edit(slot.$index,slot.row)"><Edit /></el-icon>
             <el-icon color="#1890ff" size="25px" class="icon-gap"><List /></el-icon>
-            <el-icon color="#ffa8e3" size="25px" class="icon-gap"><SwitchButton /></el-icon>
+            <el-icon :color="slot.status===0? '#b7eb8f' : '#ffa8e3'" size="25px" class="icon-gap" @click="toggleModelStatus(slot.row)"><SwitchButton /></el-icon>
           </template>
         </el-table-column>
       </el-table>
@@ -168,6 +182,8 @@
 <script setup lang="ts">
 import addModel from './addModel.vue'
 import { useRouter } from 'vue-router'
+import {onMounted} from 'vue';
+import {getModelByType,queryModelByNameType,deleteModel,queryModelList,toggleStatus} from '@/api/modelConfig/index'
 
 const router = useRouter()
 const addOrEdit = ref("新增")
@@ -177,17 +193,37 @@ const modelTypeOption = ref(["类型1","类型2"])
 const modelStateOption = ref(["全部","开启","关闭"])
 const models = ref([{}])
 const pageSize = ref(10)
+const selectedRows = ref([])
 
 const modelInfo = ref(null)
 
 const modelName = ref(null)
 const modelType = ref(null)
 const service = ref(null)
-const modelState = ref(null)
+const modelStatus = ref(null)
 const dialogVisible = ref(false)
 //test enabled
 const statusClass = ref('enabled')
 
+onMounted(()=>{
+  fetchData()
+})
+const fetchData = async() =>{
+  const res = await queryModelList({})
+  if(res.code===0){
+    models.value = res.data
+  }
+}
+const toggleModelStatus = async (row) =>{
+  const data = row.modelStatus === 0
+  const res = await toggleStatus(data,row.id)
+  if(res.code===0){
+    await fetchData()
+  }
+}
+const handleSelectionChange = (value)=>{
+  selectedRows.value = value
+}
 const handleAddModel = ()=>{
   addOrEdit.value="新增"
   dialogVisible.value = true;
@@ -201,6 +237,24 @@ const edit = ((index,row)=>{
   addOrEdit.value = "编辑"
   dialogVisible.value=true
 })
+const handleSearch = async () => {
+  if(modelType.value&&modelName.value){
+    const data = {
+      modelName:modelName.value,
+      modelType:modelType.value
+    }
+    const res = await queryModelByNameType(data)
+    if(res.code===0){
+      models.value = res.data
+    }
+  }else if(modelType.value){
+    const res = await getModelByType(modelType.value)
+    if(res.code===0){
+      models.value=[];
+      models.push(res.data)
+    }
+  }
+}
 </script>
 
 <style scoped lang="scss">

+ 141 - 0
src/views/promptWordClassify/index.vue

@@ -0,0 +1,141 @@
+<script setup lang="ts">
+import {ref} from 'vue'
+import {useRouter} from 'vue-router';
+const router = useRouter()
+
+const defaultProps = ref()
+
+interface Tree{
+  label:string
+  children?: Tree[]
+}
+const data : Tree[] = [
+  {label:'全部提示词'},
+  {label:'聊天对话'},
+  {
+    label:'内容创作',
+    children : [
+      {label:'文案撰写'},
+      {label:'文章生成'}
+    ]
+  }
+]
+const createTime = ref('')
+const templateData = ref([{}])
+const pageSize = ref(10)
+const handleNodeClick = () => {
+
+}
+const edit = () =>{
+  router.push('/editPromptWord')
+}
+</script>
+
+<template>
+  <el-container>
+    <el-aside width="200px">
+      <el-container>
+        <el-header>
+          <h4>提示词分类</h4>
+        </el-header>
+        <el-main>
+          <el-tree
+            :data="data"
+            :props="defaultProps"
+            @node-click = "handleNodeClick"
+          >
+          </el-tree>
+        </el-main>
+      </el-container>
+    </el-aside>
+    <el-container>
+      <el-header>
+        <h3>提示词管理</h3>
+      </el-header>
+      <el-main>
+        <el-row>
+          <el-col :span="16">
+            <el-input placeholder="搜索提示词名称,描述..."/>
+          </el-col>
+          <el-col :span="3" :offset="1">
+            <el-form-item label="类型">
+              <el-select>
+                <el-option/>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="3" :offset="1">
+            <el-form-item label="状态">
+              <el-select>
+                <el-option/>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="创建时间:">
+              <el-date-picker
+                v-model="createTime"
+                type="datetimerange"
+                start-placeholder="年 -月-日"
+                end-placeholder="年 -月-日"
+                range-separator="至"
+                format="YYYY-MM-DD"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="1" :offset="1">
+            <el-button>重置</el-button>
+          </el-col>
+          <el-col :span="1" :offset="1">
+            <el-button type="primary">查询</el-button>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-table
+            :data="templateData"
+            empty-text="暂无数据"
+            height="400px"
+          >
+            <el-table-column label="序号">
+              <template #default="scope">
+                {{++scope.$index}}
+              </template>
+            </el-table-column>
+            <el-table-column label="模板名称" prop="templateName"/>
+            <el-table-column label="模板类型" prop="templateType"/>
+            <el-table-column label="分类"/>
+            <el-table-column label="状态"/>
+            <el-table-column label="版本号"/>
+            <el-table-column label="最后更新时间"/>
+            <el-table-column label="操作">
+              <template #default="scope">
+                <el-icon color="#1890ff" size="25px" class="icon-gap"><View /></el-icon>
+                <el-icon color="#1890ff" size="25px" class="icon-gap" @click="edit(scope.$index,scope.row)"><Edit /></el-icon>
+                <el-icon color="#1890ff" size="25px" class="icon-gap"><List /></el-icon>
+                <el-icon color="" size="25px" class="icon-gap"><Delete /></el-icon>
+              </template>
+            </el-table-column>
+          </el-table>
+        </el-row>
+        <div class="page-right"></div>
+        <el-pagination
+          background
+          layout="prev, pager, next"
+          :total="10"
+          :page-size="pageSize"
+        />
+      </el-main>
+    </el-container>
+  </el-container>
+</template>
+
+<style scoped lang="scss">
+.icon-gap{
+  padding-left: 5px;
+}
+.page-right{
+  float: right;
+}
+</style>