🔄 卡若AI 同步 2026-02-27 05:21 | 更新:水桥平台对接、运营中枢工作台 | 排除 >20MB: 14 个

This commit is contained in:
2026-02-27 05:21:50 +08:00
parent 40b2a6aa45
commit cabc44b837
6 changed files with 107 additions and 27 deletions

View File

@@ -48,6 +48,7 @@ python3 "/Users/karuo/Documents/个人/卡若AI/02_卡人/水桥_平台
2. 写入前校验标题月份;不匹配拒绝写入。
3. 写入后打开对应月份文档。
4. 默认登记内容包含:目标进度、卡点、下一步、运营登记说明。
5. **TNTWF 格式**:仅 **W(工作)****F(反馈)** 有复选框T(目标)、N(过程)、T(思考) 为纯文本,无勾选框。
---

View File

@@ -93,7 +93,15 @@ python3 "/Users/karuo/Documents/个人/卡若AI/02_卡人/水桥_平台
---
## 7. 推荐填写模板
## 7. TNTWF 格式与复选框规则
- **T(目标)、N(过程)、T(思考)**:纯文本,无复选框。
- **W(工作)、F(反馈)**:任务列表,带复选框,可勾选完成。
- 覆盖已有日志:`write_today_0227.py --overwrite` 或脚本支持 `--overwrite` 时使用。
---
## 8. 推荐填写模板
- 今日主题卡若AI / 接口 / 网站 / 运营报表
- 完成度:例如 `55%`
@@ -103,7 +111,7 @@ python3 "/Users/karuo/Documents/个人/卡若AI/02_卡人/水桥_平台
---
## 8. 故障排查
## 9. 故障排查
- 提示 Token 失败:先重新执行一次,触发静默刷新
- 写入失败(字段校验):缩短单条文本长度后重试
@@ -111,7 +119,7 @@ python3 "/Users/karuo/Documents/个人/卡若AI/02_卡人/水桥_平台
---
## 9. 关联文件
## 10. 关联文件
- 子技能:`02_卡人/水桥_平台对接/飞书管理/卡若的飞书日志_SKILL.md`
- 主技能:`02_卡人/水桥_平台对接/飞书管理/SKILL.md`

View File

