310 lines
8.4 KiB
JavaScript
310 lines
8.4 KiB
JavaScript
/**
|
||
* 营地业务逻辑模块
|
||
* 负责营地相关的业务操作
|
||
*/
|
||
|
||
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'
|
||
});
|
||
});
|
||
}
|
||
}
|
||
});
|
||
}
|
||
|