// pages/project/detail.js
|
const app = getApp()
|
|
Page({
|
data: {
|
projectId: '',
|
projectDetail: null,
|
ratingStats: null,
|
loading: true,
|
error: '',
|
statusText: '',
|
genderText: '',
|
educationText: ''
|
},
|
|
onLoad(options) {
|
if (options.id) {
|
this.setData({
|
projectId: options.id
|
})
|
this.loadProjectDetail()
|
} else {
|
this.setData({
|
error: '缺少项目ID参数',
|
loading: false
|
})
|
}
|
},
|
|
// 加载项目详情
|
async loadProjectDetail() {
|
try {
|
this.setData({
|
loading: true,
|
error: ''
|
})
|
|
// 调用API获取项目详情
|
const projectDetail = await this.getProjectDetailFromAPI(this.data.projectId)
|
|
if (projectDetail) {
|
// 处理文件大小显示
|
if (projectDetail.submissionFiles) {
|
projectDetail.submissionFiles.forEach(file => {
|
file.fileSizeText = this.formatFileSize(file.fileSize)
|
})
|
}
|
|
// 获取评分统计
|
const ratingStats = await this.getRatingStatsFromAPI(this.data.projectId)
|
|
// 处理评分时间显示
|
if (ratingStats && ratingStats.judgeRatings) {
|
ratingStats.judgeRatings.forEach(rating => {
|
if (rating.ratingTime) {
|
rating.ratingTimeText = this.formatDateTime(rating.ratingTime)
|
}
|
})
|
}
|
|
this.setData({
|
projectDetail,
|
ratingStats,
|
statusText: this.getStatusText(projectDetail.state),
|
genderText: this.getGenderText(projectDetail.playerInfo?.gender),
|
educationText: this.getEducationText(projectDetail.playerInfo?.education),
|
loading: false
|
})
|
} else {
|
throw new Error('项目详情获取失败')
|
}
|
} catch (error) {
|
console.error('加载项目详情失败:', error)
|
this.setData({
|
error: error.message || '加载失败,请重试',
|
loading: false
|
})
|
}
|
},
|
|
// 从API获取项目详情
|
async getProjectDetailFromAPI(projectId) {
|
// 构建GraphQL查询
|
const query = `
|
query GetProjectDetail($id: ID!) {
|
activityPlayerDetail(id: $id) {
|
id
|
activityId
|
playerId
|
playerName
|
playerGender
|
playerPhone
|
playerEducation
|
playerBirthDate
|
playerIdCard
|
playerAddress
|
projectName
|
projectDescription
|
projectCategory
|
projectTags
|
projectFiles {
|
id
|
fileName
|
fileUrl
|
fileSize
|
fileType
|
uploadTime
|
}
|
submitTime
|
reviewTime
|
reviewerId
|
reviewerName
|
score
|
rating {
|
id
|
judgeId
|
judgeName
|
score
|
feedback
|
ratingTime
|
}
|
state
|
feedback
|
}
|
}
|
`
|
|
try {
|
const result = await app.graphqlRequest(query, { id: projectId })
|
return result.activityPlayerDetail
|
} catch (error) {
|
throw error
|
}
|
},
|
|
// 获取评分统计
|
async getRatingStatsFromAPI(projectId) {
|
const query = `
|
query GetRatingStats($activityPlayerId: ID!) {
|
ratingStats(activityPlayerId: $activityPlayerId) {
|
averageScore
|
totalRatings
|
scoreDistribution {
|
score
|
count
|
}
|
}
|
}
|
`
|
|
try {
|
const result = await app.graphqlRequest(query, { activityPlayerId: projectId })
|
return result.ratingStats
|
} catch (error) {
|
throw error
|
}
|
},
|
|
// 获取评委评分详情
|
async getJudgeRatingDetail(activityPlayerId, judgeId) {
|
const query = `
|
query GetJudgeRatingDetail($activityPlayerId: ID!, $judgeId: ID!) {
|
judgeRatingDetail(activityPlayerId: $activityPlayerId, judgeId: $judgeId) {
|
remark
|
}
|
}
|
`
|
|
try {
|
const result = await app.graphqlRequest(query, { activityPlayerId, judgeId })
|
return result.judgeRatingDetail
|
} catch (error) {
|
throw error
|
}
|
},
|
|
// 预览文件
|
previewFile(e) {
|
const file = e.currentTarget.dataset.file
|
|
if (!file || !file.fullUrl) {
|
wx.showToast({
|
title: '文件链接无效',
|
icon: 'none'
|
})
|
return
|
}
|
|
// 根据文件类型进行不同处理
|
const fileExt = (file.fileExt || '').toLowerCase()
|
|
if (this.isImageFile(fileExt)) {
|
// 图片预览
|
wx.previewImage({
|
urls: [file.fullUrl],
|
current: file.fullUrl
|
})
|
} else if (this.isVideoFile(fileExt)) {
|
// 视频预览
|
wx.navigateTo({
|
url: `/pages/video/video?url=${encodeURIComponent(file.fullUrl)}&title=${encodeURIComponent(file.name)}`
|
})
|
} else if (this.isPdfFile(fileExt)) {
|
// PDF文档预览
|
this.previewPdfFile(file)
|
} else if (this.isOfficeFile(fileExt)) {
|
// Office文档预览
|
this.previewOfficeFile(file)
|
} else {
|
// 其他文件类型,尝试下载打开
|
this.downloadAndOpenFile(file)
|
}
|
},
|
|
// PDF文档预览
|
previewPdfFile(file) {
|
wx.showLoading({
|
title: '正在打开PDF...'
|
})
|
|
wx.downloadFile({
|
url: file.fullUrl,
|
success: (downloadRes) => {
|
wx.hideLoading()
|
if (downloadRes.statusCode === 200) {
|
wx.openDocument({
|
filePath: downloadRes.tempFilePath,
|
fileType: 'pdf',
|
success: () => {
|
console.log('PDF打开成功')
|
},
|
fail: (error) => {
|
console.error('PDF打开失败:', error)
|
wx.showToast({
|
title: 'PDF打开失败',
|
icon: 'none'
|
})
|
}
|
})
|
} else {
|
wx.showToast({
|
title: 'PDF下载失败',
|
icon: 'none'
|
})
|
}
|
},
|
fail: (error) => {
|
wx.hideLoading()
|
console.error('PDF下载失败:', error)
|
wx.showToast({
|
title: 'PDF下载失败',
|
icon: 'none'
|
})
|
}
|
})
|
},
|
|
// Office文档预览
|
previewOfficeFile(file) {
|
const fileExt = (file.fileExt || '').toLowerCase()
|
|
wx.showLoading({
|
title: '正在打开文档...',
|
mask: true
|
})
|
|
wx.downloadFile({
|
url: file.fullUrl,
|
success: (downloadRes) => {
|
wx.hideLoading()
|
if (downloadRes.statusCode === 200) {
|
// 文件类型映射
|
const fileTypeMap = {
|
'doc': 'doc',
|
'docx': 'docx',
|
'xls': 'xls',
|
'xlsx': 'xlsx',
|
'ppt': 'ppt',
|
'pptx': 'pptx'
|
}
|
|
wx.openDocument({
|
filePath: downloadRes.tempFilePath,
|
fileType: fileTypeMap[fileExt] || 'doc',
|
success: () => {
|
console.log('文档打开成功')
|
},
|
fail: (error) => {
|
console.error('文档打开失败:', error)
|
wx.showModal({
|
title: '打开失败',
|
content: '文档打开失败,可能是文件格式不支持或文件损坏',
|
showCancel: false,
|
confirmText: '确定'
|
})
|
}
|
})
|
} else {
|
wx.showToast({
|
title: '文件下载失败',
|
icon: 'none'
|
})
|
}
|
},
|
fail: (error) => {
|
wx.hideLoading()
|
console.error('文档下载失败:', error)
|
wx.showToast({
|
title: '文件下载失败',
|
icon: 'none'
|
})
|
}
|
})
|
},
|
|
// 下载并打开文件
|
downloadAndOpenFile(file) {
|
wx.showModal({
|
title: '文件预览',
|
content: '是否要下载并打开此文件?',
|
confirmText: '下载',
|
cancelText: '取消',
|
success: (res) => {
|
if (res.confirm) {
|
wx.showLoading({
|
title: '正在下载...'
|
})
|
|
wx.downloadFile({
|
url: file.fullUrl,
|
success: (downloadRes) => {
|
wx.hideLoading()
|
if (downloadRes.statusCode === 200) {
|
wx.openDocument({
|
filePath: downloadRes.tempFilePath,
|
success: () => {
|
console.log('文档打开成功')
|
},
|
fail: (error) => {
|
console.error('文档打开失败:', error)
|
wx.showToast({
|
title: '文件打开失败',
|
icon: 'none'
|
})
|
}
|
})
|
} else {
|
wx.showToast({
|
title: '文件下载失败',
|
icon: 'none'
|
})
|
}
|
},
|
fail: (error) => {
|
wx.hideLoading()
|
console.error('文件下载失败:', error)
|
wx.showToast({
|
title: '文件下载失败',
|
icon: 'none'
|
})
|
}
|
})
|
}
|
}
|
})
|
},
|
|
// 判断是否为图片文件
|
isImageFile(fileExt) {
|
const imageExts = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp']
|
return imageExts.includes(fileExt)
|
},
|
|
// 判断是否为视频文件
|
isVideoFile(fileExt) {
|
const videoExts = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'mkv', 'webm']
|
return videoExts.includes(fileExt)
|
},
|
|
// 判断是否为PDF文件
|
isPdfFile(fileExt) {
|
return fileExt === 'pdf'
|
},
|
|
// 判断是否为Office文件
|
isOfficeFile(fileExt) {
|
const officeExts = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'dotx', 'xlsb', 'xlsm', 'ppsx', 'pps', 'potx', 'ppsm']
|
return officeExts.includes(fileExt)
|
},
|
|
// 格式化文件大小
|
formatFileSize(bytes) {
|
if (!bytes || bytes === 0) return '0 B'
|
|
const k = 1024
|
const sizes = ['B', 'KB', 'MB', 'GB']
|
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
},
|
|
// 格式化日期时间
|
formatDateTime(dateTimeStr) {
|
if (!dateTimeStr) return ''
|
|
try {
|
const date = new Date(dateTimeStr)
|
const year = date.getFullYear()
|
const month = String(date.getMonth() + 1).padStart(2, '0')
|
const day = String(date.getDate()).padStart(2, '0')
|
const hours = String(date.getHours()).padStart(2, '0')
|
const minutes = String(date.getMinutes()).padStart(2, '0')
|
|
return `${year}-${month}-${day} ${hours}:${minutes}`
|
} catch (error) {
|
return dateTimeStr
|
}
|
},
|
|
// 获取状态文本
|
getStatusText(state) {
|
const statusMap = {
|
0: '未审核',
|
1: '审核通过',
|
2: '审核不通过'
|
}
|
return statusMap[state] || '未知状态'
|
},
|
|
// 获取性别文本
|
getGenderText(gender) {
|
const genderMap = {
|
'MALE': '男',
|
'FEMALE': '女'
|
}
|
return genderMap[gender] || ''
|
},
|
|
// 获取学历文本
|
getEducationText(education) {
|
const educationMap = {
|
'HIGH_SCHOOL': '高中及以下',
|
'COLLEGE': '大专',
|
'BACHELOR': '本科',
|
'MASTER': '硕士',
|
'DOCTOR': '博士'
|
}
|
return educationMap[education] || ''
|
},
|
|
// 分享功能
|
onShareAppMessage() {
|
return {
|
title: `项目详情 - ${this.data.projectDetail?.projectName || ''}`,
|
path: `/pages/project/detail?id=${this.data.projectId}`
|
}
|
}
|
})
|