@@ -204,21 +204,23 @@ def build_blocks(date_str, tasks):
'style': {'done': False, 'align': 1}}})
blocks.append({'block_type': 2, 'text': {'elements': [{'text_run': {'content': '{'}}], 'style': {}}})
# TNTWF格式,标注清楚
# TNTWF格式:仅 W(工作) F(反馈) 有复选框T/N/T 为纯文本
labels = [
('T', 't_targets', '目标'),
('N', 'n_process', '过程'),
('T', 't_thoughts', '思考'),
('W', 'w_work', '工作'),
('F', 'f_feedback', '反馈')
('T', 't_targets', '目标', False),
('N', 'n_process', '过程', False),
('T', 't_thoughts', '思考', False),
('W', 'w_work', '工作', True),
('F', 'f_feedback', '反馈', True)
]
for label, key, name in labels:
for label, key, name, use_todo in labels:
items = task.get(key, [])
if items:
blocks.append({'block_type': 2, 'text': {'elements': [{'text_run': {'content': f'{label} ({name})', 'text_element_style': {'bold': True}}}], 'style': {}}})
for item in items:
blocks.append({'block_type': 17, 'todo': {'elements': [{'text_run': {'content': item}}], 'style': {'done': False}}})
if use_todo:
blocks.append({'block_type': 17, 'todo': {'elements': [{'text_run': {'content': item}}], 'style': {'done': False}}})
else:
blocks.append({'block_type': 2, 'text': {'elements': [{'text_run': {'content': item}}], 'style': {}}})
blocks.append({'block_type': 2, 'text': {'elements': [{'text_run': {'content': '}'}}], 'style': {}}})
blocks.append({'block_type': 2, 'text': {'elements': [{'text_run': {'content': ''}}], 'style': {}}})
@@ -246,8 +248,39 @@ def resolve_wiki_token_for_date(date_str, explicit_wiki_token=None):
return CONFIG['MONTH_WIKI_TOKENS'][month]
return CONFIG['WIKI_TOKEN']
def write_log(token, date_str=None, tasks=None, wiki_token=None):
"""写入日志(倒序插入:新日期在最上面"""
def _find_date_section_block_ids(blocks, date_str, doc_id):
"""找到某日期区块的 block_id 列表(用于覆盖删除"""
date_re = re.compile(r'\d+\s*月\s*\d+\s*日')
start_i = None
for i, block in enumerate(blocks):
for key in ['heading4', 'text']:
if key in block:
for el in block[key].get('elements', []):
c = el.get('text_run', {}).get('content', '')
if date_str in c:
start_i = i
break
if start_i is not None:
break
if start_i is None:
return []
# 从 start_i 向后收集,直到遇到下一个日期标题
ids = []
for i in range(start_i, len(blocks)):
b = blocks[i]
bid = b.get('block_id')
if not bid:
continue
# 若遇下一个日期 heading4停止
if i > start_i and 'heading4' in b:
for el in b.get('heading4', {}).get('elements', []):
if date_re.search(el.get('text_run', {}).get('content', '')):
return ids
ids.append(bid)
return ids
def write_log(token, date_str=None, tasks=None, wiki_token=None, overwrite=False):
"""写入日志倒序插入新日期在最上面overwrite=True 时先删后写"""
headers = {'Authorization': f'Bearer {token}', 'Content-Type': 'application/json'}
if not date_str or not tasks:
@@ -264,27 +297,58 @@ def write_log(token, date_str=None, tasks=None, wiki_token=None):
doc_id = node['obj_token']
doc_title = node.get('title', '')
# 防串月:日期月份与文档标题不一致时拒绝写入
# 防串月
month = parse_month_from_date_str(date_str)
if month and f"{month}" not in doc_title:
print(f"❌ 月份校验失败:{date_str} 不应写入《{doc_title}")
return False
# 获取blocks检查日期是否存在
r = requests.get(f"https://open.feishu.cn/open-apis/docx/v1/documents/{doc_id}/blocks",
headers=headers, params={'page_size': 500}, timeout=30)
blocks = r.json().get('data', {}).get('items', [])
headers=headers, params={'document_revision_id': -1, 'page_size': 500}, timeout=30)
blk_data = r.json().get('data', {})
blocks = blk_data.get('items', [])
# 检查是否已存在
exists = False
for block in blocks:
for key in ['heading4', 'text']:
if key in block:
for el in block[key].get('elements', []):
if 'text_run' in el and date_str in el['text_run'].get('content', ''):
print(f"{date_str} 日志已存在,无需重复写入")
return True
exists = True
break
if exists:
break
# 找插入位置(倒序:插入到"本月最重要的任务"标题后,即第一个位置)
if exists and overwrite:
to_del = _find_date_section_block_ids(blocks, date_str, doc_id)
if to_del:
try:
for i in range(0, len(to_del), 20):
batch = to_del[i:i+20]
body = {"requests": [{"block_id": bid} for bid in batch]}
rd = requests.post(f"https://open.feishu.cn/open-apis/docx/v1/documents/{doc_id}/blocks/batch_delete",
headers=headers, json=body, timeout=30)
try:
j = rd.json()
except Exception:
j = {}
if j.get('code') != 0:
print(f"⚠️ 覆盖删除失败: {j.get('msg', rd.text[:80])},请手动删飞书中 {date_str} 后重试")
break
else:
r = requests.get(f"https://open.feishu.cn/open-apis/docx/v1/documents/{doc_id}/blocks",
headers=headers, params={'document_revision_id': -1, 'page_size': 500}, timeout=30)
blocks = r.json().get('data', {}).get('items', [])
exists = False
except Exception as e:
print(f"⚠️ 覆盖删除异常: {e},请手动删飞书中 {date_str} 后重试")
if exists:
print(f"{date_str} 日志已存在,无需重复写入(可用 --overwrite 覆盖)")
return True
# 找插入位置(倒序:插入到"本月最重要的任务"标题后)
insert_index = 1
for i, block in enumerate(blocks):
if block.get('parent_id') == doc_id and 'heading2' in block:

