基于springboot2+vue2的美食推荐商城
温馨提示:
本文最后更新于 2026年05月28日,已超过 12 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我。
1. 项目简介
美食推荐商城是一个基于 Spring Boot + MyBatis Plus 的后端服务与 Vue.js(后台管理) + LayUI(前台展示) 的前端界面构成的 B2B2C(商家对用户) 型电商平台。系统面向三类角色:
- 管理员:对平台进行整体管理,包括基础数据维护(公告类型、美食类型、会员等级)、公告管理、留言板管理、美食及订单管理、商家管理、用户管理等。
- 商家:可以上架/下架自己的美食,查看订单,回复用户评价,管理商家基本信息。
- 用户:浏览美食、收藏、加入购物车、下单(支持余额或积分支付)、评价订单、留言反馈、个人中心充值等。
系统核心业务流程:
用户注册登录 → 浏览美食列表/详情 → 收藏或加入购物车 → 结算下单 → 支付(余额/积分) → 商家确认 → 用户收货 → 评价 → 完成。
2. 技术栈
2.1 后端
| 技术 | 版本/说明 |
|---|---|
| Spring Boot | 2.2.2.RELEASE |
| MyBatis Plus | 2.3 + 1.0.5 启动器 |
| 数据库 | MySQL 5.7.32 |
| 数据库连接池 | HikariCP(Spring Boot默认) |
| 权限控制 | 基于 Token(自定义拦截器 + Redis?无Redis,使用数据库token表) + Shiro(依赖引入但未使用,实际使用自定义AuthorizationInterceptor) |
| 工具库 | Hutool、Fastjson、Apache Commons Lang3、Poi(Excel导入导出)) |
| 定时任务 | 无,但提供线程基类 MyThreadMethod 用于后台常驻任务(如自动状态变更) |
2.2 前端
2.2.1 后台管理(admin)
- Vue.js 2.x
- Element UI(组件库)
- Vue Router(静态路由)
- Axios(封装为
http.js) - ECharts(图表统计)
- Vuex(未使用,采用 localStorage 管理状态)
2.2.2 用户前台(front)
- 原生 HTML / CSS / JavaScript
- LayUI(轮播图、弹层、分页等)
- jQuery
- Swiper(部分轮播)
- Vue.js(仅用于部分页面数据绑定,非单页应用)
- Element UI(部分页面如留言板、订单弹窗)
2.3 其他
- 构建工具:Maven
- 项目打包:JAR(Spring Boot 内置 Tomcat)
- 数据库初始化:提供
db.sql文件
3. 详细介绍
3.1 数据库设计
| 表名 | 说明 |
|---|---|
yonghu |
用户表(账户、密码、姓名、手机、身份证、头像、性别、邮箱、余额、积分、会员等级) |
shangjia |
商家表(账户、密码、商家名称、联系方式、邮箱、营业执照、星级、余额) |
meishi |
美食表(所属商家、名称、照片、类型、库存、购买获得积分、原价、现价、点击次数、上下架状态) |
meishi_order |
订单表(订单号、美食、用户、购买数量、实付价格、订单状态、支付类型、创建时间) |
cart |
购物车表(用户、美食、购买数量) |
meishi_collection |
收藏表(用户、美食、收藏类型) |
meishi_commentback |
评价表(美食、用户、评价内容、回复内容) |
liuyan |
留言板(用户、留言标题、内容、回复) |
gonggao |
公告表(标题、图片、类型、内容、发布时间) |
dictionary |
字典表(统一管理枚举值:性别、会员等级、商家星级、美食类型、订单状态等) |
config |
配置表(轮播图路径等) |
token |
Token 管理表(用户id、用户名、表名、角色、token、过期时间) |
users |
管理员表(用户名、密码、角色) |
3.2 核心功能模块
3.2.1 用户端(前台)
- 注册 / 登录:支持用户名/密码登录,注册时验证手机号、身份证唯一性。
- 首页:轮播图、美食推荐列表、公告展示、商家推荐。
- 美食浏览:按类型筛选、关键词搜索、点击查看详情(浏览次数+1)。
- 购物车:添加美食(限购数量不超过库存)、修改数量、删除、统一下单。
- 订单流程:
- 确认订单(选择支付方式:余额或积分)
- 支付(折扣根据会员等级自动计算)
- 商家确认(后台操作,此处前端暂未实现商家确认按钮?订单类型4表示已确认)
- 用户收货(状态变为5)
- 评价(状态变为1)
- 个人中心:修改资料、上传头像、充值余额、查看收藏、订单列表(可按状态筛选)。
- 留言板:发表留言,管理员后台回复。
- 公告:查看平台公告。
3.2.2 商家端(后台)
- 美食管理:添加/修改/删除自己的美食,管理库存、价格、上下架。
- 订单管理:查看购买自己美食的订单,可以确认订单(
deliver接口将订单状态改为4)。 - 评价管理:查看用户对自己美食的评价,并可回复。
- 基本信息:修改商家资料、营业执照、星级等。
3.2.3 管理员端(后台)
- 基础数据管理:管理字典表(公告类型、会员等级、美食类型等)。
- 公告管理:发布、编辑、删除公告。
- 留言板管理:回复用户留言。
- 美食管理:全平台美食的查看、删除(逻辑删除)。
- 订单管理:查看所有订单、退款审核(退款接口可还原库存和金额)。
- 商家管理:查看、添加、删除商家,重置商家密码。
- 用户管理:查看、添加、删除用户,重置密码。
- 轮播图管理:配置首页轮播图图片路径。
3.3 业务规则
- 会员等级:根据总积分自动升级(青铜 < 10000、白银 < 100000、黄金 ≥ 100000),不同等级享受不同折扣(字典表
beizhu字段存储折扣系数,如青铜0.98)。 - 支付方式:
- 余额支付:扣除用户余额,增加商家余额,同时增加用户积分(购买美食时获得的积分)。
- 积分支付:扣除用户当前积分(
yonghu_new_jifen),不增加积分。
- 退款:用户可对“已支付”的订单申请退款,恢复库存、退还用户金额(或积分)、扣减商家余额、扣回已获得的积分。
- 库存扣减:下单时(订单创建即支付)立即扣减库存,退款时恢复。
- 订单状态流转:
- 3-已支付 → 4-已确认(商家操作) → 5-已收到(用户操作) → 1-已评价(用户操作)。
- 2-退款(用户申请退款后状态变为2)。
3.4 接口设计(RESTful)
后端Controller示例(部分):
/yonghu/login(登录)、/yonghu/register(注册)/meishi/list(美食列表)、/meishi/detail/{id}(详情,自动+1点击量)/cart/save、/cart/update、/cart/delete/meishiOrder/order(批量下单)、/meishiOrder/refund(退款)、/meishiOrder/receiving(确认收货)、/meishiOrder/commentback(评价)/shangjia/session(获取商家信息)
所有需要登录的接口均通过请求头 Token 校验(自定义拦截器 AuthorizationInterceptor)。
3.5 安全性
- 登录生成随机32位Token,存入数据库并返回客户端,后续请求携带。
- Token有效期为1小时,过期需重新登录。
- 拦截器对所有请求进行Token验证(除
@IgnoreAuth标记的方法外)。 - 密码明文存储(示例中未加密,实际生产应加密)。
- 逻辑删除:
meishi_delete、shangjia_delete字段标记删除,查询时过滤已删除数据。
4. 部分代码
4.1 后端 – 订单下单核心逻辑(MeishiOrderController.order)
@RequestMapping("/order")
public R add(@RequestParam Map<String, Object> params, HttpServletRequest request){
// 获取当前登录用户、支付方式、购物车商品列表
Integer userId = (Integer) request.getSession().getAttribute("userId");
Integer meishiOrderPaymentTypes = Integer.valueOf(String.valueOf(params.get("meishiOrderPaymentTypes")));
String data = String.valueOf(params.get("meishis"));
JSONArray jsonArray = JSON.parseArray(data);
List<Map> meishis = JSON.parseObject(jsonArray.toString(), List.class);
YonghuEntity yonghuEntity = yonghuService.selectById(userId);
// 计算会员折扣
BigDecimal zhekou = getDiscount(yonghuEntity.getHuiyuandengjiTypes());
List<MeishiOrderEntity> meishiOrderList = new ArrayList<>();
List<ShangjiaEntity> shangjiaList = new ArrayList<>();
List<MeishiEntity> meishiList = new ArrayList<>();
List<Integer> cartIds = new ArrayList<>();
for (Map<String, Object> map : meishis) {
Integer meishiId = Integer.valueOf(String.valueOf(map.get("meishiId")));
Integer buyNumber = Integer.valueOf(String.valueOf(map.get("buyNumber")));
MeishiEntity meishiEntity = meishiService.selectById(meishiId);
// 库存校验
if(meishiEntity.getMeishiKucunNumber() < buyNumber){
return R.error(meishiEntity.getMeishiName()+"的库存不足");
}
meishiEntity.setMeishiKucunNumber(meishiEntity.getMeishiKucunNumber() - buyNumber);
// 订单对象组装
MeishiOrderEntity order = new MeishiOrderEntity();
order.setMeishiOrderUuidNumber(String.valueOf(new Date().getTime()));
order.setMeishiId(meishiId);
order.setYonghuId(userId);
order.setBuyNumber(buyNumber);
order.setMeishiOrderTypes(3);
order.setMeishiOrderPaymentTypes(meishiOrderPaymentTypes);
order.setInsertTime(new Date());
if(meishiOrderPaymentTypes == 1){ // 余额支付
Double money = meishiEntity.getMeishiNewMoney() * buyNumber * zhekou.doubleValue();
// 余额不足校验...
yonghuEntity.setNewMoney(yonghuEntity.getNewMoney() - money);
// 增加积分...
order.setMeishiOrderTruePrice(money);
// 增加商家余额
ShangjiaEntity shangjia = shangjiaService.selectById(meishiEntity.getShangjiaId());
shangjia.setNewMoney(shangjia.getNewMoney() + money);
shangjiaList.add(shangjia);
}
meishiOrderList.add(order);
meishiList.add(meishiEntity);
if(map.containsKey("id")) cartIds.add(Integer.valueOf(map.get("id").toString()));
}
// 批量保存订单、更新商品、更新商家、更新用户、清空购物车
meishiOrderService.insertBatch(meishiOrderList);
meishiService.updateBatchById(meishiList);
shangjiaService.updateBatchById(shangjiaList);
yonghuService.updateById(yonghuEntity);
if(cartIds.size()>0) cartService.deleteBatchIds(cartIds);
return R.ok();
}
4.2 前端 – 美食详情页(meishi/detail.html) – 收藏与购物车
// 收藏/取消收藏
addMeishiCollection() {
let _this = this;
layui.http.request('meishiCollection/list', 'get', {
meishiId: _this.detail.id,
yonghuId: localStorage.getItem('userid'),
}, (res) => {
if (res.data.list.length == 1) {
layui.http.requestJson('meishiCollection/delete', 'post', [res.data.list[0].id], function (res) {
layer.msg('取消成功', { time: 1000, icon: 5 }, function () { window.location.reload(); });
});
} else {
layui.http.requestJson('meishiCollection/add', 'post', {
yonghuId: localStorage.getItem('userid'),
meishiId: _this.detail.id,
meishiCollectionTypes: 1,
}, function (res) {
layer.msg('收藏成功', { time: 1000, icon: 6 }, function () { window.location.reload(); });
});
}
});
},
// 添加到购物车
addMeishiCart(){
if (this.detail.meishiKucunNumber < this.buyNumber) {
layer.msg(`库存不足`, { time: 2000, icon: 5 }); return;
}
layui.http.request('cart/list', 'get', {
yonghuId: localStorage.getItem('userid'),
meishiId : this.detail.id,
}, (res) => {
if(res.data.list.length > 0){
layer.msg("该美食已经添加到购物车", { time: 2000, icon: 5 }); return;
}
layui.http.requestJson('cart/add', 'post', {
yonghuId : localStorage.getItem('userid'),
meishiId : this.detail.id,
buyNumber: this.buyNumber,
}, (res) => {
if(res.code==0) layer.msg('添加成功', { time: 2000, icon: 6 });
else layer.msg(res.msg, { time: 2000, icon: 2 });
});
});
}
4.3 MyBatis Plus 分页查询配置(MeishiDao.xml)
<select id="selectListView" parameterType="map" resultType="com.entity.view.MeishiView">
SELECT a.*, shangjia.shangjia_name as shangjiaName, ...
FROM meishi a LEFT JOIN shangjia ON a.shangjia_id = shangjia.id
<where>
<if test="params.shangjiaId != null">a.shangjia_id = #{params.shangjiaId}</if>
<if test="params.meishiName != null and params.meishiName != ''">
a.meishi_name like CONCAT('%',#{params.meishiName},'%')
</if>
...
</where>
order by a.${params.orderBy} desc
</select>
5. 部分截图





































6. 项目总结
本项目实现了一个功能完整的美食推荐商城系统,覆盖了电商平台常见的用户、商家、管理员三端操作,包含商品管理、购物车、订单、支付(余额/积分)、会员折扣、评价留言、公告发布等核心模块。后端采用 Spring Boot + MyBatis Plus 架构,代码分层清晰(Controller、Service、Dao、Entity、View),通过自定义 Token 拦截器实现无状态认证,支持跨域。前端后台使用 Vue + Element UI,前台使用 LayUI + 原生 JS,实现了良好的用户体验。
总体而言,该系统适合作为毕业设计、课程设计或小型电商平台的起步模板,具备良好的扩展性和参考价值。
7. 资源
正文到此结束
- 本文标签: Java Spring Boot 毕业设计
- 本文链接: https://blog.xiaobias.com/article/32
- 版权声明: 本文由十五喵原创发布,转载请遵循《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权
