三亩地 三亩地SAN MU DI · CODE DIARY
ARTICLE DETAIL

日记详情

真实记录编程学习的某一天,欢迎挑你感兴趣的翻一翻。

【免费】SpringBoot4+Vue3电子相册管理系统 锋哥原创出品,必属精品

【免费】SpringBoot4+Vue3电子相册管理系统 锋哥原创出品,必属精品

大家好,我是Java1234_小锋老师,分享一套锋哥原创的SpringBoot4+Vue3电子相册管理系统。

项目介绍

随着移动互联网与数字影像技术的快速发展,个人与组织积累的电子照片数量持续增长,传统的本地文件夹管理方式已难以满足分类整理、在线分享、互动交流和统一维护等需求。针对上述问题,本文设计并实现了一套基于Spring Boot与Vue3的电子相册管理系统。系统采用前后端分离架构,后端以Spring Boot作为核心框架,结合MyBatis-Plus完成数据持久化,使用JWT实现身份认证与权限控制;前端基于Vue3、Vite、Element Plus与ECharts构建管理端与用户端界面,实现相册创建、照片上传、广场浏览、点赞收藏、评论互动、公告发布及后台数据统计等功能。

在需求分析阶段,本文从可行性、功能性需求和非功能性需求三个维度展开分析,明确了用户端与管理员端的业务边界。系统设计阶段则涵盖了总体架构、功能结构、数据库E-R模型以及关键表结构的设计。在实现阶段,我们围绕认证授权、相册与照片管理、互动模块、评论审核、统计看板等核心功能,详细阐述了实现思路并提供了关键代码示例。最后,通过全面的功能测试验证了系统的可用性。实践结果表明,该系统结构清晰、交互友好、扩展性良好,能够有效满足电子相册日常管理与内容运营的基本需求,对同类Web应用的设计与开发具有一定的参考价值。

源码下载

链接: https://pan.baidu.com/s/1GpCCtiT9Dm6PBC-zMVYvvQ?pwd=1234
提取码: 1234

系统展示

核心代码

package com.java1234.controller; import com.java1234.aspect.OperLog; import com.java1234.common.R; import com.java1234.entity.Photo; import com.java1234.service.impl.UserManageService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; /** * 照片管理控制器 */ @RestController @RequestMapping("/api/photo") public class PhotoController { @Autowired private UserManageService userManageService; /** * 分页查询照片 */ @GetMapping("/page") public R<?> page(@RequestParam(defaultValue = "1") int pageNum, @RequestParam(defaultValue = "12") int pageSize, @RequestParam(required = false) String name, @RequestParam(required = false) Long albumId, @RequestParam(required = false) Long userId) { return R.ok(userManageService.pagePhotos(pageNum, pageSize, name, albumId, userId)); } /** * 新增照片 */ @PostMapping @OperLog("上传照片") public R<Void> add(@RequestBody Photo photo) { userManageService.addPhoto(photo); return R.ok(); } /** * 修改照片 */ @PutMapping public R<Void> update(@RequestBody Photo photo) { userManageService.updatePhoto(photo); return R.ok(); } /** * 删除照片 */ @DeleteMapping("/{id}") @OperLog("删除照片") public R<Void> delete(@PathVariable Long id) { userManageService.deletePhoto(id); return R.ok(); } }
<template> <div class="page-container"> <div class="card-box"> <div class="search-bar"> <el-input v-model="query.name" placeholder="搜索相册名称" clearable style="width:220px" @clear="loadData" /> <el-button type="primary" @click="loadData"><el-icon><Search /></el-icon>搜索</el-button> </div> <el-table :data="tableData" stripe border> <el-table-column prop="id" label="ID" min-width="60" /> <el-table-column label="封面" min-width="80"> <template #default="{ row }"> <el-image :src="row.cover" style="width:50px;height:50px;border-radius:6px" fit="cover" /> </template> </el-table-column> <el-table-column prop="name" label="相册名称" min-width="120" /> <el-table-column prop="username" label="所属用户" min-width="100" /> <el-table-column prop="categoryName" label="分类" min-width="80" /> <el-table-column label="公开" min-width="70"> <template #default="{ row }"> <el-tag :type="row.isPublic === 1 ? 'success' : 'info'" size="small">{{ row.isPublic === 1 ? '公开' : '私密' }}</el-tag> </template> </el-table-column> <el-table-column prop="photoCount" label="照片数" min-width="70" /> <el-table-column prop="viewCount" label="浏览量" min-width="70" /> <el-table-column label="创建时间" min-width="160"> <template #default="{ row }">{{ formatDateTime(row.createTime) }}</template> </el-table-column> <el-table-column label="操作" min-width="100" fixed="right"> <template #default="{ row }"> <el-button type="danger" link @click="handleDelete(row)">删除</el-button> </template> </el-table-column> </el-table> <el-pagination style="margin-top:16px;justify-content:flex-end" v-model:current-page="query.pageNum" v-model:page-size="query.pageSize" :total="total" :page-sizes="[10,20,50]" layout="total,sizes,prev,pager,next" @change="loadData" /> </div> </div> </template> <script setup> import { ref, reactive, onMounted } from 'vue' import { pageAlbum, deleteAlbum, formatDateTime } from '@/api' import { ElMessage, ElMessageBox } from 'element-plus' const tableData = ref([]) const total = ref(0) const query = reactive({ pageNum: 1, pageSize: 10, name: '' }) const loadData = async () => { const res = await pageAlbum(query) tableData.value = res.data.records total.value = res.data.total } const handleDelete = (row) => { if (row.photoCount > 0) { ElMessage.warning('相册内还有照片,请先删除全部照片后再删除相册') return } ElMessageBox.confirm(`确定删除相册「${row.name}」吗?`, '删除确认', { type: 'warning' }).then(async () => { await deleteAlbum(row.id) ElMessage.success('删除成功') loadData() }).catch(() => {}) } onMounted(loadData) </script>
← 返回列表