deploy: 2026-07-15 15:33 部署更新

This commit is contained in:
selfrelease
2026-07-15 15:33:06 +08:00
parent 378d08c477
commit 2ed6dbe733
+90 -3
View File
@@ -1281,10 +1281,50 @@ function renderMarkdown(md) {
listStack.push('ul');
}
let liContent = inlineMd(trimmed.slice(2));
// 销售话术突出显示:微信绿色聊天气泡
let rawText = trimmed.slice(2).replace(/^\*\*(.+?)\*\*[:]?\s*/, '');
// 销售话术:绿色高亮卡片 + 复制按钮
if (/^\*\*销售话术\*\*/.test(trimmed.slice(2).trim())) {
liContent = liContent.replace(/^<strong class="font-semibold text-gray-900">销售话术<\/strong>[:]?/, '');
html += `<li class="text-gray-700"><div class="inline-block max-w-full" style="background:#95ec69;border-radius:12px;padding:12px 16px;color:#111827;line-height:1.6;box-shadow:0 1px 2px rgba(0,0,0,0.05);"><span class="text-xs font-medium text-green-800 opacity-75 mb-1 block">销售话术</span>${liContent}</div></li>`;
liContent = liContent.replace(/^<strong class="font-semibold text-gray-900">销售话术<\/strong>[:]?\s*/, '');
const scriptId = 'script-' + Math.random().toString(36).slice(2, 9);
html += `<li class="text-gray-700 list-none ml-0">
<div class="script-card border-l-4 border-green-500 bg-green-50 rounded-r-lg px-4 py-3 my-2 shadow-sm" id="${scriptId}">
<div class="flex items-center justify-between mb-1.5">
<span class="text-xs font-semibold text-green-800 flex items-center gap-1">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"/></svg>
销售话术
</span>
<button onclick="copyScript('${scriptId}')" class="text-xs text-green-700 hover:text-green-900 hover:bg-green-100 px-2 py-1 rounded transition-colors flex items-center gap-1">
<svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/></svg>
复制话术
</button>
</div>
<div class="script-content text-sm text-gray-800 leading-relaxed whitespace-pre-wrap">${liContent}</div>
</div>
</li>`;
} else if (/^\*\*预期回应\*\*/.test(trimmed.slice(2).trim())) {
// 预期回应:灰色信息块
liContent = liContent.replace(/^<strong class="font-semibold text-gray-900">预期回应<\/strong>[:]?\s*/, '');
html += `<li class="text-gray-700 list-none ml-0">
<div class="border-l-4 border-gray-300 bg-gray-50 rounded-r-lg px-4 py-3 my-2">
<div class="text-xs font-semibold text-gray-500 mb-1.5 flex items-center gap-1">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h18M7 15h12M7 20h12"/></svg>
预期回应
</div>
<div class="text-sm text-gray-600 leading-relaxed">${liContent}</div>
</div>
</li>`;
} else if (/^\*\*技巧提示\*\*/.test(trimmed.slice(2).trim())) {
// 技巧提示:黄色提示块
liContent = liContent.replace(/^<strong class="font-semibold text-gray-900">技巧提示<\/strong>[:]?\s*/, '');
html += `<li class="text-gray-700 list-none ml-0">
<div class="border-l-4 border-amber-400 bg-amber-50 rounded-r-lg px-4 py-3 my-2">
<div class="text-xs font-semibold text-amber-700 mb-1.5 flex items-center gap-1">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/></svg>
技巧提示
</div>
<div class="text-sm text-gray-700 leading-relaxed">${liContent}</div>
</div>
</li>`;
} else {
html += `<li class="text-gray-700">${liContent}</li>`;
}
@@ -1315,6 +1355,53 @@ function inlineMd(text) {
return text;
}
/** 复制销售话术到剪贴板,并显示 toast 提示 */
function copyScript(scriptId) {
const el = document.getElementById(scriptId);
if (!el) return;
const contentEl = el.querySelector('.script-content');
if (!contentEl) return;
const text = contentEl.innerText.trim();
navigator.clipboard.writeText(text).then(() => {
showToast('话术已复制', 'success');
}).catch(() => {
// 降级方案:使用临时 textarea
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed';
textarea.style.opacity = '0';
document.body.appendChild(textarea);
textarea.select();
try {
document.execCommand('copy');
showToast('话术已复制', 'success');
} catch (e) {
showToast('复制失败,请手动选择文本', 'error');
}
document.body.removeChild(textarea);
});
}
/** 轻量 toast 提示 */
function showToast(message, type) {
const colors = { success: 'bg-green-600', error: 'bg-red-500', info: 'bg-gray-700' };
const toast = document.createElement('div');
toast.className = `fixed top-6 left-1/2 -translate-x-1/2 ${colors[type] || colors.info} text-white text-sm px-4 py-2 rounded-lg shadow-lg z-50 transition-all duration-300`;
toast.style.opacity = '0';
toast.style.transform = 'translate(-50%, -10px)';
toast.textContent = message;
document.body.appendChild(toast);
requestAnimationFrame(() => {
toast.style.opacity = '1';
toast.style.transform = 'translate(-50%, 0)';
});
setTimeout(() => {
toast.style.opacity = '0';
toast.style.transform = 'translate(-50%, -10px)';
setTimeout(() => toast.remove(), 300);
}, 2000);
}
// --- 工具 ---
function escapeHtml(s) {
const div = document.createElement('div');