Pārlūkot izejas kodu

模型供应商

zhaoen 5 mēneši atpakaļ
vecāks
revīzija
832923ea29

+ 31 - 48
src/views/modleServiceProvide/components/AdditionInfo.vue

@@ -69,19 +69,19 @@
       </el-col>
     </el-row>
 
-    <!-- 备注 -->
-    <el-row :gutter="20">
-      <el-col :span="24">
-        <el-form-item label="备注" prop="remark">
-          <el-input
-              v-model="form.remark"
-              type="textarea"
-              :rows="4"
-              placeholder="请输入备注信息"
-          />
-        </el-form-item>
-      </el-col>
-    </el-row>
+    <!--&lt;!&ndash; 备注 &ndash;&gt;-->
+    <!--<el-row :gutter="20">-->
+    <!--  <el-col :span="24">-->
+    <!--    <el-form-item label="备注" prop="remark">-->
+    <!--      <el-input-->
+    <!--          v-model="form.remark"-->
+    <!--          type="textarea"-->
+    <!--          :rows="4"-->
+    <!--          placeholder="请输入备注信息"-->
+    <!--      />-->
+    <!--    </el-form-item>-->
+    <!--  </el-col>-->
+    <!--</el-row>-->
 
   </el-form>
 </template>
@@ -90,25 +90,23 @@
 import { ref } from 'vue'
 import { ElMessage } from 'element-plus'
 
-// ================== 表单数据类型定义 ==================
-interface Form {
-  contact: string
-  website: string
-  apiDocUrl: string
-  pricingUrl: string
-  description: string
-  remark: string
-}
-const dialogVisible = ref(true)
-// ================== 表单数据初始化 ==================
-const form = ref<Form>({
-  contact: '',
-  website: '',
-  apiDocUrl: '',
-  pricingUrl: '',
-  description: '',
-  remark: ''
-})
+
+const props = defineProps<{
+    modelValue: {
+        contactInfo: string
+        website: string
+        apiDocUrl: string
+        pricingUrl: string
+        description: string
+    };
+}>();
+
+const emit = defineEmits(['update:modelValue']);
+
+const model = computed({
+    get: () => props.modelValue,
+    set: (value) => emit('update:modelValue', value)
+});
 
 // ================== 表单验证规则 ==================
 const rules = {
@@ -129,22 +127,7 @@ const rules = {
   ]
 }
 
-// ================== 表单引用 ==================
-const formRef = ref()
-
-// ================== 提交方法 ==================
-const submitForm = () => {
-  formRef.value.validate((valid: boolean) => {
-    if (valid) {
-      ElMessage.success('验证通过,准备提交')
-      console.log('提交数据:', form.value)
-      // 这里可以调用 API 提交数据
-    } else {
-      ElMessage.error('请检查表单输入')
-      return false
-    }
-  })
-}
+
 </script>
 
 <style scoped lang="scss">

+ 51 - 74
src/views/modleServiceProvide/components/ApiInfo.vue

@@ -1,6 +1,54 @@
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import { ElMessage } from 'element-plus'
+const dialogVisible = ref(true)
+// ================== 表单数据类型定义 ==================
+const props = defineProps<{
+    modelValue: {
+        defaultUrl: string
+        extraConfig: string
+    };
+}>();
+
+const emit = defineEmits(['update:modelValue']);
+
+const model = computed({
+    get: () => props.modelValue,
+    set: (value) => emit('update:modelValue', value)
+});
+
+
+
+
+// ================== 表单验证规则 ==================
+const rules = {
+    defaultUrl: [
+        { required: true, message: '请输入默认 API 地址', trigger: 'blur' },
+        { type: 'url', message: '请输入合法的 URL 地址', trigger: 'blur' }
+    ],
+    authType: [
+        { required: true, message: '请选择认证方式', trigger: 'change' }
+    ],
+    requestHeaderKey: [
+        { required: true, message: '请输入请求头 Key', trigger: 'blur' }
+    ],
+    requestHeaderValuePrefix: [
+        { required: true, message: '请输入请求头 Value 前缀', trigger: 'blur' }
+    ],
+    retryCount: [
+        { required: true, message: '请输入重试次数', trigger: 'blur' },
+        { type: 'number', min: 0, max: 10, message: '重试次数应在 0~10 之间', trigger: 'blur' }
+    ]
+}
+
+
+
+</script>
+
 <template>
   <el-form
