feat: 添加微信SDK和关卡页面,重构预制体结构
- 新增 WxSDK 微信SDK工具类 - 新增 PageLevel 关卡选择页面组件 - 将 prefabs 目录从 resources 移至根目录 - 更新 ViewManager 支持预制体属性引用 - 添加 BaseView 页面基类 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -399,6 +399,14 @@
|
|||||||
},
|
},
|
||||||
"_enabled": true,
|
"_enabled": true,
|
||||||
"__prefab": null,
|
"__prefab": null,
|
||||||
|
"pageHomePrefab": {
|
||||||
|
"__uuid__": "ae6e1ab4-19be-4cb3-90e4-9a1f3204a0fd",
|
||||||
|
"__expectedType__": "cc.Prefab"
|
||||||
|
},
|
||||||
|
"pageLevelPrefab": {
|
||||||
|
"__uuid__": "8611dbdc-4749-49f1-97ca-aedae3d16320",
|
||||||
|
"__expectedType__": "cc.Prefab"
|
||||||
|
},
|
||||||
"_id": "c2b3nbzv9JuZmP2jxQyN72"
|
"_id": "c2b3nbzv9JuZmP2jxQyN72"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { _decorator, Component } from 'cc';
|
import { _decorator, Component, Prefab } from 'cc';
|
||||||
import { ViewManager } from './scripts/core/ViewManager';
|
import { ViewManager } from './scripts/core/ViewManager';
|
||||||
const { ccclass } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 主入口脚本
|
* 主入口脚本
|
||||||
@@ -8,6 +8,12 @@ const { ccclass } = _decorator;
|
|||||||
*/
|
*/
|
||||||
@ccclass('main')
|
@ccclass('main')
|
||||||
export class main extends Component {
|
export class main extends Component {
|
||||||
|
@property({ type: Prefab, tooltip: '首页预制体' })
|
||||||
|
pageHomePrefab: Prefab | null = null;
|
||||||
|
|
||||||
|
@property({ type: Prefab, tooltip: '关卡页面预制体' })
|
||||||
|
pageLevelPrefab: Prefab | null = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* onLoad 比 start 更早执行
|
* onLoad 比 start 更早执行
|
||||||
* 确保 ViewManager 在 PageLoading.start() 之前初始化
|
* 确保 ViewManager 在 PageLoading.start() 之前初始化
|
||||||
@@ -23,18 +29,21 @@ export class main extends Component {
|
|||||||
// 初始化 ViewManager,绑定 Canvas 作为页面容器
|
// 初始化 ViewManager,绑定 Canvas 作为页面容器
|
||||||
ViewManager.instance.init(this.node);
|
ViewManager.instance.init(this.node);
|
||||||
|
|
||||||
// 注册页面配置
|
// 注册页面配置(通过编辑器属性引用预制体)
|
||||||
ViewManager.instance.register('PageHome', {
|
if (this.pageHomePrefab) {
|
||||||
prefabPath: 'prefabs/PageHome',
|
ViewManager.instance.register('PageHome', {
|
||||||
cache: true,
|
prefab: this.pageHomePrefab,
|
||||||
zIndex: 0
|
cache: true,
|
||||||
});
|
zIndex: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 注册关卡页面
|
if (this.pageLevelPrefab) {
|
||||||
ViewManager.instance.register('PageLevel', {
|
ViewManager.instance.register('PageLevel', {
|
||||||
prefabPath: 'prefabs/PageLevel',
|
prefab: this.pageLevelPrefab,
|
||||||
cache: true,
|
cache: true,
|
||||||
zIndex: 1
|
zIndex: 1
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { _decorator, Node, Button } from 'cc';
|
import { _decorator, Node, Button } from 'cc';
|
||||||
import { BaseView } from '../../scripts/core/BaseView';
|
import { BaseView } from 'db://assets/scripts/core/BaseView';
|
||||||
import { ViewManager } from '../../scripts/core/ViewManager';
|
import { ViewManager } from 'db://assets/scripts/core/ViewManager';
|
||||||
|
import { WxSDK } from 'db://assets/scripts/utils/WxSDK';
|
||||||
const { ccclass, property } = _decorator;
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -18,6 +19,18 @@ export class PageHome extends BaseView {
|
|||||||
onViewLoad(): void {
|
onViewLoad(): void {
|
||||||
console.log('[PageHome] onViewLoad');
|
console.log('[PageHome] onViewLoad');
|
||||||
this._initButtons();
|
this._initButtons();
|
||||||
|
this._initWxShare();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化微信分享功能
|
||||||
|
*/
|
||||||
|
private _initWxShare(): void {
|
||||||
|
WxSDK.initShare({
|
||||||
|
title: '写英语',
|
||||||
|
imageUrl: '',
|
||||||
|
query: ''
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
File diff suppressed because it is too large
Load Diff
221
assets/prefabs/PageLevel.ts
Normal file
221
assets/prefabs/PageLevel.ts
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
import { _decorator, Node, EditBox, instantiate, Vec3 } from 'cc';
|
||||||
|
import { BaseView } from 'db://assets/scripts/core/BaseView';
|
||||||
|
const { ccclass, property } = _decorator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关卡配置接口
|
||||||
|
*/
|
||||||
|
export interface LevelConfig {
|
||||||
|
/** 需要的输入框数量 */
|
||||||
|
inputCount: number;
|
||||||
|
/** 题目文本 */
|
||||||
|
questionText?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关卡页面组件
|
||||||
|
* 继承 BaseView,实现页面生命周期
|
||||||
|
*/
|
||||||
|
@ccclass('PageLevel')
|
||||||
|
export class PageLevel extends BaseView {
|
||||||
|
// ========== 节点引用 ==========
|
||||||
|
@property(Node)
|
||||||
|
inputLayout: Node | null = null;
|
||||||
|
|
||||||
|
@property(Node)
|
||||||
|
submitButton: Node | null = null;
|
||||||
|
|
||||||
|
@property(Node)
|
||||||
|
inputTemplate: Node | null = null;
|
||||||
|
|
||||||
|
@property(Node)
|
||||||
|
actionNode: Node | null = null;
|
||||||
|
|
||||||
|
// ========== 配置属性 ==========
|
||||||
|
@property({
|
||||||
|
tooltip: '默认输入框数量',
|
||||||
|
min: 1,
|
||||||
|
max: 10
|
||||||
|
})
|
||||||
|
defaultInputCount: number = 2;
|
||||||
|
|
||||||
|
// ========== 内部状态 ==========
|
||||||
|
/** 当前输入框数量 */
|
||||||
|
private _inputCount: number = 0;
|
||||||
|
|
||||||
|
/** 当前创建的输入框节点数组 */
|
||||||
|
private _inputNodes: Node[] = [];
|
||||||
|
|
||||||
|
/** 当前关卡配置 */
|
||||||
|
private _levelConfig: LevelConfig | null = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面首次加载时调用
|
||||||
|
*/
|
||||||
|
onViewLoad(): void {
|
||||||
|
console.log('[PageLevel] onViewLoad');
|
||||||
|
this.initLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面每次显示时调用
|
||||||
|
*/
|
||||||
|
onViewShow(): void {
|
||||||
|
console.log('[PageLevel] onViewShow');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面隐藏时调用
|
||||||
|
*/
|
||||||
|
onViewHide(): void {
|
||||||
|
console.log('[PageLevel] onViewHide');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 页面销毁时调用
|
||||||
|
*/
|
||||||
|
onViewDestroy(): void {
|
||||||
|
console.log('[PageLevel] onViewDestroy');
|
||||||
|
this.clearInputNodes();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置关卡配置
|
||||||
|
*/
|
||||||
|
setLevelConfig(config: LevelConfig): void {
|
||||||
|
this._levelConfig = config;
|
||||||
|
this.initLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化关卡
|
||||||
|
*/
|
||||||
|
private initLevel(): void {
|
||||||
|
// 使用配置或默认值
|
||||||
|
const inputCount = this._levelConfig?.inputCount ?? this.defaultInputCount;
|
||||||
|
|
||||||
|
// 隐藏提交按钮
|
||||||
|
if (this.submitButton) {
|
||||||
|
this.submitButton.active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建输入框
|
||||||
|
this.createInputs(inputCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 动态创建输入框
|
||||||
|
*/
|
||||||
|
private createInputs(count: number): void {
|
||||||
|
if (!this.inputLayout || !this.inputTemplate) {
|
||||||
|
console.error('[PageLevel] inputLayout 或 inputTemplate 未设置');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理现有输入框
|
||||||
|
this.clearInputNodes();
|
||||||
|
|
||||||
|
this._inputCount = count;
|
||||||
|
|
||||||
|
// 隐藏模板节点
|
||||||
|
this.inputTemplate.active = false;
|
||||||
|
|
||||||
|
// 创建指定数量的输入框
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
const inputNode = instantiate(this.inputTemplate);
|
||||||
|
inputNode.active = true;
|
||||||
|
inputNode.name = `input${i}`;
|
||||||
|
|
||||||
|
// 设置位置(Layout 会自动排列)
|
||||||
|
inputNode.setPosition(new Vec3(0, 0, 0));
|
||||||
|
|
||||||
|
// 获取 EditBox 组件并监听事件
|
||||||
|
const editBox = inputNode.getComponent(EditBox);
|
||||||
|
if (editBox) {
|
||||||
|
// 清空输入内容
|
||||||
|
editBox.string = '';
|
||||||
|
// 监听文本变化事件
|
||||||
|
editBox.node.on(EditBox.EventType.TEXT_CHANGED, this.onInputTextChanged, this);
|
||||||
|
// 监听编辑结束事件
|
||||||
|
editBox.node.on(EditBox.EventType.EDITING_DID_ENDED, this.onInputEditingEnded, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.inputLayout.addChild(inputNode);
|
||||||
|
this._inputNodes.push(inputNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[PageLevel] 创建了 ${count} 个输入框`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理所有输入框节点
|
||||||
|
*/
|
||||||
|
private clearInputNodes(): void {
|
||||||
|
for (const node of this._inputNodes) {
|
||||||
|
if (node.isValid) {
|
||||||
|
node.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._inputNodes = [];
|
||||||
|
this._inputCount = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查所有输入框是否都已填写
|
||||||
|
*/
|
||||||
|
private checkAllInputsFilled(): void {
|
||||||
|
let allFilled = true;
|
||||||
|
|
||||||
|
for (const node of this._inputNodes) {
|
||||||
|
const editBox = node.getComponent(EditBox);
|
||||||
|
if (!editBox || editBox.string.trim() === '') {
|
||||||
|
allFilled = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据填写状态显示/隐藏提交按钮
|
||||||
|
if (this.submitButton) {
|
||||||
|
this.submitButton.active = allFilled;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[PageLevel] 检查输入状态: ${allFilled ? '全部已填写' : '未全部填写'}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有输入框的值
|
||||||
|
*/
|
||||||
|
getInputValues(): string[] {
|
||||||
|
const values: string[] = [];
|
||||||
|
for (const node of this._inputNodes) {
|
||||||
|
const editBox = node.getComponent(EditBox);
|
||||||
|
values.push(editBox?.string ?? '');
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取拼接后的答案字符串
|
||||||
|
*/
|
||||||
|
getAnswer(): string {
|
||||||
|
return this.getInputValues().join('');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========== EditBox 事件回调 ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入框文本变化回调
|
||||||
|
*/
|
||||||
|
private onInputTextChanged(editBox: EditBox): void {
|
||||||
|
this.checkAllInputsFilled();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入框编辑结束回调
|
||||||
|
*/
|
||||||
|
private onInputEditingEnded(editBox: EditBox): void {
|
||||||
|
this.checkAllInputsFilled();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
import { _decorator } from 'cc';
|
|
||||||
import { BaseView } from '../../scripts/core/BaseView';
|
|
||||||
const { ccclass } = _decorator;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 关卡页面组件
|
|
||||||
* 继承 BaseView,实现页面生命周期
|
|
||||||
*/
|
|
||||||
@ccclass('PageLevel')
|
|
||||||
export class PageLevel extends BaseView {
|
|
||||||
/**
|
|
||||||
* 页面首次加载时调用
|
|
||||||
*/
|
|
||||||
onViewLoad(): void {
|
|
||||||
console.log('[PageLevel] onViewLoad');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 页面每次显示时调用
|
|
||||||
*/
|
|
||||||
onViewShow(): void {
|
|
||||||
console.log('[PageLevel] onViewShow');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 页面隐藏时调用
|
|
||||||
*/
|
|
||||||
onViewHide(): void {
|
|
||||||
console.log('[PageLevel] onViewHide');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 页面销毁时调用
|
|
||||||
*/
|
|
||||||
onViewDestroy(): void {
|
|
||||||
console.log('[PageLevel] onViewDestroy');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
import { _decorator, Component } from 'cc';
|
import { _decorator, Component, Prefab } from 'cc';
|
||||||
const { ccclass } = _decorator;
|
const { ccclass } = _decorator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 页面配置接口
|
* 页面配置接口
|
||||||
*/
|
*/
|
||||||
export interface ViewConfig {
|
export interface ViewConfig {
|
||||||
prefabPath: string; // 相对于 resources 的路径
|
prefab: Prefab; // 预制体引用(主包资源)
|
||||||
cache?: boolean; // 是否缓存页面,默认 true
|
cache?: boolean; // 是否缓存页面,默认 true
|
||||||
zIndex?: number; // 层级,默认 0
|
zIndex?: number; // 层级,默认 0
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { _decorator, Node, resources, Prefab, instantiate, error } from 'cc';
|
import { _decorator, Node, Prefab, instantiate, error } from 'cc';
|
||||||
import { BaseView, ViewConfig, ViewOptions } from './BaseView';
|
import { BaseView, ViewConfig, ViewOptions } from './BaseView';
|
||||||
const { ccclass } = _decorator;
|
const { ccclass } = _decorator;
|
||||||
|
|
||||||
@@ -7,7 +7,6 @@ const { ccclass } = _decorator;
|
|||||||
*/
|
*/
|
||||||
interface RegisteredView {
|
interface RegisteredView {
|
||||||
config: ViewConfig;
|
config: ViewConfig;
|
||||||
prefab: Prefab | null; // 缓存的预制体
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,8 +69,7 @@ export class ViewManager {
|
|||||||
cache: true, // 默认缓存
|
cache: true, // 默认缓存
|
||||||
zIndex: 0, // 默认层级
|
zIndex: 0, // 默认层级
|
||||||
...config
|
...config
|
||||||
},
|
}
|
||||||
prefab: null
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,24 +109,8 @@ export class ViewManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查是否有缓存的预制体
|
// 直接使用预制体引用实例化
|
||||||
if (registered.prefab) {
|
this._instantiateView(viewId, registered.config.prefab, options);
|
||||||
this._instantiateView(viewId, registered.prefab, options);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 动态加载预制体
|
|
||||||
resources.load(registered.config.prefabPath, Prefab, (err, prefab) => {
|
|
||||||
if (err) {
|
|
||||||
error(`ViewManager: 加载预制体失败 "${registered.config.prefabPath}"`, err);
|
|
||||||
options?.onError?.(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 缓存预制体
|
|
||||||
registered.prefab = prefab;
|
|
||||||
this._instantiateView(viewId, prefab!, options);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -144,7 +126,7 @@ export class ViewManager {
|
|||||||
const view = node.getComponent(BaseView);
|
const view = node.getComponent(BaseView);
|
||||||
|
|
||||||
if (!view) {
|
if (!view) {
|
||||||
error(`ViewManager: 预制体 "${registered.config.prefabPath}" 缺少 BaseView 组件`);
|
error(`ViewManager: 预制体 "${viewId}" 缺少 BaseView 组件`);
|
||||||
node.destroy();
|
node.destroy();
|
||||||
options?.onError?.(new Error('缺少 BaseView 组件'));
|
options?.onError?.(new Error('缺少 BaseView 组件'));
|
||||||
return;
|
return;
|
||||||
@@ -290,7 +272,7 @@ export class ViewManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 预加载页面预制体
|
* 预加载页面预制体(主包资源已随游戏加载,此方法仅为兼容性保留)
|
||||||
* @param viewId 页面标识
|
* @param viewId 页面标识
|
||||||
* @param onProgress 进度回调
|
* @param onProgress 进度回调
|
||||||
* @param onComplete 完成回调
|
* @param onComplete 完成回调
|
||||||
@@ -303,22 +285,9 @@ export class ViewManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 已缓存
|
// 主包资源已加载,直接回调
|
||||||
if (registered.prefab) {
|
onProgress?.(1);
|
||||||
onProgress?.(1);
|
onComplete?.();
|
||||||
onComplete?.();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
resources.load(registered.config.prefabPath, Prefab, (err, prefab) => {
|
|
||||||
if (err) {
|
|
||||||
error(`ViewManager: 预加载失败 "${registered.config.prefabPath}"`, err);
|
|
||||||
} else {
|
|
||||||
registered.prefab = prefab;
|
|
||||||
onProgress?.(1);
|
|
||||||
}
|
|
||||||
onComplete?.();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
148
assets/scripts/utils/WxSDK.ts
Normal file
148
assets/scripts/utils/WxSDK.ts
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
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 全局对象(仅微信环境下可用)
|
||||||
|
*/
|
||||||
|
private static getWx(): any {
|
||||||
|
if (!WxSDK.isWechat()) return null;
|
||||||
|
return typeof wx !== 'undefined' ? wx : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 分享相关 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开启转发/分享菜单
|
||||||
|
* 调用后用户可通过右上角菜单进行转发
|
||||||
|
* @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] 分享功能初始化完成');
|
||||||
|
}
|
||||||
|
}
|
||||||
9
assets/scripts/utils/WxSDK.ts.meta
Normal file
9
assets/scripts/utils/WxSDK.ts.meta
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"ver": "4.0.24",
|
||||||
|
"importer": "typescript",
|
||||||
|
"imported": true,
|
||||||
|
"uuid": "ba0af7e0-a456-4b08-b058-8f77f5a7481f",
|
||||||
|
"files": [],
|
||||||
|
"subMetas": {},
|
||||||
|
"userData": {}
|
||||||
|
}
|
||||||
18
package-lock.json
generated
Normal file
18
package-lock.json
generated
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"name": "mp-xieyingeng",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "mp-xieyingeng",
|
||||||
|
"dependencies": {
|
||||||
|
"minigame-api-typings": "^3.8.18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/minigame-api-typings": {
|
||||||
|
"version": "3.8.18",
|
||||||
|
"resolved": "https://mirrors.tencent.com/npm/minigame-api-typings/-/minigame-api-typings-3.8.18.tgz",
|
||||||
|
"integrity": "sha512-EdHRr/3qDfzd5ofylR5gKTAsu+Hrqq4N2ylHG7TfC5BroeQOEPBT1jKNmTYypY7dX9vnbMvIE4iCge7r09NdzA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,5 +3,8 @@
|
|||||||
"uuid": "9ee27804-ead0-4e3b-bcbf-82df2cb9434a",
|
"uuid": "9ee27804-ead0-4e3b-bcbf-82df2cb9434a",
|
||||||
"creator": {
|
"creator": {
|
||||||
"version": "3.8.8"
|
"version": "3.8.8"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"minigame-api-typings": "^3.8.18"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user