修复拼图生成前订阅授权

新增小程序原生订阅消息授权页,在用户点击后请求生成结果通知授权。

拼图 compile_puzzle_draft 前等待授权页返回或跳过后再发起生成 action。

移除 web-view message 订阅授权路径,改用 storage/hash 回写订阅结果。

补充订阅授权测试、文档和团队踩坑记录。
This commit is contained in:
kdletters
2026-06-08 13:06:07 +08:00
parent 38d9c292ae
commit 3a918687c5
17 changed files with 708 additions and 71 deletions

View File

@@ -5,7 +5,6 @@ const {
API_BASE_URL,
DEV_API_BASE_URL,
DEV_WEB_VIEW_ENTRY_URL,
GENERATION_RESULT_SUBSCRIBE_TEMPLATE_ID,
MINI_PROGRAM_APP_ID,
MINI_PROGRAM_ENV,
WEB_VIEW_ENTRY_URL,
@@ -16,13 +15,12 @@ const MINI_PROGRAM_CLIENT_TYPE = 'mini_program';
const MINI_PROGRAM_CLIENT_RUNTIME = 'wechat_mini_program';
const CLIENT_INSTANCE_STORAGE_KEY = 'genarrative:mini-program-client-instance-id';
const PAY_RESULT_STORAGE_KEY = 'genarrative:wechat-pay-result';
const SUBSCRIBE_RESULT_STORAGE_KEY = 'genarrative:wechat-subscribe-result';
const AUTH_RESULT_STORAGE_KEY = 'genarrative:mini-program-auth-result';
const AUTH_ACTION_LOGIN = 'login';
const PAY_RESULT_RECHECK_DELAY_MS = 120;
const WEB_VIEW_SHARE_TITLE = '陶泥儿';
const WEB_VIEW_SHARE_PATH = '/pages/web-view/index';
const SUBSCRIBE_MESSAGE_TYPE = 'genarrative:request-subscribe-message';
const GENERATION_RESULT_SUBSCRIBE_SCENE = 'generation-result';
function showWebViewShareMenu() {
if (typeof wx.showShareMenu !== 'function') {
@@ -418,36 +416,6 @@ function requestMiniProgramBindPhone(authToken, wechatPhoneCode, displayName) {
});
}
function requestGenerationResultSubscribeMessage() {
return new Promise((resolve) => {
if (!GENERATION_RESULT_SUBSCRIBE_TEMPLATE_ID) {
resolve({ ok: false, reason: 'missing_template_id' });
return;
}
if (typeof wx.requestSubscribeMessage !== 'function') {
resolve({ ok: false, reason: 'unsupported' });
return;
}
wx.requestSubscribeMessage({
tmplIds: [GENERATION_RESULT_SUBSCRIBE_TEMPLATE_ID],
success(result) {
resolve({
ok: result[GENERATION_RESULT_SUBSCRIBE_TEMPLATE_ID] === 'accept',
result,
});
},
fail(error) {
console.warn('[web-view] request subscribe message failed', error);
resolve({
ok: false,
reason: error && error.errMsg ? error.errMsg : 'failed',
});
},
});
});
}
async function resolveAuthResult(displayName) {
const code = await wxLogin();
const response = await requestMiniProgramLogin(code, displayName);
@@ -638,8 +606,10 @@ Page({
}
this.consumePayResult();
this.consumeSubscribeResult();
setTimeout(() => {
this.consumePayResult();
this.consumeSubscribeResult();
}, PAY_RESULT_RECHECK_DELAY_MS);
},
@@ -655,6 +625,18 @@ Page({
}
},
consumeSubscribeResult() {
const result = wx.getStorageSync(SUBSCRIBE_RESULT_STORAGE_KEY);
if (result && this.data.webViewUrl) {
wx.removeStorageSync(SUBSCRIBE_RESULT_STORAGE_KEY);
this.setData({
webViewUrl: appendHashParams(this.data.webViewUrl, {
wx_subscribe_result: result,
}),
});
}
},
async handleGetPhoneNumber(event) {
if (!this.data.authResult || !this.data.authResult.token) {
this.handleRetryLogin();
@@ -745,23 +727,7 @@ Page({
},
handleWebViewMessage(event) {
const messages =
event && event.detail && Array.isArray(event.detail.data)
? event.detail.data
: [];
const shouldRequestSubscribe = messages.some((message) => {
const payload = message && typeof message === 'object' ? message : {};
return (
payload.type === SUBSCRIBE_MESSAGE_TYPE &&
payload.scene === GENERATION_RESULT_SUBSCRIBE_SCENE
);
});
if (shouldRequestSubscribe) {
void requestGenerationResultSubscribeMessage();
return;
}
// 中文注释:支付由独立 native 页面承接,其他 web-view 消息只保留调试输出。
// 中文注释:支付和订阅消息都由独立 native 页面承接web-view 消息只保留调试输出。
console.info('[web-view] message', event.detail);
},