跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Java大前端java

基于 SpringBoot+Vue 的网上摄影工作室管理系统设计与实现

基于 SpringBoot 和 Vue 的前后端分离架构实现了摄影工作室管理系统。系统包含用户管理、作品展示、预约订单等功能模块,利用 MySQL 和 MyBatis 完成数据存储与持久化。通过角色权限控制保障数据安全,优化了摄影师与用户的交互流程,为摄影服务的数字化转型提供了完整的技术方案。

人间失格发布于 2026/3/24更新于 2026/9/1062 浏览
基于 SpringBoot+Vue 的网上摄影工作室管理系统设计与实现

项目背景

随着互联网技术的普及,摄影行业正从传统线下模式向线上平台转型。现有的摄影服务平台往往功能单一,缺乏个性化的服务与管理工具。为了解决这一问题,我们设计并实现了一套基于前后端分离架构的网上摄影工作室管理系统。该系统旨在整合摄影资源,优化服务流程,提升用户体验,同时为摄影师和用户搭建高效的沟通桥梁。

系统采用 Vue.js 构建前端交互界面,SpringBoot 搭建后端服务层,MySQL 存储数据,并通过 MyBatis 实现持久化操作。主要功能涵盖用户管理、摄影作品展示、在线预约、订单管理及评论互动等模块,支持多角色权限控制以确保数据安全。

技术架构

后端:Spring Boot

作为现代 Java 企业级开发的核心框架,Spring Boot 通过'约定优于配置'的设计哲学简化了应用开发。其核心特性包括零配置启动、嵌入式服务器(Tomcat/Jetty/Undertow)以及生产就绪的 Actuator 监控组件。Starter 依赖体系让开发者能聚焦于业务逻辑,而无需过多关注底层基础设施。

前端:Vue.js

Vue.js 以其渐进式设计和响应式数据流成为前端开发的首选。单文件组件(SFC)实现了样式、逻辑与模板的完美封装,配合 Vue Router 和 Pinia 等官方工具链,能够高效构建复杂的 SPA 解决方案。TypeScript 支持和开发者工具则为大型项目的维护提供了可靠保障。

数据库设计

用户信息表 (user_info)

用于存储注册用户的基本信息,包括角色、登录凭证和个人资料。用户 ID 为主键,注册时间由系统自动获取。

字段名数据类型是否为空描述
user_idBIGINT否用户唯一标识(主键)
user_nameVARCHAR(50)否用户昵称
user_emailVARCHAR(100)否用户邮箱(登录账号)
user_passwordVARCHAR(100)否用户密码(加密存储)
user_avatarVARCHAR(255)是用户头像 URL
user_roleTINYINT否用户角色(0-普通用户,1-摄影师,2-管理员)
create_timeDATETIME否用户注册时间
update_timeDATETIME否最后更新时间

摄影作品表 (photo_work)

存储摄影师上传的作品信息,包含标题、描述、分类及图片 URL。摄影师 ID 作为外键关联用户表。

字段名数据类型是否为空描述
work_idBIGINT否作品唯一标识(主键)
photographer_idBIGINT否摄影师 ID(外键)
work_titleVARCHAR(100)否作品标题
work_descTEXT是作品描述
work_categoryVARCHAR(50)否作品分类(如人像、风景)
work_imageVARCHAR(255)否作品图片 URL
create_timeDATETIME否作品上传时间
update_timeDATETIME否最后更新时间

预约订单表 (reserve_order)

记录用户预约摄影服务的订单详情,包括预约时间、服务类型和状态。用户 ID 和摄影师 ID 均为外键。

字段名数据类型是否为空描述
order_idBIGINT否订单唯一标识(主键)
user_idBIGINT否用户 ID(外键)
photographer_idBIGINT否摄影师 ID(外键)
service_typeVARCHAR(50)否服务类型(如婚纱摄影、商业拍摄)
reserve_timeDATETIME否预约拍摄时间
order_statusTINYINT否订单状态(0-待确认,1-已确认,2-已完成,3-已取消)
create_timeDATETIME否订单创建时间
update_timeDATETIME否最后更新时间

核心逻辑实现

在用户认证环节,我们需要处理登录、注册及 Token 生成。下面以 UsersController 为例,看看如何安全地处理这些请求。

package com.controller;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.annotation.IgnoreAuth;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.entity.TokenEntity;
import com.entity.UsersEntity;
import com.service.TokenService;
import com.service.UsersService;
import com.utils.CommonUtil;
import com.utils.MPUtil;
import com.utils.PageUtils;
import com.utils.R;
import com.utils.ValidatorUtils;

/**
 * 登录相关
 */
@RequestMapping("users")
@RestController
public class UsersController{
    @Autowired
    private UsersService userService;
    @Autowired
    private TokenService tokenService;

    /**
     * 登录
     */
    @IgnoreAuth
    @PostMapping(value = "/login")
    public R login(String username, String password, String captcha, HttpServletRequest request) {
        UsersEntity user = userService.selectOne(new EntityWrapper<UsersEntity>().eq("username", username));
        if(user==null || !user.getPassword().equals(password)) {
            return R.error("账号或密码不正确");
        }
        String token = tokenService.generateToken(user.getId(),username, "users", user.getRole());
        return R.ok().put("token", token);
    }

