Files
mp-xieyingeng/assets/scripts/utils/WxSDK.ts
richarjiang 69c0986996 feat: 进入关卡时 toast 提示体力消耗,修复 StorageManager 接口位置和 WxSDK 访问级别
- 进入关卡成功后显示 toast 提示消耗体力及剩余体力
- 将 StorageManager 中 UserInfo 接口移至模块顶层,修复嵌套接口语法问题
- WxSDK.getWx() 改为 static 公开方法,便于外部调用
2026-04-10 10:10:19 +08:00

450 lines
14 KiB
TypeScript
Raw 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 { sys } from 'cc';
/**
* 微信分享配置
*/
export interface WxShareConfig {
/** 分享标题 */
title: string;
/** 分享图片 URL 或本地路径 */
imageUrl?: string;
/** 查询字符串,从这条转发消息进入后,可通过 wx.getLaunchOptionsSync 或 wx.onShow 获取 */
query?: string;
}
/**
* 微信朋友圈分享配置
*/
export interface WxShareTimelineConfig {
/** 分享标题 */
title: string;
/** 分享图片 URL 或本地路径 */
imageUrl?: string;
/** 查询字符串 */
query?: string;
}
/**
* 微信小游戏 SDK 工具类
* 封装微信平台相关 API非微信环境下静默降级
*/
export class WxSDK {
/**
* 是否处于微信小游戏环境
*/
static isWechat(): boolean {
return sys.platform === sys.Platform.WECHAT_GAME;
}
/**
* 获取 wx 全局对象(仅微信环境下可用)
*/
static getWx(): any {
if (!WxSDK.isWechat()) return null;
return typeof wx !== 'undefined' ? wx : null;
}
// ==================== 登录相关 ====================
/**
* 微信登录,获取临时 code
* @returns Promise<string> 登录 code
*/
static login(): Promise<string> {
return new Promise((resolve, reject) => {
const wxApi = WxSDK.getWx();
if (!wxApi) {
reject(new Error('非微信环境,无法调用 wx.login'));
return;
}
wxApi.login({
success: (res: any) => {
if (res.code) {
console.log('[WxSDK] wx.login 成功,获取到 code');
resolve(res.code);
} else {
console.error('[WxSDK] wx.login 失败:', res.errMsg);
reject(new Error(res.errMsg || 'wx.login 失败'));
}
},
fail: (err: any) => {
console.error('[WxSDK] wx.login 调用失败:', err);
reject(new Error(err.errMsg || 'wx.login 调用失败'));
}
});
});
}
// ==================== 分享相关 ====================
/**
* 开启转发/分享菜单
* 调用后用户可通过右上角菜单进行转发
* @param withShareTicket 是否带 shareTicket用于获取群信息
*/
static showShareMenu(withShareTicket: boolean = true): void {
const wxApi = WxSDK.getWx();
if (!wxApi) return;
wxApi.showShareMenu({
withShareTicket,
menus: ['shareAppMessage', 'shareTimeline'],
success: () => {
console.log('[WxSDK] showShareMenu 成功');
},
fail: (err: any) => {
console.warn('[WxSDK] showShareMenu 失败', err);
}
});
}
/**
* 设置被动分享(右上角菜单 "转发给朋友")的内容
* 需要在页面加载后尽早调用,只需调用一次
* @param config 分享配置
*/
static onShareAppMessage(config: WxShareConfig): void {
const wxApi = WxSDK.getWx();
if (!wxApi) return;
wxApi.onShareAppMessage(() => ({
title: config.title,
imageUrl: config.imageUrl ?? '',
query: config.query ?? ''
}));
console.log('[WxSDK] onShareAppMessage 已设置');
}
/**
* 设置分享到朋友圈的内容
* @param config 朋友圈分享配置
*/
static onShareTimeline(config: WxShareTimelineConfig): void {
const wxApi = WxSDK.getWx();
if (!wxApi) return;
if (typeof wxApi.onShareTimeline !== 'function') {
console.warn('[WxSDK] 当前微信版本不支持 onShareTimeline');
return;
}
wxApi.onShareTimeline(() => ({
title: config.title,
imageUrl: config.imageUrl ?? '',
query: config.query ?? ''
}));
console.log('[WxSDK] onShareTimeline 已设置');
}
/**
* 主动触发转发(拉起分享面板)
* @param config 分享配置
*/
static shareAppMessage(config: WxShareConfig): void {
const wxApi = WxSDK.getWx();
if (!wxApi) return;
wxApi.shareAppMessage({
title: config.title,
imageUrl: config.imageUrl ?? '',
query: config.query ?? ''
});
console.log('[WxSDK] shareAppMessage 已触发');
}
/**
* 一键初始化分享功能
* 开启分享菜单 + 设置被动分享内容 + 设置朋友圈分享内容
* @param config 分享配置
*/
static initShare(config: WxShareConfig): void {
if (!WxSDK.isWechat()) {
console.log('[WxSDK] 非微信环境,跳过分享初始化');
return;
}
WxSDK.showShareMenu();
WxSDK.onShareAppMessage(config);
WxSDK.onShareTimeline({
title: config.title,
imageUrl: config.imageUrl,
query: config.query
});
console.log('[WxSDK] 分享功能初始化完成');
}
// ==================== 震动相关 ====================
/**
* 触发短震动15ms
* 用于轻量级反馈,如按钮点击
*/
static vibrateShort(): void {
const wxApi = WxSDK.getWx();
if (!wxApi) return;
wxApi.vibrateShort({
type: 'medium',
success: () => {
console.log('[WxSDK] 短震动成功');
},
fail: (err: any) => {
console.warn('[WxSDK] 短震动失败', err);
}
});
}
/**
* 触发长震动400ms
* 用于重要反馈,如错误提示
*/
static vibrateLong(): void {
const wxApi = WxSDK.getWx();
if (!wxApi) return;
wxApi.vibrateLong({
success: () => {
console.log('[WxSDK] 长震动成功');
},
fail: (err: any) => {
console.warn('[WxSDK] 长震动失败', err);
}
});
}
// ==================== 激励视频广告 ====================
/** 激励视频广告实例(复用) */
private static _rewardedVideoAd: any = null;
/**
* 展示激励视频广告
* 用户看完广告后返回 true中途退出或失败返回 false
* 非微信环境直接返回 true开发模式直接通过
* @param adUnitId 广告单元 ID默认使用项目配置的 ID
* @returns Promise<boolean> 是否看完广告
*/
static showRewardedVideoAd(adUnitId: string = ''): Promise<boolean> {
return new Promise((resolve) => {
const wxApi = WxSDK.getWx();
if (!wxApi) {
console.log('[WxSDK] 非微信环境,跳过激励视频广告');
resolve(true);
return;
}
if (typeof wxApi.createRewardedVideoAd !== 'function') {
console.warn('[WxSDK] 当前微信版本不支持激励视频广告');
resolve(true);
return;
}
try {
// 复用或创建广告实例
if (!WxSDK._rewardedVideoAd) {
WxSDK._rewardedVideoAd = wxApi.createRewardedVideoAd({
adUnitId: adUnitId,
});
}
const ad = WxSDK._rewardedVideoAd;
// 定义关闭回调(一次性)
const onClose = (res: any) => {
ad.offClose(onClose);
if (res && res.isEnded) {
console.log('[WxSDK] 激励视频广告观看完成');
resolve(true);
} else {
console.log('[WxSDK] 激励视频广告中途退出');
resolve(false);
}
};
// 定义错误回调(一次性)
const onError = (err: any) => {
ad.offError(onError);
ad.offClose(onClose);
console.error('[WxSDK] 激励视频广告错误:', err);
resolve(false);
};
ad.onClose(onClose);
ad.onError(onError);
// 先尝试 show如果广告未加载则先 load
ad.show().catch(() => {
ad.load().then(() => ad.show()).catch((loadErr: any) => {
ad.offClose(onClose);
ad.offError(onError);
console.error('[WxSDK] 激励视频广告加载失败:', loadErr);
resolve(false);
});
});
} catch (err) {
console.error('[WxSDK] 激励视频广告异常:', err);
resolve(false);
}
});
}
// ==================== 启动参数 ====================
/**
* 从启动参数中获取分享码
* @returns 分享码,不存在则返回 null
*/
static getShareCodeFromLaunch(): string | null {
const wxApi = WxSDK.getWx();
if (!wxApi) return null;
try {
const options = wxApi.getLaunchOptionsSync();
if (options?.query?.shareCode) {
console.log('[WxSDK] 检测到分享码:', options.query.shareCode);
return options.query.shareCode;
}
} catch (err) {
console.warn('[WxSDK] 获取启动参数失败:', err);
}
return null;
}
}
// ==================== 隐私授权相关 ====================
/**
* 检查用户是否已授权隐私
* @returns Promise<{ needAuthorization: boolean }> needAuthorization 为 false 表示已授权
*/
export async function checkPrivacySetting(): Promise<{ needAuthorization: boolean }> {
return new Promise((resolve) => {
const wxApi = WxSDK.getWx();
if (!wxApi) {
// 非微信环境,认为已授权
resolve({ needAuthorization: false });
return;
}
if (typeof wxApi.getPrivacySetting !== 'function') {
// 低版本微信,认为已授权
console.warn('[WxSDK] 当前微信版本不支持 getPrivacySetting');
resolve({ needAuthorization: false });
return;
}
wxApi.getPrivacySetting({
success: (res: any) => {
console.log('[WxSDK] 隐私授权检查结果:', res);
resolve({ needAuthorization: res.needAuthorization });
},
fail: (err: any) => {
console.warn('[WxSDK] 隐私授权检查失败:', err);
// 检查失败时认为需要授权
resolve({ needAuthorization: true });
}
});
});
}
/**
* 引导用户进行隐私授权
* 调用后会弹出微信隐私授权弹窗
* @returns Promise<void>
*/
export async function requirePrivacyAuthorize(): Promise<void> {
return new Promise((resolve, reject) => {
const wxApi = WxSDK.getWx();
if (!wxApi) {
console.warn('[WxSDK] 非微信环境,跳过隐私授权');
resolve();
return;
}
if (typeof wxApi.requirePrivacyAuthorize !== 'function') {
console.warn('[WxSDK] 当前微信版本不支持 requirePrivacyAuthorize');
resolve();
return;
}
wxApi.requirePrivacyAuthorize({
success: () => {
console.log('[WxSDK] 用户已授权隐私');
resolve();
},
fail: (err: any) => {
console.warn('[WxSDK] 用户拒绝或授权失败:', err);
reject(new Error(err.errMsg || '隐私授权失败'));
}
});
});
}
// ==================== 用户信息相关 ====================
/**
* 用户信息(头像、昵称)
*/
export interface WxUserInfo {
avatarUrl: string;
nickName: string;
country?: string;
province?: string;
city?: string;
gender?: number;
}
/**
* 获取用户头像和昵称(需要用户主动授权)
* @returns Promise<WxUserInfo>
*/
export async function getUserProfile(): Promise<WxUserInfo> {
return new Promise((resolve, reject) => {
const wxApi = WxSDK.getWx();
if (!wxApi) {
// 非微信环境,返回 mock 数据
console.warn('[WxSDK] 非微信环境,返回 mock 用户信息');
resolve({
avatarUrl: '',
nickName: '微信用户'
});
return;
}
if (typeof wxApi.getUserProfile !== 'function') {
console.warn('[WxSDK] 当前微信版本不支持 getUserProfile');
reject(new Error('当前微信版本不支持 getUserProfile'));
return;
}
wxApi.getUserProfile({
desc: '用于完善用户资料',
success: (res: any) => {
if (res.userInfo) {
console.log('[WxSDK] 获取用户信息成功');
resolve({
avatarUrl: res.userInfo.avatarUrl,
nickName: res.userInfo.nickName,
country: res.userInfo.country,
province: res.userInfo.province,
city: res.userInfo.city,
gender: res.userInfo.gender
});
} else {
console.error('[WxSDK] 获取用户信息失败: 无 userInfo');
reject(new Error('获取用户信息失败'));
}
},
fail: (err: any) => {
console.error('[WxSDK] 获取用户信息失败:', err);
reject(new Error(err.errMsg || '获取用户信息失败'));
}
});
});
}