这个项目非常适合有一定springboot基础的新手入门练习,对于其中不需要练习的前端部分特此介绍一下
一、技术架构
瑞吉外卖后台管理端采用前后端分离的开发模式,前端主要技术栈包括:
- HTML5 + CSS3 构建页面结构与样式
- Vue.js 实现数据绑定与组件化开发
- Element UI 提供丰富的 UI 组件
- Axios 处理网络请求
- JavaScript 实现业务逻辑
二、核心功能模块解析
1. 系统整体布局
系统采用经典的后台管理系统布局,主要分为三个部分:
- 左侧导航菜单:包含系统所有功能入口
- 顶部导航栏:显示当前页面标题、用户信息和操作按钮
- 主内容区:展示各功能模块的具体内容,通过 iframe 实现页面切换
html
<!-- 布局核心代码 -->
<div class="app-wrapper openSidebar clearfix">
<!-- 侧边栏导航 -->
<div class="sidebar-container">
<el-menu :default-active="defAct" background-color="#343744" text-color="#bfcbd9" active-text-color="#f4f4f5">
<!-- 菜单项 -->
</el-menu>
</div>
<!-- 主内容区 -->
<div class="main-container">
<!-- 顶部导航栏 -->
<div class="navbar">
<div class="head-lable">{{headTitle}}</div>
<div class="right-menu">
<!-- 用户信息与操作 -->
</div>
</div>
<!-- 页面内容(iframe) -->
<div class="app-main">
<iframe id="cIframe" :src="iframeUrl" width="100%" height="auto" frameborder="0"></iframe>
</div>
</div>
</div>
2. 菜品管理模块
菜品管理是系统的核心功能之一,主要实现菜品的增删改查、状态管理等功能。
2.1 菜品列表页
菜品列表采用表格展示,支持分页、搜索、批量操作等功能:
html
<!-- 菜品列表表格 -->
<el-table :data="tableData" stripe @selection-change="handleSelectionChange">
<el-table-column type="selection" width="25"></el-table-column>
<el-table-column prop="name" label="菜品名称"></el-table-column>
<el-table-column prop="image" label="图片" align="center">
<template slot-scope="{ row }">
<el-image :src="getImage(row.image)" :preview-src-list="[ `/common/download?name=${row.image}` ]">
<div slot="error" class="image-slot">
<img src="./../../images/noImg.png" style="width: auto; height: 40px;">
</div>
</el-image>
</template>
</el-table-column>
<!-- 其他列 -->
<el-table-column label="操作" width="160" align="center">
<template slot-scope="scope">
<el-button type="text" @click="addFoodtype(scope.row.id)">修改</el-button>
<el-button type="text" @click="statusHandle(scope.row)">
{{ scope.row.status == '0' ? '启售' : '停售' }}
</el-button>
<el-button type="text" @click="deleteHandle('单删', scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
:page-sizes="[10, 20, 30, 40]"
:page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="counts"
@size-change="handleSizeChange"
:current-page.sync="page"
@current-change="handleCurrentChange"
></el-pagination>
列表数据加载逻辑:
javascript
async init () {
const params = {
page: this.page,
pageSize: this.pageSize,
name: this.input ? this.input : undefined
}
await getDishPage(params).then(res => {
if (String(res.code) === '1') {
this.tableData = res.data.records || []
this.counts = res.data.total
}
}).catch(err => {
this.$message.error('请求出错了:' + err)
})
}
2.2 菜品新增与编辑
菜品表单支持图片上传、口味配置等功能,通过同一个页面实现新增和编辑功能:
javascript
<!-- 菜品图片上传 -->
<el-upload
class="avatar-uploader"
action="/common/upload"
:show-file-list="false"
:on-success="handleAvatarSuccess"
:on-change="onChange"
ref="upload"
>
<img v-if="imageUrl" :src="imageUrl" class="avatar"></img>
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
<!-- 口味配置 -->
<div class="flavorBox">
<div v-for="(item, index) in dishFlavors" :key="index" class="items">
<div class="itTit">
<el-input v-model="item.name" placeholder="请输入口味"></el-input>
</div>
<div class="labItems">
<span v-for="(it, ind) in item.value" :key="ind">
{{ it }} <i @click="delFlavorLabel(index, ind)">X</i>
</span>
<div class="inputBox" contenteditable="true"
@keydown.enter="(val)=>keyDownHandle(val,index)"></div>
</div>
<span class="delFlavor" @click="delFlavor(index)">删除</span>
</div>
<div class="addBut" @click="addFlavore">添加口味</div>
</div>
图片上传处理:
javascript
handleAvatarSuccess (response, file, fileList) {
if(response.code === 0 && response.msg === '未登录'){
window.top.location.href = '/backend/page/login/login.html'
}else{
this.imageUrl = `/common/download?name=${response.data}`
this.ruleForm.image = response.data
}
}
3. 分类管理模块
分类管理实现对菜品分类的维护,采用类似的列表 + 表单模式:
javascript
// 分类相关API
// 查询列表接口
const getCategoryPage = (params) => {
return $axios({
url: '/category/page',
method: 'get',
params
})
}
// 编辑页面反查详情接口
const queryCategoryById = (id) => {
return $axios({
url: `/category/${id}`,
method: 'get'
})
}
// 删除接口
const deleCategory = (id) => {
return $axios({
url: '/category',
method: 'delete',
params: { id }
})
}
4. 订单管理模块
订单管理模块实现订单查询、状态修改等功能:
javascript
// 订单相关API
// 查询列表页接口
const getOrderDetailPage = (params) => {
return $axios({
url: '/order/page',
method: 'get',
params
})
}
// 查看接口
const queryOrderDetailById = (id) => {
return $axios({
url: `/orderDetail/${id}`,
method: 'get'
})
}
// 取消,派送,完成接口
const editOrderDetail = (params) => {
return $axios({
url: '/order',
method: 'put',
data: { ...params }
})
}
三、系统亮点功能
图片上传与预览:通过 Element UI 的 Upload 组件实现图片上传,支持预览和错误处理
javascript
beforeUpload (file) {
if(file){
const suffix = file.name.split('.')[1]
const size = file.size / 1024 / 1024 < 2
if(['png','jpeg','jpg'].indexOf(suffix) < 0){
this.$message.error('上传图片只支持 png、jpeg、jpg 格式!')
this.$refs.upload.clearFiles()
return false
}
if(!size){
this.$message.error('上传文件大小不能超过 2MB!')
return false
}
return file
}
}
批量操作:支持菜品的批量删除、批量启售 / 停售等操作
javascript
// 状态更改
statusHandle (row) {
let params = {}
if (typeof row === 'string' ) {
// 批量操作
if (this.checkList.length === 0) {
this.$message.error('批量操作,请先勾选操作菜品!')
return false
}
params.id = this.checkList.join(',')
params.status = row
} else {
// 单个操作
params.id = row.id
params.status = row.status ? '0' : '1'
}
// 确认对话框
this.$confirm('确认更改该菜品状态?', '提示', {
'confirmButtonText': '确定',
'cancelButtonText': '取消',
'type': 'warning'
}).then(() => {
dishStatusByStatus(params).then(res => {
if (res.code === 1) {
this.$message.success('菜品状态已经更改成功!')
this.handleQuery()
} else {
this.$message.error(res.msg || '操作失败')
}
})
})
}
动态菜单与路由:通过 JavaScript 动态生成菜单,并通过 iframe 实现页面无刷新切换
javascript
menuHandle(item, goBackFlag) {
this.loading = true
this.menuActived = item.id
this.iframeUrl = item.url
this.headTitle = item.name
this.goBackFlag = goBackFlag
this.closeLoading()
}
四、总结
瑞吉外卖后台管理端采用了现代化的前端技术栈和设计理念,实现了餐饮管理的核心功能。系统的亮点在于:
- 清晰的模块划分,使代码结构清晰,易于维护
- 丰富的交互体验,如批量操作、图片预览等功能
- 响应式设计,适配不同屏幕尺寸
- 完善的错误处理和用户提示
学者可以考虑引入 Vue Router 实现更完善的路由管理,使用 Vuex 进行状态管理,进一步提升系统的可扩展性和可维护性。同时,可以增加数据统计与分析功能。