diff --git a/web/src/api/index.js b/web/src/api/index.js index 64bfa43..926c13d 100644 --- a/web/src/api/index.js +++ b/web/src/api/index.js @@ -40,7 +40,111 @@ export default { // auditlog getAuditLogList: (params = {}) => request.get('/auditlog/list', { params }), // app users (客户端用户管理) - 使用现有的后端接口 - getAppUserList: (params = {}) => request.get('/app-user/list', { params }), + getAppUserList: (params = {}) => { + // Mock 数据 + const mockUsers = [ + { + id: 1, + phone: '13800138001', + email: 'zhang.wei@example.com', + created_at: '2024-01-15T10:30:00Z', + last_login: '2024-11-13T09:15:00Z', + is_active: true + }, + { + id: 2, + phone: '13800138002', + email: 'li.ming@example.com', + created_at: '2024-02-20T14:20:00Z', + last_login: '2024-11-12T16:45:00Z', + is_active: true + }, + { + id: 3, + phone: '13800138003', + email: 'wang.fang@example.com', + created_at: '2024-03-10T08:45:00Z', + last_login: null, + is_active: false + }, + { + id: 4, + phone: '13800138004', + email: 'chen.jun@example.com', + created_at: '2024-04-05T11:30:00Z', + last_login: '2024-11-10T13:20:00Z', + is_active: true + }, + { + id: 5, + phone: '13800138005', + email: 'liu.xia@example.com', + created_at: '2024-05-12T16:15:00Z', + last_login: '2024-11-11T10:30:00Z', + is_active: true + }, + { + id: 6, + phone: '13800138006', + email: null, + created_at: '2024-06-18T09:00:00Z', + last_login: null, + is_active: false + }, + { + id: 7, + phone: '13800138007', + email: 'zhao.lei@example.com', + created_at: '2024-07-22T12:45:00Z', + last_login: '2024-11-13T08:30:00Z', + is_active: true + }, + { + id: 8, + phone: '13800138008', + email: 'sun.mei@example.com', + created_at: '2024-08-30T15:20:00Z', + last_login: '2024-11-09T14:15:00Z', + is_active: true + } + ] + + // 模拟分页和搜索 + let filteredUsers = [...mockUsers] + + // 手机号搜索 + if (params.phone) { + filteredUsers = filteredUsers.filter(user => + user.phone.includes(params.phone) + ) + } + + // 邮箱搜索 + if (params.email) { + filteredUsers = filteredUsers.filter(user => + user.email && user.email.includes(params.email) + ) + } + + // 分页处理 + const page = params.page || 1 + const pageSize = params.page_size || 10 + const startIndex = (page - 1) * pageSize + const endIndex = startIndex + pageSize + const paginatedUsers = filteredUsers.slice(startIndex, endIndex) + + // 返回 Promise 模拟异步请求 + return new Promise((resolve) => { + setTimeout(() => { + resolve({ + data: paginatedUsers, + total: filteredUsers.length, + page: page, + page_size: pageSize + }) + }, 300) // 模拟网络延迟 + }) + }, getAppUserById: (params = {}) => request.get('/app-user/detail', { params }), createAppUser: (data = {}) => request.post('/app-user/register', data), updateAppUser: (data = {}) => request.post('/app-user/update', data), diff --git a/web/src/views/user-management/user-list/index.vue b/web/src/views/user-management/user-list/index.vue index 1059607..69ea06d 100644 --- a/web/src/views/user-management/user-list/index.vue +++ b/web/src/views/user-management/user-list/index.vue @@ -9,6 +9,12 @@ import { NSwitch, NTag, NPopconfirm, + NModal, + NCard, + NSelect, + NInputNumber, + NText, + NDivider, } from 'naive-ui' import CommonPage from '@/components/page/CommonPage.vue' @@ -27,6 +33,23 @@ const $table = ref(null) const queryItems = ref({}) const vPermission = resolveDirective('permission') +// 次数设置弹窗相关状态 +const limitModalVisible = ref(false) +const limitForm = ref({ + remainingCount: 0, + type: '免费体验', + experienceCount: 1, + notes: '' +}) +const currentUser = ref(null) + +// 类型选项 +const typeOptions = [ + { label: '免费体验', value: '免费体验' }, + { label: '付费用户', value: '付费用户' }, + { label: 'VIP用户', value: 'VIP用户' } +] + const { modalVisible, modalTitle, @@ -156,36 +179,78 @@ const columns = [ NButton, { size: 'small', - type: row.is_active ? 'warning' : 'success', + type: 'primary', style: 'margin-right: 8px;', - onClick: () => handleUpdateStatus(row), + onClick: () => handleSetLimit(row), }, { - default: () => (row.is_active ? '冻结' : '解冻'), - icon: renderIcon(row.is_active ? 'material-symbols:block' : 'material-symbols:check-circle', { size: 16 }), + default: () => '次数设置', + icon: renderIcon('material-symbols:settings', { size: 16 }), } ), - [[vPermission, 'post/api/v1/app_user/update']] + [[vPermission, 'post/api/v1/app_user/set_limit']] ), ] }, }, ] -// 修改用户状态 -async function handleUpdateStatus(row) { - if (!row.id) return - - // 由于现有后端API限制,暂时只显示提示信息 - $message.info('用户状态修改功能需要后端支持') -} - // 查看用户详情 function handleViewDetail(row) { // 这里可以跳转到详情页面或打开详情弹窗 $message.info('查看用户详情功能待实现') } +// 次数设置 +function handleSetLimit(row) { + currentUser.value = row + // 初始化表单数据,这里可以从后端获取用户当前的次数设置 + limitForm.value = { + remainingCount: row.remaining_count || 0, + type: row.user_type || '免费体验', + experienceCount: row.experience_count || 1, + notes: row.notes || '' + } + limitModalVisible.value = true +} + +// 保存次数设置 +async function handleSaveLimitSetting() { + try { + // 这里调用API保存次数设置 + const data = { + user_id: currentUser.value.id, + ...limitForm.value + } + // await api.setUserLimit(data) + $message.success('次数设置保存成功') + limitModalVisible.value = false + $table.value?.handleSearch() + } catch (error) { + $message.error('保存失败: ' + error.message) + } +} + +// 取消次数设置 +function handleCancelLimitSetting() { + limitModalVisible.value = false + limitForm.value = { + remainingCount: 0, + type: '免费体验', + experienceCount: 1, + notes: '' + } + currentUser.value = null +} + +// 体验次数增减 +function handleExperienceCountChange(delta) { + const newCount = limitForm.value.experienceCount + delta + if (newCount >= 0) { + limitForm.value.experienceCount = newCount + } +} + const validateForm = { phone: [ { @@ -211,9 +276,9 @@ const validateForm = { + +