duidui_mini_program/pages/camp_task_subjective_question/index.js
2026-03-27 10:41:46 +08:00

558 lines
27 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import * as taskService from './modules/task-service.js';
import * as imageHandler from './modules/image-handler.js';
import { campApi } from '../../config/camp_api.js';
// 兼容formatDateTime 可能不存在,提供安全封装
function safeFormatDateTime(v) {
try {
if (typeof formatDateTime === 'function') return formatDateTime(v);
} catch (_) { }
return v || '';
}
// 格式化日期为 YYYY-MM-DD HH:mm:ss 格式
function formatDateTimeString(date) {
var d = date || new Date();
var year = d.getFullYear();
var month = String(d.getMonth() + 1).padStart(2, '0');
var day = String(d.getDate()).padStart(2, '0');
var hours = String(d.getHours()).padStart(2, '0');
var minutes = String(d.getMinutes()).padStart(2, '0');
var seconds = String(d.getSeconds()).padStart(2, '0');
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds;
}
import { formatDateTime } from '../../utils/util';
var app = getApp();
Page({
data: {
pdfUrl: '',
description: '',
fileName: '主观题试卷.pdf',
loading: true,
needReview: false,
reviewStatus: 'NOT_STARTED',
reviewTime: '',
reviewComment: '',
reviewImages: [],
submittedImages: [],
hasSubmitted: false,
allowResubmit: false,
tempImages: [],
taskId: null,
showPdfActionSheet: false,
statusText: '', // 状态文本:任务已完成、需要审核、等待审核、审核通过、已驳回
statusClass: '' // 状态样式类名
},
onLoad: function (options) {
var that = this;
// 从 URL 参数中获取数据
var campId = options.campId || '';
var courseId = options.courseId || '';
var taskId = options.taskId || '';
var taskTitle = options.taskTitle ? decodeURIComponent(options.taskTitle) : '主观题';
if (!taskId) {
wx.showToast({
title: '任务ID不存在',
icon: 'none'
});
return;
}
wx.setNavigationBarTitle({
title: taskTitle
});
that.setData({
campId: String(campId),
courseId: String(courseId),
taskId: String(taskId)
});
that.getTaskDetail();
},
getTaskDetail: function () {
var that = this;
var taskId = this.data.taskId;
taskService.getTaskDetail(taskId).then(function (taskData) {
console.log('taskData', taskData,taskId);
if (taskData) {
var needReview = taskData.needReview || false;
// 初始状态:还没有进度信息,根据 needReview 计算状态文本
var statusInfo = that.computeStatusText(needReview, 'NOT_STARTED', false);
that.setData({
pdfUrl: taskData.pdfUrl,
description: taskData.description || '',
needReview: needReview,
reviewStatus: taskData.reviewStatus,
loading: false,
statusText: statusInfo.text,
statusClass: statusInfo.class
});
}
}).finally(function () {
var userId = wx.getStorageSync('wxuserid');
if (userId && taskId) {
taskService.fetchProgressSilent(userId, taskId)
.then(function (progressRes) {
var progress = null;
if (progressRes && progressRes.success === true && progressRes.progress) {
progress = progressRes.progress;
} else if (progressRes && progressRes.code === 200 && progressRes.data) {
progress = progressRes.data;
}
if (progress) {
var hasImgs = Array.isArray(progress.answer_images) && progress.answer_images.length > 0;
var done = hasImgs || progress.is_completed === true || progress.is_completed === 1;
if (done) {
that.setData({ hasSubmitted: true });
}
that.handleTaskDetail(progress);
} else {
// 没有进度信息,根据 needReview 计算状态文本
var needReview = that.data.needReview;
var statusInfo = that.computeStatusText(needReview, 'NOT_STARTED', false);
that.setData({
hasSubmitted: false,
submittedImages: [],
reviewImages: [],
reviewStatus: 'NOT_STARTED',
reviewTime: '',
statusText: statusInfo.text,
statusClass: statusInfo.class
});
}
})
.catch(function () {
// 获取进度失败,根据 needReview 计算状态文本
var needReview = that.data.needReview;
var statusInfo = that.computeStatusText(needReview, 'NOT_STARTED', false);
that.setData({
hasSubmitted: false,
submittedImages: [],
reviewImages: [],
reviewStatus: 'NOT_STARTED',
reviewTime: '',
statusText: statusInfo.text,
statusClass: statusInfo.class
});
});
}
});
},
/**
* 计算状态文本和样式类
* @param {Boolean} needReview - 是否需要审核
* @param {String} reviewStatus - 审核状态
* @param {Boolean} hasProgress - 是否有进度信息
* @returns {Object} {text: String, class: String}
*/
computeStatusText: function (needReview, reviewStatus, hasProgress) {
var statusText = '';
var statusClass = '';
if (!needReview) {
// 不需要审核
if (hasProgress) {
statusText = '任务已完成';
statusClass = 'no-audit';
} else {
statusText = '不需要审核';
statusClass = 'no-audit';
}
} else {
// 需要审核
if (!hasProgress) {
// 没有进度信息
statusText = '需要审核';
statusClass = 'need-audit';
} else {
// 有进度信息,根据审核状态判断
var normalizedStatus = String(reviewStatus || '').toLowerCase();
if (normalizedStatus === 'approved' || normalizedStatus === 'review_status_approved') {
statusText = '审核通过';
statusClass = 'approved';
} else if (normalizedStatus === 'rejected' || normalizedStatus === 'review_status_rejected') {
statusText = '已驳回';
statusClass = 'need-audit';
} else if (normalizedStatus === 'pending' || normalizedStatus === 'review_status_pending') {
statusText = '等待审核';
statusClass = 'need-audit';
} else {
statusText = '需要审核';
statusClass = 'need-audit';
}
}
}
return {
text: statusText,
class: statusClass
};
},
handleTaskDetail: function (data) {
var that = this;
try {
// 解析已提交的图片(优先使用 answer_images 数组)
var submittedImages = [];
if (Array.isArray(data.answer_images)) {
submittedImages = data.answer_images;
} else if (typeof data.images === 'string') {
try { submittedImages = JSON.parse(data.images) || []; } catch (_) { submittedImages = []; }
}
// 解析批复图片可能是数组、JSON 字符串或空对象
var reviewImages = [];
if (Array.isArray(data.review_images)) {
reviewImages = data.review_images;
} else if (typeof data.review_images === 'string') {
try { reviewImages = JSON.parse(data.review_images) || []; } catch (_) { reviewImages = []; }
}
// 格式化时间(安全封装)
var reviewTime = safeFormatDateTime(data.review_time)
// 更新 needReview如果后端返回了该字段优先使用后端返回的值
var currentNeedReview = that.data.needReview;
if (data.need_review !== undefined) {
currentNeedReview = !!data.need_review;
}
var hasProgress = true; // 有进度数据
var reviewStatus = data.review_status || 'NOT_STARTED';
// 计算状态文本
var statusInfo = that.computeStatusText(currentNeedReview, reviewStatus, hasProgress);
var updateData = {
submittedImages: submittedImages,
hasSubmitted: (submittedImages.length > 0) || (data.is_completed === true || data.is_completed === 1),
reviewStatus: reviewStatus,
reviewTime: reviewTime,
reviewComment: data.review_comment || '',
reviewImages: reviewImages,
tempImages: [],
statusText: statusInfo.text,
statusClass: statusInfo.class
};
// 如果后端返回了 need_review 字段,使用后端返回的值(更准确)
if (data.need_review !== undefined) {
updateData.needReview = !!data.need_review;
}
this.setData(updateData);
console.log("reviewStatus", this.data.reviewStatus);
console.log("needReview", this.data.needReview);
console.log("statusText", this.data.statusText);
} catch (error) {
console.error('处理数据失败:', error);
}
},
chooseImage: function () {
var that = this;
var currentCount = this.data.tempImages.length;
imageHandler.chooseImage(6, currentCount).then(function (newImages) {
var tempImages = that.data.tempImages.concat(newImages);
that.setData({ tempImages: tempImages });
}).catch(function (err) {
console.error('选择图片失败:', err);
});
},
deleteImage: function (e) {
var index = e.currentTarget.dataset.index;
var tempImages = this.data.tempImages.slice();
tempImages.splice(index, 1);
this.setData({ tempImages: tempImages });
},
previewImage: function (e) {
var url = e.currentTarget.dataset.url;
var images = this.data.tempImages.length > 0 ?
this.data.tempImages :
this.data.submittedImages;
imageHandler.previewImage(url, images);
},
previewFeedbackImage: function (e) {
var current = e.currentTarget.dataset.url;
wx.previewImage({
current: current,
urls: this.data.feedbackImages
});
},
uploadImage: function (tempFilePath) {
return imageHandler.uploadImage(tempFilePath, this.data.taskId, 'subjective');
},
submitAnswer: function () {
var that = this;
if (this.data.tempImages.length === 0) {
wx.showToast({
title: '请上传答案图片',
icon: 'none'
});
return;
}
wx.showLoading({
title: '提交中...',
mask: true
});
var uploadedUrls = [];
var uploadPromises = this.data.tempImages.map(function (tempPath) {
return that.uploadImage(tempPath).then(function (imageUrl) {
uploadedUrls.push(imageUrl);
});
});
Promise.all(uploadPromises)
.then(function () {
var userId = String(wx.getStorageSync('wxuserid') || '');
var taskIdStr = String(that.data.taskId);
return taskService.submitAnswer(userId, taskIdStr, uploadedUrls);
})
.then(function (result) {
if ((result && result.code === 200) || (result && result.success === true)) {
wx.showToast({
title: '提交成功',
icon: 'success'
});
// 如果不需要审核,直接标记为完成(审核通过)
// 需要审核:设置为 pending等待审核
// 不需要审核:设置为 approved审核通过任务完成
// 注意后端返回的格式是小写pending, approved, rejected
var newReviewStatus = that.data.needReview ? 'pending' : 'approved';
// 计算状态文本(提交后有进度信息)
var statusInfo = that.computeStatusText(that.data.needReview, newReviewStatus, true);
that.setData({
hasSubmitted: true,
submittedImages: uploadedUrls,
tempImages: [],
reviewStatus: newReviewStatus,
statusText: statusInfo.text,
statusClass: statusInfo.class
});
// 如果不需要审核,重新获取进度信息以确保状态同步
// 后端应该已经将任务标记为完成,重新获取以确认
if (!that.data.needReview) {
var userId = wx.getStorageSync('wxuserid');
if (userId && that.data.taskId) {
// 延迟一小段时间,确保后端已更新
setTimeout(function () {
taskService.fetchProgressSilent(userId, that.data.taskId)
.then(function (progressRes) {
var progress = null;
if (progressRes && progressRes.success === true && progressRes.progress) {
progress = progressRes.progress;
} else if (progressRes && progressRes.code === 200 && progressRes.data) {
progress = progressRes.data;
}
if (progress) {
// 更新状态,确保与后端同步
that.handleTaskDetail(progress);
// 如果后端返回的状态是已完成且不需要审核,确保 reviewStatus 为 approved
if ((progress.is_completed === true || progress.is_completed === 1) && !that.data.needReview) {
that.setData({
reviewStatus: 'approved'
});
}
}
})
.catch(function (err) {
console.log('获取进度信息失败:', err);
});
}, 500);
}
}
} else {
throw new Error((result && (result.message || result.msg)) || '提交失败');
}
})
.catch(function (error) {
console.error('提交失败:', error);
wx.showToast({
title: error.message || '提交失败,请重试',
icon: 'none'
});
})
.finally(function () {
wx.hideLoading();
});
},
handlePdfTap: function () {
if (!this.data.pdfUrl) {
wx.showToast({
title: 'PDF文件不存在',
icon: 'none'
});
return;
}
wx.showActionSheet({
itemList: ['预览文件', '直接下载', '分享文件'],
success: (res) => {
var that = this;
if (res.tapIndex === 0) {
// 预览文件
wx.downloadFile({
url: that.data.pdfUrl,
success: function (res) {
if (res.statusCode === 200) {
wx.openDocument({
filePath: res.tempFilePath,
success: function () {
console.log('打开文档成功');
},
fail: function (error) {
console.error('打开文档失败:', error);
wx.showToast({
title: '打开文档失败',
icon: 'none'
});
}
});
}
},
fail: function (error) {
console.error('下载文件失败:', error);
wx.showToast({
title: '下载文件失败',
icon: 'none'
});
}
});
} else if (res.tapIndex === 1) {
// 直接下载
wx.downloadFile({
url: that.data.pdfUrl,
success: function (res) {
if (res.statusCode === 200) {
var fs = wx.getFileSystemManager();
fs.saveFile({
tempFilePath: res.tempFilePath,
success: function () {
wx.showToast({
title: '已保存到本地',
icon: 'success'
});
},
fail: function (err) {
console.error('保存失败:', err);
wx.showToast({
title: '保存失败',
icon: 'none'
});
}
});
}
},
fail: function (error) {
console.error('下载文件失败:', error);
wx.showToast({
title: '下载文件失败',
icon: 'none'
});
}
});
} else if (res.tapIndex === 2) {
// 分享文件
wx.downloadFile({
url: that.data.pdfUrl,
success: function (res) {
if (res.statusCode === 200) {
wx.shareFileMessage({
fileName: that.data.fileName,
filePath: res.tempFilePath,
success: () => {
console.log('分享文件成功');
},
fail: (error) => {
console.error('分享文件失败:', error);
wx.showToast({
title: '分享文件失败',
icon: 'none'
});
}
});
}
},
fail: (error) => {
console.error('下载文件失败:', error);
wx.showToast({
title: '下载文件失败',
icon: 'none'
});
}
});
}
}
});
},
handleResubmit() {
console.log('handleResubmit')
this.setData({
tempImages: [],
allowResubmit: true,
hasSubmitted: false,
submittedImages: []
});
},
previewReviewImage: function (e) {
const { url } = e.currentTarget.dataset;
const reviewImages = this.data.reviewImages;
if (!reviewImages || reviewImages.length === 0) {
console.error('找不到老师批复的图片');
return;
}
wx.previewImage({
urls: reviewImages,
current: url,
success: () => {
console.log('预览成功');
},
fail: (err) => {
console.error('预览失败:', err);
}
});
},
onShareAppMessage: function () {
const fileName = this.data.fileName || '主观题试卷.pdf';
return {
title: fileName,
path: `/pages/camp_task_subjective_question/index?campId=${this.data.campId}&courseId=${this.data.courseId}&taskId=${this.data.taskId}`,
imageUrl: this.data.pdfUrl
}
},
onShareTimeline: function () {
const fileName = this.data.fileName || '主观题试卷.pdf';
return {
title: fileName,
query: `campId=${this.data.campId}&courseId=${this.data.courseId}&taskId=${this.data.taskId}`,
imageUrl: this.data.pdfUrl
}
}
});