9 Commits

Author SHA1 Message Date
yuzhiran 56c9376c58 docs: document brand optimization v25.1 (brand tone, SEO/GEO, sources, series column, WeChat publisher)
PROGRESS.md: adds Phase A-F brand optimization to v25 section covering 6 prompt brand tone injection, long-tail SEO keywords, differentiated sources (machine-intelligence/arXiv/indie dev/industry reports/AI products), series column feature, and WeChat publisher blocked status.

Ultraworked with Sisyphus

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-23 13:32:23 +08:00
yuzhiran 302efd5f2d fix(ui): responsive mobile layout with auth flow refactoring for campaigns
Adds: v-cloak fix, mobile card-list views for all tables, responsive CSS breakpoints, early auth redirect, CDN script reorder to head, ElementPlusIconsVue safety check, global ElMessage reference. Moves async mounted to .then() pattern to avoid Vue 3 SFC issues.

Ultraworked with Sisyphus

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-23 13:30:19 +08:00
yuzhiran 897f72012f chore(cleanup): remove old content ideas and sustainability data
Deleted: 10 legacy topic cards (001-010), README from content/ideas/, old sustainability_topics.json, test-fix notification. These belonged to deprecated 'sustainable living' content pillar.

Ultraworked with Sisyphus

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-23 13:26:50 +08:00
yuzhiran 0258a9af9f feat(script): add DB migration script for content focus refactoring
Comprehensive DB migration: TopicField cleanup (5 old deactivated, 3 new updated), Topic reassignment (43/47 migrated), Article cleanup (15 deleted), CollectorCategory/Cleaning (12 old deactivated), TrendFieldMapping sync (11 entries)

Ultraworked with Sisyphus

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-23 13:26:22 +08:00
yuzhiran 9058539bae feat(config): add differentiated information sources (arXiv/indie dev/industry reports)
Adds 5 new sources: machine-intelligence RSS, arXiv paper search, indie developer search, industry data report search, AI product changelog search. Differentiates from generic AI media.

Ultraworked with Sisyphus

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-23 13:25:39 +08:00
yuzhiran 9fba863ce7 feat(config): align content strategy with brand direction
initial_data: field descriptions humanized, collector search queries include long-tail keywords, platform formats updated collector.py: DEFAULT_CHINA_PAINS expanded with specific pain questions (e.g. '35岁学AI来得及吗') topic_selector.py: domain mapping 11->18 entries (Prompt/AI编程/AI写作/数据隐私/AI教育/一人企业)

Ultraworked with Sisyphus

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-23 13:25:11 +08:00
yuzhiran 45ad5443c1 feat(prompt): inject brand tone into 6 platform prompts
Section expansion: zhihu (unique data + debate), wechat (tech-humanity reflection), xiaohongshu (real usage data) Title optimize: all 3 platforms aligned with new brand direction

Ultraworked with Sisyphus

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-23 13:24:38 +08:00
yuzhiran ef289b18d1 feat(ui): add series filter to topics search area
Adds column/category filter dropdown in topics.html search form, with seriesOptions computed and filteredTopics logic

Ultraworked with Sisyphus

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-23 13:23:19 +08:00
yuzhiran f1e6c11505 feat(models): add series column to Topic for content columns
Topic model: new series VARCHAR field (optional, indexed)
Schema: series in TopicBase/TopicCreate/TopicUpdate
API: GET /api/topics supports ?series= query param
DB migration: ALTER TABLE topics ADD COLUMN series

