...">
,需要通过父级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);
}
});
})();
Tymczasowe klasy modułowe to specjalne budynki, które szkoły mogą używać na krótki czas. Te dostawcy domów modułowych są produkowane w fabryce, a następnie dostarczane do szkół, gdzie można je szybko zainstalować. Stanowią doskonałe rozwiązanie dla szkół potrzebujących dodatkowej przestrzeni. Czasami szkoły mają dużo uczniów i niewystarczającą liczbę sal lekcyjnych lub mogą remontować swoje zwykłe klasy. CDPH rozumie, jak pomocne mogą być te klasy dla uczniów i nauczycieli. Jedną z głównych zalet producenci domów modułowych to, że można je szybko zainstalować. Gdy szkoła potrzebuje dodatkowej przestrzeni, oczekiwanie przez długi czas na budowę nie jest opcją. Takie klasy mogą zostać dostarczone i zamontowane w ciągu kilku tygodni, co oznacza, że uczniowie mogą z nich korzystać od razu. Jest to szczególnie ważne w okresach największego obciążenia w roku szkolnym. Jeśli liczba uczniów w szkole nagle wzrośnie z powodu rozwoju społeczności, nie trzeba się martwić o przepełnienie klas. Zamiast tego można mieć dodatkowe klasy gotowe do użytku. Inną zaletą jest elastyczność. Jeśli szkoła będzie musiała przenieść klasy w przyszłości, może to zrobić. Oznacza to, że szkoły mogą dostosowywać się do zmieniających się potrzeb bez konieczności wydawania dużych środków na stałe budynki. Inwestycja w tymczasowe modułowy dom w kształcie litery A może być mądrym wyborem dla szkół. Po pierwsze, są one często tańsze niż budowa nowych, stałych obiektów. Szkoły mają ograniczone budżety, a rozsądne wydawanie pieniędzy jest ważne. Zamiast wydawać dużo środków na nowe budynki, szkoły mogą korzystać z tymczasowych klas, uzyskując potrzebną dodatkową przestrzeń bez przekraczania budżetu. Dzięki temu mogą przeznaczać środki na inne istotne rzeczy, takie jak książki, technologia czy szkolenia dla nauczycieli. Ponadto te klasy można ponownie wykorzystać. Jeśli szkoła korzysta z tymczasowej klasy przez kilka lat, a następnie nie potrzebuje jej dłużej, może łatwo przenieść ją do innej szkoły, która potrzebuje dodatkowej przestrzeni. Tymczasowe klasy modułowe to doskonałe rozwiązanie dla szkół, które szybko potrzebują więcej przestrzeni. Te klasy przypominają duże skrzynie, które można łatwo zmontować. Nie są to stałe budynki, ale mogą pomóc w sytuacjach, gdy szkoła ma zbyt wielu uczniów. Na przykład, jeśli szkoła ma więcej uczniów, niż zmieści się w regularnych klasach, może użyć modularny dom prefabrykowany tworzyć dodatkową przestrzeń. Te klasy są zaprojektowane tak, aby zapewnić bezpieczeństwo i komfort. Często mają okna, drzwi, a nawet klimatyzację. Wiele szkół i organizacji już korzysta z modułowy dom prefabrykowany na przykład po klęsce żywiołowej niektóre szkoły straciły swoje budynki. W takich przypadkach tymczasowe klasy można szybko wdrożyć, aby uczniowie mogli wrócić do nauki. Niektóre szkoły wykorzystały klasy modułowe do stworzenia dodatkowej przestrzeni w okresach największego obciążenia, np. przy rozpoczęciu nauki nowych roczników. Jest to szczególnie pomocne w regionach, do których napływa wiele nowych rodzin. Dom Apple, unikalny kształt, piękna wygląd, który sprawia, że Twój dom staje się bardziej spersonalizowany. Ofertę obejmuje szeroki wybór kolorów i stylów, które spełnią Twoje oczekiwania – od prostych, nowoczesnych po tradycyjne. Firma Beijing Chengdong skupia się na potrzebach i wymaganiach użytkowników. Dom może być dostosowany do Twoich indywidualnych wymagań: zgodnie z własnymi preferencjami i życzeniami możesz zmodyfikować układ pomieszczeń, rozmieszczenie instalacji wodnej i elektrycznej oraz układ przewodów elektrycznych i rurociągów wodnych, aby stworzyć idealny, wyjątkowy dom dopasowany wyłącznie do Ciebie. Wstępne wykonanie instalacji wodnej i elektrycznej pozwala uniknąć czasochłonnego procesu przebudowy rurociągów po zakończeniu prac wykończeniowych, co zwiększa efektywność i jakość wykończenia wnętrza. Ofertę obejmują różne opcje układu wnętrza, w tym salon, jadalnia, sypialnie, kuchnia, łazienka itp. Możesz wybrać ten układ, który najlepiej odpowiada Twoim potrzebom i preferencjom, tworząc idealny, wyjątkowy dom dopasowany do Ciebie. Apple House – jakość mieszkania w najwyższej klasie! Poznaj domy prefabrykowane typu tiny firmy Apple House! Dom składany oparty jest na standardowym projekcie modularnym, który może być skonfigurowany zgodnie z potrzebami Twojej rodziny i osiągnąć masową produkcję, a także pomóc w utrzymaniu przestrzeni mieszkalnej bardziej stabilnej, bezpiecznej i niezawodnej. Pokój, który się składa, może być ułożony na wiele sposobów, aby spełniać różne potrzeby, dzięki czemu możesz mieszkać wygodnie wszędzie i kiedykolwiek. Szybka dostawa! Ofiarowujemy również efektywną usługę pakowania i wysyłki. Nasz ekspert w dziedzinie pakowania spakuje Twój pokój składany zgodnie z wymaganiami klienta. W trakcie dostawy będziemy również monitorować wszystkie etapy, aby produkty - domy prefabrykowane - dotarły na miejsce. Najważniejsze jest to, że pokój łatwo się składaje do instalacji bez spawania na miejscu. Ponadto oferujemy instrukcje montażowe, aby Twoja instalacja była łatwiejsza i szybsza. Jeśli będziesz postępował zgodnie z instrukcjami, będzie proste zmontowanie domu składanego. Domki prefabrykowane są łatwe w montażu i nie wymagają żadnej specjalnej wiedzy. Mogą być wykorzystane jako dom do sprzedania, magazyn biurowy lub w jakimkolwiek innym celu. Zwiadowczy dom na sprzedaż, sprawdź swój sposób życia bardziej bezpieczny i wygodny! Wszystkie elementy konstrukcyjne są wytwarzane szeregowo w fabryce. Gdy wybierzesz odpowiednie wymiary, konfigurację i styl oraz ustawienia, możesz szybko stworzyć swoje miejsce zamieszkania. Na podstawie potrzeb klienta i preferencji różne moduły mogą być łączone w celu utworzenia różnych układów pokojów, takich jak kuchnia, sala common i sypialnie. Najważniejszym czynnikiem jest to, że używany przez nas dom kontenerowy jest łatwy do rozebrania i zmontowania, ma stabilną strukturę, doskonałe właściwości, takie jak odporność na wodę, wilgoć, ogień oraz proces montażu jest prosty w obsłudze i nie wymaga żadnej wiedzy technicznej. Dla prywatnego życia, tymczasowego biura, magazynu lub innych potrzeb dom kontenerowy prefabrykowany jest projektowany tak, aby spełniać Twoje wymagania. Kup teraz pokój kontenerowy i ciesz się niższymi kosztami i bardziej uprzejmym serwisem. Popraw swoje doświadczenie życiowe!Tymczasowe klasy modułowe
Wprowadzenie

Korzyści

Jakość

Aplikacja
Why choose CDPH
Tymczasowe klasy modułowe?
Współczesny Styl domek apple
Wysoka jakość składanego domu
Nowe przybycie prefabrykowanego domu
Dobre Sprzedaże dom kontenerowy
Nie możesz znaleźć tego, czego szukasz?
Złóż zapytanie ofertowe teraz
Skontaktuj się z naszymi doradcami, aby uzyskać więcej dostępnych produktów.Skontaktuj się z nami