box_app: add wx-h5-demo standalone project (two mini-program auth scenarios); mount /wx-h5-demo; update auth doc; drop old examples/wx-h5-auth

This commit is contained in:
2026-09-07 16:22:51 +08:00
commit eaaf2b6773
6 changed files with 280 additions and 0 deletions

View File

@@ -0,0 +1,33 @@
// 场景1:授权桥页(H5 在微信浏览器 → 跳进本页 → 授权 → 回到 H5)
// 路径:/pages/demo/auth.js
// 入口:<wx-open-launch-weapp path="/pages/demo/auth"> 或 小程序 URL Scheme
// ⚠️ openid 由登录态/onLoad 取;授权结果放 globalData,webview 页再拼进 H5 url。
const app = getApp();
const H5_BASE = 'https://mp.yizhezhe.com/wx-h5-demo/'; // 示例 H5(独立二级目录项目)
Page({
data: { nickname: '', avatar: '' },
_phone: '', _nick: '', _avatar: '', _openid: '',
onLoad(q) { this._openid = q.openid || app.globalData.openid || 'YOUR_OPENID'; },
onPhone(e) {
if (e.detail.errMsg === 'getPhoneNumber:ok' && e.detail.code) {
wx.request({ url: 'https://YOUR_API/phone', method: 'POST', data: { code: e.detail.code },
success: r => { this._phone = r.data.phoneNumber; wx.showToast({ title: '已获取手机号', icon: 'none' }); } });
} else { wx.showToast({ title: '未授权手机号', icon: 'none' }); }
},
onNick(e) { this._nick = e.detail.value; this.setData({ nickname: this._nick }); },
onAvatar(e) {
const p = e.detail.avatarUrl;
wx.uploadFile({ url: 'https://YOUR_API/avatar', filePath: p, name: 'file',
success: (res) => { const r = JSON.parse(res.data || '{}'); this._avatar = r.url || p; this.setData({ avatar: this._avatar }); } });
},
// 授权完成 → 写 globalData → 去 webview 页加载 H5(结果在 URL)→ 即“回到 H5”
finishAuth() {
app.globalData.wxH5Result = { openid: this._openid, phone: this._phone, nickname: this._nick, avatar: this._avatar };
wx.redirectTo({ url: '/pages/demo/webview' });
},
cancel() { wx.navigateBack({}); },
});

View File

@@ -0,0 +1,16 @@
<!-- 场景1:授权桥页(H5 在微信浏览器 → 跳进本页 → 授权 → 回到 H5)
START:经 <wx-open-launch-weapp path="/pages/demo/auth"> 或 小程序 URL Scheme(path=/pages/demo/auth) 进入 -->
<!-- wxml -->
<view class="auth-wrap">
<view class="auth-title">授权获取资料</view>
<view class="auth-sub">授权后自动回到「wx-h5-demo」H5</view>
<button class="auth-btn" open-type="getPhoneNumber" bindgetphonenumber="onPhone">获取手机号</button>
<input class="auth-input" type="nickname" bindblur="onNick" bindchange="onNick" placeholder="输入昵称" />
<button class="auth-btn avatar" open-type="chooseAvatar" bindchooseavatar="onAvatar">
<image wx:if="{{avatar}}" class="auth-avatar" src="{{avatar}}" mode="aspectFill" /><text wx:else>选择头像</text>
</button>
<button class="auth-done" bindtap="finishAuth">完成</button>
<view class="auth-cancel" bindtap="cancel">取消</view>
</view>

View File

@@ -0,0 +1,51 @@
// 场景2(也是场景1落地页):web-view 承载 H5 + postMessage 授权 + 回传
// 路径:/pages/demo/webview.js
// H5 地址(独立二级目录项目)
const H5_BASE = 'https://mp.yizhezhe.com/wx-h5-demo/';
const app = getApp();
Page({
data: { url: '', showAuth: false, nickname: '', avatar: '' },
_phone: '', _nick: '', _avatar: '', _openid: '',
onLoad() {
this._openid = app.globalData.openid || 'YOUR_OPENID';
// 场景1:auth-bridge 授权后 redirectTo 本页,结果在 globalData
const r = app.globalData.wxH5Result;
if (r) { this._phone = r.phone || ''; this._nick = r.nickname || ''; this._avatar = r.avatar || ''; }
this.applyUrl();
},
// 拼 H5 url:openid 走 query;授权结果走 hash(webview 丢 query、不丢 hash)
applyUrl() {
const u = H5_BASE + '?openid=' + encodeURIComponent(this._openid) +
'#phone=' + encodeURIComponent(this._phone || '') +
'&nickname=' + encodeURIComponent(this._nick || '') +
'&avatar=' + encodeURIComponent(this._avatar || '');
this.setData({ url: u });
},
// 场景2:H5 通过 postMessage 请求授权
onMessage(e) {
const data = (e.detail && e.detail.data) || [];
(Array.isArray(data) ? data : [data]).forEach((m) => {
if (m && m.action === 'requestProfile') this.setData({ showAuth: true });
});
},
onPhone(e) {
if (e.detail.errMsg === 'getPhoneNumber:ok' && e.detail.code) {
wx.request({ url: 'https://YOUR_API/phone', method: 'POST', data: { code: e.detail.code },
success: r => { this._phone = r.data.phoneNumber; this.finishAuth(); } });
} else { wx.showToast({ title: '未授权手机号', icon: 'none' }); }
},
onNick(e) { this._nick = e.detail.value; this.setData({ nickname: this._nick }); },
onAvatar(e) {
const p = e.detail.avatarUrl;
wx.uploadFile({ url: 'https://YOUR_API/avatar', filePath: p, name: 'file',
success: (res) => { const r = JSON.parse(res.data || '{}'); this._avatar = r.url || p; this.setData({ avatar: this._avatar }); } });
},
finishAuth() { this.setData({ showAuth: false }); this.applyUrl(); }, // 更新 web-view src → H5 重载显示结果
closeAuth() { this.setData({ showAuth: false }); },
noop() {},
});

View File

@@ -0,0 +1,19 @@
<!-- 场景2(也是场景1授权后的落地页):web-view 承载 H5 + postMessage 授权 + 回传
用法:本页 <web-view src="{{url}}"> 加载 wx-h5-demo/index.html。
- 场景2:H5 请求授权 → bindmessage 收到 → 弹原生面板 → 授权 → 更新 web-view src(带结果)。
- 场景1:auth-bridge 授权后 redirectTo 本页,本页 onLoad 从 globalData 读结果拼进 H5 url。 -->
<!-- wxml -->
<web-view wx:if="{{url}}" src="{{url}}" bindmessage="onMessage"></web-view>
<view wx:if="{{showAuth}}" class="auth-mask" bindtap="closeAuth">
<view class="auth-panel" catchtap="noop">
<view class="auth-title">授权获取资料</view>
<view class="auth-sub">用于在 wx-h5-demo 中展示昵称/头像/手机号</view>
<button class="auth-btn" open-type="getPhoneNumber" bindgetphonenumber="onPhone">获取手机号</button>
<input class="auth-input" type="nickname" bindblur="onNick" bindchange="onNick" placeholder="输入昵称" />
<button class="auth-btn avatar" open-type="chooseAvatar" bindchooseavatar="onAvatar">
<image wx:if="{{avatar}}" class="auth-avatar" src="{{avatar}}" mode="aspectFill" /><text wx:else>选择头像</text>
</button>
<view class="auth-cancel" bindtap="closeAuth">取消</view>
</view>
</view>