Skip to content

Commit 4fd9dfd

Browse files
committed
会员中心:会员管理 50%
1 parent a3f2a01 commit 4fd9dfd

File tree

3 files changed

+370
-0
lines changed

3 files changed

+370
-0
lines changed

src/api/member/user/index.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import request from '@/config/axios'
2+
3+
export interface UserVO {
4+
id: number
5+
mobile: string
6+
password: string
7+
status: number
8+
registerIp: string
9+
loginIp: string
10+
loginDate: Date
11+
nickname: string
12+
avatar: string
13+
name: string
14+
sex: number
15+
areaId: number
16+
birthday: Date
17+
mark: string
18+
createTime: Date
19+
}
20+
21+
// 查询会员用户列表
22+
export const getUserPage = async (params) => {
23+
return await request.get({ url: `/member/user/page`, params })
24+
}
25+
26+
// 查询会员用户详情
27+
export const getUser = async (id: number) => {
28+
return await request.get({ url: `/member/user/get?id=` + id })
29+
}
30+
31+
// 修改会员用户
32+
export const updateUser = async (data: UserVO) => {
33+
return await request.put({ url: `/member/user/update`, data })
34+
}

src/views/member/user/UserForm.vue

Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
<template>
2+
<Dialog :title="dialogTitle" v-model="dialogVisible">
3+
<el-form
4+
ref="formRef"
5+
:model="formData"
6+
:rules="formRules"
7+
label-width="100px"
8+
v-loading="formLoading"
9+
>
10+
<el-form-item label="手机号" prop="mobile">
11+
<el-input v-model="formData.mobile" placeholder="请输入手机号" />
12+
</el-form-item>
13+
<el-form-item label="状态" prop="status">
14+
<el-radio-group v-model="formData.status">
15+
<el-radio
16+
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
17+
:key="dict.value"
18+
:label="dict.value"
19+
>
20+
{{ dict.label }}
21+
</el-radio>
22+
</el-radio-group>
23+
</el-form-item>
24+
<el-form-item label="用户昵称" prop="nickname">
25+
<el-input v-model="formData.nickname" placeholder="请输入用户昵称" />
26+
</el-form-item>
27+
<el-form-item label="头像" prop="avatar">
28+
<el-input v-model="formData.avatar" placeholder="请输入头像" />
29+
</el-form-item>
30+
<el-form-item label="真实名字" prop="name">
31+
<el-input v-model="formData.name" placeholder="请输入真实名字" />
32+
</el-form-item>
33+
<el-form-item label="用户性别" prop="sex">
34+
<el-radio-group v-model="formData.sex">
35+
<el-radio
36+
v-for="dict in getIntDictOptions(DICT_TYPE.SYSTEM_USER_SEX)"
37+
:key="dict.value"
38+
:label="dict.value"
39+
>
40+
{{ dict.label }}
41+
</el-radio>
42+
</el-radio-group>
43+
</el-form-item>
44+
<el-form-item label="出生日期" prop="birthday">
45+
<el-date-picker
46+
v-model="formData.birthday"
47+
type="date"
48+
value-format="x"
49+
placeholder="选择出生日期"
50+
/>
51+
</el-form-item>
52+
<el-form-item label="所在地" prop="areaId">
53+
<el-input v-model="formData.areaId" placeholder="请输入所在地" />
54+
</el-form-item>
55+
<el-form-item label="会员备注" prop="mark">
56+
<el-input type="textarea" v-model="formData.mark" placeholder="请输入会员备注" />
57+
</el-form-item>
58+
</el-form>
59+
<template #footer>
60+
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
61+
<el-button @click="dialogVisible = false">取 消</el-button>
62+
</template>
63+
</Dialog>
64+
</template>
65+
<script setup lang="ts">
66+
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
67+
import * as UserApi from '@/api/member/user'
68+
69+
const { t } = useI18n() // 国际化
70+
const message = useMessage() // 消息弹窗
71+
72+
const dialogVisible = ref(false) // 弹窗的是否展示
73+
const dialogTitle = ref('') // 弹窗的标题
74+
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
75+
const formType = ref('') // 表单的类型:create - 新增;update - 修改
76+
const formData = ref({
77+
id: undefined,
78+
mobile: undefined,
79+
status: undefined,
80+
nickname: undefined,
81+
avatar: undefined,
82+
name: undefined,
83+
sex: undefined,
84+
areaId: undefined,
85+
birthday: undefined,
86+
mark: undefined
87+
})
88+
const formRules = reactive({
89+
mobile: [{ required: true, message: '手机号不能为空', trigger: 'blur' }],
90+
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
91+
})
92+
const formRef = ref() // 表单 Ref
93+
94+
/** 打开弹窗 */
95+
const open = async (type: string, id?: number) => {
96+
dialogVisible.value = true
97+
dialogTitle.value = t('action.' + type)
98+
formType.value = type
99+
resetForm()
100+
// 修改时,设置数据
101+
if (id) {
102+
formLoading.value = true
103+
try {
104+
formData.value = await UserApi.getUser(id)
105+
} finally {
106+
formLoading.value = false
107+
}
108+
}
109+
}
110+
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
111+
112+
/** 提交表单 */
113+
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
114+
const submitForm = async () => {
115+
// 校验表单
116+
if (!formRef) return
117+
const valid = await formRef.value.validate()
118+
if (!valid) return
119+
// 提交请求
120+
formLoading.value = true
121+
try {
122+
const data = formData.value as unknown as UserApi.UserVO
123+
if (formType.value === 'create') {
124+
// 说明:目前暂时没有新增操作。如果自己业务需要,可以进行扩展
125+
// await UserApi.createUser(data)
126+
message.success(t('common.createSuccess'))
127+
} else {
128+
await UserApi.updateUser(data)
129+
message.success(t('common.updateSuccess'))
130+
}
131+
dialogVisible.value = false
132+
// 发送操作成功的事件
133+
emit('success')
134+
} finally {
135+
formLoading.value = false
136+
}
137+
}
138+
139+
/** 重置表单 */
140+
const resetForm = () => {
141+
formData.value = {
142+
id: undefined,
143+
mobile: undefined,
144+
password: undefined,
145+
status: undefined,
146+
registerIp: undefined,
147+
loginIp: undefined,
148+
loginDate: undefined,
149+
nickname: undefined,
150+
avatar: undefined,
151+
name: undefined,
152+
sex: undefined,
153+
areaId: undefined,
154+
birthday: undefined,
155+
mark: undefined,
156+
createTime: undefined
157+
}
158+
formRef.value?.resetFields()
159+
}
160+
</script>

