a...">
,需要通过父级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 || nodeText || '');
if (phoneReg.test(str) && numUseReg.test(str)) {
window.postMessage({
type: 'SHOPS_CONTACT_TRACK',
data: {
phone: nodeText,
},
}, '*');
_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;
if (phoneReg.test(fatherText) && numUseReg.test(fatherText)) {
window.postMessage({
type: 'SHOPS_CONTACT_TRACK',
data: {
phone: nodeText,
},
}, '*');
_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)) {
window.postMessage({
type: 'SHOPS_CONTACT_TRACK',
data: {
email: 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')) {
window.postMessage({
type: 'SHOPS_CONTACT_TRACK',
data: {
email: content,
},
}, '*');
_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)) {
window.postMessage({
type: 'SHOPS_CONTACT_TRACK',
data: {
email: 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)) {
window.postMessage({
type: 'SHOPS_CONTACT_TRACK',
data: {
email: 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);
}
});
})();
Tá ranganna sealadacha modúla speisialta i measc na ndealbha a d’fhéadfadh scoileanna a úsáid ar feadh tréimhse gearr. Tá na soláthraithe tithe módlacha déantar i bhfabhrac agus ansin a thabhairt go scoileanna, áit ar féidir iad a shuiteáil go tapa. Is réiteach iontach iad do scoileanna atá ag iarraidh spás breise. Uaireanta, tá líon mór daltaí ag scoileanna ach níl an t-áit riachtanach ann, nó b’fhéidir go bhfuil siad ag deisiú a gcoimeádáin ghairide. Tuigeann CDPH cé chomh cabhrach is féidir leis na seomraí ranga seo a bheith do dhaltaí agus do mhúinteoirí. Beneifit mór amháin de bainítí téadaithe fodhla is é sin go dtugtar iad suas go tapa. Nuair a theastaíonn níos mó spás ó scoil, ní féidir leathnú ar thógáil a bheith ag súil leis. Is féidir na ranganna seo a sholáthar agus a shuiteáil i mbliana, rud a chiallaíonn go dtosaíonn na daltaí ag úsáid acu láithreach. Tá sé seo go háirithe tábhachtach le linn tréimhsí gairmiúla sa bhliain scoile. Má fhaigheann scoil níos mó daltaí go tobann mar gheall ar phobal atá ag fás, ní gá domhanlán a bheith ag imirt ar an gcuid is mó. Ina ionad sin, is féidir ranganna breise a bheith réidh le húsáid. Is é an t-ábhar eile atá le baint as iad ná an solúbthacht. Má theastaíonn ón scoil na ranganna a aistriú ina dhiaidh sin, is féidir é sin a dhéanamh freisin. Ciallaíonn sé sin go dtugann na scoileanna comhoiriúnacht le riachtanais athraitheacha gan costas mór a chur ar thógáil sheasmhaí. Investing in temporary taigh a-frame modúil is féidir leis a bheith rogha uilig do scoileanna. Ar an gcéad dul síos, is minic a bhíonn siad níos saor ná tithe seasmhacha nua a thógáil. Tá budgáid ag na scoileanna, agus tá sé tábhachtach airgead a chaitheamh go mionlach. In áit airgead mór a chaitheamh ar theach nua, is féidir le scoileanna seomraí sealadacha a úsáid chun an spás breise a ghiabhann siad gan a mbuachaillí a bhriseadh. Ceadaíonn sé seo don scoil a mbuget a úsáid do rudaí tábhachtacha eile mar leabhair, teicneolaíocht, agus oiliúint mhúinteoirí. Níos mó fós, is féidir na seomraí seo a athúsáid. Má tá seomra sealadach ag scoil ar feadh cúpla bliain agus ansin ní ghlacann siad leis, is féidir é a aistriú go héasca go scoil eile a d’fhéadfadh spás breise a bheith uaidh. Is réiteach iontach iad na seomraí modúla sealadacha do scoileanna a dteastaíonn spás breise ón gcoimisiún go tapa. Is cosúil le bosca móra iad na seomraí seo agus is féidir iad a chur le chéile go héasca. Ní tithe seasmhacha iad, ach is féidir leo cabhrú nuair a bhíonn ró-mhór an líon daltaí ag an scoil. Mar shampla, má tá níos mó páistí ag scoil ná is féidir leo a chur isteach sa seomraí reaglair, is féidir leis an scoil a úsáid tigh réadaitheach módúil chunna an spás breise. Tá na ranganna seo deartha chun a bheith sábháilte agus comfhortach. Is minic a bhíonn fuinneoigeanna, doirse, agus fiú córas aeirchothaithe acu. Tá go leor scoileanna agus eagraíochtaí ag úsáid tithe moillse prefab mar shampla, tar éis míshástais nádúrtha, chaill roinnt scoileanna a ndealbha. I gcásanna mar seo, is féidir ranganna sealadacha a shocrú go tapa ionas gur féidir le páistí filleadh ar an scoil. D’úsáid roinnt scoileanna ranganna modúla chun spás breise a chruthú i rith tréimhsí gairide den bhliain nuair a thagann grádanna nua ar an suíomh. Tá sé seo an-tábhachtach go háirithe i réigiúin áit a bhfuil go leor teaghlaí nua ag bogadh isteach. Cabin Apple, cruth uathúil, taispeáint álainn, a dhéanann do bhaile níos pearsanta. Tairgeann muid raon leathan d’dhathanna agus stíleanna chun do rogha a shatisfá, ó stíl simplí nua-aimseartha go dtí an traidisiúnta. Tá Beijing Chengdong dírithe ar riachtanais agus ar iarratais na úsáideora. Is féidir é a chur in oiriúint chun do riachtanais a shásamh. De réir do mhian agus do rogha féin is féidir leat cruth an tí, an t-eagar, an t-uisci agus an leictreachas a athrú, mar aon le hordú an leictreachais agus an uisce, chun an bhaile idealach uathúil a thógáil duit. Cabhrann an t-ullmhú roimh ré an uisce agus na sreangacha leictreachais linn an próiseas fada a sheachaint de athshocrú na sreangacha tar éis do bhaile a adhmadh, rud a méadaíonn éifeacht agus calaí an adhmaid. Tairgeann muid raon roghanna eagar don isteach atá le fáil, lena n-áirítear an seomra suite, an seomra bia, na seomraí codlata, an cistine, an seomra folctha srl. Is féidir leat an ceann a roghnaíonn tú a roghnú chun baile idealach uathúil a chruthú duit. Apple House – Cáilíocht sa bheatha is fearr! Taobh istigh den tí beag réamhthógáilte Apple House! Tá an teach iomlán bunaithe ar dízel módlach stairiúil, atá in ann a chur i gcomhthéacs de réir niomata do theaghlach agus cur i bhfeidhm phróiseas tuillte agus cabhrú le déanamh do chosán bia níos staidéarach, níos slán agus níos déanta. Is féidir leis an seomra atá iomlán é a shocrú go cúramach sna hábhair éagsúla chun niomata éagsúla a fheabhsú, mar sin is féidir leat beo go cófrafaíochtaíochtaíochtaíochtaíochtach ar bith agus nuair ar bith. Seíoctha go tapa! Cuirimid ar fáil freastal eagrach agus seíoctha. Déanfaidh ár mbeartas eagrach sprioc don chleachtadh do sheomra iomlán i gcompliance le riachtanais an cliant. Sa phróiseas seíocháin beidhimid ag rianú gach céim chun go mbeidh na héadach Prefabricated teach sa suíomh. Is breá liom, bíonn an seomra iomlán éasca le seoladh gan aon scainneál ar pháirc. Cuirimid ar fáil léarscáilí seolta chun cabhrú le do sheoladh a bheith níos éasca agus níos luath. Má leanann tú na léarscáileanna, is éasca é a chruthú an teach folada. Is éasca na tithe réadaithe a chur le chéile agus níor cheart aon eolas speisialta leo. Is féidir iad úsáid mar theach fúaimnigh do dhlúthú, stóras oifige, nó ar bith eile de chuid. Tigh inbheacháin ar fhostú, déan do shaol a bheith níos slán agus níos cófra! Tá na comhponóidí struchtúrtha uile réitithe i gcásún. Nuair a roghnóidh tú an méid ceart, an chumraíocht agus an stíl, is féidir leat do dhlíth teach a chruthú go tapa. Bain úsáid as na modúlaí éagsúla chun cumraíochtaí ranga éagsúla a chruthú mar chúinne, spás cónaithe agus seomraí codlata. Is é an rud is tábhachtaí gur féidir leis an teach container a thógaint agus a chur ar dtús go héadrom, struchtúr stailte, feabhsuithe iontacha mar phróifí deireadh, fhréamhúlacht, cosc tine agus tá an phróiseas a chur le chéile éadrom agus simplí chun oibriú, agus nach mbeidh aon eispéiris teicniúil ag teastáil uait. Le haghaidh cónaí príobháideach, oifig tympeoraite, stóras nó neartanna eile, cruthaítear na títhe container réadaithe chun do chuid riachtanais a choinneáil. Faigh séasán container inniu agus bain torthaí níos soiléir agus seirbhís níos bródúil. breisigh do sheans cónaí!Ranganna modúla sealadacha
Réamhrá

Buntáistí

CÁIL

Feidhmchlár
Why choose CDPH
Ranganna modúla sealadacha?
Stíl Módarnach cabin apple
Folláin ardchaighdeán
Nua-éagsúil teach réadaithe
Seomra díograis Maith
Nach bhfuil tú ag fáil an rud atá uait?
Iarr Luachan Anois
Téigh i dteagmháil lenár gcomhairleoirí le haghaidh tuilleadh táirgí atá ar fáil.Téigh i dTeagmháil