PyWxDump/test.py
2025-05-01 18:14:28 +08:00

955 lines
38 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import json
import re
def main(json_data):
# 加载模板
html = """
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>[群/用户名称]日报 - [日期]</title>
<style>
/* 严格定义的CSS样式确保风格一致性 */
:root {
--bg-primary: #0f0e17;
--bg-secondary: #1a1925;
--bg-tertiary: #252336;
--text-primary: #fffffe;
--text-secondary: #a7a9be;
--accent-primary: #ff8906;
--accent-secondary: #f25f4c;
--accent-tertiary: #e53170;
--accent-blue: #3da9fc;
--accent-purple: #7209b7;
--accent-cyan: #00b4d8;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'SF Pro Display', 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', sans-serif;
background-color: var(--bg-primary);
color: var(--text-primary);
line-height: 1.6;
font-size: 16px;
width: 1200px;
margin: 0 auto;
padding: 20px;
}
header {
text-align: center;
padding: 30px 0;
background-color: var(--bg-secondary);
margin-bottom: 30px;
}
h1 {
font-size: 36px;
font-weight: 700;
color: var(--accent-primary);
margin-bottom: 10px;
}
.date {
font-size: 18px;
color: var(--text-secondary);
margin-bottom: 20px;
}
.meta-info {
display: flex;
justify-content: center;
gap: 20px;
}
.meta-info span {
background-color: var(--bg-tertiary);
padding: 5px 15px;
border-radius: 20px;
font-size: 14px;
}
section {
background-color: var(--bg-secondary);
margin-bottom: 30px;
padding: 25px;
}
h2 {
font-size: 28px;
font-weight: 600;
color: var(--accent-blue);
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 2px solid var(--accent-blue);
}
h3 {
font-size: 22px;
font-weight: 600;
color: var(--accent-primary);
margin: 15px 0 10px 0;
}
h4 {
font-size: 18px;
font-weight: 600;
color: var(--accent-secondary);
margin: 12px 0 8px 0;
}
p {
margin-bottom: 15px;
}
ul, ol {
margin-left: 20px;
margin-bottom: 15px;
}
li {
margin-bottom: 5px;
}
a {
color: var(--accent-blue);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* 卡片容器样式 */
.topics-container, .tutorials-container, .messages-container,
.dialogues-container, .qa-container, .participants-container {
display: grid;
grid-template-columns: 1fr;
gap: 20px;
}
/* 卡片样式 */
.topic-card, .tutorial-card, .message-card,
.dialogue-card, .qa-card, .participant-item, .night-owl-item {
background-color: var(--bg-tertiary);
padding: 20px;
}
/* 话题卡片 */
.topic-category {
display: inline-block;
background-color: var(--accent-blue);
color: var(--text-primary);
padding: 3px 10px;
border-radius: 15px;
font-size: 14px;
margin-bottom: 10px;
}
.topic-keywords {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin: 10px 0;
}
.keyword {
background-color: rgba(61, 169, 252, 0.2);
padding: 3px 10px;
border-radius: 12px;
font-size: 14px;
}
.topic-mentions {
color: var(--accent-cyan);
font-weight: 600;
}
/* 教程卡片 */
.tutorial-type {
display: inline-block;
background-color: var(--accent-secondary);
color: var(--text-primary);
padding: 3px 10px;
border-radius: 15px;
font-size: 14px;
margin-bottom: 10px;
}
.tutorial-meta {
color: var(--text-secondary);
margin-bottom: 10px;
font-size: 14px;
}
.tutorial-category {
margin-top: 10px;
font-style: italic;
color: var(--text-secondary);
}
/* 消息卡片 */
.message-meta {
margin-bottom: 10px;
}
.message-meta span {
margin-right: 15px;
font-size: 14px;
}
.message-type {
background-color: var(--accent-tertiary);
color: var(--text-primary);
padding: 3px 10px;
border-radius: 15px;
}
.priority {
padding: 3px 10px;
border-radius: 15px;
}
.priority-high {
background-color: var(--accent-secondary);
}
.priority-medium {
background-color: var(--accent-primary);
}
.priority-low {
background-color: var(--accent-blue);
}
/* 对话卡片 */
.dialogue-type {
display: inline-block;
background-color: var(--accent-purple);
color: var(--text-primary);
padding: 3px 10px;
border-radius: 15px;
font-size: 14px;
margin-bottom: 10px;
}
.dialogue-content {
background-color: rgba(255, 255, 255, 0.05);
padding: 15px;
margin-bottom: 15px;
}
.dialogue-highlight {
font-style: italic;
color: var(--accent-primary);
margin: 10px 0;
font-weight: 600;
}
/* 问答卡片 */
.question {
margin-bottom: 15px;
}
.question-meta, .answer-meta {
color: var(--text-secondary);
margin-bottom: 5px;
font-size: 14px;
}
.question-tags {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 10px;
}
.tag {
background-color: rgba(114, 9, 183, 0.2);
padding: 3px 10px;
border-radius: 12px;
font-size: 14px;
}
.answer {
background-color: rgba(255, 255, 255, 0.05);
padding: 15px;
margin-top: 10px;
}
.accepted-badge {
background-color: var(--accent-primary);
color: var(--text-primary);
padding: 3px 10px;
border-radius: 15px;
font-size: 14px;
}
/* 热度图 */
.heatmap-container {
display: grid;
grid-template-columns: 1fr;
gap: 15px;
}
.heat-topic {
font-weight: 600;
margin-bottom: 5px;
}
.heat-bar {
height: 20px;
background-color: rgba(255, 255, 255, 0.1);
margin: 5px 0;
border-radius: 10px;
overflow: hidden;
}
.heat-fill {
height: 100%;
border-radius: 10px;
}
/* 话唠榜 */
.participant-rank {
font-size: 28px;
font-weight: 700;
color: var(--accent-primary);
margin-right: 15px;
float: left;
}
.participant-name {
font-weight: 600;
font-size: 18px;
margin-bottom: 5px;
}
.participant-count {
color: var(--accent-cyan);
margin-bottom: 10px;
}
.participant-characteristics, .participant-words {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin-top: 10px;
}
.characteristic {
background-color: rgba(242, 95, 76, 0.2);
padding: 3px 10px;
border-radius: 12px;
font-size: 14px;
}
.word {
background-color: rgba(229, 49, 112, 0.2);
padding: 3px 10px;
border-radius: 12px;
font-size: 14px;
}
/* 熬夜冠军 */
.night-owl-item {
background: linear-gradient(135deg, #0f0e17 0%, #192064 100%);
padding: 20px;
display: flex;
align-items: center;
}
.owl-crown {
font-size: 40px;
margin-right: 20px;
}
.owl-name {
font-weight: 600;
font-size: 18px;
margin-bottom: 5px;
}
.owl-title {
color: var(--accent-primary);
font-style: italic;
margin-bottom: 10px;
}
.owl-time, .owl-messages {
color: var(--text-secondary);
margin-bottom: 5px;
}
.owl-note {
font-size: 14px;
color: var(--text-secondary);
margin-top: 10px;
font-style: italic;
}
/* 词云 - 云朵样式 */
.cloud-container {
position: relative;
margin: 0 auto;
padding: 20px 0;
}
.cloud-wordcloud {
position: relative;
width: 600px;
height: 400px;
margin: 0 auto;
background-color: var(--bg-tertiary);
border-radius: 50%;
box-shadow:
40px 40px 0 -5px var(--bg-tertiary),
80px 10px 0 -10px var(--bg-tertiary),
110px 35px 0 -5px var(--bg-tertiary),
-40px 50px 0 -8px var(--bg-tertiary),
-70px 20px 0 -10px var(--bg-tertiary);
overflow: visible;
}
.cloud-word {
position: absolute;
transform-origin: center;
text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
transition: all 0.3s ease;
}
.cloud-word:hover {
transform: scale(1.1);
z-index: 10;
}
.cloud-legend {
margin-top: 60px;
display: flex;
justify-content: center;
gap: 30px;
}
.legend-item {
display: flex;
align-items: center;
gap: 10px;
}
.legend-color {
width: 20px;
height: 20px;
border-radius: 50%;
}
/* 底部 */
footer {
text-align: center;
padding: 20px 0;
margin-top: 50px;
background-color: var(--bg-secondary);
color: var(--text-secondary);
font-size: 14px;
}
footer p {
margin: 5px 0;
}
.disclaimer {
margin-top: 15px;
font-style: italic;
}
/* 新增头像相关样式 */
.user-avatar {
width: 50px;
height: 50px;
border-radius: 50%;
object-fit: cover;
transition: transform 0.3s ease;
position: relative;
cursor: pointer;
border: 2px solid var(--accent-primary);
}
/* 头像悬停效果 */
.user-avatar:hover {
transform: scale(1.1) rotate(5deg);
z-index: 100;
}
/* 头像tooltip */
.avatar-tooltip {
visibility: hidden;
background-color: var(--bg-tertiary);
color: var(--text-primary);
text-align: center;
padding: 5px 10px;
border-radius: 6px;
position: absolute;
z-index: 1000;
bottom: 125%;
left: 50%;
transform: translateX(-50%);
white-space: nowrap;
opacity: 0;
transition: opacity 0.3s;
font-size: 14px;
box-shadow: 0 3px 10px rgba(0,0,0,0.2);
}
.user-avatar:hover .avatar-tooltip {
visibility: visible;
opacity: 1;
}
/* 热度用户专区 */
.hot-users {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
gap: 20px;
margin-top: 20px;
}
.hot-user-item {
position: relative;
text-align: center;
}
/* 皇冠标识 */
.hot-crown {
position: absolute;
top: -10px;
right: -5px;
font-size: 24px;
color: #ffd700;
filter: drop-shadow(0 2px 2px rgba(0,0,0,0.3));
}
</style>
</head>
<body>
<header>
<h1>[群/用户名称]日报</h1>
<p class="date">[日期]</p>
<div class="meta-info">
<span>总消息数:[数量]</span>
<span>活跃用户:[数量]</span>
<span>时间范围:[时间范围]</span>
</div>
</header>
<!-- 1. 今日讨论热点 -->
<section class="hot-topics">
<h2>今日讨论热点</h2>
<div class="topics-container">
<!-- 在这里填充讨论热点内容严格按照以下格式保留3-5个话题 -->
<!-- 在这里填充讨论热点内容 -->
<!-- 复制上述卡片结构添加更多话题 -->
</div>
</section>
<!-- 2. 实用教程与资源分享 -->
<section class="tutorials">
<h2>实用教程与资源分享</h2>
<div class="tutorials-container">
<!-- 在这里填充教程和资源内容,严格按照以下格式 -->
<!-- 在这里填充教程和资源内容 -->
<!-- 复制上述卡片结构添加更多资源 -->
</div>
</section>
<!-- 3. 重要消息汇总 -->
<section class="important-messages">
<h2>重要消息汇总</h2>
<div class="messages-container">
<!-- 在这里填充重要消息内容,严格按照以下格式 -->
<!-- 在这里填充重要消息内容 -->
<!-- 复制上述卡片结构添加更多消息 -->
</div>
</section>
<!-- 4. 有趣对话或金句 -->
<section class="interesting-dialogues">
<h2>有趣对话或金句</h2>
<div class="dialogues-container">
<!-- 在这里填充对话内容,严格按照以下格式 -->
<!-- 在这里填充对话内容 -->
<!-- 复制上述卡片结构添加更多对话 -->
</div>
</section>
<!-- 5. 问题与解答 -->
<section class="questions-answers">
<h2>问题与解答</h2>
<div class="qa-container">
<!-- 在这里填充问答内容,严格按照以下格式 -->
<!-- 在这里填充问答内容 -->
<!-- 复制上述卡片结构添加更多问答 -->
</div>
</section>
<!-- 6. 群内数据可视化 -->
<section class="analytics">
<h2>群内数据可视化</h2>
<!-- 话题热度 -->
<h3>话题热度</h3>
<div class="heatmap-container">
<!-- 在这里填充话题热度数据,严格按照以下格式 -->
<!-- 复制上述结构添加更多热度项,每项使用不同颜色 -->
<!-- 在这里填充话题热度数据 -->
<!-- 可用的颜色: #3da9fc, #f25f4c, #7209b7, #e53170, #00b4d8, #4cc9f0 -->
</div>
<!-- 话唠榜 -->
<!-- 在话唠榜添加头像 -->
<section class="analytics">
<h3>话唠榜</h3>
<div class="participants-container">
<!-- 在这里填充话唠榜数据 -->
</div>
</section>
<!-- 熬夜冠军 -->
<h3>熬夜冠军</h3>
<div class="night-owls-container">
<!-- 在这里填充熬夜冠军数据,严格按照以下格式 -->
<!-- 在这里填充熬夜冠军内容 -->
</div>
</section>
<!-- 7. 词云 -->
<section class="word-cloud">
<h2>热门词云</h2>
<div class="cloud-container">
<!-- 词云容器 - 现在是云朵样式 -->
<div class="cloud-wordcloud" id="word-cloud">
<!-- 为每个词创建一个span元素使用绝对定位放置 -->
<!-- 以下是一些示例请根据实际内容生成40-60个词 -->
<!-- 在这里填充词云内容 -->
<!-- 继续添加更多词 -->
</div>
<div class="cloud-legend">
<!-- 在这里填充词云分类内容 -->
</div>
</div>
</section>
<!-- 8. 页面底部 -->
<footer>
<p>数据来源:[群名称]聊天记录</p>
<p>生成时间:<span class="generation-time">[当前时间]</span></p>
<p>统计周期:[日期] [时间范围]</p>
<p class="disclaimer">免责声明:本报告内容基于群聊公开讨论,如有不当内容或侵权问题请联系管理员处理。</p>
</footer>
</body>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 获取所有词云元素
const cloudWords = document.querySelectorAll('.cloud-word');
const container = document.querySelector('.cloud-wordcloud');
const containerWidth = container.offsetWidth;
const containerHeight = container.offsetHeight;
// 为每个词云元素设置随机位置
cloudWords.forEach(word => {
const wordWidth = word.offsetWidth;
const wordHeight = word.offsetHeight;
// 计算随机位置,确保词云元素不会超出容器边界
const randomLeft = Math.random() * (containerWidth - wordWidth);
const randomTop = Math.random() * (containerHeight - wordHeight);
// 设置位置
word.style.left = `${randomLeft}px`;
word.style.top = `${randomTop}px`;
// 添加悬停效果
word.addEventListener('mouseover', function() {
this.style.transform = 'scale(1.1)';
this.style.zIndex = '10';
});
word.addEventListener('mouseout', function() {
this.style.transform = 'scale(1)';
this.style.zIndex = '1';
});
});
});
</script>
</html>
"""
json_data = json_data[7:-3]
# 清洗json_data
# 判断是否是转义的换行符
if '\n' in json_data:
json_data = json_data.replace('\n', '\n')
else:
json_data = json_data.replace(r'\"','"').replace(r"\n",'\n')
# print(json_data)
# 使用正则表达式查找json字符串
pattern = re.compile('{.*}', flags=re.IGNORECASE | re.MULTILINE | re.S)
# print(pattern.search(json_data).group())
json_data = json.loads(pattern.search(json_data).group())
# json_data = json.loads(json_data)
# print(json_data)
# print(json.dumps(json_data,indent=4, ensure_ascii=False))
# 替换头部信息
header = json_data['header']
html = html.replace('[群/用户名称]日报', f"{header['title']}报告")
html = html.replace('[日期]', header['date'])
html = html.replace('总消息数:[数量]', f"总消息数:{header['metaInfo']['totalMessages']}")
html = html.replace('活跃用户:[数量]', f"活跃用户:{header['metaInfo']['activeUsers']}")
html = html.replace('时间范围:[时间范围]', f"时间范围:{header['metaInfo']['timeRange']}")
# 处理热点话题
hot_topics = []
for topic in json_data['sections']['hotTopics']['items']:
keywords = ''.join([f'<span class="keyword">{kw}</span>' for kw in topic['keywords']])
hot_topics.append(f"""
<div class="topic-card">
<h3>{topic['name']}</h3>
<div class="topic-category">{topic['category']}</div>
<p class="topic-summary">{topic['summary']}</p>
<div class="topic-keywords">
{keywords}
</div>
<div class="topic-mentions">提及次数:{topic['mentions']}</div>
</div>""")
html = html.replace('<!-- 在这里填充讨论热点内容 -->', '\n'.join(hot_topics))
# 处理教程资源
tutorials = []
for tut in json_data['sections']['tutorials']['items']:
points = ''.join([f'<li>{p}</li>' for p in tut['keyPoints']])
tutorials.append(f"""
<div class="tutorial-card">
<div class="tutorial-type">{tut['type']}</div>
<h3>{tut['title']}</h3>
<div class="tutorial-meta">
<span class="shared-by">分享者:{tut['sharedBy']}</span>
<span class="share-time">时间:{tut['time']}</span>
</div>
<p class="tutorial-summary">{tut['summary']}</p>
<div class="key-points">
<h4>要点:</h4>
<ul>{points}</ul>
</div>
<div class="tutorial-link">
<a href="{tut['url']}" class="link valid">查看原文: {tut['domain']}</a>
</div>
<div class="tutorial-category">分类:{tut['category']}</div>
</div>""")
html = html.replace('<!-- 在这里填充教程和资源内容 -->', '\n'.join(tutorials))
# 处理重要消息
messages = []
for msg in json_data['sections']['importantMessages']['items']:
messages.append(f"""
<div class="message-card">
<div class="message-meta">
<span class="time">{msg['time']}</span>
<span class="sender">{msg['sender']}</span>
<span class="message-type">{msg['type']}</span>
<span class="priority priority-{msg['priority']}">优先级:{msg['priority']}</span>
</div>
<p class="message-content">{msg['content']}</p>
<div class="message-full-content">
<p>{msg['fullContent']}</p>
</div>
</div>""")
html = html.replace('<!-- 在这里填充重要消息内容 -->', '\n'.join(messages))
# 处理对话
dialogues = []
for dia in json_data['sections']['dialogues']['items']:
messages = ''.join([f"""
<div class="message">
<div class="message-meta">
<span class="speaker">{m['speaker']}</span>
<span class="time">{m['time']}</span>
</div>
<p class="message-content">{m['content']}</p>
</div>""" for m in dia['messages']])
dialogues.append(f"""
<div class="dialogue-card">
<div class="dialogue-type">{dia['type']}</div>
<div class="dialogue-content">
{messages}
</div>
<div class="dialogue-highlight">{dia['highlight']}</div>
<div class="dialogue-topic">相关话题:{dia['relatedTopic']}</div>
</div>""")
html = html.replace('<!-- 在这里填充对话内容 -->', '\n'.join(dialogues))
# 处理问答
qas = []
for qa in json_data['sections']['qa']['items']:
tags = ''.join([f'<span class="tag">{tag}</span>' for tag in qa['question']['tags']])
answers = ''.join([f"""
<div class="answer">
<div class="answer-meta">
<span class="responder">{ans['responder']}</span>
<span class="time">{ans['time']}</span>
{"<span class='accepted-badge'>最佳回答</span>" if ans['isAccepted'] else ""}
</div>
<p class="answer-content">{ans['content']}</p>
</div>""" for ans in qa['answers']])
qas.append(f"""
<div class="qa-card">
<div class="question">
<div class="question-meta">
<span class="asker">{qa['question']['asker']}</span>
<span class="time">{qa['question']['time']}</span>
</div>
<p class="question-content">{qa['question']['content']}</p>
<div class="question-tags">
{tags}
</div>
</div>
<div class="answers">
{answers}
</div>
</div>""")
html = html.replace('<!-- 在这里填充问答内容 -->', '\n'.join(qas))
# 处理数据可视化
heatmap = []
colors = ['#3da9fc', '#f25f4c', '#7209b7', '#e53170', '#00b4d8', '#4cc9f0']
for i, topic in enumerate(json_data['sections']['analytics']['heatmap']):
color = colors[i % len(colors)]
heatmap.append(f"""
<div class="heat-item">
<div class="heat-topic">{topic['topic']}</div>
<div class="heat-percentage">{topic['percentage']}%</div>
<div class="heat-bar">
<div class="heat-fill" style="width: {topic['percentage']}%; background-color: {color};"></div>
</div>
<div class="heat-count">{topic['count']}条消息</div>
</div>""")
html = html.replace('<!-- 在这里填充话题热度数据 -->', '\n'.join(heatmap))
# 处理话唠榜
chatty = []
for rank in json_data['sections']['analytics']['chattyRanking']:
words = ''.join([f'<span class="word">{w}</span>' for w in rank['commonWords']])
characteristics = ''.join([f'<span class="characteristic">{c}</span>' for c in rank['characteristics']])
chatty.append(f"""
<div class="participant-item">
<div class="participant-rank">{rank['rank']}</div>
<div class="participant-info">
<div class="participant-name">{rank['name']}</div>
<div class="participant-count">发言数:{rank['count']}</div>
<div class="participant-characteristics">
{characteristics}
</div>
<div class="participant-words">
{words}
</div>
</div>
</div>""")
html = html.replace('<!-- 在这里填充话唠榜数据 -->', '\n'.join(chatty))
# 处理熬夜冠军
nightOwl = json_data['sections']['analytics']['nightOwl']
f = f"""
<div class="night-owl-item">
<div class="owl-crown" title="熬夜冠军">👑</div>
<div class="owl-info">
<div class="owl-name">{nightOwl['name']}</div>
<div class="owl-title">{nightOwl['title']}</div>
<div class="owl-time">最晚活跃时间:{nightOwl['latestTime']}</div>
<div class="owl-messages">深夜消息数:{nightOwl['messageCount']}</div>
<div class="owl-last-message">{nightOwl['lastMessage']}</div>
<div class="owl-note">注熬夜时段定义为23:00-06:00已考虑不同时区</div>
</div>"""
html = html.replace('<!-- 在这里填充熬夜冠军内容 -->','\n' + f + '\n')
# 处理词云
words = []
for word in json_data['sections']['wordCloud']['words']:
words.append(f"""
<span class="cloud-word" style="left: {word.get('x', 300)}px; top: {word.get('y', 120)}px;
font-size: {word['size']}px; color: {word['color']};
transform: rotate({word['rotation']}deg);">{word['text']}</span>""")
html = html.replace('<!-- 在这里填充词云内容 -->', '\n'.join(words))
# 处理词云的分类
types = []
for typ in json_data['sections']['wordCloud']['legend']:
types.append(f""" <div class="legend-item">
<span class="legend-color" style="background-color: {typ['color']};"></span>
<span class="legend-label">{typ['label']}</span>
</div>
"""
)
html = html.replace('<!-- 在这里填充词云分类内容 -->', '\n'.join(types))
# 处理页脚
footer = json_data['footer']
html = html.replace('[群名称]', footer['dataSource'])
html = html.replace('[当前时间]', footer['generationTime'])
html = html.replace('[日期] [时间范围]', footer['statisticalPeriod'])
return html
if __name__ == '__main__':
json_data = r"```json\n{\n\"header\": {\n\"title\": \"群聊报告\",\n\"date\": \"2025-04-29\",\n\"metaInfo\": {\n\"totalMessages\": \"35\",\n\"activeUsers\": \"12\",\n\"timeRange\": \"07:03:10 - 15:36:25\"\n}\n},\n\"sections\": {\n\"hotTopics\": {\n\"items\": [\n{\n\"name\": \"AI技术讨论\",\n\"category\": \"科技\",\n\"summary\": \"群内围绕Qwen3开源、Vidu Q1体验、夸克AI相机等AI技术展开热烈讨论涉及模型性能、应用场景和开发者体验。多位成员分享了相关技术文章和体验报告。\",\n\"keywords\": [\"Qwen3\", \"Vidu\", \"AI相机\"],\n\"mentions\": \"15\"\n},\n{\n\"name\": \"熬夜与工作压力\",\n\"category\": \"生活\",\n\"summary\": \"成员们讨论熬夜工作现象,分享各自熬夜经历,对比互联网大厂与普通开发者的工作强度差异,引发关于工作生活平衡的思考。\",\n\"keywords\": [\"熬夜\", \"加班\", \"工作强度\"],\n\"mentions\": \"8\"\n}\n]\n},\n\"tutorials\": {\n\"items\": [\n{\n\"type\": \"TUTORIAL\",\n\"title\": \"体验完刚上线的Vidu Q1后劲有点大附AI视频创作教程\",\n\"sharedBy\": \"苍何\",\n\"time\": \"2025-04-29 09:39:42\",\n\"summary\": \"分享Vidu Q1 AI视频创作工具的体验和教程介绍其清晰度和一致性的提升。\",\n\"keyPoints\": [\"AI视频清晰度提升\", \"一致性改进\"],\n\"url\": \"http://mp.weixin.qq.com/s?__biz=MzU4NTE1Mjg4MA==&mid=2247493267&idx=1&sn=0189fb501578ce8e27142fbe2f590d03&chksm=fc9a946728c367005c19cb5a335300d05d51a441f9f20424a0a72c904a47bdf003252576318a&mpshare=1&scene=1&srcid=04297l70B2zsuypDfjUh0rh5&sharer_shareinfo=181efb947f938ab90786c776bf7bbda7&sharer_shareinfo_first=181efb947f938ab90786c776bf7bbda7#rd\",\n\"domain\": \"mp.weixin.qq.com\",\n\"category\": \"AI工具\"\n},\n{\n\"type\": \"TUTORIAL\",\n\"title\": \"阿里新出的夸克AI相机强大到我有点陌生\",\n\"sharedBy\": \"苍何\",\n\"time\": \"2025-04-29 09:42:38\",\n\"summary\": \"介绍夸克AI相机的新奇玩法和功能展示其强大的AI图像处理能力。\",\n\"keyPoints\": [\"新奇玩法\", \"抽象功能\"],\n\"url\": \"http://mp.weixin.qq.com/s?__biz=MzU4NTE1Mjg4MA==&mid=2247493275&idx=1&sn=93556ddd1da7fb8733a23a7c4adbb76b&chksm=fc2a2d25774cce23c75acd8850b85c585c0bcf78d14b810e157efaec5106abf563cf58e26aef&mpshare=1&scene=1&srcid=0429vDf8NbEzNLBQQyFlABmU&sharer_shareinfo=28b94477ec8201b88aa30338e82e8999&sharer_shareinfo_first=28b94477ec8201b88aa30338e82e8999#rd\",\n\"domain\": \"mp.weixin.qq.com\",\n\"category\": \"AI应用\"\n},\n{\n\"type\": \"RESOURCE\",\n\"title\": \"仅2MBWindows瞬间超级丝滑\",\n\"sharedBy\": \"AHapi²⁰²⁵\",\n\"time\": \"2025-04-29 11:13:38\",\n\"summary\": \"分享一款轻量级Windows优化工具声称能显著提升系统运行速度。\",\n\"keyPoints\": [\"2MB大小\", \"系统优化\"],\n\"url\": \"https://mp.weixin.qq.com/s/es77Jc6Du03ppJD5XJeQUg\",\n\"domain\": \"mp.weixin.qq.com\",\n\"category\": \"系统工具\"\n}\n]\n},\n\"importantMessages\": {\n\"items\": [\n{\n\"time\": \"2025-04-29 10:00:18\",\n\"sender\": \"苍何\",\n\"type\": \"NEWS\",\n\"priority\": \"\",\n\"content\": \"2025年04月29日 AI科技早报阿里开源8款Qwen3模型腾讯开源Kuikly跨端框架OpenAI推出ChatGPT购物功能等11条重要新闻。\",\n\"fullContent\": \"2025年04月29日 AI科技早报1、阿里开源8款Qwen3模型集成MCP性能超DeepSeek-R1、OpenAI o1。2、Qafind Labs发布ChatDLM扩散语言模型推理速度高达2800 tokens/s。3、腾讯开源Kuikly跨端框架基于Kotlin支持多平台开发已应用于QQ。4、OpenAI 推出 ChatGPT 购物功能,用户可通过 ChatGPT 便捷购物。5、字节Seed团队提出PHD-Transformer突破预训练长度扩展瓶颈。6、百度发布文心快码3.5版本与多模态AI智能体Zulu助力工程师提效。7、Kimi与财新传媒合作提供专业财经内容推动AI+传统媒体融合。8、苹果加速「N50」智能眼镜项目融合AI技术预计2027年亮相。9、研究显示OpenAI o3在病毒学领域超越94%人类专家生物安全引关注。10、华为测试自研AI芯片Ascend 910D旨在替代英伟达H100芯片。11、🔥【记得收藏】早报同步更新到开源 AI 知识库https://u55dyuejxc.feishu.cn/wiki/FkmNwxYHDigJ3akIUGHc8MSTn4d\"\n}\n]\n},\n\"dialogues\": {\n\"items\": [\n{\n\"type\": \"DIALOGUE\",\n\"messages\": [\n{\n\"speaker\": \"好名字\",\n\"time\": \"2025-04-29 08:16:23\",\n\"content\": \"这个我弄完ai做的小程序有bug流程走不通还改不了[捂脸]\"\n},\n{\n\"speaker\": \"贾👦🏻\",\n\"time\": \"2025-04-29 08:54:33\",\n\"content\": \"可以微调 不过源码需要买的\"\n},\n{\n\"speaker\": \"好名字\",\n\"time\": \"2025-04-29 09:13:32\",\n\"content\": \"微调一次,然后再想调就需要开会员了\"\n},\n{\n\"speaker\": \"贾👦🏻\",\n\"time\": \"2025-04-29 09:14:09\",\n\"content\": \"需求变更一个字 就需要重新购买[破涕为笑]\"\n}\n],\n\"highlight\": \"AI小程序开发中的商业化模式讨论\",\n\"relatedTopic\": \"AI开发工具\"\n},\n{\n\"type\": \"DIALOGUE\",\n\"messages\": [\n{\n\"speaker\": \"苍何\",\n\"time\": \"2025-04-29 09:26:49\",\n\"content\": \"我熬不动\"\n},\n{\n\"speaker\": \"AHapi²⁰²⁵\",\n\"time\": \"2025-04-29 09:27:25\",\n\"content\": \"不要卷别人[旺柴]别人写了 就不卷他们了\"\n},\n{\n\"speaker\": \"苍何\",\n\"time\": \"2025-04-29 09:27:55\",\n\"content\": \"新闻得第一时间,做不到写了也没啥用\"\n},\n{\n\"speaker\": \"苍何\",\n\"time\": \"2025-04-29 09:28:03\",\n\"content\": \"还不如写些应用\"\n},\n{\n\"speaker\": \"大风Wind\",\n\"time\": \"2025-04-29 09:28:23\",\n\"content\": \"看看哪些是5-7点发推文的基本都是卷王了\"\n},\n{\n\"speaker\": \"沉默王二\",\n\"time\": \"2025-04-29 09:28:44\",\n\"content\": \"身体能扛住确实离谱\"\n},\n{\n\"speaker\": \"苍何\",\n\"time\": \"2025-04-29 09:29:03\",\n\"content\": \"是啊,太肝了\"\n}\n],\n\"highlight\": \"关于工作强度和熬夜文化的讨论\",\n\"relatedTopic\": \"工作生活平衡\"\n}\n]\n},\n\"qa\": {\n\"items\": [\n{\n\"question\": {\n\"asker\": \"银色子弹-捷\",\n\"time\": \"2025-04-29 11:10:26\",\n\"content\": \"问一下win11电脑你长时间没清理运行慢一般用什么来清理电脑 不要360啊那个太流氓了想知道各位大佬有没有优秀的软件推荐一下\",\n\"tags\": [\"Windows优化\", \"系统清理\"]\n},\n\"answers\": [\n{\n\"responder\": \"昏沉沉的\",\n\"time\": \"2025-04-29 11:11:59\",\n\"content\": \"ccclean\",\n\"isAccepted\": false\n},\n{\n\"responder\": \"🤑程序儒\",\n\"time\": \"2025-04-29 11:13:07\",\n\"content\": \"360极速版、Wise Care 365\",\n\"isAccepted\": false\n},\n{\n\"responder\": \"AHapi²⁰²⁵\",\n\"time\": \"2025-04-29 11:13:38\",\n\"content\": \"仅2MBWindows瞬间超级丝滑这才是真神器\",\n\"isAccepted\": true\n}\n]\n},\n{\n\"question\": {\n\"asker\": \"ಠ_ಠ 闲鱼一条ಠ_ಠ\",\n\"time\": \"2025-04-29 11:37:49\",\n\"content\": \"请问哪位哥还有扣子的邀请码吗?\",\n\"tags\": [\"邀请码\", \"扣子空间\"]\n},\n\"answers\": [\n{\n\"responder\": \"贾👦🏻\",\n\"time\": \"2025-04-29 11:40:37\",\n\"content\": \"RootUser_2105656329 邀请你体验扣子空间,快来和 Agent 一起开始你的工作吧https://www.coze.cn/space-preview?invite_code=SCL7DAL0\",\n\"isAccepted\": true\n},\n{\n\"responder\": \"9527\",\n\"time\": \"2025-04-29 11:47:43\",\n\"content\": \"RootUser_2106519373 邀请你体验扣子空间,快来和 Agent 一起开始你的工作吧https://www.coze.cn/space-preview?invite_code=A8IT4MUE\",\n\"isAccepted\": false\n}\n]\n}\n]\n},\n\"analytics\": {\n\"heatmap\": [\n{\n\"topic\": \"AI技术\",\n\"percentage\": \"45%\",\n\"color\": \"#3da9fc\",\n\"count\": \"16\"\n},\n{\n\"topic\": \"工作讨论\",\n\"percentage\": \"25%\",\n\"color\": \"#4361ee\",\n\"count\": \"9\"\n},\n{\n\"topic\": \"工具推荐\",\n\"percentage\": \"15%\",\n\"color\": \"#00b4d8\",\n\"count\": \"5\"\n},\n{\n\"topic\": \"其他\",\n\"percentage\": \"15%\",\n\"color\": \"#7209b7\",\n\"count\": \"5\"\n}\n],\n\"chattyRanking\": [\n{\n\"rank\": 1,\n\"name\": \"苍何\",\n\"count\": \"7\",\n\"characteristics\": [\"技术分享\", \"新闻发布\"],\n\"commonWords\": [\"AI\", \"开源\", \"熬夜\"]\n},\n{\n\"rank\": 2,\n\"name\": \"AHapi²⁰²⁵\",\n\"count\": \"6\",\n\"characteristics\": [\"幽默评论\", \"资源分享\"],\n\"commonWords\": [\"旺柴\", \"加班\", \"神器\"]\n},\n{\n\"rank\": 3,\n\"name\": \"贾👦🏻\",\n\"count\": \"3\",\n\"characteristics\": [\"问题解答\", \"邀请码分享\"],\n\"commonWords\": [\"源码\", \"购买\", \"邀请\"]\n}\n],\n\"nightOwl\": {\n\"name\": \"苍何\",\n\"title\": \"熬夜冠军\",\n\"latestTime\": \"09:42:54\",\n\"messageCount\": \"7\",\n\"lastMessage\": \"我熬夜写了这一篇[旺柴]\"\n}\n},\n\"wordCloud\": {\n\"words\": [\n{\n\"text\": \"AI\",\n\"size\": 42,\n\"color\": \"#00b4d8\",\n\"rotation\": 0\n},\n{\n\"text\": \"熬夜\",\n\"size\": 36,\n\"color\": \"#4361ee\",\n\"rotation\": -15\n},\n{\n\"text\": \"开源\",\n\"size\": 32,\n\"color\": \"#00b4d8\",\n\"rotation\": 15\n},\n{\n\"text\": \"Qwen3\",\n\"size\": 28,\n\"color\": \"#3da9fc\",\n\"rotation\": -10\n},\n{\n\"text\": \"Vidu\",\n\"size\": 26,\n\"color\": \"#3da9fc\",\n\"rotation\": 10\n},\n{\n\"text\": \"清理\",\n\"size\": 24,\n\"color\": \"#7209b7\",\n\"rotation\": -5\n},\n{\n\"text\": \"邀请码\",\n\"size\": 22,\n\"color\": \"#7209b7\",\n\"rotation\": 5\n}\n],\n\"legend\": [\n{\"color\": \"#00b4d8\", \"label\": \"技术 相关词汇\"},\n{\"color\": \"#4361ee\", \"label\": \"生活 相关词汇\"},\n{\"color\": \"#7209b7\", \"label\": \"工具 相关词汇\"}\n]\n}\n},\n\"footer\": {\n\"dataSource\": \"群聊聊天记录\",\n\"generationTime\": \"2025-04-29 16:00:00\",\n\"statisticalPeriod\": \"2025-04-29 07:03:10 - 15:36:25\",\n\"disclaimer\": \"本报告内容基于群聊公开讨论,如有不当内容或侵权问题请联系管理员处理。\"\n}\n}\n```"
with open('text.html', 'w', encoding='utf-8') as f:
f.write(main(json_data))