做外贸soho 需要有网站吗,数码网站建设图片,织梦网站备份几种方法,gofair做网站文章目录 fullText富文本1. 后端接口1.1 定义常量1.2 定义返回实体类1.3 上传图片接口1.4 下载图片接口 2. 前端代码编写2.1 安装2.2 快速使用 3. 配置富文本图片上传地址3.1 配置图片上传配置 4. 全部代码展示 前言#xff1a;最近写项目#xff0c;发现了一些很有意思的功能… 文章目录 fullText富文本1. 后端接口1.1 定义常量1.2 定义返回实体类1.3 上传图片接口1.4 下载图片接口 2. 前端代码编写2.1 安装2.2 快速使用 3. 配置富文本图片上传地址3.1 配置图片上传配置 4. 全部代码展示 前言最近写项目发现了一些很有意思的功能想写文章录视频把这些内容记录下。但这些功能太零碎如果为每个功能都单独搭建一个项目这明显不合适。于是我想就搭建一个项目把那些我想将的小功能全部整合到一起。实现
搭一次环境处处使用。 本文主要实现一下两个功能
富文本图片上传下载
环境搭建 文章链接
已录制视频 视频链接
fullText富文本
使用wangEditor(vue3) springboot实现富文本功能
效果图
1. 后端接口
图片存储的逻辑
接收前端传递图片数据将图片下载到后端本地返回图片访问URL
图片下载的逻辑
提供下载文件的名字在后端服务器根据文件名寻找文件所在位置将文件以流数据形式导出并通过HttpServletResponse返回 tip: 图片访问URL本质上是访问下载文件接口URL 1.1 定义常量
/**
* 文件访问域名(请求下载的接口)
* DOMAIN本质是访问图片下载接口
*/
private static final String DOMAIN http://localhost:9005/api_demo/fullText/file/download/;/**
* 文件物理存储位置
*/
private static final String STORE_DIR E:\\B站视频创作\\前后端项目构建-小功能实现\\代码\\backend\\src\\main\\resources\\pict\\;
1.2 定义返回实体类 static class Success {public final int errno;public final Object data;public Success(String url) {this.errno 0;HashMapString, String map new HashMap();map.put(url, url);this.data map;}}tip: 后端接口返回的图片需要按照一定的格式返回具体可以参考文档[图片上传](菜单配置 | wangEditor) 上传成功 {errno: 0, // 注意值是数字不能是字符串data: {url: xxx, // 图片 src 必须alt: yyy, // 图片描述文字非必须href: zzz // 图片的链接非必须}
}上传失败 {errno: 1, // 只要不等于 0 就行message: 失败信息
}1.3 上传图片接口 /*** 获取后缀*/public static String getFileSuffix(String fileName) {// 检查文件名是否为null或空if (fileName null || fileName.isEmpty()) {return ;}// 查找最后一个点.的位置int dotIndex fileName.lastIndexOf(.);// 检查是否找到点且不是在字符串开头if (dotIndex 0) {// 从点开始截取直到字符串末尾return fileName.substring(dotIndex);}// 如果没有找到点或点在字符串开头则返回空字符串return ;}/*** 上传文件接口* param file* return* throws IOException*/RequestMapping(/file/upload)public Object uploadPict(RequestParam(image) MultipartFile file) throws IOException {// 获取文件流InputStream is file.getInputStream();// 获取文件真实名字String fileName UUID.randomUUID().toString().substring(0, 10) getFileSuffix(file.getOriginalFilename());// 在服务器中存储文件FileUtils.copyInputStreamToFile(is, new File(STORE_DIR fileName));// 返回图片urlString url DOMAIN fileName;return new Success(url);}1.4 下载图片接口 /*** 文件下载接口* param fileName 文件名* param request* param response*/GetMapping(/file/download/{fileName})public void download(PathVariable(fileName) String fileName, HttpServletRequest request, HttpServletResponse response) {// 获取真实的文件路径String filePath STORE_DIR fileName;System.out.println(完整路径为filePath);try {// 下载文件// 设置响应头response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);response.setHeader(HttpHeaders.CONTENT_DISPOSITION, attachment; filename fileName);// 读取文件内容并写入输出流Files.copy(Paths.get(filePath), response.getOutputStream());response.getOutputStream().flush();} catch (IOException e) {response.setStatus(404);}}2. 前端代码编写
2.1 安装
pnpm install wangeditor/editor --savepnpm install wangeditor/editor-for-vuenext --save2.2 快速使用
模板
templatediv styleborder: 1px solid #cccToolbarstyleborder-bottom: 1px solid #ccc:editoreditorRef:modemode/Editorstyleheight: 500px; overflow-y: hiddenv-modelvalueHtml:defaultConfigeditorConfig:modemodeonCreatedhandleCreated//div
/templatescript
使用setup语法糖
script setup langts
import wangeditor/editor/dist/css/style.css;
import { Editor, Toolbar } from wangeditor/editor-for-vue;
import { IEditorConfig } from wangeditor/editor;
import { shallowRef, ref } from vue;// 初始化 MENU_CONF 属性
const editorConfig: PartialIEditorConfig {MENU_CONF: {}
};
const mode default;// 编辑器实例必须用 shallowRef重要
const editorRef shallowRef();const handleCreated editor {console.log(created, editor);editorRef.value editor; // 记录 editor 实例重要
};// 绑定数据
const valueHtml ref();// 组件销毁时也及时销毁编辑器重要
onBeforeUnmount(() {const editor editorRef.value;if (editor null) return;editor.destroy();
});
/script3. 配置富文本图片上传地址
3.1 配置图片上传配置
script
// 配置上传地址
editorConfig.MENU_CONF[uploadImage] {// form-data fieldName 默认值 wangeditor-uploaded-imagefieldName: image,server: baseUrlApi(fullText/file/upload),// 小于该值就插入 base64 格式而不上传默认为 0base64LimitSize: 5 * 1024 // 5kb
};
/scripttip: fieldName对应的是后端的文件上传接口RequestParam(“xxx”) MultipartFile中xxx的内容 4. 全部代码展示 前端 script setup langts
import wangeditor/editor/dist/css/style.css;
import { Editor, Toolbar } from wangeditor/editor-for-vue;
import { IEditorConfig } from wangeditor/editor;
import { shallowRef, ref, onBeforeUnmount } from vue;
import { baseUrlApi } from /api/utils;// 初始化 MENU_CONF 属性
const editorConfig: PartialIEditorConfig {MENU_CONF: {}
};
const mode default;// 编辑器实例必须用 shallowRef重要
const editorRef shallowRef();const handleCreated editor {console.log(created, editor);editorRef.value editor; // 记录 editor 实例重要
};// 绑定数据
const valueHtml ref();// 组件销毁时也及时销毁编辑器重要
onBeforeUnmount(() {const editor editorRef.value;if (editor null) return;editor.destroy();
});// 配置上传地址
editorConfig.MENU_CONF[uploadImage] {// form-data fieldName 默认值 wangeditor-uploaded-imagefieldName: image,server: baseUrlApi(fullText/file/upload),// 小于该值就插入 base64 格式而不上传默认为 0base64LimitSize: 5 * 1024 // 5kb
};const handleChange editor {// TS 语法console.log(content, editor.getHtml());
};
/scripttemplatediv styleborder: 1px solid #ccc; margin-top: 10pxToolbarstyleborder-bottom: 1px solid #ccc:editoreditorRef:modemode/Editorstyleheight: 500px; overflow-y: hiddenv-modelvalueHtml:defaultConfigeditorConfig:modemodeonCreatedhandleCreatedonChangehandleChange//div
/templatestyle langscss scoped/style后端 RequestMapping(/fullText)
RestController
public class FullTextController {/*** 文件访问域名(请求下载的接口)*/private static final String DOMAIN http://localhost:9005/api_demo/fullText/file/download/;/*** 文件物理存储位置*/private static final String STORE_DIR E:\\B站视频创作\\前后端项目构建-小功能实现\\代码\\backend\\src\\main\\resources\\pict\\;static class Success {public final int errno;public final Object data;public Success(String url) {this.errno 0;HashMapString, String map new HashMap();map.put(url, url);this.data map;}}/*** 获取后缀*/public static String getFileSuffix(String fileName) {// 检查文件名是否为null或空if (fileName null || fileName.isEmpty()) {return ;}// 查找最后一个点.的位置int dotIndex fileName.lastIndexOf(.);// 检查是否找到点且不是在字符串开头if (dotIndex 0) {// 从点开始截取直到字符串末尾return fileName.substring(dotIndex);}// 如果没有找到点或点在字符串开头则返回空字符串return ;}/*** 上传文件接口* param file* return* throws IOException*/RequestMapping(/file/upload)public Object uploadPict(RequestParam(image) MultipartFile file) throws IOException {// 获取文件流InputStream is file.getInputStream();// 获取文件真实名字String fileName UUID.randomUUID().toString().substring(0, 10) getFileSuffix(file.getOriginalFilename());// 在服务器中存储文件FileUtils.copyInputStreamToFile(is, new File(STORE_DIR fileName));// 返回图片urlString url DOMAIN fileName;return new Success(url);}/*** 文件下载接口* param fileName 文件名* param request* param response*/GetMapping(/file/download/{fileName})public void download(PathVariable(fileName) String fileName, HttpServletRequest request, HttpServletResponse response) {// 获取真实的文件路径String filePath STORE_DIR fileName;System.out.println(完整路径为filePath);try {// 下载文件// 设置响应头response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);response.setHeader(HttpHeaders.CONTENT_DISPOSITION, attachment; filename fileName);// 读取文件内容并写入输出流Files.copy(Paths.get(filePath), response.getOutputStream());response.getOutputStream().flush();} catch (IOException e) {response.setStatus(404);}}
}