/** * 营地业务逻辑模块 * 负责营地相关的业务操作 */ import { campApi } from '../../../config/camp_api.js'; import * as dataFetcher from './data-fetcher.js'; /** * 加入营地 * @param {Object} context - 页面上下文 */ export function joinCamp(context) { var campId = context.data.campId; if (!campId) return; wx.showLoading({ title: '加入中...' }); campApi.joinCamp(campId) .then(function (res) { wx.hideLoading(); if (res.success === true) { wx.showToast({ title: res.message || '加入成功', icon: 'success' }); context.setData({ hasJoined: true }); // 加入成功后,自动开启第一小节(购买第一小节) var courseList = context.data.courseList || []; if (!courseList || courseList.length === 0) { dataFetcher.fetchCampData(context, campId); return; } // 选择第一小节:优先按 section_number 升序,否则取数组第一个 var first = courseList.slice().sort(function(a,b){ var an = a.section_number || a.number || 0; var bn = b.section_number || b.number || 0; return an - bn; })[0]; var firstSectionId = first && (first.id || first.section_id || first.course_id); if (!firstSectionId) { dataFetcher.fetchCampData(context, campId); return; } // 自动开启第一小节 campApi.purchaseSection(campId, firstSectionId) .then(function(purRes){ if (purRes && (purRes.success === true || purRes.code === 200)) { wx.showToast({ title: purRes.message || '已开启第一小节', icon: 'success' }); } else { wx.showToast({ title: (purRes && purRes.message) || '开启第一小节失败', icon: 'none' }); } }) .finally(function(){ dataFetcher.fetchCampData(context, campId); }); } else { wx.showToast({ title: res.message || '加入失败', icon: 'none' }); } }) .catch(function (err) { wx.hideLoading(); wx.showToast({ title: '加入失败', icon: 'none' }); }); } /** * 检查并开启小节 * @param {Object} context - 页面上下文 * @param {String} sectionId - 小节ID * @param {Function} callback - 回调函数 * @param {Boolean} showPaymentModal - 是否显示支付提示弹窗 */ export function checkAndUnlockSection(context, sectionId, callback, showPaymentModal) { var campId = context.data.campId; var accessList = context.data.accessList || []; var courseList = context.data.courseList || []; if (showPaymentModal === undefined) { showPaymentModal = false; } if (!sectionId || !campId) { if (callback) callback(false); return Promise.resolve(false); } // 检查 section_id 是否在 accessList 中 var hasAccess = accessList.some(function (item) { return String(item.section_id) === String(sectionId); }); if (hasAccess) { if (callback) callback(true); return Promise.resolve(true); } // 查找小节信息 var section = courseList.find(function (item) { return String(item.id) === String(sectionId) || String(item.section_id) === String(sectionId) || String(item.course_id) === String(sectionId); }); if (!section) { if (callback) callback(false); return Promise.resolve(false); } // 先请求后端判断是否允许开启(上一小节是否完成等) return campApi.canUnlockSection(campId, sectionId) .then(function (res) { var ok = res && (res.success === true || res.code === 200); var canUnlock = ok && (res.can_unlock === true); var msg = (res && res.message) ? res.message : '请先完成上一小节'; if (!ok) { wx.showToast({ title: msg || '检查失败', icon: 'none' }); if (callback) callback(false); return false; } if (!canUnlock) { wx.showModal({ title: '提示', content: msg, showCancel: false, confirmText: '知道了' }); if (callback) callback(false); return false; } return true; }) .then(function (allowed) { if (allowed !== true) { return Promise.resolve(false); } var priceFen = section.price_fen || section.price || 0; var isPurchased = section.is_purchased || false; var needPayment = priceFen > 0 && !isPurchased; var sectionTitle = section.title || section.course_title || '小节'; if (needPayment) { if (showPaymentModal) { var priceYuan = (priceFen / 100).toFixed(2); wx.showModal({ title: '提示', content: '开启小节👉' + sectionTitle + '?\n需要支付' + priceYuan + '元', success: function (res) { if (res.confirm) { wx.showLoading({ title: '准备支付...' }); if (context.createOrderAndPay) { context.createOrderAndPay(sectionId, priceFen, section) .then(function (success) { wx.hideLoading(); if (success) { dataFetcher.fetchCampData(context, campId); if (callback) callback(true); return true; } else { if (callback) callback(false); return false; } }) .catch(function (err) { wx.hideLoading(); if (callback) callback(false); return false; }); } } else { if (callback) callback(false); } } }); return Promise.resolve(false); } else { if (callback) callback(false); return Promise.resolve(false); } } else { // 不需要支付,直接调用 purchaseSection wx.showLoading({ title: '开启中...' }); return campApi.purchaseSection(campId, sectionId) .then(function (res) { wx.hideLoading(); if (res && (res.success === true || res.code === 200)) { wx.showToast({ title: res.message || '已开启小节', icon: 'success' }); dataFetcher.fetchCampData(context, campId); if (callback) callback(true); return true; } else { wx.showToast({ title: (res && res.message) || '开启小节失败', icon: 'none' }); if (callback) callback(false); return false; } }) .catch(function (err) { wx.hideLoading(); wx.showToast({ title: '开启小节失败', icon: 'none' }); if (callback) callback(false); return false; }); } }); } /** * 切换章节展开/收起(仅做展开/收起,不触发支付、解锁等任何其他操作) * @param {Object} context - 页面上下文 * @param {Object} e - 事件对象 */ export function toggleSection(context, e) { var course = e.currentTarget.dataset.course; var index = e.currentTarget.dataset.index; var sections = context.data.sections; var isCurrentlyExpanded = sections[index] && sections[index].expanded; var willExpand = !isCurrentlyExpanded; var newSections = sections.slice(); newSections[index] = Object.assign({}, newSections[index], { expanded: willExpand }); context.setData({ sections: newSections }); } /** * 重启打卡营 * @param {Object} context - 页面上下文 */ export function restartCamp(context) { var campId = context.data.campId; wx.showModal({ title: '提示', content: "确认重启打卡营吗?\n 重启打卡营后将会清空所有答题记录,已购买的课程不会重复收费!", success: function (res) { if (res.confirm) { var allCompleted = context.data.courseList.every(function (item) { return item.is_completed; }); if (!allCompleted) { wx.showModal({ title: '提示', content: '完成所有小节课程后才能重启打卡营!!', showCancel: false, confirmText: '知道了', confirmColor: '#333' }); return; } var userId = wx.getStorageSync('wxuserid') || ''; wx.showLoading({ title: '重启中...' }); campApi.resetCampProgress(campId, userId, true).then(function (res) { wx.hideLoading(); if (res.success === true || res.code === 200) { wx.showToast({ title: res.message || '重启成功', icon: 'success' }); context.setData({ hasVideoPlayed: false, isAutoPlay: true, _isDataLoaded: false }); dataFetcher.fetchCampData(context, campId); } else { wx.showToast({ title: res.message || '重启失败', icon: 'none' }); } }) .catch(function (err) { wx.hideLoading(); wx.showToast({ title: '重启失败', icon: 'none' }); }); } } }); }