feat: 完善会员和课程管理模块
This commit is contained in:
parent
103ce228f0
commit
7c1b021178
8 changed files with 580 additions and 6 deletions
12
src/App.vue
12
src/App.vue
|
|
@ -47,6 +47,12 @@ const activeMenu = computed(() => route.path)
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span>会员列表</span>
|
<span>会员列表</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
<el-menu-item index="/addmember">
|
||||||
|
<el-icon>
|
||||||
|
<Link />
|
||||||
|
</el-icon>
|
||||||
|
<span>会员新增</span>
|
||||||
|
</el-menu-item>
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
|
|
||||||
<el-sub-menu index="course">
|
<el-sub-menu index="course">
|
||||||
|
|
@ -62,6 +68,12 @@ const activeMenu = computed(() => route.path)
|
||||||
</el-icon>
|
</el-icon>
|
||||||
<span>课程列表</span>
|
<span>课程列表</span>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
|
<el-menu-item index="/addcourse">
|
||||||
|
<el-icon>
|
||||||
|
<Link />
|
||||||
|
</el-icon>
|
||||||
|
<span>课程新增</span>
|
||||||
|
</el-menu-item>
|
||||||
</el-sub-menu>
|
</el-sub-menu>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
|
|
|
||||||
46
src/mock/course.js
Normal file
46
src/mock/course.js
Normal file
|
|
@ -0,0 +1,46 @@
|
||||||
|
const list = [
|
||||||
|
{"id":1,"name":"瑜伽入门","coachName":"铁娃","price":199,"duration":"60分钟","status":"进行中","remark":"适合零基础学员"},
|
||||||
|
{"id":2,"name":"力量训练","coachName":"小明","price":299,"duration":"45分钟","status":"进行中","remark":"增肌塑形专用"},
|
||||||
|
{"id":3,"name":"有氧舞蹈","coachName":"李娜","price":159,"duration":"50分钟","status":"进行中","remark":"燃脂效果好"},
|
||||||
|
{"id":4,"name":"搏击操","coachName":"王强","price":259,"duration":"40分钟","status":"进行中","remark":"释放压力"},
|
||||||
|
{"id":5,"name":"普拉提","coachName":"刘芳","price":229,"duration":"55分钟","status":"进行中","remark":"改善体态"},
|
||||||
|
{"id":6,"name":"动感单车","coachName":"陈刚","price":179,"duration":"45分钟","status":"已结束","remark":"高强度有氧"},
|
||||||
|
{"id":7,"name":"游泳训练","coachName":"赵敏","price":349,"duration":"60分钟","status":"进行中","remark":"全身运动"},
|
||||||
|
{"id":8,"name":"拳击入门","coachName":"周涛","price":289,"duration":"50分钟","status":"进行中","remark":"防身健身两不误"},
|
||||||
|
{"id":9,"name":"形体塑造","coachName":"吴雪","price":199,"duration":"45分钟","status":"进行中","remark":"塑造完美身材"},
|
||||||
|
{"id":10,"name":"康复训练","coachName":"孙磊","price":399,"duration":"60分钟","status":"进行中","remark":"运动损伤恢复"},
|
||||||
|
{"id":11,"name":"舞蹈培训","coachName":"朱婷","price":249,"duration":"50分钟","status":"已结束","remark":"多种舞种"},
|
||||||
|
{"id":12,"name":"攀岩课程","coachName":"林浩","price":329,"duration":"90分钟","status":"进行中","remark":"挑战自我"},
|
||||||
|
{"id":13,"name":"空手道","coachName":"杨丽","price":279,"duration":"55分钟","status":"进行中","remark":"防身技能"},
|
||||||
|
{"id":14,"name":"肚皮舞","coachName":"黄勇","price":189,"duration":"45分钟","status":"进行中","remark":"女性专属"},
|
||||||
|
{"id":15,"name":"CrossFit","coachName":"徐静","price":359,"duration":"60分钟","status":"进行中","remark":"综合训练"}
|
||||||
|
]
|
||||||
|
|
||||||
|
export const getByPage = (query) => {
|
||||||
|
const { name, status, page, limit } = query
|
||||||
|
const result = list.filter(item => {
|
||||||
|
if (name && item.name.indexOf(name) === -1) return false
|
||||||
|
if (status && item.status !== status) return false
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
const start = (page - 1) * limit
|
||||||
|
return { total: result.length, data: result.slice(start, start + limit) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除课程
|
||||||
|
export const remove = (id) => {
|
||||||
|
const index = list.findIndex(item => item.id === id)
|
||||||
|
if (index > -1) {
|
||||||
|
list.splice(index, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增课程
|
||||||
|
export const add = (course) => {
|
||||||
|
const newCourse = {
|
||||||
|
id: list.length === 0 ? 1 : list[list.length - 1].id + 1,
|
||||||
|
...course,
|
||||||
|
status: "进行中"
|
||||||
|
}
|
||||||
|
list.push(newCourse)
|
||||||
|
}
|
||||||
57
src/mock/member.js
Normal file
57
src/mock/member.js
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
const list = [
|
||||||
|
{"id":1,"name":"张三","sex":1,"avatar":"","phone":"13800138001","remark":"年卡会员,喜欢瑜伽","expireDate":"2025-12-31"},
|
||||||
|
{"id":2,"name":"李四","sex":2,"avatar":"","phone":"13800138002","remark":"季卡会员,减脂塑形","expireDate":"2025-09-15"},
|
||||||
|
{"id":3,"name":"王五","sex":1,"avatar":"","phone":"13800138003","remark":"月卡会员,增肌训练","expireDate":"2025-08-01"},
|
||||||
|
{"id":4,"name":"赵六","sex":2,"avatar":"","phone":"13800138004","remark":"年卡会员,产后恢复","expireDate":null},
|
||||||
|
{"id":5,"name":"钱七","sex":1,"avatar":"","phone":"13800138005","remark":"次卡会员,游泳爱好者","expireDate":"2025-07-20"},
|
||||||
|
{"id":6,"name":"孙八","sex":2,"avatar":"","phone":"13800138006","remark":"年卡会员,搏击训练","expireDate":null},
|
||||||
|
{"id":7,"name":"周九","sex":1,"avatar":"","phone":"13800138007","remark":"季卡会员,普拉提","expireDate":"2025-10-10"},
|
||||||
|
{"id":8,"name":"吴十","sex":2,"avatar":"","phone":"13800138008","remark":"月卡会员,有氧舞蹈","expireDate":"2025-07-30"},
|
||||||
|
{"id":9,"name":"郑十一","sex":1,"avatar":"","phone":"13800138009","remark":"年卡会员,自由重量","expireDate":"2026-01-15"},
|
||||||
|
{"id":10,"name":"冯十二","sex":2,"avatar":"","phone":"13800138010","remark":"次卡会员,动感单车","expireDate":"2025-08-25"},
|
||||||
|
{"id":11,"name":"陈十三","sex":1,"avatar":"","phone":"13800138011","remark":"年卡会员,拳击训练","expireDate":null},
|
||||||
|
{"id":12,"name":"楚十四","sex":2,"avatar":"","phone":"13800138012","remark":"季卡会员,形体塑造","expireDate":"2025-11-30"},
|
||||||
|
{"id":13,"name":"魏十五","sex":1,"avatar":"","phone":"13800138013","remark":"月卡会员,康复训练","expireDate":"2025-07-25"},
|
||||||
|
{"id":14,"name":"蒋十六","sex":2,"avatar":"","phone":"13800138014","remark":"年卡会员,舞蹈培训","expireDate":"2026-02-28"},
|
||||||
|
{"id":15,"name":"沈十七","sex":1,"avatar":"","phone":"13800138015","remark":"次卡会员,攀岩爱好者","expireDate":"2025-09-05"},
|
||||||
|
{"id":16,"name":"韩十八","sex":2,"avatar":"","phone":"13800138016","remark":"季卡会员,有氧操","expireDate":"2025-12-01"},
|
||||||
|
{"id":17,"name":"杨十九","sex":1,"avatar":"","phone":"13800138017","remark":"年卡会员,力量训练","expireDate":null},
|
||||||
|
{"id":18,"name":"朱二十","sex":2,"avatar":"","phone":"13800138018","remark":"月卡会员,纤体瑜伽","expireDate":"2025-08-10"},
|
||||||
|
{"id":19,"name":"秦廿一","sex":1,"avatar":"","phone":"13800138019","remark":"年卡会员,CrossFit","expireDate":"2026-03-20"},
|
||||||
|
{"id":20,"name":"许廿二","sex":2,"avatar":"","phone":"13800138020","remark":"季卡会员,空中瑜伽","expireDate":"2025-10-25"}
|
||||||
|
]
|
||||||
|
|
||||||
|
export const getByPage = (query) => {
|
||||||
|
const { sex, name, page, limit, status } = query
|
||||||
|
const result = list.filter(item => {
|
||||||
|
if (sex && item.sex !== sex) return false
|
||||||
|
if (name && item.name.indexOf(name) === -1) return false
|
||||||
|
if (status == 2 && item.expireDate !== null) return false
|
||||||
|
if (status == 3 && item.expireDate === null) return false
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
const start = (page - 1) * limit
|
||||||
|
return { total: result.length, data: result.slice(start, start + limit) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注销
|
||||||
|
export const cancel = (id) => {
|
||||||
|
const target = list.find(item => item.id === id)
|
||||||
|
target.expireDate = new Date().toLocaleDateString()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 续费
|
||||||
|
export const renew = (id) => {
|
||||||
|
const target = list.find(item => item.id === id)
|
||||||
|
target.expireDate = null
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增会员
|
||||||
|
export const add = (member) => {
|
||||||
|
const newMember = {
|
||||||
|
id: list.length === 0 ? 1 : list[list.length - 1].id + 1,
|
||||||
|
...member,
|
||||||
|
expireDate: null
|
||||||
|
}
|
||||||
|
list.push(newMember)
|
||||||
|
}
|
||||||
|
|
@ -23,6 +23,14 @@ const router = createRouter({
|
||||||
path: '/addcoach',
|
path: '/addcoach',
|
||||||
component: ()=>import('../views/AddCoachView.vue'),
|
component: ()=>import('../views/AddCoachView.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/addmember',
|
||||||
|
component: ()=>import('../views/AddMemberView.vue'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/addcourse',
|
||||||
|
component: ()=>import('../views/AddCourseView.vue'),
|
||||||
|
},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
71
src/views/AddCourseView.vue
Normal file
71
src/views/AddCourseView.vue
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
<script setup>
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { reactive, ref } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { add } from '../mock/course.js'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const formRef = ref(null)
|
||||||
|
|
||||||
|
const course = reactive({
|
||||||
|
name: "",
|
||||||
|
coachName: "",
|
||||||
|
price: null,
|
||||||
|
duration: "",
|
||||||
|
remark: ""
|
||||||
|
})
|
||||||
|
const rules = {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: "课程名称不能为空", trigger: "blur" },
|
||||||
|
{ min: 2, max: 20, message: "课程名称长度 2-20", trigger: "blur" }
|
||||||
|
],
|
||||||
|
coachName: [
|
||||||
|
{ required: true, message: "授课教练不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
price: [
|
||||||
|
{ required: true, message: "价格不能为空", trigger: "blur" }
|
||||||
|
],
|
||||||
|
duration: [
|
||||||
|
{ required: true, message: "课程时长不能为空", trigger: "blur" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
const addHandler = async () => {
|
||||||
|
await formRef.value.validate()
|
||||||
|
add(course)
|
||||||
|
ElMessage({ type: "success", message: `课程 "${course.name}" 添加成功` })
|
||||||
|
router.replace("/course")
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-form label-width="100px" label-position="left" ref="formRef" :model="course" :rules="rules">
|
||||||
|
<h2 class="title">——新增课程——</h2>
|
||||||
|
<el-form-item label="课程名称" prop="name">
|
||||||
|
<el-input placeholder="请输入课程名称" v-model.trim="course.name"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="授课教练" prop="coachName">
|
||||||
|
<el-input placeholder="请输入教练姓名" v-model.trim="course.coachName"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="价格(元)" prop="price">
|
||||||
|
<el-input-number v-model="course.price" :min="0" :step="10"></el-input-number>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="课程时长" prop="duration">
|
||||||
|
<el-input placeholder="如:60分钟" v-model.trim="course.duration"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model.trim="course.remark" type="textarea" :rows="5" placeholder="请输入课程备注..."></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="addHandler">确定</el-button>
|
||||||
|
<el-button>取消</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.title {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: rgb(196, 86, 86);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
107
src/views/AddMemberView.vue
Normal file
107
src/views/AddMemberView.vue
Normal file
|
|
@ -0,0 +1,107 @@
|
||||||
|
<script setup>
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
import { reactive, ref } from 'vue'
|
||||||
|
import { useRouter } from 'vue-router'
|
||||||
|
import { add } from '../mock/member.js'
|
||||||
|
import { Plus } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const formRef = ref(null)
|
||||||
|
|
||||||
|
const member = reactive({
|
||||||
|
name: "",
|
||||||
|
sex: 1,
|
||||||
|
avatar: "",
|
||||||
|
phone: "",
|
||||||
|
remark: ""
|
||||||
|
})
|
||||||
|
const rules = {
|
||||||
|
name: [
|
||||||
|
{ required: true, message: "会员名字不能为空", trigger: "blur" },
|
||||||
|
{ min: 2, max: 20, message: "会员名字长度 2-20", trigger: "blur" }
|
||||||
|
],
|
||||||
|
phone: [
|
||||||
|
{ required: true, message: "手机号不能为空", trigger: "blur" },
|
||||||
|
{ pattern: /^1[3-9]\d{9}$/, message: "手机号格式不正确", trigger: "blur" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
const addHandler = async () => {
|
||||||
|
await formRef.value.validate()
|
||||||
|
add(member)
|
||||||
|
ElMessage({ type: "success", message: `会员 "${member.name}" 添加成功` })
|
||||||
|
router.replace("/member")
|
||||||
|
}
|
||||||
|
const uploadChangeHandler = (file, fileList) => {
|
||||||
|
if (fileList.length > 1) { fileList.shift() }
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.onload = e => {
|
||||||
|
member.avatar = e.target.result
|
||||||
|
}
|
||||||
|
reader.readAsDataURL(file.raw)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-form label-width="100px" label-position="left" ref="formRef" :model="member" :rules="rules">
|
||||||
|
<h2 class="title">——新增会员——</h2>
|
||||||
|
<el-form-item label="会员名字" prop="name">
|
||||||
|
<el-input placeholder="请输入.." v-model.trim="member.name"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="性别:">
|
||||||
|
<el-radio-group v-model="member.sex">
|
||||||
|
<el-radio :value="1">男</el-radio>
|
||||||
|
<el-radio :value="2">女</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="手机号" prop="phone">
|
||||||
|
<el-input placeholder="请输入手机号.." v-model.trim="member.phone"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="头像">
|
||||||
|
<el-upload class="avatar-uploader" action="" :auto-upload="false" list-type="picture-card"
|
||||||
|
:on-change="uploadChangeHandler">
|
||||||
|
<el-icon class="avatar-uploader-icon">
|
||||||
|
<Plus />
|
||||||
|
</el-icon>
|
||||||
|
<template #tip>
|
||||||
|
<div style="color: red;">提示:上传 300*300 的 png/jp(e)g 图片</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="备注">
|
||||||
|
<el-input v-model.trim="member.remark" type="textarea" :rows="5" placeholder="请输入会员备注..."></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="addHandler">确定</el-button>
|
||||||
|
<el-button>取消</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.title {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
color: rgb(196, 86, 86);
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-uploader .el-upload {
|
||||||
|
border: 1px dashed var(--el-border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: var(--el-transition-duration-fast);
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-uploader .el-upload:hover {
|
||||||
|
border-color: var(--el-color-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-icon.avatar-uploader-icon {
|
||||||
|
font-size: 28px;
|
||||||
|
color: #8c939d;
|
||||||
|
width: 178px;
|
||||||
|
height: 178px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,9 +1,127 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="page-text">这是课程列表页面</div>
|
<el-container>
|
||||||
|
<el-header>
|
||||||
|
<el-form :inline="true" @submit.prevent="submitHandler">
|
||||||
|
<el-form-item label="课程名:">
|
||||||
|
<el-input placeholder="请输入课程名" clearable v-model="queryModel.name" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="课程状态">
|
||||||
|
<el-select v-model="queryModel.status" style="width: 120px;" @change="submitHandler">
|
||||||
|
<el-option label="全部" :value="''"></el-option>
|
||||||
|
<el-option label="进行中" value="进行中"></el-option>
|
||||||
|
<el-option label="已结束" value="已结束"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="warning" native-type='submit' :icon="Search">查询</el-button>
|
||||||
|
<el-button type="primary" :icon="Plus" @click="$router.push('/addcourse')">新增</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-header>
|
||||||
|
<el-main>
|
||||||
|
<el-table border :data="courseList">
|
||||||
|
<el-table-column type="index" label="序号" width="60" align="center" :index="indexMethod"></el-table-column>
|
||||||
|
<el-table-column prop="name" label="课程名称" width="120" align="center"></el-table-column>
|
||||||
|
<el-table-column prop="coachName" label="授课教练" width="100" align="center"></el-table-column>
|
||||||
|
<el-table-column prop="price" label="价格(元)" width="100" align="center"></el-table-column>
|
||||||
|
<el-table-column prop="duration" label="时长" width="80" align="center"></el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="状态" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag type="success" v-if="scope.row.status === '进行中'">进行中</el-tag>
|
||||||
|
<el-tag type="info" v-else>已结束</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="备注" width="200">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-popover placement="right-start" :title="scope.row.name" :width="200" trigger="hover"
|
||||||
|
:content="scope.row.remark">
|
||||||
|
<template #reference>
|
||||||
|
<span class="remark">{{ scope.row.remark }}</span>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 操作 -->
|
||||||
|
<el-table-column label="操作" width="100">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button :icon="Delete" type="danger" size="small" @click="deleteHandler(scope.row)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-main>
|
||||||
|
<el-footer>
|
||||||
|
<el-pagination background :total="total" layout="prev, pager, next, jumper,->,total, sizes"
|
||||||
|
:page-sizes="[10, 20, 30, 40]" v-model:current-page="pageInfo.page" v-model:page-size="pageInfo.limit"
|
||||||
|
@size-change="query" @current-change="query" />
|
||||||
|
</el-footer>
|
||||||
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { getByPage, remove } from '@/mock/course';
|
||||||
|
import { Delete, Plus, Search } from '@element-plus/icons-vue';
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import { reactive, ref, onMounted, shallowRef } from 'vue';
|
||||||
|
|
||||||
|
const queryModel = reactive({
|
||||||
|
name: "",
|
||||||
|
status: ""
|
||||||
|
})
|
||||||
|
|
||||||
|
const pageInfo = reactive({
|
||||||
|
page: 1,
|
||||||
|
limit: 10
|
||||||
|
})
|
||||||
|
|
||||||
|
const total = ref(0)
|
||||||
|
const courseList = shallowRef<any[]>([])
|
||||||
|
|
||||||
|
const query = () => {
|
||||||
|
const response = getByPage({ ...queryModel, ...pageInfo })
|
||||||
|
total.value = response.total
|
||||||
|
courseList.value = response.data
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
query()
|
||||||
|
})
|
||||||
|
|
||||||
|
const submitHandler = () => {
|
||||||
|
pageInfo.page = 1;
|
||||||
|
query()
|
||||||
|
}
|
||||||
|
const indexMethod = (index: number) => {
|
||||||
|
return (pageInfo.page - 1) * pageInfo.limit + index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
const deleteHandler = (course: any) => {
|
||||||
|
ElMessageBox.confirm(`你确认要删除课程 "${course.name}" 吗?`, "警告", { type: "warning" })
|
||||||
|
.then(() => {
|
||||||
|
remove(course.id)
|
||||||
|
ElMessage({ type: 'success', message: `课程 "${course.name}" 删除成功!` })
|
||||||
|
query()
|
||||||
|
})
|
||||||
|
.catch(() => { })
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-text {
|
.remark {
|
||||||
line-height: 1;
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-header,
|
||||||
|
.el-footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,164 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="page-text">这是会员列表页面</div>
|
<el-container>
|
||||||
|
<el-header>
|
||||||
|
<el-form :inline="true" @submit.prevent="submitHandler">
|
||||||
|
<el-form-item label="会员名:">
|
||||||
|
<el-input placeholder="请输入姓名" clearable v-model="queryModel.name" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item label="会员性别">
|
||||||
|
<el-select v-model="queryModel.sex" style="width: 100px;" @change="submitHandler">
|
||||||
|
<el-option label="全部" :value="0"></el-option>
|
||||||
|
<el-option label="男" :value="1"></el-option>
|
||||||
|
<el-option label="女" :value="2"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="会员状态">
|
||||||
|
<el-select v-model="queryModel.status" style="width: 100px;" @change="submitHandler">
|
||||||
|
<el-option label="全部" :value="1"></el-option>
|
||||||
|
<el-option label="有效" :value="2"></el-option>
|
||||||
|
<el-option label="过期" :value="3"></el-option>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="warning" native-type='submit' :icon="Search">查询</el-button>
|
||||||
|
<el-button type="primary" :icon="Plus" @click="$router.push('/addmember')">新增</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-header>
|
||||||
|
<el-main>
|
||||||
|
<el-table border :data="memberList">
|
||||||
|
<el-table-column type="index" label="序号" width="60" align="center" :index="indexMethod"></el-table-column>
|
||||||
|
<el-table-column prop="name" label="会员名字" width="100" align="center"></el-table-column>
|
||||||
|
<el-table-column prop="sex" label="性别" width="80" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag type="primary" v-if="scope.row.sex === 1">男</el-tag>
|
||||||
|
<el-tag type="danger" v-else>女</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="phone" label="手机号" width="130" align="center"></el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="备注" width="200">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-popover placement="right-start" :title="scope.row.name" :width="200" trigger="hover"
|
||||||
|
:content="scope.row.remark">
|
||||||
|
<template #reference>
|
||||||
|
<span class="remark">{{ scope.row.remark }}</span>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="状态" width="200">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag type="success" v-if="scope.row.expireDate === null">有效</el-tag>
|
||||||
|
<el-tag type="info" v-else>过期:{{ scope.row.expireDate }}</el-tag>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<el-table-column label="头像" width="80">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-popover v-if="scope.row.avatar" placement="right-start" :title="scope.row.name" trigger="click">
|
||||||
|
<el-image :src="scope.row.avatar"></el-image>
|
||||||
|
<template #reference>
|
||||||
|
<el-button type="primary" link>查看</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popover>
|
||||||
|
<span v-else>暂无</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
|
||||||
|
<!-- 操作 -->
|
||||||
|
<el-table-column label="操作" width="120">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button :icon="Delete" type="danger" size="small" v-if="scope.row.expireDate"
|
||||||
|
@click="renewHandler(scope.row)">续费</el-button>
|
||||||
|
<el-button :icon="Mug" type="warning" size="small" v-else @click="cancelHandler(scope.row)">注销</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-main>
|
||||||
|
<el-footer>
|
||||||
|
<el-pagination background :total="total" layout="prev, pager, next, jumper,->,total, sizes"
|
||||||
|
:page-sizes="[10, 20, 30, 40]" v-model:current-page="pageInfo.page" v-model:page-size="pageInfo.limit"
|
||||||
|
@size-change="query" @current-change="query" />
|
||||||
|
</el-footer>
|
||||||
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { getByPage, cancel, renew } from '@/mock/member';
|
||||||
|
import { Delete, Mug, Plus, Search } from '@element-plus/icons-vue';
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
|
import { reactive, ref, onMounted, shallowRef } from 'vue';
|
||||||
|
|
||||||
|
const queryModel = reactive({
|
||||||
|
name: "",
|
||||||
|
sex: 0,
|
||||||
|
status: 1
|
||||||
|
})
|
||||||
|
|
||||||
|
const pageInfo = reactive({
|
||||||
|
page: 1,
|
||||||
|
limit: 10
|
||||||
|
})
|
||||||
|
|
||||||
|
const total = ref(0)
|
||||||
|
const memberList = shallowRef<any[]>([])
|
||||||
|
|
||||||
|
const query = () => {
|
||||||
|
const response = getByPage({ ...queryModel, ...pageInfo })
|
||||||
|
total.value = response.total
|
||||||
|
memberList.value = response.data
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
query()
|
||||||
|
})
|
||||||
|
|
||||||
|
const submitHandler = () => {
|
||||||
|
pageInfo.page = 1;
|
||||||
|
query()
|
||||||
|
}
|
||||||
|
const indexMethod = (index: number) => {
|
||||||
|
return (pageInfo.page - 1) * pageInfo.limit + index + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注销
|
||||||
|
const cancelHandler = (member: any) => {
|
||||||
|
ElMessageBox.confirm(`你确认要注销会员 "${member.name}" 吗?`, "警告", { type: "warning" })
|
||||||
|
.then(() => {
|
||||||
|
cancel(member.id)
|
||||||
|
ElMessage({ type: 'success', message: `会员 "${member.name}" 注销成功!` })
|
||||||
|
query()
|
||||||
|
})
|
||||||
|
.catch(() => { })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 续费
|
||||||
|
const renewHandler = (member: any) => {
|
||||||
|
ElMessageBox.confirm(`你确认要给会员 "${member.name}" 续费吗?`, "提示", { type: "info" })
|
||||||
|
.then(() => {
|
||||||
|
renew(member.id)
|
||||||
|
ElMessage({ type: 'success', message: `会员 "${member.name}" 续费成功!` })
|
||||||
|
query()
|
||||||
|
})
|
||||||
|
.catch(() => { })
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.page-text {
|
.remark {
|
||||||
line-height: 1;
|
cursor: pointer;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-header,
|
||||||
|
.el-footer {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue