Skip to content

Commit f1735a4

Browse files
committed
会员:增加会员等级增删改查
1 parent 76a63e0 commit f1735a4

File tree

3 files changed

+394
-0
lines changed

3 files changed

+394
-0
lines changed

src/api/member/level/index.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import request from '@/config/axios'
2+
3+
export interface LevelVO {
4+
id: number
5+
name: string
6+
experience: number
7+
value: number
8+
discount: number
9+
icon: string
10+
bgUrl: string
11+
status: number
12+
}
13+
14+
// 查询会员等级列表
15+
export const getLevelPage = async (params) => {
16+
return await request.get({ url: `/member/level/page`, params })
17+
}
18+
19+
// 查询会员等级详情
20+
export const getLevel = async (id: number) => {
21+
return await request.get({ url: `/member/level/get?id=` + id })
22+
}
23+
24+
// 新增会员等级
25+
export const createLevel = async (data: LevelVO) => {
26+
return await request.post({ url: `/member/level/create`, data })
27+
}
28+
29+
// 修改会员等级
30+
export const updateLevel = async (data: LevelVO) => {
31+
return await request.put({ url: `/member/level/update`, data })
32+
}
33+
34+
// 删除会员等级
35+
export const deleteLevel = async (id: number) => {
36+
return await request.delete({ url: `/member/level/delete?id=` + id })
37+
}

src/views/member/level/LevelForm.vue

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
<template>
2+
<Dialog :title="dialogTitle" v-model="dialogVisible" width="800">
3+
<el-form
4+
ref="formRef"
5+
:model="formData"
6+
:rules="formRules"
7+
label-width="110px"
8+
v-loading="formLoading"
9+
>
10+
<el-row>
11+
<el-col :span="12">
12+
<el-form-item label="等级名称" prop="name">
13+
<el-input v-model="formData.name" placeholder="请输入等级名称" class="!w-240px" />
14+
</el-form-item>
15+
</el-col>
16+
<el-col :span="12">
17+
<el-form-item label="等级" prop="level">
18+
<el-input-number
19+
v-model="formData.level"
20+
:min="0"
21+
:precision="0"
22+
placeholder="请输入等级"
23+
class="!w-240px"
24+
/>
25+
</el-form-item>
26+
</el-col>
27+
</el-row>
28+
<el-row>
29+
<el-col :span="12">
30+
<el-form-item label="升级经验" prop="experience">
31+
<el-input-number
32+
v-model="formData.experience"
33+
:min="0"
34+
:precision="0"
35+
placeholder="请输入升级经验"
36+
class="!w-240px"
37+
/>
38+
</el-form-item>
39+
</el-col>
40+
<el-col :span="12">
41+
<el-form-item label="享受折扣(%)" prop="discount">
42+
<el-input-number
43+
v-model="formData.discount"
44+
:min="0"
45+
:max="100"
46+
:precision="0"
47+
placeholder="请输入享受折扣"
48+
class="!w-240px"
49+
/>
50+
</el-form-item>
51+
</el-col>
52+
</el-row>
53+
<el-row>
54+
<el-col :span="12">
55+
<el-form-item label="等级图标">
56+
<UploadImg v-model="formData.icon" />
57+
</el-form-item>
58+
</el-col>
59+
<el-col :span="12">
60+
<el-form-item label="背景图">
61+
<UploadImg v-model="formData.backgroundUrl" />
62+
</el-form-item>
63+
</el-col>
64+
</el-row>
65+
<el-form-item label="状态" prop="status">
66+
<el-radio-group v-model="formData.status">
67+
<el-radio
68+
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
69+
:key="dict.value"
70+
:label="dict.value"
71+
>
72+
{{ dict.label }}
73+
</el-radio>
74+
</el-radio-group>
75+
</el-form-item>
76+
</el-form>
77+
<template #footer>
78+
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
79+
<el-button @click="dialogVisible = false">取 消</el-button>
80+
</template>
81+
</Dialog>
82+
</template>
83+
<script setup lang="ts">
84+
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
85+
import * as LevelApi from '@/api/member/level'
86+
import { CommonStatusEnum } from '@/utils/constants'
87+
88+
/** 会员等级表单 **/
89+
defineOptions({ name: 'MemberLevelForm' })
90+
91+
const { t } = useI18n() // 国际化
92+
const message = useMessage() // 消息弹窗
93+
94+
const dialogVisible = ref(false) // 弹窗的是否展示
95+
const dialogTitle = ref('') // 弹窗的标题
96+
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
97+
const formType = ref('') // 表单的类型:create - 新增;update - 修改
98+
const formData = ref({
99+
id: undefined,
100+
name: undefined,
101+
experience: undefined,
102+
level: undefined,
103+
discount: undefined,
104+
icon: undefined,
105+
backgroundUrl: undefined,
106+
status: CommonStatusEnum.ENABLE
107+
})
108+
const formRules = reactive({
109+
name: [{ required: true, message: '等级名称不能为空', trigger: 'blur' }],
110+
experience: [{ required: true, message: '升级经验不能为空', trigger: 'blur' }],
111+
level: [{ required: true, message: '等级不能为空', trigger: 'blur' }],
112+
discount: [{ required: true, message: '享受折扣不能为空', trigger: 'blur' }],
113+
status: [{ required: true, message: '状态不能为空', trigger: 'change' }]
114+
})
115+
const formRef = ref() // 表单 Ref
116+
117+
/** 打开弹窗 */
118+
const open = async (type: string, id?: number) => {
119+
dialogVisible.value = true
120+
dialogTitle.value = t('action.' + type)
121+
formType.value = type
122+
resetForm()
123+
// 修改时,设置数据
124+
if (id) {
125+
formLoading.value = true
126+
try {
127+
formData.value = await LevelApi.getLevel(id)
128+
} finally {
129+
formLoading.value = false
130+
}
131+
}
132+
}
133+
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
134+
135+
/** 提交表单 */
136+
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
137+
const submitForm = async () => {
138+
// 校验表单
139+
if (!formRef) return
140+
const valid = await formRef.value.validate()
141+
if (!valid) return
142+
// 提交请求
143+
formLoading.value = true
144+
try {
145+
const data = formData.value as unknown as LevelApi.LevelVO
146+
if (formType.value === 'create') {
147+
await LevelApi.createLevel(data)
148+
message.success(t('common.createSuccess'))
149+
} else {
150+
await LevelApi.updateLevel(data)
151+
message.success(t('common.updateSuccess'))
152+
}
153+
dialogVisible.value = false
154+
// 发送操作成功的事件
155+
emit('success')
156+
} finally {
157+
formLoading.value = false
158+
}
159+
}
160+
161+
/** 重置表单 */
162+
const resetForm = () => {
163+
formData.value = {
164+
id: undefined,
165+
name: undefined,
166+
experience: undefined,
167+
level: undefined,
168+
discount: undefined,
169+
icon: undefined,
170+
backgroundUrl: undefined,
171+
status: CommonStatusEnum.ENABLE
172+
}
173+
formRef.value?.resetFields()
174+
}
175+
</script>

