当前位置: 首页 > news >正文

Softhub软件下载站实战开发(六):软件配置面板实现

Softhub软件下载站实战开发(六):软件配置面板实现

在上一篇文章中,我们实现了分类模块。本文实现配置面板功能,并聚焦ai配置信息存储,并为后续配置信息拓展留足空间。

设计思路与核心功能

AI配置面板需要满足以下需求:

  • 多提供商支持:支持OpenAI、DeepSeek、Ollama及自定义API
  • 动态表单:根据不同提供商显示不同配置项
  • 模型管理:自动获取可用模型列表
  • 参数配置:温度、最大Token数等关键参数
  • 本地存储:使用IndexedDB保存配置

实现详解

1. 多提供商支持与动态表单

<el-form-item label="AI 提供商" prop="provider"><el-select v-model="aiConfig.provider" placeholder="请选择 AI 提供商" @change="handleProviderChange"><el-option label="OpenAI" value="openai" /><el-option label="DeepSeek" value="deepseek" /><el-option label="Ollama" value="ollama" /><el-option label="自定义" value="custom" /></el-select>
</el-form-item>

根据选择的提供商动态显示/隐藏相关字段:

<el-form-item label="API Key" prop="apiKey" v-if="aiConfig.provider !== 'ollama'"><!-- API Key输入框 -->
</el-form-item><el-form-item label="API 地址" prop="apiEndpoint" v-if="aiConfig.provider !== 'custom'"><!-- API地址输入框 -->
</el-form-item><el-form-item label="自定义地址" prop="customEndpoint" v-if="aiConfig.provider === 'custom'"><!-- 自定义地址输入框 -->
</el-form-item>

2. 模型管理

为不同提供商设置默认模型列表:

const defaultModels = {openai: ['gpt-4', 'gpt-3.5-turbo'],deepseek: ['deepseek-chat', 'deepseek-reasoner'],ollama: []
};

对于Ollama提供商,动态获取本地模型列表:

const fetchOllamaModels = async () => {loadingModels.value = true;try {const response = await fetch('http://localhost:11434/api/tags');const data = await response.json();availableModels.value = data.models.map(model => model.name);} catch (error) {ElMessage.error('获取 Ollama 模型列表失败');availableModels.value = [];} finally {loadingModels.value = false;}
};

3. 参数配置

温度参数使用滑块控制:

<el-form-item label="温度" prop="temperature"><el-sliderv-model="aiConfig.temperature":min="0":max="1":step="0.1"show-input/>
</el-form-item>

最大Token数使用步进器控制:

<el-form-item label="最大长度" prop="maxTokens"><el-input-numberv-model="aiConfig.maxTokens":min="100":max="4000":step="100"/>
</el-form-item>

4. 数据持久化

使用IndexedDB存储配置:

需要安装idb库

npm install idb
const initDB = async () => {try {const db = await openDB('softhub', 1, {upgrade(db) {const store = db.createObjectStore('aiConfig', { keyPath: 'id' });store.createIndex('current', 'id', { unique: true });}});return db;} catch (error) {console.error('初始化数据库失败:', error);throw error;}
};const loadConfig = async () => {try {const db = await initDB();const config = await db.get('aiConfig', 'current');if (config) {Object.assign(aiConfig, config);if (aiConfig.provider === 'ollama') {await fetchOllamaModels();} else if (aiConfig.provider) {availableModels.value = defaultModels[aiConfig.provider];}}} catch (error) {console.error('加载配置失败:', error);}
};const handleSave = async () => {try {await aiFormRef.value.validate();saving.value = true;const db = await initDB();const configToSave = {id: 'current',...aiConfig,apiEndpoint: aiConfig.provider === 'custom' ? aiConfig.customEndpoint : aiConfig.apiEndpoint};await db.put('aiConfig', configToSave);ElMessage.success('配置保存成功');} catch (error) {ElMessage.error('配置保存失败');} finally {saving.value = false;}
};

布局与UI设计

1. 主页面布局

