# 会员管理模块 - 前端详细设计 --- | 文档信息 | 内容 | |---------|------| | **文档版本** | V1.0 | | **模块名称** | 会员管理模块 - 前端 | | **编写团队** | pangu | | **创建日期** | 2026-01-31 | --- ## 1. 设计概述 ### 1.1 技术选型 | 技术 | 版本 | 说明 | |-----|------|------| | Vue | 3.5.26 | 前端框架 | | Element Plus | 2.13.2 | UI组件库 | | Pinia | 3.0.4 | 状态管理 | | Vue Router | 4.6.4 | 路由管理 | | Axios | 1.13.4 | HTTP客户端 | | Vite | 7.3.1 | 构建工具 | ### 1.2 目录结构 ``` frontend/src/ ├── api/ │ └── member.js # 会员API接口 ├── views/ │ └── member/ │ ├── index.vue # 会员列表页 │ ├── form.vue # 会员新增/编辑页 │ └── components/ │ ├── MemberSearch.vue # 搜索表单组件 │ ├── MemberTable.vue # 数据表格组件 │ ├── StudentBindDialog.vue # 学生绑定弹窗 │ └── PasswordDialog.vue # 密码显示弹窗 ├── store/ │ └── modules/ │ └── member.js # 会员状态管理 └── utils/ └── member.js # 会员相关工具函数 ``` --- ## 2. 路由配置 ### 2.1 路由定义 ```javascript // router/index.js { path: '/member', component: Layout, redirect: '/member/list', name: 'Member', meta: { title: '会员管理', icon: 'peoples' }, children: [ { path: 'list', name: 'MemberList', component: () => import('@/views/member/index.vue'), meta: { title: '会员列表', activeMenu: '/member' } }, { path: 'add', name: 'MemberAdd', component: () => import('@/views/member/form.vue'), meta: { title: '新增会员', activeMenu: '/member' }, hidden: true }, { path: 'edit/:id', name: 'MemberEdit', component: () => import('@/views/member/form.vue'), meta: { title: '编辑会员', activeMenu: '/member' }, hidden: true } ] } ``` --- ## 3. API接口层 ### 3.1 接口定义(member.js) ```javascript /** * 会员管理API接口 * @author pangu */ import request from '@/utils/request' // 查询会员列表 export function listMember(query) { return request({ url: '/member/list', method: 'get', params: query }) } // 获取会员详情 export function getMember(id) { return request({ url: `/member/${id}`, method: 'get' }) } // 新增会员 export function addMember(data) { return request({ url: '/member', method: 'post', data }) } // 修改会员 export function updateMember(data) { return request({ url: '/member', method: 'put', data }) } // 删除会员 export function deleteMember(id) { return request({ url: `/member/${id}`, method: 'delete' }) } // 重置会员密码 export function resetMemberPwd(id) { return request({ url: `/member/resetPwd/${id}`, method: 'put' }) } // 修改会员状态 export function changeMemberStatus(id, status) { return request({ url: '/member/changeStatus', method: 'put', data: { memberId: id, status } }) } // 绑定学生 export function bindStudent(memberId, studentId) { return request({ url: '/member/bindStudent', method: 'post', data: { memberId, studentId } }) } // 解绑学生 export function unbindStudent(memberId, studentId) { return request({ url: `/member/unbindStudent/${memberId}/${studentId}`, method: 'delete' }) } // 获取区域树 export function getRegionTree() { return request({ url: '/region/tree', method: 'get' }) } // 获取学校列表(根据区域) export function getSchoolListByRegion(regionId) { return request({ url: '/school/listByRegion', method: 'get', params: { regionId } }) } // 获取年级列表(根据学校) export function getGradeListBySchool(schoolId) { return request({ url: '/school/gradeList', method: 'get', params: { schoolId } }) } // 获取班级列表(根据学校年级) export function getClassListByGrade(schoolGradeId) { return request({ url: '/school/classList', method: 'get', params: { schoolGradeId } }) } // 获取可绑定的学生列表 export function getBindableStudents(query) { return request({ url: '/student/bindableList', method: 'get', params: query }) } ``` --- ## 4. 页面组件设计 ### 4.1 会员列表页(index.vue) #### 4.1.1 完整代码 ```vue ``` ### 4.2 会员编辑页(form.vue) #### 4.2.1 完整代码 ```vue ``` ### 4.3 学生绑定弹窗(StudentBindDialog.vue) ```vue ``` --- ## 5. 工具函数 ### 5.1 会员相关工具(utils/member.js) ```javascript /** * 会员管理相关工具函数 * @author pangu */ /** * 手机号脱敏 * @param {string} phone 手机号 * @returns {string} 脱敏后的手机号 */ export function maskPhone(phone) { if (!phone || phone.length !== 11) return phone return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2') } /** * 性别格式化 * @param {string} gender 性别代码 * @returns {string} 性别文字 */ export function formatGender(gender) { const map = { '0': '未知', '1': '男', '2': '女' } return map[gender] || '未知' } /** * 身份类型格式化 * @param {string} type 身份类型代码 * @returns {string} 身份类型文字 */ export function formatIdentityType(type) { return type === '1' ? '家长' : '教师' } /** * 注册来源格式化 * @param {string} source 注册来源代码 * @returns {string} 注册来源文字 */ export function formatRegisterSource(source) { const map = { '1': '小程序', '2': 'H5', '3': '后台新增', '4': '批量导入' } return map[source] || '-' } /** * 复制文本到剪贴板 * @param {string} text 要复制的文本 * @returns {Promise} 是否成功 */ export async function copyToClipboard(text) { try { await navigator.clipboard.writeText(text) return true } catch (error) { console.error('复制失败:', error) return false } } /** * 生成默认昵称 * @param {string} phone 手机号 * @returns {string} 默认昵称 */ export function generateNickname(phone) { if (!phone || phone.length < 4) return '用户' return `用户${phone.slice(-4)}` } /** * 验证手机号格式 * @param {string} phone 手机号 * @returns {boolean} 是否有效 */ export function validatePhone(phone) { return /^1[3-9]\d{9}$/.test(phone) } ``` --- ## 6. Mock数据更新 如果需要在开发阶段使用Mock数据,更新 `mock/member.js` 以匹配新的接口格式。 --- ## 7. 注意事项 ### 7.1 开发注意事项 1. **手机号脱敏**:列表页显示脱敏手机号,编辑页显示完整手机号 2. **身份类型切换**:切换身份类型时需清空或显示相关字段 3. **级联选择器**:区域-学校-年级-班级需要逐级加载 4. **学生绑定规则**:教师只能绑定本校学生,家长可绑定任意学生 5. **密码复制**:使用 Clipboard API,需要处理兼容性 ### 7.2 性能优化 1. **列表分页**:使用后端分页,避免大数据量渲染 2. **区域树缓存**:区域树数据可缓存到 Pinia Store 3. **防抖处理**:搜索输入可添加防抖 4. **懒加载**:级联数据使用懒加载方式 ### 7.3 用户体验 1. **加载状态**:所有异步操作显示 loading 状态 2. **操作确认**:删除、解绑等操作需要二次确认 3. **表单验证**:即时验证,提交前完整校验 4. **错误提示**:友好的错误提示信息 --- *文档结束*