- 替换开发环境API基础URL为本地服务地址 - 实现签名URL本地缓存机制,解决微信按URL缓存图片导致重复下载问题 - 添加缓存清理功能,包括过期清理和按需删除特定缓存项 - 集成阿里云OSS上传功能,支持直传减少服务器带宽占用 - 优化头像地址处理逻辑,统一使用签名缓存避免地址频繁变化 - 移除过时的OSS上传示例文件oss-upload.js - 更新课程页面实现跳转第三方小程序功能 - 调整打卡记录图片地址获取方式,统一使用新的签名缓存逻辑 - 优化图片上传流程,增加压缩处理和批量上传支持 - 完善认证模块中的缓存清理逻辑,切换账号时清除相关图片缓存 - 添加后端环境变量配置模板和代理文档说明
167 lines
5.7 KiB
JavaScript
167 lines
5.7 KiB
JavaScript
// 课程中心:全屏 web-view 加载线上课程列表
|
||
//
|
||
// 注意:课程页部署在 www.muguaclub.cn,与首页 H5 的 m.muguaclub.cn 是不同主机名,
|
||
// www 必须单独加入微信公众平台「开发设置 → 业务域名」并在该站点根目录放校验文件,
|
||
// 否则真机打开会白屏。
|
||
// 登录态:课程页本体是公开的,但产品要求「未登录不进课程页」——未登录时切到「我的」引导登录,
|
||
// 因此也不需要走 webview/redirect 换 cookie。
|
||
const auth = require('../../utils/auth');
|
||
|
||
const COURSE_URL = 'https://www.muguaclub.cn/courses/index.html';
|
||
|
||
// 「去上课」浮窗的目标小程序(第三方,appId 由业务方提供)。
|
||
// 只用 navigateToMiniProgram,不传 path → 落对方首页;若将来要直达某个页面,
|
||
// 在这里补 path: '/pages/xxx/xxx'(以 / 开头)。
|
||
// 白名单:app.json 的 navigateToMiniProgramAppIdList 已于 2020-04-24 取消(配置里若还留着反而报 appJSON 无效),
|
||
// 所以不需要任何平台/工程配置。但下面两条绕不过去:
|
||
// ① 必须由用户点击触发(基础库 2.3.0 起),所以在 onShow 里自动调会报
|
||
// `navigateToMiniProgram:fail can only be invoked by user TAP gesture`;
|
||
// ② 跳转前微信一定弹系统确认框,用户取消时 fail.errMsg 含 'cancel'。
|
||
const CLASS_MINI_APP_ID = 'wxa3589f1193170aa3';
|
||
|
||
Page({
|
||
data: {
|
||
webviewUrl: '',
|
||
webviewError: false,
|
||
errorMsg: '',
|
||
webviewKey: 0,
|
||
// 「去上课」浮窗是否已挂载。**故意不跟 web-view 同帧渲染**,见 _scheduleFloat
|
||
showFloat: false
|
||
},
|
||
|
||
_webviewKey: 0,
|
||
_redirecting: false,
|
||
_jumping: false,
|
||
_floatTimer: null,
|
||
|
||
onShow() {
|
||
this.ensureAccess();
|
||
},
|
||
|
||
// 未登录不进课程页,直接切到「我的」引导登录
|
||
ensureAccess() {
|
||
if (auth.getToken()) {
|
||
this.loadWebview();
|
||
return;
|
||
}
|
||
// token 可能还在 App.onLaunch 发起的登录流程里,复用同一个登录单例再判一次,避免冷启动误跳
|
||
return auth.ensureLogin()
|
||
.then((token) => {
|
||
if (token) {
|
||
this.loadWebview();
|
||
return;
|
||
}
|
||
this.denyAccess();
|
||
})
|
||
.catch(() => {
|
||
this.denyAccess();
|
||
});
|
||
},
|
||
|
||
// 清掉可能残留的 web-view(如退出登录后切回本 tab),再切到「我的」
|
||
denyAccess() {
|
||
clearTimeout(this._floatTimer);
|
||
if (this.data.webviewUrl || this.data.showFloat) {
|
||
this.setData({ webviewUrl: '', webviewError: false, errorMsg: '', showFloat: false });
|
||
}
|
||
if (this._redirecting) {
|
||
return;
|
||
}
|
||
this._redirecting = true;
|
||
wx.switchTab({
|
||
url: '/pages/profile/profile',
|
||
complete: () => {
|
||
this._redirecting = false;
|
||
}
|
||
});
|
||
},
|
||
|
||
loadWebview() {
|
||
// key 自增 + 时间戳:强制 web-view 销毁重建,避免切 tab 回来白屏或读到上一次的缓存
|
||
this._webviewKey += 1;
|
||
this.setData({
|
||
webviewUrl: COURSE_URL + '?_t=' + Date.now(),
|
||
webviewError: false,
|
||
errorMsg: '',
|
||
webviewKey: this._webviewKey,
|
||
// 与上面的字段合并成同一次 setData,别拆开发(同同步树连发会撞 recursive update)
|
||
showFloat: false
|
||
});
|
||
this._scheduleFloat();
|
||
},
|
||
|
||
// 延迟一拍再把浮窗插进去。
|
||
//
|
||
// 为什么不能跟 web-view 同帧渲染:原生组件按「后插入的盖住先插入的」决定层级,
|
||
// 而 web-view 每次 onShow 都因 key 自增被销毁重建 —— 同帧渲染时重建后的 web-view
|
||
// 反而压在浮窗上,**真机上是「浮窗不见了」**(安卓默认如此,iOS 多数机型不出现;
|
||
// 开发者工具里则是完全看不到覆盖效果,无论怎么改都只能真机验证)。
|
||
// 等 web-view 挂载完(250ms)再 setData,浮窗就成了后插入的那一个。
|
||
_scheduleFloat() {
|
||
clearTimeout(this._floatTimer);
|
||
this._floatTimer = setTimeout(() => {
|
||
// 定时器可能落在 webviewError / 已切走的场景里,必须再判一次
|
||
if (this.data.webviewUrl && !this.data.webviewError) {
|
||
this.setData({ showFloat: true });
|
||
}
|
||
}, 250);
|
||
},
|
||
|
||
onWebviewError(e) {
|
||
// 加载失败时把浮窗收掉(错误页上不叠浮窗),同时取消待触发的显示定时器
|
||
clearTimeout(this._floatTimer);
|
||
this.setData({
|
||
webviewError: true,
|
||
errorMsg: (e && e.detail && e.detail.errMsg) || '加载失败,请检查网络后重试',
|
||
showFloat: false
|
||
});
|
||
},
|
||
|
||
onRetry() {
|
||
clearTimeout(this._floatTimer);
|
||
this.setData({ webviewUrl: '', webviewError: false, errorMsg: '', showFloat: false });
|
||
setTimeout(() => {
|
||
this.loadWebview();
|
||
}, 60);
|
||
},
|
||
|
||
// ---- 去上课:跳转到第三方授课小程序 ----
|
||
onGoClass() {
|
||
// 防重入:连点会连续弹系统确认框。complete 里复位(跳转成功时本页被挂起,
|
||
// 用户从对方小程序返回会走 onShow → 重新加载课程页,这是本页既有行为,不在这里动)
|
||
if (this._jumping) {
|
||
return;
|
||
}
|
||
this._jumping = true;
|
||
wx.navigateToMiniProgram({
|
||
appId: CLASS_MINI_APP_ID,
|
||
fail: (err) => {
|
||
const msg = (err && err.errMsg) || '';
|
||
// 用户点了取消,不是错误
|
||
if (msg.indexOf('cancel') >= 0) {
|
||
return;
|
||
}
|
||
wx.showToast({ title: '打开失败,请稍后再试', icon: 'none' });
|
||
},
|
||
complete: () => {
|
||
this._jumping = false;
|
||
}
|
||
});
|
||
},
|
||
|
||
// ---- 分享 ----
|
||
onShareAppMessage() {
|
||
return {
|
||
title: '明缘云道场 · 全部课程',
|
||
path: '/pages/course/course'
|
||
};
|
||
},
|
||
|
||
onShareTimeline() {
|
||
return {
|
||
title: '明缘云道场 · 全部课程',
|
||
query: 'from=timeline'
|
||
};
|
||
}
|
||
});
|