文章目录

    • Softhub软件下载站实战开发(十二):软件管理编辑页面实现✨
    • 功能概述 📋
    • 编辑页面实现 🛠️
      • 1. 页面结构设计
      • 2. aieEditor集成 🌟
        • 初始化配置
        • 编辑器功能
      • 3. 大整数处理 🔢
      • 4. 封面图片上传 📤
    • 关键代码解析 💻
      • 编辑器保存处理
      • 编辑器初始化配置
    • 样式优化 🎨
    • 效果展示

Softhub软件下载站实战开发(十二):软件管理编辑页面实现✨

前面几篇文章我们已经实现了软件管理主要的接口,本篇文章来实现软件管理的前端部分。

基础代码采用代码生成器生成即可,再次不赘述

功能概述 📋

软件管理模块主要包含以下功能:

软件管理
软件列表
新增软件
编辑软件
删除软件
资源管理
基本信息编辑
详情富文本编辑

编辑页面实现 🛠️

1. 页面结构设计

编辑页面采用全屏弹窗设计,包含两个标签页:

  1. 基本信息:软件名称、分类、平台等基础信息
  2. 软件详情:使用aieEditor实现的富文本编辑器
<template><div class="system-edit-post-container"><el-dialog v-model="isShowDialog" width="1200px" :fullscreen="true" class="edit-dialog"><template #header><div>{{ (formData.id === '0' ? '添加' : '修改') + '软件表' }}</div></template><div class="edit-container"><el-card class="main-card"><el-tabs v-model="activeTab" class="software-tabs" tab-position="top"><el-tab-pane label="基本信息" name="basic"><div class="tab-content"><el-form ref="formRef" :model="formData" :rules="rules" size="default" label-width="100px"><el-row :gutter="24"><el-col :span="12"><el-form-item label="分类" prop="categoryId"><el-cascaderv-model="formData.categoryId":options="categoryOptions"placeholder="请选择分类"size="large"clearable:props="{checkStrictly: true,value: 'id',label: 'categoryName',children: 'children',disabled: 'disabled',emitPath: false}"/></el-form-item></el-col><el-col :span="12"><el-form-item label="平台" prop="platformIds"><el-selectv-model="formData.platformIds"placeholder="请选择平台"size="large"clearablemultiplecollapse-tagscollapse-tags-tooltip:empty-values="[null, undefined, []]"><el-option v-for="item in platformList" :key="item.id" :label="item.platformName" :value="item.id" /></el-select></el-form-item></el-col></el-row><el-row :gutter="24"><el-col :span="12"><el-form-item label="软件名称" prop="softwareName"><el-input v-model="formData.softwareName" placeholder="请输入软件名称" clearable /></el-form-item></el-col><el-col :span="12"><el-form-item label="官网地址" prop="officialWebsite"><el-input v-model="formData.officialWebsite" placeholder="请输入官网地址" clearable /></el-form-item></el-col></el-row><el-row :gutter="24"><el-col :span="12"><el-form-item label="Git仓库" prop="gitRepo"><el-input v-model="formData.gitRepo" placeholder="请输入Git仓库地址" clearable /></el-form-item></el-col><el-col :span="12"><el-form-item label="备注" prop="remark"><el-input v-model="formData.remark" placeholder="请输入备注" clearable /></el-form-item></el-col></el-row><el-row :gutter="24"><el-col :span="24"><el-form-item label="封面" prop="coverId"><div class="cover-upload-container"><el-uploadclass="cover-uploader":action="uploadAction":show-file-list="false":on-success="handleCoverSuccess":before-upload="beforeCoverUpload":headers="{ 'Authorization': `Bearer ${Session.get('token')}` }"><img v-if="coverUrl" :src="coverUrl" class="cover-image" /><div v-else class="cover-upload-placeholder"><el-icon class="cover-uploader-icon"><ele-Plus /></el-icon></div></el-upload><div class="cover-tips"><p>建议尺寸:400x300px,支持 JPG、PNG 格式,文件大小不超过 2MB</p></div></div></el-form-item></el-col></el-row></el-form></div></el-tab-pane><el-tab-pane label="软件描述" name="detail"><div class="tab-content"><div class="editor-section"><div class="editor-header"><h3>软件详情</h3><p class="editor-tips">在这里详细描述软件的功能、特点、使用方法等信息</p></div><div id="aiEditor" ref="divRef" class="editor-container"><div class="aie-container"><div class="aie-container-header"></div><div class="aie-container-main"></div><div class="aie-container-footer"></div></div></div></div></div></el-tab-pane></el-tabs></el-card></div><div class="dialog-footer"><el-button @click="onCancel" size="default">取 消</el-button><el-button type="primary" @click="onSubmit" size="default" :loading="loading">{{ formData.id === '0' ? '新 增' : '修 改' }}</el-button></div></el-dialog></div>
</template>