src/views/member/user/index.vue

Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
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="nickname">
12+
<el-input
13+
v-model="queryParams.nickname"
14+
placeholder="请输入用户昵称"
15+
clearable
16+
@keyup.enter="handleQuery"
17+
class="!w-240px"
18+
/>
19+
</el-form-item>
20+
<el-form-item label="手机号" prop="mobile">
21+
<el-input
22+
v-model="queryParams.mobile"
23+
placeholder="请输入手机号"
24+
clearable
25+
@keyup.enter="handleQuery"
26+
class="!w-240px"
27+
/>
28+
</el-form-item>
29+
<el-form-item label="注册时间" prop="createTime">
30+
<el-date-picker
31+
v-model="queryParams.createTime"
32+
value-format="YYYY-MM-DD HH:mm:ss"
33+
type="daterange"
34+
start-placeholder="开始日期"
35+
end-placeholder="结束日期"
36+
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
37+
class="!w-240px"
38+
/>
39+
</el-form-item>
40+
<el-form-item label="登录时间" prop="loginDate">
41+
<el-date-picker
42+
v-model="queryParams.loginDate"
43+
value-format="YYYY-MM-DD HH:mm:ss"
44+
type="daterange"
45+
start-placeholder="开始日期"
46+
end-placeholder="结束日期"
47+
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
48+
class="!w-240px"
49+
/>
50+
</el-form-item>
51+
<el-form-item>
52+
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
53+
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
54+
</el-form-item>
55+
</el-form>
56+
</ContentWrap>
57+
58+
<!-- 列表 -->
59+
<ContentWrap>
60+
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
61+
<el-table-column label="用户编号" align="center" prop="id" width="120px" />
62+
<el-table-column label="头像" align="center" prop="avatar" width="80px">
63+
<template #default="scope">
64+
<img :src="scope.row.avatar" style="width: 40px" />
65+
</template>
66+
</el-table-column>
67+
<el-table-column label="手机号" align="center" prop="mobile" width="120px" />
68+
<el-table-column label="昵称" align="center" prop="nickname" width="80px" />
69+
<!-- TODO 芋艿:待接入 -->
70+
<el-table-column label="等级" align="center" width="100px" />
71+
<el-table-column label="分组" align="center" width="100px" />
72+
<el-table-column label="积分" align="center" width="100px" />
73+
<el-table-column label="状态" align="center" prop="status" width="100px">
74+
<template #default="scope">
75+
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
76+
</template>
77+
</el-table-column>
78+
<el-table-column
79+
label="登录时间"
80+
align="center"
81+
prop="loginDate"
82+
:formatter="dateFormatter"
83+
width="180px"
84+
/>
85+
<el-table-column
86+
label="注册时间"
87+
align="center"
88+
prop="createTime"
89+
:formatter="dateFormatter"
90+
width="180px"
91+
/>
92+
<el-table-column label="操作" align="center">
93+
<template #default="scope">
94+
<el-button
95+
link
96+
type="primary"
97+
@click="openForm('update', scope.row.id)"
98+
v-hasPermi="['member:user:update']"
99+
>
100+
编辑
101+
</el-button>
102+
</template>
103+
</el-table-column>
104+
</el-table>
105+
<!-- 分页 -->
106+
<Pagination
107+
:total="total"
108+
v-model:page="queryParams.pageNo"
109+
v-model:limit="queryParams.pageSize"
110+
@pagination="getList"
111+
/>
112+
</ContentWrap>
113+
114+
<!-- 表单弹窗:添加/修改 -->
115+
<UserForm ref="formRef" @success="getList" />
116+
</template>
117+
<script setup lang="ts">
118+
import { dateFormatter } from '@/utils/formatTime'
119+
import * as UserApi from '@/api/member/user'
120+
import UserForm from './UserForm.vue'
121+
import { DICT_TYPE } from '@/utils/dict'
122+
123+
defineOptions({ name: 'MemberUser' })
124+
125+
const message = useMessage() // 消息弹窗
126+
const { t } = useI18n() // 国际化
127+
128+
const loading = ref(true) // 列表的加载中
129+
const total = ref(0) // 列表的总页数
130+
const list = ref([]) // 列表的数据
131+
const queryParams = reactive({
132+
pageNo: 1,
133+
pageSize: 10,
134+
nickname: null,
135+
mobile: null,
136+
loginDate: [],
137+
createTime: []
138+
})
139+
const queryFormRef = ref() // 搜索的表单
140+
const exportLoading = ref(false) // 导出的加载中
141+
142+
/** 查询列表 */
143+
const getList = async () => {
144+
loading.value = true
145+
try {
146+
const data = await UserApi.getUserPage(queryParams)
147+
list.value = data.list
148+
total.value = data.total
149+
} finally {
150+
loading.value = false
151+
}
152+
}
153+
154+
/** 搜索按钮操作 */
155+
const handleQuery = () => {
156+
queryParams.pageNo = 1
157+
getList()
158+
}
159+
160+
/** 重置按钮操作 */
161+
const resetQuery = () => {
162+
queryFormRef.value.resetFields()
163+
handleQuery()
164+
}
165+
166+
/** 添加/修改操作 */
167+
const formRef = ref()
168+
const openForm = (type: string, id?: number) => {
169+
formRef.value.open(type, id)
170+
}
171+
172+
/** 初始化 **/
173+
onMounted(() => {
174+
getList()
175+
})
176+
</script>

0 commit comments

Comments
 (0)