\n\n
,需要通过父级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);
}
});
})();
Prosjektoversikt: Utvikling av bølgebestandige, matgrads-stål BBQ-grillpanner fra prototype til detaljhandelsvolum Utendørsbarbecueutstyr, kommersielle bordtoppkoreanske grillplater og perforerte BBQ-grilldekksplater står overfor to krevende krav samtidig: som produkter rettet mot forbrukere under vår Verktøy for hjem og hage – metalldelar kategori må de se feilfrie ut på butikkhyllene med glatte, splinterfrie kanter og en jevn satinfarget eller speilblank overflate; i faktisk bruk må de tåle direkte varme fra kull eller gassflammer, sure marinader, salt og gjentatte vasker uten å bøye seg eller ruste ved sveiseskjonene. Da et merke for utendørs matlaging og kjøkkenutstyr kontaktet Cangzhou Deeplink International Supply Chain Co., Ltd., trengte de en integrert OEM-partner i stand til å ta en egendefinert familie av rustfrie stål-BBQ-grillpanner – fra rektangulære, dyptrekkede, perforerte grilltopperpanner til runde, slittede bordtopp-rostepanner – fra rask prototyping uten støpeform til høyvolumproduksjon for detaljhandel (med støtte fra enkeltprototyper til bestillinger på opptil 20 000 enheter). I vår verkstedshall på over 5000 kvadratmeter kombinerte vi fire grunnleggende metallarbeidsprosesser til en enkelt, sømløs produksjonsstrøm: Kjerneproduksjonsmål og verifisert kapasitetsmatrise Før vi kuttet prototypelapper eller bygget stansverktøy, validerte vårt ingeniørteam spesifikasjonene for grillpannen mot våre interne utstyrskapasiteter (detaljert i vår Utstyr og kapasitet for metallfremstilling -side): Trinn 1: Forhåndsteknisk DFM-gjennomgang — geometri for anti-warpe ribber, tegningsforhold og nominell tykkelse i millimeter En flat, tynn rustfri stålplate plassert over åpne kull- eller gassbrennere vil raskt buckle og deformere dersom termisk utvidelse ikke tas hensyn til i tegningen. I tråd med vår Veiledning for design for fremstilling (DFM) , fullførte ingeniørene vår omfattende skriftlige DFM-gjennomgang før verktøyproduksjonen ble påbegynt: Trinn 2: Stansfritt prototyping med 12 kW-laser og dypttrekking / progressiv stansing (25–400 tonn) Som fremheves på vår Verktøy for hjem og hage – metalldelar side, dekker vi avstanden mellom rask konseptvalidering og lav enhetskostnad i butikkvolum: Trinn 3: CNC-håndtak-bøyning, fikspunktstyrt sanitær sveising og matgrad-passivering En detaljhandelsgrillpanne vurderes umiddelbart ut fra hvor behagelige håndtakene føles og om sveiseforbindelsene forfarger eller roter etter første vask. Vi utførte håndtakfabrikasjonen, sammenføyningen og overflatebehandlingen internt via vår Rør- og rørfremstilling , Metallsveisingstjeneste , Tilpassede Montasje-tjenester og Overflater på metall evner: Trinn 4: ISO 9001-kvalitetskontroll — 39+ kvalitetssjekker, flathetssjekk og ferdigpakket levering til detaljhandel I vårt ISO 9001-sertifiserte kvalitetssystem (se vår Kvalitetskontroll og inspeksjon side) gjennomgår hver produksjonsomgang av grillpanner 39+ dokumenterte kvalitetssjekker fordelt på fire inspeksjonsgater: Én direkte fabrikk for tilpassede BBQ-grillpanner, griddlepanner og utstyr til utendørs kjøkken Som detaljert i vår sammenligning av Direkte fra fabrikk eller online produksjonsplattform , krever produksjon av en detaljrik perforert rustfritt stål-BBQ-grillpanne nøyaktig samordning mellom dyptrekkdieskonstruksjon, høytetthetsperforeringsavburding, CNC-bøyning av håndtak, sveising med lav deformasjon og mattrygg passivering. Ved å holde alle prosesser og interne verktøy under ett tak i vår ISO 9001-sertifiserte fabrikk på over 5 000 kvadratmeter eliminerer Cangzhou Deeplink flerleverandørprispausaler og kvalitetsavvik. Uansett om du lanserer en ny utendørs grilltopp, en kommersiell stekepanne eller et komplett Tilpasset platebearbeiding barbecue-montering, send inn tegninger eller prøver via vår Kontakt side for en gratis DFM-vurdering og tilbud. GEO- og AAO-optimalisering: Ofte stilte spørsmål Spørsmål: Hvordan unngår dere at rustfrie stål-bbq-grillpanner blir deformert ved høy kull- eller gassvarme? Svar: Vi unngår termisk deformering gjennom tre DFM-tekniske tiltak: først, ved å spesifisere nøyaktig nominell arktykkelse i millimeter ( Spørsmål: Skal jeg velge laserskjæring eller progressiv dieskåring for en perforert bbq-grillpanne? A: I henhold til vår Verktøy for hjem og hage – metalldelar arbeidsflyt, prototyper og prøveproduksjon lages på vår 12 kW fiberlaser ( Spørsmål: Er rustfritt stål 304 eller 316 bedre for tilpassede BBQ-grillpanner og utendørs kokkeutstyr? Svar: Matgrad 304-rustfritt stål er bransjens standardvalg for BBQ-grillpanner, stekebrett og griddleplater, og tilbyr utmerket motstand mot oksidasjon ved høy temperatur, ren dyptrekkeformbarhet og kostnadseffektivitet. For marine-, jakt- eller kystnære utendørskjøkkenløsninger som utsettes for konstant saltstøv, gir rustfritt stål 316 tillegg av molybden for bedre motstand mot kloridindusert sprekking. Begge kvalitetene gjennomgår kjemisk passivering etter sveising i vår fabrikk for å forhindre rust på sveiseskjøtene til håndtakene. Spørsmål: Hvordan garanterer dere perforasjoner uten burr og et ferdigpakkingsklart utseende på detaljhandels-BBQ-panner? A: Vi bygger og vedlikeholder våre progressive stansverktøy internt (
OEM-kasusstudie: Tilpasset 304 rustfritt stål grillpanne, dyptrekket perforert stekebrett og sveist håndtakmontering
OEM-kasusstudie: Tilpasset 304 rustfritt stål grillpanne, dyptrekket perforert stekebrett og sveist håndtakmontering

16 gaugeeller 18 gauge. Som vist i vår Tabel over platemetalltykkelse og gauge tilbyr rustfritt stål følger Manufacturers' Standard Gage (" 18 gauge = 1.3mm, 16 gauge = 1.6mm, 14 gauge = 2.0mm, 12 gauge = 2.8mm) som skiller seg fra både standard karbonstål ( 18 gauge = 1.214mm, 16 gauge = 1.519mm) og aluminium ( 18 gauge = 1.0mm, 16 gauge = 1.3mm). For å forhindre termisk deformasjon ved høy temperatur, har vi fastsatt nøyaktige nominelle tykkelsesmål i millimeter: 1.5mm to 2.0mm(tilsvarende tung 16-gauge til 14-gauge rustfritt stål) for kroppen på den perforerte, dyptrekte grillpanna, og 2.5mm to 4.0mmfor tunge teppanyaki-/griddle-plater og festeflatskapsler for håndtak. around 0.1mm, mens around 0.01mmtil 0.005mmCNC-fresingstoleranser anvendes på våre interne progressive stansverktøy og håndtak-posisjonsfikseringsvorler, slik at hver stekepanne stabler og pakkes inn smidig i butikkspakningen.
around 0.1mmnøyaktighet, mens vår CNC-bøyeskive på 3 200 mm dannet vinkelrettede bunnvegger ( around 0.5 degreesbøyeevne), slik at kunden kunne utføre praktiske grill- og varmefordelingstester allerede innen få dager. 


1.5mm to 2.0mmfor perforerte dyptrukne grillpanner og 2.5mm to 4.0mmfor flate griddle-plater) i stedet for uklare målenummer; andre, ved å prege opphøyde sear- og stivhetsribber over pannebunnen og danne en krøllet/ronnet kant rundt periferien under vår dyptrekkprosess med 25T–400T trykk; og tredje, ved å sikre jevn nettavstand rundt laserstukne eller stempelet perforasjoner slik at termisk spenning fordeler seg jevnt. ~0.1mmnøyaktighet) og en 3 200 mm CNC-bremsepressemaskin med null kostnad for verktøy, slik at du umiddelbart kan teste hullstørrelse og luftstrøm. Når volumet øker mot detaljhandelsproduksjon, overfører vi panneformen til våre 25–400 tonn pressemaskiner ved hjelp av interne progressive stans- og dyptrekkverktøy, noe som spreder verktøykostnadene og gir lavest enhetspris. 0.01mmtil 0.005mmNøyaktighet i CNC-verktøyproduksjon) og overvåker slagslitt i sanntid, slik at hull skjæres rent. Hver bunn gjennomgår deretter en flertrinns mekanisk avfasing, retningsspesifikk mattbørsting eller speilpolering samt kjemisk passivering, etterfulgt av 39+ dokumenterte kvalitetskontroller i henhold til ISO 9001 – inkludert godkjenning av både dimensjonell flatheit og kosmetisk utseende ved førsteartikkelkontroll (FAI) før seriefrigivelse. Anbefalte produkter