duidui_mini_program/pages/camp_detail/modules/camp-service.js
2026-03-27 10:41:46 +08:00

310 lines
8.4 KiB
JavaScript
Raw Permalink 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 { 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'
});
});
}
}
});
}