237 行
7.5 KiB
JavaScript
237 行
7.5 KiB
JavaScript
// ==============================================================================
|
|
// OmniCard AI (CRMmp) - BTP-19 意向度雷达评分算法与线索全景画像测试环境初始化脚本
|
|
// ==============================================================================
|
|
(function() {
|
|
console.log('[BTP-19] Injected test harness for Lead Scoring & Panoramic Profile...');
|
|
|
|
// 1. 设置登录凭证与权限
|
|
try {
|
|
window.localStorage.setItem('userStatus', 'login');
|
|
window.localStorage.setItem('userRole', 'admin');
|
|
window.localStorage.setItem('arco-lang', 'zh-CN');
|
|
} catch(e) {}
|
|
|
|
const token = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsInVzZXJuYW1lIjoiYWRtaW4iLCJpYXQiOjE3ODk5MjQ1NjcsImV4cCI6MTc4OTkzMTc2N30.Ia84OYGFXIl6ppPc1E3Y2aGgtdbe__g36oIHNfSGoVk';
|
|
|
|
// 2. 预设符合 BTP-19 意向度评分算法的潜客线索数据集
|
|
const leadsDatabase = [
|
|
{
|
|
id: 1,
|
|
name: 'Fatima Al-Mansoor',
|
|
company: 'Al-Mansoor Enterprises',
|
|
phone: '+971-50-9876543',
|
|
email: 'fatima@almansoor.ae',
|
|
status: 'hot',
|
|
intentScore: 92,
|
|
source: 'nfc',
|
|
notes: 'Gitex 展会近场 NFC 触碰,高意向采购 5,000 张双语智能卡,已咨询 AI 顾问方案',
|
|
visitorId: 'vis_uae_001',
|
|
cardId: 1,
|
|
createTime: '2026-09-21 01:10:00',
|
|
updateTime: '2026-09-21 01:10:00'
|
|
},
|
|
{
|
|
id: 2,
|
|
name: 'Michael Scott',
|
|
company: 'Dunder Mifflin Global',
|
|
phone: '+1-555-0199',
|
|
email: 'michael.scott@dundermifflin.com',
|
|
status: 'contacted',
|
|
intentScore: 85,
|
|
source: 'qr',
|
|
notes: '扫描宣传单二维码访问,下载了 vCard 电子名片并深度浏览案例达 4 分钟',
|
|
visitorId: 'vis_us_002',
|
|
cardId: 1,
|
|
createTime: '2026-09-21 01:12:00',
|
|
updateTime: '2026-09-21 01:12:00'
|
|
},
|
|
{
|
|
id: 3,
|
|
name: 'Elena Rostova',
|
|
company: 'Nordic Logistics AB',
|
|
phone: '+46-8-123456',
|
|
email: 'elena@nordiclogistics.se',
|
|
status: 'new',
|
|
intentScore: 65,
|
|
source: 'link',
|
|
notes: '通过国际博客短链初次访问,初步浏览了个人档案与核心深度文章',
|
|
visitorId: 'vis_se_003',
|
|
cardId: 1,
|
|
createTime: '2026-09-21 01:15:00',
|
|
updateTime: '2026-09-21 01:15:00'
|
|
},
|
|
{
|
|
id: 4,
|
|
name: 'Kenji Sato',
|
|
company: 'Tokyo Cloud Systems',
|
|
phone: '+81-3-5555-0143',
|
|
email: 'sato@tokyocloud.jp',
|
|
status: 'won',
|
|
intentScore: 98,
|
|
source: 'ai_chat',
|
|
notes: '与在线智能顾问深度交互 8 轮后主动提交留资表单,成功签署全球战略合作协议',
|
|
visitorId: 'vis_jp_004',
|
|
cardId: 1,
|
|
createTime: '2026-09-21 01:20:00',
|
|
updateTime: '2026-09-21 01:20:00'
|
|
}
|
|
];
|
|
|
|
// 3. 关联的雷达访问足迹轨迹数据集 (针对 Lead #1 / cardId: 1)
|
|
const radarDatabase = [
|
|
{
|
|
id: 1,
|
|
cardId: 1,
|
|
visitorId: 'vis_uae_001',
|
|
ip: '194.170.1.1',
|
|
country: 'United Arab Emirates',
|
|
city: 'Dubai',
|
|
touchType: 'nfc',
|
|
stayDurationMs: 320000,
|
|
scrollDepth: 95,
|
|
viewedBlocks: ['hero', 'case', 'form', 'social'],
|
|
createTime: '2026-09-21 01:25:00',
|
|
createdAt: '2026-09-21 01:25:00'
|
|
},
|
|
{
|
|
id: 2,
|
|
cardId: 1,
|
|
visitorId: 'vis_uae_001',
|
|
ip: '217.80.0.1',
|
|
country: 'Germany',
|
|
city: 'Frankfurt',
|
|
touchType: 'qr',
|
|
stayDurationMs: 85000,
|
|
scrollDepth: 60,
|
|
viewedBlocks: ['hero', 'article'],
|
|
createTime: '2026-09-21 01:15:00',
|
|
createdAt: '2026-09-21 01:15:00'
|
|
},
|
|
{
|
|
id: 3,
|
|
cardId: 1,
|
|
visitorId: 'vis_uae_001',
|
|
ip: '8.8.8.8',
|
|
country: 'United States',
|
|
city: 'San Francisco',
|
|
touchType: 'link',
|
|
stayDurationMs: 125000,
|
|
scrollDepth: 85,
|
|
viewedBlocks: ['hero', 'social'],
|
|
createTime: '2026-09-21 00:50:00',
|
|
createdAt: '2026-09-21 00:50:00'
|
|
}
|
|
];
|
|
|
|
// 4. 拦截网络请求,保证数据顺畅回显
|
|
const origOpen = window.XMLHttpRequest.prototype.open;
|
|
const origSend = window.XMLHttpRequest.prototype.send;
|
|
|
|
window.XMLHttpRequest.prototype.open = function(method, url) {
|
|
this.__method = method;
|
|
this.__url = url;
|
|
return origOpen.apply(this, arguments);
|
|
};
|
|
|
|
window.XMLHttpRequest.prototype.send = function(data) {
|
|
const url = this.__url || '';
|
|
let parsedBody = {};
|
|
if (typeof data === 'string') {
|
|
try { parsedBody = JSON.parse(data); } catch(e) {}
|
|
}
|
|
|
|
// 1) POST /api/admin/crm/lead/page
|
|
if (url.includes('/api/admin/crm/lead/page') || url.includes('/admin/crm/lead/page')) {
|
|
let filtered = [...leadsDatabase];
|
|
if (parsedBody.status) {
|
|
filtered = filtered.filter(item => item.status === parsedBody.status);
|
|
}
|
|
if (parsedBody.source) {
|
|
filtered = filtered.filter(item => item.source === parsedBody.source);
|
|
}
|
|
if (parsedBody.keyWord) {
|
|
const kw = parsedBody.keyWord.toLowerCase();
|
|
filtered = filtered.filter(item =>
|
|
item.name.toLowerCase().includes(kw) ||
|
|
item.company.toLowerCase().includes(kw) ||
|
|
item.email.toLowerCase().includes(kw) ||
|
|
item.phone.toLowerCase().includes(kw)
|
|
);
|
|
}
|
|
|
|
respond(this, JSON.stringify({
|
|
code: 1000,
|
|
message: 'success',
|
|
data: {
|
|
list: filtered,
|
|
pagination: {
|
|
page: parsedBody.page || 1,
|
|
size: parsedBody.size || 10,
|
|
total: filtered.length
|
|
}
|
|
}
|
|
}));
|
|
return;
|
|
}
|
|
|
|
// 2) GET /api/admin/crm/lead/info
|
|
if (url.includes('/api/admin/crm/lead/info') || url.includes('/admin/crm/lead/info')) {
|
|
const urlObj = new URL(url, window.location.href);
|
|
const queryId = urlObj.searchParams.get('id') || '1';
|
|
const lead = leadsDatabase.find(l => String(l.id) === String(queryId)) || leadsDatabase[0];
|
|
|
|
respond(this, JSON.stringify({
|
|
code: 1000,
|
|
message: 'success',
|
|
data: lead
|
|
}));
|
|
return;
|
|
}
|
|
|
|
// 3) POST /api/admin/crm/radar/page
|
|
if (url.includes('/api/admin/crm/radar/page') || url.includes('/admin/crm/radar/page')) {
|
|
let filteredRadar = [...radarDatabase];
|
|
if (parsedBody.cardId !== undefined && parsedBody.cardId !== null && parsedBody.cardId !== '') {
|
|
filteredRadar = filteredRadar.filter(item => String(item.cardId) === String(parsedBody.cardId));
|
|
}
|
|
|
|
respond(this, JSON.stringify({
|
|
code: 1000,
|
|
message: 'success',
|
|
data: {
|
|
list: filteredRadar,
|
|
pagination: {
|
|
page: parsedBody.page || 1,
|
|
size: parsedBody.size || 10,
|
|
total: filteredRadar.length
|
|
}
|
|
}
|
|
}));
|
|
return;
|
|
}
|
|
|
|
// 默认请求附带 Token
|
|
try {
|
|
this.setRequestHeader('Authorization', token);
|
|
} catch(e) {}
|
|
return origSend.apply(this, arguments);
|
|
};
|
|
|
|
function respond(xhr, jsonStr) {
|
|
Object.defineProperty(xhr, 'readyState', { get: () => 4 });
|
|
Object.defineProperty(xhr, 'status', { get: () => 200 });
|
|
Object.defineProperty(xhr, 'statusText', { get: () => 'OK' });
|
|
Object.defineProperty(xhr, 'responseText', { get: () => jsonStr });
|
|
Object.defineProperty(xhr, 'response', { get: () => jsonStr });
|
|
|
|
setTimeout(() => {
|
|
if (typeof xhr.onreadystatechange === 'function') {
|
|
xhr.onreadystatechange();
|
|
}
|
|
xhr.dispatchEvent(new Event('readystatechange'));
|
|
xhr.dispatchEvent(new Event('load'));
|
|
xhr.dispatchEvent(new Event('loadend'));
|
|
}, 40);
|
|
}
|
|
})();
|