View File

@@ -24,19 +24,19 @@ def build_tasks_0227():
"events": ["一人公司Agent", "玩值电竞", "重要未完成项", "飞书日志迭代"],
"quadrant": "重要紧急",
"t_targets": [
"一人公司Agent→视频切片/文章/直播/小程序/朋友圈/聚合 (5%)",
"玩值电竞→Docker部署与功能推进 (第二) (25%)",
"一人公司Agent→视频切片/文章/直播/小程序/朋友圈/聚合 (5%) 【自2月17日迭代】",
"玩值电竞→Docker部署与功能推进 (第二) (25%) 【自2月17日迭代】",
"卡若AI 4项优化→减重+收口+规则+输出+护栏 (执行中)",
"飞书日志→每日迭代+进度百分比更新 (100%)",
],
"n_process": [
"【一人公司】视频切片分发、文章全网、每日直播、小程序、朋友圈→聚合平台",
"【玩值电竞】Docker 3001MongoDB wanzhi_esports持续迭代",
"【重要未完成】卡若AI优化、书小程序、玉宁直播等持续迭代",
"【重要未完成】卡若AI优化、书小程序、玉宁直播等 自2月17日持续迭代",
"【昨日2月26】卡若AI 56%、一场创业实验→永平、GitHub yongpxu-soul",
],
"t_thoughts": [
"一人公司第一、玩值电竞第二;重要未完成项加入今日迭代",
"一人公司第一、玩值电竞第二;未完成进度自2月17日迭代至今日",
],
"w_work": ["一人公司Agent", "玩值电竞", "卡若AI优化", "飞书日志登记"],
"f_feedback": [
@@ -50,9 +50,14 @@ def build_tasks_0227():
def main():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--overwrite", action="store_true", help="覆盖已有当日日志")
args = parser.parse_args()
date_str = "2月27日"
print("=" * 50)
print(f"📝 写入飞书日志:{date_str}")
print(f"📝 写入飞书日志:{date_str}" + (" [覆盖]" if args.overwrite else ""))
print("=" * 50)
token = get_token_silent()
@@ -62,7 +67,7 @@ def main():
tasks = build_tasks_0227()
target_wiki_token = resolve_wiki_token_for_date(date_str)
ok = write_log(token, date_str, tasks, target_wiki_token)
ok = write_log(token, date_str, tasks, target_wiki_token, overwrite=args.overwrite)
if ok:
open_result(target_wiki_token)
print(f"{date_str} 日志写入成功")

View File

@@ -165,3 +165,4 @@
| 2026-02-26 00:31:13 | 🔄 卡若AI 同步 2026-02-26 00:31 | 更新:水桥平台对接、运营中枢工作台 | 排除 >20MB: 14 个 |
| 2026-02-26 00:43:29 | 🔄 卡若AI 同步 2026-02-26 00:43 | 更新:运营中枢工作台 | 排除 >20MB: 14 个 |
| 2026-02-26 16:43:05 | 🔄 卡若AI 同步 2026-02-26 16:41 | 更新:金仓、水桥平台对接、卡木、运营中枢工作台 | 排除 >20MB: 14 个 |
| 2026-02-27 05:06:58 | 🔄 卡若AI 同步 2026-02-27 05:06 | 更新:水桥平台对接、运营中枢工作台 | 排除 >20MB: 14 个 |

View File

@@ -168,3 +168,4 @@
| 2026-02-26 00:31:13 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-26 00:31 | 更新:水桥平台对接、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-02-26 00:43:29 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-26 00:43 | 更新:运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-02-26 16:43:05 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-26 16:41 | 更新:金仓、水桥平台对接、卡木、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-02-27 05:06:58 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-27 05:06 | 更新:水桥平台对接、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |