fix: 今日新增筛选统计不准 + LLM提示词动态当前日期 + 微信配图按选题生成
topics.html:
- 今日新增筛选时全量拉取 allTopics 用于保持 stats 统计正确,todayTopics
存储服务端日期过滤结果
- filteredTopics 对 'today' 返回 todayTopics,不按不存在的 status 过滤
writer.py/research.py/outline.py:
- 所有 LLM 提示词注入今天的动态年月日(datetime.now)
- 禁用过时数据的年份改为动态 {当前年-1}-{当前年}
- 每个论点必须配真实最新案例+数据来源
writer.py WeChat 配图:
- 从 null placeholder 改为动态 SVG,展示选题标题+领域
- 标题自动换行(24字/行),附蓝色装饰条 + 渐变背景
This commit is contained in:
+6
-3
@@ -51,8 +51,11 @@ class Outliner:
|
||||
cases_summary = self.research_notes[:2000] if self.research_notes else "暂无研究笔记"
|
||||
|
||||
if HAVE_LLM:
|
||||
_now = datetime.datetime.now()
|
||||
prompt = f"""你是一个资深内容编辑,擅长设计读者爱看+搜索引擎友好+平台愿意推荐+有市场传播力的文章结构。
|
||||
|
||||
⚠️ 今天日期:{_now.strftime('%Y年%m月%d日')}。当前年份:{_now.year}年。
|
||||
|
||||
## 选题信息
|
||||
标题:{title}
|
||||
领域:{field}
|
||||
@@ -72,9 +75,9 @@ class Outliner:
|
||||
- 开头要有"钩子"(hook)抓住读者,结尾要有可转发/收藏的总结
|
||||
|
||||
### 数据与热点
|
||||
- **全文使用2025-2026年最新数据**,禁用过时数据
|
||||
- 每个观点尽量配最新的国内外热点事件/数据/政策来佐证
|
||||
- 体现当前行业正在讨论的核心议题
|
||||
- **全文必须使用{_now.year-1}-{_now.year}年最新数据**,禁用一切过时数据
|
||||
- 每个观点必须配最新的国内外热点事件/数据/政策来佐证
|
||||
- 体现当前行业正在讨论的核心议题,拒绝泛泛而谈
|
||||
|
||||
### 独特风格
|
||||
- 有自己的判断和立场,不是搬运观点
|
||||
|
||||
+4
-1
@@ -75,8 +75,11 @@ class Researcher:
|
||||
# 获取实时搜索数据作为 LLM 参考
|
||||
search_data = enrich_topic_research(self.topic)
|
||||
search_section = f"\n## 实时搜索结果\n{search_data}\n" if search_data else ""
|
||||
_now = datetime.datetime.now()
|
||||
prompt = f"""你是一个行业研究员+内容策略师,擅长从案例中发现真洞察+抢占热点的敏锐嗅觉,能判断什么内容对真实读者最有价值且正被市场热议。
|
||||
|
||||
⚠️ 今天日期:{_now.strftime('%Y年%m月%d日')}。当前年份:{_now.year}年。
|
||||
|
||||
基于以下选题和相关案例,写出能支撑文章核心观点、对读者真正有用的研究发现。
|
||||
|
||||
## 选题
|
||||
@@ -90,7 +93,7 @@ class Researcher:
|
||||
{cases_text}
|
||||
|
||||
## 输出要求(按顺序):
|
||||
1. **国内外最新热点关联**:当前该领域正在讨论什么、国内外哪些事件/政策/数据在发酵、为什么现在这个话题值得关注。**所有数据必须是2025-2026年最新数据**
|
||||
1. **国内外最新热点关联**:当前该领域正在讨论什么、国内外哪些事件/政策/数据在发酵、为什么现在这个话题值得关注。**所有数据必须是{_now.year-1}-{_now.year}年最新数据,禁用一切过时数据**
|
||||
2. **核心发现**:2-3个真正有价值的洞察。每条需包含这个发现对读者意味着什么,以及支撑数据(附数据来源)
|
||||
3. **独特观点储备**:哪些角度别人没写过、可以讲出差异化?提供至少一个反向/冷门视角
|
||||
4. **SEO关键词建议**:重点布局哪些搜索词(3-5个,含1-2个长尾词),以及各平台近期搜索上升趋势
|
||||
|
||||
+30
-6
@@ -107,14 +107,17 @@ class Writer:
|
||||
logger.info(f"使用 LLM 扩写章节: {section['title']}")
|
||||
prompt = f"""你是一个真人写作者+行业观察者,正在写一篇关于「{self.topic['title']}」的文章。现在写「{section['title']}」这一节。
|
||||
|
||||
⚠️ 今天日期:{datetime.datetime.now().strftime('%Y年%m月%d日')}。当前年份:{datetime.datetime.now().year}年。
|
||||
|
||||
笔记要点:
|
||||
{content}
|
||||
|
||||
要求(逐条对照,每一条都不能跳过):
|
||||
### 热点与时效
|
||||
- **引用2025-2026年最新数据/事件/政策/行业报告**,禁用过时数据
|
||||
- 体现当前国内外在讨论什么、最新的趋势变化
|
||||
- 每个论点尽量配一个真实发生的最新案例
|
||||
- **必须引用{datetime.datetime.now().year-1}-{datetime.datetime.now().year}年最新数据/事件/政策/行业报告**,禁用一切过时数据
|
||||
- 体现当前国内外正在讨论什么、最新的趋势变化
|
||||
- 每个论点必须配一个真实发生的最新案例(附数据来源),严禁使用虚构数据
|
||||
- 写作前先确认:这个数据和案例是否是最近{datetime.datetime.now().year-1}-{datetime.datetime.now().year}年的?
|
||||
|
||||
### 独特观点
|
||||
- 有自己的判断和立场,拒绝"车轱辘话"和"正确废话"
|
||||
@@ -371,12 +374,33 @@ class Writer:
|
||||
html = template.replace("{{TITLE}}", title).replace("{{DATE}}", TODAY).replace("{{GEN_TIME}}", GEN_TIME)
|
||||
html_content = _md_parser(adapted)
|
||||
|
||||
# WeChat: insert image placeholder at start of body
|
||||
# WeChat: insert topic-relevant image at start of body
|
||||
if platform == "wechat":
|
||||
img_svg = '<svg xmlns="http://www.w3.org/2000/svg" width="1080" height="600" viewBox="0 0 1080 600" style="width:100%;max-width:1080px;border-radius:8px;background:#f0f2f5"><rect width="1080" height="600" fill="#f0f2f5"/><g transform="translate(540,260)" text-anchor="middle" font-family="-apple-system,BlinkMacSystemFont,sans-serif"><circle cx="0" cy="-20" r="40" fill="#d0d5dd"/><path d="M-25,10 L-10,10 L-5,0 L5,0 L10,10 L25,10 L25,60 L-25,60 Z" fill="#d0d5dd"/><circle cx="0" cy="10" r="15" fill="#fff"/><text y="80" font-size="18" fill="#98a2b3">点击替换配图(建议 1080×600)</text></g></svg>'
|
||||
import base64
|
||||
topic_title = self.topic.get('title', title)
|
||||
topic_field = self.topic.get('field', '')
|
||||
safe_title = topic_title.replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"').replace("'", ''')
|
||||
safe_field = topic_field.replace('&', '&').replace('<', '<').replace('>', '>')
|
||||
lines = []
|
||||
chars_per_line = 24
|
||||
for i in range(0, len(safe_title), chars_per_line):
|
||||
lines.append(safe_title[i:i+chars_per_line])
|
||||
if not lines:
|
||||
lines = ['配图']
|
||||
line_y = 220 - (len(lines) - 1) * 20
|
||||
title_texts = ''.join(f'<text x="540" y="{line_y + i*55}" font-size="36" fill="#1a1a1a" font-weight="bold">{l}</text>' for i, l in enumerate(lines))
|
||||
field_text = f'<text x="540" y="{line_y + len(lines)*55 + 30}" font-size="20" fill="#98a2b3">{safe_field}</text>' if safe_field else ''
|
||||
img_svg = f'''<svg xmlns="http://www.w3.org/2000/svg" width="1080" height="600" viewBox="0 0 1080 600" style="width:100%;max-width:1080px;border-radius:8px;background:linear-gradient(135deg,#f0f4ff,#e8f0fe)">
|
||||
<rect width="1080" height="600" fill="url(#bg)"/>
|
||||
<defs><linearGradient id="bg" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color:#f0f4ff"/><stop offset="100%" style="stop-color:#e8f0fe"/></linearGradient></defs>
|
||||
<g transform="translate(540,300)" text-anchor="middle" font-family="-apple-system,BlinkMacSystemFont,Helvetica Neue,PingFang SC,Microsoft YaHei,sans-serif">
|
||||
<rect x="-60" y="-100" width="120" height="4" rx="2" fill="#409eff"/>
|
||||
{title_texts}
|
||||
{field_text}
|
||||
<text y="100" font-size="14" fill="#c0c4cc">宇之然 · 配图(可替换)</text>
|
||||
</g></svg>'''
|
||||
img_b64 = 'data:image/svg+xml;base64,' + base64.b64encode(img_svg.encode('utf-8')).decode('ascii')
|
||||
img_tag = f'<p><img src="{img_b64}" alt="配图" style="width:100%;max-width:1080px;border-radius:8px;"></p>\n'
|
||||
img_tag = f'<p><img src="{img_b64}" alt="{safe_title}" style="width:100%;max-width:1080px;border-radius:8px;"></p>\n'
|
||||
h1_end = html_content.find('</h1>')
|
||||
if h1_end != -1:
|
||||
html_content = html_content[:h1_end + 5] + '\n' + img_tag + html_content[h1_end + 5:]
|
||||
|
||||
Reference in New Issue
Block a user