...">
,需要通过父级DOM结构来判断
*/
var trackActionPhone = function (node) {
var nodeInnerText = node.innerText || '';
if (!limitRegLength(nodeInnerText)) return;
var nodeText = trimText(nodeInnerText);
if (nodeText.length < 5 || nodeText.length > 20) return false;
var type =
arguments.length > 1 && arguments[1] !== undefined
? arguments[1]
: 'click';
var str = trimText(node.href || node.innerHTML || '');
if (phoneReg.test(str) && numUseReg.test(str)) {
_paq.push(['trackEvent', type, 'phone', nodeText]);
return true;
}
/** 排查父级嵌套非标签场景,并且对dom的正则校验做一个性能兜底,通过控制innerText的长度,来确保正则的性能 */
var fatherText = trimText(node.parentNode.innerText || '');
if (fatherText.length < 5 || fatherText.length > 20) return false;
var fatherDom = trimText(node.parentNode.innerHTML || '');
if (phoneReg.test(fatherDom) && numUseReg.test(fatherDom)) {
_paq.push(['trackEvent', type, 'phone', nodeText]);
return true;
}
return false;
};
window.addEventListener('click', function (e) {
var node = e.target;
/** 社媒点击 */
var appName = '';
var getAppAriaLabel =
node.ariaLabel || node.parentNode.ariaLabel || '';
if (mediaList.includes(getAppAriaLabel.toLowerCase())) {
appName = getAppAriaLabel;
}
if (
!appName &&
node.nodeName &&
node.nodeName.toLowerCase() === 'a'
) {
appName = getMediaName(node.href) || getMediaName(node.alt);
}
if (
!appName &&
node.nodeName &&
node.nodeName.toLowerCase() === 'img'
) {
appName = getMediaName(node.alt) || getMediaName(node.src);
}
if (
!appName &&
node.nodeName &&
node.nodeName.toLowerCase() === 'i'
) {
appName = getMediaName(node.className);
}
if (appName) {
_paq.push(['trackEvent', 'click', 'contactApp', appName]);
return;
}
/** 联系方式点击 */
if (trackActionPhone(node, 'click')) return;
if (node.nodeName && node.nodeName.toLowerCase() === 'a') {
var val = node.href;
if (!limitRegLength(val)) return;
if (emailReg.test(val)) {
_paq.push(['trackEvent', 'click', 'email', val]);
return;
}
}
if (node.nodeName && node.nodeName.toLowerCase() === 'i') {
var val = node.className;
var content = node.parentNode.href || '';
if (val.includes('email')) {
_paq.push(['trackEvent', 'click', 'email', content]);
return;
}
}
var nodeChildList = node.childNodes;
for (var i = 0; i < nodeChildList.length; i++) {
if (nodeChildList[i].nodeType !== 3) continue;
var val = nodeChildList[i].textContent.replace(/\s?:?/g, '');
if (!limitRegLength(val)) continue;
if (emailReg.test(val)) {
_paq.push(['trackEvent', 'click', 'email', val]);
return;
}
}
trackNumberData(node);
});
window.addEventListener('copy', function (e) {
if (trackActionPhone(e.target, 'copy')) return;
var text = e.target.textContent;
if (!text) return;
var val = text.replace(/\s:?/g, '');
if (!limitRegLength(val)) return;
if (emailReg.test(val)) {
_paq.push(['trackEvent', 'copy', 'email', val]);
return;
}
trackNumberData(e.target);
});
}
trackContactInit();
/**
* 基于custom_inquiry_form.js 以及 form.js 对于询盘表单提交的实现,来反推询盘表单的input标签触发,用来收集意向客户
* 1. 缓存的KEY:TRACK_INPUT_ID_MTM_00;
* 2. 缓存策略 - lockTrackInput:单个页面内,10分钟内,不重复上报
*/
function trackActionInput() {
const CACHE_KEY = 'TRACK_INPUT_ID_MTM_00';
const pathName = window.location.hostname + window.location.pathname;
var lockTrackInput = function () {
try {
const lastCacheData = localStorage.getItem(CACHE_KEY);
if (!lastCacheData) return false;
const cacheData = JSON.parse(lastCacheData);
const cacheTime = cacheData[pathName];
if (!cacheTime) return false;
return Date.now() - cacheTime < 1000 * 60 * 10; // 10分钟内,不重复上报
} catch (error) {
console.error('lockTrackInput Error', error);
return false;
}
};
var setInputTrackId = function () {
try {
const curCacheData = localStorage.getItem(CACHE_KEY);
if (curCacheData) {
const cacheData = JSON.parse(curCacheData);
cacheData[pathName] = Date.now();
localStorage.setItem(CACHE_KEY, JSON.stringify(cacheData));
return;
}
const cacheData = {
[pathName]: Date.now(),
};
localStorage.setItem(CACHE_KEY, JSON.stringify(cacheData));
} catch (error) {
console.error('setInputTrackId Error', error);
}
};
var getInputDom = function (initDom) {
var ele = initDom;
while (ele) {
/**
* isWebSiteForm 是站点的表单
* isChatWindowForm 是聊天窗口的表单
*/
/** 旧模板表单 */
var isWebSiteForm = !!(
/crm-form/i.test(ele.className) && ele.querySelector('form')
);
/** 1:新模板自定义表单、2:Get a Quote 弹框表单 */
var isWebSiteFormNew = !!(
/inquiry/i.test(ele.className) && ele.querySelector('form')
);
if (isWebSiteForm || isWebSiteFormNew) {
_paq.push(['trackEvent', 'formInquiry', 'formInput', 'page']);
setInputTrackId();
return;
}
/** Mkt会话触达-聊天弹框的表单输入: MKT由于是iframe嵌入,所以MKT的上报,会单独写到MKT-form代码上 */
var isInquiryChatForm = !!(
/comp-form/i.test(ele.className) && ele.querySelector('form')
);
if (isInquiryChatForm) {
_paq.push(['trackEvent', 'formInquiry', 'formInput', 'chat']);
setInputTrackId();
return;
}
/** 向上查找父节点 */
ele = ele.parentNode;
}
};
function initInputListener() {
var inputUseDebounce = function (fn, delay) {
var timer = null;
var that = this;
return function () {
var args = Array.prototype.slice.call(arguments);
if (timer) clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(that, args);
}, delay);
};
};
var optimizeGetInputDom = inputUseDebounce(getInputDom, 300);
window.addEventListener('input', function (e) {
/** 如果已经上报过,则不再上报 */
if (lockTrackInput()) return;
optimizeGetInputDom(e.target);
});
}
try {
initInputListener();
} catch (error) {
console.log('initInputListener Error', error);
}
}
trackActionInput();
}
/** 第三方消息上报:目前主要是针对全点托管会话;在msgCollect/index.js中调试,访问test.html */
function thirdMsgCollect() {
/** 先检测是否是stayReal托管:如果stayReal脚本都没有,那么说明当前站点未开启stayReal会话托管 */
const scriptList = Array.prototype.slice.call(
document.querySelectorAll('script'),
);
const checkStayReal = () =>
!!scriptList.find((s) => s.src.includes('stayreal.xiaoman.cn'));
if (!checkStayReal()) return;
/** 缓存当前消息队列的最后一条消息id */
const CACHE_KEY = 'CACHE_KEY_MONITOR';
const setCache = (msgIndex) => {
/** 对缓存KEY进行base64转码处理 */
const cacheMsgIndex = btoa(msgIndex);
localStorage.setItem(CACHE_KEY, cacheMsgIndex);
};
const getCache = () => {
const cacheMsgIndex = localStorage.getItem(CACHE_KEY);
if (cacheMsgIndex) return Number(atob(cacheMsgIndex));
return -1;
};
/** 拉取最新msg列表 */
const pullMsgList = () => {
const msgEleList = Array.prototype.slice.call(
document.querySelectorAll('#chat-list li'),
);
const msgIds = [];
const msgMap = msgEleList.reduce((acc, item) => {
const sendTime = item
.querySelector('.message-data-time')
.textContent.trim();
const sendContent = item.querySelector('.message').textContent.trim();
/** msg带有class:other-message的是访客消息,my-message的是客服消息 */
const isOtherMessage = item
.querySelector('.message')
.classList.contains('other-message');
const msgId = item.querySelector('.message').getAttribute('id');
const msgItemData = {
msgId,
user: isOtherMessage ? 'visitor' : 'official',
time: sendTime,
content: sendContent,
};
msgIds.push(msgId);
acc[msgId] = msgItemData;
return acc;
}, {});
return {
ids: msgIds,
dataMap: msgMap,
};
};
/** 加密并上传消息数据 */
let ENCRYPT_KEY = 'de29f1aab63ab033';
let ENCRYPT_IV = 'b8d2badf875e76ac';
const baseUrl = 'https://cms.xiaoman.cn';
// var getEncryptConfig = function () {
// const url = baseUrl + '/shop-api/innerApi/getKeyIv'
// $.get(
// url,
// function (result) {
// console.log('result', result)
// if (Number(result.code) === 0 && result.data.key && result.data.iv) {
// ENCRYPT_KEY = result.data.key
// ENCRYPT_IV = result.data.iv
// uploadMsgData()
// } else {
// /** 如果获取失败,则重试 */
// setTimeout(() => {
// getEncryptConfig()
// }, 1000)
// }
// },
// 'json'
// )
// }
// getEncryptConfig()
const encryptMsg = function (msgData) {
const enc = new TextEncoder();
// 转字节
const keyBytes = enc.encode(ENCRYPT_KEY);
const ivBytes = enc.encode(ENCRYPT_IV);
const plainBytes = enc.encode(msgData);
// 导入密钥并加密
return crypto.subtle
.importKey('raw', keyBytes, { name: 'AES-CBC' }, false, ['encrypt'])
.then(function (cryptoKey) {
return crypto.subtle.encrypt(
{ name: 'AES-CBC', iv: ivBytes },
cryptoKey,
plainBytes,
);
})
.then(function (encryptedBuffer) {
// 转 base64 返回
return btoa(
String.fromCharCode(...new Uint8Array(encryptedBuffer)),
);
})
.catch((err) => {
return Promise.reject(err);
});
};
let uploadFlag = false;
const uploadMsgData = function () {
if (uploadFlag) return;
uploadFlag = true;
const { ids, dataMap } = pullMsgList();
let cacheMsgIndex = getCache();
const msgLen = ids.length;
if (!msgLen) {
// 消息DOM未挂载 || 消息DOM已挂载,但是消息列表为空
uploadFlag = false;
return;
}
if (msgLen - 1 < cacheMsgIndex) {
/** 针对站点挂后台一段时间,消息列表会自动塞入重复消息,导致消息有重复,刷新后又重置回正常消息列表,所以这里需要更新锚点下标 */
cacheMsgIndex = msgLen - 1;
setCache(cacheMsgIndex);
uploadFlag = false;
return;
}
if (msgLen - 1 === cacheMsgIndex) {
// 缓存的最后一次发送的消息ID是最后一条(说明当前消息均已经上报),则不跳过本地上报
uploadFlag = false;
return;
}
const currentMsgIds = ids.slice(cacheMsgIndex + 1, msgLen);
const currentMsgData = currentMsgIds.map((id) => dataMap[id]);
const mtmId = window.matomo_site_id_cookie_key || ''; // 获取mtm会话id
const msgBody = {
mtmId,
curl: window.location.href,
msgList: currentMsgData,
};
const msgBodyStr = JSON.stringify(msgBody);
encryptMsg(msgBodyStr)
.then(function (encryptedMsg) {
console.log('encryptedMsg:', encryptedMsg, msgBodyStr);
const url = baseUrl + '/shop-api/External/ListenSiteActiveStatus';
$.ajax({
type: 'POST',
url,
data: JSON.stringify({ d_v: encryptedMsg }),
contentType: 'application/json',
success: function (result) {
if (Number(result.code) === 0) {
// 更新消息队列
setCache(msgLen - 1);
}
uploadFlag = false;
},
error: function (err) {
console.error(err, '请求异常');
uploadFlag = false;
},
});
})
.catch((err) => {
console.error(err, '数据加密失败');
uploadFlag = false;
});
};
/** 监控chat-list的DOM变更 */
const initChatListObserver = () => {
// 需要监听的 DOM 节点
const target = document.getElementById('chat-list');
if (!target) return;
// 回调函数
const callback = function (mutationsList, observer) {
for (const mutation of mutationsList) {
console.log('mutation', mutation);
if (mutation.type === 'childList') {
uploadMsgData();
}
}
};
// 配置
const config = {
childList: true, // 监听子节点的增删
subtree: true, // 是否也监听后代节点
};
// 创建 observer
const observer = new MutationObserver(callback);
// 开始监听
observer.observe(target, config);
};
let testCount = 30;
let itv = null;
const checkChatDom = () => !!document.querySelector('#vc-model');
const initTalkCheck = () => {
itv = setTimeout(() => {
console.log('checkChatDom', checkChatDom(), testCount);
if (!checkChatDom() && testCount > 0) {
testCount--;
initTalkCheck();
return;
}
clearTimeout(itv);
uploadMsgData();
initChatListObserver();
}, 1500);
};
initTalkCheck();
}
try {
gtmTrack();
thirdMsgCollect();
console.log('inserted gtm code');
} catch (error) {
console.error('gtmTrack Error', error);
}
});
})();
In quaerenda optimarum praefabricatarum aedificiorum unitatum pro tua negotiatione? CDPH hic est ut iuvet! Ex nostra technologia professionali praefabricatorum aedificiorum instrumentorum et domus modularis, cum producto excellentis qualitatis perfectique designi ministerii, habemus clientes domi et peregre iuvatos. Utrum in opere aedificatorio vel in castris metallorum, fama nobis est celeriter et efficaciter productum adferre pretio quod sit moderatum. Apud CDPH, nos honorati sumus posse vobis castra personalia praebere, si vestrae necessitates satisfaciunt. Domus praefabricatae nostrae sunt efficaces, pretio moderato et facile adaptandae, tecta secura pro vestrīs operārīs aut ministeribus offerentes. Utrum habitatio tempōrāria requiratur pro opere aedificandi aut pro diūtūrnīs hospitiīs in communitate metallīcā remotā, scientiam et experientiam habemus ad vestra officia implenda. Meliores nulla sunt domūs praefabricatae quam quae a CDPH offeruntur; eas in plus quam centum nātiōnibus habemus, sīve quantulacumque sit vestrī negōtiī māgna. Eodem tempore, in his praefabricatis hospitiorum unitatibus investire multas opportunitates pro tuo opere praebeat. Praeterquam quod simplicia et celeriter installanda sunt, haec domicilia vili sunt et sustinenda. Unitates alti ordinis quae normis artis et legibus respondent, cum experientia CDPH in aedificando modulari. Domus praefabricatae ita factae sunt ut celeriter et facile coniciantur, quod significat in novo aedificio habitare esse facile. Cum CDPH, frui poteris plene solutionibus habitaculorum efficacium et robustarum pro tuo opere. Ut emptor cuiusdam praefabricatorum habitaculorum, debes tempus sumere ut notitiam habeas de tendentibus industriae. CDPH clientibus nostris varietatem solutionum creativarum ostendit quae novis petitionibus satisfaciunt. Per rationem nostram supplicantium, haec habitacula ad mensuram constructa efficientiam energiae habent, sed in minore scala qualitatem PrecisionCraft attingunt. Cum cooperatione CDPH, emptores cuiusdam praefabricatorum hospitiolorum uti possunt domiciliis modularis generis quae non solum sunt elegantis aspectu sed etiam practica et competitiva. Innovatio praefabricatorum in loco dormiendi domiciliorum mutat rationem aedificandi in loco—citra, facilius, viridius et efficacius quam aedificia conventionalia. CDPH ducit hanc conversionem cum domesticis modularibus creativis quae necessitatibus mutantibus clientium nostrorum satisfaciunt. Credimus praefabricatae unitates habitaculi esse futurum constructionis et esse partem eius volumus! Cum CDPH ut socio tuo expectare potes solutiones habitaculorum primi ordinis, quae in artibus hodiernis descriptae et probatae sunt. Domus praefabricata certum habet designum ad robur structurale et bonam praebere potest resistentiam contra terremotos, ut tutelam securitatis garantiat. Designum modulare, facile transportanda; installatio ad personales gustus variorum stylum et typorum camerarum adaptari potest. Omnes partes praefabricatae sunt et facile in loco ponuntur, nullis artificum peritiis indigentes. Utrum ad officium, ad habitandum, ad depositum, an ad alias usus destinetur, domus praefabricatae necessitates tuas implebunt. Unitates habitatoriae praefabricatae, lineae leves, et ad tuos personales gustus adinodari possunt, ut spatium habitandi unicum creetur. Optimum autem est quod domus praefabricatae non requirunt soldaturam in situ, et nos instructiones pro installatione praebemus, ut installatio simplicior et celerior fiat. Vitam meliorem amplectere eligendo domus praefabricatas Chengdong. Fac domum tuam tutiorem et commodiorem instituendo domum ex contentoribus! Omnes partes structurales in officina praefabricantur. Per electionem dimensionum, configurationis et stili idoneorum, spatium habitandi tuum cito creare potes. Secundum necessitates et studia sua, plura modula in varias dispositiones cubiculorum incorporari possunt, ut unitates habitatiores praefabricatae multifunctionales, ut salutatorium, culina aut cubiculum, efficiantur. Quod maxime notandum est, est quod domus ex contentoribus, quam utimur, facile dissolvitur et rursus constriuitur, structura solida, cum praestantissimis proprietatibus, ut impermeabilitas, praeservatio contra incendia, et processus installationis facilis atque simplicis administrandus, nullam vero peritiam technicam specialem postulans. Ad usus privatos habitandi, ad servos, ad spatia officiorum temporaria, aut ad alios fines, domus ex contentoribus praefabricatae ita sunt designatae, ut ad tua desiderata accommodentur. Hodierno die fruere camera ex casside, meliorem pretium et meliorem servitium consequere, vitam tuam emenda! Unitates habitatio praefabricatae, forma unica, species pulchra, domum tuam magis personalizant. Ab simplici moderno ad vetustum, varia stilia et colores offerimus, qui gustui tuo conveniunt. Peking Chengdong in necessitatibus utentium versatur et ad tua specifica desiderata personalizari possunt. Domum tuam somniorum designare potes mutando dispositionem, distributionem aquae et electricitatis, formam aliasque proprietates secundum tuas preferentias. Praefabricatio tuborum electricorum et aquarum nos a longo processu reordinandi tubos post ornatum aedificii liberat, quod qualitatem et efficaciam ornatus augent. Largam varietatem optionum dispositionis interioris offerimus, quae salam, triclinium, cubiculum, culinam, latrinam, etc. includunt. Secundum tuas preferentias eligere potes, ut domum tibi idealem et unicum crees. Apple House – Optima qualitas vivendi! Apple House est area unica! Domus plicabilis ex designo modulari standardi constat, quod ad necessitates familiae tuae configurari potest et ad productionem in massa conducit, ut spatium habitandi tuum stabilius, tutius et fideliore reddas. Camera plicabilis variis modis disponi potest, ut diversae necessitates explentur, ita ut ubicumque et quandoque commodissime habitare possis. Cito mittitur! Etiam efficacem praeparationem et expeditionem praebemus. Adeptus nostrae praeparationis grex cameram plicabilem tuam iuxta clientis postulationes conponet. In ipso expeditionis processu omnes gradus observabimus, ut unitates habitatiores praefabricatae ad locum destinatum perveniant. Optimum autem est, quod camera facile plicatur et sine saldatura in loco installatur. Praebemus etiam instructiones pro installatione, ut installatio tua facilius et celerius fiant. Si instructiones sequeris, tunc domus plicabilis erigere simplex est. CDPH artificia et varias vendunt aedes modularis, Prefab domus et villa domus. Proventus amplis efficit ut apta solutio ad singula castra machinatoria nos expediat.Unitates habitaculi praefabricatae
Ubi optimas praefabricatas sedes habitaculi pro tua re quaerere

Commoda investendi in praefabricatas sedes habitaculi pro tuo opere

Primae tendentiae in praefabricatis sedibus habitaculi pro emptoribus ad magnum

Cur praefabricatae sedes habitaculi sint futurum aedificationis
Why choose CDPH
Unitates habitaculi praefabricatae?
Novus advenil prefab domum
Bonus Sales continens domum
Modern Style malum Cameram
Princeps qualis tenens domum
Categories Producti Relatae
Non invenis quod quaeris?
Petere Citatio Nunc
Consulere nostros pro magis productis disponibilibus.Cum Nobis Contacata
27+ annos Usus
Engineering Castra Construction