\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);
}
});
})();
Projectoverzicht: Ontwikkeling van anti-vervormende, voedselgeschikte roestvrijstalen BBQ-grillpannen van prototype naar detailhandelsvolume Buitenkookgerei, commerciële tafeltop-Koreaanse grillplaten en geperforeerde BBQ-grilltoppers moeten tegelijkertijd aan twee strenge eisen voldoen: als producten die in de detailhandel worden aangeboden onder onze Huis- en tuigereedschapsmetaaldelen categorie moeten ze er op het winkelrek onberispelijk uitzien, met gladde, splintervrije randen en een uniforme satijnglanz- of spiegelafwerking; tijdens het gebruik moeten ze bestand zijn tegen directe hittewerking van houtskool of gasvlam, zure marinades, zout en herhaalde spoelingen zonder te vervormen of te roesten op de lasnaden. Toen een merk voor buitenkoken en keukengerei Cangzhou Deeplink International Supply Chain Co., Ltd. benaderde, hadden zij een geïntegreerde OEM-partner nodig die in staat was om een aangepaste reeks roosterpannen van roestvrij staal — van een rechthoekige, diepgetrokken, geperforeerde roosterbovenplaat tot een ronde, geperforeerde tafelroosterplaat — van snelle prototypen zonder matrijs te brengen naar productie in grote oplages voor de retail (ondersteuning van afzonderlijke prototypes tot orders van 20.000 stuks). In onze werkplaats van meer dan 5.000 m² combineerden wij vier kernprocessen voor bewerking van metaal tot één naadloze productiestroom: Kernproductiemetrics en geverifieerde capaciteitenmatrix Voordat prototypeplaten werden gesneden of stempelmatrijzen gebouwd, heeft ons technisch team de specificaties van de BBQ-grillpan gevalideerd tegen onze eigen apparatuurcapaciteiten (beschreven in onze Apparatuur en capaciteit voor metaalbewerking pagina): Fase 1: Voorbewerkings-DFM-beoordeling — anti-vervormingsribgeometrie, tekenverhoudingen en nominale dikte in millimeter Een platte, dunne roestvrijstalen bak die op open houtskool- of gasbranders wordt geplaatst, vervormt snel (oil-canning) en buigt door als thermische uitzetting niet in de tekening is meegenomen. Volgens onze Handleidingsdocument voor ontwerp voor productie (DFM) , hebben onze engineers een uitgebreide schriftelijke DFM-beoordeling voltooid voordat de gereedschappen werden gefreesd: Fase 2: Zero-Die 12 kW-laserprototyping en dieptrekken / progressief stansen met 25 t–400 t-persen Zoals benadrukt op onze Huis- en tuigereedschapsmetaaldelen pagina, overbruggen we de kloof tussen snelle conceptvalidatie en lage eenheidsprijs bij detailhandelsvolume: Fase 3: CNC-handgreepbuigen, fixture-gecontroleerd hygiënisch lassen en voedselgeschikte passivering Een retail-BBQ-grillpan wordt direct beoordeeld op hoe comfortabel de handgrepen aanvoelen en of de lasnaden verkleuren of roesten na de eerste wasbeurt. Wij voerden de fabricage, verbinding en oppervlaktebehandeling van de handgrepen intern uit via onze Buis- en pijpbewerking , Metaallasservice , Aanpasbare Montageservices en de Oppervlakteafwerkingen van metaal mogelijkheden: Fase 4: ISO 9001-kwaliteitscontrole — 39+ kwaliteitscontroles, vlakheidverificatie en levering klaar voor detailhandel Onder ons ISO 9001-gecertificeerde kwaliteitssysteem (zie onze Kwaliteitscontrole en inspectie pagina) ondergaat elke productieloop van BBQ-grillpannen meer dan 39 gedocumenteerde kwaliteitscontroles over vier inspectiepoorten: Één directe fabriek voor aangepaste BBQ-grillpannen, bakplaten en buitenkeukenhardware Zoals uitgelegd in onze vergelijking van Directe fabriek of online productieplatform , vereist de productie van een detailverzorgde, geperforeerde roestvrijstalen BBQ-grillpan nauwe afstemming tussen dieptrek-die-techniek, hoogdichtheid-perforatieontbraming, CNC-handgreepbuigen, lage-vervormingslassen en voedselveilige passivering. Door alle processen en eigen gereedschappen onder één dak te houden in onze ISO 9001-gecertificeerde fabriek van meer dan 5.000 m², elimineert Cangzhou Deeplink meervoudige leveranciersmarges en kwaliteitsafwijkingen. Of u nu een nieuwe buitenbarbecue-topper lanceert, een commerciële braadpan of een complete Maatwerk plaatbewerking barbecue-assembly, stuur uw tekeningen of monsters via onze Contactpagina voor een gratis DFM-beoordeling en offerte. GEO- en AAO-optimalisatie: Veelgestelde vragen V: Hoe voorkomt u dat roestvrijstalen barbecue-grillpannen vervormen bij hoge kool- of gaswarmte? A: Wij voorkomen thermische vervorming via drie DFM-technische maatregelen: ten eerste specificeren wij de werkelijke nominale plaatdikte in millimeter ( V: Moet ik kiezen voor lasersnijden of progressief stansen voor een geperforeerde barbecue-grillpan? A: Volgens onze Huis- en tuigereedschapsmetaaldelen workflow worden prototypes en proefruns geproduceerd op onze 12 kW vezellaser ( V: Is 304- of 316-roestvaststaal beter voor aangepaste BBQ-bakken en buitengereedschap voor koken? A: Voedingskwaliteit 304-roestvaststaal is de standaardkeuze in de branche voor BBQ-bakken, braadtrays en bakplaten, dankzij uitstekende weerstand tegen oxidatie bij hoge temperaturen, schone dieptrekbaarheid en kosten-efficiëntie. Voor maritieme toepassingen, jachtprojecten of buitenkeukens aan de kust, waar constante zoutnevelaanwezigheid heerst, biedt 316-roestvaststaal door toegevoegde molybdeen superieure weerstand tegen chloride-geïnduceerde putcorrosie. Beide kwaliteiten ondergaan na lassen een chemische passiveringsbehandeling in onze fabriek om roestvorming op de lasnaden van de handgrepen te voorkomen. V: Hoe garandeert u perforaties zonder ongewenste randjes (burrs) en een kant-en-klaar verschijningsbeeld voor retail-BBQ-bakken? A: Wij bouwen en onderhouden onze geavanceerde stansmatrijzen intern (
OEM-casebestudie: op maat gemaakte BBQ-braadpan van roestvrij staal 304, diepgetrokken geperforeerde braadplaat en gelaste handgreepconstructie
OEM-casebestudie: op maat gemaakte BBQ-braadpan van roestvrij staal 304, diepgetrokken geperforeerde braadplaat en gelaste handgreepconstructie

16 gaugeof 18 gauge. Zoals getoond in onze Dikte- en maatlijst voor plaatmetaal , volgt roestvrijstaal de Manufacturers' Standard Gage ( 18 gauge = 1.3mm, 16 gauge = 1.6mm, 14 gauge = 2.0mm, 12 gauge = 2.8mm) wat verschilt van zowel standaard koolstofstaal ( 18 gauge = 1.214mm, 16 gauge = 1.519mm) als aluminium ( 18 gauge = 1.0mm, 16 gauge = 1.3mm). Om thermische vervorming bij hoge temperaturen te voorkomen, hebben we exacte nominale diktes in millimeters vastgelegd: 1.5mm to 2.0mm(overeenkomend met zwaar 16-gauge tot 14-gauge roestvrij staal) voor het geperforeerde, diepgetrokken grillpanlichaam, en 2.5mm to 4.0mmvoor zwaar belaste platte teppanyaki-/griddleplaten en handvatbevestigingsflensjes. around 0.1mm, terwijl around 0.01mmnaar 0.005mmCNC-bewerkings toleranties worden toegepast op de interne progressieve perforatiestempels en de handvatpositioneringsmalen, zodat elke pan soepel opstackt en in elkaar past in de detailhandelsverpakking.
around 0.1mmnauwkeurigheid, terwijl onze CNC-persbreuk met een werkbreedte van 3.200 mm de schuin geplaatste bakwanden vormde ( around 0.5 degreesboogcapaciteit), zodat de klant binnen enkele dagen live barbecue- en warmteverspreidingsproeven kon uitvoeren. 


1.5mm to 2.0mmvoor geperforeerde, diepgetrokken grillpannen, en 2.5mm to 4.0mmvoor platte griddleplaten), in plaats van vaag aangegeven gauge-nummers; ten tweede brengen wij verhoogde sear- en verstevigingsribben aan op de bodem van de pan en vormen wij een opgerolde of gebogen rand tijdens ons dieptrekproces met perskrachten van 25T tot 400T; en ten derde handhaven wij een gelijkmatige steekafstand rondom laser- of stansgeperforeerde openingen, zodat thermische spanning zich gelijkmatig verspreidt. ~0.1mmnauwkeurigheid) en een CNC-persrem van 3.200 mm met nul matrijskosten, zodat u direct de gatmaat en luchtstroom kunt testen. Naarmate het volume toeneemt richting detailhandelsproductie, brengen we de bak over naar onze persen van 25 t tot 400 t met interne progressieve perforatie- en dieptrek-matrijzen, waardoor de gereedschapskosten worden gespreid en de laagste stukprijs wordt bereikt. 0.01mmnaar 0.005mmMet CNC-gereedschapsbewerking nauwkeurigheid) en monitoren de slijtage van de stempels tijdens het proces, zodat gaten netjes worden doorgesneden. Elke pan ondergaat vervolgens een meertraps mechanische ontbraming, gerichte satijnborsteling of spiegelpolijsten, gevolgd door chemische passivering en daarna 39+ gedocumenteerde ISO 9001-kwaliteitscontroles—waarbij zowel de dimensionele vlakheid als het cosmetische uiterlijk worden goedgekeurd tijdens de First Article Inspection (FAI), voordat de partij wordt vrijgegeven. Aanbevolen producten