// utils/scriptService.js — 客服话术拉取与自动回复匹配 import request from './request.js'; const DEFAULT_SCRIPTS = { chat_image_confirm: { title: '温馨提示', content: '平台禁止任何违法违规行为,聊天内容仅限于商家与接单员正常业务对接。严禁赌博、诈骗及其他非法行为,违者后果自负。', confirm_text: '确认', cancel_text: '取消', }, cs_welcome: { content: '你好,请问有什么可以帮到您的?', }, }; const textCache = {}; const TEXT_CACHE_TTL = 5 * 60 * 1000; function fitModalBtn(text, fallback) { const t = (text || fallback || '确定').trim(); if (t && t.length <= 4) return t; return fallback || '确定'; } function openConfirmModal(script, onConfirm, onCancel) { wx.showModal({ title: ((script.title || '提示').trim()).slice(0, 32), content: script.content || '', confirmText: fitModalBtn(script.confirm_text, '确认'), cancelText: fitModalBtn(script.cancel_text, '取消'), success: (res) => { if (res.confirm) onConfirm && onConfirm(); else onCancel && onCancel(); }, fail: () => onCancel && onCancel(), }); } function mergeScript(sceneKey, remote) { const base = DEFAULT_SCRIPTS[sceneKey] || {}; if (!remote) return { ...base }; return { ...base, ...remote }; } export async function fetchScripts(sceneKeys) { if (!sceneKeys || !sceneKeys.length) return {}; const now = Date.now(); const cached = {}; const needFetch = []; sceneKeys.forEach((key) => { const entry = textCache[key]; if (entry && now - entry.time < TEXT_CACHE_TTL) { cached[key] = entry.data; } else { needFetch.push(key); } }); if (needFetch.length) { try { const res = await request({ url: '/peizhi/huashuhq', method: 'POST', data: { scene_keys: needFetch }, }); const payload = (res && res.data && res.data.code === 200) ? res.data.data || {} : {}; needFetch.forEach((key) => { textCache[key] = { time: now, data: payload[key] }; cached[key] = payload[key]; }); } catch (e) { console.warn('fetchScripts failed', e); } } const result = {}; sceneKeys.forEach((key) => { result[key] = mergeScript(key, cached[key]); }); return result; } export async function showConfirmByScene(sceneKey, onConfirm, onCancel) { try { const data = await fetchScripts([sceneKey]); openConfirmModal(data[sceneKey] || mergeScript(sceneKey, null), onConfirm, onCancel); } catch (e) { openConfirmModal(mergeScript(sceneKey, null), onConfirm, onCancel); } } export async function matchAutoReply(userText) { if (!userText || !userText.trim()) { return { matched: false, content: '', reply_type: 'text' }; } try { const res = await request({ url: '/peizhi/huashu_match', method: 'POST', data: { scene_key: 'cs_auto_reply', user_text: userText.trim(), }, }); if (res && res.data && res.data.code === 200 && res.data.data) { return res.data.data; } } catch (e) { console.warn('matchAutoReply failed', e); } return { matched: false, content: '', reply_type: 'text' }; } export async function getWelcomeText() { const data = await fetchScripts(['cs_welcome']); const script = data.cs_welcome || DEFAULT_SCRIPTS.cs_welcome; return script.content || DEFAULT_SCRIPTS.cs_welcome.content; } export default { fetchScripts, showConfirmByScene, matchAutoReply, getWelcomeText, };