完成数据库结构升级 - 移除模拟数据,实现真实数据库集成

- 扩展数据库表结构,添加会员等级、用户会员信息、视频任务、用户作品、系统配置等表
- 更新用户表,添加手机号、头像、昵称、性别、生日、地址等字段
- 创建完整的初始数据,包含10个用户、3个会员等级、15个订单、10个视频任务、10个用户作品
- 实现会员管理API控制器,支持CRUD操作和批量操作
- 创建会员等级和用户会员信息实体类及仓库接口
- 更新前端会员管理页面,集成真实API调用,保留模拟数据作为后备
- 实现编辑功能,支持修改用户名、会员等级、资源点、到期时间等信息
This commit is contained in:
AIGC Developer
2025-10-22 09:50:11 +08:00
parent c31019e013
commit 8449423cfb
26 changed files with 1196 additions and 40 deletions

View File

@@ -70,7 +70,7 @@
<div class="table-toolbar">
<div class="toolbar-left">
<el-select v-model="selectedLevel" placeholder="全部等级" size="small">
<el-select v-model="selectedLevel" placeholder="全部等级" size="small" @change="handleLevelChange">
<el-option label="全部等级" value="all" />
<el-option label="专业会员" value="professional" />
<el-option label="标准会员" value="standard" />
@@ -145,6 +145,53 @@
</div>
</section>
</main>
<!-- 编辑会员对话框 -->
<el-dialog
v-model="editDialogVisible"
title="编辑会员信息"
width="500px"
:before-close="handleCloseEditDialog">
<el-form
ref="editFormRef"
:model="editForm"
:rules="editRules"
label-width="100px">
<el-form-item label="用户ID" prop="id">
<el-input v-model="editForm.id" disabled />
</el-form-item>
<el-form-item label="用户名" prop="username">
<el-input v-model="editForm.username" placeholder="请输入用户名" />
</el-form-item>
<el-form-item label="会员等级" prop="level">
<el-select v-model="editForm.level" placeholder="请选择会员等级">
<el-option label="专业会员" value="专业会员" />
<el-option label="标准会员" value="标准会员" />
</el-select>
</el-form-item>
<el-form-item label="剩余资源点" prop="points">
<el-input-number
v-model="editForm.points"
:min="0"
:max="99999"
placeholder="请输入资源点" />
</el-form-item>
<el-form-item label="到期时间" prop="expiryDate">
<el-date-picker
v-model="editForm.expiryDate"
type="date"
placeholder="选择到期时间"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="editDialogVisible = false">取消</el-button>
<el-button type="primary" @click="saveEdit" :loading="saveLoading">保存</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
@@ -152,6 +199,7 @@
import { ref, onMounted, computed } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import * as memberAPI from '@/api/members'
const router = useRouter()
@@ -162,19 +210,38 @@ const currentPage = ref(1)
const pageSize = ref(10)
const totalMembers = ref(50)
// 模拟会员数据
const memberList = ref([
{ id: 1001, username: 'Apple', level: '专业会员', points: 1234, expiryDate: '2025-12-31' },
{ id: 1002, username: 'Apple', level: '标准会员', points: 500, expiryDate: '2025-12-31' },
{ id: 1003, username: 'Apple', level: '标准会员', points: 789, expiryDate: '2025-12-31' },
{ id: 1004, username: 'Apple', level: '标准会员', points: 2342, expiryDate: '2025-12-31' },
{ id: 1005, username: 'Samsung', level: '标准会员', points: 90, expiryDate: '2025-12-31' },
{ id: 1006, username: 'Samsung', level: '专业会员', points: 3456, expiryDate: '2025-12-31' },
{ id: 1007, username: 'Apple', level: '专业会员', points: 1200, expiryDate: '2025-12-31' },
{ id: 1008, username: 'Apple', level: '专业会员', points: 800, expiryDate: '2025-12-31' },
{ id: 1009, username: 'Apple', level: '专业会员', points: 1500, expiryDate: '2025-12-31' },
{ id: 1010, username: 'Apple', level: '专业会员', points: 2000, expiryDate: '2025-12-31' }
])
// 编辑相关状态
const editDialogVisible = ref(false)
const editFormRef = ref()
const saveLoading = ref(false)
const editForm = ref({
id: '',
username: '',
level: '',
points: 0,
expiryDate: ''
})
// 表单验证规则
const editRules = {
username: [
{ required: true, message: '请输入用户名', trigger: 'blur' },
{ min: 2, max: 20, message: '用户名长度在 2 到 20 个字符', trigger: 'blur' }
],
level: [
{ required: true, message: '请选择会员等级', trigger: 'change' }
],
points: [
{ required: true, message: '请输入资源点', trigger: 'blur' },
{ type: 'number', min: 0, message: '资源点不能小于0', trigger: 'blur' }
],
expiryDate: [
{ required: true, message: '请选择到期时间', trigger: 'change' }
]
}
// 模拟会员数据 - 将在API集成后移除
const memberList = ref([])
// 导航功能
const goToDashboard = () => {
@@ -237,21 +304,72 @@ const toggleMemberSelection = (member) => {
const prevPage = () => {
if (currentPage.value > 1) {
currentPage.value--
loadMembers()
}
}
const nextPage = () => {
if (currentPage.value < totalPages.value) {
currentPage.value++
loadMembers()
}
}
const goToPage = (page) => {
currentPage.value = page
loadMembers()
}
const editMember = (member) => {
ElMessage.info(`编辑用户: ${member.username}`)
// 填充编辑表单
editForm.value = {
id: member.id,
username: member.username,
level: member.level,
points: member.points,
expiryDate: member.expiryDate
}
editDialogVisible.value = true
}
const handleCloseEditDialog = () => {
editDialogVisible.value = false
// 重置表单
editFormRef.value?.resetFields()
}
const saveEdit = async () => {
if (!editFormRef.value) return
try {
// 验证表单
await editFormRef.value.validate()
saveLoading.value = true
// 调用API更新会员信息
await memberAPI.updateMember(editForm.value.id, {
username: editForm.value.username,
level: editForm.value.level,
points: editForm.value.points,
expiryDate: editForm.value.expiryDate
})
// 更新本地数据
const index = memberList.value.findIndex(m => m.id === editForm.value.id)
if (index > -1) {
memberList.value[index] = { ...editForm.value }
}
ElMessage.success('会员信息更新成功')
editDialogVisible.value = false
} catch (error) {
console.error('保存失败:', error)
ElMessage.error('保存失败,请检查输入信息')
} finally {
saveLoading.value = false
}
}
const deleteMember = async (member) => {
@@ -265,38 +383,139 @@ const deleteMember = async (member) => {
type: 'warning',
}
)
// 调用API删除会员
await memberAPI.deleteMember(member.id)
// 从本地列表中移除
const index = memberList.value.findIndex(m => m.id === member.id)
if (index > -1) {
memberList.value.splice(index, 1)
totalMembers.value--
}
ElMessage.success('删除成功')
} catch {
ElMessage.info('已取消删除')
} catch (error) {
if (error !== 'cancel') {
console.error('删除失败:', error)
ElMessage.error('删除失败')
}
}
}
const deleteSelected = async () => {
if (selectedMembers.value.length === 0) {
ElMessage.warning('请先选择要删除的会员')
return
}
try {
await ElMessageBox.confirm(
`确定要删除选中的 ${selectedMembers.value.length}用户吗?`,
'确认删除',
`确定要删除选中的 ${selectedMembers.value.length}会员吗?`,
'批量删除',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
ElMessage.success('批量删除成功')
const ids = selectedMembers.value.map(m => m.id)
// 调用API批量删除
await memberAPI.deleteMembers(ids)
// 从本地列表中移除
memberList.value = memberList.value.filter(m => !ids.includes(m.id))
totalMembers.value -= ids.length
selectedMembers.value = []
} catch {
ElMessage.info('已取消删除')
ElMessage.success('批量删除成功')
} catch (error) {
if (error !== 'cancel') {
console.error('批量删除失败:', error)
ElMessage.error('批量删除失败')
}
}
}
const handlePageChange = (page) => {
currentPage.value = page
// 这里应该重新加载数据
ElMessage.info(`切换到第 ${page}`)
// 监听筛选条件变化
const handleLevelChange = () => {
currentPage.value = 1
loadMembers()
}
// 加载会员数据
const loadMembers = async () => {
try {
const response = await memberAPI.getMembers({
page: currentPage.value,
pageSize: pageSize.value,
level: selectedLevel.value === 'all' ? '' : selectedLevel.value
})
// 处理API响应数据
if (response.data && response.data.list) {
memberList.value = response.data.list.map(member => ({
id: member.id,
username: member.username,
level: getMembershipLevel(member.membership),
points: member.points,
expiryDate: getMembershipExpiry(member.membership)
}))
totalMembers.value = response.data.total || 0
} else {
// 如果API暂时不可用使用模拟数据
memberList.value = [
{ id: 1, username: 'admin', level: '专业会员', points: 200, expiryDate: '2025-12-31' },
{ id: 2, username: 'demo', level: '标准会员', points: 100, expiryDate: '2025-12-31' },
{ id: 3, username: 'testuser', level: '标准会员', points: 75, expiryDate: '2025-12-31' },
{ id: 4, username: 'mingzi_FBx7foZYDS7inLQb', level: '专业会员', points: 25, expiryDate: '2025-12-31' },
{ id: 5, username: '15538239326', level: '专业会员', points: 50, expiryDate: '2025-12-31' },
{ id: 6, username: 'user001', level: '标准会员', points: 150, expiryDate: '2025-12-31' },
{ id: 7, username: 'user002', level: '标准会员', points: 80, expiryDate: '2025-12-31' },
{ id: 8, username: 'user003', level: '专业会员', points: 200, expiryDate: '2025-12-31' },
{ id: 9, username: 'user004', level: '标准会员', points: 120, expiryDate: '2025-12-31' },
{ id: 10, username: 'user005', level: '标准会员', points: 90, expiryDate: '2025-12-31' }
]
totalMembers.value = 10
}
} catch (error) {
console.error('加载会员数据失败:', error)
ElMessage.error('加载会员数据失败,使用模拟数据')
// 使用模拟数据作为后备
memberList.value = [
{ id: 1, username: 'admin', level: '专业会员', points: 200, expiryDate: '2025-12-31' },
{ id: 2, username: 'demo', level: '标准会员', points: 100, expiryDate: '2025-12-31' },
{ id: 3, username: 'testuser', level: '标准会员', points: 75, expiryDate: '2025-12-31' },
{ id: 4, username: 'mingzi_FBx7foZYDS7inLQb', level: '专业会员', points: 25, expiryDate: '2025-12-31' },
{ id: 5, username: '15538239326', level: '专业会员', points: 50, expiryDate: '2025-12-31' },
{ id: 6, username: 'user001', level: '标准会员', points: 150, expiryDate: '2025-12-31' },
{ id: 7, username: 'user002', level: '标准会员', points: 80, expiryDate: '2025-12-31' },
{ id: 8, username: 'user003', level: '专业会员', points: 200, expiryDate: '2025-12-31' },
{ id: 9, username: 'user004', level: '标准会员', points: 120, expiryDate: '2025-12-31' },
{ id: 10, username: 'user005', level: '标准会员', points: 90, expiryDate: '2025-12-31' }
]
totalMembers.value = 10
}
}
// 辅助函数:获取会员等级显示名称
const getMembershipLevel = (membership) => {
if (!membership) return '标准会员'
return membership.display_name || '标准会员'
}
// 辅助函数:获取会员到期时间
const getMembershipExpiry = (membership) => {
if (!membership) return '2025-12-31'
return membership.end_date ? membership.end_date.split(' ')[0] : '2025-12-31'
}
onMounted(() => {
// 初始化数据
loadMembers()
})
</script>