// pages/profile/profile.js const app = getApp() const { graphqlRequest, formatDate } = require('../../lib/utils') Page({ data: { userInfo: null, avatarText: '用', // 头像文字 loading: false, // 统计数据 stats: { totalRegistrations: 0, ongoingActivities: 0, completedActivities: 0, awards: 0 }, // 用户项目 userProjects: [], projectsLoading: false, // 角色相关 userRoles: [], isJudge: false, isOrganizer: false, hasPlayer: false, // 评委相关数据 judgeStats: { pendingReviews: 0, completedReviews: 0, studentUnReviewedCount: 0 }, // 主办方相关数据 organizerStats: { activeActivities: 0, totalParticipants: 0, totalActivities: 0 }, // 通用菜单项 menuItems: [ { icon: '📝', iconName: 'ic-list', title: '我的报名', desc: '查看报名记录', path: '/pages/profile/registrations' }, { icon: '🏆', iconName: 'ic-award', title: '我的成绩', desc: '查看活动成绩', path: '/pages/profile/achievements' }, { icon: '⭐', iconName: 'ic-star', title: '我的收藏', desc: '收藏的活动', path: '/pages/profile/favorites' }, { icon: '📊', iconName: 'ic-chart', title: '数据统计', desc: '个人数据分析', path: '/pages/profile/statistics' }, { icon: '⚙️', iconName: 'ic-setting', title: '设置', desc: '个人设置', path: '/pages/profile/settings' } ], // 评委菜单 judgeMenuItems: [ { icon: '📋', iconName: 'ic-list', title: '待评审', desc: '待评审的作品', path: '/pages/judge/pending', badge: 0 }, { icon: '✅', iconName: 'ic-choose', title: '已评审', desc: '已完成评审', path: '/pages/judge/completed' }, { icon: '📈', iconName: 'ic-chart', title: '评审统计', desc: '评审数据统计', path: '/pages/judge/statistics' } ], // 主办方菜单 organizerMenuItems: [ { icon: '🎯', iconName: 'ic-calendar', title: '活动管理', desc: '管理我的活动', path: '/pages/organizer/activities' }, { icon: '👥', iconName: 'ic-user', title: '参赛管理', desc: '管理参赛者', path: '/pages/organizer/participants' }, { icon: '📊', iconName: 'ic-chart', title: '数据分析', desc: '活动数据分析', path: '/pages/organizer/analytics' } ] }, onLoad() { // 从全局数据获取用户信息并设置头像文字 const globalUserInfo = app.globalData.userInfo if (globalUserInfo && globalUserInfo.name) { this.setData({ avatarText: globalUserInfo.name.substring(0, 1) }) } this.loadUserInfo() this.loadUserStats() this.loadUserProjects() }, onShow() { // 页面显示时刷新数据 this.loadUserInfo() this.loadUserStats() this.loadUserProjects() // 初始化自定义 tabbar if (typeof this.getTabBar === 'function' && this.getTabBar()) { this.getTabBar().init() } }, onPullDownRefresh() { this.refreshData() }, // 刷新数据 async refreshData() { this.setData({ loading: true }) try { await Promise.all([ this.loadUserInfo(), this.loadUserStats(), this.loadUserProjects() ]) } catch (error) { console.error('刷新数据失败:', error) } finally { this.setData({ loading: false }) wx.stopPullDownRefresh() } }, // 加载用户信息 async loadUserInfo() { try { this.setData({ loading: true }) const query = ` query GetUserProfile { userProfile { id name avatar phone email school major grade roles createdAt player { id name phone description } } } ` const result = await graphqlRequest(query) if (result && result.userProfile) { const userInfo = result.userProfile // 解析用户角色 const userRoles = userInfo.roles || [] const isJudge = userRoles.includes('JUDGE') const isOrganizer = userRoles.includes('ORGANIZER') const hasPlayer = userInfo.player && userInfo.player.id // 处理头像文字 const avatarText = (userInfo.name || '用户').substring(0, 1) this.setData({ userInfo, avatarText, userRoles, isJudge, isOrganizer, hasPlayer }) // 更新全局用户信息 app.globalData.userInfo = userInfo // 根据角色加载相应数据 if (isJudge) { this.loadJudgeStats() } if (isOrganizer) { this.loadOrganizerStats() } } } catch (error) { console.error('加载用户信息失败:', error) wx.showToast({ title: '加载失败', icon: 'error' }) } finally { this.setData({ loading: false }) } }, // 加载用户统计数据 async loadUserStats() { try { const query = ` query GetUserStats { userStats { totalRegistrations ongoingActivities completedActivities awards } } ` const result = await graphqlRequest(query) if (result && result.userStats) { this.setData({ stats: result.userStats }) } } catch (error) { console.error('加载统计数据失败:', error) } }, // 加载最近报名记录 // 加载用户项目 async loadUserProjects() { this.setData({ projectsLoading: true }) try { const query = ` query GetMyProjects { myProjects { id projectName activityName status statusText createTime submissionFiles { id name path fullUrl fullThumbUrl fileExt mediaType } } } ` const result = await graphqlRequest(query) if (result && result.myProjects) { const projects = result.myProjects.map(project => { // 获取项目的第一个媒体文件作为缩略图 let thumbnailUrl = '' let iconClass = this.getProjectIcon(project.status) if (project.submissionFiles && project.submissionFiles.length > 0) { const firstFile = project.submissionFiles[0] // 根据文件类型设置缩略图和图标 if (firstFile.mediaType === 'IMAGE') { thumbnailUrl = firstFile.fullThumbUrl || firstFile.fullUrl iconClass = 'ic-image' } else if (firstFile.mediaType === 'VIDEO') { thumbnailUrl = firstFile.fullThumbUrl || firstFile.fullUrl iconClass = 'ic-video' } else if (firstFile.fileExt && firstFile.fileExt.toLowerCase() === 'pdf') { iconClass = 'ic-pdf' } else if (firstFile.fileExt && ['doc', 'docx'].includes(firstFile.fileExt.toLowerCase())) { iconClass = 'ic-word' } else { iconClass = 'ic-file' } } return { id: project.id, projectName: project.projectName, activityName: project.activityName, state: project.status, statusText: project.statusText || this.getProjectStatusText(project.status), statusType: this.getProjectStatusType(project.status), icon: iconClass, thumbnailUrl: thumbnailUrl, createTime: project.createTime } }) this.setData({ userProjects: projects }) } } catch (error) { console.error('加载用户项目失败:', error) // 不显示错误提示,静默失败 } finally { this.setData({ projectsLoading: false }) } }, // 加载评委统计数据 async loadJudgeStats() { try { const query = ` query GetReviewStatistics { reviewStatistics { unReviewedCount reviewedCount studentUnReviewedCount } } ` const result = await graphqlRequest(query) if (result && result.reviewStatistics) { const stats = result.reviewStatistics // 转换字段名以匹配现有的数据结构 const judgeStats = { pendingReviews: stats.unReviewedCount, completedReviews: stats.reviewedCount, studentUnReviewedCount: stats.studentUnReviewedCount } this.setData({ judgeStats, 'judgeMenuItems[0].badge': judgeStats.pendingReviews }) } } catch (error) { console.error('加载评委统计失败:', error) } }, // 加载主办方统计数据 async loadOrganizerStats() { try { const query = ` query GetOrganizerStats { organizerStats { activeActivities totalParticipants totalActivities } } ` const result = await graphqlRequest(query) if (result && result.organizerStats) { this.setData({ organizerStats: result.organizerStats }) } } catch (error) { console.error('加载主办方统计失败:', error) } }, // 编辑个人信息 onEditProfile() { wx.navigateTo({ url: '/pages/profile/edit' }) }, // 跳转到个人信息页面 goToPersonalInfo() { wx.navigateTo({ url: '/pages/profile/personal-info' }) }, // 跳转到项目详情页面 goToProjectDetail(e) { const projectId = e.currentTarget.dataset.projectId if (!projectId) { wx.showToast({ title: '项目ID无效', icon: 'none' }) return } // 如果是示例数据,显示提示 if (projectId === 'registrations' || projectId === 'achievements') { wx.showToast({ title: '这是示例项目,请选择真实项目', icon: 'none' }) return } wx.navigateTo({ url: `/pages/project/detail?id=${projectId}` }) }, // 跳转到评审页面 goToReviewPage() { wx.navigateTo({ url: '/pages/review/index' }) }, // 查看报名详情 onRegistrationTap(e) { const { id } = e.currentTarget.dataset wx.navigateTo({ url: `/pages/profile/registration-detail?id=${id}` }) }, // 查看活动详情 onActivityTap(e) { const { id } = e.currentTarget.dataset wx.navigateTo({ url: `/pages/activity/detail?id=${id}` }) }, // 查看更多报名记录 onViewMoreRegistrations() { wx.navigateTo({ url: '/pages/profile/registrations' }) }, // 获取状态文本 getStatusText(status) { const statusMap = { 'PENDING': '待审核', 'APPROVED': '已通过', 'REJECTED': '已拒绝', 'CANCELLED': '已取消' } return statusMap[status] || status }, // 获取状态样式类 getStatusClass(status) { const classMap = { 'PENDING': 'status-pending', 'APPROVED': 'status-approved', 'REJECTED': 'status-rejected', 'CANCELLED': 'status-cancelled' } return classMap[status] || '' }, // 获取活动状态文本 getActivityStatusText(status) { const statusMap = { 'UPCOMING': '即将开始', 'ONGOING': '进行中', 'COMPLETED': '已结束', 'CANCELLED': '已取消' } return statusMap[status] || status }, // 格式化日期 formatDate(dateString) { return formatDate(dateString, 'MM-DD HH:mm') }, // 获取项目状态文本(支持数字和字符串状态) getProjectStatusText(status) { // 数字状态映射(与web端保持一致) const numericStatusMap = { 0: '未审核', 1: '审核通过', 2: '审核驳回', 3: '已结束' } // 字符串状态映射 const stringStatusMap = { 'SUBMITTED': '已提交', 'UNDER_REVIEW': '评审中', 'REVIEWED': '已评审', 'REJECTED': '已拒绝', 'DRAFT': '草稿' } // 优先使用数字状态映射 if (typeof status === 'number' && numericStatusMap[status]) { return numericStatusMap[status] } return stringStatusMap[status] || '未知状态' }, // 获取项目状态类型(用于样式) getProjectStatusType(status) { // 数字状态类型映射(与web端保持一致) const numericTypeMap = { 0: 'warning', // 未审核 1: 'success', // 审核通过 2: 'danger', // 审核驳回 3: 'info' // 已结束 } // 字符串状态类型映射 const stringTypeMap = { 'SUBMITTED': 'primary', 'UNDER_REVIEW': 'warning', 'REVIEWED': 'success', 'REJECTED': 'danger', 'DRAFT': 'info' } // 优先使用数字状态映射 if (typeof status === 'number' && numericTypeMap[status]) { return numericTypeMap[status] } return stringTypeMap[status] || 'info' }, // 获取项目图标 getProjectIcon(status) { // 数字状态图标映射 const numericIconMap = { 0: '⏳', // 未审核 1: '✅', // 审核通过 2: '❌', // 审核驳回 3: '📋' // 已结束 } // 字符串状态图标映射 const stringIconMap = { 'SUBMITTED': '📋', 'UNDER_REVIEW': '⏳', 'REVIEWED': '✅', 'REJECTED': '❌', 'DRAFT': '📝' } // 优先使用数字状态映射 if (typeof status === 'number' && numericIconMap[status]) { return numericIconMap[status] } return stringIconMap[status] || '📋' }, // 分享页面 onShareAppMessage() { return { title: '蓉易创 - 我的个人中心', path: '/pages/index/index' } } })