
1. 项目概述网上摄影工作室系统开发全流程这个基于SpringBootVueMyBatisMySQL的网上摄影工作室系统是我去年为一个本地摄影团队开发的实际项目。整套系统从需求分析到最终部署上线历时3个月目前稳定运行已超过半年日均UV达到2000。系统采用经典的前后端分离架构后端提供RESTful API接口前端通过Vue.js实现动态交互完美解决了传统摄影工作室线下预约效率低、作品展示形式单一等痛点。核心功能模块包括摄影师作品展示与管理在线预约与档期管理客户评价系统订单支付与状态跟踪后台数据统计分析技术选型心得选择SpringBootVue这套技术栈时主要考虑团队技术储备和社区生态。实际开发证明这套组合在开发效率、性能表现和可维护性方面都达到了很好的平衡。2. 技术架构深度解析2.1 后端技术栈实现方案SpringBoot 2.7.18作为后端框架采用多模块Maven项目结构photostudio-backend ├── photostudio-common // 公共模块 ├── photostudio-system // 系统核心 ├── photostudio-admin // 管理后台API └── photostudio-api // 客户端APIMyBatis-Plus 3.5.3作为ORM框架配置了动态数据源以支持主从分离。特别值得分享的是分页插件配置Configuration public class MyBatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); // 分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 乐观锁插件 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } }数据库设计采用MySQL 8.0主要表结构包括photographer摄影师信息表portfolio作品集表appointment预约表order_info订单表user用户表踩坑记录初期没有为portfolio表的image_url字段设置合适长度导致长链接被截断。建议VARCHAR至少设置512长度。2.2 前端工程化实践Vue 3.2 Vite构建的前端项目采用以下核心配置路由管理vue-router 4.x状态管理Pinia替代VuexUI框架Element PlusHTTP客户端axios封装项目目录结构示例src/ ├── api/ // 接口定义 ├── assets/ // 静态资源 ├── components/ // 公共组件 ├── router/ // 路由配置 ├── stores/ // Pinia状态 ├── utils/ // 工具类 └── views/ // 页面组件关键优化点使用动态导入实现路由懒加载封装统一的请求拦截器处理Token验证采用Composition API组织代码逻辑3. 核心功能实现细节3.1 摄影师作品展示模块后端接口设计遵循RESTful规范RestController RequestMapping(/api/portfolio) public class PortfolioController { Autowired private PortfolioService portfolioService; GetMapping(/{photographerId}) public Result listByPhotographer(PathVariable Long photographerId) { ListPortfolio list portfolioService.listByPhotographer(photographerId); return Result.success(list); } // 其他CRUD接口... }前端采用瀑布流布局展示作品关键代码template div classmasonry div v-foritem in portfolioList :keyitem.id classmasonry-item el-image :srcitem.imageUrl :preview-src-listpreviewImages fitcover /el-image /div /div /template script setup import { ref, computed } from vue const portfolioList ref([]) const previewImages computed(() portfolioList.value.map(item item.imageUrl) ) // 获取作品数据 const loadPortfolio async (photographerId) { const res await getPortfolioByPhotographer(photographerId) portfolioList.value res.data } /script3.2 在线预约系统实现预约业务涉及的关键技术点档期冲突检测算法微信/支付宝支付集成状态机设计档期检测SQL示例SELECT COUNT(*) FROM appointment WHERE photographer_id #{photographerId} AND appointment_date #{date} AND ( (start_time #{endTime} AND end_time #{startTime}) OR status NOT IN (CANCELED, REJECTED) )支付状态机设计public enum OrderStatus { PENDING_PAYMENT, // 待支付 PAID, // 已支付 CONFIRMED, // 已确认 SHOOTING, // 拍摄中 COMPLETED, // 已完成 CANCELLED // 已取消 }4. 系统部署实战指南4.1 后端部署关键步骤生产环境配置application-prod.ymlserver: port: 8080 servlet: context-path: /api spring: datasource: url: jdbc:mysql://mysql-host:3306/photostudio?useSSLfalse username: prod_user password: ${DB_PASSWORD} hikari: maximum-pool-size: 20 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl使用Docker打包部署FROM openjdk:11-jre WORKDIR /app COPY target/photostudio-backend.jar . EXPOSE 8080 ENTRYPOINT [java, -jar, photostudio-backend.jar]构建命令mvn clean package -DskipTests docker build -t photostudio-backend . docker run -d -p 8080:8080 --name ps-backend photostudio-backend4.2 前端部署优化方案Vite生产构建配置// vite.config.js export default defineConfig({ base: /, build: { outDir: dist, assetsDir: static, rollupOptions: { output: { chunkFileNames: static/js/[name]-[hash].js, entryFileNames: static/js/[name]-[hash].js, assetFileNames: static/[ext]/[name]-[hash].[ext] } } } })Nginx配置示例server { listen 80; server_name photostudio.example.com; location / { root /var/www/photostudio/dist; try_files $uri $uri/ /index.html; } location /api { proxy_pass http://backend:8080; proxy_set_header Host $host; } }5. 开发中的典型问题与解决方案5.1 跨域问题处理开发环境解决方案SpringBoot配置Configuration public class CorsConfig implements WebMvcConfigurer { Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping(/**) .allowedOrigins(*) .allowedMethods(GET, POST, PUT, DELETE) .allowCredentials(true) .maxAge(3600); } }生产环境推荐通过Nginx反向代理解决避免直接开放跨域。5.2 图片上传与存储方案采用七牛云OSS存储方案关键实现public class QiniuService { private final String accessKey ...; private final String secretKey ...; private final String bucket photostudio; public String upload(MultipartFile file) { Auth auth Auth.create(accessKey, secretKey); String upToken auth.uploadToken(bucket); Configuration cfg new Configuration(Region.autoRegion()); UploadManager uploadManager new UploadManager(cfg); try { Response response uploadManager.put( file.getBytes(), generateFileName(file), upToken ); return response.jsonToObject(DefaultPutRet.class).key; } catch (Exception ex) { throw new RuntimeException(上传失败, ex); } } }前端上传组件关键代码template el-upload action# :auto-uploadfalse :on-changehandleChange :show-file-listfalse el-button typeprimary选择图片/el-button /el-upload /template script setup const handleChange async (file) { const formData new FormData() formData.append(file, file.raw) const { data } await uploadImage(formData) console.log(上传成功:, data) } /script5.3 性能优化实践接口响应优化启用MyBatis二级缓存添加Spring Cache注解Cacheable(value photographer, key #id) public Photographer getById(Long id) { return photographerMapper.selectById(id); }前端性能优化图片懒加载路由组件懒加载使用Web Worker处理大数据量数据库优化为高频查询字段添加索引定期执行ANALYZE TABLE优化慢查询日志监控6. 项目扩展与进阶方向6.1 微服务化改造随着业务增长可以考虑拆分为以下微服务用户服务作品服务预约服务支付服务通知服务技术选型建议服务注册与发现Nacos服务通信OpenFeign配置中心Nacos Config网关Spring Cloud Gateway6.2 管理后台增强现有系统可以扩展数据看板使用ECharts实现操作日志审计权限精细化控制工作流引擎集成6.3 移动端适配方案开发微信小程序版本使用Uniapp跨端方案PWA渐进式Web应用支持这套系统从技术选型到最终部署每个环节都经过精心设计和反复验证。在实际开发中最大的体会是前期良好的架构设计比后期优化更重要。特别是接口规范的定义、状态管理的设计这些基础工作做好后后续功能扩展会非常顺畅。