// @ts-ignore (function () { const _window: any = window; const React = _window.React; const ReactDOM = _window.ReactDOM; const RXUI = _window.rxui; const ErrorBoundary = _window.ErrorBoundary; const Yoda = _window.Yoda; const weblog = _window.weblog; const getRequestAgent = _window.getRequestAgent; const VConsole = _window.VConsole; const { parse, RenderReact } = _window.xgCompilerWeb; const { serviceAgent, ENV } = _window.designerService; const envType: any = _window?.xgProjectJson?.envType || "prod"; const fileId = "--activityFileId--"; // 星辰activity_name const xcActivityName = "--xcActivityName--"; // @ts-ignore const projectJson: any = window.xgProjectJson; const globalServiceList = Symbol("globalServiceList"); _window[globalServiceList] = "--globalServiceList--"; const query = {}; location.search .slice(1) .split("&") .forEach((kv) => { const [key, value] = kv.split("="); query[key] = value; }); var __spreadArray = (this && this.__spreadArray) || function (to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; }; var opts_1 = { minPixelValue: 1, unitPrecision: 13, }; function pxTovw(opts) { var viewportUnit = "vw", viewportSize = 414; return function (m) { var $1 = m.replace("px", ""); var pixels = Number($1); if (isNaN(pixels)) return m; if (Math.abs(pixels) <= opts.minPixelValue) return m; var parsedVal = toFixed( (pixels / viewportSize) * 100, opts.unitPrecision ); return parsedVal === 0 ? "0" : parsedVal + viewportUnit; }; } function toFixed(number, precision) { var multiplier = Math.pow(10, precision + 1), wholeNumber = Math.floor(number * multiplier); return (Math.round(wholeNumber / 10) * 10) / multiplier; } var oriCreateElement = React.createElement; React.createElement = function (type, props) { var _a; var args = []; for (var _i = 2; _i < arguments.length; _i++) { args[_i - 2] = arguments[_i]; } if (props === null || props === void 0 ? void 0 : props.style) { Object.keys(props.style).forEach(function (key) { if (/[\d.]+(px)$/.test(props.style[key])) { props.style[key] = props.style[key].replace( /[\d.]+(px)$/g, function (e) { var res = pxTovw(opts_1); return res(e); } ); } }); } if ( (_a = props === null || props === void 0 ? void 0 : props.dangerouslySetInnerHTML) === null || _a === void 0 ? void 0 : _a.__html ) { props.dangerouslySetInnerHTML.__html = props.dangerouslySetInnerHTML.__html.replace( /style="[^\\"]*?"/g, function (e) { return e.replace(/[\d.]+(px)/g, function (e) { var res = pxTovw(opts_1); return res(e); }); } ); } return oriCreateElement.apply(void 0, __spreadArray([type, props], args)); }; function varClone(val) { if (val && typeof val === "object") { try { return JSON.parse(JSON.stringify(val)); } catch (ex) { return val; } } return val; } window.allLibs.comAray.push( { namespace: "mybricks.core-comlib.fn", runtime: () => {}, useComs: [], version: "1.0.0", }, { namespace: "mybricks.core-comlib.var", runtime: ({ data, outputs, inputs }) => { inputs["get"]((val, relOutpus) => { relOutpus["return"](varClone(data.val)); }); inputs["set"]((val) => { data.val = val; outputs["changed"](varClone(val)); }); }, useComs: [], version: "1.0.0", }, { namespace: "mybricks.core-comlib.module", runtime: ({ slots }) => { const names = Object.keys(slots); const slotName = names[0]; return slots[slotName].render(null, slotName); }, useComs: [], version: "1.0.0", }, { namespace: "mybricks.core-comlib.frame-output", runtime: () => {}, useComs: [], version: "1.0.0", }, { namespace: "mybricks.core-comlib.type-change", runtime: ({ data, outputs, inputs, onError }) => { inputs["from"]((val, relOutpus) => { const script = data.exchange && data.exchange.script; if (script) { let fn, returnVal, isOk; try { eval(`fn = ${script}`); returnVal = fn(val); isOk = true; } catch (ex) { onError(`数据转换错误:${ex.message}`); } if (isOk) { outputs["to"](returnVal); } } else { onError("未配置转换规则"); } }); }, useComs: [], version: "1.0.0", } ); function spliceOne(list, index) { for (let i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1) { list[i] = list[k]; } list.pop(); } function isAbsolute(pathname) { return pathname.charAt(0) === "/"; } function resolvePathname(to, from) { if (from === undefined) from = ""; const toParts = (to && to.split("/")) || []; let fromParts = (from && from.split("/")) || []; const isToAbs = to && isAbsolute(to); const isFromAbs = from && isAbsolute(from); const mustEndAbs = isToAbs || isFromAbs; if (to && isAbsolute(to)) { // to is absolute fromParts = toParts; } else if (toParts.length) { // to is relative, drop the filename fromParts.pop(); fromParts = fromParts.concat(toParts); } if (!fromParts.length) return "/"; let hasTrailingSlash; if (fromParts.length) { const last = fromParts[fromParts.length - 1]; hasTrailingSlash = last === "." || last === ".." || last === ""; } else { hasTrailingSlash = false; } let up = 0; for (let i = fromParts.length; i >= 0; i--) { const part = fromParts[i]; if (part === ".") { spliceOne(fromParts, i); } else if (part === "..") { spliceOne(fromParts, i); up++; } else if (up) { spliceOne(fromParts, i); up--; } } if (!mustEndAbs) for (; up--; up) fromParts.unshift(".."); if ( mustEndAbs && fromParts[0] !== "" && (!fromParts[0] || !isAbsolute(fromParts[0])) ) fromParts.unshift(""); let result = fromParts.join("/"); if (hasTrailingSlash && result.substr(-1) !== "/") result += "/"; return result; } /** * 打开新页面 */ function openPage( url: string, yoda: any, openOnNewPage: boolean = true ): void { if (!url) return; if (openOnNewPage == false || /^kwai:\/\/.+/.test(url)) { if (query["isPc"] === "1") { window.parent.location.href = url; } else { location.href = url; } return; } if (url[0] === ".") { url = resolvePathname(url, location.pathname); } if (url[0] === "/") { url = location.protocol + "//" + location.host + url; } if ( yoda && yoda.kwai && yoda.kwai.loadUrlOnNewPage && url.indexOf("http") === 0 ) { yoda.kwai.loadUrlOnNewPage({ url, type: "back" }); } else { if (query["isPc"] === "1") { window.parent.location.href = url; } else { location.href = url; } } } function rawBack(yoda: any) { let kwai = yoda?.kwai || yoda?.Kwai || {}; if (kwai.popBack) { kwai.popBack(); } else if (kwai.exitWebView) { kwai.exitWebView(); } else { history?.back(); } } /** * 返回 */ function back(yoda: any) { if ((window as any)._physicalBackCb) { (window as any)._physicalBackCb(); } else { rawBack(yoda); } } const docCookie = { getItem: function (sKey) { return ( decodeURIComponent( document.cookie.replace( new RegExp( "(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$" ), "$1" ) ) || null ); }, setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) { if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; } var sExpires = ""; if (vEnd) { switch (vEnd.constructor) { case Number: sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd; break; case String: sExpires = "; expires=" + vEnd; break; case Date: sExpires = "; expires=" + vEnd.toUTCString(); break; } } document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : ""); return true; }, removeItem: function (sKey, sPath, sDomain) { if (!sKey || !this.hasItem(sKey)) { return false; } document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : ""); return true; }, hasItem: function (sKey) { return new RegExp( "(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\=" ).test(document.cookie); }, keys: /* optional method: you can safely remove it! */ function () { var aKeys = document.cookie .replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "") .split(/\s*(?:\=[^;]*)?;\s*/); for (var nIdx = 0; nIdx < aKeys.length; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); } return aKeys; }, }; /** * 分享 */ function share(env, logger, shareParams, cb) { // env?.yoda?.ui?.showLoading('分享中...'); if (typeof env?.yoda?.kwai.share === "function") { if (shareParams?.subBiz) { // 自定义分享配置 env.yoda.Kwai.share( { param: { shareContent: "ACTIVITY", showSharePanel: true, shareObjectId: docCookie.getItem("ud"), ...shareParams, }, }, function (res) { typeof cb === "function" && cb(res); // env?.yoda?.ui?.hideLoading(); } ); } else { // 页面默认分享配置 env.kwai.share( { ...shareParams, }, function (res) { typeof cb === "function" && cb(res); // env?.yoda?.ui?.hideLoading(); } ); } } else { logger?.error("无法调起分享"); // env?.yoda?.ui?.hideLoading(); } } function fillProtocol(url) { if (/^\/\//.test(url)) { return "https:" + url; } return url; } function getIdcAvailHostname(hostname) { // @ts-ignore let domains = (window && window.DOMAINS) || ""; let result = "" + domains[hostname]; // 合法的 hostname 判断 if (!/^(?:[\w\-]+\.)+\w{2,}$/.test(result)) { result = hostname; } return result; } const localHostname = (location && location.hostname) || ""; const BACKUP_IDC_DOMAIN = ".kwaigobuy.com"; const backupIDCReg = new RegExp( BACKUP_IDC_DOMAIN.replace(/\./g, "\\.") + "$" ); const islocalKwaigobuy = backupIDCReg.test(localHostname); function getIdcAvailUrl(orgUrl) { let url = ""; try { url = new URL(fillProtocol(orgUrl)); } catch { // 提供的 orgUrl 为非法 url,或浏览器环境不支持 URL 对象的,全都原样返回 return orgUrl; } url.hostname = getIdcAvailHostname(url.hostname); // 兜底 idc 逃生。如果当前根域为 kwaigobuy 且 url.hostname 的根域为 kwaixiaodian // 时,强制切到 kwaigobuy 上来 if (islocalKwaigobuy) { url.hostname = url.hostname.replace( /\.kwaixiaodian\.com$/, BACKUP_IDC_DOMAIN ); } let result = url.toString(); if (url.pathname === "/" && !/\/$/.test(orgUrl)) { return result.replace(/\/$/, ""); } return result; } function isInClient(el) { let { top, right, bottom, left } = el.getBoundingClientRect(); let clientHeight = _window.innerHeight; let clientWidth = _window.innerWidth; return !( top > clientHeight || bottom < 0 || left > clientWidth || right < 0 ); } function cdnCut({ url, el }) { let handledUrl = url; const rect = el.getBoundingClientRect(); const rawWidth = rect.width || 200; const rawHeight = rect.height || 200; const radio = window.devicePixelRatio || 2; if (!url) return; let width = parseInt(rawWidth * radio, 10); let height = parseInt(rawHeight * radio, 10); let flag = ""; if (handledUrl.indexOf("?") > 0) { flag = "&"; } else { flag = "?"; } if ( handledUrl.indexOf("ali-ad") > -1 || handledUrl.indexOf("ali-ec") > -1 || handledUrl.indexOf("ali2.a.kwimgs.com") > -1 || handledUrl.indexOf("kcdn.staging.kuaishou.com") || handledUrl.indexOf("a.yximgs.com") ) { handledUrl += `${flag}x-oss-process=image/resize,m_fill,w_${width},h_${height}/format,jpg/interlace,1`; } else if (url.indexOf("tx-ad") > -1 || url.indexOf("tx-ec") > -1) { handledUrl += `${flag}imageView2/1/w/${width}/h/${height}/format/jpg/interlace/1`; } else if ( url.indexOf("s1.") > -1 || url.indexOf("s2.") > -1 || url.indexOf("eckwai.com") > -1 || url.indexOf(".ecukwai.") > -1 ) { handledUrl += `${flag}x-oss-process=image/resize,w_${width},h_${height},m_lfit,limit_0/auto-orient,0/quality,q_85`; } return handledUrl; } function checkAllImags() { const imgs = document.querySelectorAll("img"); const domLength = imgs.length; for (let inx = 0; inx < domLength; inx++) { const img = imgs[inx]; if (img.dataset && img.dataset.src) { if (!img["__render__"]) { if (isInClient(img)) { img.src = cdnCut({ url: img.dataset.src, el: img }); img["__render__"] = img.dataset.src; } } else { if (img["__render__"] !== img.dataset.src) { img.src = cdnCut({ url: img.dataset.src, el: img }); img["__render__"] = img.dataset.src; } } } } } function debounce(fn, delay) { let timer: any = 0; return function () { // @ts-ignore const context = this; const args = arguments; clearTimeout(timer); timer = setTimeout(function () { fn.apply(context, args); timer = 0; }, delay); }; } const pageComs = {}; const exposeNodeMap = {}; function genPage(page, allLibs, comEnv, { fileId, envType, xcActivityName }) { if (pageComs[page.id]) { return pageComs[page.id]; } const { mainModule, requireComs } = parse(page); const comDefs = {}; requireComs.forEach((ns) => { const onlyNs = ns.substring(0, ns.indexOf("@")); let comDef = findInLibs( (com) => `${com.namespace}@${com.version}` === ns, allLibs.comAray ) || findInLibs((com) => com.namespace === onlyNs, allLibs.comAray); if (!comDef) { throw new Error(`组件定义(${onlyNs})未找到.`); } comDefs[ns] = comDef.runtime; }); const Page = PageCom(mainModule, comDefs, comEnv, { fileId, envType, xcActivityName, }); return React.createElement(Page, { _onError_: (ex, type) => { console.error(ex); }, }); } function PageCom( mainModule, comDefs, comEnv, { fileId, envType, xcActivityName } ) { return function () { React.useEffect(() => { function collectLog() { let domList = document.querySelectorAll("[data-weblogger]"); domList.forEach((dom) => { let attr; try { const exposeString = dom.getAttribute("data-weblogger"); attr = JSON.parse(exposeString); // @ts-ignore // 老的逻辑 ['SHOW', {action, params: {}}] let type = attr[0]; let params = attr[1]; if (typeof type === "string") { switch (type) { case "SHOW": { if (!dom["__exposed__"]) { const key = Math.random(); exposeNodeMap[key] = exposeString; dom["__exposed__"] = key; if (!params.page) { params.page = pageParam; } weblog.collect(type, params); } else { if (exposeNodeMap[dom["__exposed__"]] !== exposeString) { exposeNodeMap[dom["__exposed__"]] = exposeString; if (!params.page) { params.page = pageParam; } weblog.collect(type, params); } } break; } } } else { // 重构流程 [{triggrName: 'SHOW', params: {}, action}, {triggrName: 'CLICK', params: {}, action},] attr?.forEach((item) => { const newParams = Object.assign( {}, { action: item.action, params: item.params, } ); switch (item.triggerTime) { case "SHOW": { if (!dom["__exposed__"]) { const key = Math.random(); exposeNodeMap[key] = exposeString; dom["__exposed__"] = key; if (!newParams.page) { newParams.page = pageParam; } weblog.collect(item.triggerTime, newParams); } else { if ( exposeNodeMap[dom["__exposed__"]] !== exposeString ) { exposeNodeMap[dom["__exposed__"]] = exposeString; if (!newParams.page) { newParams.page = pageParam; } weblog.collect(item.triggerTime, newParams); } } break; } case "CLICK": { if (!dom["__binded__"]) { dom.addEventListener("click", function (e) { const bindedParam = JSON.parse( e.currentTarget.dataset?.weblogger || "[]" ); let clickParam = newParams; if (bindedParam?.[1]?.triggerTime === "CLICK") { clickParam = { action: bindedParam?.[1]?.action, params: bindedParam?.[1]?.params, }; } else if ( bindedParam?.[0]?.triggerTime === "CLICK" ) { clickParam = { action: bindedParam?.[0]?.action, params: bindedParam?.[0]?.params, }; } weblog.collect(item.triggerTime, clickParam); }); dom["__binded__"] = true; } } } }); } } catch (e) {} }); } const thCheck = debounce(checkAllImags, 10); var observer = new MutationObserver(checkAllImags); observer.observe(document.body, { attributeFilter: ["data-src"], attributes: true, childList: true, subtree: true, }); var observer2 = new MutationObserver(collectLog); observer2.observe(document.body, { attributeFilter: ["data-weblogger"], attributes: true, childList: true, subtree: true, }); setTimeout(() => { window.addEventListener("scroll", thCheck); }, 1000); const pathName = location.pathname?.substring( location.pathname?.lastIndexOf("/") + 1 ); const queryObject = parseQuery(); const pageParam = pathName ? `OP_ACTIVITY_FZ_${pathName}` : "MERCHANT_FANGZHOU_ACTIVITY"; const pvParam = { type: "enter", page: pageParam, params: { activity_name: xcActivityName ? xcActivityName + "" : "", activity_id: fileId, file_id: fileId, entry_src: queryObject ? queryObject["entry_src"] : "", hyId: queryObject ? queryObject["hyId"] : "", push_id: queryObject ? queryObject["push_id"] : "", }, }; if (queryObject["__LOG__"]) { let extraParam = {}; try { extraParam = JSON.parse(decodeURIComponent(queryObject["__LOG__"])); } catch (e) {} Object.assign(pvParam.params, extraParam); } weblog?.sendImmediately("PV", pvParam); weblog?.collect("CUSTOM", { key: "FANGZHOU_PV", value: { activity_id: fileId, }, }); return () => { window.removeEventListener("scroll", thCheck); }; }, []); function beautifulLog(type, name, content, isBaseType) { const BASE_COLOR = "#606060"; const INPUT_COLOR = "#42c02e"; const OUTPUT_COLOR = "#1475b2"; if (typeof name !== "string") { console[type](name, content); return; } if (name.match(/^程序运行 /)) { const textArr = name.split(" ").filter((item) => item); const ioType = textArr.pop(); const comName = textArr.join(" "); if (isBaseType) { console.log( `%c ${comName} %c ${ioType} %c ${content}`, `padding: 2px; border-radius: 3px 0 0 3px; color: #fff; background: ${BASE_COLOR};`, `padding: 2px; border-radius: 0 3px 3px 0; color: #fff; background: ${ ioType === "传入" ? INPUT_COLOR : OUTPUT_COLOR };`, "" ); } else { console.groupCollapsed( `%c ${comName} %c ${ioType}`, `padding: 2px; border-radius: 3px 0 0 3px; color: #fff; background: ${BASE_COLOR};`, `padding: 2px; border-radius: 0 3px 3px 0; color: #fff; background: ${ ioType === "传入" ? INPUT_COLOR : OUTPUT_COLOR };` ); console[type](content); console.groupEnd(); } } else { if (isBaseType) { console.log( `%c ${name} %c ${content}`, `padding: 2px; border-radius: 3px; color: #fff; background: ${BASE_COLOR};`, "" ); } else { console.groupCollapsed( `%c ${name} `, `padding: 2px; border-radius: 3px; color: #fff; background: ${BASE_COLOR};` ); console[type](content); console.groupEnd(); } } } const coms = RenderReact({ mainModule: mainModule, comDefs: comDefs, get inputParams() {}, inputs: { onBack(fn) { if (fn) { _window._physicalBackCb = fn; } else { _window._physicalBackCb = undefined; } }, onReentry(fn) { if (fn) { _window._onReentry = fn; } else { _window._onReentry = undefined; } }, // onError(fn){ // setTimeout(()=>{fn(3)},2000) // //use fn to pipe in // } }, outputs: { test(value) {}, }, env: comEnv, runtimeCfg: { get staging() { return envType === "staging"; }, get prt() { return envType === "prt"; }, get prod() { return envType === "prod"; }, }, logs: { info({ catelog, content, isBaseType, focus, blur }) { if (envType === "prod") { // prod环境 将复杂log改成 ... beautifulLog("info", catelog, isBaseType ? content : "...", true); } else { beautifulLog("info", catelog, content, isBaseType); } }, error({ catelog, content, isBaseType, focus, blur }) { beautifulLog("warn", catelog, content, isBaseType); }, }, events: [ { type: "jump", title: "跳转", exe({ options }) { let handledUrl = getIdcAvailUrl(options.url); openPage(handledUrl, comEnv.yoda, true); }, options: [ { id: "url", title: "地址", editor: "textarea", }, ], }, { type: "back", title: "返回上一级", exe() { back(comEnv.yoda); }, }, { type: "share", title: "分享", exe() { share(comEnv, void 0, {}, () => {}); }, }, ], logger: (comDef) => getComLogger(comDef), createPortal: (com) => ReactDOM.createPortal(com, document.body), }); const viewModel = mainModule.slot; let classes = ["-page"], style; const viewStyle = viewModel.style; if (viewStyle) { style = { // paddingLeft: viewStyle.paddingLeft || 0, // paddingTop: viewStyle.paddingTop || 0, // paddingRight: viewStyle.paddingRight || 0, // paddingBottom: `calc( ${viewStyle.paddingRight || 0} + constant(safe-area-inset-bottom))`, // paddingBottom: `calc(${viewStyle.paddingBottom || 0}px + env(safe-area-inset-bottom))`, // paddingBottom: viewStyle.paddingBottom || 0, // backgroundColor: viewStyle.backgroundColor || 'RGBA(255,255,255,.8)', }; if (viewStyle.layout === "flex-column") { classes.push("lyFlexColumn"); } else if (viewStyle.layout === "flex-row") { classes.push("lyFlexRow"); } const justifyContent = viewStyle.justifyContent; if (justifyContent) { if (justifyContent.toUpperCase() === "FLEX-START") { classes.push("justifyContentFlexStart"); } else if (justifyContent.toUpperCase() === "CENTER") { classes.push("justifyContentFlexCenter"); } else if (justifyContent.toUpperCase() === "FLEX-END") { classes.push("justifyContentFlexFlexEnd"); } else if (justifyContent.toUpperCase() === "SPACE-AROUND") { classes.push("justifyContentFlexSpaceAround"); } else if (justifyContent.toUpperCase() === "SPACE-BETWEEN") { classes.push("justifyContentFlexSpaceBetween"); } } const alignItems = viewStyle.alignItems; if (alignItems) { if (alignItems.toUpperCase() === "FLEX-START") { classes.push("alignItemsFlexStart"); } else if (alignItems.toUpperCase() === "CENTER") { classes.push("alignItemsFlexCenter"); } else if (alignItems.toUpperCase() === "FLEX-END") { classes.push("alignItemsFlexFlexEnd"); } } } return React.createElement( ErrorBoundary, {}, React.createElement( "div", { style: style, className: classes.join(" ") }, coms ) ); }; } function findInLibs(fn, libs) { let rtn; libs.find((lib) => { if (lib && Array.isArray(lib.comAray)) { return (rtn = findInLibs(fn, lib.comAray)); } else { return fn(lib) && (rtn = lib); } }); return rtn; } const Logger = { warn(cate = "未分类", content) { console.warn(`【${cate}】`, content); }, error(cate = "未分类", content) { console.error(`【${cate}】`, content); }, }; const parseQuery = function () { let search = location.search; let obj = {}; let str = search.substr(1); let arr = str.split("&"); for (let i = 0; i < arr.length; i++) { let newArr = arr[i].split("="); obj[newArr[0]] = newArr[1]; } return obj; }; function getComLogger(comDef) { return { trace(msg, catelog) { console.info(comDef.title + (catelog ? `-${catelog}` : ""), msg); _window.traceLoggerH5?.push({ comTitle: comDef.title, category: catelog || "-", content: msg, type: "trace", createTime: Date.now(), }); }, info(msg, catelog) { console.info(comDef.title + (catelog ? `-${catelog}` : ""), msg); _window.traceLoggerH5 && _window.traceLoggerH5.push({ comTitle: comDef.title, category: catelog || "-", content: msg, type: "info", createTime: Date.now(), }); }, warn(msg, catelog) { console.warn(comDef.title + (catelog ? `-${catelog}` : ""), msg); _window.traceLoggerH5 && _window.traceLoggerH5.push({ comTitle: comDef.title, category: catelog || "-", content: msg, type: "warn", createTime: Date.now(), }); }, error(msg, catelog) { console.error(comDef.title + (catelog ? `-${catelog}` : ""), msg); _window.traceLoggerH5 && _window.traceLoggerH5.push({ comTitle: comDef.title, category: catelog || "-", content: msg, type: "error", createTime: Date.now(), }); }, }; } function ajax(requestAgent, url, opts?) { if (typeof url === "object") { opts = url; } else { opts = Object.assign({ url: url, method: "get" }, opts); } var Logger = getComLogger({ title: "ajax请求" }); Logger.info(`请求参数:${JSON.stringify(opts)}`, `开始请求:${url}`); if (!opts.url) { Logger.error("ajax", opts); return Promise.reject(null); } return new Promise((resolve, reject) => { requestAgent(opts) .then((resp) => { if (resp && resp.status === 200) { resolve(resp.data); Logger.info( `请求参数:${JSON.stringify(opts)}`, `请求成功:${url}:` ); if (window._fmpTimerId) { // setTimeout(() => { clearTimeout(window._fmpTimerId); window._fmpTimerId = null; weblog?.fmp(); setTimeout(() => { weblog?.collect("CUSTOM", "FANGZHOU_CUSTOM_H5_FMP", { host: location.host, url: location.href, cost: new Date().getTime() - window.performance?.timing?.navigationStart, message: "1", }); }, 500); window._fzPerformanceData.fmpPoint = Date.now(); console.log("fmp trigger after xhr"); // }) } } else { reject(resp); Logger.warn( `返回信息:${JSON.stringify(resp)}`, `请求失败:${url}` ); if (window._fmpTimerId) { // setTimeout(() => { clearTimeout(window._fmpTimerId); window._fmpTimerId = null; weblog?.fmp(); setTimeout(() => { weblog?.collect("CUSTOM", "FANGZHOU_CUSTOM_H5_FMP", { host: location.host, url: location.href, cost: new Date().getTime() - window.performance?.timing?.navigationStart, message: "1", }); }, 500); window._fzPerformanceData.fmpPoint = Date.now(); console.log("fmp trigger after xhr"); // }) } } }) .catch((error) => { reject(error); Logger.error( `异常信息:${JSON.stringify(error)}`, `请求异常:${url}` ); if (window._fmpTimerId) { // window._fzPerformanceData.firstRequestArrive = Date.now(); // setTimeout(() => { clearTimeout(window._fmpTimerId); window._fmpTimerId = null; weblog?.fmp(); // 延迟上报 setTimeout(() => { weblog?.collect("CUSTOM", "FANGZHOU_CUSTOM_H5_FMP", { host: location.host, url: location.href, cost: new Date().getTime() - window.performance?.timing?.navigationStart, message: "1", }); }, 500); window._fzPerformanceData.fmpPoint = Date.now(); console.log("fmp trigger after xhr"); // }) } }); }); } function ajaxProxy(requestAgent, url, opts?) { if (typeof url === "object") { opts = url; } else { opts = Object.assign({ url: url, method: "get" }, opts); } if (!opts.url) { Logger.error("ajax", opts); return Promise.reject(null); } const { search, pathname, host, protocol } = new URL(opts.url); const options = { ...opts }; options.headers = { ...options.headers, "x-target-host": `${protocol}//${host}`, }; if (host.includes(".staging")) { options.headers["x-target-staging"] = true; } const laneId = projectJson.serviceTemplate?.[envType]?.laneId; if (laneId) { options.headers["x-target-laneId"] = `{"laneId":"${laneId}"}`; } const { cookie = "", Cookie = "", ...others } = options.headers; options.headers = { ...others, }; if (cookie || Cookie) { options.headers["x-target-cookie"] = cookie || Cookie; } const { url: targetUrl, ...config } = options; var Logger = getComLogger({ title: "ajax请求" }); Logger.info(`请求参数:${JSON.stringify(opts)}`, `开始请求:${url}`); return new Promise((resolve, reject) => { requestAgent({ ...config, url: `/app/eca/desn/proxy${pathname}${search}`, }) .then((resp) => { if (resp && resp.status === 200) { resolve(resp.data); Logger.info( `请求参数:${JSON.stringify(opts)}`, `请求成功:${url}:` ); } else { reject(resp); Logger.warn( `返回信息:${JSON.stringify(resp)}`, `请求失败:${url}` ); } }) .catch((error) => { reject(error); Logger.error( `异常信息:${JSON.stringify(error)}`, `请求异常:${url}` ); }); }); } function getCookies(): any { return document.cookie.split("; ").reduce((s, e) => { const p = e.indexOf("="); s[e.slice(0, p)] = e.slice(p + 1); return s; }, {}); } async function yodaShare( yoda, shareConfig, openShare, shareParams, cb, paramsForLog ) { // 未开启分享或分享的subBiz不存在 if (!openShare || !shareConfig.subBiz) return; try { await yoda.ready(); const logParams = Object.assign( { share_source: "FANGZHOU_H5", share_scene: "", }, paramsForLog ); let configParam = { subBiz: shareConfig.subBiz, showSharePanel: true, shareObjectId: `FANGZHOU_${shareConfig.activityToken}`, logParams: JSON.stringify(logParams), }; if (typeof shareParams === "object") { configParam = Object.assign(configParam, shareParams); } // //116返场特殊需求 // if(configParam.subBiz === "FANGZHOU_DFODMRLDALU") { // configParam.subBiz = "SHOP_FANCHANG"; // } const res = await yoda.Kwai?.share({ param: configParam }); typeof cb === "function" && cb(res); if (res.result !== 1) { weblog.sendImmediately("CUSTOM", { key: "FANGZHOU_SHARE_SUCCESS", value: { subBiz: shareConfig.subBiz, }, }); } else { weblog.sendImmediately("CUSTOM", { key: "FANGZHOU_SHARE_ERROR", value: { subBiz: shareConfig.subBiz, errorMsg: "接口失败", }, }); } return res; } catch (e) { var Logger = getComLogger({ title: "yoda分享" }); Logger.info(`分享失败:${JSON.stringify(e)}`, shareConfig.subBiz); weblog.sendImmediately("CUSTOM", { key: "FANGZHOU_SHARE_ERROR", value: { subBiz: shareConfig.subBiz, errorMsg: "分享调用失败", }, }); } } function log(url) { if (!url) return; weblog.sendImmediately("CUSTOM", { key: "FANGZHOU_IMAGE_ERROR", value: { imageUrl: url, pageUrl: location.href, }, }); } const loadImg = (url) => { if (!url) return Promise.reject(null); return new Promise((resolve, reject) => { const img = new Image(); img.src = url; img.onload = () => { resolve(url); }; img.onerror = () => { reject(url); }; }); }; // CDN 切换重试 async function retry(url, node) { if (!url || !node) return; const cdnHosts = [ "ali2.a.kwimgs.com", `h1.static.yximgs.com`, `static.yximgs.com`, "ali-ec.static.yximgs.com", "f2.eckwai.com", "js-ec.static.yximgs.com", ]; const tryCdnHosts = [ "ali2.a.kwimgs.com", "tx2.a.kwimgs.com", "ali-ec.static.yximgs.com", "f2.eckwai.com", "js-ec.static.yximgs.com", ]; const m = url.match(/^http(s)?:\/\/(.*?)\//); const host = m && m[2]; let success = false; if (host && cdnHosts.includes(host)) { cdnHosts.splice(cdnHosts.indexOf(host), 1); const urls = tryCdnHosts.map((cdn) => { return url.replace("http:", "https:").replace(host, cdn); }); for (const item of urls) { try { const src = await loadImg(item); node.src = src; success = true; break; } catch (error) { // console.log(error) } } if (!success) { node.style.display = "none"; } } } _window.addEventListener( "error", (event) => { const node = event.target as any; if (node && node.nodeName && node.nodeName.toLowerCase() == "img") { const url = node.src; retry(url, node); setTimeout((v) => log(url)); } }, true ); /** * 隐藏页面层级(H5 和 Native)的loading */ function hideLoadingPage() { try { // 隐藏 Loading if (projectJson.pubLoadingType === "h5") { const loadingDom = document.querySelector("#loading"); loadingDom && ((loadingDom as HTMLElement).style.display = "none"); } // loading方案配置项更改为h5/无,使用yoda的loading最终还是在url上拼接相应参数 // else if (projectJson.pubLoadingType === 'yoda') { // if (Yoda && typeof Yoda.ready === 'function') { // Yoda.ready(() => { // if (!Yoda.ui || !Yoda.ui.hideLoadingPage) return; // Yoda.ui.hideLoadingPage(); // }); // } // } } catch (e) { console.log("hideLoadingPage Error: ", e); } } // const sentryConfig = { // dsn: `https://a022629d68bd49648e7064366a7e831b@${ // envType === 'prod' // ? 'sentry.kuaishou.com' // : 'sentry-web.corp.kuaishou.com' // }/1489`, // release: 'FANGZHOU_' + '--activitySentryFileId--', // } // Sentry.init({ // ...sentryConfig, // sampleRate: 1, // environment: envType // }); if (Yoda && typeof Yoda.ready === "function") { Yoda.ready(() => { // 物理返回 if ( (window as any)._physicalBackCb && typeof Yoda?.kwai?.setPhysicalBackButton == "function" ) { Yoda.kwai.setPhysicalBackButton({ onClick: (window as any)._physicalBackCb, }); console.log("_physicalBackCb injected"); } // 返回当前页面 // yoda已知bug 在页面第一次访问时会调用 native_reentry // 兼容方案 在页面离开后注册返回监听事件 if ((window as any)._onReentry) { Yoda?.kwai?.on({ type: "native_reentry", handler: (window as any)._onReentry, }); } // 状态栏字体颜色 if (typeof Yoda?.kwai?.setStatusBarStyle == "function") { const { statusBarStyle } = projectJson; if (statusBarStyle !== -1) { Yoda.kwai.setStatusBarStyle({ style: typeof statusBarStyle === "undefined" ? 1 : statusBarStyle, }); } } }); } const requestAgent = getRequestAgent(); // const requestAgent = app.create({ // kpn: 'KUAISHOU', //快手产品名称,用于区分来源 在快手app端是KUAISHOU,极速版是NEBULA,pc端需要去快手产品中台自行注册 // kpf: '', // 快手产品平台,用于区分来源,默认会设置,可不传 // Yoda, // 目前是在app端sig3签名用 // logConfig: { // logger: weblog // 用来网络库异常、接口日志收集 // }, // traceIdGenerator: genTraceId, // debounceConfig: { // time: 300 // 请求防抖时效,默认为300毫秒 // }, // formatResponse(response) { // return response; // } // }); function createPxReplace(opts?, viewportUnit?, viewportSize?) { if (opts === void 0) { opts = { minPixelValue: 1, unitPrecision: 13, }; } if (viewportUnit === void 0) { viewportUnit = "vw"; } if (viewportSize === void 0) { viewportSize = 414; } return function (m) { var $1 = m.replace("px", ""); var pixels = Number($1); if (isNaN(pixels)) return m; if (Math.abs(pixels) <= opts.minPixelValue) return m; var parsedVal = toFixed( (pixels / viewportSize) * 100, opts.unitPrecision ); return parsedVal === 0 ? "0" : parsedVal + viewportUnit; }; } function toFixed(number, precision) { var multiplier = Math.pow(10, precision + 1), wholeNumber = Math.floor(number * multiplier); return (Math.round(wholeNumber / 10) * 10) / multiplier; } const useAjaxProxy = (url: string = "", opts: any) => { // if (envType === "prod") { // return ajax(requestAgent, url, opts); // } const curDomainObj = projectJson.serviceTemplate?.[envType]; const domain = curDomainObj?.domain || "https://fangzhou.kwaixiaodian.com"; console.log("domain", `${domain}${url}`); return ajaxProxy( requestAgent, domain && !url.startsWith("http") ? `${domain}${url}` : url, opts ); }; function formatTheme(themes: any[]) { const bgPage = themes.find( (theme) => theme.name === "--color-bg-page" )?.value; const bgPrimary = themes.find( (theme) => theme.name === "--color-bg-primary" )?.value; const bgSecondary = themes.find( (theme) => theme.name === "--color-bg-secondary" )?.value; const fontPrimary = themes.find( (theme) => theme.name === "--color-font-primary" )?.value; const fontSecondary = themes.find( (theme) => theme.name === "--color-font-secondary" )?.value; return { bgPage, bgPrimary, bgSecondary, fontPrimary, fontSecondary }; } //组件运行时环境配置 const comEnv = { pageType: "H5", get projectId() { return fileId; }, getPageCode() { let uri = projectJson.uri; return `OP_ACTIVITY_FZ_${uri.split("/").pop()}`; }, get params() { return parseQuery(); }, // get assets() { // if (!BusiCfg.assets) { // throw new Error(`${projectJson.busiType}.assets未定义.`) // } // return BusiCfg.assets // }, createPortal(children) { return ReactDOM.createPortal(children, document.body); }, // getConfig(key) {// 获取配置项 // return new Promise(((resolve, reject) => {///TODO 兜底config // getCfgProcessor((next, cache) => { // try { // if (typeof cache['global'] === 'object') { // resolve(key ? cache['global'][key] : cache['global']) // next() // } else { // if (BusiCfg.globalConfigUrl) { // const opt = getServiceOpt(BusiCfg.globalConfigUrl) // // ajax(opt).then(data => { // if (typeof data === 'object') { // if (data.result === 1) { // cache['global'] = data.data // // resolve(key ? cache['global']?.[key] : cache['global']) // // next() // } else { // reject(data.err_msg) // // next() // } // } else { // reject(data) // // next() // } // }).catch(err => { // reject(err) // // next() // }) // } else { // reject(new Error(`${projectJson.busiType}.globalConfigUrl.`)) // // next() // } // } // } catch(e) { // console.log('getConfig Error: ', e) // } finally { // hideLoadingPage() // } // }) // })) // }, login(forceLogin?): Promise<{}> { return new Promise<{}>((resolve, reject) => { const cookies = getCookies(); const ifLogin = (cookies.ud && +cookies.ud !== 0) || (cookies.userId && +cookies.userId !== 0); /////TODO //1. Yoda.Kwai.isLogin(); //2. Yoda.callback if (!ifLogin) { ///TODO 两次问题 if (forceLogin === undefined || forceLogin) { if (Yoda && Yoda.Kwai) { Yoda.Kwai.login({}, (res) => { if (res.result === 1) { location.reload(); //登录成功页面刷新 } }); } else { reject(`Yoda&&Yoda.Kwai 未定义,请在端内调试.`); } } else { reject(`User not login.`); } } else { resolve({ id: cookies.ud || cookies.userId }); } }); }, get ajax() { //ajax return ( url: string, opts: { method: "get" | "post" }, useProxy?: boolean ) => { // debugger; if (!url || typeof url !== "string") { throw new Error(`url is undefined`); } if (useProxy) { return useAjaxProxy(url, opts); } // 直连,不走代理 return ajax(requestAgent, url, opts); }; }, weblog: weblog, get yoda() { return Yoda; }, callService(id: number, params: any) { return serviceAgent(id, params, { context: { projectData: projectJson }, publishEnv: envType, useProxyAfterPublish: envType !== ENV.PROD, prefix: "/app/eca/desn/proxy", agent: requestAgent, }); }, kwai: { share(shareParams: any, cb: any, extraLogInfo?: Record) { return yodaShare( Yoda, projectJson.shareConfig, projectJson.openShare, shareParams, cb, extraLogInfo ); }, }, lazyLoadImage: debounce(checkAllImags, 10), pxTovw, themes: formatTheme(projectJson?.runtimePages?.themes || []), }; if (projectJson.pubShowVConsole) { try { const vConsole = new VConsole(); const clearStoragePlugin = new VConsole.VConsolePlugin( "clearStorage", "清理缓存" ); clearStoragePlugin.on("renderTab", function (callback) { var html = '
点击下面确认按钮,清理缓存
'; callback(html); }); clearStoragePlugin.on("addTool", function (callback) { var button = { name: "确认", onClick: function (event) { if (_window.confirm) { const result = _window.confirm(`是否确认清理缓存?`); if (!result) { return false; } } if (!!_window.localStorage) { try { localStorage.clear(); location.reload(); } catch (e) { alert("localStorage.clear() fail."); } } }, }; callback([button]); }); vConsole.addPlugin(clearStoragePlugin); // vConsole.removePlugin('storage') } catch (ex) { Logger.error("vconsole", ex); } } function themeInject() { const themes = projectJson.runtimePages.themes; if (Array.isArray(themes)) { themes.map((item) => { document.body.style.setProperty(item.name, item.value); }); } else if (themes) { Object.entries(themes).map(([name, value]: [string, string]) => { document.body.style.setProperty(name, value); }); } } themeInject(); const PageJSX = genPage(projectJson.runtimePages, window.allLibs, comEnv, { fileId, envType, xcActivityName, }); const appView: HTMLElement = document.querySelector("#appview"); const statusBarHeight = _window.statusBarHeight || 0; if (projectJson.useSafeBarTop && statusBarHeight) { const safeBar: HTMLElement = document.querySelector("#safeBar"); safeBar.style.marginBottom = "-1px"; safeBar.style.height = createPxReplace()(statusBarHeight + "px"); } appView.style.visibility = "visible"; hideLoadingPage(); const ua = navigator.userAgent; let isMobile = false; if (ua) { isMobile = /(iPhone|iPod|iPad|Android|ios)/i.test(ua) || /AppleWebKit.*Mobile.*/i.test(ua); } if (isMobile || query["isPc"] === "1") { ReactDOM.render(PageJSX, appView); } else { const RenderIframe = () => { return React.createElement("iframe", { src: location.href + `${location.search ? "&" : "?"}isPc=1`, style: { borderWidth: 0, width: "100%", maxWidth: "640", height: "100%", boxShadow: "0 2px 6px #aaa", }, }); }; const showQRcode = !query["hideQRcode"]; const QRCode = () => { React.useEffect(() => { if (showQRcode) { const script = document.createElement("script"); script.src = "https://f2.eckwai.com/udata/pkg/eshop/fangzhou/pub/pkg/qrcode/qrcode.js"; script.onload = () => { window.QRCode.toCanvas( document.getElementById("preview-qrcode"), `${location.href}${location.search ? "&" : "?"}layoutType=4`, { height: 150, width: 150, }, function (error) { if (error) console.error(error); } ); }; document.body.appendChild(script); } }, []); return React.createElement( "div", { style: { width: "100%", maxWidth: 280, display: "flex", flexDirection: "column", alignItems: "center", marginLeft: 10, }, }, showQRcode && React.createElement( "div", { style: { marginTop: 10, }, }, React.createElement( "div", { style: { textAlign: "center", }, }, "建议使用快手APP扫码预览" ) ), showQRcode && React.createElement( "div", { style: { width: 150, height: 150, display: "flex", justifyContent: "center", position: "relative", }, }, React.createElement("div", { style: { width: 20, height: 20, left: "50%", top: "50%", transform: "translate(-50%, -50%)", position: "absolute", backgroundSize: "contain", backgroundImage: "url(https://f2.eckwai.com/udata/pkg/eshop/fangzhou/images/kwai_icon.c84a6252fe8e3e37.png)", }, }), React.createElement("canvas", { id: "preview-qrcode", }) ) ); }; const Container = () => { return React.createElement( "div", { style: { display: "flex", maxWidth: 900, width: "100%", height: "100vh", position: "absolute", left: "50%", transform: "translateX(-50%)", marginLeft: 140, }, }, React.createElement(RenderIframe, null), React.createElement(QRCode, null) ); }; ReactDOM.render(React.createElement(Container, null), appView); } })();