2.ai配置提取

// 初始化 IndexedDB
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 config = await db.get('aiConfig', 'current')
console.log('读取到的配置:', config)let aiConfig = {}

2. aieEditor集成 🌟

初始化配置

配置ai、图片上传下载以及视频上传下载接口

const initAiEditor = async () => {await nextTick()if (divRef.value && !aiEditor) {const db = await initDB()// 尝试读取配置const config = await db.get('aiConfig', 'current')console.log('读取到的配置:', config)let aiConfig = {}if (config.provide == "custom"){aiConfig =  {models:{openai:{endpoint:  config.apiEndpoint || '',apiKey:  config.apiKey || '',model:  config.model || '',}}}}else{aiConfig =  {models:{openai:{customUrl:  config.customEndpoint || '',apiKey:  config.apiKey || '',model:  config.model || '',}}}}console.log(aiConfig)aiEditor = new AiEditor({element: divRef.value as Element,placeholder: '点击输入内容...',ai: aiConfig,toolbarExcludeKeys: ["attachment","printer"],image: {uploadUrl: import.meta.env.VITE_API_URL + '/api/v1/admin/ds/dsImage/upload',uploadHeaders: {'Authorization': `Bearer ${Session.get('token')}`},uploaderEvent: {onSuccess: (file, response) => {console.log("response@@@@",response)if (response.code === 0) {let res =  {errorCode: 0,data: {src: response.data.url,alt: file.name}}console.log("res@@@",res)return res}return false},onError: (file, error) => {console.error('图片上传失败:', error)ElMessage.error('图片上传失败')return false}},uploadFormName: 'file'},video: {uploadUrl: import.meta.env.VITE_API_URL + '/api/v1/admin/ds/dsVidio/upload',uploadHeaders: {'Authorization': `Bearer ${Session.get('token')}`},uploaderEvent: {onSuccess: (file, response) => {console.log("response@@@@",response)if (response.code === 0) {let res =  {errorCode: 0,data: {src: response.data.url,poster: response.data.poster}}console.log("res@@@",res)return res}return false},onError: (file, error) => {console.error('视频上传失败:', error)ElMessage.error('视频上传失败')return false}},uploadFormName: 'file'}})}
}
编辑器功能
  • AI辅助写作 🤖:集成OpenAI API提供智能写作建议
  • 多媒体支持 🖼️:支持图片、视频上传
  • Markdown兼容 📝:同时支持富文本和Markdown编辑
  • 响应式设计 📱:适配不同屏幕尺寸
aieEditor
文本编辑
图片上传
视频上传
AI辅助
代码高亮
表格支持

3. 大整数处理 🔢

由于JavaScript的Number类型限制,对于大整数ID我们做了特殊处理:

// 大整数转换工具函数
const toBigIntString = (id: number | string): string => {try {return BigInt(id).toString()} catch {return String(id)}
}// 数据处理示例
const processedRow = {...row,id: toBigIntString(row.id),coverId: row.coverId ? toBigIntString(row.coverId) : ''
}

4. 封面图片上传 📤

<el-uploadclass="cover-uploader":action="uploadAction":show-file-list="false":on-success="handleCoverSuccess":before-upload="beforeCoverUpload"><img v-if="coverUrl" :src="coverUrl" class="cover-image" /><div v-else class="cover-upload-placeholder"><el-icon><ele-Plus /></el-icon></div>
</el-upload>

上传限制:

  • 仅支持图片格式
  • 大小不超过2MB
  • 建议尺寸400x300px

关键代码解析 💻

编辑器保存处理

const onSubmit = async () => {const detail = aiEditor?.getHtml() || '';if (!detail) {ElMessage.error('软件详情不能为空');return;}const submitData = {...formData,detail,id: toBigIntString(formData.id),coverId: formData.coverId ? toBigIntString(formData.coverId) : 0};if (formData.id === '0') {await addDsSoftware(submitData);ElMessage.success('添加成功');} else {await editDsSoftware(submitData);ElMessage.success('修改成功');}
}

编辑器初始化配置

从IndexedDB中读取AI配置:

const initDB = async () => {const db = await openDB('softhub', 1, {upgrade(db) {db.createObjectStore('aiConfig', { keyPath: 'id' });}});const config = await db.get('aiConfig', 'current');return {models: {openai: {endpoint: config.apiEndpoint,apiKey: config.apiKey,model: config.model}}};
}

样式优化 🎨

编辑页面采用了全屏弹窗设计,并优化了编辑器的显示区域:

.editor-container {flex: 1;overflow: hidden;min-height: 500px;border: 1px solid var(--el-border-color);border-radius: 6px;:deep(.aie-container-main) {height: calc(100% - 40px);}
}

效果展示

image.png
image.png


softhub系列往期文章

  1. Softhub软件下载站实战开发(一):项目总览
  2. Softhub软件下载站实战开发(二):项目基础框架搭建
  3. Softhub软件下载站实战开发(三):平台管理模块实战
  4. Softhub软件下载站实战开发(四):代码生成器设计与实现
  5. Softhub软件下载站实战开发(五):分类模块实现
  6. Softhub软件下载站实战开发(六):软件配置面板实现
  7. Softhub软件下载站实战开发(七):集成MinIO实现文件存储功能
  8. Softhub软件下载站实战开发(八):编写软件后台管理
  9. Softhub软件下载站实战开发(九):编写软件配置管理界面
  10. Softhub软件下载站实战开发(十):实现图片视频上传下载接口
  11. Softhub软件下载站实战开发(十一):软件分片上传接口实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/87433.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/87433.shtml
英文地址,请注明出处:http://en.pswp.cn/web/87433.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务外联Feign调用:第三方API调用的负载均衡与容灾实战

01Feign 简介 Feign 是 Spring Cloud Netflix 中的 声明式 HTTP 客户端&#xff0c;它如同一位贴心的信使&#xff0c;帮我们化繁为简&#xff0c;让服务间的调用变得轻松又高效。 Feign 的核心优势在于&#xff1a;。 • 声明式调用&#xff1a;开发者只需定义接口和注解&a…

k8s pod调度基础

目录 一&#xff1a;replication controller和replicaset 1&#xff1a;replication controller replication controller的使用示例。 2&#xff1a;标签与标签选择器 &#xff08;1&#xff09;标签 &#xff08;2&#xff09;标签选择器 &#xff08;3&#xff09;标签…

学习者的Python项目灵感

一、实用工具类 - 文件批量重命名工具 用 os 模块实现按规则&#xff08;如添加日期、序号、替换关键词&#xff09;批量重命名文件&#xff0c;适合处理大量图片/文档。 - 简易待办事项管理器&#xff08;To-Do List&#xff09; 用 tkinter 或 PyQt 做GUI界面&#xff0c;…

gRPC服务发现

基于 etcd 实现的服务发现&#xff0c;按照非规范化的 etcd key 实现&#xff0c;详细见代码注释。 package discoveryimport ("context""encoding/json""fmt""go.etcd.io/etcd/api/v3/mvccpb"clientv3 "go.etcd.io/etcd/client/…

基于Linux的Spark本地模式环境搭建实验指南

一、实验目的 掌握Spark本地模式的安装与配置方法验证Spark本地环境是否搭建成功了解Spark基本操作和运行原理 二、实验环境准备 操作系统&#xff1a;Linux&#xff08;推荐ubuntu&#xff09;Java环境&#xff1a;JDK 1.8或以上版本内存&#xff1a;至少4GB&#xff08;推…

数学建模_时间序列

什么是时间序列时间序列预测方法/模型条件&#xff1a;非白噪音平稳平稳性评估不平稳变成平稳然后用ARIMA模型确定p,qAR模型(ARMA特例)MA模型(ARMA特例)ARMA模型(普适)灰色模型神经网络/LSTM组合预测模型向量数据预测结果和为1的情况什么是时间序列 省略具体图形例子 时间序列…

linux用rpm包升级sudo包为sudo-1.9.17-2版本

rpm下载地址&#xff1a; https://www.sudo.ws/dist/packages/1.9.17p1/ 备注&#xff1a;其他压缩包下载地址&#xff1a;https://www.sudo.ws/download.html sudo-1.9.17-2.el7.x86_64.rpm 检查一下&#xff0c;本地sudo版本&#xff0c;执行&#xff1a;sudo -V 或者sudo -…

【开源项目】一款真正可修改视频MD5工具视频质量不损失

文章目录 视频MD5修改工具 🎬📋 目录✨ 功能特点💻 系统要求🏗️ 设计架构🔬 技术原理💻 核心代码1. 视频MD5修改核心逻辑2. 前端异步处理代码3. 错误处理与日志记录📥 安装方法方法一:直接下载方法二:使用本地服务器📚 使用教程基本使用步骤高级使用技巧📁…

Day05: Python 中的并发和并行(1)

理解 Python 中的线程和进程 理解线程和进程是实现在 Python 中并发和并行的基础。这种知识使你能够编写能够看似同时执行多个任务的程序&#xff0c;从而提高性能和响应能力。本课程将深入探讨线程和进程的核心概念、它们的区别&#xff0c;以及它们如何为更高级的并发技术奠…

Spring Boot 集成 MinIO 实现分布式文件存储与管理

Spring Boot 集成 MinIO 实现分布式文件存储与管理 一、MinIO 简介 MinIO 是一个高性能的分布式对象存储服务器&#xff0c;兼容 Amazon S3 API。它具有以下特点&#xff1a; 轻量级且易于部署高性能&#xff08;读写速度可达每秒数GB&#xff09;支持数据加密和访问控制提供…

从小白入门,基于Cursor开发一个前端小程序之Cursor 编程实践与案例分析

Cursor 编程实践与案例分析 Cursor 编程实践与案例分析 1. 什么是 Cursor&#xff1f; Cursor 是一款面向开发者的 AI 编程助手&#xff0c;集成于本地 IDE&#xff0c;支持自然语言与代码的无缝协作。它不仅能自动补全、重构、查找代码&#xff0c;还能理解业务上下文&#…

一、如何用MATLAB画一个三角形 代码

一、如何用MATLAB画一个三角形 代码在MATLAB中绘制三角形可以通过指定三个顶点的坐标并使用 fill 或 patch 函数实现。以下是详细代码示例&#xff1a;方法1&#xff1a;使用 fill 函数&#xff08;简单填充&#xff09;% 定义三角形的三个顶点坐标 (x, y) x [0, 1, 0.5]; % …

Postman自动化测试提取相应body体中的参数

文章目录Postman自动化测试提取相应body体中的参数1. 示例响应 Body 参数2. 提取响应 Body 参数Postman自动化测试提取相应body体中的参数 上一篇的文中介绍了使用postman自动化测试时从响应的header中提取token参数&#xff0c;很多同学私信问如何从响应体body中提取参数。 有…

vue-39(为复杂 Vue 组件编写单元测试)

实际练习:为复杂 Vue 组件编写单元测试 单元测试对于确保复杂 Vue 组件的可靠性和可维护性至关重要。通过隔离和测试代码的各个单元,您可以在开发过程的早期发现并修复错误,从而构建更健壮和可预测的应用程序。本课程重点介绍为复杂 Vue 组件编写单元测试的实用方面,建立在…

c语言中的函数IV

函数的先后关系 直接把函数放在程序上方是可以的 在实际开发中&#xff0c;我们更希望把main函数放在前面 这样子直接把自己定义的函数放在main函数下方&#xff0c;编译会出现warning和error正确的解决方案是&#xff1a;把函数的头放到main函数上方&#xff0c;这样就能正常…

大模型Decoder-Only深入解析

Decoder-Only整体结构 我们以模型Llama-3.1-8B-Instruct为例&#xff0c;打印其结构如下&#xff08;后面会慢慢解析每一部分&#xff0c;莫慌&#xff09;&#xff1a; LlamaForCausalLM((model): LlamaModel((embed_tokens): VocabParallelEmbedding(num_embeddings128256,…

web网页,在线%电商,茶叶,商城,网上商城系统%分析系统demo,于vscode,vue,java,jdk,springboot,mysql数据库

经验心得 这也是帮之前一客户加了几个功能&#xff0c;需要掌握crud&#xff0c;前后端开发&#xff0c;前后端怎么对接&#xff0c;前后端通讯是以那种格式&#xff0c;把这些掌握后咱们就可以进行网站开发了。后端记好一定要分层开发&#xff0c;不要像老早一起所有代码写到一…

MybatisPlus-05.核心功能-条件构造器

一.条件构造器 我们前面使用的MP功能主要是根据id进行操作的&#xff0c;并未涉及到复杂查询。而根据id所进行的增删改查操作在MP中都有直接的封装。但是遇到复杂的查询条件时&#xff0c;如何使用MP进行操作是我们要考虑的问题。因此MP为我们提供了条件构造器。 在BaseMapper…

ES6从入门到精通:常用知识点

变量声明ES6引入了let和const替代var。let用于声明可变的块级作用域变量&#xff0c;const用于声明不可变的常量。块级作用域有效避免了变量提升和污染全局的问题。let name Alice; const PI 3.1415;箭头函数箭头函数简化了函数写法&#xff0c;且自动绑定当前上下文的this值…

51单片机教程(十一)- 单片机定时器

11、单片机定时器 项目目标 通过定时器/计数器实现流水灯控制。知识要点 定时器的结构。TMOD和TCON;定时/计数器工作方式;定时/计数器编程步骤;1、项目分析 前面的流水灯的时间控制通过空循环语句来实现,定时不是很精确。本章通过用定时器来控制流水灯任务可以实现精确的时…