|
@@ -124,6 +124,13 @@
|
|
|
z-index: 20;
|
|
z-index: 20;
|
|
|
padding: 10px 15px calc(10px + var(--safe-bottom));
|
|
padding: 10px 15px calc(10px + var(--safe-bottom));
|
|
|
background: linear-gradient(180deg, rgba(244, 246, 251, 0) 0%, #f4f6fb 36%);
|
|
background: linear-gradient(180deg, rgba(244, 246, 251, 0) 0%, #f4f6fb 36%);
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .footer__dock {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ pointer-events: auto;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.continue-btn {
|
|
.continue-btn {
|
|
@@ -136,6 +143,47 @@
|
|
|
color: #fff;
|
|
color: #fff;
|
|
|
font-size: 16px;
|
|
font-size: 16px;
|
|
|
font-weight: 600;
|
|
font-weight: 600;
|
|
|
|
|
+ touch-action: manipulation;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #launch-btn {
|
|
|
|
|
+ display: none;
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 44px;
|
|
|
|
|
+ min-height: 44px;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ body.is-wechat.wx-jssdk-ready #launch-btn {
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ body.is-wechat.wx-jssdk-ready #btnContinue {
|
|
|
|
|
+ visibility: hidden;
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ #openAppToast {
|
|
|
|
|
+ display: none;
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ left: 16px;
|
|
|
|
|
+ right: 16px;
|
|
|
|
|
+ bottom: calc(72px + var(--safe-bottom));
|
|
|
|
|
+ z-index: 10001;
|
|
|
|
|
+ padding: 10px 14px;
|
|
|
|
|
+ font-size: 13px;
|
|
|
|
|
+ line-height: 1.45;
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ background: rgba(0, 0, 0, 0.78);
|
|
|
|
|
+ border-radius: 8px;
|
|
|
|
|
+ pointer-events: none;
|
|
|
|
|
+ word-break: break-all;
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|
|
|
</head>
|
|
</head>
|
|
@@ -144,13 +192,60 @@
|
|
|
<div class="empty">对话内容加载中…</div>
|
|
<div class="empty">对话内容加载中…</div>
|
|
|
</main>
|
|
</main>
|
|
|
|
|
|
|
|
|
|
+ <div id="openAppToast" role="status" aria-live="polite"></div>
|
|
|
|
|
+
|
|
|
<footer class="footer">
|
|
<footer class="footer">
|
|
|
- <button type="button" class="continue-btn" id="btnContinue">和U宝继续聊 →</button>
|
|
|
|
|
|
|
+ <div class="footer__dock">
|
|
|
|
|
+ <button type="button" class="continue-btn" id="btnContinue">和U宝继续聊 →</button>
|
|
|
|
|
+ <wx-open-launch-app id="launch-btn" appid="wxf5f1efe3a9f5012e" extinfo="">
|
|
|
|
|
+ <script type="text/wxtag-template">
|
|
|
|
|
+ <style>
|
|
|
|
|
+ .wx-open-app-btn {
|
|
|
|
|
+ display: block;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 44px;
|
|
|
|
|
+ margin: 0;
|
|
|
|
|
+ padding: 0;
|
|
|
|
|
+ border: none;
|
|
|
|
|
+ border-radius: 999px;
|
|
|
|
|
+ background: linear-gradient(90deg, #ffb347 0%, #f47d1f 55%, #ff7849 100%);
|
|
|
|
|
+ box-shadow: 0 4px 12px rgba(244, 125, 31, 0.28);
|
|
|
|
|
+ color: #fff;
|
|
|
|
|
+ font-size: 16px;
|
|
|
|
|
+ font-weight: 600;
|
|
|
|
|
+ line-height: 44px;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ -webkit-tap-highlight-color: transparent;
|
|
|
|
|
+ }
|
|
|
|
|
+ </style>
|
|
|
|
|
+ <button class="wx-open-app-btn">和U宝继续聊 →</button>
|
|
|
|
|
+ </script>
|
|
|
|
|
+ </wx-open-launch-app>
|
|
|
|
|
+ </div>
|
|
|
</footer>
|
|
</footer>
|
|
|
|
|
|
|
|
|
|
+ <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
|
|
|
<script>
|
|
<script>
|
|
|
(function () {
|
|
(function () {
|
|
|
- var APP_DEEPLINK = "shopro://pages/aiSearchResult/index?pageType=home";
|
|
|
|
|
|
|
+ "use strict";
|
|
|
|
|
+
|
|
|
|
|
+ var API_BASE = "https://test.ailien.shop/alienStore";
|
|
|
|
|
+ var WECHAT_MP_APP_ID = "wx412792c77f47babd";
|
|
|
|
|
+ var WECHAT_OPEN_APP_ID = "wxf5f1efe3a9f5012e";
|
|
|
|
|
+ var WECHAT_GET_WX_CONFIG_PATH = "/wx/getWxConfig";
|
|
|
|
|
+ var H5_PAGE_BASE_FALLBACK = "https://test.ailien.shop/h5/HBuilderProjects/";
|
|
|
|
|
+ var WX_GET_CONFIG_SIGN_URL = H5_PAGE_BASE_FALLBACK + "shareAiConsult.html";
|
|
|
|
|
+ var WECHAT_JS_SAFE_HOSTS = ["uat.ailien.shop", "test.ailien.shop"];
|
|
|
|
|
+ var APP_ANDROID_PACKAGE = "com.alien.Udianzaizhe";
|
|
|
|
|
+ var APP_IOS_URL_SCHEME = "shopro://";
|
|
|
|
|
+ var APP_UNI_AI_PATH = "pages/aiSearchResult/index";
|
|
|
|
|
+
|
|
|
|
|
+ var sharePayloadCache = null;
|
|
|
|
|
+ var weChatJssdkConfigured = false;
|
|
|
|
|
+ var wxConfigSignRetriedBaseUrl = false;
|
|
|
|
|
+ var wxInitLastError = "";
|
|
|
|
|
+ var wxJssdkInitPromise = null;
|
|
|
|
|
|
|
|
function escHtml(s) {
|
|
function escHtml(s) {
|
|
|
return String(s || "")
|
|
return String(s || "")
|
|
@@ -160,6 +255,15 @@
|
|
|
.replace(/"/g, """);
|
|
.replace(/"/g, """);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ function q(name) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ var v = new URLSearchParams(location.search || "").get(name);
|
|
|
|
|
+ return v == null ? "" : String(v);
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
function getQueryParam(name) {
|
|
function getQueryParam(name) {
|
|
|
var m = new RegExp("[?&]" + name + "=([^&]*)").exec(window.location.search);
|
|
var m = new RegExp("[?&]" + name + "=([^&]*)").exec(window.location.search);
|
|
|
if (!m) return "";
|
|
if (!m) return "";
|
|
@@ -193,10 +297,10 @@
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function formatDiscussionTitle(question) {
|
|
function formatDiscussionTitle(question) {
|
|
|
- var q = String(question || "").trim();
|
|
|
|
|
- if (!q) return "与AI助手对话";
|
|
|
|
|
- if (q.slice(-3) === "的讨论") return q;
|
|
|
|
|
- return q + "的讨论";
|
|
|
|
|
|
|
+ var qText = String(question || "").trim();
|
|
|
|
|
+ if (!qText) return "与AI助手对话";
|
|
|
|
|
+ if (qText.slice(-3) === "的讨论") return qText;
|
|
|
|
|
+ return qText + "的讨论";
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function formatDate(ts) {
|
|
function formatDate(ts) {
|
|
@@ -233,9 +337,11 @@
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function render(data) {
|
|
function render(data) {
|
|
|
|
|
+ sharePayloadCache = data || null;
|
|
|
var main = document.getElementById("main");
|
|
var main = document.getElementById("main");
|
|
|
if (!data) {
|
|
if (!data) {
|
|
|
main.innerHTML = '<div class="empty">对话内容不存在或链接已失效</div>';
|
|
main.innerHTML = '<div class="empty">对话内容不存在或链接已失效</div>';
|
|
|
|
|
+ refreshWxLaunchTagAttrs();
|
|
|
return;
|
|
return;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -271,20 +377,505 @@
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
main.innerHTML = bodyHtml;
|
|
main.innerHTML = bodyHtml;
|
|
|
|
|
+ refreshWxLaunchTagAttrs();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function buildAiConsultOpenParams() {
|
|
|
|
|
+ var params = new URLSearchParams();
|
|
|
|
|
+ params.set("pageType", "home");
|
|
|
|
|
+ params.set("fromShareAiConsult", "1");
|
|
|
|
|
+ return params;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function buildAppDeepLink() {
|
|
|
|
|
+ var path = APP_UNI_AI_PATH;
|
|
|
|
|
+ var qs = buildAiConsultOpenParams().toString();
|
|
|
|
|
+ var root = APP_IOS_URL_SCHEME.replace(/\/$/, "");
|
|
|
|
|
+ return root + "/" + path + (qs ? "?" + qs : "");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function buildWeChatLaunchExtinfo() {
|
|
|
|
|
+ var qs = buildAiConsultOpenParams().toString();
|
|
|
|
|
+ var uniPage = qs ? APP_UNI_AI_PATH + "?" + qs : APP_UNI_AI_PATH;
|
|
|
|
|
+ return uniPage.length <= 1024 ? uniPage : APP_UNI_AI_PATH + "?pageType=home&fromShareAiConsult=1";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function isWeChatInAppBrowser() {
|
|
|
|
|
+ return /MicroMessenger/i.test(navigator.userAgent || "");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function isIOSWeChatBrowser() {
|
|
|
|
|
+ var ua = navigator.userAgent || "";
|
|
|
|
|
+ return /MicroMessenger/i.test(ua) && /iPhone|iPad|iPod/i.test(ua);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function isWxDebugOn() {
|
|
|
|
|
+ return q("wxDebug") === "1";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function isWxForceDebug() {
|
|
|
|
|
+ return q("wxForce") === "1";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function isWxPcAutoDebugHost() {
|
|
|
|
|
+ var h = (location.hostname || "").toLowerCase();
|
|
|
|
|
+ if (h === "localhost" || h === "127.0.0.1") return true;
|
|
|
|
|
+ for (var i = 0; i < WECHAT_JS_SAFE_HOSTS.length; i++) {
|
|
|
|
|
+ if (WECHAT_JS_SAFE_HOSTS[i] === h) return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function isWxPcBrowser() {
|
|
|
|
|
+ return !isWeChatInAppBrowser();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function shouldInitWeChatJssdkOnLoad() {
|
|
|
|
|
+ if (isWeChatInAppBrowser()) return true;
|
|
|
|
|
+ return isWxForceDebug() || isWxPcAutoDebugHost();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function shouldFetchWxConfig(fromUserClick) {
|
|
|
|
|
+ if (isWeChatInAppBrowser()) return true;
|
|
|
|
|
+ if (fromUserClick) return true;
|
|
|
|
|
+ return isWxForceDebug() || isWxPcAutoDebugHost();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function getWxHtmlUrl() {
|
|
|
|
|
+ var forced = String(q("wxSignUrl") || "").trim();
|
|
|
|
|
+ if (forced) return forced.split("#")[0];
|
|
|
|
|
+ return String(location.href || "").split("#")[0];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function getWxSignPageUrlForApi() {
|
|
|
|
|
+ var htmlUrl = getWxHtmlUrl();
|
|
|
|
|
+ if (htmlUrl && /^https?:\/\//i.test(htmlUrl)) return htmlUrl;
|
|
|
|
|
+ return WX_GET_CONFIG_SIGN_URL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function getWxHtmlUrlBase() {
|
|
|
|
|
+ var htmlUrl = getWxSignPageUrlForApi();
|
|
|
|
|
+ try {
|
|
|
|
|
+ var u = new URL(htmlUrl);
|
|
|
|
|
+ return u.origin + u.pathname;
|
|
|
|
|
+ } catch (eU) {
|
|
|
|
|
+ return WX_GET_CONFIG_SIGN_URL;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function getWxConfigSignUrl() {
|
|
|
|
|
+ if (String(q("wxSignBaseOnly") || "") === "1") return getWxHtmlUrlBase();
|
|
|
|
|
+ return getWxSignPageUrlForApi();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function getWxGetConfigApiUrl() {
|
|
|
|
|
+ return API_BASE.replace(/\/$/, "") + WECHAT_GET_WX_CONFIG_PATH;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function buildWxGetConfigRequestBody(htmlUrl) {
|
|
|
|
|
+ return {
|
|
|
|
|
+ url: String(htmlUrl || "").split("#")[0].trim(),
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function resolveWxConfigAppIdFromSignData(d) {
|
|
|
|
|
+ if (!d || typeof d !== "object") return "";
|
|
|
|
|
+ var mp =
|
|
|
|
|
+ d.mpAppId ||
|
|
|
|
|
+ d.mpAppid ||
|
|
|
|
|
+ d.officialAppId ||
|
|
|
|
|
+ d.gzhAppId ||
|
|
|
|
|
+ d.serviceAppId;
|
|
|
|
|
+ if (mp != null && String(mp).trim() !== "") return String(mp).trim();
|
|
|
|
|
+ var fromQuery = String(q("wxMpAppId") || WECHAT_MP_APP_ID || "").trim();
|
|
|
|
|
+ if (fromQuery) return fromQuery;
|
|
|
|
|
+ var raw = d.appId || d.appid || d.wxAppId;
|
|
|
|
|
+ return raw != null && String(raw).trim() !== "" ? String(raw).trim() : "";
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function normalizeWxJssdkSignPayload(res, signUrlUsed) {
|
|
|
|
|
+ if (!res || typeof res !== "object") return null;
|
|
|
|
|
+ var d = res.data != null && typeof res.data === "object" ? res.data : res;
|
|
|
|
|
+ if (!d || typeof d !== "object") return null;
|
|
|
|
|
+ var appId = resolveWxConfigAppIdFromSignData(d);
|
|
|
|
|
+ var timestamp = d.timestamp != null ? d.timestamp : d.timeStamp;
|
|
|
|
|
+ var nonceStr =
|
|
|
|
|
+ d.nonceStr != null && String(d.nonceStr) !== ""
|
|
|
|
|
+ ? d.nonceStr
|
|
|
|
|
+ : d.noncestr != null && String(d.noncestr) !== ""
|
|
|
|
|
+ ? d.noncestr
|
|
|
|
|
+ : d.nonce;
|
|
|
|
|
+ var signature = d.signature || d.sign;
|
|
|
|
|
+ if (!appId || timestamp == null || nonceStr == null || nonceStr === "" || !signature) {
|
|
|
|
|
+ return null;
|
|
|
|
|
+ }
|
|
|
|
|
+ return {
|
|
|
|
|
+ appId: String(appId),
|
|
|
|
|
+ timestamp: Number(timestamp),
|
|
|
|
|
+ nonceStr: String(nonceStr),
|
|
|
|
|
+ signature: String(signature),
|
|
|
|
|
+ signUrl: String(signUrlUsed || "")
|
|
|
|
|
+ .split("#")[0]
|
|
|
|
|
+ .trim(),
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function getWxErrMsg(err) {
|
|
|
|
|
+ if (!err) return "";
|
|
|
|
|
+ if (err.errMsg) return String(err.errMsg);
|
|
|
|
|
+ if (typeof err === "string") return err;
|
|
|
|
|
+ try {
|
|
|
|
|
+ return JSON.stringify(err);
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ return String(err);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function formatWxConfigErrorTip(err, signPageUrl) {
|
|
|
|
|
+ var errMsg = getWxErrMsg(err);
|
|
|
|
|
+ var tip = "微信 JSSDK 配置失败";
|
|
|
|
|
+ if (/invalid signature/i.test(errMsg)) {
|
|
|
|
|
+ return (
|
|
|
|
|
+ tip +
|
|
|
|
|
+ ":签名无效。请核对:①后端用与前端相同的 url 签名;②url=" +
|
|
|
|
|
+ (signPageUrl || getWxHtmlUrl()) +
|
|
|
|
|
+ ";③nonceStr/timestamp 与接口返回一致;④appId=" +
|
|
|
|
|
+ WECHAT_MP_APP_ID
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+ if (/require\s*subscribe/i.test(errMsg)) {
|
|
|
|
|
+ return tip + ":" + errMsg + "(服务号需用户已关注)";
|
|
|
|
|
+ }
|
|
|
|
|
+ return errMsg ? tip + ":" + errMsg : tip;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function setWxInitError(msg) {
|
|
|
|
|
+ wxInitLastError = String(msg || "").trim();
|
|
|
|
|
+ if (wxInitLastError) console.warn("[wx]", wxInitLastError);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function requestWeChatJssdkSignAndConfig(htmlUrlOptional) {
|
|
|
|
|
+ var htmlUrl = String(htmlUrlOptional != null ? htmlUrlOptional : getWxConfigSignUrl())
|
|
|
|
|
+ .split("#")[0]
|
|
|
|
|
+ .trim();
|
|
|
|
|
+ if (!htmlUrl || !/^https?:\/\//i.test(htmlUrl)) {
|
|
|
|
|
+ htmlUrl = WX_GET_CONFIG_SIGN_URL;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (isWxDebugOn()) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ window.alert("htmlUrl(签名用,应与地址栏一致):\n" + htmlUrl);
|
|
|
|
|
+ } catch (eDbg) {}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var requestUrl = getWxGetConfigApiUrl();
|
|
|
|
|
+ var requestBody = buildWxGetConfigRequestBody(htmlUrl);
|
|
|
|
|
+
|
|
|
|
|
+ return fetch(requestUrl, {
|
|
|
|
|
+ method: "POST",
|
|
|
|
|
+ mode: "cors",
|
|
|
|
|
+ credentials: "omit",
|
|
|
|
|
+ headers: {
|
|
|
|
|
+ Accept: "application/json",
|
|
|
|
|
+ "Content-Type": "application/json;charset=UTF-8",
|
|
|
|
|
+ },
|
|
|
|
|
+ body: JSON.stringify(requestBody),
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(function (r) {
|
|
|
|
|
+ if (r.ok) return r.json();
|
|
|
|
|
+ return r
|
|
|
|
|
+ .text()
|
|
|
|
|
+ .catch(function () {
|
|
|
|
|
+ return "";
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(function (text) {
|
|
|
|
|
+ var hint = "";
|
|
|
|
|
+ try {
|
|
|
|
|
+ var j = JSON.parse(text);
|
|
|
|
|
+ hint = j.msg || j.message || "";
|
|
|
|
|
+ } catch (eP) {
|
|
|
|
|
+ if (text) hint = text.slice(0, 120);
|
|
|
|
|
+ }
|
|
|
|
|
+ throw new Error("getWxConfig HTTP " + r.status + (hint ? ":" + hint : ""));
|
|
|
|
|
+ });
|
|
|
|
|
+ })
|
|
|
|
|
+ .then(function (res) {
|
|
|
|
|
+ if (res && res.code != null) {
|
|
|
|
|
+ var c = Number(res.code);
|
|
|
|
|
+ if (c !== 200 && c !== 0 && res.success !== true) {
|
|
|
|
|
+ throw new Error(res.msg || res.message || "getWxConfig code " + c);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ var sign = normalizeWxJssdkSignPayload(res, htmlUrl);
|
|
|
|
|
+ if (!sign) {
|
|
|
|
|
+ throw new Error("getWxConfig 缺少 appId/timestamp/nonceStr/signature(见控制台)");
|
|
|
|
|
+ }
|
|
|
|
|
+ if (typeof wx === "undefined") {
|
|
|
|
|
+ if (isWxPcBrowser()) {
|
|
|
|
|
+ console.log("[wx] PC getWxConfig 成功(无 jweixin)", sign);
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ setWxInitError("jweixin.js 未加载");
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ return applyWxConfigFromSign(sign, htmlUrl);
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function applyWxConfigFromSign(sign, htmlUrl) {
|
|
|
|
|
+ var wxConfigParams = {
|
|
|
|
|
+ debug: isWxDebugOn(),
|
|
|
|
|
+ appId: String(sign.appId),
|
|
|
|
|
+ timestamp: sign.timestamp,
|
|
|
|
|
+ nonceStr: String(sign.nonceStr),
|
|
|
|
|
+ signature: String(sign.signature),
|
|
|
|
|
+ jsApiList: [],
|
|
|
|
|
+ openTagList: ["wx-open-launch-app"],
|
|
|
|
|
+ };
|
|
|
|
|
+ return new Promise(function (resolve) {
|
|
|
|
|
+ wx.config(wxConfigParams);
|
|
|
|
|
+ wx.ready(function () {
|
|
|
|
|
+ weChatJssdkConfigured = true;
|
|
|
|
|
+ document.body.classList.add("wx-jssdk-ready");
|
|
|
|
|
+ refreshWxLaunchTagAttrs();
|
|
|
|
|
+ console.log("[wx.config] ready, htmlUrl=", htmlUrl);
|
|
|
|
|
+ resolve(true);
|
|
|
|
|
+ });
|
|
|
|
|
+ wx.error(function (err) {
|
|
|
|
|
+ weChatJssdkConfigured = false;
|
|
|
|
|
+ document.body.classList.remove("wx-jssdk-ready");
|
|
|
|
|
+ wxJssdkInitPromise = null;
|
|
|
|
|
+ var errMsg = getWxErrMsg(err);
|
|
|
|
|
+ setWxInitError(formatWxConfigErrorTip(err, htmlUrl));
|
|
|
|
|
+ if (isWxDebugOn()) window.alert(wxInitLastError);
|
|
|
|
|
+ console.warn("[wx.config]", errMsg, "htmlUrl=", htmlUrl);
|
|
|
|
|
+ var baseUrl = getWxHtmlUrlBase();
|
|
|
|
|
+ var fullUrl = getWxSignPageUrlForApi();
|
|
|
|
|
+ if (
|
|
|
|
|
+ !/invalid signature/i.test(errMsg) ||
|
|
|
|
|
+ wxConfigSignRetriedBaseUrl ||
|
|
|
|
|
+ baseUrl === fullUrl ||
|
|
|
|
|
+ htmlUrl === baseUrl
|
|
|
|
|
+ ) {
|
|
|
|
|
+ resolve(false);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ wxConfigSignRetriedBaseUrl = true;
|
|
|
|
|
+ requestWeChatJssdkSignAndConfig(baseUrl).then(resolve);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function refreshWxLaunchTagAttrs() {
|
|
|
|
|
+ var tag = document.getElementById("launch-btn");
|
|
|
|
|
+ if (!tag) return;
|
|
|
|
|
+ try {
|
|
|
|
|
+ tag.setAttribute("appid", WECHAT_OPEN_APP_ID);
|
|
|
|
|
+ tag.setAttribute("extinfo", buildWeChatLaunchExtinfo());
|
|
|
|
|
+ } catch (eA) {}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function bindWeChatLaunchTagEvents() {
|
|
|
|
|
+ var tag = document.getElementById("launch-btn");
|
|
|
|
|
+ if (!tag || tag._wxLaunchBound) return;
|
|
|
|
|
+ tag._wxLaunchBound = true;
|
|
|
|
|
+ refreshWxLaunchTagAttrs();
|
|
|
|
|
+ tag.addEventListener("launch", function () {
|
|
|
|
|
+ console.log("[wx-open-launch-app] launch ok");
|
|
|
|
|
+ });
|
|
|
|
|
+ tag.addEventListener("error", function (e) {
|
|
|
|
|
+ var detail = e && e.detail;
|
|
|
|
|
+ var errMsg =
|
|
|
|
|
+ detail && detail.errMsg
|
|
|
|
|
+ ? String(detail.errMsg)
|
|
|
|
|
+ : detail && detail.errmsg
|
|
|
|
|
+ ? String(detail.errmsg)
|
|
|
|
|
+ : "";
|
|
|
|
|
+ console.warn("[wx-open-launch-app]", detail);
|
|
|
|
|
+ showAppOpenFailTip(
|
|
|
|
|
+ errMsg
|
|
|
|
|
+ ? "未能打开 App:" + errMsg
|
|
|
|
|
+ : "未能打开 App,请确认已安装最新版「U店在哪」"
|
|
|
|
|
+ );
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function initWeChatOpenLaunchApp(fromUserClick) {
|
|
|
|
|
+ if (!shouldFetchWxConfig(!!fromUserClick)) {
|
|
|
|
|
+ return Promise.resolve(false);
|
|
|
|
|
+ }
|
|
|
|
|
+ if (wxJssdkInitPromise && !fromUserClick) return wxJssdkInitPromise;
|
|
|
|
|
+
|
|
|
|
|
+ wxConfigSignRetriedBaseUrl = false;
|
|
|
|
|
+ wxInitLastError = "";
|
|
|
|
|
+ var htmlUrl = getWxConfigSignUrl();
|
|
|
|
|
+
|
|
|
|
|
+ bindWeChatLaunchTagEvents();
|
|
|
|
|
+ wxJssdkInitPromise = requestWeChatJssdkSignAndConfig(htmlUrl)
|
|
|
|
|
+ .then(function (ok) {
|
|
|
|
|
+ if (ok === true) return true;
|
|
|
|
|
+ if (!wxInitLastError) {
|
|
|
|
|
+ setWxInitError("wx.config 失败,可加 ?wxDebug=1 查看 htmlUrl");
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(function (e) {
|
|
|
|
|
+ var msg = e && e.message ? e.message : "getWxConfig 请求失败";
|
|
|
|
|
+ setWxInitError(msg);
|
|
|
|
|
+ console.warn("[wx] requestWeChatJssdkSignAndConfig failed", msg, "htmlUrl=", htmlUrl);
|
|
|
|
|
+ if (isWeChatInAppBrowser() && isWxDebugOn()) window.alert(msg);
|
|
|
|
|
+ return false;
|
|
|
|
|
+ })
|
|
|
|
|
+ .finally(function () {
|
|
|
|
|
+ if (!weChatJssdkConfigured) wxJssdkInitPromise = null;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ return wxJssdkInitPromise;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function scheduleWeChatJssdkBootstrap() {
|
|
|
|
|
+ if (!shouldInitWeChatJssdkOnLoad()) return;
|
|
|
|
|
+ var attempts = 0;
|
|
|
|
|
+ function tick() {
|
|
|
|
|
+ attempts += 1;
|
|
|
|
|
+ if (weChatJssdkConfigured) return;
|
|
|
|
|
+ initWeChatOpenLaunchApp();
|
|
|
|
|
+ if (!weChatJssdkConfigured && attempts < 8 && typeof wx === "undefined") {
|
|
|
|
|
+ setTimeout(tick, 400);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (isIOSWeChatBrowser()) {
|
|
|
|
|
+ setTimeout(tick, 350);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ tick();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function showFabToast(msg, ms) {
|
|
|
|
|
+ var tip = String(msg || "").trim();
|
|
|
|
|
+ if (!tip) return;
|
|
|
|
|
+ var el = document.getElementById("openAppToast");
|
|
|
|
|
+ if (el) {
|
|
|
|
|
+ el.textContent = tip;
|
|
|
|
|
+ el.style.display = "block";
|
|
|
|
|
+ if (showFabToast._t) clearTimeout(showFabToast._t);
|
|
|
|
|
+ showFabToast._t = setTimeout(function () {
|
|
|
|
|
+ el.style.display = "none";
|
|
|
|
|
+ }, ms || 2800);
|
|
|
|
|
+ }
|
|
|
|
|
+ console.log("[openApp]", tip);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function showDownloadTip() {
|
|
|
|
|
+ var msg = "请到应用商店下载「U店在哪」";
|
|
|
|
|
+ if (typeof uni !== "undefined" && typeof uni.showToast === "function") {
|
|
|
|
|
+ uni.showToast({ title: msg, icon: "none", duration: 2500 });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ window.alert(msg);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function showAppOpenFailTip(msg) {
|
|
|
|
|
+ var tip = msg || "未能打开 App,请确认已安装最新版「U店在哪」。";
|
|
|
|
|
+ if (typeof uni !== "undefined" && typeof uni.showToast === "function") {
|
|
|
|
|
+ uni.showToast({ title: msg, icon: "none", duration: 2800 });
|
|
|
|
|
+ } else if (isWeChatInAppBrowser()) {
|
|
|
|
|
+ window.alert(tip);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ showFabToast(tip);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function launchAppDeepLink(deepLink) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ var a = document.createElement("a");
|
|
|
|
|
+ a.href = deepLink;
|
|
|
|
|
+ a.setAttribute("target", "_self");
|
|
|
|
|
+ document.body.appendChild(a);
|
|
|
|
|
+ a.click();
|
|
|
|
|
+ document.body.removeChild(a);
|
|
|
|
|
+ } catch (e1) {}
|
|
|
|
|
+ try {
|
|
|
|
|
+ window.location.href = deepLink;
|
|
|
|
|
+ } catch (e2) {}
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ function tryOpenHBuilderAppViaScheme() {
|
|
|
|
|
+ var deepLink = buildAppDeepLink();
|
|
|
|
|
+
|
|
|
|
|
+ if (typeof plus !== "undefined" && plus.runtime) {
|
|
|
|
|
+ var installed = null;
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (typeof plus.runtime.isApplicationExist === "function") {
|
|
|
|
|
+ installed = plus.runtime.isApplicationExist({
|
|
|
|
|
+ pname: APP_ANDROID_PACKAGE,
|
|
|
|
|
+ action: APP_IOS_URL_SCHEME,
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (e) {
|
|
|
|
|
+ console.warn(e);
|
|
|
|
|
+ }
|
|
|
|
|
+ try {
|
|
|
|
|
+ plus.runtime.openURL(deepLink);
|
|
|
|
|
+ } catch (e2) {
|
|
|
|
|
+ console.warn(e2);
|
|
|
|
|
+ if (installed === false) {
|
|
|
|
|
+ showDownloadTip();
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var done = false;
|
|
|
|
|
+ function finish() {
|
|
|
|
|
+ if (done) return;
|
|
|
|
|
+ done = true;
|
|
|
|
|
+ document.removeEventListener("visibilitychange", onVis);
|
|
|
|
|
+ window.removeEventListener("pagehide", onHide);
|
|
|
|
|
+ }
|
|
|
|
|
+ function onVis() {
|
|
|
|
|
+ if (document.visibilityState === "hidden") finish();
|
|
|
|
|
+ }
|
|
|
|
|
+ function onHide() {
|
|
|
|
|
+ finish();
|
|
|
|
|
+ }
|
|
|
|
|
+ document.addEventListener("visibilitychange", onVis);
|
|
|
|
|
+ window.addEventListener("pagehide", onHide);
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ launchAppDeepLink(deepLink);
|
|
|
|
|
+ } catch (e3) {
|
|
|
|
|
+ finish();
|
|
|
|
|
+ showDownloadTip();
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ window.setTimeout(function () {
|
|
|
|
|
+ finish();
|
|
|
|
|
+ }, 3200);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- function openApp() {
|
|
|
|
|
- var start = Date.now();
|
|
|
|
|
- window.location.href = APP_DEEPLINK;
|
|
|
|
|
- setTimeout(function () {
|
|
|
|
|
- if (Date.now() - start < 2800) {
|
|
|
|
|
- window.location.href = "https://www.ailien.shop/";
|
|
|
|
|
|
|
+ function tryOpenApp() {
|
|
|
|
|
+ if (isWeChatInAppBrowser()) {
|
|
|
|
|
+ if (!weChatJssdkConfigured) {
|
|
|
|
|
+ initWeChatOpenLaunchApp(true).then(function (ok) {
|
|
|
|
|
+ if (!ok) {
|
|
|
|
|
+ showAppOpenFailTip(wxInitLastError || "微信唤起 App 初始化失败");
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
}
|
|
}
|
|
|
- }, 2500);
|
|
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ tryOpenHBuilderAppViaScheme();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- document.getElementById("btnContinue").addEventListener("click", openApp);
|
|
|
|
|
|
|
+ if (isWeChatInAppBrowser()) {
|
|
|
|
|
+ document.body.classList.add("is-wechat");
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
|
|
+ bindWeChatLaunchTagEvents();
|
|
|
|
|
+ scheduleWeChatJssdkBootstrap();
|
|
|
|
|
+ document.getElementById("btnContinue").addEventListener("click", tryOpenApp);
|
|
|
render(parsePayload());
|
|
render(parsePayload());
|
|
|
})();
|
|
})();
|
|
|
</script>
|
|
</script>
|