✨✨个人主页:沫洺的主页
📚📚系列专栏: 📖 JavaWeb专栏📖 JavaSE专栏 📖 Java基础专栏📖vue3专栏
📖MyBatis专栏📖Spring专栏📖SpringMVC专栏📖SpringBoot专栏
💖💖如果文章对你有所帮助请留下三连✨✨
🧀图库效果图
描述:
在图库页面点击图片上传按钮,可通过Nginx服务器将图片保存到本地,并且将图片路径等信息保存到数据库,通过调用后端接口,可将数据库中存放的图片路径展示出来对应的图片
🥞环境搭建
准备工作,上面提到我们需要Nginx代理服务器,先下载Nginx
Nginx下载网址: nginx: download
解压到图片存储路径位置,可自定义(我的路径是D:\Develop\nginx-1.22.0\下,解压)
解压后在html下新建images文件夹(D:\Develop\nginx-1.22.0\nginx-1.22.0\html\images)最后点击nginx.exe运行
找到C:\Windows\System32\drivers\etc文件夹
打开hosts文件(作用是定义IP地址和Host name(主机名)的映射关系)添加一行127.0.0.1 moming.com(修改时可将此文件移到桌面,改好后覆盖源文件即可)
测试在images下放一个图片例如1.jpg
访问http://moming.com/images/1.jpg,访问成功即可创建数据库db5
CREATE TABLE `scm_images` ( `id` int NOT NULL AUTO_INCREMENT COMMENT 'Id', `img` varchar(255) NOT NULL COMMENT '图片路径', `name` varchar(255) NOT NULL COMMENT '图片名称', `createTime` datetime NOT NULL COMMENT '上传时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8mb4;
🌭后端接口搭建
SpringBoot+MyBatis
相关依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.5</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.2.9</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.4</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency>
entity
@Data public class ImagesEntity { private Integer id; private String img;//图片地址 private String name;//图片名字 private LocalDateTime createTime = LocalDateTimeUtil.now(); }
dto
@Data public class ImagesDto { private String imgBase64; private String imgName; private String imgUrl; }
mapper
@Mapper public interface ImagesMapper{ @Select("select * from scm_images order by createTime desc") List<ImagesEntity> select(); }
service
@Service public class ImagesService { @Autowired private ImagesMapper imagesMapper; public Integer add(ImagesDto imagesDto){ String base64 = imagesDto.getImgBase64(); String[] dataArray = StrUtil.splitToArray(base64, "base64,"); byte[] bytes = Base64.decode(dataArray[1]); String imgName = imagesDto.getImgName(); imgName = IdUtil.fastSimpleUUID() +"_"+ imgName; FileUtil.writeBytes(bytes,"D:/Develop/nginx-1.22.0/nginx-1.22.0/html/images/"+imgName); ImagesEntity entity = new ImagesEntity(); entity.setImg("http://moming.com/images/"+imgName); entity.setName(imagesDto.getImgName()); int rowNum = imagesMapper.insert(entity); return rowNum; } public List<ImagesDto> select(){ List<ImagesEntity> entities = imagesMapper.select(); List<ImagesDto> dtos = new ArrayList<>(); for(ImagesEntity entity : entities){ ImagesDto dto = new ImagesDto(); dto.setImgUrl(entity.getImg()); dtos.add(dto); } return dtos; } }
controller
@RestController @RequestMapping("/api/tuku") public class ImagesController { @Autowired private ImagesService imagesService; @PostMapping("/add") public Integer add(@RequestBody ImagesDto imagesDto){ return imagesService.add(imagesDto); } @GetMapping("/select") public List<ImagesDto> select(){ return imagesService.select(); } }
🍕前端页面呈现
vue3-vite+TypeScript+Element Plus
api/tukuApi.ts
import http from "@/http/index" export default { select:{ name:"图库查询", url:"/api/tuku/select", call: async function (params:any = {}) { return await http.get(this.url,params); } }, add:{ name:"图库添加", url:"/api/tuku/add", call: async function (params:any) { return await http.post(this.url,params); } }, }
api/index.ts
import tukuApi from "./tukuApi"; export {tukuApi}
router/index.ts
import { createRouter, createWebHistory } from "vue-router"; const routes = [ { path: '/tuku', name: 'tuku', component: () => import("@/views/tools/Tuku.vue"), meta:{ title:"图库" ,icon:"Coordinate",show:true,useFrame:true} }, ] const router = createRouter({ history: createWebHistory(), routes }) export default router
views/tools/Tuku.vue
<template> <el-upload class="avatar-uploader" :auto-upload="false" :show-file-list="false" :on-change="onChange"> <img v-if="imgData.imgBase64" :src="imgData.imgBase64" class="avatar" /> <el-icon v-else class="avatar-uploader-icon"> <Plus /> </el-icon> </el-upload> <el-divider border-style="dashed" /> <el-row :gutter="20"> <el-col v-for="item in imgList"> <el-image class="demo-image" @click='copy(item.imgUrl)' :src="item.imgUrl" /> </el-col> </el-row> </template> <script setup lang="ts"> import { onMounted, ref, reactive } from 'vue' import {tukuApi} from "@/api/index" import { ElMessage } from 'element-plus' import useClipboard from 'vue-clipboard3' const { toClipboard } = useClipboard() const imgList = ref([]) const imgData = reactive({ imgBase64: '', imgName: "" }) const copy = async (imgUrl: string) => { await toClipboard(imgUrl) ElMessage.success('复制成功') } onMounted(() => { callTukuApi() }) const callTukuApi = () => { tukuApi.select.call().then((res) => { imgList.value = res }) } const onChange = (uploadFile: any, uploadFiles: any) => { var reader = new FileReader(); reader.readAsDataURL(uploadFile.raw); reader.onload = () => { imgData.imgBase64 = reader.result; imgData.imgName = uploadFile.raw.name; tukuApi.add.call({ imgBase64: imgData.imgBase64, imgName: imgData.imgName }).then((res) => { if (res === 1) { ElMessage.success('上传成功') callTukuApi() setTimeout(()=>{ imgData.imgBase64="" },2000) } }) } } </script> <style scoped> .avatar-uploader .avatar { width: 100px; height: 100px; display: block; } .avatar-uploader .el-upload { border: 2px dashed var(--el-color-primary); border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; transition: var(--el-transition-duration-fast); } .avatar-uploader .el-upload:hover { border-color: var(--el-color-primary); } .el-icon.avatar-uploader-icon { font-size: 28px; color: #3f2a67; width: 100px; height: 100px; text-align: center; border: 1px dashed var(--el-color-primary); } .demo-image { border-radius: 0.2rem; width: 100px; height: 100px; cursor: pointer; } .el-col-24 { flex: 0 0 0%; } </style>