
简介这是一套面向计算机专业本科生的期末大作业级实战项目基于Spring Boot后端与Vue 3前端构建的校园奶茶店线上点单系统适用于课程设计、毕业设计选题及Java全栈开发入门练习。资源包含完整可运行源码、MySQL数据库脚本、详细设计报告文档含需求分析、ER图、接口说明与部署指南所有代码均经本地编译调试通过评审得分98分内容获助教审定认可。压缩包共2000个文件17.02MB涵盖49个核心Java后端类、16个Vue组件、1192个JS逻辑文件、204个CSS样式文件、150个JSON配置及143份Markdown文档结构清晰前后端分离规范便于理解MVC架构与RESTful API设计实践。1. 项目概述与核心价值又到了期末大作业扎堆的季节后台收到不少私信都在问有没有一个能“抄作业”但又显得不那么“水”的完整项目。今天就来聊聊一个经典选题校园奶茶店线上点单系统。这个项目听起来简单但麻雀虽小五脏俱全它完美融合了前后端主流技术栈Spring Boot Vue涵盖了从用户下单、商家管理到数据统计的全流程业务是检验你Web开发综合能力的绝佳试金石。我当年带学生做课程设计十个里有八个选类似的外卖或点餐系统但能把业务逻辑理清、代码写得优雅、报告写得专业的其实不多。这个项目真正的价值在于它不是一个孤立的Demo而是一个具备完整业务闭环、可直接部署运行、并能写进简历作为项目经验的实战案例。无论你是计算机专业的学生需要完成期末大作业还是刚入行的开发者想找一个全栈项目练手它都能提供一条清晰的路径。2. 技术选型与架构设计思路2.1 为什么是Spring Boot Vue选择这个技术组合绝非偶然而是基于快速开发、生态成熟和前后端分离架构的必然选择。后端Spring Boot 作为坚实后盾Spring Boot的核心优势在于“约定大于配置”。对于校园奶茶店这种业务逻辑明确但并发量不会特别高的系统它能让开发者从繁琐的XML配置中解放出来快速搭建一个稳定、可扩展的后端服务。内嵌的Tomcat服务器使得项目可以打包成一个独立的Jar包部署变得极其简单无论是交给老师演示还是自己放到云服务器上都省心省力。此外Spring Boot生态中丰富的Starter依赖如spring-boot-starter-webWeb开发、spring-boot-starter-data-jpa或mybatis-spring-boot-starter数据访问、spring-boot-starter-security安全控制可选让我们能像搭积木一样构建应用。对于点单系统事务管理确保下单和库存扣减的原子性、RESTful API设计为前端Vue提供清晰的数据接口是Spring Boot的天然强项。前端Vue.js 构建灵活交互界面Vue以其轻量、渐进式和上手快的特点成为前端框架的热门选择。对于点单系统用户界面需要频繁的动态交互商品列表的筛选、购物车的实时增删改、订单状态的更新等。Vue的响应式数据绑定和组件化开发模式让这些功能的实现变得直观。通过Vue CLI可以快速搭建项目结构配合Vue Router实现单页面应用SPA的无刷新跳转如从菜单页跳到订单详情页使用Vuex管理全局状态如用户登录信息、购物车数据整个前端架构清晰且易于维护。与后端的交互则通过Axios库发起HTTP请求调用Spring Boot提供的API接口。前后端分离架构的优势采用前后端分离意味着后端只负责数据和业务逻辑通过API接口提供服务前端专注于用户界面和交互逻辑。这种架构的好处非常明显开发可以并行进行前端和后端工程师只需约定好API文档即可各自开发部署相互独立前端可以部署在Nginx等静态服务器后端部署在Java应用服务器互不影响技术栈灵活未来即使要替换前端框架比如换成React后端也几乎不需要改动。2.2 系统核心模块设计在动手敲代码之前必须把系统的核心模块和它们之间的关系想清楚。一个线上点单系统通常可以划分为以下四个核心模块用户端模块面向校园内的学生和教职工。核心功能包括用户注册/登录、浏览奶茶菜单按分类、热度排序、将商品加入购物车、编辑购物车、提交订单选择配送地址、支付方式模拟、查看个人订单历史及状态。商品与菜单管理模块这是系统的基石。需要管理奶茶的品类如水果茶、芝士奶盖、经典奶茶、具体商品名称、图片、描述、价格、库存以及可定制的选项如甜度、冰度、加料。这个模块通常提供后台管理界面。订单处理模块系统的业务核心。负责处理用户提交的订单包括订单的创建、状态流转待支付-已支付-制作中-待取餐/配送中-已完成、库存的同步扣减、以及简单的订单查询与统计。后台管理模块面向奶茶店管理员。功能包括商品的上架/下架/信息修改、订单的集中查看与处理接单、出餐完成标记、销售数据的简单图表统计如今日销量Top5、用户管理通常仅查看校园系统注册一般开放。这些模块通过数据库的表关系紧密连接。例如一个用户user表可以有多个订单order表一个订单包含多个订单项order_item表每个订单项关联一个商品product表。理清这些实体关系是设计数据库表结构的前提。注意在真正的商业系统中支付和配送是两大复杂子系统。作为期末作业我们通常采用“模拟”策略。支付可以集成一个简单的支付宝/微信支付沙箱接口或者更简单地在下单后直接置订单状态为“已支付”。配送则简化为“到店自取”和“校内配送需填写宿舍楼号”两种选择状态由后台管理员手动更新。这既能体现业务完整性又控制了项目复杂度。3. 数据库设计与关键表结构解析数据库设计是项目的“地基”设计得好后续开发事半功倍。这里采用MySQL作为关系型数据库因为它免费、通用且与Spring Boot集成简单。以下是核心表结构的设计思路与SQL示例。3.1 核心表字段设计用户表 (user)这是系统的基础。除了基本字段role字段用于区分普通用户(USER)和管理员(ADMIN)是实现权限控制的关键。CREATE TABLE user ( id int(11) NOT NULL AUTO_INCREMENT COMMENT 用户ID, username varchar(50) NOT NULL UNIQUE COMMENT 用户名学号/工号, password varchar(255) NOT NULL COMMENT 加密后的密码, nickname varchar(50) DEFAULT NULL COMMENT 昵称, phone varchar(20) DEFAULT NULL COMMENT 手机号, avatar varchar(500) DEFAULT NULL COMMENT 头像URL, role varchar(20) NOT NULL DEFAULT USER COMMENT 角色USER, ADMIN, create_time datetime DEFAULT CURRENT_TIMESTAMP COMMENT 注册时间, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 更新时间, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT用户表;商品分类表 (category) 与商品表 (product)分类表用于管理奶茶大类。商品表是核心status字段控制上架(ON_SALE)/下架(OFF_SALE)stock字段是实现库存扣减的关键。CREATE TABLE category ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(50) NOT NULL COMMENT 分类名称如果茶奶盖, sort_order int(11) DEFAULT 0 COMMENT 排序值, PRIMARY KEY (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT商品分类表; CREATE TABLE product ( id int(11) NOT NULL AUTO_INCREMENT, category_id int(11) NOT NULL COMMENT 所属分类ID, name varchar(100) NOT NULL COMMENT 商品名称, price decimal(10,2) NOT NULL COMMENT 商品价格, description text COMMENT 商品描述, image_url varchar(500) DEFAULT NULL COMMENT 商品图片URL, stock int(11) NOT NULL DEFAULT 0 COMMENT 库存数量, status varchar(20) NOT NULL DEFAULT ON_SALE COMMENT 状态ON_SALE, OFF_SALE, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_category_id (category_id), CONSTRAINT fk_product_category FOREIGN KEY (category_id) REFERENCES category (id) ON DELETE CASCADE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT商品表;订单表 (order) 与订单项表 (order_item)这是业务的核心表。订单表记录订单概要order_no订单号需要全局唯一通常用时间戳随机数生成。total_amount是订单总金额status跟踪订单生命周期。订单项表是订单与商品的多对多关联表记录了购买时的快照信息如商品当时的价格、选择的规格。CREATE TABLE order ( id int(11) NOT NULL AUTO_INCREMENT, order_no varchar(64) NOT NULL UNIQUE COMMENT 订单号唯一, user_id int(11) NOT NULL COMMENT 下单用户ID, total_amount decimal(10,2) NOT NULL COMMENT 订单总金额, status varchar(30) NOT NULL DEFAULT UNPAID COMMENT 订单状态UNPAID, PAID, MAKING, READY_FOR_PICKUP, DELIVERING, COMPLETED, CANCELLED, delivery_method varchar(20) DEFAULT PICKUP COMMENT 配送方式PICKUP自取, DELIVERY配送, delivery_address varchar(255) DEFAULT NULL COMMENT 配送地址如宿舍楼号, remark varchar(500) DEFAULT NULL COMMENT 用户备注, create_time datetime DEFAULT CURRENT_TIMESTAMP, update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY idx_user_id (user_id), KEY idx_order_no (order_no), CONSTRAINT fk_order_user FOREIGN KEY (user_id) REFERENCES user (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT订单主表; CREATE TABLE order_item ( id int(11) NOT NULL AUTO_INCREMENT, order_id int(11) NOT NULL COMMENT 所属订单ID, product_id int(11) NOT NULL COMMENT 商品ID, product_name varchar(100) NOT NULL COMMENT 商品名称快照, product_image varchar(500) DEFAULT NULL COMMENT 商品图片快照, unit_price decimal(10,2) NOT NULL COMMENT 商品单价快照, quantity int(11) NOT NULL COMMENT 购买数量, total_price decimal(10,2) NOT NULL COMMENT 该项总价, specification varchar(200) DEFAULT NULL COMMENT 规格如少糖去冰加珍珠, PRIMARY KEY (id), KEY idx_order_id (order_id), KEY idx_product_id (product_id), CONSTRAINT fk_order_item_order FOREIGN KEY (order_id) REFERENCES order (id) ON DELETE CASCADE, CONSTRAINT fk_order_item_product FOREIGN KEY (product_id) REFERENCES product (id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT订单项表;3.2 设计要点与避坑指南密码存储绝对不要明文存储密码在Java后端使用BCryptPasswordEncoder这类强哈希函数对密码进行加密后存储。这是安全底线。金额字段涉及金额的字段如price,total_amount必须使用DECIMAL类型而不是FLOAT或DOUBLE以避免浮点数计算带来的精度丢失问题。订单号生成订单号order_no需要全局唯一且尽可能难以猜测。一个常见的做法是时间戳yyyyMMddHHmmss 随机数6位 用户ID后4位。也可以考虑使用分布式ID生成算法如雪花算法Snowflake。数据快照order_item表中存储了商品下单时的名称、图片和单价而不是直接关联product表的当前信息。这是因为商品信息可能会变调价、改名但订单历史必须保持原样这是电商类系统的通用设计。索引优化在经常用于查询条件的字段上建立索引如user.id、order.order_no、product.category_id可以大幅提升查询性能。外键字段自动会有索引但像order.status这种高频筛选字段也值得考虑加索引。4. Spring Boot后端核心功能实现后端采用经典的MVC分层架构Controller层处理HTTP请求Service层实现业务逻辑Repository层或Mapper层负责数据持久化。这里以MyBatis-Plus作为数据访问层框架因为它提供了强大的CRUD封装和条件构造器能极大减少SQL编写。4.1 项目结构与依赖配置使用Spring Initializr或IDE直接创建初始化项目主要依赖包括Spring Web用于构建RESTful API。MyBatis FrameworkMyBatis-Plus数据持久化。MySQL Driver连接MySQL数据库。Lombok简化实体类代码如自动生成getter/setter。Spring Boot DevTools开发热部署。在application.yml中配置数据库连接、MyBatis-Plus和日志spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/campus_tea_shop?useUnicodetruecharacterEncodingutf-8serverTimezoneAsia/Shanghai username: root password: your_password mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台打印SQL调试用 global-config: db-config: logic-delete-field: deleted # 全局逻辑删除字段名如果启用 logic-delete-value: 1 logic-not-delete-value: 0 mapper-locations: classpath:mapper/*.xml logging: level: com.yourpackage.mapper: debug # 打印特定包下的SQL日志4.2 用户认证与权限控制对于校园系统一个简单实用的认证方案是使用Spring Security结合JWTJSON Web Token。这里简述流程登录接口用户提交用户名和密码后端验证通过后使用JJWT库生成一个JWT Token包含用户ID、角色等信息返回给前端。Token校验创建一个JWT认证过滤器JwtAuthenticationFilter拦截除登录、注册外的所有请求。从请求头中解析Token验证有效性并从中提取用户信息存入SecurityContextHolder。权限注解在Controller方法上使用PreAuthorize(“hasRole(‘ADMIN’)”)这样的注解即可轻松实现方法级别的权限控制。例如商品管理、订单处理的后台接口只允许ADMIN角色访问。实操心得如果觉得Spring Security配置稍显复杂对于课程作业也可以采用更简单的方案在用户登录成功后将用户信息剔除密码存入Redis并生成一个Session Key返回给前端作为Token。后续请求前端携带此Token后端从Redis中获取用户信息。这种方式避免了JWT的令牌刷新问题实现起来更直观。关键在于无论哪种方式密码比对必须在服务器端进行对比加密后的哈希值且Token或Session需设置合理的过期时间。4.3 商品与订单业务逻辑实现商品服务ProductService核心逻辑列表查询支持按分类、关键词、状态分页查询。使用MyBatis-Plus的QueryWrapper可以轻松构建动态查询条件。库存扣减这是下单的关键必须保证原子性防止超卖。通常有两种做法悲观锁在查询商品库存时使用SELECT ... FOR UPDATE但这会影响并发性能。乐观锁为商品表增加一个版本号字段version。更新库存时使用UPDATE product SET stock stock - ?, version version 1 WHERE id ? AND version ? AND stock ?。如果更新影响行数为0说明库存不足或版本冲突需要回滚或提示用户。乐观锁在高并发场景下更优。订单服务OrderService下单流程 这是系统最核心的业务必须保证事务性。Transactional(rollbackFor Exception.class) // 声明式事务任何异常都回滚 public Order createOrder(OrderCreateRequest request, Integer userId) { // 1. 基础校验验证用户、配送地址等 User user userService.getById(userId); if (user null) { throw new BusinessException(“用户不存在”); } // 2. 生成唯一订单号 String orderNo generateOrderNo(); // 3. 遍历购物车项计算总价并逐个校验库存使用乐观锁 BigDecimal totalAmount BigDecimal.ZERO; ListOrderItem orderItemList new ArrayList(); for (CartItem cartItem : request.getCartItems()) { Product product productService.getProductForUpdate(cartItem.getProductId()); // 这里可以封装一个带乐观锁校验的方法 if (product.getStock() cartItem.getQuantity()) { throw new BusinessException(product.getName() “库存不足”); } // 扣减库存 boolean updateSuccess productService.reduceStock(cartItem.getProductId(), cartItem.getQuantity()); if (!updateSuccess) { throw new BusinessException(product.getName() “库存扣减失败请重试”); } // 构建订单项快照 OrderItem orderItem new OrderItem(); orderItem.setProductName(product.getName()); orderItem.setUnitPrice(product.getPrice()); // ... 设置其他属性 orderItemList.add(orderItem); totalAmount totalAmount.add(product.getPrice().multiply(new BigDecimal(cartItem.getQuantity()))); } // 4. 创建订单主记录 Order order new Order(); order.setOrderNo(orderNo); order.setUserId(userId); order.setTotalAmount(totalAmount); order.setStatus(OrderStatusEnum.UNPAID.getCode()); // ... 设置其他属性 orderMapper.insert(order); // 5. 批量保存订单项并关联订单ID for (OrderItem item : orderItemList) { item.setOrderId(order.getId()); } orderItemService.saveBatch(orderItemList); // 6. 可选清空该用户的购物车 cartService.clearCart(userId); return order; }注意事项上述流程中库存扣减和订单创建必须在同一个数据库事务中。Transactional注解确保了这一点。在高并发场景下第3步的库存校验和扣减是性能瓶颈需要仔细设计。对于课程项目如果并发压力不大此方案足够。此外可以考虑引入消息队列如RabbitMQ进行异步削峰将下单和扣库存解耦但这会显著增加系统复杂度。5. Vue前端项目搭建与核心页面开发前端使用Vue 3 Composition API Vite构建UI库选用Element Plus因为它组件丰富风格中性适合后台管理系统。5.1 项目初始化与路由配置使用Vite快速创建项目并安装必要依赖npm create vuelatest campus-tea-shop-frontend cd campus-tea-shop-frontend npm install element-plus element-plus/icons-vue axios vue-router pinia在src/router/index.js中配置路由实现SPAimport { createRouter, createWebHistory } from ‘vue-router’; const routes [ { path: ‘/‘, redirect: ‘/home‘ }, { path: ‘/home‘, name: ‘Home‘, component: () import(‘/views/Home.vue‘) // 首页商品列表 }, { path: ‘/cart‘, name: ‘Cart‘, component: () import(‘/views/Cart.vue‘) // 购物车页 }, { path: ‘/order‘, name: ‘Order‘, component: () import(‘/views/Order.vue‘) // 订单页 }, { path: ‘/admin‘, name: ‘Admin‘, component: () import(‘/views/admin/AdminLayout.vue‘), // 后台布局 meta: { requiresAuth: true, requiresAdmin: true }, // 路由元信息用于权限校验 children: [ { path: ‘products‘, component: () import(‘/views/admin/ProductManage.vue‘) }, { path: ‘orders‘, component: () import(‘/views/admin/OrderManage.vue‘) } ] } ]; const router createRouter({ history: createWebHistory(), routes }); // 全局前置守卫进行权限检查 router.beforeEach((to, from, next) { const userStore useUserStore(); // 假设使用Pinia管理用户状态 if (to.meta.requiresAuth !userStore.isLoggedIn) { next(‘/login‘); } else if (to.meta.requiresAdmin userStore.userRole ! ‘ADMIN‘) { next(‘/home‘); // 非管理员跳回首页 } else { next(); } }); export default router;5.2 状态管理与API请求封装使用Pinia进行全局状态管理存储用户信息、购物车数据等。 在src/stores/user.js中import { defineStore } from ‘pinia‘; import { login as apiLogin } from ‘/api/auth‘; // 封装的API模块 export const useUserStore defineStore(‘user‘, { state: () ({ token: localStorage.getItem(‘token‘) || ‘‘, userInfo: JSON.parse(localStorage.getItem(‘userInfo‘)) || null }), getters: { isLoggedIn: (state) !!state.token, userRole: (state) state.userInfo?.role }, actions: { async login(loginForm) { const res await apiLogin(loginForm); this.token res.data.token; this.userInfo res.data.userInfo; // 存储到localStorage localStorage.setItem(‘token‘, this.token); localStorage.setItem(‘userInfo‘, JSON.stringify(this.userInfo)); // 设置axios默认请求头 axios.defaults.headers.common[‘Authorization‘] Bearer ${this.token}; }, logout() { this.token ‘‘; this.userInfo null; localStorage.removeItem(‘token‘); localStorage.removeItem(‘userInfo‘); delete axios.defaults.headers.common[‘Authorization‘]; } } });在src/api/request.js中封装Axios实例统一处理请求拦截添加Token、响应拦截处理错误import axios from ‘axios‘; import { ElMessage } from ‘element-plus‘; import router from ‘/router‘; const service axios.create({ baseURL: process.env.VITE_API_BASE_URL, // 从环境变量读取后端API地址 timeout: 10000 }); service.interceptors.request.use( config { const userStore useUserStore(); if (userStore.token) { config.headers.Authorization Bearer ${userStore.token}; } return config; }, error { return Promise.reject(error); } ); service.interceptors.response.use( response { const res response.data; // 假设后端统一返回格式为 { code: 200, data: {}, message: ‘success‘ } if (res.code ! 200) { ElMessage.error(res.message || ‘Error‘); // 如果是token过期或无效 if (res.code 401) { userStore.logout(); router.push(‘/login‘); } return Promise.reject(new Error(res.message || ‘Error‘)); } else { return res; } }, error { ElMessage.error(error.message || ‘网络请求失败‘); return Promise.reject(error); } ); export default service;5.3 核心页面组件开发示例商品列表与购物车商品列表页 (Home.vue) 关键点在于使用el-row和el-col进行栅格布局循环渲染商品卡片。每个卡片包含商品图片、名称、价格和“加入购物车”按钮。点击按钮时调用Vuex/Pinia的action将商品信息id, name, price, count等添加到全局的购物车状态中并可以同时更新本地存储localStorage以实现页面刷新后数据不丢失。template div class“home” el-row :gutter“20” el-col :span“6” v-for“product in productList” :key“product.id” el-card :body-style“{ padding: ‘0px’ }” img :src“product.imageUrl” class“product-image” / div style“padding: 14px;” span{{ product.name }}/span div class“bottom” span class“price”¥{{ product.price }}/span el-button type“primary” size“small” click“addToCart(product)”加入购物车/el-button /div /div /el-card /el-col /el-row /div /template script setup import { ref, onMounted } from ‘vue‘; import { getProductList } from ‘/api/product‘; import { useCartStore } from ‘/stores/cart‘; const productList ref([]); const cartStore useCartStore(); const loadProducts async () { const res await getProductList({ page: 1, pageSize: 12 }); productList.value res.data.list; }; const addToCart (product) { cartStore.addItem({ id: product.id, name: product.name, price: product.price, image: product.imageUrl, count: 1 }); ElMessage.success(‘已加入购物车‘); }; onMounted(() { loadProducts(); }); /script购物车页 (Cart.vue) 购物车页面需要展示所有已选商品允许用户修改数量、删除商品并实时计算总价。关键逻辑在于从全局状态Pinia Store中获取购物车列表。使用el-table展示数量列使用el-input-number组件方便增减。任何数量修改或删除操作都需要同步更新全局状态和本地存储。底部展示总价并提供“去结算”按钮点击后跳转到订单确认页。实操心得购物车数据在前端管理但提交订单时后端需要重新校验价格和库存。因为用户可能在提交前商品信息已发生变化。所以前端购物车更多是一个“草稿”真正的校验和计价发生在后端下单接口。此外购物车状态持久化到localStorage时建议只存商品ID和数量商品详情在每次进入页面时从接口重新获取以保证信息的实时性。6. 项目部署与报告文档撰写要点6.1 后端部署以Linux服务器为例环境准备服务器安装JDK 8、MySQL。数据库初始化在MySQL中执行项目SQL目录下的建表脚本创建数据库和表结构。应用打包在项目根目录下执行mvn clean package -DskipTestsMaven或使用Gradle打包会在target目录生成一个可执行的jar文件如campus-tea-shop-0.0.1-SNAPSHOT.jar。上传与运行将jar包上传至服务器。可以使用nohup命令在后台运行nohup java -jar campus-tea-shop-0.0.1-SNAPSHOT.jar --spring.profiles.activeprod app.log 21 。这里的prodprofile对应application-prod.yml配置文件用于配置生产环境的数据库连接等。使用Nginx反向代理可选但推荐为了让前端能访问后端API且隐藏端口可以配置Nginx。在Nginx配置文件中添加一个location块将/api/路径的请求代理到后端Spring Boot应用默认端口8080。server { listen 80; server_name your-domain.com; # 或服务器IP location /api/ { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } # 前端静态文件部署配置见下节 }6.2 前端部署构建生产版本在前端项目目录下运行npm run build会在dist目录生成优化后的静态文件HTML, JS, CSS。部署静态文件将dist目录下的所有文件上传到服务器的某个目录例如/var/www/html/campus-tea-shop。配置Nginx在同一个Nginx配置中添加一个location /块指向前端静态文件目录并配置try_files以实现Vue Router的history模式支持。server { listen 80; server_name your-domain.com; location / { root /var/www/html/campus-tea-shop; index index.html; try_files $uri $uri/ /index.html; # 支持Vue Router history模式 } location /api/ { proxy_pass http://127.0.0.1:8080; # ... 其他代理配置 } }重启Nginx服务sudo systemctl restart nginx。6.3 期末报告文档撰写核心要点报告文档是展示你项目思考和总结能力的关键。一份优秀的报告不应只是代码的堆砌而应体现系统化思维。需求分析清晰描述校园奶茶店线上点单系统的功能性需求用户、商家分别能做什么和非功能性需求性能、安全性、易用性等。系统设计架构设计图绘制前后端分离的架构图标明浏览器、Nginx、Spring Boot应用、MySQL之间的关系和数据流向。数据库ER图使用工具如PDManer、Navicat生成实体关系图并附上核心表结构的详细说明。核心功能流程图如下单流程、支付模拟流程的流程图。详细设计与实现这是报告的主体。分模块阐述例如用户模块注册登录的时序图、密码加密方式、JWT/Session认证流程。商品模块后台管理的界面设计、富文本编辑器如用于商品描述的集成。订单模块重点详细画出下单的序列图说明如何解决超卖问题悲观锁/乐观锁订单状态机是如何设计的。前端组件设计说明关键组件如商品卡片、购物车浮层的数据流和交互逻辑。系统测试列出测试用例表。包括单元测试对核心Service方法如库存扣减的测试。接口测试使用Postman或Swagger测试主要API接口。界面测试主要功能的界面操作测试。性能测试可选使用JMeter模拟多用户并发下单给出响应时间、吞吐量数据。部署说明详细记录从环境准备到服务上线的每一步命令和配置让评审老师能按步骤重现。总结与展望总结项目中学到的技术点和遇到的挑战如跨域问题、事务管理、前端状态保持。展望可能的优化方向如引入Redis缓存热门商品、使用WebSocket实现订单状态实时推送、集成真正的支付网关等。避坑指南报告中最容易丢分的地方是“只有描述没有论证”。例如提到“使用了JWT做认证”要接着说明“为什么选JWT而不是SessionJWT的无状态特性适合分布式部署但我们也考虑了其令牌刷新机制在本项目中我们设置了1小时的有效期……”。这种深层次的思考才是区分普通作业和优秀作业的关键。本文还有配套的精品资源点击获取