    /**
     * 注册
     */
    @IgnoreAuth
    @PostMapping(value = "/register")
    public R register(@RequestBody UsersEntity user){
        // ValidatorUtils.validateEntity(user);
        if(userService.selectOne(new EntityWrapper<UsersEntity>().eq("username", user.getUsername())) !=null) {
            return R.error("用户已存在");
        }
        userService.insert(user);
        return R.ok();
    }

    /**
     * 退出
     */
    @GetMapping(value = "logout")
    public R logout(HttpServletRequest request) {
        request.getSession().invalidate();
        return R.ok("退出成功");
    }

    /**
     * 密码重置
     */
    @IgnoreAuth
    @RequestMapping(value = "/resetPass")
    public R resetPass(String username, HttpServletRequest request){
        UsersEntity user = userService.selectOne(new EntityWrapper<UsersEntity>().eq("username", username));
        if(user==null) {
            return R.error("账号不存在");
        }
        user.setPassword("123456");
        userService.update(user,null);
        return R.ok("密码已重置为:123456");
    }

    /**
     * 列表
     */
    @RequestMapping("/page")
    public R page(@RequestParam Map<String, Object> params,UsersEntity user){
        EntityWrapper<UsersEntity> ew = new EntityWrapper<UsersEntity>();
        PageUtils page = userService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.allLike(ew, user), params), params));
        return R.ok().put("data", page);
    }

    /**
     * 列表
     */
    @RequestMapping("/list")
    public R list( UsersEntity user){
        EntityWrapper<UsersEntity> ew = new EntityWrapper<UsersEntity>();
        ew.allEq(MPUtil.allEQMapPre( user, "user"));
        return R.ok().put("data", userService.selectListView(ew));
    }

    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    public R info(@PathVariable("id") String id){
        UsersEntity user = userService.selectById(id);
        return R.ok().put("data", user);
    }

    /**
     * 获取用户的 session 用户信息
     */
    @RequestMapping("/session")
    public R getCurrUser(HttpServletRequest request){
        Long id = (Long)request.getSession().getAttribute("userId");
        UsersEntity user = userService.selectById(id);
        return R.ok().put("data", user);
    }

    /**
     * 保存
     */
    @PostMapping("/save")
    public R save(@RequestBody UsersEntity user){
        // ValidatorUtils.validateEntity(user);
        if(userService.selectOne(new EntityWrapper<UsersEntity>().eq("username", user.getUsername())) !=null) {
            return R.error("用户已存在");
        }
        userService.insert(user);
        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    public R update(@RequestBody UsersEntity user){
        // ValidatorUtils.validateEntity(user);
        UsersEntity u = userService.selectOne(new EntityWrapper<UsersEntity>().eq("username", user.getUsername()));
        if(u!=null && u.getId()!=user.getId() && u.getUsername().equals(user.getUsername())) {
            return R.error("用户名已存在。");
        }
        userService.updateById(user);//全部更新
        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    public R delete(@RequestBody Long[] ids){
        userService.deleteBatchIds(Arrays.asList(ids));
        return R.ok();
    }
}

在实际运行中,登录接口会先校验用户名是否存在,再比对密码。验证通过后,系统会生成一个 Token 返回给前端,后续请求需携带此 Token 进行身份鉴权。注册接口则需检查用户名是否重复,避免冲突。此外,密码重置功能仅用于测试环境,生产环境中应结合邮件或短信验证码机制。

总结

本系统通过前后端分离架构,实现了摄影工作室管理的数字化与规范化。数据库设计兼顾了扩展性与查询效率,代码结构清晰便于维护。对于希望涉足该领域的开发者而言,这套方案提供了一个可参考的完整实践路径。

目录

  1. 项目背景
  2. 技术架构
  3. 后端:Spring Boot
  4. 前端:Vue.js
  5. 数据库设计
  6. 用户信息表 (user_info)
  7. 摄影作品表 (photo_work)
  8. 预约订单表 (reserve_order)
  9. 核心逻辑实现
  10. 总结

更多推荐文章

查看全部
  • 前端地图开发基础:服务类型、坐标系与 SDK 简介
  • 前端函数防抖详解:原理、手写与 Lodash 实战
  • DeepSeek-R1 大模型基于 MS-Swift 框架部署推理微调指南
  • Llama.cpp 跨平台部署本地大模型实战指南
  • C语言标准库与工具链:string.h、stdio.h、stdlib.h及CMake构建
  • Fooocus 部署实践:本地手动配置与云端一键启用对比
  • 如何成为卓越的 AIGC 产品经理:从传统产品到 AI 领域的转型指南
  • Python 基础语法详解
  • Python 基础语法详解:变量、类型、运算符与输入输出
  • 大模型应用开发:RAG 入门与实战
  • 31 岁转行软件测试:一位 34 岁从业者的经历与感悟
  • Trae CN IDE Python 开发流程与配置指南
  • LLM 指令微调:数据质量与多样性对对齐效果的影响
  • 二分算法实战:A-B 数对与高考志愿录取匹配
  • PAT 1041 考试座位号 Python 解法
  • Arcade-plus 专业谱面制作从入门到精通指南
  • AI 前沿动态:自进化代理、云端开发环境与多模态模型更新
  • AI 绘画的商业应用:广告、插画与游戏设计
  • faster-whisper 快速安装与使用指南
  • OpenAI o1 模型解析:推理能力突破与人类水平对比

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online