跳到主要内容
苍穹外卖前端开发实战:员工与套餐管理模块 | 极客日志
TypeScript Node.js 大前端 java
苍穹外卖前端开发实战:员工与套餐管理模块 介绍苍穹外卖项目前端开发流程。基于 Node.js、Vue、ElementUI 及 TypeScript 构建环境。详细演示员工管理模块的分页查询、状态切换、新增与修改功能,以及套餐管理模块的分页查询、售卖状态控制、批量删除与新增操作。通过封装 Axios 请求、配置 Vue Router 及使用 ElementUI 组件实现前后端数据交互与界面展示。
FrontendX 发布于 2026/4/6 更新于 2026/5/26 37 浏览前端环境搭建
技术选型
使用的前端技术栈 :Node.js、Vue、ElementUI、Axios、Vuex、Vue Router、TypeScript
代码结构
核心目录 / 文件:
目录 / 文件 说明 api 封装 Ajax 请求的文件目录 components 公共组件存放目录 views 视图组件存放目录 App.vue 项目主组件、页面入口文件 main.ts 整个项目的入口文件 router.ts 路由配置文件
环境准备
安装依赖包(生成 node_modules 目录):
npm install
启动前端项目(需同时启动后端 Java 服务):
npm run serve
员工管理
员工分页查询
需求分析和接口设计
代码开发
步骤一:制作页面头部
<div >
<label > 员工姓名:</label >
<el-input placeholder ="请输入员工姓名" />
<el-button type ="primary" > 查询</el-button >
+ 添加员工
<el-button type ="primary" >
</el-button >
</div >
说明:输入框和按钮均使用 ElementUI 提供的组件,可参考其官方文档进行修改。
绑定查询事件:为查询按钮添加 @click="pageQuery()" 事件。
<el-button type ="primary" @click ="pageQuery()" > 查询</el-button >
定义查询方法:在 methods 中定义 pageQuery 方法,验证方法能否正常执行。
<script lang="ts" >
export default {
methods : {
pageQuery ( ) {
alert (1 )
}
}
}
</script>
封装 API 请求:在 src/api/employee.ts 中定义 getEmployeeList 方法,用于发送 Ajax 请求获取分页数据。
export const getEmployeeList = (params : any ) => {
return request ({ url : '/employee/page' , method : 'get' , params : params })
}
导入 API 并定义模型数据:在员工管理组件中导入 getEmployeeList 方法,并在 data() 中定义分页相关的模型数据。
import { getEmployeeList } from '@/api/employee'
export default {
data ( ) {
return {
name : '' ,
page : 1 ,
pageSize : 10 ,
total : 0 ,
records : []
}
}
}
双向绑定输入框:将 name 属性与员工姓名输入框进行双向绑定。
<el-input v-model ="name" placeholder ="请输入员工姓名" clearable />
完善查询方法:在 pageQuery 方法中调用 getEmployeeList 方法,处理返回数据。
pageQuery ( ) {
const params = { page : this .page , pageSize : this .pageSize , name : this .name }
getEmployeeList (params)
.then ((res ) => {
if (res.data .code === 1 ) {
this .records = res.data .data .records
this .total = res.data .data .total
}
})
.catch ((err ) => {
this .$message .error ('请求出错了:' + err.message )
})
}
使用 Vue 的 created 生命周期钩子,可以在组件加载后自动发送 Ajax 请求,查询第一页数据。
created ( ) {
this .pageQuery ()
}
使用 ElementUI 的表格组件展示后端返回的员工数据。
<el-table :data ="records" stripe >
<el-table-column prop ="name" label ="员工姓名" />
<el-table-column prop ="username" label ="账号" />
<el-table-column prop ="phone" label ="手机号" />
<el-table-column prop ="status" label ="账号状态" >
<template slot-scope ="scope" >
<span :class ="scope.row.status === 0 ? 'stopUse' : 'stopUse'" >
{{ scope.row.status === 0 ? '禁用' : '启用' }}
</span >
</template >
</el-table-column >
<el-table-column prop ="updateTime" label ="最后操作时间" />
<el-table-column prop ="操作" label ="操作" >
<template slot-scope ="scope" >
<el-button size ="small" type ="text" > 修改</el-button >
<el-button size ="small" type ="text" > {{ scope.row.status === 1 ? '禁用' : '启用' }}</el-button >
<el-button size ="small" type ="text" > 删除</el-button >
</template >
</el-table-column >
</el-table >
<el-pagination
:page-sizes ="[10, 20, 30, 40, 50]"
:page-size ="pageSize"
layout ="total, sizes, prev, pager, next, jumper"
:total ="total"
@size-change ="handleSizeChange"
@current-change ="handleCurrentChange"
/>
handleSizeChange (pageSize ) {
this .pageSize = pageSize
this .pageQuery ()
},
handleCurrentChange (currentPage ) {
this .page = currentPage
this .pageQuery ()
}
启用禁用员工账号
需求分析和接口设计
代码开发 为表格中的 "启用 / 禁用" 按钮绑定 handleStartOrStop 事件,并根据当前状态动态显示按钮文字。
<el-button type ="text" size ="small" @click ="handleStartOrStop(scope.row)" >
{{ scope.row.status == '1' ? '禁用' : '启用' }}
</el-button >
在 methods 中定义 handleStartOrStop 方法,验证方法能否成功执行。
handleStartOrStop (row ) {
alert (`id=${row.id} status=${row.status} ` )
}
在 src/api/employee.ts 中定义 enableOrDisableEmployee 方法,用于发送 Ajax 请求更新员工状态。
export const enableOrDisableEmployee = (params : any ) => {
return request ({ url : `/employee/status/${params.status} ` , method : 'post' , params : { id : params.id } })
}
在员工管理组件中导入 enableOrDisableEmployee 方法,并完善 handleStartOrStop 方法,添加确认弹窗和状态更新逻辑。
handleStartOrStop (row ) {
this .$confirm('确认调整该账号的状态?' , '提示' , {
confirmButtonText : '确定' ,
cancelButtonText : '取消' ,
type : 'warning' ,
}).then (() => {
enableOrDisableEmployee ({ id : row.id , status : !row.status ? 1 : 0 })
.then ((res ) => {
if (res.status === 200 ) {
this .$message .success ('账号状态更改成功!' )
this .pageQuery ()
}
})
.catch ((err ) => {
this .$message .error ('请求出错了:' + err.message )
})
})
}
在 handleStartOrStop 方法中添加判断,如果是管理员账号则不允许修改状态并给出提示。
handleStartOrStop (row ) {
if (row.username === 'admin' ) {
this .$message .error ('admin 为管理员账号,不能更改账号状态!' )
return
}
this .$confirm('确认调整该账号的状态?' , '提示' , {
confirmButtonText : '确定' ,
cancelButtonText : '取消' ,
type : 'warning' ,
}).then (() => {
enableOrDisableEmployee ({ id : row.id , status : !row.status ? 1 : 0 })
.then ((res ) => {
if (res.status === 200 ) {
this .$message .success ('账号状态更改成功!' )
this .pageQuery ()
}
})
.catch ((err ) => {
this .$message .error ('请求出错了:' + err.message )
})
})
}
新增员工
需求分析和接口设计
代码开发 <div >
<label > 员工姓名:</label >
<el-input v-model ="name" placeholder ="请输入员工姓名" clearable />
<el-button type ="primary" @click ="pageQuery()" > 查询</el-button >
<el-button type ="primary" @click ="handleAddEmp" > + 添加员工</el-button >
</div >
步骤二:编写 handleAddEmp 方法,进行路由跳转
handleAddEmp ( ) {
this .$router .push ('/employee/add' )
}
{
path : "/employee/add" ,
component : () => import ("@/views/employee/addEmployee.vue" ),
meta : { title : "添加/修改员工" , hidden : true }
}
<template >
<div >
<div >
<el-form :model ="ruleForm" :rules ="rules" ref ="ruleForm" label-width ="180px" >
<el-form-item label ="账号" prop ="username" >
<el-input v-model ="ruleForm.username" > </el-input >
</el-form-item >
<el-form-item label ="员工姓名" prop ="name" >
<el-input v-model ="ruleForm.name" > </el-input >
</el-form-item >
<el-form-item label ="手机号" prop ="phone" >
<el-input v-model ="ruleForm.phone" > </el-input >
</el-form-item >
<el-form-item label ="性别" prop ="sex" >
<el-radio v-model ="ruleForm.sex" label ="1" > 男</el-radio >
<el-radio v-model ="ruleForm.sex" label ="2" > 女</el-radio >
</el-form-item >
<el-form-item label ="身份证号" prop ="idNumber" >
<el-input v-model ="ruleForm.idNumber" > </el-input >
</el-form-item >
<div >
<el-button type ="primary" @click ="submitForm('ruleForm',false)" > 保存</el-button >
<el-button type ="primary" @click ="submitForm('ruleForm',true)" > 保存并继续添加员工</el-button >
<el-button @click ="() => this.$router.push('/employee')" > 返回</el-button >
</div >
</el-form >
</div >
</div >
</template >
export default {
data ( ) {
return {
ruleForm : {
name : '' ,
username : '' ,
sex : '1' ,
phone : '' ,
idNumber : ''
},
rules : {
name : [
{ required : true , message : '请输入员工姓名' , trigger : 'blur' }
],
username : [
{ required : true , message : '请输入账号' , trigger : 'blur' }
],
phone : [
{
required : true ,
trigger : 'blur' ,
validator : (rule, value, callback ) => {
if (value === '' || !(/^1[3|4|5|6|7|8]\d{9}$/ .test (value))) {
callback (new Error ('请输入正确的手机号' ))
} else {
callback ()
}
}
}
],
idNumber : [
{
required : true ,
trigger : 'blur' ,
validator : (rule, value, callback ) => {
if (value === '' || !(/(\^\d{15}$)|(\^\d{18}$)|(\^\d{17}(\d|X|x)$)/ .test (value))) {
callback (new Error ('请输入正确的身份证号' ))
} else {
callback ()
}
}
}
]
}
}
}
}
步骤五:在 employee.ts 中封装新增员工方法
export const addEmployee = (params : any ) => {
return request ({ url : '/employee' , method : 'post' , data : params })
}
步骤六:定义提交表单的方法 submitForm:
methods : {
submitForm (formName, isContinue ) {
this .$refs [formName].validate ((valid ) => {
if (valid) {
addEmployee (this .ruleForm )
.then ((res : any ) => {
if (res.data .code === 1 ) {
this .$message .success ('员工添加成功!' )
if (isContinue) {
this .$router .push ({ path : '/employee/add' })
} else {
this .ruleForm = {
username : '' ,
name : '' ,
phone : '' ,
sex : '1' ,
idNumber : ''
}
}
} else {
this .$message .error (res.data .msg )
}
})
}
})
}
}
修改员工
需求分析和接口设计
代码开发 <el-button type ="text" size ="small" @click ="handleUpdateEmp(scope.row)" > 修改</el-button >
步骤二:编写 handleUpdateEmp 方法,实现路由跳转
在员工列表组件的 methods 中定义跳转方法,并对管理员账号进行保护:
handleUpdateEmp (row ) {
if (row.username === 'admin' ) {
this .$message .error ('admin 为管理员账号,不能修改!' )
return
}
this .$router .push ({ path : '/employee/add' , query : { id : row.id } })
}
地址栏传递参数:this.$router.push({path: 路由路径,query:{参数名:参数值}})
步骤三:在 addEmployee.vue 中定义操作类型并区分新增 / 修改
在组件的 data() 中定义 optType 用于区分操作类型,并在 created 生命周期中根据路由参数判断:
<script lang="ts" >
import { addEmployee } from '@/api/employee'
export default {
data ( ) {
return {
optType : '' ,
ruleForm : { },
rules : { }
}
},
created ( ) {
this .optType = this .$route .query .id ? 'update' : 'add'
},
methods : { }
}
</script>
获取路由参数:this.$router.query.参数名
步骤四:在 employee.ts 中封装根据 ID 查询员工的方法
export const queryEmployeeById = (id : number ) => {
return request ({ url : `/employee/${id} ` , method : 'get' })
}
步骤五:在 addEmployee.vue 中实现数据回显
在 created 方法中,如果是修改操作,则调用查询方法回显数据:
created ( ) {
this .optType = this .$route .query .id ? 'update' : 'add'
if (this .optType === 'update' ) {
queryEmployeeById (this .$route .query .id )
.then ((res ) => {
if (res.data .code === 1 ) {
this .ruleForm = res.data .data
}
})
}
}
在模板中使用 v-if 指令,仅在新增操作时显示该按钮:
<div >
<el-button type ="primary" @click ="submitForm('ruleForm',false)" > 保存</el-button >
<el-button v-if ="this.optType === 'add'" type ="primary" @click ="submitForm('ruleForm',true)" > 保存并继续添加员工</el-button >
<el-button @click ="() => this.$router.push('/employee')" > 返回</el-button >
</div >
步骤七:在 employee.ts 中封装修改员工的方法
export const updateEmployee = (params : any ) => {
return request ({ url : '/employee' , method : 'put' , data : params })
}
步骤八:修改 submitForm 方法,区分新增和修改操作
在组件的 methods 中,根据 optType 执行不同的请求:
submitForm (formName, isContinue ) {
this .$refs [formName].validate ((valid ) => {
if (valid) {
if (this .optType === 'add' ) {
addEmployee (this .ruleForm )
.then ((res : any ) => {
})
} else {
updateEmployee (this .ruleForm )
.then ((res : any ) => {
if (res.data .code === 1 ) {
this .$message .success ('员工修改成功!' )
this .$router .push ({ path : '/employee' })
} else {
this .$message .error (res.data .msg )
}
})
}
}
})
}
套餐管理
套餐分页查询
需求分析和接口设计
代码开发 <div >
<label > 套餐名称:</label >
<el-input v-model ="name" clearable />
<label > 套餐分类:</label >
<el-select v-model ="categoryId" placeholder ="请选择" >
<el-option v-for ="item in options" :key ="item.id" :label ="item.name" :value ="item.id" />
</el-select >
<label > 售卖状态:</label >
<el-select v-model ="status" placeholder ="请选择" clearable >
<el-option v-for ="item in statusArr" :key ="item.value" :label ="item.label" :value ="item.value" />
</el-select >
<el-button type ="primary" > 查询</el-button >
<div >
<el-button type ="danger" > 批量删除</el-button >
<el-button type ="info" > + 新建套餐</el-button >
</div >
</div >
export default {
data ( ) {
return {
name : '' ,
categoryId : '' ,
status : '' ,
options : [],
statusArr : [
{ value : '1' , label : '启售' },
{ value : '0' , label : '停售' }
]
}
}
}
封装 API 请求:在 src/api/category.ts 中已定义 getCategoryByType 方法,用于根据类型查询分类。
export const getCategoryByType = (params : any ) => {
return request ({ url : '/category/list' , method : 'get' , params : params })
}
导入并调用 API:在套餐管理组件中导入该方法,并在 created 生命周期中调用,动态填充下拉框。
<script lang="ts" >
import { getCategoryByType } from '@/api/category'
export default {
data ( ) {
},
created ( ) {
getCategoryByType ({ type : 2 })
.then ((res ) => {
if (res.data .code === 1 ) {
this .options = res.data .data
}
})
}
}
</script>
绑定查询事件:为查询按钮添加 @click="pageQuery" 事件。
<el-button type ="primary" @click ="pageQuery()" > 查询</el-button >
封装 API 请求:在 src/api/setMeal.ts 中定义 getSetmealPage 方法,用于发送 Ajax 请求获取套餐分页数据。
export const getSetmealPage = (params : any ) => {
return request ({ url : '/setmeal/page' , method : 'get' , params : params })
}
导入 API 并定义模型数据:在套餐管理组件中导入 getSetmealPage 方法,并在 data() 中定义分页相关的模型数据。
import { getSetmealPage } from '@/api/setMeal'
export default {
data ( ) {
return {
page : 1 ,
pageSize : 10 ,
total : 0 ,
records : [],
name : '' ,
categoryId : '' ,
status : '' ,
options : [],
statusArr : []
}
}
}
完善查询方法:在 pageQuery 方法中调用 getSetmealPage 方法,处理返回数据。
pageQuery ( ) {
const params = {
page : this .page ,
pageSize : this .pageSize ,
name : this .name ,
status : this .status ,
categoryId : this .categoryId
}
getSetmealPage (params)
.then ((res ) => {
if (res.data .code === 1 ) {
this .total = res.data .data .total
this .records = res.data .data .records
}
})
}
在 created 生命周期中调用 pageQuery 方法,可以在组件加载后自动发送 Ajax 请求,查询第一页数据。
created ( ) {
getCategoryByType ({ type : 2 })
.then ((res ) => {
if (res.data .code === 1 ) {
this .options = res.data .data
}
})
this .pageQuery ()
}
<el-table :data ="records" stripe >
<el-table-column prop ="image" label ="图片" >
<template slot-scope ="scope" >
<el-image :src ="scope.row.image" > </el-image >
</template >
</el-table-column >
<el-table-column prop ="name" label ="套餐名称" />
<el-table-column prop ="price" label ="套餐价" />
<el-table-column prop ="categoryName" label ="套餐分类" />
<el-table-column label ="售卖状态" >
<template slot-scope ="scope" >
<div :class ="scope.row.status === 0 ? 'stopUse' : 'stopUse'" >
{{ scope.row.status === 0 ? '停售' : '启售' }}
</div >
</template >
</el-table-column >
<el-table-column prop ="updateTime" label ="最后操作时间" />
<el-table-column label ="操作" >
<template slot-scope ="scope" >
<el-button type ="text" size ="small" > 修改</el-button >
<el-button type ="text" size ="small" > {{ scope.row.status === 1 ? '停售' : '启售' }}</el-button >
<el-button type ="text" size ="small" > 删除</el-button >
</template >
</el-table-column >
</el-table >
<el-pagination
background
@size-change ="handleSizeChange"
@current-change ="handleCurrentChange"
:current-page ="page"
:page-sizes ="[10, 20, 30, 40, 50]"
:page-size ="pageSize"
layout ="total, sizes, prev, pager, next, jumper"
:total ="total"
>
</el-pagination >
handleSizeChange (pageSize ) {
this .pageSize = pageSize
this .pageQuery ()
},
handleCurrentChange (page ) {
this .page = page
this .pageQuery ()
}
启售停售套餐
需求分析和接口设计
代码开发 为表格中的 "起售 / 停售" 按钮绑定 handleStartOrStop 事件,并根据当前状态动态显示按钮文字。
<el-button type ="text" size ="small" @click ="handleStartOrStop(scope.row)" >
{{ scope.row.status == '1' ? '停售' : '启售' }}
</el-button >
在 methods 中定义 handleStartOrStop 方法,验证方法能否成功执行。
handleStartOrStop (row ) {
alert (`id=${row.id} status=${row.status} ` )
}
在 src/api/setMeal.ts 中定义 enableOrDisableSetmeal 方法,用于发送 Ajax 请求更新套餐状态。
export const enableOrDisableSetmeal = (params : any ) => {
return request ({ url : `/setmeal/status/${params.status} ` , method : 'post' , params : { id : params.id } })
}
在套餐管理组件中导入 enableOrDisableSetmeal 方法,并完善 handleStartOrStop 方法,添加确认弹窗和状态更新逻辑。
handleStartOrStop (row ) {
this .$confirm('确认调整该套餐的售卖状态?' , '提示' , {
confirmButtonText : '确定' ,
cancelButtonText : '取消' ,
type : 'warning' ,
}).then (() => {
enableOrDisableSetmeal ({ id : row.id , status : !row.status ? 1 : 0 })
.then ((res ) => {
if (res.status === 200 ) {
this .$message .success ('套餐售卖状态更改成功!' )
this .pageQuery ()
}
})
.catch ((err ) => {
this .$message .error ('请求出错了:' + err.message )
})
})
}
删除套餐
需求分析和接口设计
代码开发 在 src/api/setMeal.ts 中定义 deleteSetmeal 方法,用于发送 Ajax 请求删除套餐。
export const deleteSetmeal = (ids : string ) => {
return request ({ url : '/setmeal' , method : 'delete' , params : { ids : ids } })
}
为批量删除按钮绑定 handleDelete 事件,验证方法执行。
<el-button type ="danger" @click ="handleDelete" > 批量删除</el-button >
handleDelete ( ) {
alert ('删除套餐' )
}
为表格添加 selection-change 事件,动态获取当前勾选的套餐行。
<el-table :data ="records" stripe @selection-change ="handleSelectionChange" >
<el-table-column type ="selection" />
</el-table >
data ( ) {
return {
multipleSelection : []
}
}
handleSelectionChange (val ) {
this .multipleSelection = val
}
步骤四:完善 handleDelete 方法,处理批量删除
在 handleDelete 方法中,获取选中的套餐 ID 并拼接成字符串。
handleDelete ( ) {
const arr = new Array ()
this .multipleSelection .forEach (element => {
arr.push (element.id )
})
const ids = arr.join (',' )
alert (ids)
}
为单个删除按钮绑定 handleDelete 事件,并通过参数区分操作类型。
<el-button type ="text" size ="small" @click ="handleDelete('S',scope.row.id)" > 删除</el-button >
步骤六:调整 handleDelete 方法,兼容单个和批量删除
修改 handleDelete 方法,根据传入的 type 参数(S 表示单个删除,B 表示批量删除)执行不同逻辑。
handleDelete (type : string , id : string ) {
let param
if (type === 'S' ) {
param = id
} else {
const arr = new Array ()
this .multipleSelection .forEach (element => {
arr.push (element.id )
})
param = arr.join (',' )
}
deleteSetmeal (param)
.then (res => {
if (res.data .code === 1 ) {
this .$message .success ('删除成功!' )
this .pageQuery ()
} else {
this .$message .error (res.data .msg )
}
})
}
步骤七:完善 handleDelete 方法,添加提示和确认
handleDelete (type : string , id : string ) {
if (type === 'B' && this .multipleSelection .length === 0 ) {
this .$message('请选择需要删除的套餐!' )
return
}
this .$confirm('确定删除该套餐?' , '确定删除' , {
confirmButtonText : '删除' ,
cancelButtonText : '取消' ,
type : 'warning' ,
}).then (() => {
let param
if (type === 'S' ) {
param = id
} else {
const arr = new Array ()
this .multipleSelection .forEach (element => {
arr.push (element.id )
})
param = arr.join (',' )
}
deleteSetmeal (param)
.then (res => {
if (res.data .code === 1 ) {
this .$message .success ('删除成功!' )
this .pageQuery ()
} else {
this .$message .error (res.data .msg )
}
})
})
}
新增套餐
需求分析和接口设计
代码解读 在套餐管理列表页面中,找到新建套餐按钮,其绑定的点击事件为 handleAdd:
<el-button type ="info" @click ="handleAdd" > + 新建套餐</el-button >
步骤二:查看 handleAdd 方法的路由跳转逻辑
在 methods 中找到 handleAdd 方法,它通过路由跳转到新增套餐页面:
handleAdd ( ) {
this .$router .push ('/setmeal/add' )
}
在路由配置文件中,路径 /setmeal/add 对应的视图组件为 src/views/setmeal/addSetmeal.vue:
{
path : "/setmeal/add" ,
component : () => import ("@/views/setmeal/addSetmeal.vue" ),
meta : { title : "添加套餐" , hidden : true }
}
解读 src/views/setmeal/addSetmeal.vue 文件:
<template>
<div>
<div>
<div>
<label>套餐名称:</label>
<el-input clearable v-model="name" />
<label>套餐分类:</label>
<el-select v-model="categoryId" placeholder="请选择" clearable>
<el-option v-for="item in options" :key="item.id" :label="item.name" :value="item.id">
</el-option>
</el-select>
<label>售卖状态:</label>
<el-select v-model="status" placeholder="请选择" clearable>
<el-option v-for="item in statusArr" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-button type="primary" @click="pageQuery()">查询</el-button>
<div>
<el-button type="danger" @click="handleDelete('B')">批量删除</el-button>
<el-button type="info" @click="handleAdd">+ 新建套餐</el-button>
</div>
</div>
<el-table :data="records" stripe @selection-change="handleSelectionChange">
<el-table-column type="selection" />
<el-table-column prop="name" label="套餐名称" />
<el-table-column label="图片">
<template slot-scope="scope">
<el-image :src="scope.row.image"></el-image>
</template>
</el-table-column>
<el-table-column prop="categoryName" label="套餐分类" />
<el-table-column prop="price" label="套餐价"/>
<el-table-column label="售卖状态">
<template slot-scope="scope">
<div :class="{ 'stop-use': scope.row.status === 0 }">
{{ scope.row.status === 0 ? '停售' : '启售' }}
</div>
</template>
</el-table-column>
<el-table-column prop="updateTime" label="最后操作时间" />
<el-table-column label="操作">
<template slot-scope="scope">
<el-button type="text" size="small">修改</el-button>
<el-button type="text" size="small" @click="handleStartOrStop(scope.row)">{{ scope.row.status == '1' ? '停售' : '启售' }}</el-button>
<el-button type="text" size="small" @click="handleDelete('S',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="total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
</div>
</div>
</template>
<script lang="ts">
import { getCategoryByType } from '@/api/category'
import { getSetmealPage, enableOrDisableSetmeal, deleteSetmeal } from '@/api/setMeal'
export default {
data() {
return {
page: 1,
pageSize: 10,
name: '', // 套餐名称
status: '', // 售卖状态
categoryId: '', // 分类 id
total: 0,
records: [],
options: [],
statusArr: [ // 为售卖状态下拉框提供的数据
{ value: '1', label: '启售' },
{ value: '0', label: '停售' }
],
multipleSelection: [] // 当前被选中的行
}
},
created() {
// 查询套餐分类,用于填充查询页面的下拉框
getCategoryByType({ type: 2 })
.then((res) => {
if (res.data.code == 1) {
this.options = res.data.data
}
})
// 查询套餐分页数据
this.pageQuery()
},
methods: {
// 套餐分页查询
pageQuery() {
// 封装分页查询参数
const params = {
page: this.page,
pageSize: this.pageSize,
name: this.name,
status: this.status,
categoryId: this.categoryId
}
// 调用分页查询接口
getSetmealPage(params)
.then(res => {
if (res.data.code === 1) {
this.total = res.data.data.total
this.records = res.data.data.records
}
})
},
// 分页条的事件处理函数,pageSize 改变时会触发
handleSizeChange(pageSize) {
this.pageSize = pageSize
this.pageQuery()
},
// 分页条的事件处理函数,currentPage 改变时会触发
handleCurrentChange(page) {
this.page = page
this.pageQuery()
},
// 套餐起售、停售
handleStartOrStop(row) {
this.$confirm('确认调整该套餐的售卖状态?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
enableOrDisableSetmeal({ id: row.id, status: !row.status ? 1 : 0 })
.then((res) => {
if (res.status === 200) {
this.$message.success('套餐售卖状态更改成功!')
this.pageQuery()
}
})
.catch((err) => {
this.$message.error('请求出错了:' + err.message)
})
})
},
// 删除套餐
handleDelete(type: string, id: string) {
if (type === 'B' && this.multipleSelection.length == 0) {
this.$message('请选择需要删除的套餐!')
return
}
this.$confirm('确定删除该套餐?', '确定删除', {
confirmButtonText: '删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let param
// 判断当前是单个删除还是批量删除
if (type === 'S') {
// 单个删除
param = id
} else {
// 批量删除
const arr = new Array()
this.multipleSelection.forEach(element => {
// 将套餐 id 放入数组中
arr.push(element.id)
})
param = arr.join(',') // 将数组中的 id 拼接到一起,中间用逗号分隔
}
deleteSetmeal(param)
.then(res => {
if (res.data.code === 1) {
this.$message.success('删除成功!')
this.pageQuery()
} else {
this.$message.error(res.data.msg)
}
})
})
},
// 当选择项发生变化时会触发该事件
handleSelectionChange(val) {
this.multipleSelection = val
//alert(this.multipleSelection.length)
},
// 新增套餐,跳转到新增页面(组件)
handleAdd() {
this.$router.push('/setmeal/add')
}
}
}
</script>
<style lang="scss">
.el-table-column--selection .cell {
padding-left: 10px;
}
</style>
<style lang="scss" scoped>
.dashboard {
&-container {
margin: 30px;
.container {
background: #fff;
position: relative;
z-index: 1;
padding: 30px 28px;
border-radius: 4px;
.tableBar {
margin-bottom: 20px;
.tableLab {
float: right;
span {
cursor: pointer;
display: inline-block;
font-size: 14px;
padding: 0 20px;
color: $gray-2;
}
}
}
.tableBox {
width: 100%;
border: 1px solid $gray-5;
border-bottom: 0;
}
.pageList {
text-align: center;
margin-top: 30px;
}
// 查询黑色按钮样式
.normal-btn {
background: #333333;
color: white;
margin-left: 20px;
}
}
}
}
</style>
相关免费在线工具 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