Update README and project cleanup

This commit is contained in:
inkling
2026-04-08 14:52:09 +08:00
commit fafd267288
71 changed files with 14865 additions and 0 deletions

159
LOGIC_FIX_SUMMARY.md Normal file
View File

@@ -0,0 +1,159 @@
# 转化率清零问题 - 修复总结
## 🔴 问题描述
用户选择**多个标签**(特别是同一分类中的多个标签)后,转化率变成**0%**
## 🔍 根本原因
### 标签分类特性
系统中的标签按**分类**组织,同一分类中的标签通常是**互斥的**
```
监护人身份分类:
- 母亲 (tag_id=1)
- 父亲
- 祖母
- 外祖母 (tag_id=14) ← 与母亲互斥
文化程度分类:
- 小学
- 初中
- 高中
- 本科 (tag_id=2)
职业分类:
- 专业人士 (tag_id=3)
- 工人 (tag_id=16) ← 与专业人士互斥
- 农民
```
### 旧逻辑的问题
**所有标签都用AND逻辑**INTERSECT
```javascript
// 错误的逻辑
SELECT user_id FROM user_tags WHERE tag_id = 1 // 母亲
INTERSECT
SELECT user_id FROM user_tags WHERE tag_id = 14 // 外祖母
```
**结果为0**:因为没有用户既是"母亲"又是"外祖母"
### 数据验证
```sql
-- 测试同分类标签交集
SELECT COUNT(*) FROM (
SELECT user_id FROM user_tags WHERE tag_id = 1 -- 母亲99人
INTERSECT
SELECT user_id FROM user_tags WHERE tag_id = 14 -- 外祖母26人
);
-- 结果0 ❌ (预期应该是在这两个标签中任选其一的人数)
```
## ✅ 解决方案
### 新逻辑分类感知的OR/AND组合
**同一分类内**的多个标签 → **用OR逻辑**(任选其一)
**不同分类的**标签 → **用AND逻辑**(需同时满足)
```javascript
// 新逻辑示例
// 选择:(母亲 OR 外祖母) AND 本科
SELECT user_id FROM user_tags WHERE tag_id IN (1, 14) // 同分类OR
INTERSECT
SELECT user_id FROM user_tags WHERE tag_id = 2 // 不同分类AND
```
**结果125 ✓** (99个母亲 + 26个外祖母 = 125人其中与本科的交集)
### 实现细节
**文件修改**`server.js``/api/compute` 端点
```javascript
// 第1步按分类对选中标签分组
const categoryMap = {};
for (const inc of includes) {
const tagInfo = db.prepare(`
SELECT t.id, t.category_id FROM tags t WHERE t.id = ?
`).get(inc.tagId);
if (tagInfo) {
if (!categoryMap[tagInfo.category_id]) {
categoryMap[tagInfo.category_id] = [];
}
categoryMap[tagInfo.category_id].push(inc.tagId);
}
}
// 第2步为每个分类生成SQL子句
const categoryParts = [];
for (const catId in categoryMap) {
const tagIds = categoryMap[catId];
if (tagIds.length === 1) {
// 单标签直接用WHERE tag_id = ?
baseParams.push(tagIds[0]);
categoryParts.push(`SELECT user_id FROM user_tags WHERE tag_id = ?`);
} else {
// 多标签用IN (OR逻辑)
baseParams.push(...tagIds);
const placeholders = tagIds.map(() => '?').join(',');
categoryParts.push(`SELECT user_id FROM user_tags WHERE tag_id IN (${placeholders})`);
}
}
// 第3步分类间用INTERSECT (AND逻辑)
baseSql = categoryParts.join(' INTERSECT ');
```
## 📊 测试结果
### 测试1同分类多选
```bash
curl -X POST http://localhost:3456/api/compute \
-H "Content-Type: application/json" \
-d '{"selected":[{"tagId":1,"mode":"include"},{"tagId":14,"mode":"include"}]}'
```
**旧结果**count: 0, rate: 0% ❌
**新结果**count: 125, rate: 65.45% ✓
### 测试2跨分类组合
```bash
# 选择:(母亲 OR 外祖母) AND 本科
curl -X POST http://localhost:3456/api/compute \
-H "Content-Type: application/json" \
-d '{"selected":[{"tagId":1,"mode":"include"},{"tagId":14,"mode":"include"},{"tagId":2,"mode":"include"}]}'
```
**结果**count: 33, rate: 17.28% ✓
(其中29个母亲+本科4个外祖母+本科)
## 🎨 UI优化
在"已选条件"栏添加逻辑说明:
```
已选条件:[母亲] [本科] (同分类: OR | 不同分类: AND[✕清空]
```
## 📌 总结
| 方面 | 旧行为 | 新行为 |
|------|--------|--------|
| 同分类多标签 | AND导致为0 | **OR**(返回合理结果) |
| 跨分类标签 | AND | **AND**(保持不变) |
| 转化率 | 0% | ✓ 正确计算 |
| 用户体验 | 困惑 | ✓ 显示逻辑说明 |
## 🚀 验证步骤
1.**刷新浏览器**Ctrl+F5/Cmd+Shift+R清除缓存
2.**多选同分类标签**(如"母亲"+"父亲"
3.**观察转化率** - 应显示正常数值不为0%
4.**结合其他分类** - 结合不同分类验证AND逻辑
---
**修复时间**2026-04-07
**涉及文件**`server.js`, `public/index.html`