-      :model="form"
+      :model="model"
       label-position="top"
       label-width="120px"
       :rules="rules"
@@ -15,7 +63,7 @@
             <span class="el-form-item__label">默认API地址</span>
           </template>
           <el-input
-              v-model="form.defaultUrl"
+              v-model="model.defaultUrl"
               placeholder="请输入默认API地址,如:https://api.openai.com/v1"
           />
           <div class="input-tips">用于连接服务器的API基础地址</div>
@@ -102,7 +150,7 @@
       <el-col :span="24">
         <el-form-item label="拓展配置" prop="extraConfig">
           <el-input
-              v-model="form.extraConfig"
+              v-model="model.extraConfig"
               type="textarea"
               :rows="4"
               placeholder="请输入拓展配置,例如:{ timeout: 5000, proxy: 'xxx' }"
@@ -116,77 +164,6 @@
   </el-form>
 </template>
 
-<script setup lang="ts">
-import { ref } from 'vue'
-import { ElMessage } from 'element-plus'
-const dialogVisible = ref(true)
-// ================== 表单数据类型定义 ==================
-interface Form {
-  defaultUrl: string
-  authType: string
-  requestHeaderKey: string
-  requestHeaderValuePrefix: string
-  requestTimeout: number | null
-  retryCount: number | null
-  extraConfig: string
-}
-
-// ================== 表单数据初始化 ==================
-const form = ref<Form>({
-  defaultUrl: '',
-  authType: 'API_KEY',
-  requestHeaderKey: 'Authorization',
-  requestHeaderValuePrefix: 'Bearer',
-  requestTimeout: 6,
-  retryCount: 3,
-  extraConfig: ''
-})
-
-// ================== 认证方式选项 ==================
-const authTypeOption = [
-  { label: 'API Key', value: 'API_KEY' },
-  { label: 'OAuth2', value: 'OAUTH2' },
-  { label: 'None', value: 'NONE' }
-]
-
-// ================== 表单验证规则 ==================
-const rules = {
-  defaultUrl: [
-    { required: true, message: '请输入默认 API 地址', trigger: 'blur' },
-    { type: 'url', message: '请输入合法的 URL 地址', trigger: 'blur' }
-  ],
-  authType: [
-    { required: true, message: '请选择认证方式', trigger: 'change' }
-  ],
-  requestHeaderKey: [
-    { required: true, message: '请输入请求头 Key', trigger: 'blur' }
-  ],
-  requestHeaderValuePrefix: [
-    { required: true, message: '请输入请求头 Value 前缀', trigger: 'blur' }
-  ],
-  retryCount: [
-    { required: true, message: '请输入重试次数', trigger: 'blur' },
-    { type: 'number', min: 0, max: 10, message: '重试次数应在 0~10 之间', trigger: 'blur' }
-  ]
-}
-
-// ================== 表单引用 ==================
-const formRef = ref()
-
-// ================== 提交方法 ==================
-const submitForm = () => {
-  formRef.value.validate((valid: boolean) => {
-    if (valid) {
-      ElMessage.success('验证通过,准备提交')
-      console.log('提交数据:', form.value)
-      // 这里可以调用 API 提交数据
-    } else {
-      ElMessage.error('请检查表单输入')
-      return false
-    }
-  })
-}
-</script>
 
 <style scoped lang="scss">
 .input-tips {

+ 62 - 67
src/views/modleServiceProvide/components/BasicInfo.vue

@@ -4,24 +4,37 @@ import { UploadFilled } from '@element-plus/icons-vue'
 import { ElMessage } from 'element-plus'
 
 // ================== 表单数据类型定义 ==================
-interface Form {
-  vendorCode: string
-  vendorName: string
-  modelKind: string[]
-  isofficial: boolean
-  status: boolean
-  sortOrder: number | null
-}
 
-// ================== 表单数据初始化 ==================
-const form = ref<Form>({
-  vendorCode: '',
-  vendorName: '',
-  modelKind: [],
-  isofficial: false,
-  status: true,
-  sortOrder: null
-})
+const props = defineProps<{
+    modelValue: {
+        vendorCode: string
+        vendorName: string
+        modelKind: string[]
+        logoUrl: string;
+        logoFile: File | null;
+        isofficial: boolean
+        status: boolean
+        sortOrder: number | null
+    };
+}>();
+
+const emit = defineEmits(['update:modelValue']);
+
+const model = computed({
+    get: () => props.modelValue,
+    set: (value) => emit('update:modelValue', value)
+});
+
+const fileList = ref<any[]>([]);
+// 文件变更时更新 logoFile
+const handleLogoChange = (file: any) => {
+    model.value.logoFile = file.raw; // 获取原始 File 对象
+};
+
+// 超出文件数量限制提示
+const handleExceed = () => {
+    alert('最多只能上传一个文件');
+};
 
 // ================== 模型种类选项 ==================
 const modelKindOption = ['大语言模型', '多模态', 'OCR', '视觉', '向量化', '重排序', '语音']
@@ -46,32 +59,10 @@ const rules = {
 
 // ================== 表单引用 ==================
 const formRef = ref()
-
-// ================== 提交方法 ==================
-const submitForm = () => {
-  formRef.value.validate((valid: boolean) => {
-    if (valid) {
-      ElMessage.success('验证通过,准备提交')
-      console.log('提交数据:', form.value)
-      // 这里可以调用 API 提交数据
-    } else {
-      ElMessage.error('请检查表单输入')
-      return false
-    }
-  })
-}
-
-// ================== 控制对话框显示 ==================
-const dialogVisible = ref(true)
-
-interface ProviderModel {
-
-}
-
 </script>
 
 <template>
-  <el-form :model="form" label-position="top" label-width="100px" :rules="rules" ref="formRef">
+  <el-form :model="model" label-position="top" label-width="100px" :rules="rules" ref="formRef">
     <!-- 服务商编码 -->
     <el-row>
       <el-col :span="24">
@@ -79,7 +70,7 @@ interface ProviderModel {
           <template #label>
             <span class="el-form-item__label">服务商编码</span>
           </template>
-          <el-input v-model="form.vendorCode" placeholder="输入服务商编码,如:openai" />
+          <el-input v-model="model.vendorCode" placeholder="输入服务商编码,如:openai" />
           <div class="input-tips">英文小写,不含特殊字符,作为系统标识</div>
         </el-form-item>
       </el-col>
@@ -92,7 +83,7 @@ interface ProviderModel {
           <template #label>
             <span class="el-form-item__label">服务商名称</span>
           </template>
-          <el-input v-model="form.vendorName" placeholder="输入服务商名称,如:OpenAi" />
+          <el-input v-model="model.vendorName" placeholder="输入服务商名称,如:OpenAi" />
         </el-form-item>
       </el-col>
     </el-row>
@@ -104,7 +95,7 @@ interface ProviderModel {
           <template #label>
             <span class="el-form-item__label">模型种类</span>
           </template>
-          <el-checkbox-group v-model="form.modelKind" style="width: 100%">
+          <el-checkbox-group v-model="model.modelKind" style="width: 100%">
             <el-checkbox
                 v-for="option in modelKindOption"
                 :key="option"
@@ -116,32 +107,36 @@ interface ProviderModel {
       </el-col>
     </el-row>
 
-    <!-- Logo -->
-    <el-row :gutter="20">
-      <el-col :span="24">
-        <el-form-item label="Logo">
-          <el-upload
-              style="width: 100%"
-              class="upload-demo"
-              drag
-              action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
-              multiple
-          >
-            <el-icon class="el-icon--upload"><upload-filled /></el-icon>
-            <div class="el-upload__text">
-              点击或拖拽上传Logo
-            </div>
-          </el-upload>
-        </el-form-item>
-      </el-col>
-    </el-row>
+      <!-- Logo -->
+      <el-row :gutter="20">
+          <el-col :span="24">
+              <el-form-item label="Logo">
+                  <el-upload
+                          style="width: 100%"
+                          class="upload-demo"
+                          drag
+                          action="#"
+                          :auto-upload="false"
+                          :on-change="handleLogoChange"
+                          :file-list="fileList"
+                          :limit="1"
+                          :on-exceed="handleExceed"
+                  >
+                      <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+                      <div class="el-upload__text">
+                          点击或拖拽上传Logo
+                      </div>
+                  </el-upload>
+              </el-form-item>
+          </el-col>
+      </el-row>
 
     <!-- 官方认证 -->
     <el-row :gutter="20">
       <el-col :span="24">
         <el-form-item label="官方认证">
-          <el-switch v-model="form.isofficial" />
-          <span class="switch-label">{{ form.isofficial ? '是' : '否' }}</span>
+          <el-switch v-model="model.isofficial" />
+          <span class="switch-label">{{ model.isofficial ? '是' : '否' }}</span>
         </el-form-item>
       </el-col>
     </el-row>
@@ -150,8 +145,8 @@ interface ProviderModel {
     <el-row :gutter="20">
       <el-col :span="12">
         <el-form-item label="状态">
-          <el-switch v-model="form.status" />
-          <span class="switch-label">{{ form.status ? '启用' : '未启用' }}</span>
+          <el-switch v-model="model.status" />
+          <span class="switch-label">{{ model.status ? '启用' : '未启用' }}</span>
         </el-form-item>
       </el-col>
     </el-row>
@@ -160,7 +155,7 @@ interface ProviderModel {
     <el-row :gutter="20">
       <el-col :span="12">
         <el-form-item label="排序值" >
-          <el-input v-model.number="form.sortOrder" placeholder="0" />
+          <el-input v-model.number="model.sortOrder" placeholder="0" />
           <div class="input-tips">数值越小越靠前</div>
         </el-form-item>
       </el-col>

+ 167 - 111
src/views/modleServiceProvide/index.vue

@@ -3,49 +3,49 @@
     <el-row>
       <h3>模型服务商管理</h3>
     </el-row>
-    <el-row :gutter="20">
-      <el-col :span="4" style="margin-left: 20px">
-        <el-form-item label="服务商名称">
-          <el-input v-model="input" style="width: 240px" placeholder="请输入服务商名称" />
-        </el-form-item>
-
-      </el-col>
-      <el-col :span="5">
-        <el-form-item label="服务商编码">
-          <el-input v-model="input" style="width: 240px" placeholder="请输入服务商编码" />
-        </el-form-item>
-      </el-col>
-      <el-col :span="4">
-        <el-form-item label="服务商种类">
-          <el-select v-model="modelKind" placeholder="全部">
-            <el-option
-                v-for="item in modelKindOption"
-                :value="item"
-                :label="item"
-                :key="item"
-            />
-          </el-select>
-        </el-form-item>
-      </el-col>
-      <el-col :span="4">
-        <el-form-item label="状态">
-          <el-select v-model="modelState" placeholder="全部">
-            <el-option
-                v-for="item in modelStateOption"
-                :label="item"
-                :value="item"
-                :key="item"
-            />
-          </el-select>
-        </el-form-item>
-      </el-col>
-      <el-col :span="1" :offset="4" style="padding-left: 30px">
-        <el-button type="primary">搜索</el-button>
-      </el-col>
-      <el-col :span="1" style="padding-left: 30px">
-        <el-button>重置</el-button>
-      </el-col>
-    </el-row>
+    <!--  筛选器-->
+      <el-row :gutter="20">
+          <el-col :span="4" style="margin-left: 20px">
+              <el-form-item label="服务商名称">
+                  <el-input v-model="filters.vendorName" style="width: 240px" placeholder="请输入服务商名称" />
+              </el-form-item>
+          </el-col>
+          <el-col :span="5">
+              <el-form-item label="服务商编码">
+                  <el-input v-model="filters.vendorCode" style="width: 240px" placeholder="请输入服务商编码" />
+              </el-form-item>
+          </el-col>
+          <el-col :span="4">
+              <el-form-item label="服务商种类">
+                  <el-select v-model="filters.modelKind" placeholder="全部">
+                      <el-option
+                              v-for="item in modelKindOption"
+                              :value="item"
+                              :label="item"
+                              :key="item"
+                      />
+                  </el-select>
+              </el-form-item>
+          </el-col>
+          <el-col :span="4">
+              <el-form-item label="状态">
+                  <el-select v-model="filters.status" placeholder="全部">
+                      <el-option
+                              v-for="item in modelStateOption"
+                              :label="item"
+                              :value="item"
+                              :key="item"
+                      />
+                  </el-select>
+              </el-form-item>
+          </el-col>
+          <el-col :span="1" :offset="4" style="padding-left: 30px">
+              <el-button type="primary">搜索</el-button>
+          </el-col>
+          <el-col :span="1" style="padding-left: 30px">
+              <el-button @click="resetFilters">重置</el-button>
+          </el-col>
+      </el-row>
     <el-row :gutter="20">
       <el-col :span="2">
         <el-button type="primary" @click="dialogVisible = true">+新增服务商</el-button>
@@ -131,9 +131,9 @@
             "
             >
               {{
-                slot.row.status === 'active'
+                slot.row.status === 1
                     ? '启用'
-                    : slot.row.status === 'configuring'
+                    : slot.row.status === ''
                         ? '配置中'
                         : '待配置'
               }}
@@ -186,32 +186,85 @@
 </template>
 
 <script setup lang="ts">
-import { ref } from 'vue'
+import { ref, onMounted } from 'vue'
 import type { TabsInstance, FormInstance } from 'element-plus'
 import {Download, More, UploadFilled} from "@element-plus/icons-vue";
 import { View, Edit, List, Check, Close } from '@element-plus/icons-vue'
 import BasicInfo from "@/views/modleServiceProvide/components/BasicInfo.vue";
 import ApiInfo from "@/views/modleServiceProvide/components/ApiInfo.vue";
 import AdditionInfo from "@/views/modleServiceProvide/components/AdditionInfo.vue";
-import components from "../../../vite/plugins/components";
-import listModelVendor from "@/api/modleServiceProvide/index"
-import type { ModelVendorQuery, ModelVendorDto } from '../../api/modleServiceProvide/type' // 根据实际类型调整
+import { listModelVendor,addModelVendor, ModelVendorQuery, ModelVendorDto } from '@/api/modleServiceProvide';
+
+import request from "@/utils/request";
+// 筛选条件
+const filters = ref({
+    vendorName: '',
+    vendorCode: '',
+    modelKind: '',
+    status: ''
+});
+
+// 筛选后的数据
+const filteredData = computed(() => {
+    return dataList.value.filter(item => {
+        const matchName = item.vendorName.includes(filters.value.vendorName);
+        const matchCode = item.vendorCode.includes(filters.value.vendorCode);
+        const matchKind = !filters.value.modelKind || item.modelKind === filters.value.modelKind;
+        const matchStatus = !filters.value.status || item.status === filters.value.status;
+        return matchName && matchCode && matchKind && matchStatus;
+    });
+});
+
+// 重置筛选条件
+const resetFilters = () => {
+    filters.value = {
+        vendorName: '',
+        vendorCode: '',
+        modelKind: '',
+        status: ''
+    };
+};
+// 分页参数
+const queryParams = ref<ModelVendorQuery>({
+  pageNum: 1,
+  pageSize: 10
+});
+
+// 数据绑定
+const dataList = ref<ModelVendorDto[]>([]);
+const total = ref<number>(0);
+const loading = ref<boolean>(false);
+
+// 获取数据方法
+const getList = async () => {
+  loading.value = true;
+  try {
+    const res = await listModelVendor(queryParams.value);
+    dataList.value = res.data.list;
+    total.value = res.data.total;
+  } catch (error) {
+    console.error('获取数据失败:', error);
+  } finally {
+    loading.value = false;
+  }
+};
+
+// 页面加载时请求数据
+onMounted(() => {
+  getList();
+});
 
 
-const serviceOption = ref(["OpenAI"])
-const modelNameOption = ref(["服务商1","服务商2"])
 const modelKindOption = ref(["大语言模型","多模态","OCR","视觉","向量化","重排序","语音"])
 const modelStateOption = ref(["全部","开启","关闭"])
 // const models = ref([])
-const total = ref(50) // 总条目数
 const currentPage = ref(1) // 当前页码
 const pageSize = ref(10) // 每页显示条目个数
 const selected = ref<number[]>([]) // 存储选中的行ID
-const modelName = ref(null)
-const modelKind = ref(null)
+
 const activeTab = 'info1'
-const service = ref(null)
 const modelState = ref(null)
+
 // 定义表格数据的类型
 interface ProviderModel {
   id: number
@@ -291,40 +344,33 @@ const handleSelectionChange = (selection: ProviderModel[]) => {
 const dialogVisible = ref(false)
 const formRef = ref<FormInstance>()
 
-interface Info1 {
-  name: string
-  desc: string
-}
 
-interface Info2 {
-  phone: string
-  email: string
-}
 const formData = ref({
-  info1: { name: '', desc: '' },
-  info2: { phone: '', email: '' },
-  info3: { address: '', remark: '' }
+    info1: {
+        vendorCode: '',
+        vendorName: '',
+        modelKind: '',
+        logoUrl: '',
+        logoFile: null, // 用于保存上传的文件对象
+        isOfficial: false,
+        status:0,
+        sortOrder: 0
+    },
+    info2: {
+        defaultUrl: '',
+        extraConfig: ''
+    },
+    info3: {
+        contactInfo: '',
+        website: '',
+        apiDocUrl: '',
+        pricingUrl: '',
+        description: '',
+
+    }
 })
-interface Info3 {
-  address: string
-  remark: string
-}
 
-interface formData {
-  info1: Info1
-  info2: Info2
-  info3: Info3
-}
 
-const form = ref({
-  vendorName: '',
-  vendorCode: '',
-  modelKind: '',
-  logoUrl: '',
-  isofficial: false,
-  apiAccess: false,
-  status: 'active'
-})
 
 //表单规则
 const rules = {
@@ -355,35 +401,45 @@ const beforelogoUrlUpload = (file) => {
   return isValid
 }
 
-// 提交表单
 const submitForm = () => {
-  formRef.value.validate(valid => {
-    if (valid) {
-      // 添加 ID 和 创建时间
-      const newProvider = {
-        ...form.value,
-        id: Math.floor(Math.random() * 10000),
-        createTime: new Date().toLocaleString()
-      }
-
-      // 添加到表格数据
-      models.value.unshift(newProvider)
-
-      // 关闭弹窗并重置表单
-      dialogVisible.value = false
-      form.value = {
-        vendorName: '',
-        vendorCode: '',
-        modelKind: '',
-        logoUrl: '',
-        isofficial: false,
-        apiAccess: false,
-        status: 'active'
-      }
-    } else {
-      return false
+    const data = formData.value;
+
+    const submitData = new FormData();
+
+    // 添加普通字段
+    submitData.append('vendorName', data.info1.vendorName);
+    submitData.append('vendorCode', data.info1.vendorCode);
+    submitData.append('modelKind', data.info1.modelKind);
+    submitData.append('isOfficial', data.info1.isOfficial.toString());
+    submitData.append('sortOrder', data.info1.sortOrder.toString());
+
+    submitData.append('defaultUrl', data.info2.defaultUrl);
+    submitData.append('extraConfig', data.info2.extraConfig);
+
+    submitData.append('apiDocUrl', data.info3.apiDocUrl);
+    submitData.append('pricingUrl', data.info3.pricingUrl);
+    submitData.append('contactInfo', data.info3.contactInfo);
+    submitData.append('website', data.info3.website);
+
+    // 添加文件
+    if (data.info1.logoFile) {
+        submitData.append('logo', data.info1.logoFile);
     }
-  })
+
+   const res =  listModelVendor(submitData);
+
+    // 发送请求
+    // axios.post('/api/model/vendor/save', submitData, {
+    //     headers: {
+    //         'Content-Type': 'multipart/form-data'
+    //     }
+    // }).then(() => {
+    //     ElMessage.success('提交成功');
+    //     dialogVisible.value = false;
+    // }).catch(() => {
+    //     ElMessage.error('提交失败');
+    // });
+
 }
 </script>