/** * 塔罗小程序 - 提问过滤与质量评分模块 * 纯本地规则,不依赖外部 API */ /** * 验证问题并返回过滤结果 * @param {string} question - 用户输入的问题 * @returns {Object} { status: "pass"|"rewrite"|"reject", reason: "", suggestions: [] } */ function validateQuestion(question) { if (!question || question.trim().length === 0) { return { status: 'reject', reason: '请输入您的问题', suggestions: [] }; } const q = question.trim(); // ========== 1. 直接拒绝规则 (reject) ========== // 1.1 联系方式检测 const contactPatterns = [ /微信|wx|weixin|vx/i, /qq|扣扣|q q/i, /电话|手机|tel|phone/i, /tg|telegram|飞机/i, /\d{5,}/ // 5位以上数字(可能是QQ号、电话等) ]; if (contactPatterns.some(pattern => pattern.test(q))) { return { status: 'reject', reason: '为了保证内容健康与占卜体验,该问题暂不支持占卜。', suggestions: [] }; } // 1.2 广告引流检测 const adPatterns = [ /加我|联系我|找我|私信|咨询我/i, /推广|代理|兼职|赚钱|刷单/i, /链接|网址|http|www\./i ]; if (adPatterns.some(pattern => pattern.test(q))) { return { status: 'reject', reason: '为了保证内容健康与占卜体验,该问题暂不支持占卜。', suggestions: [] }; } // 1.3 成人/违法内容检测 const illegalPatterns = [ /黄色|色情|裸|性爱/i, /毒品|大麻|冰毒/i, /枪支|炸药|爆炸/i ]; if (illegalPatterns.some(pattern => pattern.test(q))) { return { status: 'reject', reason: '为了保证内容健康与占卜体验,该问题暂不支持占卜。', suggestions: [] }; } // 1.4 专业决策类检测(医疗/法律/金融/赌博) const professionalPatterns = [ /病|癌|肿瘤|手术|治疗|吃药|诊断/i, /官司|诉讼|判决|坐牢|犯法/i, /股票|期货|基金|投资.*收益|炒股/i, /彩票|赌博|赌|博彩|中奖号码/i ]; if (professionalPatterns.some(pattern => pattern.test(q))) { return { status: 'reject', reason: '为了让占卜更聚焦你自身的成长,建议调整提问方式。塔罗牌无法替代专业咨询。', suggestions: [] }; } // 1.5 危险内容检测 const dangerPatterns = [ /自杀|轻生|结束生命|不想活/i, /杀人|伤害.*人|报复/i, /什么时候死|何时去世|死亡时间/i ]; if (dangerPatterns.some(pattern => pattern.test(q))) { return { status: 'reject', reason: '为了保证内容健康与占卜体验,该问题暂不支持占卜。如您正面临困境,建议寻求专业心理咨询帮助。', suggestions: [] }; } // ========== 2. 建议改写规则 (rewrite) ========== const rewritePatterns = [ { // 他/她爱不爱我 pattern: /(他|她|ta|TA|对方|那个人)(爱不爱|喜不喜欢|有没有感觉|在乎)/i, suggestions: [ '我在这段感情中感受到爱了吗', '我对这段关系的真实期待是什么', '我需要怎样的爱才能感到满足' ] }, { // 是否出轨 pattern: /(他|她|ta|TA|对方).*(出轨|劈腿|有别人|背叛)/i, suggestions: [ '我内心的不安来自哪里', '我在这段关系中缺失了什么', '我该如何重建内心的安全感' ] }, { // TA在干嘛 pattern: /(他|她|ta|TA|对方).*(在干嘛|在做什么|在想什么|想法)/i, suggestions: [ '我为什么会如此在意对方的动态', '我现在最需要关注的是什么', '我该如何平复内心的焦虑' ] }, { // 控制类问题 pattern: /(怎么|如何).*(让|使|控制|改变).*(他|她|ta|TA|对方)/i, suggestions: [ '我可以如何让自己变得更有吸引力', '我在关系中真正想要的是什么', '我该如何更好地表达自己的需求' ] }, { // 怎么让他喜欢我 pattern: /(怎么|如何).*(让|使).*(他|她|ta|TA|对方).*(喜欢|爱上|回来)/i, suggestions: [ '我身上最值得被爱的特质是什么', '我该如何在关系中保持真实的自己', '我准备好迎接一段健康的关系了吗' ] } ]; for (const item of rewritePatterns) { if (item.pattern.test(q)) { console.log('匹配到改写规则:', item.pattern); return { status: 'rewrite', reason: '为了让占卜更聚焦你的成长,我们建议这样提问:', suggestions: item.suggestions }; } } // ========== 3. 通过验证 ========== console.log('问题通过所有过滤规则'); return { status: 'pass', reason: '', suggestions: [] }; } /** * 评估问题质量 * @param {string} question - 用户输入的问题 * @returns {Object} { score: 0-5, level: "普通"|"良好"|"优秀", icon: "🌱"|"🌿"|"🌳" } */ function scoreQuestion(question) { if (!question || question.trim().length === 0) { return { score: 0, level: '普通', icon: '🌱' }; } const q = question.trim(); let score = 0; // 规则1: 以"我"为主体 (+2分) if (/^我|[,。!?\s]我/.test(q)) { score += 2; } // 规则2: 包含情绪或状态词 (+1分) const emotionWords = /感受|状态|心情|情绪|焦虑|迷茫|困惑|压力|快乐|幸福|痛苦|难过/; if (emotionWords.test(q)) { score += 1; } // 规则3: 开放式问题 (+1分) const openQuestions = /如何|怎样|什么|哪些|为什么/; if (openQuestions.test(q)) { score += 1; } // 规则4: 包含绝对预测词 (-2分) const absoluteWords = /会不会|能不能|一定会|肯定|必然|到底|结果是/; if (absoluteWords.test(q)) { score -= 2; } // 确保分数在 0-5 范围内 score = Math.max(0, Math.min(5, score)); // 映射等级 let level, icon; if (score <= 2) { level = '普通'; icon = '🌱'; } else if (score <= 4) { level = '良好'; icon = '🌿'; } else { level = '优秀'; icon = '🌳'; } return { score, level, icon }; } module.exports = { validateQuestion, scoreQuestion };