src/views/member/level/index.vue

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
<template>
2+
<ContentWrap>
3+
<!-- 搜索工作栏 -->
4+
<el-form
5+
class="-mb-15px"
6+
:model="queryParams"
7+
ref="queryFormRef"
8+
:inline="true"
9+
label-width="68px"
10+
>
11+
<el-form-item label="等级名称" prop="name">
12+
<el-input
13+
v-model="queryParams.name"
14+
placeholder="请输入等级名称"
15+
clearable
16+
@keyup.enter="handleQuery"
17+
class="!w-240px"
18+
/>
19+
</el-form-item>
20+
<el-form-item label="状态" prop="status">
21+
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable class="!w-240px">
22+
<el-option
23+
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
24+
:key="dict.value"
25+
:label="dict.label"
26+
:value="dict.value"
27+
/>
28+
</el-select>
29+
</el-form-item>
30+
<el-form-item>
31+
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
32+
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
33+
<el-button type="primary" @click="openForm('create')" v-hasPermi="['member:level:create']">
34+
<Icon icon="ep:plus" class="mr-5px" /> 新增
35+
</el-button>
36+
</el-form-item>
37+
</el-form>
38+
</ContentWrap>
39+
40+
<!-- 列表 -->
41+
<ContentWrap>
42+
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
43+
<el-table-column label="编号" align="center" prop="id" min-width="60" />
44+
<el-table-column label="等级图标" align="center" prop="icon" min-width="80">
45+
<template #default="scope">
46+
<el-image
47+
:src="scope.row.icon"
48+
class="w-30px h-30px"
49+
:preview-src-list="[scope.row.icon]"
50+
/>
51+
</template>
52+
</el-table-column>
53+
<el-table-column label="等级背景图" align="center" prop="backgroundUrl" min-width="100">
54+
<template #default="scope">
55+
<el-image
56+
:src="scope.row.backgroundUrl"
57+
class="w-30px h-30px"
58+
:preview-src-list="[scope.row.backgroundUrl]"
59+
/>
60+
</template>
61+
</el-table-column>
62+
<el-table-column label="等级名称" align="center" prop="name" min-width="100" />
63+
<el-table-column label="等级" align="center" prop="level" min-width="60" />
64+
<el-table-column label="升级经验" align="center" prop="experience" min-width="80" />
65+
<el-table-column label="享受折扣(%)" align="center" prop="discount" min-width="110" />
66+
<el-table-column label="状态" align="center" prop="status" min-width="70">
67+
<template #default="scope">
68+
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
69+
</template>
70+
</el-table-column>
71+
<el-table-column
72+
label="创建时间"
73+
align="center"
74+
prop="createTime"
75+
:formatter="dateFormatter"
76+
min-width="170"
77+
/>
78+
<el-table-column label="操作" align="center" min-width="110px" fixed="right">
79+
<template #default="scope">
80+
<el-button
81+
link
82+
type="primary"
83+
@click="openForm('update', scope.row.id)"
84+
v-hasPermi="['member:level:update']"
85+
>
86+
编辑
87+
</el-button>
88+
<el-button
89+
link
90+
type="danger"
91+
@click="handleDelete(scope.row.id)"
92+
v-hasPermi="['member:level:delete']"
93+
>
94+
删除
95+
</el-button>
96+
</template>
97+
</el-table-column>
98+
</el-table>
99+
<!-- 分页 -->
100+
<Pagination
101+
:total="total"
102+
v-model:page="queryParams.pageNo"
103+
v-model:limit="queryParams.pageSize"
104+
@pagination="getList"
105+
/>
106+
</ContentWrap>
107+
108+
<!-- 表单弹窗:添加/修改 -->
109+
<LevelForm ref="formRef" @success="getList" />
110+
</template>
111+
112+
<script setup lang="ts">
113+
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
114+
import { dateFormatter } from '@/utils/formatTime'
115+
import * as LevelApi from '@/api/member/level'
116+
import LevelForm from './LevelForm.vue'
117+
118+
/** 会员等级管理 **/
119+
defineOptions({ name: 'MemberLevel' })
120+
121+
const message = useMessage() // 消息弹窗
122+
const { t } = useI18n() // 国际化
123+
124+
const loading = ref(true) // 列表的加载中
125+
const total = ref(0) // 列表的总页数
126+
const list = ref([]) // 列表的数据
127+
const queryParams = reactive({
128+
pageNo: 1,
129+
pageSize: 10,
130+
name: null,
131+
status: null
132+
})
133+
const queryFormRef = ref() // 搜索的表单
134+
135+
/** 查询列表 */
136+
const getList = async () => {
137+
loading.value = true
138+
try {
139+
const data = await LevelApi.getLevelPage(queryParams)
140+
list.value = data.list
141+
total.value = data.total
142+
} finally {
143+
loading.value = false
144+
}
145+
}
146+
147+
/** 搜索按钮操作 */
148+
const handleQuery = () => {
149+
queryParams.pageNo = 1
150+
getList()
151+
}
152+
153+
/** 重置按钮操作 */
154+
const resetQuery = () => {
155+
queryFormRef.value.resetFields()
156+
handleQuery()
157+
}
158+
159+
/** 添加/修改操作 */
160+
const formRef = ref()
161+
const openForm = (type: string, id?: number) => {
162+
formRef.value.open(type, id)
163+
}
164+
165+
/** 删除按钮操作 */
166+
const handleDelete = async (id: number) => {
167+
try {
168+
// 删除的二次确认
169+
await message.delConfirm()
170+
// 发起删除
171+
await LevelApi.deleteLevel(id)
172+
message.success(t('common.delSuccess'))
173+
// 刷新列表
174+
await getList()
175+
} catch {}
176+
}
177+
178+
/** 初始化 **/
179+
onMounted(() => {
180+
getList()
181+
})
182+
</script>

0 commit comments

Comments
 (0)