/** * 申论题任务服务模块 * 负责任务详情和进度相关的 API 调用 */ import { campApi } from '../../../config/camp_api.js'; import { questionApi } from '../../../config/question_api.js'; /** * 静默获取用户任务进度 * @param {String} userId - 用户ID * @param {String} taskId - 任务ID * @returns {Promise} 任务进度 */ export function fetchProgressSilent(userId, taskId) { // 使用 Fiber 后端的接口 return campApi.getProgressDetail(userId, taskId).then(function(res) { // 统一返回格式 if (res && res.success === true) { return res; } else if (res && res.code === 200) { return { success: true, progress: res.data || res.progress }; } return res; }).catch(function(err) { // 静默失败,返回 null return null; }); } /** * 获取任务详情 * @param {String} taskId - 任务ID * @returns {Promise} 任务详情 */ export function getTaskDetail(taskId) { return campApi.getTaskDetailById(taskId).then(function(taskDetail){ if (!taskDetail || taskDetail.success !== true || !taskDetail.task) { return null; } var task = taskDetail.task; // 接口返回的 content 和 condition 是直接对象,不是嵌套在 essay 中 var content = task.content || {}; var condition = task.condition || {}; // 兼容两种格式:直接在 content 中,或嵌套在 content.essay 中 var paperId = content.exam_id || content.paper_id || null; if (!paperId && content.essay) { paperId = content.essay.exam_id || content.essay.paper_id || null; } // 兼容两种格式:直接在 condition 中,或嵌套在 condition.essay 中 var needReview = !!condition.need_review; if (!needReview && condition.essay) { needReview = !!condition.essay.need_review; } return { paperId: paperId, needReview: needReview }; }); } /** * 获取试卷内容 * @param {String} paperId - 试卷ID * @returns {Promise} 试卷数据 */ export function fetchPaperData(paperId) { return questionApi.getPaperDetail(paperId).then(function(res){ if (!res || res.success !== true || !res.paper) { throw new Error('获取试卷内容失败'); } var paper = res.paper; var questions = paper.questions || []; var problems = questions.map(function(q) { return { problem_id: String(q.id), problem_content: q.content || q.title || '', title: q.title || '', type: q.type, material_id: q.material_id || null, // 保留题目关联的材料ID options: q.options || [], explanation: q.explanation || '', answer: q.answer || '', submittedImages: [], tempImages: [], totalImageCount: 0, allowResubmit: true, teacherFeedback: { comment: '', images: [], review_time: '' } }; }); // 提取 paper 级别的材料列表(与客观题页面保持一致) var materials = Array.isArray(paper.materials) ? paper.materials : []; return { problems: problems, materials: materials, title: paper.title || '作业详情' }; }); } /** * 提交答案(单题提交,保留用于兼容) * @param {String} userId - 用户ID * @param {String} taskId - 任务ID * @param {Array} answerImages - 答案图片URL数组 * @returns {Promise} 提交结果 */ export function submitAnswer(userId, taskId, answerImages) { const 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; }; var submitData = { user_id: String(userId), task_id: String(taskId), is_completed: true, completed_at: formatDateTimeString(new Date()), answer_images: answerImages }; return campApi.updateCampProgress(submitData); } /** * 申论题提交 / 暂存:按题目顺序提交答案图片;支持部分题目暂存(后端会与已有进度合并) * @param {String} userId - 用户ID * @param {String} taskId - 任务ID * @param {Array>} essayAnswerImages - 按题目顺序的答案图片数组,如 [ [url, url], [url], [] ],空题可为 [] * @param {Boolean} allFilled - 是否全部题目都已作答(用于设置 is_completed,不传则根据 essayAnswerImages 推断) * @returns {Promise} 提交结果 */ export function submitEssayAnswer(userId, taskId, essayAnswerImages, allFilled) { const 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; }; if (typeof allFilled !== 'boolean') { allFilled = (essayAnswerImages || []).every(function(arr) { return Array.isArray(arr) && arr.length > 0; }); } var submitData = { user_id: String(userId), task_id: String(taskId), is_completed: allFilled, completed_at: formatDateTimeString(new Date()), essay_answer_images: essayAnswerImages, essay_question_count: essayAnswerImages.length }; return campApi.updateCampProgress(submitData); }