Ultraworked with Sisyphus

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-06-23 13:22:13 +08:00
26 changed files with 676 additions and 2008 deletions
+126 -2
View File
@@ -3,7 +3,7 @@
> 本文件为项目进度唯一真理源,所有进度信息以此为准。
> 其他文档中的进度描述一律以本文为准。
**最后更新**2026-06-21 (v24)
**最后更新**2026-06-23 (v25)
---
@@ -234,7 +234,131 @@
---
## 六、归档日志
## 十二、内容策略聚焦改造(v25 · 2026-06-23
### 从「6领域分散」到「3领域聚焦」
**背景**:此前内容覆盖可持续生活、数字游民、个人成长等 6 个领域,资源分散、品牌辨识度低。v25 聚焦「宇之然」品牌核心方向:AI 与前沿科技。
**聚焦的 3 个领域:**
| 领域 | 方向 | 覆盖话题 |
|------|------|---------|
| AI与效率 🤖 | AI 工具、工作流、效率方法 | AI工具实测、AI前沿资讯、效率方法论 |
| 科技人文 🔬 | AI 伦理、科技反思 | 数据隐私、人机关系、数字生活反思 |
| 未来工作方式 💼 | 远程工作、职业转型 | AI时代职场、一人企业、技能升级 |
### Phase 1 — 代码改造(6 个文件)
| 文件 | 改动 |
|------|------|
| `initial_data.py` | TopicField 从 6 个缩减为 3 个;CollectorCategory 从 8 个环保类改为 5 个 AI/科技类;PlatformConfig allowed_tags 全部替换为 AI/效率/科技标签 |
| `prompt_loader.py` | `sources_optimization` 提示词从"可持续生活领域"改为"AI与科技人文领域" |
| `config/sources.yaml` | 全部信息源替换为 AI/科技相关(36氪RSS、少数派RSS、5 组 AI 搜索词、1 个本地案例库) |
| `collector.py` | `DEFAULT_CHINA_PAINS` 从 8 个(7 环保 + 1 AI)改为 5 个 AI 焦点;`map_category_to_field` 返回 AI 领域;移除 4 处"可持续性"日志/默认值 |
| `topic_selector.py` | `DEFAULT_TREND_DOMAIN_MAP` 从 12 条(含可持续生活/个人成长/副业/家庭教育)改为 11 条纯 AI/科技映射 |
| `migrate_content_focus.py` | **新建** — Phase 2 DB 迁移脚本 |
### Phase 2 — DB 迁移
| 操作 | 影响 |
|------|------|
| TopicField | 更新 3 个新领域字段(排序/描述/图标),停用 5 个旧领域(可持续生活系统/可持续生活/数字游民/个人成长/个人知识工厂) |
| Topic | 47 个 Topic 中 43 个已迁移到新领域(4 个无法映射的归入"AI与效率" |
| Article | 删除 15 篇与旧可持续领域关联的旧文章 |
| CollectorCategory | 创建 3 个新分类(AI前沿资讯/AI工具实测/AI与职场),更新 2 个(AI生活化/科技人文),停用 12 个旧分类(循环消费/低碳出行/干净饮食/零浪费生活/绿色家电与节能/碳普惠/环保科技产品/自我丰容/适我主义/情绪价值与心理健康/沉浸式新生活/数字游民与自由职业) |
| CollectorSource | 停用 1 个旧源,创建 2 个新 AI 搜索源 |
| PlatformConfig | 3 个平台(知乎/微信/小红书)的 allowed_tags 全部替换为 AI/科技标签 |
| TrendFieldMapping | 同步 11 条新映射,停用旧映射 |
### Phase 3 — 文件清理
| 项目 | 数量 | 释放空间 |
|------|------|---------|
| 日志文件 (`automation/logs/`) | 400 个 | 2.5 MB |
| 旧选题卡片 (`content/ideas/`) | 11 个文件 | 96 KB |
| 可持续采集原始数据 (`sustainability_raw/`) | 多子目录 | 224 KB |
| 旧数据文件 (`sustainability_cases.json/topics.json`) | 2 个 | - |
| 旧草稿/大纲/研究笔记 (`drafts/outlines/research/`) | 91 个文件 | 740 KB |
| 通知记录 (`notifications/`) | 1 个 | 4 KB |
### Phase 4 — 重启验证
- 服务运行中:HTTP 200 ✅
- API 认证正常 ✅
- TopicFields 仅返回 3 个活跃领域 ✅
- Topic 总计 47 个,全部关联新领域 ✅
- Articles 已清理(0 篇过时文章)✅
- CollectorCategories 仅 5 个 AI 分类活跃 ✅
### 关键架构决策
- `collector.py` 类名(SustainabilityCollector/SustainabilitySource/SustainabilityCase)保留未改——减少中断风险,功能已从 sustainable 转向 AI/tech,重命名需要跨 20+ 文件修改
- DB 种子数据按 `if count() == 0` 判断,已有数据的库通过独立迁移脚本处理
- 旧数据优先保留(硬删除可能影响引用完整性),标记 `is_active=False` 而非删除
### 品牌调性与内容深化(v25.1 · 2026-06-23 第二次迭代)
**问题诊断**:第一次聚焦改造后,内容方向虽已收敛到 AI 3 领域,但存在品牌割裂("宇之然"调性偏人文自然 vs 内容全是纯工具测评)、AI 赛道竞争红海、平台策略错配(公众号叙事体不适合写 AI 工具)等深层问题。
**Phase A — 品牌调性注入(最核心改动)**
| prompt | 改动 | 预期效果 |
|--------|------|---------|
| `section_expansion_zhihu` | 加入独家数据要求+观点交锋,不只是介绍工具而是探讨技术如何改变人 | 在拥挤的 AI 知乎赛道上做出壁垒 |
| `section_expansion_wechat` | 从「AI 工具叙事」→「科技人文思辨」:用「我」口吻写 AI 时代的困惑、顿悟或观察 | 对齐品牌调性,摆脱"AI 测评不适合叙事体"的结构性矛盾 |
| `section_expansion_xiaohongshu` | 每个结论配亲测数据/对比/结果 | 用真实数据对抗同质化 |
| `title_optimize_zhihu` | 增加观点交锋感+立场态度 | 从"工具文标题"→"辩论帖标题" |
| `title_optimize_wechat` | 改为科技叙事方向,参考风格:「AI帮我写周报的第3个月,我终于发现哪里不对了」 | 对齐公众号新定位 |
| `title_optimize_xhs` | 每条标题含数字/时间/效果结果感 | 提高点击率 |
**Phase B — SEO/GEO 长尾关键词**
- `collector.py`: `DEFAULT_CHINA_PAINS` 每个痛点扩展 3-5 个长尾问题("AI写周报""AI提示词怎么写""35岁学AI来得及吗"
- `topic_selector.py`: `DEFAULT_TREND_DOMAIN_MAP` 从 11 条→18 条(新增 Prompt/提示词/AI编程/AI写作/数据隐私/AI教育/一人企业)
**Phase C — 差异化信息源**
`sources.yaml` 中新增 5 个与通用 AI 媒体形成区分的源:
| 新源 | 差异化定位 |
|------|-----------|
| 机器之心 RSS | AI 学术前沿,区别于大众科技媒体 |
| AI 学术论文搜索(arXiv 中文) | 一手论文解读内容源 |
| 独立开发者搜索 | 独特的小众 AI 产品视角 |
| 行业数据报告搜索 | 自采数据的基础来源 |
| AI 产品动态搜索 | 第一手产品更新信息 |
**Phase D — 栏目化内容机制**
为「AI工具实测周报」等固定栏目铺平道路:
- Topic 模型新增 `series` 字段(VARCHAR, optional, indexed
- API 端点 `/api/topics` 新增 `?series=` 筛选参数
- 前端 topics.html 搜索区增加「栏目」下拉筛选器
- `database.py` 新增 ALTER TABLE 迁移(`topics.series`
**Phase E — 公众号发布流水线**[需提供 WeChat APP_ID/APP_SECRET]
- 已安装 `/wechat-mp-publisher` 技能,支持远程 MCP 中转
- `wechat.env``mcp.json` 尚未配置
### 关键文件变更汇总
| 文件 | 变更类型 | 说明 |
|------|---------|------|
| `scripts/prompt_loader.py` | 修改 | 6 个 prompt 品牌调性注入(section_expansion×3 + title_optimize×3 |
| `platform/backend/app/initial_data.py` | 修改 | 领域描述人文化、采集搜索词长尾化、平台格式说明更新 |
| `scripts/collector.py` | 修改 | DEFAULT_CHINA_PAINS 长尾关键词扩展 |
| `scripts/topic_selector.py` | 修改 | DEFAULT_TREND_DOMAIN_MAP 从 11→18 条 |
| `config/sources.yaml` | 修改 | 新增机器之心/arXiv/独立开发者/行业报告/AI产品动态 5 个差异源 |
| `platform/backend/app/models.py` | 修改 | Topic 模型新增 series 字段 |
| `platform/backend/app/schemas.py` | 修改 | TopicBase/TopicCreate/TopicUpdate 新增 series |
| `platform/backend/app/api/topics.py` | 修改 | list_topics 新增 series 查询参数 |
| `platform/backend/app/database.py` | 修改 | ALTER TABLE 添加 topics.series 列 |
| `platform/frontend/topics.html` | 修改 | 搜索区新增栏目下拉筛选器 |
| `scripts/migrate_content_focus.py` | 新建 | DB 迁移脚本(Phase 2 遗留) |
---
> 过时文档统一移入 `archive/`,防止误导。
@@ -1,14 +0,0 @@
{
"task": "test",
"time": "2026-04-22 19:00",
"topic_count": 1,
"case_count": 2,
"source_count": 3,
"details_link": "/test",
"topic_title": "测试选题",
"image_count": 5,
"output_dir": "/test",
"status": "测试状态",
"error": "",
"log_path": "/tmp/test.log"
}
@@ -1,54 +0,0 @@
[
{
"id": "LIVING-001-26",
"title": "零浪费家庭实验:从囤积到精简的100天",
"cases": [],
"audience": "26-35岁城市焦虑青年",
"china_pain_points": "消费主义陷阱、快递包装泛滥、垃圾分类执行难",
"localization_solution": "家庭减法清单、快递包装回收点地图、社区交换市集",
"mvp_actions": "1. 本月减少50%快递包装 2. 建立家庭减法清单 3. 参与社区交换市集",
"estimated_length": 3500,
"priority_score": 85.5,
"field": "可持续生活系统",
"format": "趋势洞察 + 实操指南",
"core_concept": "少即是多,从消费主义回归生活本质",
"audience_pain": "被消费主义裹挟,想改变但不知道从何开始",
"unique_angle": "用数据量化减法效果,用真实案例展示转变过程",
"priority": "高",
"total_score": 85.5,
"compliance_score": 100,
"source_file": "automation/data/sustainability_topics.json",
"ready_at": "2026-05-08",
"published_at": null,
"platform_urls": {},
"status": "待处理",
"lock_by": null,
"lock_at": null
},
{
"id": "TECH-001-26",
"title": "AI副业入门:用DeepSeek实现第一笔收入的100天",
"cases": [],
"audience": "26-35岁城市焦虑青年",
"china_pain_points": "主业不稳定、副业方向迷茫、技能变现难",
"localization_solution": "AI工具链整合、国内平台变现路径、从0到1的实战案例",
"mvp_actions": "1. 学习DeepSeek基础操作 2. 找到第一个付费客户 3. 建立可复制的服务流程",
"estimated_length": 4000,
"priority_score": 88.2,
"field": "科技向善",
"format": "趋势洞察 + 实操指南",
"core_concept": "用AI放大个人能力,实现副业收入",
"audience_pain": "想搞钱但不知道从哪开始,担心AI替代自己",
"unique_angle": "100天真实记录,从0到第一笔收入的完整路径",
"priority": "高",
"total_score": 88.2,
"compliance_score": 100,
"source_file": "automation/data/sustainability_topics.json",
"ready_at": "2026-05-08",
"published_at": null,
"platform_urls": {},
"status": "待处理",
"lock_by": null,
"lock_at": null
}
]
+73 -87
View File
@@ -1,4 +1,4 @@
# 信息源配置(可持续性相关
# 信息源配置(AI与科技人文领域
# 注意:仅保留国内可稳定访问的源,移除被墙/下线的源
sustainability_sources:
@@ -9,16 +9,14 @@ sustainability_sources:
url: "https://36kr.com/feed"
update_frequency: "daily"
credibility: "high"
focus: "科技商业、绿色经济"
focus: "科技商业、AI行业"
keywords:
- "AI"
- "新能源"
- "可持续"
- "环保"
- "绿色"
- "低碳"
- "ESG"
- "循环"
- "人工智能"
- "大模型"
- "科技"
- "数字化"
- "创业"
- name: "少数派"
type: "rss"
url: "https://sspai.com/feed"
@@ -31,99 +29,87 @@ sustainability_sources:
- "工具"
- "数字"
- "智能"
- "工作流"
- name: "机器之心"
type: "rss"
url: "https://jiqizhixin.com/rss"
update_frequency: "daily"
credibility: "high"
focus: "AI学术前沿、论文解读"
keywords:
- "AI"
- "论文"
- "大模型"
- "算法"
- "研究"
- "学术"
# 搜索引擎采集(通过Bing中文搜索抓取热点)
# 基于《2025中国可持续消费报告》《绿色低碳消费大数据报告》等权威调研得出的七大热点方向
web_search:
- name: "循环消费搜索"
- name: "AI前沿资讯搜索"
type: "web_search"
query: "以旧换新 二手交易 闲置 循环 2026"
query: "AI 人工智能 大模型 前沿 突破 2026"
update_frequency: "daily"
credibility: "medium"
focus: "以旧换新/二手循环/租赁经济"
- name: "低碳出行搜索"
type: "web_search"
query: "新能源车 骑行 绿色通勤 低碳出行 2026"
update_frequency: "daily"
credibility: "medium"
focus: "新能源车/骑行/绿色出行"
- name: "干净饮食搜索"
type: "web_search"
query: "干净饮食 有机食品 植物基 本地食材 2026"
update_frequency: "daily"
credibility: "medium"
focus: "干净饮食/有机食品/植物基"
- name: "零浪费生活搜索"
type: "web_search"
query: "零浪费 自带杯 极简生活 可持续时尚 2026"
update_frequency: "daily"
credibility: "medium"
focus: "零浪费/自带杯/极简/可持续时尚"
- name: "绿色家电搜索"
type: "web_search"
query: "绿色家电 一级能效 以旧换新 节能 2026"
update_frequency: "daily"
credibility: "medium"
focus: "绿色家电/家庭节能/国补政策"
- name: "碳普惠搜索"
type: "web_search"
query: "碳账户 碳普惠 个人碳减排 蚂蚁森林 2026"
update_frequency: "daily"
credibility: "medium"
focus: "碳账户/碳普惠/个人碳减排"
- name: "环保科技搜索"
type: "web_search"
query: "环保科技 绿色产品 可持续材料 2026"
update_frequency: "daily"
credibility: "medium"
focus: "环保科技/可持续产品/绿色材料"
focus: "AI行业动态、技术突破"
- name: "AI工具搜索"
type: "web_search"
query: "AI工具 人工智能 效率提升 2026"
query: "AI工具 效率提升 AI工作流 实用 2026"
update_frequency: "daily"
credibility: "medium"
focus: "AI工具/效率方法"
focus: "AI工具评测、效率方法"
- name: "AI职场搜索"
type: "web_search"
query: "AI 裁员 职业转型 AI技能 远程工作 2026"
update_frequency: "daily"
credibility: "medium"
focus: "AI对就业影响、职业转型"
- name: "AI生活化搜索"
type: "web_search"
query: "AI陪伴 AI生活助手 AI心理咨询 智能体 2026"
update_frequency: "daily"
credibility: "medium"
focus: "AI人格化、生活场景应用"
- name: "科技人文搜索"
type: "web_search"
query: "AI伦理 数字生活 科技反思 人机关系 2026"
update_frequency: "daily"
credibility: "medium"
focus: "AI伦理、科技人文反思"
# ── 差异化源(与通用AI媒体形成区分)──
- name: "AI学术论文搜索"
type: "web_search"
query: "arXiv 论文 AI 最新研究 大模型 2026"
update_frequency: "weekly"
credibility: "high"
focus: "AI学术前沿、论文中文解读"
- name: "独立开发者搜索"
type: "web_search"
query: "独立开发者 AI产品 一人公司 出海工具 indie hacking 2026"
update_frequency: "daily"
credibility: "medium"
focus: "独立开发者生态、小众AI产品"
- name: "行业数据报告搜索"
type: "web_search"
query: "AI行业报告 数据统计 市场分析 AI应用渗透率 2026"
update_frequency: "daily"
credibility: "high"
focus: "行业数据、市场报告、AI应用统计"
- name: "AI产品动态搜索"
type: "web_search"
query: "AI产品发布 更新 changelog 新功能 OpenAI Claude 2026"
update_frequency: "daily"
credibility: "medium"
focus: "AI产品迭代、功能更新"
# 本地案例库(保底数据源)
local:
- name: "宇之然本地案例库"
- name: "宇之然AI案例库"
type: "local"
file: "strategy/全球案例数据库-v1.md"
file: "automation/data/ai_cases.json"
update_frequency: "weekly"
credibility: "medium"
focus: "全球-本土案例"
- name: "历史选题库"
type: "local"
file: "automation/data/sustainability_topics.json"
update_frequency: "daily"
credibility: "medium"
focus: "复用已有选题"
# 案例验证要求
validation:
require_at_least_2_sources: false
prefer_official_data: false
min_data_points: 1
# 选题优先级权重
topic_priority:
audience_match: 0.3
data_availability: 0.25
uniqueness: 0.2
executability: 0.15
brand_fit: 0.1
# 可持续性子领域分类(基于2025-2026中国消费市场实际趋势调研)
# 参考来源:《2025中国可持续消费报告》《绿色低碳消费大数据报告》商务部等9部门绿色消费20条
sustainability_categories:
- "循环消费" # 以旧换新/二手交易/租赁经济 | 2025年二手交易额1.69万亿,闲鱼6亿用户
- "低碳出行" # 新能源车/骑行/绿色通勤 | 新能源车年产销破1000万辆,骑行爱好者超1800万
- "干净饮食" # 有机食品/植物基/本地食材 | 有机食品1247亿销售,干净饮食笔记344万篇
- "零浪费生活" # 自带杯/极简/可持续时尚 | 自带杯笔记277万篇,精简护肤121万篇,极简1186万讨论
- "绿色家电与节能" # 一级能效/智能节能/以旧换新 | 一级能效家电占比90%+,国补政策明确导向
- "碳普惠" # 碳账户/碳积分/个人碳减排 | 武汉200万市民碳账户,多城碳普惠平台上线
- "环保科技产品" # 可持续材料/绿色产品/环保科技 | 消费者愿意为绿色产品支付溢价,但需可感知价值
- "AI与效率" # AI工具/效率方法/数字助手 | 2026年AI深度融入消费与生活,消费链被AI重新定义
focus: "AI行业案例"
# 内容合规检查清单
compliance:
@@ -136,5 +122,5 @@ compliance:
required:
- "至少3个可靠引用"
- "数据标注来源"
- "包含MVP行动"
- "包含可操作建议"
- "中性客观语气"
@@ -1,123 +0,0 @@
# 在上海阳台种菜一年,我收获了啥?
**领域**:自然 / 生活
**形式**:实操指南 + 个人故事
**预估字数**2500
**核心观点**:城市农业不仅是种菜,更是与自然重建连接的生活方式
**受众痛点**
- 想体验田园生活但没条件去农村
- 担心食品安全,想自己种菜但不懂技术
- 阳台空间小,不知道能种什么
- 担心养不活植物,缺乏信心
- 城市生活压力大,寻求放松方式
**独特角度**
- 不鼓吹"田园牧歌",客观展示失败和踩坑
- 用数据说话(产量、成本、时间投入)
- 结合科技元素(智能种植、垂直农业)
- 从心理层面谈与植物建立连接的意义
- 延伸讨论城市食物系统和可持续生活
**数据/案例**(至少3个来源):
1. 上海阳台种植调研报告(找本地社区数据)
2. 不同蔬菜的生长周期和产量数据(农业网站)
3. 城市农业的心理学研究(减压、幸福感)
4. 自己一年的种植记录(日志、照片)
5. 智能种植设备对比(自动浇水、补光灯等)
**预估完成时间**4天
**优先级**:高
**预计发布时间**2026-04-15
**状态**:待处理
---
## 选题评估矩阵
| 维度 | 评分 | 说明 |
|------|------|------|
| 受众覆盖 | 8 | 城市青年有共鸣,但相对垂直 |
| 独特性 | 9 | 结合个人故事+科学种植+城市农业视角 |
| 数据可得性 | 8 | 自己有一年数据,可补充调研 |
| 可持续性 | 7 | 可写成系列(不同季节、不同植物) |
| 平台契合度 | 9 | 知乎生活/园艺话题,小红书也适合 |
| 品牌契合度 | 10 | 科技+自然+生活的完美结合 |
| **总分** | **51** | 优先执行 ✅ |
---
## 大纲草稿
### 开头(300字)
- 场景:在上海20㎡阳台种出一个小菜园
- 问题:很多人觉得不可能/太麻烦
- 引子:一年的收获不仅是蔬菜,还有更多
### 主体(2000字)
**第一部分:为什么开始?(300字)**
- 疫情后的食物焦虑
- 对超市蔬菜的不信任
- 想找回"土地连接感"
- 初始期待(vs 现实)
**第二部分:阳台农业的真相(500字)**
- 空间利用:垂直种植+合理规划
- 品种选择:适合上海的蔬菜(番茄、辣椒、生菜、香草)
- 成本核算:投入 vs 产出(经济账和心理账)
- 时间投入:每天半小时,周末2小时
- 失败案例分享(死掉的植物+经验)
**第三部分:科技让种菜变简单(400字)**
- 智能灌溉系统(DIY vs 购买)
- 补光灯的应用(光照不足的冬天)
- 种植APP辅助(记录、提醒、社区)
- 垂直农业设备介绍(Aerogarden等)
- AI助手帮我分析植物健康(拍照识别病害)
**第四部分:收获的不仅是蔬菜(400字)**
- 产量记录(一年收获多少斤)
- 心理收获:减压、专注、成就感
- 家庭关系改善(和家人一起照料)
- 环保意义(减少碳足迹、包装垃圾)
- 生活方式的改变(更关注季节性、本地食物)
**第五部分:给新手的建议(400字)**
- 从简单的开始(香草、生菜)
- 不要一次买太多植物
- 必备工具清单(花盆、土、工具)
- 常见问题和解决方案
- 哪里获取信息和社区支持
### 结尾(200字)
- 城市农业不是回归原始,而是科技赋能的现代生活选择
- 哪怕只有一盆香草,也是与自然的连接
- 呼吁:从小事做起,重建人与自然的联系
- 预告:后续会分享具体种植技术细节
---
## 资源清单
### 数据来源(待收集)
- [ ] 上海市社区农业调查报告
- [ ] 阳台种植产量统计数据
- [ ] 城市农业心理健康研究论文
- [ ] 各蔬菜品种生长数据
### 图片素材(待准备)
- [ ] 一年种植时间线照片
- [ ] 不同生长阶段特写
- [ ] 收获成果展示
- [ ] 种植设施和工具照片
### 引用来源(待标注)
- [ ] 农业技术网站
- [ ] 学术数据库
- [ ] 种植社区讨论
- [ ] 科技产品官网
---
**决策**:这是一个高潜力选题,品牌契合度极高,预计能获得良好反响。建议优先执行。
@@ -1,143 +0,0 @@
# AI时代,什么能力不会被替代?
**领域**:科技 / 职场
**形式**:趋势洞察 + 实操建议
**预估字数**2800
**核心观点**:AI淘汰的不是工作,而是不会使用AI的人;但有些"人类特质"能力反而更珍贵
**受众痛点**
- 担心被AI替代,职业焦虑严重
- 不知道如何提升自己的竞争力
- 听说AI很强,但不知道学什么
- 想转行但方向迷茫
- 担心投入学习最后还是被淘汰
**独特角度**
- 区分配"被AI强化的能力"和"AI无法替代的能力"
- 从历史技术进步规律看职业演变(不是第一次自动化革命)
- 强调"审美、共情、意义构建"等软技能
- 给出具体的能力提升路径,不是泛泛而谈
- 结合宇之然"科技沟通万物,回归自然"的哲学
**数据/案例**(至少3个来源):
1. 世界经济论坛《未来就业报告》技能趋势数据
2. 美国劳工统计局职业自动化概率研究
3. AI能力边界研究(GPT-4o vs 人类能力对比)
4. 历史案例:工业革命、计算机革命后的职业变化
5. 访谈案例:哪些岗位在AI时代反而增值?
**预估完成时间**5天
**优先级**:高
**预计发布时间**2026-04-18
**状态**:待处理
---
## 选题评估矩阵
| 维度 | 评分 | 说明 |
|------|------|------|
| 受众覆盖 | 9 | 所有职场人士都关心,流量潜力大 |
| 独特性 | 8 | 避开"AI工具教程"红海,聚焦深度思考 |
| 数据可得性 | 9 | 大量研究报告和历史数据 |
| 可持续性 | 8 | 可写成系列(不同行业、不同能力维度) |
| 平台契合度 | 9 | 知乎职场/科技话题热门 |
| 品牌契合度 | 10 | 科技向善+人文关怀,契合价值观 |
| **总分** | **53** | 优先执行 ✅ |
---
## 大纲草稿
### 开头(400字)
- 现象:朋友被AI工具震撼,担心失业
- 核心问题:AI时代,我们该学什么?
- 观点:AI淘汰的不是工作,而是不会使用AI的人;但有些"人类特质"能力反而更珍贵
- 预告:本文将分析AI的能力边界,并给出具体的技能提升建议
### 主体(2200字)
**第一部分:AI到底有多强?(400字)**
- 当前AI能力范围(文本、图像、代码、数据分析)
- AI的局限性:没有意识、没有真实体验、无法承担责任
- AI的依赖:需要人类提供高质量prompt、数据、验证
- 数据:哪些职业自动化概率高(根据研究报告)
- 事实:AI不是万能,只是工具
**第二部分:历史给我们的启示(300字)**
- 工业革命:机器取代体力劳动,但创造了新职业
- 计算机革命:打字员消失,但程序员、设计师兴起
- 每次技术革命都淘汰旧技能,但同时创造更多新技能
- 规律:重复性工作易被替代,创造性、社交性工作更难
- 结论:不恐惧技术,而是学会驾驭技术
**第三部分:AI无法替代的3类能力(800字)**
**A. 审美与创造力**
- AI生成的美术、音乐、文字缺少"灵魂"
- 真正的好设计需要理解人的情感和文化
- 创意工作者(作家、艺术家、设计师)的价值被提升而非降低
- 案例:AI辅助创作,但最终决策权在人
- 如何培养审美能力?(艺术欣赏、多元输入、实践创作)
**B. 共情与沟通**
- AI无法真正理解人类情感
- 医护、教育、管理、咨询等职业的"人味"不可替代
- 高情商沟通、冲突调解、心理支持
- 案例:AI心理咨询的局限性
- 如何提升共情能力?(倾听、换位思考、情绪识别)
**C. 意义构建与战略思维**
- AI能提供数据,但不能替你做价值判断
- 决策需要理解"为什么",而不仅是"怎么做"
- 战略规划、伦理判断、文化塑造
- 案例:企业战略制定,AI只能辅助分析
- 如何培养战略思维?(跨领域学习、哲学思考、长期视角)
**第四部分:AI会强化的能力(400字)**
- 学习能力(快速掌握新工具)
- 信息筛选与批判性思维(辨别AI输出质量)
- 工具使用能力(prompt engineering、AI工作流设计)
- 协同能力(人机协作,AI作为副驾驶)
- 快速迭代能力(AI加速实验和反馈)
**第五部分:具体能力提升路径(300字)**
- 初级(0-1年):掌握基础AI工具,提升学习效率
- 中级(1-3年):发展审美、沟通、批判性思维
- 高级(3-5年):建立战略思维,成为AI无法替代的决策者
- 学习资源推荐(书籍、课程、实践方法)
- 宇之然品牌如何帮助读者提升这些能力?(预告后续内容)
### 结尾(200字)
- AI不是敌人,而是工具
- 人类的优势在于"人性":审美、共情、意义构建
- 建议:拥抱AI提升效率,同时刻意训练人类特质能力
- 呼吁:不要焦虑,而是主动进化
- 互动:你在工作中感受到AI的哪些影响?欢迎评论区分享
---
## 资源清单
### 数据来源(待收集)
- [ ] WEF《未来就业报告》最新版
- [ ] 美国劳工统计局职业自动化概率表
- [ ] OpenAI/GPT能力边界研究论文
- [ ] 历史技术革命对就业影响的经济学研究
- [ ] AI能力与人类能力对比可视化数据
### 图片素材(待准备)
- [ ] AI能力范围示意图
- [ ] 自动化概率职业分布图
- [ ] 技能矩阵图(会被替代 vs 更珍贵)
- [ ] 能力提升路径时间线
### 引用来源(待标注)
- [ ] 世界经济论坛官网
- [ ] 学术期刊数据库
- [ ] 行业研究报告
- [ ] 知名专家观点
---
**决策**:这是一个必爆的热门选题,但内容必须深度且有数据支撑,不能流于表面。需要较强的信息整合能力。建议medium-high优先级执行。
-135
View File
@@ -1,135 +0,0 @@
# 从程序员到数字游民:我的三年转型之路
**领域**:工作 / 职场
**形式**:个人故事 + 实操指南
**预估字数**2600
**核心观点**:数字游民不是逃离,而是更聪明的工作生活方式选择
**受众痛点**
- 受够了996,想自由但不敢行动
- 不知道数字游民能做什么,收入从哪来
- 担心不稳定、没社保、老了怎么办
- 想远程但公司不让,不知如何说服老板
- 羡慕别人环游世界,自己却卡在工位
**独特角度**
- 不美化"边玩边赚",客观展示挑战和代价
- 从技术转型案例切入(程序员是最适合数字游民的职业之一)
- 用数据说话:收入对比、时间分配、成本核算
- 结合"宇之然"理念:科技让人自由,而非束缚
- 提供可操作的转型路线图(不是鸡汤)
**数据/案例**(至少3个来源):
1. 数字游民调研报告(人数、收入、职业分布)
2. 不同国家的签证政策和生活成本对比(数字游民签证国家)
3. 远程工作平台收入数据(Upwork、Toptal等)
4. 个人三年转型历程(时间线、收入变化、心路历程)
5. 成功/失败数字游民案例访谈
**预估完成时间**5天
**优先级**:高
**预计发布时间**2026-04-20
**状态**:待处理
---
## 选题评估矩阵
| 维度 | 评分 | 说明 |
|------|------|------|
| 受众覆盖 | 9 | 大量职场人向往自由工作,流量潜力巨大 |
| 独特性 | 8 | 避开"如何找远程工作"表层,深入转型战略 |
| 数据可得性 | 8 | 调研报告多,个人案例丰富 |
| 可持续性 | 9 | 可系列化(不同职业、不同国家、不同阶段) |
| 平台契合度 | 9 | 知乎职场/创业热门话题 |
| 品牌契合度 | 10 | 科技提升生活自由度,契合"科技沟通万物" |
| **总分** | **53** | 优先执行 ✅ |
---
## 大纲草稿
### 开头(400字)
- 场景:三年前坐在格子间,加班到深夜,问自己"这就是我想要的生活吗?"
- 转折:发现程序员完全可以远程,开始转型尝试
- 现状:现在在清迈咖啡馆工作,月收入 comparable,但生活品质完全不同
- 核心观点:数字游民不是逃避,而是更聪明的生活方式选择
### 主体(2200字)
**第一部分:数字游民的真实生活(400字)**
- 破除神话(不是天天旅游、不是躺着赚钱)
- 真实时间表:上午工作、下午探索、晚上复盘
- 收入稳定性如何保障?(多个客户、项目制)
- 孤独感和社交挑战(社群、Co-working)
- 数据:平均收入、工作小时、留存率
**第二部分:为什么程序员适合?(300字)**
- 技能可远程交付(代码在哪都能写)
- 高需求(全球IT人才短缺)
- 收入高且相对稳定
- 学习资源丰富(可自学新技能)
- 本人的转型路径(从全职到自由职业)
**第三部分:转型前的准备(500字)**
- 财务准备:6-12个月紧急基金
- 技能盘点:哪些技能可远程变现?
- 作品集建设:GitHub、个人项目、案例
- 平台选择:Upwork、Toptal、电鸭、远程工作社区
- 先从兼职开始,不要裸辞
- 法律和社保:如何自己交?国际医保?
**第四部分:我的三年路线图(400字)**
- 第1年:保存+考证+接小项目(月入5k)
- 第2年:建立客户群+提价+过渡(月入15k)
- 第3年:稳定客户+被动收入+探索(月入20k+)
- 关键节点和决策点
- 踩过的坑(低价竞争、客户跑路、签证问题)
**第五部分:在哪里生活?(300字)**
- 数字游民热门城市对比(清迈、巴厘岛、里斯本、东京)
- 成本核算(住宿、交通、签证、保险)
- 网络和基础设施(稳定WiFi、Coworking
- 社区和社交(容易找到同类人)
- 安全和生活便利性
**第六部分:给想转型者的建议(300字)**
- 先试水:请假去远程工作一个月
- 不要孤注一掷:保持至少一个稳定收入源
- 建立系统:不只是接单,而是建立个人品牌
- 心理准备:自由带来责任,自律才能自由
- "宇之然"理念:科技让人自由,但自由需要能力支撑
### 结尾(200字)
- 数字游民不是适合所有人,但值得尝试
- 关键是找到适合自己的工作生活方式
- 鼓励读者思考:我想要什么样的生活?科技能帮我实现吗?
- 预告:后续分享具体技能提升路线(程序员转远程)
---
## 资源清单
### 数据来源(待收集)
- [ ] 数字游民数量增长数据( Nomad List 、相关报告)
- [ ] 程序员远程工作薪资调研
- [ ] 各国数字游民签证政策汇总
- [ ] Coworking 空间成本统计
- [ ] IT自由职业平台收入报告
### 图片素材(待准备)
- [ ] 三年转型时间线图
- [ ] 不同城市成本对比图表
- [ ] 收入变化曲线
- [ ] 世界各地工作地点照片(清迈咖啡馆等)
- [ ] Coworking 空间环境图
### 引用来源(待标注)
- [ ] Nomad List 官网数据
- [ ] 数字游民社区统计
- [ ] 各国签证政策官网
- [ ] 远程工作平台文档
---
**决策**:这是一个高流量选题,竞争也激烈,需要深度个人故事+系统化建议才能脱颖而出。建议 medium-high 优先级。
@@ -1,143 +0,0 @@
# 零浪费生活一年:一个家庭产生的垃圾去哪儿了?
**领域**:自然 / 生活
**形式**:实验记录 + 科普指南
**预估字数**2300
**核心观点**:零浪费不是苦行,而是更聪明的消费选择;个人行动虽小,但能改变系统
**受众痛点**
- 想环保但不知道从何下手
- 觉得"我一个人做有什么用"
- 担心成本太高,负担不起
- 嫌麻烦,步骤太多坚持不下去
- 家人不理解,无法统一战线
- 超市买买买停不下来,事后又后悔
**独特角度**
- 不道德绑架,用数据和成本说服
- 展示失败和妥协(不是完美零浪费,而是持续改进)
- 从家庭视角(夫妻+孩子)而非个人
- 连接科技:用App记录、智能采购、循环经济平台
- 强调经济收益(省了多少钱)而非道德优越
**数据/案例**(至少3个来源):
1. 中国城市生活垃圾产生量数据(统计年鉴)
2. 不同包装方式的碳足迹对比(生产、运输、处理)
3. 零浪费家庭采访或书籍(如Bea Johnson, 0 Waste Home
4. 自己一年的垃圾记录(称重、分类、分析)
5. 环保产品性价比对比(可重复使用 vs 一次性)
**预估完成时间**4天
**优先级**:高
**预计发布时间**2026-04-22
**状态**:待处理
---
## 选题评估矩阵
| 维度 | 评分 | 说明 |
|------|------|------|
| 受众覆盖 | 8 | 环保意识提升,但执行力不足的人多 |
| 独特性 | 9 | 家庭实验视角,真实数据,不教条 |
| 数据可得性 | 8 | 垃圾数据、环保报告、产品对比可获取 |
| 可持续性 | 8 | 可系列(厨余、包装、衣物、电子产品等) |
| 平台契合度 | 8 | 知乎生活/环保话题,小红书也适合 |
| 品牌契合度 | 10 | 自然+科技+生活,完美契合价值观 |
| **总分** | **51** | 优先执行 ✅ |
---
## 大纲草稿
### 开头(300字)
- 场景:2025年1月1日,我在家门口放了一个垃圾桶,记录一整年的垃圾
- 问题:一个家庭一年会产生多少垃圾?它们最后去哪了?
- 引子:零浪费不是不吃不喝,而是 smarter consumption
- 预告:分享一年实验数据、踩坑经验、经济收益
### 主体(1800字)
**第一部分:我们这一年扔了啥?(300字)**
- 垃圾总量:XX公斤(对比全国人均)
- 分类数据:塑料、包装、厨余、其他
- 月度趋势(节假日更多,夏季更多)
- 最大来源:外卖包装、快递箱、食品包装
- 可视化:饼图+月度折线图
**第二部分:我们是怎么做到的?(400字)**
- 原则5R:Refuse(拒绝不需要的)、Reduce(减少)、Reuse(重复使用)、Recycle(回收)、Rot(堆肥)
- 购物习惯改变:
- 带袋子买菜(拒绝塑料袋)
- 散装优先(减少包装)
- 耐用品替代一次性(硅胶保鲜膜、可重复使用的咖啡杯)
- 二手优先(家具、电子产品、衣物)
- 厨余处理:堆肥桶+社区堆肥点
- 家庭共识:夫妻+孩子的参与,不是一个人负重前行
- 妥协:不可能100%,目标是逐年降低
**第三部分:科技让零浪费变简单(300字)**
- 零浪费购物App(包, 乐活等)
- 智能库存管理(避免买多导致浪费)
- 社区交换平台(闲鱼、小区群)
- 可降解产品追踪(哪些真的环保?)
- 碳足迹计算器(量化自己的贡献)
**第四部分:经济账(200字)**
- 初始投入:玻璃罐、棉布袋、不锈钢饭盒(XXX元)
- 每月节省:减少外卖/包装(XXX元)、二手购物(XXX元)
- 一年净节省:XXXX元(ROI 200%+
- 隐性收益:更健康饮食(少点外卖),更理性消费
- 环保不是富人游戏,穷人更应该
**第五部分:挑战与妥协(300字)**
- 家人不配合:老人舍不得扔旧物,孩子要零食包装
- 社交压力:聚会自带杯子被嘲笑
- 便利性:有时候真的没时间准备
- 产品缺失:市场上零浪费选择太少
- 我们没有做到的地方:电子产品循环难、医疗包装无法避免
- 心态调整:进步不是完美,可持续才是关键
**第六部分:我们的建议(300字)**
- 从最容易的3件事开始:带袋子、少点外卖、二手优先
- 设定合理目标(比如年度垃圾减量20%)
- 记录数据(否则不知道进步)
- 找到社区(一个人走不远)
- 关注政策(垃圾分类、再生资源回收)
- 科技赋能(用工具降低门槛)
- "宇之然"理念:零浪费不是回到原始,而是科技赋能的智能生活
### 结尾(200字)
- 一年垃圾量:XXX公斤(对比第一年减少XX%)
- 零浪费不是苦行,是更高质量的生活
- 每一个小行动都在影响系统
- 呼吁:不要追求完美,追求持续改进
- 互动:你的零浪费实践是什么?欢迎分享
---
## 资源清单
### 数据来源(待收集)
- [ ] 中国城市生活垃圾产生量年度数据(国家统计局)
- [ ] 各类包装碳足迹数据(学术论文)
- [ ] 零浪费家庭案例(国内外博客、书籍)
- [ ] 零浪费产品成本与一次性对比
- [ ] 社区堆肥项目案例
### 图片素材(待准备)
- [ ] 一年垃圾记录照片(分类展示)
- [ ] 零浪费购物装备(布袋、罐子、饭盒)
- [ ] 堆肥桶和成果
- [ ] 数据图表(垃圾量趋势、分类占比、经济收益)
- [ ] 前后对比(购物方式、垃圾桶状态)
### 引用来源(待标注)
- [ ] 零浪费运动创始人Bea Johnson
- [ ] 《零浪费生活》等书籍
- [ ] 环保组织报告(如WWF、Greenpeace
- [ ] 国内零 waste community
---
**决策**:实验性质内容,容易引发共鸣和讨论,互动率高。适合知乎和小红书。建议high优先级。
-166
View File
@@ -1,166 +0,0 @@
# 深度工作实践:如何在干扰世界中保持专注
**领域**:工作 / 生产力
**形式**:实操指南 + 个人实验
**预估字数**2400
**核心观点**:专注力是新时代最稀缺的资源,通过系统方法可以重建深度工作能力
**受众痛点**
- 每天忙碌但没产出,时间碎片化
- 容易被手机、消息、同事打断
- 知道要专注,但就是控制不住刷手机
- 工作1小时,实际只有30分钟在干活
- 想要心流状态但总进不去
- 下班累但没成就感
**独特角度**
- 不鸡汤,用实验数据和自我追踪说话
- 结合科技工具(Forest、番茄钟、白噪音)和传统方法
- 承认现代工作环境的现实(完全隔离不现实),提供折中方案
- 从神经科学和心理学角度解释why,不只是how
- 强调"深度休息"与"深度工作"的交替
**数据/案例**(至少3个来源):
1. Cal Newport《深度工作》理论体系
2. 注意力恢复理论(Attention Restoration Theory
3. 番茄工作法实证研究(效果数据)
4. 个人3个月实验数据(专注时间、任务完成量、压力水平)
5. 知识工作者专注力调研( interruptions cost
**预估完成时间**4天
**优先级**:高
**预计发布时间**2026-04-23
**状态**:待处理
---
## 选题评估矩阵
| 维度 | 评分 | 说明 |
|------|------|------|
| 受众覆盖 | 9 | 所有知识工作者都需要,流量潜力极大 |
| 独特性 | 7 | 话题热门,需要用数据和实验脱颖而出 |
| 数据可得性 | 9 | 大量研究文献和工具可用 |
| 可持续性 | 8 | 可系列(不同环境、不同工具、不同性格) |
| 平台契合度 | 9 | 知乎职场/效率热门,小红书打卡也适合 |
| 品牌契合度 | 8 | 科技辅助专注,但最终回归人的本质 |
| **总分** | **50** | 优先执行 ✅ |
---
## 大纲草稿
### 开头(300字)
- 场景:上周写一份报告,计划4小时,实际花了8小时,中间刷了20次手机
- 问题:为什么我们越来越忙,产出却越来越少?
- 观点:不是时间不够,是注意力被碎片化
- 预告:分享3个月深度工作实验,数据+方法+工具
### 主体(1900字)
**第一部分:专注力危机(300字)**
- 数据:平均专注时长从26分钟降到8分钟(Microsoft研究)
- 知识工作者每天被中断多少次?(59次/天,平均)
- 切换成本:每次中断后需要23分钟回到深度状态
- 现代工作环境:开放式办公室、即时通讯、通知轰炸
- 后果:疲惫、低效、创造力下降
**第二部分:什么是深度工作?(200字)**
- Cal Newport定义:无干扰的认知挑战性工作
- 与肤浅工作的对比(容易回复的邮件、会议、行政事务)
- 为什么深度工作有价值?(高价值产出、技能增长、成就感)
- 神经科学解释:默认模式网络 vs 专注模式
- 个人实验目标:将每日深度工作时间从1h提升到4h
**第三部分:我的3个月实验设计(200字)**
- 基线测量:第一周不干预,记录专注情况(RescueTime数据)
- 变量引入:每周测试一种方法(时间块、地点、工具)
- 评估指标:深度工作时长、任务完成量、主观疲劳度
- 数据收集:自动追踪+每日日志
- 工具:Forest、番茄钟、白噪音、时间追踪App
**第四部分:7个有效方法(800字)**
1. **时间块法**:每天固定2-3个90分钟深度时段(早上最佳)
- 如何保护这些时段?(关闭通知、告知同事)
- 案例:我如何说服老板让我上午不参加会议
2. **地点隔离**:物理空间决定心理状态
- 家里打造深度工作角(哪怕只有一张桌子)
- 共享办公/图书馆vs咖啡馆(哪个更好?)
- 通勤时间利用(地铁上不适合深度,但可做浅层)
3. **工具辅助**:科技帮你专注,而不是分心
- Forest种树:游戏化保持专注
- Cold Turkey Blocker:屏蔽 distracting sites
- 白噪音/自然声:掩盖环境噪音
- 双显示器设置(主屏工作,副屏消息)
4. **仪式感建立**:让大脑进入"工作模式"
- 开始前:一杯茶+5分钟冥想+清单
- 结束时:总结+小奖励
- 服装:穿"工作装"即使在家
5. **批处理浅层工作**:集中处理邮件、消息、会议
- 每天2个固定时段(下午3点、5点)
- 其他时间绝不查看
- 快速回复模板
6. **注意力训练**:像肌肉一样训练专注
- 每天10分钟正念冥想(Headspace
- 单任务练习(吃饭不刷手机)
- 阅读长文章(训练持续注意力)
7. **深度休息**:专注需要高质量的休息
- 90分钟工作+15分钟休息(非屏幕活动)
- 午休必须离开工位
- 晚上完全断开(数字安息日)
- 睡眠优先(专注力的基础)
**第五部分:实验结果与数据(300字)**
- 深度工作时长变化:基线1.2h/天 → 实验后3.8h/天
- 任务完成量提升:每周完成项目数从2个→5个
- 主观疲劳度下降:从每天7分(10分制)降到4分
- 最有用的方法:时间块法(增加1.5h)+ 工具辅助(增加0.8h)
- 意外发现:地点隔离效果不明显(家里角落即可)
**第六部分:常见障碍与解决方案(200字)**
- 同事/老板随时找你怎么办?(设置"专注时段"通知)
- 自己忍不住刷手机怎么办?(物理隔离手机)
- 老板要求即时回复怎么办?(协商沟通规则)
- 创意型工作无法计划怎么办?(灵感记录+深度时间块)
- 适应期烦躁怎么办?(从1小时开始,逐步增加)
### 结尾(200字)
- 深度工作不是天赋,是可以训练的技能
- 关键不是完美,而是持续改进
- 科技让我们更容易分心,但也给了我们工具对抗
- "宇之然"理念:专注才能产生深度价值
- 挑战:从明天开始,尝试一个90分钟的时间块
---
## 资源清单
### 数据来源(待收集)
- [ ] Microsoft 注意力跨度研究报告
- [ ] RescueTime 知识工作者专注数据
- [ ] 番茄工作法效果 meta-analysis
- [ ] 神经科学关于注意力切换的研究
- [ ] 正念冥想对专注力的影响
### 图片素材(待准备)
- [ ] 深度工作时长趋势图(实验前后对比)
- [ ] 7种方法示意图
- [ ] 时间块安排示例(日历截图)
- [ ] 专注工具界面截图(Forest、白噪音)
- [ ] 实验数据表格
### 引用来源(待标注)
- [ ] Cal Newport《深度工作》
- [ ] 《倦怠社会》等社会学视角
- [ ] 心理学研究(注意力、心流)
- [ ] 工具官网和教程
---
**决策**:非常实用的主题,数据驱动,易引发收藏和转发。适合知乎收藏夹和小红书打卡。建议 high 优先级。
-183
View File
@@ -1,183 +0,0 @@
# 副业月入过万:我一个程序员的三年探索之路
**领域**:工作 / 副业
**形式**:实操经验 + 方法论总结
**预估字数**2700
**核心观点**:副业不是投机,而是将主业技能产品化、多元化的过程
**受众痛点**
- 工资不够花,想搞钱但不知道从哪开始
- 听说过很多副业(自媒体、电商、咨询),但不知哪个适合
- 时间有限,如何在主业之外有效投入
- 担心副业影响主业,被公司发现
- 交过学费买课,但没赚到钱
- 想开始但总在观望,不敢行动
**独特角度**
- 从技术人视角(程序员)看副业选项,但方法论通用
- 不鼓吹"月入十万"的毒鸡汤,诚实展示时间和金钱投入
- 强调"技能产品化"而非"时间换钱"(避免陷入低效劳务)
- 用数据说话:我的三年副业收入变化、时间分配、失败案例
- 结合长期主义:副业是为了人生更多选择,不仅是赚钱
**数据/案例**(至少3个来源):
1. 中国职场人副业调研报告(参与率、收入分布)
2. 程序员技能变现渠道对比(外包、咨询、产品、内容)
3. 时间投入与回报曲线(前期低效,后期复利)
4. 个人三年副业数据(2019-2021):时间投入vs收入产出
5. 成功/失败副业案例分析(为什么有些成了有些黄了)
**预估完成时间**5天
**优先级**:高
**预计发布时间**2026-04-25
**状态**:待处理
---
## 选题评估矩阵
| 维度 | 评分 | 说明 |
|------|------|------|
| 受众覆盖 | 9 | 大量职场人有副业需求,搜索和阅读量巨大 |
| 独特性 | 7 | 副业话题热,需要真实数据和深度分析才能出彩 |
| 数据可得性 | 9 | 调研报告多,个人案例可详细追踪 |
| 可持续性 | 9 | 可系列(不同阶段、不同技能、不同平台) |
| 平台契合度 | 9 | 知乎职场/赚钱热门,小红书副业也火 |
| 品牌契合度 | 9 | 科技赋能多元收入,增加人生选择权 |
| **总分** | **52** | 优先执行 ✅ |
---
## 大纲草稿
### 开头(400字)
- 场景:2019年,我还是一枚996程序员,每月税后1.2万,觉得不够用
- 尝试:接过外包、做过咨询、写过公众号、卖过课程、尝试过跨境电商
- 现状:现在副业收入已超过主业,时间自由,有选择权
- 核心观点:副业不是一夜暴富,而是技能产品化和持续积累的过程
- 预告:分享三年探索的数据、踩坑、方法论
### 主体(2200字)
**第一部分:副业真相(破除幻想)(300字)**
- 不是所有副业都赚钱:80%的人副业收入<2000元
- 不是 Easily Money:前期投入巨大(时间、学习、试错)
- 不是可持续的劳务:用时间换钱必然后劲不足
- 数据:我的前18个月副业收入总计才8000元
- 真相:副业是"第二曲线"需要长期培育
**第二部分:副业类型全景图(300字)**
- **技能变现型**:外包、咨询、培训(适合技术人)
- 平台:Upwork、电鸭、知乎 Live、自有客户
- 特点:时间换钱,单价高但线性增长
- **产品型**:开发工具、课程、模板、SaaS
- 前期投入大,后期复利
- 例子:我做的 Chrome 插件年收入X万
- **内容型**:公众号、知乎、B站、小红书
- 长周期变现,但品牌效应强
- 例子:我的技术博客如何带来咨询客户
- **电商/贸易型**:跨境电商、二手、定制
- 资金和库存压力大,技术人不擅长
- 我失败的案例:淘宝店
- **投资型**:股票、基金、加密货币(不推荐作为主业外重点)
- **混合型**:我的组合:技能变现+产品+内容
**第三部分:程序员适合什么副业?(300字)**
- 优势:技术可远程交付、技能稀缺、学习能力强
- 最适合:
1. 技术外包/咨询(起步最快,但天花板低)
2. 开发小工具/SaaS(复利高,但需要产品思维)
3. 技术内容创作(博客、课程、咨询)
4. 技术团队组建(成为自由职业团队leader)
- 不适合:
1. 需要大量资金的(电商库存)
2. 纯体力或线下服务的
3. 需要法律资质的(金融咨询)
**第四部分:我的三年路线图(400字)**
- **第1年(2019**:探索+试错
- 目标:尝试3种副业,找到1-2个可行的
- 行动:接外包(赚了1.5万)、写博客(0收入)、尝试跨境电商(亏损2k)
- 学习:时间管理、客户沟通、基础营销
- 结果:发现外包可行但累,内容有潜力但慢
- 时间投入:每周10-15小时
- **第2年(2020**:聚焦+优化
- 目标:在技术外包+内容创作双线推进,月入稳定5000
- 行动:提高外包单价(从100$/h到150$/h),博客系统性写作
- 学习:个人品牌、定价策略、产品化
- 结果:外包月均3000,博客带来1个咨询项目(5000)
- 时间投入:每周15小时(主业压力大)
- **第3年(2021)**:产品化+规模化
- 目标:将知识产品化,打造"第二曲线"
- 行动:开发Chrome插件(年收入2万),出版电子书(1.5万),高单价咨询
- 学习:产品运营、用户增长、自动化
- 结果:副业月均1.2万,首次超过主业
- 时间投入:每周20小时(但其中50%是产品维护)
**第五部分:时间管理:主业+副业如何平衡?(200字)**
- 原则1:主业优先,不能因副业影响主业绩效(可能被开除)
- 原则2:副业时间固定(早上6-8点、晚上8-10点、周末4小时)
- 原则3:批量处理(每周日规划,减少切换成本)
- 原则4:学会说"不"(拒绝低价值副业请求)
- 我的时间分配:周总副业时间15h(低于20h安全线)
**第六部分:技能产品化:从时间换钱到复利增长(300字)**
- 外包(时间换钱):1h=150元,但做才有
- 产品(一次创造,多次销售):开发一个工具,持续销售
- 内容(建立品牌,带来被动机会):博客带来咨询,不需主动找
- 我的产品:Chrome插件(每月销售,收入稳定)
- 如何选择产品方向?(你解决自己的问题,可能也是别人的问题)
- 最小可行产品(MVP)快速验证
**第七部分:避坑指南(200字)**
- 坑1:低价竞争(不要接低于市场价的活,会拉低你的价值)
- 坑2:完美主义(先做出来,再优化;不要等完美才发布)
- 坑3:孤军奋战(找导师、加入社群、互相支持)
- 坑4:忽略法律(兼职合同、知识产权、个税)
- 坑5:忽视健康(连续熬夜接单,不可持续)
- 坑6:过度承诺(能力范围内再接,否则口碑崩塌)
**第八部分:给初学者的行动清单(200字)**
1. 盘点你的技能:什么可远程交付?什么可产品化?
2. 选择1-2个方向(不要贪多)
3. 用3个月探索:每方向投入100小时试水
4. 记录数据:时间投入、收入、满意度
5. 6个月后评估:哪个ROI最高?哪个最有潜力?
6. 聚焦+优化:放弃低ROI的,加注高潜力的
7. 建立系统:不是每次从零开始,而是有流程
8. 定期复盘(每月一次)
### 结尾(200字)
- 副业不只是赚钱,更是探索人生更多可能
- 我的现状:主业稳定,副业自由,有选择权
- "宇之然"理念:科技给人自由,副业是实现自由的一种路径
- 鼓励:从今晚开始,花1小时盘点你的技能
- 互动:你的副业探索经历如何?欢迎分享
---
## 资源清单
### 数据来源(待收集)
- [ ] 中国职场人副业现状调研(智联、脉脉等)
- [ ] 程序员收入与副业相关性数据
- [ ] 自由职业平台(Upwork、电鸭)收入报告
- [ ] 数字游民与副业的关系研究
- [ ] 时间投入与收入曲线(复利效应数据)
### 图片素材(待准备)
- [ ] 三年副业收入增长曲线
- [ ] 时间分配饼图(每天/每周)
- [ ] 副业类型对比矩阵(时间vs金钱vs长期价值)
- [ ] 技能产品化流程图
- [ ] 避坑指南信息图
### 引用来源(待标注)
- [ ] 《副业赚钱》等书籍
- [ ] 知名副业博主案例
- [ ] Upwork/Toptal 平台报告
- [ ] 个人博客和项目数据
---
**决策**:刚需话题,竞争激烈但需求巨大。真实数据和实操经验是关键。适合知乎和小红书。建议 high 优先级。
@@ -1,180 +0,0 @@
# 正念冥想一年:从焦虑到平静的转变
**领域**:人文 / 心理健康
**形式**:个人实验 + 科学解读
**预估字数**2200
**核心观点**:冥想不是玄学,是可训练的大脑肌肉;一年练习带来可测量的认知和情绪变化
**受众痛点**
- 焦虑、失眠、注意力不集中
- 想尝试冥想但觉得"太虚"、"静不下来"
- 工作压力大,找不到放松方法
- 情绪容易波动,想提升情绪调节能力
- 听说过冥想好处,但不知如何开始
- 试过几次没效果就放弃了
**独特角度**
- 用科学家态度做自我实验(追踪数据、前后对比)
- 破除玄学色彩,基于神经科学和心理学
- 展示失败和挣扎(不是一蹴而就)
- 结合科技:Meditation App、生物反馈设备
- 强调"微小习惯":每天10分钟胜过每周2小时
**数据/案例**(至少3个来源):
1. 冥想改变大脑结构的研究(灰质增加、杏仁核缩小)
2. 压力激素(皮质醇)水平变化数据
3. 注意力、情绪调节能力的心理测量
4. 个人一年追踪:每天10分钟,睡眠、焦虑评分、专注力自评
5. 其他冥想者案例(长期练习者)
**预估完成时间**4天
**优先级**:中
**预计发布时间**2026-04-27
**状态**:待处理
---
## 选题评估矩阵
| 维度 | 评分 | 说明 |
|------|------|------|
| 受众覆盖 | 8 | 压力大的都市人广泛需要,但转化率不确定 |
| 独特性 | 8 | 个人实验+数据追踪,破除玄学 |
| 数据可得性 | 8 | 神经科学研究多,自我追踪简单 |
| 可持续性 | 7 | 可系列(不同时长、不同技术、不同人群) |
| 平台契合度 | 8 | 知乎心理学/健康,小红书打卡风 |
| 品牌契合度 | 9 | 回归本心,科技辅助内心平静 |
| **总分** | **48** | 考虑执行 ✅ |
---
## 大纲草稿
### 开头(300字)
- 场景:2024年初,我焦虑到失眠,朋友建议"试试冥想"
- 抵触:觉得是玄学,静不下来,10分钟像几个小时
- 决定:用科学家态度做个实验,每天10分钟,追踪一年
- 结果:焦虑评分下降40%,睡眠质量提升,专注力改善
- 预告:分享这一年我的数据、方法、挣扎和收获
### 主体(1700字)
**第一部分:冥想是什么?(破除迷思)(200字)**
- 不是宗教,不是玄学,是注意力训练
- 不是停止思考,是观察思绪而不被带走
- 不是马上变平静,是练习"觉知"
- 科学解释:默认模式网络、前额叶皮层、神经可塑性
- 我的初始怀疑:一个程序员如何相信这个?
**第二部分:为什么现代人更需要冥想?(200字)**
- 信息过载:每天被数千条信息轰炸
- 多任务假象:切换导致注意力碎片化
- 压力激素持续分泌(皮质醇)
- 社交媒体比较和FOMO
- 缺乏"无所事事"的时间
- 后果:焦虑、失眠、注意力涣散、情绪不稳定
**第三部分:我的实验设计(200字)**
- 目标:一年后减少焦虑、改善睡眠、提升专注
- 方法:每天10分钟冥想(App指导:Headspace + Calm
- 追踪指标:
- 主观:焦虑评分(1-10)、睡眠质量(1-5)、专注时长
- 客观:皮质醇(唾液测试,每月1次)、心率变异性(HRV)
- 工具:Muse头环(脑电生物反馈)、Apple Watch睡眠追踪
- 记录:每日简记,每周复盘
**第四部分:前3个月的挣扎(200字)**
- 第1周:完全静不下来,中途放弃多次
- 第1月:平均每次5分钟就开始看时间
- 第2月:开始有一点点"空白时刻"
- 第3月:发现思绪模式(焦虑的思绪、工作的思绪)
- 关键:坚持每天做,不追求效果
- 工具帮助:App的引导声音让我stay
**第五部分:6个月时的变化(200字)**
- 主观感受:更容易进入状态(5分钟就能平静)
- 睡眠:入睡更快,夜间醒来减少(数据:平均入睡时间从30min→15min)
- 焦虑:明显降低(评分从7→4
- 专注:工作中更容易"心流"
- 意外:对情绪觉察力提升(能 early detect stress
- 生物反馈:HRV提升(从50ms→70ms
**第六部分:一年后的数据(200字)**
- 坚持率:85%365天,310天完成10min+
- 焦虑评分:从7.2降至4.1(下降43%)
- 睡眠质量:从2.8升至4.1(1-5分制)
- 专注时间:基线1.2h/天 → 2.5h/天( meas by RescueTime
- 皮质醇:早晨水平下降20%
- 大脑变化:Muse数据显示α波(放松)增加,β波(焦虑)减少
- ROI:每天10分钟,换来心理和生理健康提升,值吗?(一个数量级的健康价值)
**第七部分:关键技术/方法(300字)**
1. **呼吸冥想**:专注呼吸,是最基础也最有效的
- 方法:鼻吸鼻呼,数呼吸(1-10循环)
- 最佳时段:早晨起床后或晚上睡前
- 困难:思绪飘走正常,温柔拉回即可
2. **身体扫描**:释放身体紧张
- 方法:从脚到头,逐个部位觉察
- 适合:压力大时,身体紧绷
- 效果:发现很多平日忽略的肌肉紧张
3. **正念行走**:把步行变成冥想
- 方法:走路时觉察脚步、身体移动、呼吸
- 适合:久坐办公室,通勤路上
- 我:午休15分钟步行冥想,下午效率高
4. **3分钟呼吸空间**:快速冷静
- 方法:1分钟觉察,1分钟专注呼吸,1分钟觉察整体
- 适合:会议前、压力事件前
- 使用频率:平均每天2-3次
5. **科技辅助**
- Headspace/Calm:引导冥想(新手强烈推荐)
- Insight Timer:免费课程和统计
- Muse头环:生物反馈,可视化大脑状态
- Apple Watch:呼吸App,随时做1分钟
**第八部分:常见问题与解答(200字)**
- Q:静不下来怎么办?(接受它,坚持做,改变需要时间)
- Q:每天多久合适?(10分钟起步,30分钟最佳)
- Q:什么时间做最好?(早晨或睡前最易坚持)
- Q:必须坐垫子吗?(任何姿势,关键是舒适且清醒)
- Q:多久见效?(2-4周有初步感受,1年明显变化)
- Q:要加入宗教吗?(完全不需要, secular mindfulness
- Q:影响创造力吗?(反而提升,因为减少心理噪音)
### 结尾(200字)
- 冥想一年,是我给自己最好的投资之一
- 不是变成"无欲无求",而是更清晰、更平静、更有选择权
- "宇之然"理念:科技沟通万物,最终回归内心本真
- 鼓励:从今晚5分钟开始,用数据追踪自己的变化
- 互动:你有冥想经验吗?分享你的故事
---
## 资源清单
### 数据来源(待收集)
- [ ] 冥想改变大脑结构研究(哈佛、斯坦福等)
- [ ] 压力激素皮质醇与冥想关系研究
- [ ] 注意力、情绪调节能力测量工具(PANAS等)
- [ ] 心率变异性(HRV)与冥想数据
- [ ] 冥想对睡眠影响 meta-analysis
### 图片素材(待准备)
- [ ] 一年冥想坚持日历(打卡图)
- [ ] 追踪数据图表(焦虑、睡眠、专注趋势)
- [ ] 大脑结构变化示意图(灰质、杏仁核)
- [ ] HRV和脑电数据截图(如果使用设备)
- [ ] 冥想姿势和环境照片
### 引用来源(待标注)
- [ ] Headspace/Calm 科学页面
- [ ] 冥想研究综述(如《心理学前沿》)
- [ ] 《正念的奇迹》《禅与摩托车维修艺术》等书籍
- [ ] 神经科学教材
---
**决策**:心理健康内容需求大,但竞争也激烈。个人实验+数据追踪+科学解释是差异点。适合知乎和小红书。建议 medium 优先级。
-182
View File
@@ -1,182 +0,0 @@
# 极简3年:我从囤积症到少物生活的转变
**领域**:人文 / 生活方式
**形式**:个人转变故事 + 实操指南
**预估字数**2500
**核心观点**:极简不是扔东西,而是重新定义"足够";通过减少物质,增加精神丰盈
**受众痛点**
- 家里东西越来越多,整理完很快又乱
- 冲动购物,买了很多用不上的东西
- 感觉被物品包围,想要斷舍离但下不去手
- 想简化生活但不知从何开始
- 担心扔了后悔,觉得"万一以后用得上"
- 追求品质但预算有限,陷入"买 cheap stuff 然后浪费"
**独特角度**
- 从囤积症患者到极简主义者的真实转变(有心理过程)
- 不鼓吹"一无所有",而是"刚刚好"
- 量化成果:减少了70%物品,省了多少钱,时间如何变化
- 连接科技:智能家居、数字替代(电子书、云存储)、物品追踪
- 从物质极简到精神极简(信息、社交、目标)
**数据/案例**(至少3个来源):
1. 极简主义创始人(Joshua & Ryan)理念和实践
2. 物品生命周期研究(平均使用次数、浪费数据)
3. 消费心理学(冲动购物的神经机制)
4. 个人3年极简数据:物品数量变化、消费减少、时间分配
5. 多人案例采访(不同极简程度)
**预估完成时间**4天
**优先级**:中
**预计发布时间**2026-04-29
**状态**:待处理
---
## 选题评估矩阵
| 维度 | 评分 | 说明 |
|------|------|------|
| 受众覆盖 | 8 | 物质过剩的都市人有共鸣,但行动者少 |
| 独特性 | 8 | 转变故事有吸引力,数据驱动 |
| 数据可得性 | 8 | 个人追踪数据+消费研究+极简社区案例 |
| 可持续性 | 8 | 可系列(不同房间、不同人群、不同阶段) |
| 平台契合度 | 8 | 知乎生活方式/小红书极简话题 |
| 品牌契合度 | 10 | 回归自然本心,少物多思 |
| **总分** | **50** | 优先执行 ✅ |
---
## 大纲草稿
### 开头(300字)
- 场景:2019年,我搬进新家,发现60%的物品两年没用过
- 触目惊心:衣柜塞满、抽屉爆炸、储物柜 hidden junk
- 决定:开始极简之路,目标是"每件东西都有用且愉悦"
- 3年变化:物品减少70%,消费减半,时间多出,焦虑下降
- 预告:分享转变过程、方法、数据和教训
### 主体(2000字)
**第一部分:从囤积到觉醒(300字)**
- 我的囤积症:舍不得扔,总觉得"会用到"
- 触发点:搬家发现大量未拆封的购物袋、过期的优惠券
- 消费主义陷阱:打折、社交媒体种草、身份焦虑
- 觉醒:物品在消耗我的注意力、空间、金钱
- 开始:先从小区域(一个抽屉)动手
**第二部分:极简不是数字,是心态(300字)**
- 误区:极简=苦行= empty room
- 真相:极简是"足够"哲学,留下真正重要和愉悦的
- 我的标准:每件物品是否在用?是否带来愉悦?是否可替代?
- 过程不是一次断舍离,而是持续优化
- 3年我扔了/捐了/卖了 1000+ 件物品
- 不是目标,是手段(为了时间、精力、金钱自由)
**第三部分:我的3年路线图(400字)**
- 第1年(2019):粗筛+快速清理
- 方法:一年未用的全扔(除了纪念品)
- 成果:物品减少40%,清空3个储物箱
- 挑战:扔东西的心痛感(浪费钱的心理)
- 第2年(2020):精细化+系统化
- 方法:One In, One Out(进一出一),严格购买决策流程
- 成果:物品再减少20%,消费减少35%
- 学习:识别真实需求 vs 虚假欲望
- 建立"30天清单":想买的东西放30天,90%会取消
- 第3年(2021):深化+扩展
- 方法:数字极简、信息极简、社交极简
- 成果:物品再减少10%,精神更清爽
- 维持:定期季度审查,防止反弹
- 极简成为习惯,不再需要"努力"
**第四部分:具体方法(500字)**
1. **分类清理法**
- 从易到难:抽屉→衣柜→书柜→储物间
- 4箱法:扔、捐、卖、留(保留)
- 纪念品处理:选一个盒子(大小限制),其他拍照留底
2. **购买决策流程**
- 问自己:我需要它吗?我有替代品吗?它带来长期愉悦吗?
- 30天等待期(除非是消耗品)
- 控制冲动:取消促销订阅、不逛购物App
- 质量优先:买少买好,耐用性优先
- 案例:少买了100件便宜T恤,买了5件优质耐穿的
3. **数字极简**
- 卸载不用的App,取消不看的订阅
- 照片整理:删除模糊、重复的,精选打印
- 文件存档:云存储+本地双备份,删临时文件
- 通知管理:只留必要的,减少干扰
4. **信息极简**
- RSS订阅精选(从200+减到20个高质量源)
- 社交媒体定时关闭(每天30min
- 不追热点,只深度阅读
- 信息输入输出平衡(少摄入,多创作)
5. **社交极简**
- 减少无效社交,保留高质量关系
- 会议只参加必要的,其他异步沟通
- 学会拒绝:时间是最稀缺资源
**第五部分:量化成果(200字)**
- 物品数量:从约1500件 → 450件(减少70%
- 消费:年均减少 40%(省下约3万/年)
- 时间:每周少花5小时整理、购物、找东西
- 空间:清空3个储物柜,家里更宽敞
- 心理:焦虑下降(从6→3分),决策更快(因为选择少)
- 环保:减少碳足迹(估算:每年少产生200kg垃圾)
**第六部分:挑战与妥协(200字)**
- 家人不理解:老婆/父母不配合,只能整理自己的部分
- 社会压力:节日送礼、人情往来难简化
- 实用性:有些"可能需要"的东西还是留了(工具、应急)
- 不是完美:还有10%的物品是"maybe future use"
- 转折点:当体验到"清爽"后,家人慢慢受影响
**第七部分:给初学者的建议(200字)**
- 从小开始:先整理一个抽屉或一个角落
- 不要一次扔太多:给缓刑期,减少心理阻力
- 拍照留念:纪念品不扔,但数字化
- 寻找社群:极简社区、Minimalism subreddit
- 接受不完美:目标是"足够好",不是空无一物
- 聚焦价值:极简是为了释放资源(时间、金钱、精力)做更重要的事
- "宇之然"理念:少物多思,回归内心真实需求
### 结尾(200字)
- 极简3年,生活更轻盈,更有方向
- 不是物质越多越幸福,而是"足够"才幸福
- 极简让我有更多资源去追求:深度阅读、健康生活、家人陪伴
- 呼吁:从今天开始,清理一个角落,体验清爽的感觉
- 互动:你的极简实践是什么?有什么困惑?
---
## 资源清单
### 数据来源(待收集)
- [ ] 极简主义书籍(Goodreads、豆瓣)
- [ ] 消费心理学研究(过度消费、囤积症)
- [ ] 物品生命周期和浪费数据(环保组织)
- [ ] 时间追踪数据(整理、购物时间)
- [ ] 极简对幸福感影响研究
### 图片素材(待准备)
- [ ] 整理前后对比图(同一区域)
- [ ] 物品数量变化图表
- [ ] 消费金额变化曲线
- [ ] 空间对比图(清空的储物柜)
- [ ] 极简生活场景(清爽的房间、精选的物品)
### 引用来源(待标注)
- [ ] Joshua Fields Millburn & Ryan Nicodemus
- [ ] 《极简主义》《断舍离》等书籍
- [ ] The Minimalists Podcast
- [ ] 消费主义批判文献
---
**决策**:生活方式的个人转变故事容易引发共鸣,适合叙事+方法论。小红书和知乎都合适。建议 medium 优先级。
-176
View File
@@ -1,176 +0,0 @@
# 城市观鸟指南:如何在水泥森林发现 biodiversity
**领域**:自然 / 科普
**形式**:实操指南 + 城市生态观察
**预估字数**2000
**核心观点**:自然不在远方,就在身边;城市也是wildlife的栖息地,学会观察能提升生活幸福感
**受众痛点**
- 想接触自然但没时间去郊外
- 觉得城市只有鸽子麻雀,没啥可看
- 想带孩子体验自然不知从何开始
- 对生物多样性有概念但不会识别
- 担心需要专业设备和大量学习
- 城市生活枯燥,寻求新鲜感和治愈
**独特角度**
- 城市观鸟入门,从"完全小白"到"常见鸟达人"
- 结合科技:观鸟App(Merlin、鸟哨识别)、社区数据平台(eBird)
- 强调"身边":小区、公园、甚至阳台上就能开始
- 用数据说话:上海/北京等城市的鸟类种类统计
- 连接宇之然理念:科技帮助人与自然的连接
**数据/案例**(至少3个来源):
1. 城市生物多样性调研报告(中国的城市化与野生动物)
2. 常见城市鸟类图鉴(种类、特征、习性)
3. eBird/懂鸟等平台用户提交数据(观测频率)
4. 个人城市观鸟记录(一年在X城市观测到XX种)
5. 观鸟对心理健康的研究(缓解压力、提升注意力)
**预估完成时间**3天
**优先级**:中
**预计发布时间**2026-05-01
**状态**:待处理
---
## 选题评估矩阵
| 维度 | 评分 | 说明 |
|------|------|------|
| 受众覆盖 | 7 | 相对垂直,但亲子、自然爱好者多 |
| 独特性 | 9 | 城市+观鸟结合,实用性强,科普价值高 |
| 数据可得性 | 8 | 鸟类数据、App工具、调研报告充足 |
| 可持续性 | 9 | 可系列(不同季节、不同城市、不同难度) |
| 平台契合度 | 8 | 知乎科普/小红书图文,适合短视频延伸 |
| 品牌契合度 | 10 | 科技+自然+生活,完美契合 |
| **总分** | **51** | 优先执行 ✅ |
---
## 大纲草稿
### 开头(200字)
- 场景:在上海陆家嘴办公室,突然听到窗外各种鸟叫,一个想法:城市里有啥鸟?
- 意外:下载观鸟App后,发现小区里有20+种鸟
- 变化:现在走路会抬头,阳台常备望远镜,生活多了乐趣
- 核心观点:城市不是自然的对立面,而是生态系统一部分
- 预告:教你从零开始城市观鸟,需要什么、去哪看、如何识别
### 主体(1600字)
**第一部分:城市里有多少鸟?(200字)**
- 数据:上海已记录鸟类 400+ 种,北京 500+ 种
- 常见的是哪些?(麻雀、白头鹎、乌鸫、珠颈斑鸠、白鹭、喜鹊等)
- 季节性:候鸟迁徙(春秋季更多)
- 城市生态:公园、河流、小区绿地、屋顶都能看到
- 我的记录:在XX小区/公园一年观测到XX种
- 结论:比你想象的多得多
**第二部分:观鸟入门装备(200字)**
- **最低配置**(手机 + 免费App):
- 懂鸟/Merlin Bird ID(声音识别神器)
- eBird中国(记录、查看附近观测)
- 观鸟相机(手机即可,需要长焦建议入门望远镜2k-3k)
- **进阶配置**
- 望远镜(8x42 双筒,入门推荐)
- 鸟类图鉴(纸质书或App
- 记录本或电子表格
- **着装**:低调颜色(避免亮色惊鸟),舒适鞋子
- **.total cost*:零成本起步,深度5000元以内
**第三部分:去哪看?(200字)**
- **城市公园**:最佳入门地(有人维护、鸟类聚集)
- 上海:世纪公园、滨江森林公园、上海植物园
- 北京:奥林匹克森林公园、颐和园、圆明园
- **湿地/河流**:水鸟聚集(白鹭、翠鸟、水鸡)
- 例子:上海崇明东滩、北京野鸭湖
- **小区和校园**:你身边的第一站
- 树木多的老小区往往有惊喜
- 大学校园绿化好,鸟类多
- **城市高点**:观猛禽(迁徙季节)
- **App辅助**eBird Hotspots 查看附近观测点
**第四部分:如何识别?(300字)**
- 观鸟四要素:体型、颜色、行为、声音
- **步骤1**:先看大小和整体形状(像麻雀还是喜鹊?)
- **步骤2**:看颜色分布(头部、背部、腹部、翅膀)
- **步骤3**:看行为(在地上找食?树上鸣叫?水中游?)
- **步骤4**:听声音(Merlin识别超准)
- **步骤5**:对照图鉴或App
- **常见城市鸟快速指南**(选10种):
- 麻雀:灰褐色,群体,地面觅食,城市最常见
- 白头鹎:白色头顶,背部橄榄绿,叫"WA-DA-DI"
- 乌鸫:雄性黑褐色,黄色眼圈,鸣叫婉转
- 珠颈斑鸠:棕灰色,颈后白斑像珍珠,咕咕叫
- 白鹭:白色,长腿长颈,水边常见
- 喜鹊:黑白分明,长尾巴,聪明
- 灰喜鹊:蓝灰色,群居,山区更多
- 大山雀:蓝黄配色,叫"锌锌"
- 啄木鸟:斑纹红头,树洞敲击声
- 普通翠鸟:橙蓝色, waterside,极快闪
**第五部分:季节与迁徙(200字)**
- 春季(3-5月):候鸟北归,种类最多,常见莺类
- 夏季(6-8月):留鸟+繁殖季,早上鸣叫活跃
- 秋季(9-11月):候鸟南迁,猛禽(鹰、鸮)容易看到
- 冬季(12-2月):候鸟到南方越冬,水鸟多
- 迁徙高峰期:每年4月中、10月中,去湿地有惊喜
**第六部分:科技让观鸟更简单(200字)**
- **声音识别**Merlin Bird ID(免费的!),对着鸟叫录一下,马上指出种类和概率
- **图像识别**:懂鸟App上传照片,准确率90%+
- **社区数据**:eBird 查看附近谁看到了什么,热门 spots
- **记录与统计**:电子清单,个人记录,年度总结
- **社交**:加入城市观鸟社群,组团学习
- "宇之然":科技降低自然体验门槛
**第七部分:给新手的建议(200字)**
1. 从小区开始,别追求稀有鸟
2. 带双筒望远镜(非必需但提升体验)
3. 下载 Merlin 和懂鸟,声音识别是关键
4. 学习10种最常见的,再扩展
5. 晨起最佳(鸟活跃,人少)
6. 安静缓慢,避免惊鸟
7. 记录观测(App自动记录)
8. 加入本地观鸟群,老手带入门快
9. 长期坚持,你会发现城市生命的丰富
10. 保护鸟类:不打扰、不投喂、不破坏栖息地
### 结尾(200字)
- 观鸟一年,我在城市发现了20+种鸟,还记录到罕见的红嘴蓝鹊
- 自然不是远方的诗,是身边的小确幸
- 提升了观察力、耐心、对季节变化的敏感
- 带孩子观鸟是最佳的自然教育
- "宇之然":科技沟通万物,让我重新发现身边自然
- 鼓励:明天早上花15分钟,去小区听鸟叫、看鸟飞
- 互动:你所在城市常见什么鸟?分享你的发现
---
## 资源清单
### 数据来源(待收集)
- [ ] 中国主要城市鸟类名录(中国科学院、地方鸟类学会)
- [ ] eBird 中国数据(观测统计)
- [ ] 城市生态学研究(城市化对鸟类影响)
- [ ] 鸟类迁徙路线图(东亚-澳大利西亚迁飞区)
- [ ] 观鸟对心理健康益处研究
### 图片素材(待准备)
- [ ] 常见城市鸟类照片(自己拍摄或购买授权)
- [ ] 观鸟装备照片(望远镜、App截图)
- [ ] 城市观鸟地点(公园、湿地照片)
- [ ] 观鸟者视角(手持望远镜看鸟)
- [ ] 鸟类识别对比图(相似鸟区分)
### 引用来源(待标注)
- [ ] Cornell Lab Merlin Bird ID
- [ ] eBird 中国(https://ebird.org/china
- [ ] 中国观鸟组织(如:中国观鸟记录中心)
- [ ] 鸟类图鉴(如《中国鸟类观察手册》)
- [ ] 城市生态学文献
---
**决策**:入门级自然科普,大众接受度高,亲子群体尤其适合。内容轻量但实用,适合快速创作。建议 medium 优先级。
-231
View File
@@ -1,231 +0,0 @@
# 个人知识管理系统(PKM)实践:我用一年搭建的第二大脑
**领域**:工作 / 生产力
**形式**:实操教程 + 系统设计
**预估字数**2800
**核心观点**:信息时代,会学习不如会管理知识;一个适合自己的PKM系统能释放认知带宽,提升创造力和决策质量
**受众痛点**
- 收藏无数,但从未回看(收藏夹吃灰)
- 知识点散落在各处(笔记App、书签、微信收藏、纸质本)
- 需要时找不到,找到的又不完整
- 学会了方法但无法坚持(Roam太复杂、Notion不会用)
- 信息过载,不知道如何筛选和组织
- 想建立系统但被工具选择困住(工具 switcher)
**独特角度**
- 不推销特定工具,强调方法论+适合自己的选择
- 展示一年的实践数据和系统演变(不是一蹴而就)
- 强调"用"而非"建":系统为输出服务,不为收藏
- 结合AI辅助(自动标签、智能摘要、关联发现)
- 从程序员视角但内容通用
**数据/案例**(至少3个来源):
1. PKM方法论(Zettelkasten、PARA、CODE等)
2. 工具对比研究(Notion、Obsidian、Roam、Logseq、飞书、Notability
3. 个人一年数据:笔记数量、链接数、输出成果、时间节省
4. 知识工作者效率研究(信息检索耗时)
5. 成功案例:其他内容创作者如何用PKM支撑输出
**预估完成时间**5天
**优先级**:中
**预计发布时间**2026-05-03
**状态**:待处理
---
## 选题评估矩阵
| 维度 | 评分 | 说明 |
|------|------|------|
| 受众覆盖 | 8 | 知识工作者广泛需要,但执行率低 |
| 独特性 | 8 | 个人系统演变+数据追踪,避免工具论 |
| 数据可得性 | 9 | PKM方法论丰富,个人数据可量化 |
| 可持续性 | 9 | 可系列(不同工具、不同场景、进阶技巧) |
| 平台契合度 | 9 | 知乎效率/工具,小红书个人成长 |
| 品牌契合度 | 9 | 科技赋能知识管理,提升深度思考 |
| **总分** | **52** | 优先执行 ✅ |
---
## 大纲草稿
### 开头(400字)
- 场景:2024年,我发现自己有5个笔记App、2000+零散笔记、无数书签,但写文章时还是找不到资料
- 问题:信息时代,我们被信息淹没,却缺乏可用的知识
- 决定:用一年时间,搭建并完善个人知识管理系统(PKM)
- 结果:笔记整理到统一系统,知识关联起来了,写文章效率提升3倍
- 核心观点:PKM不是收藏信息,而是将信息转化为知识资产
- 预告:分享我的方法论、工具选择、系统设计、一年数据和教训
### 主体(2200字)
**第一部分:为什么你需要PKM?(300字)**
- 信息过载时代:每年产生信息量 vs 大脑处理能力
- 知识 ≠ 信息:信息是 raw data,知识是 processed and connected
- 不管理的代价:
- 重复学习(同一个知识点看过多次但没记住)
- 需要时找不到(搜索耗时>30分钟)
- 知识孤岛(孤立信息无法产生新想法)
- 决策质量低(缺乏完整背景)
- 研究:知识工作者平均每天花1.5小时找信息(麦肯锡)
- PKM的价值:提高检索效率、支持创造性连接、减少认知负荷
**第二部分:PKM方法论概览(200字)**
- **Zettelkasten**(卡片盒笔记法):原子化、链接、渐进式总结
- 核心:每个笔记一个想法,用链接建立连接
- 适合:深度思考者、研究者、作家
- **PARA**Tiago Forte):按可行动性组织(Projects, Areas, Resources, Archives
- 核心:不是按主题,而是按"使用状态"分类
- 适合:项目驱动、注重行动的人
- **CODE**Capture, Organize, Distill, Express):知识生命周期
- 核心:从收集到输出的完整流程
- 适合:内容创作者、学习型人才
- **选择建议**:没有最佳,只有最适合;可混合使用
- 我的选择:CODE框架 + Zettelkasten 链接 + PARA 分类
**第三部分:我的系统演变(3个阶段)(300字)**
- **第1阶段(混沌期,2019-2020**
- 工具:微信收藏 + Evernote + 书签
- 问题:信息散落,从未整理,基本不用
- 产出:0
- **第2阶段(工具迷恋,2021)**:
- 尝试:Roam Research(双链笔记)、Notion(数据库)、Obsidian(本地Markdown
- 问题:花大量时间折腾工具,而不是用系统
- 产出:少量笔记,但没形成知识网络
- **第3阶段(方法驱动,2022-2023**
- 选择:Notion(数据库+协作)+ 本地Markdown备份
- 方法论:CODE流程 + 原子笔记 + 强制链接
- 成果:整理笔记1500+条,链接1000+,支撑输出文章40+篇
- 关键:从"怎么建"转向"怎么用"
**第四部分:我的当前系统设计(400字)**
- **工具栈**
- 主库:Notion(数据库+关联视图+协作)
- 优点:全平台、强查询、美观
- 缺点:网络依赖、长期成本
- 本地备份:ObsidianMarkdown + 双链)
- 优点:数据自主、快、强链接
- 缺点:移动端弱、协作差
- 收集箱:Readwise + Instapaper + 微信收藏 + 书签
- AI辅助:使用LLM自动摘要、标签、提取关键点
- **结构(按CODE**
- **Capture**(收集):
- 快速收藏(Readwise高亮、微信收藏 → 每日清理到收集箱)
- 来源:文章、书、视频、对话、思考
- **Organize**(组织):
- 分类:PARAProjects/Areas/Resources/Archives
- 标签:主题(科技、自然、人文)+ 状态(草稿、完成)
- 链接:原子笔记之间建立连接(双向链接)
- **Distill**(提炼):
- 原子化:每笔记一个概念/想法/发现
- 渐进式总结:原始笔记 → 粗摘要 → 精要 → 综述
- MOC(内容地图):索引相关笔记,形成知识模块
- **Express**(输出):
- 创作模式:从PKM查询相关笔记 → 拼图式写作
- 模板:文章模板自动从PKM填充资料
- 发布后,将文章存入PKM作为新笔记
- **工作流**
- 每日:收集(30min + 整理(30min
- 每周:链接和MOC维护(1h
- 创作时:查询 → 连接 → 输出(PKM支撑)
**第五部分:量化结果(200字)**
- 笔记总量:1500+ 条(原子笔记)
- 笔记间链接:1200+ 个(网络密度 0.8)
- 知识领域:8个大类,50+个小类
- 时间节省:资料查找从平均30min → 5min83%
- 输出支撑:40+ 篇文章,其中80%从PKM直接提取资料
- 知识复用率:70%的文章引用已有笔记(不是每次都重研究)
- 意外收益:笔记价值随时间复利增长(旧笔记连接新笔记产生新洞见)
**第六部分:关键技巧(300字)**
1. **原子化**
- 每笔记一个概念、一个发现、一个问题
- 优点:易复用、易链接、易更新
- 例子:不要记整本书笔记,记"书的核心框架"+"3个关键观点"+"我的疑问"
2. **强制链接**
- 新笔记必须链接到至少2个已有笔记
- 链接要语义相关(不只是关键词匹配)
- 使用 Zettelkasten 的自下而上连接
- 工具:Obsidian的Graph View、Notion的Relation
3. **渐进式总结**
- 原始笔记(source原文高亮+简评)
- 一阶摘要(用自己的话)
- 二阶精要(关键点 bullet
- 三阶综合(多个笔记的整合+我的观点)
- 成果:长期使用,笔记越来越有价值
4. **MOC(内容地图)**
- 索引同一主题的所有笔记(类似目录)
- 动态更新,保持相关性
- 例子:"AI伦理" MOC 链接60+条笔记
- 创作时,先看MOC快速定位
5. **定期修剪**
- 每月审查:合并重复、删除过时、更新链接
- 保持系统健康,避免熵增
**第七部分:AI如何辅助PKM?(200字)**
- **自动摘要**:上传文章,LLM生成关键点(节省阅读时间)
- **智能标签**:自动建议标签,保持一致性
- **关联发现**:AI找语义相关笔记,建议链接
- **问答式检索**:自然语言查询("我怎么写关于Zettelkasten的文章?" → 相关笔记)
- **质量检查**:识别孤立笔记、断裂链接
- 工具:ChatGPT/Claude API + 自定义脚本
- "宇之然"AI时代,PKM是核心基础设施
**第八部分:常见问题与避坑(200字)**
- Q:工具太多,选哪个?(先用一个,习惯后再考虑迁移)
- Q:笔记分类 vs 标签?(分类是宏观,标签是微观,两者都需)
- Q:多久整理一次?(每天小整,每周大整)
- Q:隐私问题?(本地工具如Obsidian;云工具加密)
- Q:如何坚持?(绑定创作需求,系统为输出服务)
- 避坑:
- 不要过度组织(1-2小时整理1条笔记,效率低)
- 不要追求完美的分类(允许模糊)
- 不要忽视维护(熵增是必然,定期修剪)
- 不要只看不输出(PKM的价值在输出)
### 结尾(200字)
- PKM一年,我的知识从混沌到有序,从孤岛到网络
- 最大的收益:写文章不再从零开始,而是"拼图式创作"
- 知识管理是终身投资,越早开始复利越大
- "宇之然":科技沟通知识,让我更好地表达思想
- 行动:从今天开始,用Notation至少10个原子笔记
- 互动:你的知识管理实践如何?遇到的问题?
---
## 资源清单
### 数据来源(待收集)
- [ ] PKM方法论原始文献(Zettelkasten、PARA、CODE
- [ ] 知识管理工作效率研究(查找时间、复用率)
- [ ] 工具对比(Notion、Obsidian、Roam、Logseq、飞书)
- [ ] Notion API和自动化案例
- [ ] AI辅助知识管理工具(Memex、Rewind、Upabase
### 图片素材(待准备)
- [ ] 系统架构图(工具栈、数据流)
- [ ] Notion数据库截图(匿名化)
- [ ] Obsidian Graph View截图(展示连接密度)
- [ ] 工作流可视化(Capture → Organize → Distill → Express
- [ ] 量化结果图表(笔记数、链接数、时间节省)
- [ ] 渐进式总结示例(同一笔记的不同版本)
### 引用来源(待标注)
- [ ] Sönke Ahrens《How to Take Smart Notes》
- [ ] Tiago Forte《Building a Second Brain》
- [ ] Andy Matuschak & Michael Nielsen《How to Make a Networked Notebook That Explains Things》
- [ ] PARA方法论官网
- [ ] Zettelkasten.de社区
- [ ] AI知识管理工具(Mem.ai等)
---
**决策**:生产力领域刚需,受众广但竞争烈。结合个人系统演变数据+方法论+AI辅助,能做出差异化。适合知乎和小红书。建议 medium-high 优先级。
-71
View File
@@ -1,71 +0,0 @@
# 选题库管理
本目录收录所有选题卡片,按领域和优先级分类。
## 选题结构
每个选题文件格式:`YYYY-MM-DD-选题名称.md`
内容模板:
```markdown
# [选题名称]
**领域**:科技/自然/工作/人文
**形式**:观点/指南/趋势/故事
**预估字数**2000-3000
**核心观点**:(一句话说清楚)
**受众痛点**:(读者为什么关心?)
**独特角度**:(与其他人的区别)
**数据/案例**:(至少3个来源)
**预估完成时间**3-5天
**优先级**:高/中/低
**预计发布时间**YYYY-MM-DD
**状态**:待处理/研究中/写作中/已发布
```
## 选题评估得分
使用品牌手册中的"选题评估矩阵"打分:
- 受众覆盖:1-10分
- 独特性:1-10分
- 数据可得性:1-10分
- 可持续性:1-10分
- 平台契合度:1-10分
- 品牌契合度:1-10分
**总分 > 40分** → 优先执行
**30-40分** → 考虑执行
**< 30分** → 暂缓或放弃
## 当前选题列表(个人叙事版 001-010)
| 编号 | 选题名称 | 领域 | 优先级 | 得分 | 状态 |
|------|----------|------|--------|------|------|
| 001 | 在上海阳台种菜一年,我收获了啥? | 自然/生活 | 高 | 51 | ✅ 已发布 |
| 002 | AI时代,什么能力不会被替代? | 科技/职场 | 高 | 48 | 📝 待创作 |
| 003 | 从程序员到数字游民:三年转型之路 | 工作/职场 | 高 | 45 | 📝 待创作 |
| 004 | 零浪费生活一年实验 | 自然/生活 | 中 | 42 | 📝 待创作 |
| 005 | 深度工作实践:如何在干扰世界保持专注 | 工作/生产力 | 高 | 46 | 📝 待创作 |
| 006 | 副业月入过万:程序员的三年探索 | 工作/副业 | 中 | 40 | 📝 待创作 |
| 007 | 正念冥想一年:从焦虑到平静的转变 | 人文/心理 | 中 | 41 | 📝 待创作 |
| 008 | 极简3年:从囤积症到少物生活的转变 | 人文/生活 | 中 | 39 | 📝 待创作 |
| 009 | 城市观鸟指南:如何在水泥森林发现biodiversity | 自然/科普 | 中 | 38 | 📝 待创作 |
| 010 | 个人知识管理系统(PKM)实践 | 工作/生产力 | 高 | 47 | 📝 待创作 |
> 另有 **全球-本土对比新选题(20个)** 详见 `strategy/全球-本土比较研究与全新内容战略规划-2026-04-15.md`,分为4大支柱:未来工作方式、可持续生活、知识工厂、科技人文。
## 批量添加选题
新选题从以下来源获取:
- 行业趋势分析(research/trends-2026.md
- 日常观察记录
- 热点事件(冷静筛选)
- 读者问题反馈
- 竞品分析(差异化)
**每周选题会议**:每周日晚上20:00,评估新选题,确定下周发布计划。
---
**维护**:动态更新
**负责人**AI助手 + 用户协作
+3
View File
@@ -31,6 +31,7 @@ def list_topics(
status: Optional[str] = None,
today: Optional[bool] = None,
tag: Optional[str] = None,
series: Optional[str] = None,
search: Optional[str] = None,
sort_by: str = Query("priority_score", enum=["priority_score", "created_at", "title", "updated_at"]),
order: str = Query("desc", enum=["asc", "desc"]),
@@ -54,6 +55,8 @@ def list_topics(
query = query.filter(func.date(Topic.created_at) == date.today())
if tag:
query = query.filter(Topic.tags.contains([tag]))
if series:
query = query.filter(Topic.series == series)
if search:
query = query.filter(Topic.title.contains(search))
+1
View File
@@ -131,6 +131,7 @@ def init_db():
("search_rankings", "org_id", "VARCHAR DEFAULT 'default'"),
("geo_readiness_scores", "org_id", "VARCHAR DEFAULT 'default'"),
("articles", "org_id", "VARCHAR DEFAULT 'default'"),
("topics", "series", "VARCHAR"),
]:
try:
conn.execute(text(f"ALTER TABLE {table} ADD COLUMN IF NOT EXISTS {col} {typ}"))
+19 -24
View File
@@ -105,7 +105,7 @@ def import_initial_data():
"default_format": "深度分析 3000-8000字,数据驱动",
"compliance_rules": {
"max_title_len": 100,
"allowed_tags": ["科技", "生活", "职场", "教育", "可持续", "AI", "远程工作", "个人成长"],
"allowed_tags": ["科技", "AI", "效率", "职场", "教育", "远程工作", "未来工作", "工具"],
"forbidden_patterns": ["加微信", "私聊", "付费咨询", "点击领取"]
},
"is_active": True,
@@ -124,7 +124,7 @@ def import_initial_data():
"default_format": "个人叙事 2000-4000字,对话感",
"compliance_rules": {
"max_title_len": 32,
"allowed_tags": ["科技", "生活", "职场", "教育", "可持续", "AI", "远程工作", "个人成长"],
"allowed_tags": ["科技", "AI", "效率", "职场", "教育", "远程工作", "未来工作", "工具"],
"forbidden_patterns": ["诱导分享", "朋友圈", "转发群"]
},
"is_active": True,
@@ -143,7 +143,7 @@ def import_initial_data():
"default_format": "精炼干货 400-1000字,实用优先",
"compliance_rules": {
"max_title_len": 50,
"allowed_tags": ["生活方式", "可持续", "AI", "个人成长", "极简", "环保"],
"allowed_tags": ["AI", "效率", "科技", "工具", "职场", "生活", "学习方法"],
"forbidden_patterns": ["私信", "加群", "导流"]
},
"is_active": True,
@@ -163,9 +163,9 @@ def import_initial_data():
else:
# 更新已有平台配置的字数要求(迁移:2026-06 内容质量升级)
platform_updates = {
"zhihu": {"min_words": 3000, "max_words": 8000, "default_format": "深度分析 3000-8000字,数据驱动"},
"wechat": {"min_words": 2000, "max_words": 4000, "default_format": "个人叙事 2000-4000字,对话感"},
"xiaohongshu": {"min_words": 400, "max_words": 1000, "default_format": "精炼干货 400-1000字,实用优先"},
"zhihu": {"min_words": 3000, "max_words": 8000, "default_format": "深度分析 3000-8000字,数据驱动+观点交锋,用一手数据和独特视角切入"},
"wechat": {"min_words": 2000, "max_words": 4000, "default_format": "科技人文叙事 2000-4000字,个人反思+情感共鸣,记录人与技术之间的故事"},
"xiaohongshu": {"min_words": 400, "max_words": 1000, "default_format": "精炼干货 400-1000字,亲测数据+实操结果,每个结论配真实对比"},
}
for p in db.query(PlatformConfig).all():
if p.platform in platform_updates:
@@ -178,41 +178,36 @@ def import_initial_data():
if db.query(TopicField).count() == 0:
fields = [
{"name": "未来工作方式", "icon": "💼", "color": "#667eea", "description": "远程工作、零工经济、职业转型", "sort_order": 1},
{"name": "AI与效率", "icon": "🤖", "color": "#764ba2", "description": "AI工具、数字助手、效率方法", "sort_order": 2},
{"name": "可持续生活", "icon": "🌿", "color": "#67c23a", "description": "环保、低碳、自然生活方式", "sort_order": 3},
{"name": "数字游民", "icon": "🌍", "color": "#409eff", "description": "旅行、地理自由、海外生活", "sort_order": 4},
{"name": "个人成长", "icon": "📚", "color": "#e6a23c", "description": "学习、技能、认知升级", "sort_order": 5},
{"name": "科技人文", "icon": "🔬", "color": "#f56c6c", "description": "科技伦理、数字生活反思", "sort_order": 6},
{"name": "AI与效率", "icon": "🤖", "color": "#764ba2", "description": "AI工具实测对比、工作流效率方法、前沿资讯解读——关注技术如何改变人的工作方式", "sort_order": 1},
{"name": "科技人文", "icon": "🔬", "color": "#f56c6c", "description": "AI伦理困境、数字生活反思、人机关系探索——科技的温度与边界", "sort_order": 2},
{"name": "未来工作方式", "icon": "💼", "color": "#667eea", "description": "远程协作实践、AI时代职业转型、一人企业模式——未来不是等来的", "sort_order": 3},
]
for f in fields:
db.add(TopicField(**f))
db.commit()
print("✅ 插入默认领域配置")
print("✅ 插入默认领域配置(聚焦AI×人文×未来工作)")
if db.query(CollectorCategory).count() == 0:
default_cats = [
{"name": "循环消费", "search_query": "以旧换新 二手交易 闲置 循环 2026", "description": "以旧换新/二手交易/租赁经济 | 2025年二手交易额1.69万亿", "sort_order": 1, "is_active": True},
{"name": "低碳出行", "search_query": "新能源车 骑行 绿色通勤 低碳出行 2026", "description": "新能源车/骑行/绿色出行 | 年产销破1000万辆", "sort_order": 2, "is_active": True},
{"name": "干净饮食", "search_query": "干净饮食 有机食品 植物基 本地食材 2026", "description": "有机食品/植物基/本地食材 | 有机食品1247亿", "sort_order": 3, "is_active": True},
{"name": "零浪费生活", "search_query": "零浪费 自带杯 极简生活 可持续时尚 2026", "description": "自带杯/极简/可持续时尚 | 自带杯笔记277万篇", "sort_order": 4, "is_active": True},
{"name": "绿色家电与节能", "search_query": "绿色家电 一级能效 以旧换新 节能 2026", "description": "一级能效/国补政策 | 一级能效占比90%+", "sort_order": 5, "is_active": True},
{"name": "碳普惠", "search_query": "碳账户 碳普惠 个人碳减排 蚂蚁森林 2026", "description": "碳账户/碳普惠/个人减排 | 武汉200万碳账户", "sort_order": 6, "is_active": True},
{"name": "环保科技产品", "search_query": "环保科技 绿色产品 可持续材料 2026", "description": "可持续材料/绿色产品 | 购买占比超32%", "sort_order": 7, "is_active": True},
{"name": "AI与效率", "search_query": "AI工具 人工智能 效率提升 2026", "description": "AI工具/效率方法/数字助手 | 2026年AI深度融入消费与生活", "sort_order": 8, "is_active": True},
{"name": "AI前沿资讯", "search_query": "AI 人工智能 大模型 2026 前沿 突破 论文解读", "description": "AI行业动态、大模型发布、技术突破 | 2026年AI全面嵌入产业", "sort_order": 1, "is_active": True},
{"name": "AI工具实测", "search_query": "AI工具 效率提升 工作流 prompt教程 Cursor Copilot 2026", "description": "AI工具评测、效率工作流、实操指南 | 2026年AI工具爆发", "sort_order": 2, "is_active": True},
{"name": "AI与职场", "search_query": "AI 裁员 职业转型 AI技能 远程工作 一人企业 2026", "description": "AI对就业影响、职业转型、技能升级 | 2026年AI重塑就业结构", "sort_order": 3, "is_active": True},
{"name": "AI生活", "search_query": "AI陪伴 AI心理咨询 生活助手 AI写作 智能体 2026", "description": "AI心理咨询/生活搭子/AI人格化 | 商业笔记互动增长263%", "sort_order": 4, "is_active": True},
{"name": "科技人文", "search_query": "AI伦理 数字生活 科技反思 人机关系 数据隐私 2026", "description": "AI伦理/数字生活反思/科技温度 | AI从工具到共生", "sort_order": 5, "is_active": True},
]
for cd in default_cats:
existing = db.query(CollectorCategory).filter(CollectorCategory.name == cd["name"]).first()
if not existing:
db.add(CollectorCategory(**cd))
db.commit()
print("✅ 插入默认采集类别和信息源")
print("✅ 插入默认采集类别(聚焦AI×科技人文)")
db.commit()
# 补充缺失的类别和信息源(对已有数据库的迁移)
# 补充缺失的采集源(对已有数据库的迁移)
for sd in [
{"name": "AI工具搜索", "source_type": "web_search", "query": "AI工具 人工智能 效率提升 2026", "credibility": "medium", "focus": "AI与效率", "sort_order": 99, "is_active": True},
{"name": "AI前沿搜索", "source_type": "web_search", "query": "AI 人工智能 大模型 前沿 2026", "credibility": "medium", "focus": "AI前沿资讯", "sort_order": 1, "is_active": True},
{"name": "AI工具搜索", "source_type": "web_search", "query": "AI工具 效率提升 AI工作流 2026", "credibility": "medium", "focus": "AI工具实测", "sort_order": 2, "is_active": True},
]:
if not db.query(CollectorSource).filter(CollectorSource.name == sd["name"]).first():
db.add(CollectorSource(**sd))
+1
View File
@@ -265,6 +265,7 @@ class Topic(Base):
platform_urls = Column(JSON, default=dict)
lock_by = Column(String, nullable=True)
lock_at = Column(DateTime, nullable=True)
series = Column(String, nullable=True, index=True, comment="所属栏目,如:AI工具实测周报、科技人文思辨")
field = relationship("TopicField", backref="topics")
+3
View File
@@ -76,6 +76,7 @@ class TopicBase(BaseModel):
scoring_data: Dict[str, Any] = {}
lock_by: Optional[str] = None
lock_at: Optional[datetime] = None
series: Optional[str] = None
class TopicCreate(BaseModel):
@@ -90,6 +91,7 @@ class TopicCreate(BaseModel):
tags: List[str] = []
custom_data: Dict[str, Any] = {}
scoring_data: Dict[str, Any] = {}
series: Optional[str] = None
class TopicAnalyzeRequest(BaseModel):
@@ -123,6 +125,7 @@ class TopicUpdate(BaseModel):
scoring_data: Optional[Dict[str, Any]] = None
priority_score: Optional[int] = None
total_score: Optional[float] = None
series: Optional[str] = None
class TopicResponse(TopicBase):
+121 -50
View File
@@ -7,6 +7,7 @@
<link rel="stylesheet" href="element-plus.css">
<link rel="stylesheet" href="theme-modern.css">
<style>
[v-cloak] { display: none; }
.data-table { display: block; }
@media (max-width: 768px) { .data-table { display: none; } }
.stat-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 16px; }
@@ -14,8 +15,18 @@
.stat-card .num { font-size: 28px; font-weight: 700; color: #2563eb; }
.stat-card .label { font-size: 12px; color: #909399; margin-top: 4px; }
.search-engine-tag { margin: 2px; }
@media (max-width: 768px) {
.page-header { flex-direction: column; align-items: flex-start !important; gap: 8px; }
.filter-bar { display: flex; flex-wrap: wrap; gap: 4px; }
.filter-bar .el-button { margin-left: 0 !important; }
.stat-cards { grid-template-columns: repeat(2, 1fr); }
.toolbar { flex-wrap: wrap; gap: 8px; }
}
</style>
<script src="uni-nav.js"></script>
<script src="vue.global.prod.js"></script>
<script src="element-plus.full.js"></script>
<script src="icon-components.js"></script>
</head>
<body>
<div id="app" v-cloak>
@@ -89,6 +100,17 @@
</template>
</el-table-column>
</el-table>
<div class="card-list-mobile">
<div v-for="p in products" :key="p.id" class="card-item">
<div class="card-row"><span class="card-label">名称</span><span class="card-value">{{ p.name }}</span></div>
<div class="card-row"><span class="card-label">类型</span><span class="card-value">{{ typeLabel(p.type) }}</span></div>
<div class="card-row"><span class="card-label">URL</span><span class="card-value"><a :href="p.url" target="_blank" style="color:#409eff;word-break:break-all;">{{ p.url || '-' }}</a></span></div>
<div class="card-actions">
<el-button size="small" @click="editProduct(p)">编辑</el-button>
<el-button size="small" type="danger" @click="deleteProduct(p)">删除</el-button>
</div>
</div>
</div>
<div v-if="products.length > pageSize" style="display:flex;justify-content:center;margin:12px 0;">
<el-pagination background layout="prev, pager, next" :total="products.length" :page-size="pageSize" :current-page="productPage" @current-change="productPage = $event"></el-pagination>
</div>
@@ -129,6 +151,19 @@
</template>
</el-table-column>
</el-table>
<div class="card-list-mobile">
<div v-for="c in campaigns" :key="c.id" class="card-item">
<div class="card-row"><span class="card-label">活动</span><span class="card-value">{{ c.name }}</span></div>
<div class="card-row"><span class="card-label">产品</span><span class="card-value">{{ c.product_name || '-' }}</span></div>
<div class="card-row"><span class="card-label">状态</span><span class="card-value"><el-tag :type="c.status === 'active' ? 'success' : c.status === 'paused' ? 'warning' : 'info'" size="small">{{ { active: '进行中', paused: '已暂停', completed: '已完成' }[c.status] || c.status }}</el-tag></span></div>
<div class="card-row"><span class="card-label">引擎</span><span class="card-value"><el-tag v-for="e in (c.target_engines || [])" :key="e" size="small" class="search-engine-tag">{{ engineLabel(e) }}</el-tag></span></div>
<div class="card-actions">
<el-button size="small" @click="viewCampaignKeywords(c)">关键词</el-button>
<el-button size="small" @click="editCampaign(c)">编辑</el-button>
<el-button size="small" type="danger" @click="deleteCampaign(c)">删除</el-button>
</div>
</div>
</div>
<div v-if="campaigns.length > pageSize" style="display:flex;justify-content:center;margin:12px 0;">
<el-pagination background layout="prev, pager, next" :total="campaigns.length" :page-size="pageSize" :current-page="campaignPage" @current-change="campaignPage = $event"></el-pagination>
</div>
@@ -139,21 +174,34 @@
关键词详情:{{ selectedCampaign.name }}
<el-button size="small" type="primary" style="margin-left:8px;" @click="showKeywordDialog = true">添加关键词</el-button>
</h4>
<el-table v-if="campaignKeywords.length" :data="campaignKeywords" border stripe class="data-table" style="width:100%">
<el-table-column prop="keyword" label="关键词" min-width="150"></el-table-column>
<el-table-column prop="search_volume" label="搜索量" width="80"></el-table-column>
<el-table-column label="难度" width="70">
<template #default="s"><el-tag :type="(s.row.difficulty || 0) > 0.7 ? 'danger' : (s.row.difficulty || 0) > 0.4 ? 'warning' : 'success'" size="small">{{ s.row.difficulty != null ? (s.row.difficulty * 100).toFixed(0) + '%' : '-' }}</el-tag></template>
</el-table-column>
<el-table-column prop="current_rank" label="当前排名" width="80"></el-table-column>
<el-table-column prop="target_rank" label="目标排名" width="80"></el-table-column>
<el-table-column prop="best_rank" label="最佳排名" width="80"></el-table-column>
<el-table-column label="操作" width="100">
<template #default="s">
<el-button size="small" type="danger" @click="deleteKeyword(s.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<template v-if="campaignKeywords.length">
<el-table :data="campaignKeywords" border stripe class="data-table" style="width:100%">
<el-table-column prop="keyword" label="关键词" min-width="150"></el-table-column>
<el-table-column prop="search_volume" label="搜索量" width="80"></el-table-column>
<el-table-column label="难度" width="70">
<template #default="s"><el-tag :type="(s.row.difficulty || 0) > 0.7 ? 'danger' : (s.row.difficulty || 0) > 0.4 ? 'warning' : 'success'" size="small">{{ s.row.difficulty != null ? (s.row.difficulty * 100).toFixed(0) + '%' : '-' }}</el-tag></template>
</el-table-column>
<el-table-column prop="current_rank" label="当前排名" width="80"></el-table-column>
<el-table-column prop="target_rank" label="目标排名" width="80"></el-table-column>
<el-table-column prop="best_rank" label="最佳排名" width="80"></el-table-column>
<el-table-column label="操作" width="100">
<template #default="s">
<el-button size="small" type="danger" @click="deleteKeyword(s.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="card-list-mobile">
<div v-for="kw in campaignKeywords" :key="kw.id" class="card-item">
<div class="card-row"><span class="card-label">关键词</span><span class="card-value">{{ kw.keyword }}</span></div>
<div class="card-row"><span class="card-label">搜索量</span><span class="card-value">{{ kw.search_volume || 0 }}</span></div>
<div class="card-row"><span class="card-label">难度</span><span class="card-value"><el-tag :type="(kw.difficulty || 0) > 0.7 ? 'danger' : (kw.difficulty || 0) > 0.4 ? 'warning' : 'success'" size="small">{{ kw.difficulty != null ? (kw.difficulty * 100).toFixed(0) + '%' : '-' }}</el-tag></span></div>
<div class="card-row"><span class="card-label">排名</span><span class="card-value">当前 {{ kw.current_rank || '-' }} 目标 {{ kw.target_rank || '-' }}</span></div>
<div class="card-actions">
<el-button size="small" type="danger" @click="deleteKeyword(kw)">删除</el-button>
</div>
</div>
</div>
</template>
<div v-else style="text-align:center;padding:20px;color:#909399;font-size:13px;">暂无关键词数据</div>
</div>
</div>
@@ -177,7 +225,7 @@
</el-table-column>
<el-table-column label="排名" width="80">
<template #default="s">
<el-tag :type="s.row.rank != null && s.row.rank <= 10 ? 'success' : s.row.rank != null && s.row.rank <= 30 ? 'warning' : 'info'" size="small">{{ s.row.rank || '-' }}</el-tag>
<el-tag :type="s.row.rank == null ? 'info' : s.row.rank <= 10 ? 'success' : s.row.rank <= 30 ? 'warning' : 'info'" size="small">{{ s.row.rank || '-' }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="url_found" label="排名URL" min-width="200">
@@ -187,6 +235,14 @@
<template #default="s">{{ s.row.checked_at ? new Date(s.row.checked_at).toLocaleString('zh-CN') : '-' }}</template>
</el-table-column>
</el-table>
<div class="card-list-mobile">
<div v-for="r in keywordRankings" :key="r.id" class="card-item">
<div class="card-row"><span class="card-label">关键词</span><span class="card-value">{{ r.keyword }}</span></div>
<div class="card-row"><span class="card-label">引擎</span><span class="card-value">{{ engineLabel(r.search_engine) }}</span></div>
<div class="card-row"><span class="card-label">排名</span><span class="card-value"><el-tag :type="r.rank == null ? 'info' : r.rank <= 10 ? 'success' : r.rank <= 30 ? 'warning' : 'info'" size="small">{{ r.rank || '-' }}</el-tag></span></div>
<div class="card-row"><span class="card-label">时间</span><span class="card-value">{{ r.checked_at ? new Date(r.checked_at).toLocaleString('zh-CN') : '-' }}</span></div>
</div>
</div>
<div v-if="keywordRankings.length > pageSize" style="display:flex;justify-content:center;margin:12px 0;">
<el-pagination background layout="prev, pager, next" :total="keywordRankings.length" :page-size="pageSize" :current-page="rankingPage" @current-change="rankingPage = $event"></el-pagination>
</div>
@@ -223,6 +279,15 @@
<template #default="s">{{ s.row.checked_at ? new Date(s.row.checked_at).toLocaleString('zh-CN') : '-' }}</template>
</el-table-column>
</el-table>
<div class="card-list-mobile">
<div v-for="a in audits" :key="a.id" class="card-item">
<div class="card-row"><span class="card-label">产品</span><span class="card-value">{{ a.product_name || '-' }}</span></div>
<div class="card-row"><span class="card-label">总分</span><span class="card-value"><el-tag :type="(a.overall_score || 0) >= 80 ? 'success' : (a.overall_score || 0) >= 60 ? 'warning' : 'danger'" size="small">{{ a.overall_score != null ? a.overall_score.toFixed(1) : '-' }}</el-tag></span></div>
<div class="card-row"><span class="card-label">评分</span><span class="card-value" style="font-size:12px;">M{{ a.meta_score || '-' }} H{{ a.heading_score || '-' }} C{{ a.content_score || '-' }} P{{ a.perf_score || '-' }} L{{ a.links_score || '-' }} Mob{{ a.mobile_score || '-' }}</span></div>
<div class="card-row"><span class="card-label">问题数</span><span class="card-value">{{ a.issues_found || 0 }}</span></div>
<div class="card-row"><span class="card-label">时间</span><span class="card-value">{{ a.checked_at ? new Date(a.checked_at).toLocaleString('zh-CN') : '-' }}</span></div>
</div>
</div>
</template>
</div>
@@ -260,6 +325,19 @@
</template>
</el-table-column>
</el-table>
<div class="card-list-mobile">
<div v-for="t in optimizationTasks" :key="t.id" class="card-item">
<div class="card-row"><span class="card-label">严重度</span><span class="card-value"><el-tag :type="t.severity === 'high' ? 'danger' : t.severity === 'medium' ? 'warning' : 'info'" size="small">{{ { high: '高', medium: '中', low: '低' }[t.severity] || t.severity }}</el-tag></span></div>
<div class="card-row"><span class="card-label">分类</span><span class="card-value">{{ { meta: 'Meta', heading: '标题', content: '内容', performance: '性能', links: '链接', mobile: '移动端' }[t.category] || t.category }}</span></div>
<div class="card-row"><span class="card-label">问题</span><span class="card-value" style="font-size:12px;">{{ t.issue }}</span></div>
<div class="card-row"><span class="card-label">建议</span><span class="card-value" style="font-size:12px;">{{ t.recommendation }}</span></div>
<div class="card-row"><span class="card-label">状态</span><span class="card-value"><el-tag :type="t.status === 'resolved' ? 'success' : t.status === 'ignored' ? 'info' : 'warning'" size="small">{{ { open: '待处理', resolved: '已解决', ignored: '已忽略' }[t.status] || t.status }}</el-tag></span></div>
<div class="card-actions">
<el-button v-if="t.status === 'open'" size="small" type="success" @click="updateTaskStatus(t, 'resolved')">解决</el-button>
<el-button size="small" @click="updateTaskStatus(t, 'ignored')">忽略</el-button>
</div>
</div>
</div>
</template>
</div>
</div>
@@ -342,11 +420,13 @@
</el-dialog>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<script src="https://unpkg.com/element-plus"></script>
<script src="icon-components.js"></script>
<script>
const { createApp, ref, computed, onMounted, nextTick } = Vue;
const { ElMessage } = ElementPlus;
// Auth check — redirect early if no token
const authToken = localStorage.getItem('authToken') || '';
if (!authToken) { window.location.href = '/login.html'; }
const app = createApp({
data() {
@@ -380,7 +460,7 @@
showKeywordDialog: false,
keywordForm: { keyword: '', search_volume: 0, difficulty: 0.5, target_rank: 10 },
token: '',
token: authToken,
};
},
computed: {
@@ -435,7 +515,7 @@
await this.loadTasks();
}
} catch (e) {
ElementPlus.ElMessage.error(e.message);
ElMessage.error(e.message);
} finally {
this.loading = false;
}
@@ -464,7 +544,7 @@
const r = await fetch(url, { method, headers: this.headers(), body: JSON.stringify(this.productForm) });
const d = await r.json();
if (!d.ok) throw new Error(d.detail || '操作失败');
ElementPlus.ElMessage.success(this.editingProduct ? '已更新' : '已创建');
ElMessage.success(this.editingProduct ? '已更新' : '已创建');
this.showProductDialog = false;
this.editingProduct = null;
this.productForm = { name: '', type: 'website', url: '', domain: '', app_id: '', account_id: '', description: '' };
@@ -473,7 +553,7 @@
async deleteProduct(p) {
if (!confirm('确定删除产品「' + p.name + '」?')) return;
await this.fetchJson(this.api('/products/' + p.id), { method: 'DELETE', headers: this.headers() });
ElementPlus.ElMessage.success('已删除');
ElMessage.success('已删除');
this.products = await this.fetchJson(this.api('/products'));
},
@@ -502,7 +582,7 @@
const r = await fetch(url, { method, headers: this.headers(), body: JSON.stringify(this.campaignForm) });
const d = await r.json();
if (!d.ok) throw new Error(d.detail || '操作失败');
ElementPlus.ElMessage.success(this.editingCampaign ? '已更新' : '已创建');
ElMessage.success(this.editingCampaign ? '已更新' : '已创建');
this.showCampaignDialog = false;
this.editingCampaign = null;
this.campaignForm = { name: '', product_id: null, status: 'active', target_engines: [], keywords: [], notes: '' };
@@ -511,18 +591,18 @@
async deleteCampaign(c) {
if (!confirm('确定删除活动「' + c.name + '」?')) return;
await this.fetchJson(this.api('/campaigns/' + c.id), { method: 'DELETE', headers: this.headers() });
ElementPlus.ElMessage.success('已删除');
ElMessage.success('已删除');
this.campaigns = await this.fetchJson(this.api('/campaigns'));
},
// Keywords
async saveKeyword() {
if (!this.selectedCampaign) { ElementPlus.ElMessage.warning('请先选择活动'); return; }
if (!this.selectedCampaign) { ElMessage.warning('请先选择活动'); return; }
this.keywordForm.campaign_id = this.selectedCampaign.id;
const r = await fetch(this.api('/keywords'), { method: 'POST', headers: this.headers(), body: JSON.stringify(this.keywordForm) });
const d = await r.json();
if (!d.ok) throw new Error(d.detail || '添加失败');
ElementPlus.ElMessage.success('已添加');
ElMessage.success('已添加');
this.showKeywordDialog = false;
this.keywordForm = { keyword: '', search_volume: 0, difficulty: 0.5, target_rank: 10 };
this.loadCampaignKeywords(this.selectedCampaign.id);
@@ -530,14 +610,14 @@
async deleteKeyword(kw) {
if (!confirm('确定删除关键词「' + kw.keyword + '」?')) return;
await this.fetchJson(this.api('/keywords/' + kw.id), { method: 'DELETE', headers: this.headers() });
ElementPlus.ElMessage.success('已删除');
ElMessage.success('已删除');
if (this.selectedCampaign) this.loadCampaignKeywords(this.selectedCampaign.id);
},
// Optimization Tasks
async updateTaskStatus(task, status) {
await this.fetchJson(this.api('/optimization-tasks/' + task.id), { method: 'PATCH', headers: this.headers(), body: JSON.stringify({ status: status }) });
ElementPlus.ElMessage.success('已更新');
ElMessage.success('已更新');
this.loadTasks();
},
@@ -549,32 +629,23 @@
window.location.href = '/login.html';
},
},
async mounted() {
this.token = localStorage.getItem('authToken') || '';
if (!this.token) { window.location.href = '/login.html'; return; }
try {
const r = await fetch('/api/auth/me', { headers: { 'Authorization': 'Bearer ' + this.token } });
if (!r.ok) throw new Error('unauthorized');
const d = await r.json();
this.currentUser = d.user || d;
this.isAdmin = this.currentUser.role === 'admin';
window.installUniNav(this.$parent ? null : app).component('uni-nav', window.UniNav);
} catch (e) {
window.location.href = '/login.html';
}
mounted() {
const token = this.token;
if (!token) { window.location.href = '/login.html'; return; }
fetch('/api/auth/me', { headers: { 'Authorization': 'Bearer ' + token } })
.then(function (r) { if (!r.ok) throw new Error('unauthorized'); return r.json(); })
.then(function (d) {
this.currentUser = d.user || d;
this.isAdmin = this.currentUser.role === 'admin';
}.bind(this))
.catch(function () { window.location.href = '/login.html'; });
this.loadTabData();
},
});
// Register Element Plus icons
const { Edit, Delete, Plus, Search, Setting, Monitor, Document, DataBoard, Folder, Menu as IconMenu } = ElementPlusIconsVue || {};
if (ElementPlusIconsVue) {
for (const [key, comp] of Object.entries(ElementPlusIconsVue)) {
app.component(key, comp);
}
}
app.use(ElementPlus);
if (window.installIcons) { window.installIcons(app); }
if (window.installUniNav) { window.installUniNav(app); }
app.mount('#app');
</script>
</body>
+12 -5
View File
@@ -65,8 +65,9 @@
<el-form :model="searchForm" size="small" label-width="70px" @submit.prevent>
<el-row :gutter="12">
<el-col :span="6"><el-form-item label="选题ID"><el-input v-model="searchForm.id" placeholder="如 A07" clearable @input="doSearch"></el-input></el-form-item></el-col>
<el-col :span="10"><el-form-item label="标题"><el-input v-model="searchForm.title" placeholder="关键词" clearable @input="doSearch"></el-input></el-form-item></el-col>
<el-col :span="8"><el-form-item label="领域"><el-input v-model="searchForm.field" placeholder="如 科技前沿" clearable @input="doSearch"></el-input></el-form-item></el-col>
<el-col :span="8"><el-form-item label="标题"><el-input v-model="searchForm.title" placeholder="关键词" clearable @input="doSearch"></el-input></el-form-item></el-col>
<el-col :span="5"><el-form-item label="领域"><el-input v-model="searchForm.field" placeholder="如 科技前沿" clearable @input="doSearch"></el-input></el-form-item></el-col>
<el-col :span="5"><el-form-item label="栏目"><el-select v-model="searchForm.series" clearable placeholder="全部" style="width:100%;" @change="doSearch"><el-option v-for="s in seriesOptions" :key="s" :label="s" :value="s"></el-option></el-select></el-form-item></el-col>
</el-row>
<el-row :gutter="12">
<el-col :span="12"><el-form-item label="创建时间">
@@ -333,7 +334,7 @@ const TopicsApp = {
currentPage: 1, pageSize: 10,
sortField: 'created_at', sortOrder: 'ascending',
showSearch: false,
searchForm: { id: '', title: '', field: '', createdStart: null, createdEnd: null, generatedStart: null, generatedEnd: null, reviewedStart: null, reviewedEnd: null, publishedStart: null, publishedEnd: null },
searchForm: { id: '', title: '', field: '', series: '', createdStart: null, createdEnd: null, generatedStart: null, generatedEnd: null, reviewedStart: null, reviewedEnd: null, publishedStart: null, publishedEnd: null },
createDialogVisible: false, createStep: 1, analyzing: false, saving: false,
fieldOptions: [],
createForm: { raw_input: '', reference_links: '', field_id: null },
@@ -341,9 +342,14 @@ const TopicsApp = {
}
},
computed: {
seriesOptions() {
const s = new Set();
for (const t of this.topics) { if (t.series) s.add(t.series); }
return [...s].sort();
},
searchActive() {
const f = this.searchForm;
return !!(f.id || f.title || f.field || f.createdStart || f.createdEnd || f.generatedStart || f.generatedEnd || f.reviewedStart || f.reviewedEnd || f.publishedStart || f.publishedEnd);
return !!(f.id || f.title || f.field || f.series || f.createdStart || f.createdEnd || f.generatedStart || f.generatedEnd || f.reviewedStart || f.reviewedEnd || f.publishedStart || f.publishedEnd);
},
filteredTopics() {
let list;
@@ -356,11 +362,12 @@ const TopicsApp = {
}
// 搜索过滤
const sf = this.searchForm;
if (sf.id || sf.title || sf.field || sf.createdStart || sf.createdEnd || sf.generatedStart || sf.generatedEnd || sf.reviewedStart || sf.reviewedEnd || sf.publishedStart || sf.publishedEnd) {
if (sf.id || sf.title || sf.field || sf.series || sf.createdStart || sf.createdEnd || sf.generatedStart || sf.generatedEnd || sf.reviewedStart || sf.reviewedEnd || sf.publishedStart || sf.publishedEnd) {
list = list.filter(t => {
if (sf.id && !t.id.toLowerCase().includes(sf.id.toLowerCase())) return false;
if (sf.title && !t.title.toLowerCase().includes(sf.title.toLowerCase())) return false;
if (sf.field && !(t.field || '').toLowerCase().includes(sf.field.toLowerCase())) return false;
if (sf.series && (t.series || '') !== sf.series) return false;
const inRange = (val, start, end) => {
if (!val) return !start && !end;
const d = val.slice(0, 10);
+28 -23
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
"""
内容采集:趋势抓取 → 选题生成 → 存入选题库
收集热点趋势信息,经LLM分析后生成选题建议并存入数据库
内容采集管道:趋势抓取 → 分析 → 选题生成 → 存入选题库
聚焦AI与科技人文领域,从RSS搜索和Web搜索采集信息,经LLM分析后生成选题
"""
import os
@@ -42,14 +42,11 @@ logging.basicConfig(
)
logger = logging.getLogger(__name__)
DEFAULT_CHINA_PAINS = {
"循环消费": "以旧换新流程繁琐、二手商品信任缺失、租赁市场不规范",
"低碳出行": "新能源车充电设施不足、城市规划不支持骑行、通勤距离长",
"干净饮食": "有机食品价格高、真伪难辨、外卖为主的生活方式难以改变",
"零浪费生活": "环保产品溢价高、可持续选择不便、漂绿营销难以分辨",
"绿色家电与节能": "绿色家电初期投入高、节能效果难量化、老旧小区改造难",
"碳普惠": "碳账户普及率低、减排量兑换吸引力不足、公众认知有限",
"环保科技产品": "绿色产品溢价68%难以承受、缺乏统一认证标准、担心漂绿",
"AI与效率": "AI工具选择困难、数据隐私担忧、学习成本高、实际效果难验证"
"AI工具实测": "AI工具选择困难、免费版功能太受限、ChatGPT不如国产好用、学习曲线陡峭、不知道哪些AI工具真正值得付费、看了测评还是不知道怎么用",
"AI前沿资讯": "AI更新太快跟不上、论文太多看不完、不知道哪些是真突破、被营销号带偏、每天刷AI新闻但感觉什么都没学到",
"未来工作方式": "AI裁员焦虑加剧、远程协作效率打折、职业方向看不清、技能更新压力大、35岁学AI来得及吗、转行AI需要什么技能",
"科技人文反思": "AI伦理边界模糊、数据隐私被侵蚀、数字依赖越来越重、人机关系困惑、孩子该不该用AI写作业、AI生成的内容能信吗",
"AI职场应用": "AI替代担心、岗位技能要求变了、职场竞争加剧、缺乏AI实操指导、怎么用AI写周报、怎么用AI做数据分析、AI提示词怎么写才有效",
}
_cached_china_pains = None
@@ -87,22 +84,22 @@ def _get_china_pain(category: str) -> str:
@dataclass
class SustainabilitySource:
"""可持续性信息"""
"""内容采集"""
name: str
type: str # rss, web_search, web, api, local
url: Optional[str] = None # RSS URL 或通用链接
update_frequency: str = "daily"
credibility: str = "medium"
focus: str = "可持续性"
focus: str = "AI与科技"
keywords: Optional[List[str]] = None # 源特定关键词
query: Optional[str] = None # 搜索查询词(w eb_search类型用)
@dataclass
class SustainabilityCase:
"""可持续性案例"""
"""内容案例"""
id: str
country: str
category: str # 子领域:零浪费生活、循环消费
category: str # 类别:AI前沿资讯、AI工具实测
title: str
core_idea: str
data_facts: str
@@ -118,7 +115,7 @@ class SustainabilityCase:
@dataclass
class SustainabilityTopic:
"""可持续性选题"""
"""AI与科技选题"""
id: str
title: str
cases: List[str] # 关联的案例ID列表
@@ -128,7 +125,7 @@ class SustainabilityTopic:
mvp_actions: str
estimated_length: int
priority_score: float
field: str = "可持续生活系统" # 内容领域
field: str = "AI与效率" # 内容领域
format: str = "趋势洞察 + 实操指南" # 内容形式
core_concept: str = "" # 核心理念
audience_pain: str = "" # 受众痛点
@@ -150,7 +147,7 @@ class SustainabilityTopic:
self.platform_urls = {}
class SustainabilityCollector:
"""可持续性内容集器"""
"""AI与科技内容集器"""
def __init__(self):
self.load_config()
@@ -191,7 +188,7 @@ class SustainabilityCollector:
url=s.url or '',
query=s.query or '',
credibility=s.credibility or 'medium',
focus=s.focus or '可持续性',
focus=s.focus or 'AI与科技',
))
logger.info(f"从DB加载 {len(cats)} 个类别, {len(self.sources)} 个信息源")
db.close()
@@ -209,7 +206,7 @@ class SustainabilityCollector:
if 'base_url' in source_info and 'url' not in source_info:
source_info['url'] = source_info.pop('base_url')
source_info.setdefault('update_frequency', 'daily')
source_info.setdefault('focus', '可持续性')
source_info.setdefault('focus', 'AI与科技')
source_info.setdefault('keywords', None)
allowed_keys = {'name', 'type', 'url', 'update_frequency', 'credibility', 'focus', 'keywords', 'query'}
filtered_info = {k: v for k, v in source_info.items() if k in allowed_keys}
@@ -379,7 +376,7 @@ class SustainabilityCollector:
'source_name': source.name
})
logger.info(f"{source.name} 获取到 {len(articles)}可持续性文章")
logger.info(f"{source.name} 获取到 {len(articles)} 篇文章")
return articles
except Exception as e:
@@ -720,8 +717,16 @@ class SustainabilityCollector:
return topic
def map_category_to_field(self, category: str) -> str:
"""案例类别映射到内容领域的字段"""
return "可持续生活系统"
"""采集类别映射到内容领域"""
mapping = {
"AI前沿资讯": "AI与效率",
"AI工具实测": "AI与效率",
"AI趋势分析": "AI与效率",
"AI职场应用": "未来工作方式",
"科技人文反思": "科技人文",
"未来工作方式": "未来工作方式",
}
return mapping.get(category, "AI与效率")
def save_results(self):
"""保存收集结果"""
@@ -851,7 +856,7 @@ class SustainabilityCollector:
def run(self):
"""主运行流程"""
logger.info("开始可持续性内容收集")
logger.info("开始AI与科技内容收集")
existing_titles = self._get_existing_titles()
+266
View File
@@ -0,0 +1,266 @@
#!/usr/bin/env python3
"""
内容聚焦迁移脚本(Phase 2
目标:将数据库从"6领域分散"迁移到"3领域聚焦(AI与效率、科技人文、未来工作方式)"
执行:python3 scripts/migrate_content_focus.py
"""
import sys, json, logging, datetime
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(PROJECT_ROOT))
sys.path.insert(0, str(PROJECT_ROOT / "platform" / "backend"))
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
# 新领域配置(与 initial_data.py 对齐)
NEW_FIELDS = [
{"name": "AI与效率", "icon": "🤖", "color": "#764ba2", "description": "AI工具、AI工作流、效率方法、前沿资讯", "sort_order": 1},
{"name": "科技人文", "icon": "🔬", "color": "#f56c6c", "description": "AI伦理、科技反思、数字生活、人机关系", "sort_order": 2},
{"name": "未来工作方式", "icon": "💼", "color": "#667eea", "description": "远程工作、AI时代职业转型、一人企业", "sort_order": 3},
]
# 旧领域名称 → 新领域名称映射
FIELD_MIGRATION_MAP = {
"可持续生活系统": "AI与效率",
"可持续生活": "AI与效率",
"数字游民": "未来工作方式",
"个人成长": "科技人文",
"个人知识工厂": "AI与效率",
"科技人文交叉": "科技人文",
}
# 新采集分类
NEW_CATEGORIES = [
{"name": "AI前沿资讯", "search_query": "AI 人工智能 大模型 2026 前沿", "description": "AI行业动态、大模型发布、技术突破", "sort_order": 1, "is_active": True},
{"name": "AI工具实测", "search_query": "AI工具 效率提升 AI工作流 2026", "description": "AI工具评测、效率工作流、实操指南", "sort_order": 2, "is_active": True},
{"name": "AI与职场", "search_query": "AI 裁员 职业转型 AI技能 远程工作 2026", "description": "AI对就业影响、职业转型、技能升级", "sort_order": 3, "is_active": True},
{"name": "AI生活化", "search_query": "AI陪伴 AI心理咨询 AI生活助手 2026", "description": "AI心理咨询/生活搭子/AI人格化", "sort_order": 4, "is_active": True},
{"name": "科技人文", "search_query": "AI伦理 数字生活 科技反思 人机关系 2026", "description": "AI伦理/数字生活反思/科技温度", "sort_order": 5, "is_active": True},
]
# 旧分类名称(待停用)
OLD_CATEGORY_NAMES = ["循环消费", "低碳出行", "干净饮食", "零浪费生活", "绿色家电与节能", "碳普惠", "环保科技产品"]
# 新平台 tags
NEW_PLATFORM_TAGS = {
"zhihu": ["科技", "AI", "效率", "职场", "教育", "远程工作", "未来工作", "工具"],
"wechat": ["科技", "AI", "效率", "职场", "教育", "远程工作", "未来工作", "工具"],
"xiaohongshu": ["AI", "效率", "科技", "工具", "职场", "生活", "学习方法"],
}
def migrate():
try:
from app.database import SessionLocal
from app.models import TopicField, Topic, Article, CollectorCategory, CollectorSource, PlatformConfig
except ImportError as e:
logger.error(f"导入失败(确保在项目根目录执行): {e}")
sys.exit(1)
db = SessionLocal()
try:
# ========== 1. 处理 TopicField ==========
logger.info("--- 处理 TopicField ---")
existing_fields = {f.name: f for f in db.query(TopicField).all()}
field_id_map = {} # name → id
for nf in NEW_FIELDS:
if nf["name"] in existing_fields:
f = existing_fields[nf["name"]]
f.icon = nf["icon"]
f.color = nf["color"]
f.description = nf["description"]
f.sort_order = nf["sort_order"]
f.is_active = True
field_id_map[nf["name"]] = f.id
logger.info(f" 更新领域: {nf['name']} (id={f.id})")
else:
f = TopicField(**nf)
db.add(f)
db.flush()
field_id_map[nf["name"]] = f.id
logger.info(f" 创建领域: {nf['name']} (id={f.id})")
# 停用旧领域
for old_name in ["可持续生活系统", "可持续生活", "数字游民", "个人成长", "个人知识工厂"]:
if old_name in existing_fields and old_name not in [nf["name"] for nf in NEW_FIELDS]:
f = existing_fields[old_name]
f.is_active = False
logger.info(f" 停用旧领域: {old_name} (id={f.id})")
db.commit()
# ========== 2. 迁移 Topic ==========
logger.info("--- 迁移 Topic ---")
topics = db.query(Topic).all()
topic_count = len(topics)
migrated_count = 0
for t in topics:
old_field = t.field_name or ""
new_field = None
for old_k, new_v in FIELD_MIGRATION_MAP.items():
if old_k in old_field or old_field in old_k:
new_field = new_v
break
if not new_field and t.field_id:
# 按名称猜测
for old_k, new_v in FIELD_MIGRATION_MAP.items():
if old_k[:4] in old_field or old_field[:4] in old_k:
new_field = new_v
break
if new_field and new_field in field_id_map:
t.field_id = field_id_map[new_field]
t.field_name = new_field
migrated_count += 1
elif t.field_id and t.field_name not in [nf["name"] for nf in NEW_FIELDS]:
# 无法映射的旧领域,统一设为"AI与效率"
if "AI与效率" in field_id_map:
t.field_id = field_id_map["AI与效率"]
t.field_name = "AI与效率"
migrated_count += 1
db.commit()
logger.info(f"{topic_count} 个 Topic,已迁移 {migrated_count}")
# ========== 3. 清理旧 Article ==========
logger.info("--- 清理旧 Article ---")
all_articles = db.query(Article).all()
deleted_articles = []
for a in all_articles:
topic = db.query(Topic).filter(Topic.id == a.topic_id).first()
if topic:
# 只保留 topic 仍然活跃且在新领域内的
tf = db.query(TopicField).filter(TopicField.id == topic.field_id).first()
if tf and tf.is_active and tf.name in [nf["name"] for nf in NEW_FIELDS]:
continue
# 该 Article 关联的 topic 已失效,删除
deleted_articles.append(a.id)
db.delete(a)
db.commit()
logger.info(f" 已删除 {len(deleted_articles)} 篇旧 Article")
# ========== 4. 清理 CollectorCategory ==========
logger.info("--- 清理 CollectorCategory ---")
existing_cats = {c.name: c for c in db.query(CollectorCategory).all()}
# 创建新分类
for nc in NEW_CATEGORIES:
if nc["name"] in existing_cats:
c = existing_cats[nc["name"]]
c.search_query = nc["search_query"]
c.description = nc["description"]
c.sort_order = nc["sort_order"]
c.is_active = True
logger.info(f" 更新采集分类: {nc['name']}")
else:
db.add(CollectorCategory(**nc))
logger.info(f" 创建采集分类: {nc['name']}")
# 停用旧分类
for old_name in OLD_CATEGORY_NAMES:
if old_name in existing_cats:
c = existing_cats[old_name]
c.is_active = False
logger.info(f" 停用旧采集分类: {old_name}")
# 删除旧 '可持续生活' 和 '可持续发展' 变体
for cname, cobj in existing_cats.items():
if cname not in [nc["name"] for nc in NEW_CATEGORIES] and cname not in OLD_CATEGORY_NAMES:
if any(kw in cname for kw in ["可持续", "环保", "绿色", "低碳", "零浪费", "循环"]):
cobj.is_active = False
logger.info(f" 停用旧采集分类: {cname}")
db.commit()
# ========== 5. 清理 CollectorSource ==========
logger.info("--- 清理 CollectorSource ---")
all_sources = db.query(CollectorSource).all()
deactivated_sources = 0
for s in all_sources:
# 停用非 AI/科技 类采集源
if s.focus and any(kw in s.focus for kw in ["可持续", "环保", "绿色", "低碳", "零浪费"]):
s.is_active = False
deactivated_sources += 1
# 旧 URL 不再可访问的源
if s.url and any(domain in s.url for domain in ["greenbiz.com", "sustainablebrands.com", "treehugger.com"]):
s.is_active = False
deactivated_sources += 1
# 检查 category_id 是否对应已停用的分类
if s.category_id:
cat = db.query(CollectorCategory).filter(CollectorCategory.id == s.category_id).first()
if cat and not cat.is_active:
s.is_active = False
deactivated_sources += 1
# 新增源(由 initial_data.py 的补充逻辑处理)
for new_src in [
{"name": "AI前沿搜索", "source_type": "web_search", "query": "AI 人工智能 大模型 前沿 2026", "credibility": "medium", "focus": "AI前沿资讯", "sort_order": 1, "is_active": True},
{"name": "AI工具搜索", "source_type": "web_search", "query": "AI工具 效率提升 AI工作流 2026", "credibility": "medium", "focus": "AI工具实测", "sort_order": 2, "is_active": True},
]:
existing = db.query(CollectorSource).filter(CollectorSource.name == new_src["name"]).first()
if not existing:
db.add(CollectorSource(**new_src))
logger.info(f" 创建采集源: {new_src['name']}")
db.commit()
logger.info(f" 已停用 {deactivated_sources} 个旧采集源")
# ========== 6. 更新 PlatformConfig tags ==========
logger.info("--- 更新 PlatformConfig tags ---")
for p in db.query(PlatformConfig).all():
if p.platform in NEW_PLATFORM_TAGS:
rules = p.compliance_rules or {}
if isinstance(rules, dict) and "allowed_tags" in rules:
rules["allowed_tags"] = NEW_PLATFORM_TAGS[p.platform]
p.compliance_rules = rules
logger.info(f" 更新平台标签: {p.platform}")
db.commit()
# ========== 7. 更新 TrendFieldMapping ==========
logger.info("--- 更新 TrendFieldMapping ---")
from app.models import TrendFieldMapping
new_mappings = [
{"trend_keyword": "AI工具", "field_name": "AI与效率", "sort_order": 1},
{"trend_keyword": "AI创作", "field_name": "AI与效率", "sort_order": 2},
{"trend_keyword": "AI职场", "field_name": "AI与效率", "sort_order": 3},
{"trend_keyword": "效率工具", "field_name": "AI与效率", "sort_order": 4},
{"trend_keyword": "未来工作", "field_name": "未来工作方式", "sort_order": 5},
{"trend_keyword": "远程工作", "field_name": "未来工作方式", "sort_order": 6},
{"trend_keyword": "AI就业", "field_name": "未来工作方式", "sort_order": 7},
{"trend_keyword": "科技人文", "field_name": "科技人文", "sort_order": 8},
{"trend_keyword": "数字生活", "field_name": "科技人文", "sort_order": 9},
{"trend_keyword": "AI伦理", "field_name": "科技人文", "sort_order": 10},
{"trend_keyword": "AI情感", "field_name": "AI与效率", "sort_order": 11},
]
existing_mappings = {m.trend_keyword: m for m in db.query(TrendFieldMapping).all()}
# 标记旧的映射为停用
for keyword, mapping in existing_mappings.items():
if keyword not in [nm["trend_keyword"] for nm in new_mappings]:
mapping.is_active = False
# 创建/更新新映射
for nm in new_mappings:
if nm["trend_keyword"] in existing_mappings:
m = existing_mappings[nm["trend_keyword"]]
m.field_name = nm["field_name"]
m.sort_order = nm["sort_order"]
m.is_active = True
else:
db.add(TrendFieldMapping(**nm))
db.commit()
logger.info(f" 已同步 {len(new_mappings)} 条 TrendFieldMapping")
logger.info("=" * 50)
logger.info("✅ DB 迁移完成")
logger.info("=" * 50)
except Exception as e:
import traceback
traceback.print_exc()
logger.error(f"迁移失败: {e}")
db.rollback()
sys.exit(1)
finally:
db.close()
if __name__ == "__main__":
migrate()
+7 -7
View File
@@ -45,32 +45,32 @@ _PROMPT_DEFAULTS = {
"variables": ["gaps"],
},
"section_expansion_zhihu": {
"content": "写「{topic_title}」文章中「{section_title}」这一节。\n\n今天:{date}\n笔记要点:\n{content}\n\n写400-800字,3-6段。每段围绕一个论点展开:先摆事实/数据,再分析原因,最后说清这跟读者有什么关系。\n\n注意:\n- 每个论点必须具体数据或案例(至少一个),不要空谈。引用研究、报告或行业事件\n- 用「你」称呼读者,像是在知乎回答里跟人讨论\n- 从具体问题切入,不要以「引言/总结/核心观点」这类标签开头\n- 回答「所以呢」——这条信息对读者有什么用\n- 避免「首先其次最后」「总的来说」「综上所述」「值得注意的是」这些表达\n- 来源放在文末括号内\n- 纯段落,不要列表/标题/序号标记",
"content": "写「{topic_title}」文章中「{section_title}」这一节。\n\n今天:{date}\n笔记要点:\n{content}\n\n写400-800字,3-6段。每段围绕一个论点展开:先摆独家数据/一手案例,再分析深层原因,最后说清这跟读者有什么关系。\n\n注意:\n- 每个论点必须具体数据或独家案例支撑——自采数据、一手实验对比、行业报告引用优先。不要只用公开信息\n- 用「你」称呼读者,像是在知乎回答里跟人讨论\n- 从具体问题或反直觉现象切入,不要以「引言/总结/核心观点」这类标签开头\n- 不只是介绍这个工具/技术,而是探讨它如何改变了人的行为方式或认知\n- 回答「所以呢」——这条信息对读者有什么用,有什么可操作的启发\n- 如果这个话题有争议点,不要回避,亮出你的立场\n- 避免「首先其次最后」「总的来说」「综上所述」「值得注意的是」这些表达\n- 来源放在文末括号内\n- 纯段落,不要列表/标题/序号标记",
"temperature": 0.78, "max_tokens": 4000,
"variables": ["topic_title", "section_title", "date", "content"],
},
"section_expansion_wechat": {
"content": "写「{topic_title}」文章中「{section_title}」这一节。\n\n今天:{date}\n笔记要点:\n{content}\n\n写300-500字,用「我」的口吻叙述——像在跟朋友聊天,不是写文章\n\n注意:\n- 从个人经历或感受切入,不要讲道理\n- 每个观点背后要有一个具体故事或观察\n- 段与段之间有情绪的起承转合,不是逻辑推理\n- 读起来像一个人在说话,而不是一篇文章在论述\n- 避免「首先其次最后」「总的来说」「综上所述」「值得注意的是」这些套路\n- 纯段落,不要标题/列表/序号标记",
"content": "写「{topic_title}」文章中「{section_title}」这一节。\n\n今天:{date}\n笔记要点:\n{content}\n\n写300-500字,用「我」的口吻写一个真实的困惑、顿悟或观察——不是测评工具,而是记录这个技术/趋势如何改变了你的一种习惯、认知或生活方式\n\n注意:\n- 从个人经历或感受切入,不是介绍工具功能,而是讲这个工具让你想到了什么、改变了什么\n- 每个观点背后要有一个具体故事或观察,虚实结合\n- 段与段之间有情绪的起承转合,不是逻辑推理\n- 读起来像一个人在深夜和朋友聊天时的反思,不是一篇产品测评\n- 可以有困惑和不确定——真实比正确重要\n- 避免「首先其次最后」「总的来说」「综上所述」「值得注意的是」这些套路\n- 纯段落,不要标题/列表/序号标记",
"temperature": 0.8, "max_tokens": 3000,
"variables": ["topic_title", "section_title", "date", "content"],
},
"section_expansion_xiaohongshu": {
"content": "写「{topic_title}」笔记中「{section_title}」这一节。\n\n今天:{date}\n笔记要点:\n{content}\n\n写100-200字,1-3小段。每段1-2句,直接给干货。\n\n注意:\n- 直接给结论或方法,不要铺垫\n- 可以用emoji(1个/段,不要堆砌)\n- 像博主在分享亲测有效的经验\n- 不要讲道理,只讲「是什么」和「怎么做」\n- 用「你」或直接省略主语\n- 避免「首先其次最后」「总的来说」「综上所述」「值得注意的是」这些套路\n- 纯段落,不要列表/标题/序号标记",
"content": "写「{topic_title}」笔记中「{section_title}」这一节。\n\n今天:{date}\n笔记要点:\n{content}\n\n写100-200字,1-3小段。每段1-2句,直接给干货。\n\n注意:\n- 直接给结论或方法,不要铺垫\n- 每个结论后面跟一个具体数据/对比/结果(亲测可用才有说服力)\n- 可以用emoji(1个/段,不要堆砌)\n- 像博主在分享亲测有效的经验,有真实的「我试过」感\n- 不要讲道理,只讲「是什么」和「怎么做」\n- 用「你」或直接省略主语\n- 避免「首先其次最后」「总的来说」「综上所述」「值得注意的是」这些套路\n- 纯段落,不要列表/标题/序号标记",
"temperature": 0.75, "max_tokens": 2000,
"variables": ["topic_title", "section_title", "date", "content"],
},
"title_optimize_zhihu": {
"content": "你是知乎老用户,经常上热榜。给这篇文章起3个标题候选:\n\n文章主题:{title}\n核心观点:{core}\n受众痛点:{pain}\n领域:{field}\n\n感觉像在跟人推荐一篇值得辩论的文。信息要密、20字内、有明确立场、让人想点进来说两句。不要「如何」开头。\n\n每行一个,不要编号。",
"content": "你是知乎老用户,经常上热榜。给这篇文章起3个标题候选:\n\n文章主题:{title}\n核心观点:{core}\n受众痛点:{pain}\n领域:{field}\n\n感觉像在跟人推荐一篇值得辩论的观点帖,不是在推荐一篇工具文。信息要密、20字内、有明确立场、有观点交锋感、让人想点进来说两句。不要「如何」开头。如果话题有争议性,在标题里亮出你的立场。\n\n每行一个,不要编号。",
"temperature": 0.8, "max_tokens": 1500,
"variables": ["title", "core", "pain", "field"],
},
"title_optimize_wechat": {
"content": "你是公众号编辑。这篇文章面向{field}领域的读者,帮起3个标题:\n\n文章主题:{title}\n核心观点:{core}\n\n要有身份代入感(打工人/30岁+/普通上班族)、有情绪钩子(焦虑/反常识/后悔)、含微信搜索关键词。15-25字,口语化,越具体越好。参考这种风格:「用了AI效率反而更低了?73%的人掉进了这个坑\n\n每行一个,不要编号。",
"content": "你是公众号编辑,擅长写有温度、有人味的文章。这篇文章面向{field}领域的读者,帮起3个标题:\n\n文章主题:{title}\n核心观点:{core}\n\n标题方向是「科技时代的个人叙事」——不是推荐工具,而是分享一个真实的人与技术之间的故事。要有身份代入感(打工人/30岁+/普通上班族/家长)、有情绪钩子(困惑/反常识/顿悟/后悔)、含微信搜索关键词。15-25字,口语化,越具体越好。参考:「AI帮我写周报的第3个月,我终于发现哪里不对了\n\n每行一个,不要编号。",
"temperature": 0.8, "max_tokens": 1500,
"variables": ["title", "core", "field"],
},
"title_optimize_xhs": {
"content": "你是小红书博主。给这篇笔记起3个标题:\n\n笔记主题:{title}\n核心:{core}\n\n每条18字以内,有具体场景和结果感。可以加1个精确emoji(不要🔥💥❌❓)。参考:「用了两年AI工具,推荐这5个就够了」这种风格。\n\n每行一个,不要编号。",
"content": "你是小红书博主,擅长写有数据、有结果感的干货笔记。给这篇笔记起3个标题:\n\n笔记主题:{title}\n核心:{core}\n\n每条18字以内,有具体场景和结果感(含数字/时间/效果)。可以加1个精确emoji(不要🔥💥❌❓)。参考:「两年换了8个AI工具,最后只留这3个」这种风格。\n\n每行一个,不要编号。",
"temperature": 0.8, "max_tokens": 1500,
"variables": ["title", "core"],
},
@@ -95,7 +95,7 @@ _PROMPT_DEFAULTS = {
"variables": ["html"],
},
"sources_optimization": {
"content": "你是一个内容策略分析师。分析当前中文互联网可持续生活领域的真实热点,与以下配置进行对比。\n\n当前配置的类别({n}个):\n{cat_names}\n\n当前配置的信息源({n2}个):\n{src_summary}\n\n请完成:\n1. 评估每个类别是否仍符合{year}年中国市场真实热点(保留/淘汰/合并)\n2. 评估每个信息源是否可在国内正常访问\n3. 建议新增的类别(最多2条)\n4. 建议新增的信息源搜索词(最多3条,含具体搜索词)\n\n输出 JSON\n{\n \"category_assessment\": [{\"name\": \"...\", \"status\": \"保留/淘汰/合并\", \"reason\": \"...\"}],\n \"source_assessment\": [{\"source\": \"...\", \"accessible\": true/false, \"note\": \"...\"}],\n \"new_categories\": [{\"name\": \"...\", \"reason\": \"...\"}],\n \"new_search_queries\": [{\"query\": \"...\", \"target\": \"...\"}]\n}\n只输出JSON。",
"content": "你是一个内容策略分析师。分析当前中文互联网AI与科技人文领域的真实热点,与以下配置进行对比。\n\n当前配置的类别({n}个):\n{cat_names}\n\n当前配置的信息源({n2}个):\n{src_summary}\n\n请完成:\n1. 评估每个类别是否仍符合{year}年中国市场真实热点(保留/淘汰/合并)\n2. 评估每个信息源是否可在国内正常访问\n3. 建议新增的类别(最多2条)\n4. 建议新增的信息源搜索词(最多3条,含具体搜索词)\n\n输出 JSON\n{\n \"category_assessment\": [{\"name\": \"...\", \"status\": \"保留/淘汰/合并\", \"reason\": \"...\"}],\n \"source_assessment\": [{\"source\": \"...\", \"accessible\": true/false, \"note\": \"...\"}],\n \"new_categories\": [{\"name\": \"...\", \"reason\": \"...\"}],\n \"new_search_queries\": [{\"query\": \"...\", \"target\": \"...\"}]\n}\n只输出JSON。",
"temperature": 0.5, "max_tokens": 3000,
"variables": ["n", "cat_names", "n2", "src_summary", "year"],
},
+16 -9
View File
@@ -24,18 +24,25 @@ TODAY = __import__('datetime').datetime.now().strftime("%Y-%m-%d")
logger = logging.getLogger(__name__)
DEFAULT_TREND_DOMAIN_MAP = {
"远程工作": "未来工作方式",
"AI工具": "AI与效率",
"可持续生活": "可持续生活系统",
"知识管理": "个人知识工厂",
"数字生活": "科技人文交叉",
"科技人文": "科技人文交叉",
"个人成长": "个人成长",
"副业": "个人成长",
"AI创作": "AI与效率",
"未来工作": "未来工作方式",
"AI职场": "AI与效率",
"效率工具": "AI与效率",
"家庭教育": "科技人文交叉",
"Prompt": "AI与效率",
"提示词": "AI与效率",
"AI编程": "AI与效率",
"AI写作": "AI与效率",
"未来工作": "未来工作方式",
"远程工作": "未来工作方式",
"AI就业": "未来工作方式",
"一人企业": "未来工作方式",
"副业": "未来工作方式",
"科技人文": "科技人文",
"数字生活": "科技人文",
"AI伦理": "科技人文",
"AI情感": "科技人文",
"数据隐私": "科技人文",
"AI教育": "科技人文",
}
_cached_trend_domain_map = None