<template><div class="config-container"><el-tabs v-model="activeTab" tab-position="left" class="config-tabs"><el-tab-pane name="ai"><template #label><el-icon><Connection /></el-icon><span>AI 配置</span></template><ai-config ref="aiConfigRef" /></el-tab-pane></el-tabs></div>
</template>

2. 表单样式优化

.config-content {max-width: 800px;
}.config-form {margin-top: 20px;
}:deep(.el-form-item__label) {font-weight: 500;
}:deep(.el-button) {padding: 8px 20px;
}:deep(.el-button .el-icon) {margin-right: 4px;
}

3. 标签页样式

.config-container {padding: 20px;height: calc(100vh - 40px);background-color: #f5f7fa;
}.config-tabs {background-color: #fff;border-radius: 4px;box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.05);
}:deep(.el-tabs__header) {margin: 0;border-right: 1px solid #e4e7ed;background-color: #f5f7fa;
}:deep(.el-tabs__nav-wrap) {width: 180px;
}:deep(.el-tabs__item) {height: 50px;line-height: 50px;padding: 0 20px;font-size: 14px;color: #606266;display: flex;align-items: center;gap: 8px;transition: all 0.3s ease;
}:deep(.el-tabs__item.is-active) {background-color: #fff;color: #409eff;font-weight: 500;
}

页面效果

image.png

技术总结

  1. 动态表单渲染:根据选择的AI提供商动态显示/隐藏相关配置项
  2. 混合模型管理:结合预设模型列表和动态API获取
  3. 响应式数据绑定:使用Vue的响应式系统管理复杂表单状态
  4. 本地存储方案:IndexedDB提供可靠的客户端数据持久化
  5. 优雅的错误处理:对网络请求和数据库操作进行完善的错误处理
  6. 用户友好的UI:Element Plus组件提供一致且美观的用户体验

softhub系列往期文章

  1. Softhub软件下载站实战开发(一):项目总览
  2. Softhub软件下载站实战开发(二):项目基础框架搭建
  3. Softhub软件下载站实战开发(三):平台管理模块实战
  4. Softhub软件下载站实战开发(四):代码生成器设计与实现
  5. Softhub软件下载站实战开发(五):分类模块实现
http://www.lqws.cn/news/466111.html

相关文章:

  • LeetCode 1432.改变一个整数能得到的最大差值:暴力模拟/贪心
  • 企业公用电脑登录安全管控的终极方案:ASP操作系统安全登录管控方案
  • c++ 虚继承
  • 【软考高级系统架构论文】论云上自动化运维及其应用
  • 嵌入式开发之嵌入式系统架构如何搭建?
  • Spring与SLF4J/Logback日志框架深度解析:从源码看日志系统设计
  • elasticsearch安装ik分词器
  • 3.1 Android NDK交叉编译FFmpeg
  • 领域驱动设计(DDD)【3】之事件风暴
  • React 重识
  • Seata模式
  • Spring AOP全面详讲
  • 从 Elasticsearch 集群中移除一个节点
  • `customRef` 在实战中的使用:防抖、计算属性缓存和异步数据获取
  • 腾讯云IM即时通讯:开启实时通信新时代
  • nuxt3 + vue3 分片上传组件全解析(支持大文件+断点续传)
  • RabbitMQ 的工作流程
  • 【unitrix】 3.6 类型级数转基础类型(from.rs)
  • springboot通过独立事务管理器实现资源隔离与精准控制​
  • HTTPS的加密方式介绍
  • MinIO社区版文件预览失效?一招解决
  • 【Fargo】mediasoup发送2:码率分配、传输基类设计及WebRtcTransport原理
  • React 组件通信
  • C++ 移动构造:提升性能的利器
  • docker执行yum报错Could not resolve host: mirrorlist.centos.org
  • Snapchat矩阵运营新策略:亚矩阵云手机打造高效社交网络
  • C++:动态链接库的编写,__declspec 用法详解
  • 7.3.2_2平衡二叉树的删除
  • 【RTP】基于mediasoup的RtpPacket的H.264打包、解包和demo 1:不含扩展
  • windows下docker虚拟文件大C盘迁移D盘