🔄 卡若AI 同步 2026-02-24 16:28 | 更新:水桥平台对接、卡木、卡土、运营中枢工作台 | 排除 >20MB: 10 个
This commit is contained in:
306
02_卡人(水)/水桥_平台对接/智能纪要/脚本/auto_cookie_and_export.py
Normal file
306
02_卡人(水)/水桥_平台对接/智能纪要/脚本/auto_cookie_and_export.py
Normal file
@@ -0,0 +1,306 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
全自动:从本机浏览器读取飞书 Cookie,写入 cookie_minutes.txt,并执行妙记导出。
|
||||
流程:1) 用系统默认浏览器打开妙记页 2) 等待登录 3) 从 Chrome/Safari 读取 Cookie 4) 验证无 401 后导出。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
from pathlib import Path
|
||||
|
||||
SCRIPT_DIR = Path(__file__).resolve().parent
|
||||
COOKIE_FILE = SCRIPT_DIR / "cookie_minutes.txt"
|
||||
LIST_URL = "https://cunkebao.feishu.cn/minutes/api/space/list"
|
||||
EXPORT_URL = "https://cunkebao.feishu.cn/minutes/api/export"
|
||||
MINUTES_URL = "https://cunkebao.feishu.cn/minutes/home"
|
||||
USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
|
||||
TEST_TOKEN = "obcnyg5nj2l8q281v32de6qz" # 104场,用于验证
|
||||
|
||||
|
||||
def verify_cookie(cookie: str) -> bool:
|
||||
"""验证 Cookie 能否成功调用导出接口(无 401)。"""
|
||||
try:
|
||||
import requests
|
||||
h = {
|
||||
"User-Agent": USER_AGENT,
|
||||
"cookie": cookie,
|
||||
"referer": "https://cunkebao.feishu.cn/minutes/",
|
||||
"origin": "https://cunkebao.feishu.cn",
|
||||
"content-type": "application/x-www-form-urlencoded",
|
||||
}
|
||||
# 先调 list 激活会话,再 export(试 cunkebao 和 meetings 两域)
|
||||
session = requests.Session()
|
||||
session.headers.update(h)
|
||||
session.get(f"{LIST_URL}?size=5&space_name=1", timeout=10)
|
||||
time.sleep(0.5)
|
||||
for export_base in (EXPORT_URL, "https://meetings.feishu.cn/minutes/api/export"):
|
||||
ref = "https://meetings.feishu.cn/minutes/" if "meetings" in export_base else "https://cunkebao.feishu.cn/minutes/"
|
||||
h["referer"] = ref
|
||||
r = session.post(
|
||||
export_base,
|
||||
params={"object_token": TEST_TOKEN, "add_speaker": "true", "add_timestamp": "false", "format": 2},
|
||||
headers=h,
|
||||
timeout=15,
|
||||
)
|
||||
if r.status_code != 200:
|
||||
continue
|
||||
text = (r.text or "").strip()
|
||||
if len(text) < 200:
|
||||
continue
|
||||
if text.startswith("{"):
|
||||
try:
|
||||
j = r.json()
|
||||
if j.get("code") not in (0, None) or "please log in" in (j.get("msg") or "").lower():
|
||||
continue
|
||||
return True
|
||||
except Exception:
|
||||
continue
|
||||
return True # 纯文本正文 = 成功
|
||||
return False
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def collect_cookie_via_default_browser() -> str:
|
||||
"""用 Chrome 打开妙记页,等待登录后从 Chrome 读取 Cookie。"""
|
||||
for app in ["Google Chrome", "Chromium", "Safari"]:
|
||||
try:
|
||||
subprocess.run(["open", "-a", app, MINUTES_URL], capture_output=True, timeout=5)
|
||||
print(f" 已用 {app} 打开妙记页。")
|
||||
break
|
||||
except Exception:
|
||||
continue
|
||||
print(" ⏳ 请在此浏览器中完成登录(看到妙记列表即可),等待 90 秒…")
|
||||
time.sleep(90)
|
||||
return collect_cookie_from_browsers()
|
||||
|
||||
|
||||
SOUL_ITEMS = [
|
||||
(100, "soul 派对 100场 20260214", "obcnu1rfr452595c6l51a7e1", "20260214"),
|
||||
(104, "soul 派对 104场 20260219", "obcnyg5nj2l8q281v32de6qz", "20260219"),
|
||||
(105, "soul 派对 105场 20260220", "obcny5sux74w123q3pmt8xg7", "20260220"),
|
||||
]
|
||||
OUT_DIR = Path("/Users/karuo/Documents/聊天记录/soul")
|
||||
|
||||
|
||||
def run_playwright_page_export(from_num: int, to_num: int) -> int:
|
||||
"""在 Playwright 页面内直接请求导出,绕过 Cookie,保证成功。"""
|
||||
import re
|
||||
items = [(n, t, tok, d) for n, t, tok, d in SOUL_ITEMS if from_num <= n <= to_num]
|
||||
if not items:
|
||||
return 0
|
||||
try:
|
||||
from playwright.sync_api import sync_playwright
|
||||
except ImportError:
|
||||
print("❌ 需安装 playwright: pip install playwright && playwright install chromium", file=sys.stderr)
|
||||
return 1
|
||||
import tempfile
|
||||
ud = tempfile.mkdtemp(prefix="feishu_export_")
|
||||
try:
|
||||
with sync_playwright() as p:
|
||||
ctx = p.chromium.launch_persistent_context(ud, headless=False, timeout=15000)
|
||||
pg = ctx.pages[0] if ctx.pages else ctx.new_page()
|
||||
pg.goto(MINUTES_URL, wait_until="domcontentloaded", timeout=25000)
|
||||
print(" ⚠️ 请在此窗口登录飞书妙记(看到列表即可),等待 90 秒…")
|
||||
time.sleep(90)
|
||||
saved = 0
|
||||
for num, topic, token, date_str in items:
|
||||
print(f" 导出 {topic}…")
|
||||
try:
|
||||
js = f"""
|
||||
async () => {{
|
||||
const r = await fetch('https://cunkebao.feishu.cn/minutes/api/export?object_token={token}&add_speaker=true&add_timestamp=false&format=2', {{method:'POST', credentials:'include'}});
|
||||
return await r.text();
|
||||
}}
|
||||
"""
|
||||
text = pg.evaluate(js)
|
||||
if not text or len(str(text)) < 500 or "please log in" in str(text).lower():
|
||||
print(f" ❌ 失败: {topic}")
|
||||
continue
|
||||
safe = re.sub(r'[\\/*?:"<>|]', "_", topic)
|
||||
path = OUT_DIR / f"{safe}_{date_str}.txt"
|
||||
OUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||
path.write_text(f"日期: {date_str}\n标题: {topic}\n\n文字记录:\n\n{text.strip()}", encoding="utf-8")
|
||||
print(f" ✅ {topic} -> {path.name}")
|
||||
saved += 1
|
||||
except Exception as e:
|
||||
print(f" ❌ {topic}: {e}")
|
||||
time.sleep(1)
|
||||
ctx.close()
|
||||
print(f"✅ 页面内导出完成 {saved}/{len(items)} 场,目录: {OUT_DIR}")
|
||||
return 0
|
||||
finally:
|
||||
import shutil
|
||||
shutil.rmtree(ud, ignore_errors=True)
|
||||
|
||||
|
||||
def collect_cookie_via_playwright_standalone() -> str:
|
||||
"""Playwright 启动独立 Chromium,用户登录后抓 Cookie。"""
|
||||
try:
|
||||
from playwright.sync_api import sync_playwright
|
||||
except ImportError:
|
||||
return ""
|
||||
import tempfile
|
||||
ud = tempfile.mkdtemp(prefix="feishu_cookie_")
|
||||
cookie_str = ""
|
||||
try:
|
||||
with sync_playwright() as p:
|
||||
ctx = p.chromium.launch_persistent_context(
|
||||
user_data_dir=ud,
|
||||
headless=False,
|
||||
args=["--start-maximized"],
|
||||
viewport={"width": 1280, "height": 900},
|
||||
timeout=15000,
|
||||
)
|
||||
try:
|
||||
pg = ctx.pages[0] if ctx.pages else ctx.new_page()
|
||||
pg.goto(MINUTES_URL, wait_until="domcontentloaded", timeout=25000)
|
||||
except Exception:
|
||||
pg = ctx.new_page() if not ctx.pages else ctx.pages[0]
|
||||
try:
|
||||
pg.goto(MINUTES_URL, wait_until="domcontentloaded", timeout=25000)
|
||||
except Exception:
|
||||
pass
|
||||
print(" ⚠️ 请在此窗口完成飞书妙记登录(输入账号密码直到看到列表),等待 120 秒…")
|
||||
time.sleep(120)
|
||||
cookies = ctx.cookies("https://cunkebao.feishu.cn")
|
||||
if not cookies:
|
||||
cookies = ctx.cookies()
|
||||
ctx.close()
|
||||
seen = set()
|
||||
parts = []
|
||||
for c in cookies:
|
||||
if c["name"] not in seen:
|
||||
seen.add(c["name"])
|
||||
parts.append(f"{c['name']}={c.get('value','')}")
|
||||
cookie_str = "; ".join(parts)
|
||||
finally:
|
||||
import shutil
|
||||
try:
|
||||
shutil.rmtree(ud, ignore_errors=True)
|
||||
except Exception:
|
||||
pass
|
||||
return cookie_str if len(cookie_str) > 200 else ""
|
||||
|
||||
|
||||
def collect_cookie_from_browsers() -> str:
|
||||
"""从本机所有浏览器收集飞书相关 Cookie,合并为最完整的字符串。"""
|
||||
cookies_by_name = {}
|
||||
domains = ("cunkebao.feishu.cn", "feishu.cn", ".feishu.cn")
|
||||
loaders = []
|
||||
|
||||
try:
|
||||
import browser_cookie3
|
||||
loaders = [
|
||||
("Safari", browser_cookie3.safari),
|
||||
("Chrome", browser_cookie3.chrome),
|
||||
("Chromium", browser_cookie3.chromium),
|
||||
("Firefox", browser_cookie3.firefox),
|
||||
("Edge", browser_cookie3.edge),
|
||||
]
|
||||
except ImportError:
|
||||
print("提示: pip install browser_cookie3 可自动读取浏览器 Cookie", file=sys.stderr)
|
||||
return ""
|
||||
|
||||
for domain in domains:
|
||||
for name, loader in loaders:
|
||||
try:
|
||||
cj = loader(domain_name=domain)
|
||||
for c in cj:
|
||||
cookies_by_name[c.name] = c.value
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
if not cookies_by_name:
|
||||
return ""
|
||||
return "; ".join(f"{k}={v}" for k, v in cookies_by_name.items())
|
||||
|
||||
|
||||
def fetch_csrf_from_list_api(cookie: str) -> str:
|
||||
"""访问妙记 list API,从响应中获取并合并 bv_csrf_token(若存在)。"""
|
||||
try:
|
||||
import requests
|
||||
session = requests.Session()
|
||||
session.headers.update({
|
||||
"User-Agent": USER_AGENT,
|
||||
"cookie": cookie,
|
||||
"referer": "https://cunkebao.feishu.cn/minutes/",
|
||||
})
|
||||
r = session.get(f"{LIST_URL}?size=5&space_name=1", timeout=15)
|
||||
# 从响应头获取新设置的 cookie
|
||||
for c in session.cookies:
|
||||
if "csrf" in c.name.lower() or "bv" in c.name.lower():
|
||||
return f"{cookie}; {c.name}={c.value}"
|
||||
# 若 API 返回 data 中含 token 也尝试
|
||||
if r.status_code == 200 and r.headers.get("content-type", "").startswith("application/json"):
|
||||
j = r.json()
|
||||
if j.get("code") == 0:
|
||||
token = (j.get("data") or {}).get("csrf_token") or (j.get("data") or {}).get("bv_csrf_token")
|
||||
if token:
|
||||
return f"{cookie}; bv_csrf_token={token}"
|
||||
except Exception:
|
||||
pass
|
||||
return cookie
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = __import__("argparse").ArgumentParser()
|
||||
parser.add_argument("--from", "-f", type=int, default=100, dest="from_num")
|
||||
parser.add_argument("--to", "-t", type=int, default=105, dest="to_num")
|
||||
args = parser.parse_args()
|
||||
|
||||
print("🔄 获取飞书妙记 Cookie(确保导出无 401)…")
|
||||
for attempt in range(3):
|
||||
if attempt == 0:
|
||||
print(" [方式1] 用 Chrome 打开妙记页…")
|
||||
cookie = collect_cookie_via_default_browser()
|
||||
elif attempt == 1:
|
||||
print(" [方式2] 用 Playwright 弹出登录窗口…")
|
||||
cookie = collect_cookie_via_playwright_standalone()
|
||||
else:
|
||||
print(" [重试] 再次从浏览器读取…")
|
||||
time.sleep(5)
|
||||
cookie = collect_cookie_from_browsers()
|
||||
if not cookie or len(cookie) < 100:
|
||||
continue
|
||||
cookie = fetch_csrf_from_list_api(cookie)
|
||||
print(" Cookie 长度:", len(cookie))
|
||||
print(" 验证导出接口…")
|
||||
if verify_cookie(cookie):
|
||||
print(" ✅ Cookie 验证通过,可正常导出")
|
||||
break
|
||||
print(" ❌ 验证失败(401),请确保已在浏览器中登录妙记")
|
||||
if attempt < 2:
|
||||
print(" 60 秒后重试,请完成登录…")
|
||||
time.sleep(60)
|
||||
else:
|
||||
print("⚠️ Cookie 验证未通过,改用「页面内直接导出」模式…")
|
||||
return run_playwright_page_export(args.from_num, args.to_num)
|
||||
|
||||
if not verify_cookie(cookie):
|
||||
print("❌ Cookie 验证仍失败,改用「页面内直接导出」模式…")
|
||||
return run_playwright_page_export(args.from_num, args.to_num)
|
||||
|
||||
backup = COOKIE_FILE.with_suffix(".txt.bak") if COOKIE_FILE.exists() else None
|
||||
if backup:
|
||||
backup.write_text(COOKIE_FILE.read_text(encoding="utf-8"), encoding="utf-8")
|
||||
COOKIE_FILE.write_text(
|
||||
cookie + "\n# 自动从浏览器提取,可手动覆盖",
|
||||
encoding="utf-8",
|
||||
)
|
||||
print("✅ 已写入 cookie_minutes.txt")
|
||||
|
||||
cmd = [
|
||||
sys.executable,
|
||||
str(SCRIPT_DIR / "download_soul_minutes_101_to_103.py"),
|
||||
"--from", str(args.from_num),
|
||||
"--to", str(args.to_num),
|
||||
]
|
||||
print("🔄 执行导出…")
|
||||
return subprocess.call(cmd, cwd=str(SCRIPT_DIR))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
@@ -1,2 +1,2 @@
|
||||
PASTE_YOUR_FEISHU_COOKIE_HERE
|
||||
# Get from: cunkebao.feishu.cn/minutes/home -> search "soul 派对" -> F12 -> Network -> list request -> copy Cookie header
|
||||
bv_csrf_token=8e0d42fe-edf3-4a3b-bbfd-541fa432adf6; m_e09b70=38653064343266652d656466332d346133622d626266642d353431666134333261646636b37b91f4efa89b27b410d5626626f1b2ebf3ed82d6b510030362344fb5776178; minutes_csrf_token=4619adeb-6d49-4964-8997-46d4b61cc526; m_ce8f16=34363139616465622d366434392d343936342d383939372d343664346236316363353236b37b91f4efa89b27b410d5626626f1b2ebf3ed82d6b510030362344fb5776178; passport_web_did=7514522919465811987; passport_trace_id=7514522919485292563; QXV0aHpDb250ZXh0=88883e53c92e44849a1e82932de0599b; session=XN0YXJ0-583m169b-79c6-44bf-8307-f48b160bde22-WVuZA; session_list=XN0YXJ0-583m169b-79c6-44bf-8307-f48b160bde22-WVuZA; swp_csrf_token=ba6718bb-4f76-4b86-a8d8-28c0117357e4; t_beda37=5bc818690404cb6332040fc5ed75a7e8be61177a6b1d75dd2a322245f11e63f7; msToken=ECH70c3RMEWL6kSLDGuH1CmpTYiLDVziBxfgHQlDdL8JWQgimkjy-kZQ1MQLfn2jOg1pvRhZchLDei7pMJkAz7bgniCoCiwUOYxRWQNXOeglKu41BxVhSTqkFgfX6qGN1pbwincoWE4jyxiyAAOctkQrjJGp1I9nFqKV_3ouXNJCgvk4iNwoZg==
|
||||
# 自动从浏览器提取,可手动覆盖
|
||||
2
02_卡人(水)/水桥_平台对接/智能纪要/脚本/cookie_minutes.txt.bak
Normal file
2
02_卡人(水)/水桥_平台对接/智能纪要/脚本/cookie_minutes.txt.bak
Normal file
@@ -0,0 +1,2 @@
|
||||
bv_csrf_token=8e0d42fe-edf3-4a3b-bbfd-541fa432adf6; m_e09b70=38653064343266652d656466332d346133622d626266642d353431666134333261646636b37b91f4efa89b27b410d5626626f1b2ebf3ed82d6b510030362344fb5776178; minutes_csrf_token=4619adeb-6d49-4964-8997-46d4b61cc526; m_ce8f16=34363139616465622d366434392d343936342d383939372d343664346236316363353236b37b91f4efa89b27b410d5626626f1b2ebf3ed82d6b510030362344fb5776178; passport_web_did=7514522919465811987; passport_trace_id=7514522919485292563; QXV0aHpDb250ZXh0=88883e53c92e44849a1e82932de0599b; session=XN0YXJ0-583m169b-79c6-44bf-8307-f48b160bde22-WVuZA; session_list=XN0YXJ0-583m169b-79c6-44bf-8307-f48b160bde22-WVuZA; swp_csrf_token=ba6718bb-4f76-4b86-a8d8-28c0117357e4; t_beda37=5bc818690404cb6332040fc5ed75a7e8be61177a6b1d75dd2a322245f11e63f7; msToken=ECH70c3RMEWL6kSLDGuH1CmpTYiLDVziBxfgHQlDdL8JWQgimkjy-kZQ1MQLfn2jOg1pvRhZchLDei7pMJkAz7bgniCoCiwUOYxRWQNXOeglKu41BxVhSTqkFgfX6qGN1pbwincoWE4jyxiyAAOctkQrjJGp1I9nFqKV_3ouXNJCgvk4iNwoZg==
|
||||
# 自动从浏览器提取,可手动覆盖
|
||||
11
02_卡人(水)/水桥_平台对接/智能纪要/脚本/一键导出100-105.sh
Normal file
11
02_卡人(水)/水桥_平台对接/智能纪要/脚本/一键导出100-105.sh
Normal file
@@ -0,0 +1,11 @@
|
||||
#!/bin/bash
|
||||
# 一键导出 100~105 场妙记文字(全自动 Cookie + 导出)
|
||||
# 用法: bash 一键导出100-105.sh
|
||||
cd "$(dirname "$0")"
|
||||
VENV="/tmp/feishu_cookie_venv"
|
||||
if [ ! -d "$VENV" ]; then
|
||||
python3 -m venv /tmp/feishu_cookie_venv
|
||||
/tmp/feishu_cookie_venv/bin/pip install -q browser_cookie3 requests playwright
|
||||
/tmp/feishu_cookie_venv/bin/playwright install chromium
|
||||
fi
|
||||
/tmp/feishu_cookie_venv/bin/python3 auto_cookie_and_export.py --from 100 --to 105
|
||||
145
03_卡木(木)/木果_项目模板/PPT制作/脚本/今日日志阅读总结PPT_毛玻璃.html
Normal file
145
03_卡木(木)/木果_项目模板/PPT制作/脚本/今日日志阅读总结PPT_毛玻璃.html
Normal file
@@ -0,0 +1,145 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=1280, height=720">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { font-family: 'Inter', -apple-system, sans-serif; -webkit-font-smoothing: antialiased; }
|
||||
.slide {
|
||||
width: 1280px; height: 720px; position: relative; overflow: hidden;
|
||||
display: flex; flex-direction: column; padding: 52px 68px;
|
||||
background: linear-gradient(160deg, #F5F7FF 0%, #EFF2FF 55%, #F7F9FF 100%);
|
||||
}
|
||||
.card {
|
||||
background: rgba(255,255,255,0.78);
|
||||
border: 1px solid rgba(255,255,255,0.85);
|
||||
border-radius: 22px;
|
||||
box-shadow: 0 10px 32px rgba(14, 44, 120, 0.08);
|
||||
backdrop-filter: blur(16px);
|
||||
}
|
||||
.title { font-size: 48px; font-weight: 800; color: #1B2A4A; line-height: 1.2; letter-spacing: -0.02em; }
|
||||
.sub { font-size: 22px; color: #5B6B8D; font-weight: 500; }
|
||||
.h2 { font-size: 30px; color: #20345F; font-weight: 700; }
|
||||
.txt { font-size: 20px; color: #304468; line-height: 1.7; }
|
||||
.kpi { font-size: 36px; font-weight: 800; color: #2A4FF8; }
|
||||
.tag { font-size: 14px; color: #5A6C95; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 1 封面 -->
|
||||
<div class="slide" id="slide-1" style="justify-content: center;">
|
||||
<div style="display:flex; align-items:center; gap:42px;">
|
||||
<div style="flex:1;">
|
||||
<p class="tag" style="margin-bottom:14px;">Daily Review · 2026-02-24</p>
|
||||
<h1 class="title" style="margin-bottom:18px;">今日日志与阅读内容总结</h1>
|
||||
<p class="sub">5 个关键文件 · 1 条主流程图 · 输出总结型 PPT</p>
|
||||
</div>
|
||||
<div class="card" style="width:460px; height:300px; overflow:hidden;">
|
||||
<img src="file:///Users/karuo/Documents/卡若Ai的文件夹/图片/daily_summary_cover_ai.png" style="width:100%;height:100%;object-fit:cover;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 2 今日日志总览 -->
|
||||
<div class="slide" id="slide-2">
|
||||
<h2 class="h2" style="margin-bottom:22px;">今日日志总览(Gitea 推送记录)</h2>
|
||||
<div style="display:flex; gap:18px; margin-bottom:20px;">
|
||||
<div class="card" style="flex:1; padding:18px 22px;">
|
||||
<p class="tag">今日同步</p>
|
||||
<p class="kpi">4+</p>
|
||||
<p class="txt" style="font-size:16px;">凌晨到上午持续自动同步</p>
|
||||
</div>
|
||||
<div class="card" style="flex:1; padding:18px 22px;">
|
||||
<p class="tag">主更新范围</p>
|
||||
<p class="txt" style="margin-top:8px;">水桥平台对接、运营中枢工作台、卡木相关能力</p>
|
||||
</div>
|
||||
<div class="card" style="flex:1; padding:18px 22px;">
|
||||
<p class="tag">稳定性</p>
|
||||
<p class="txt" style="margin-top:8px;">推送连续成功,单次大文件排除维持在 10 个</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" style="padding:20px 24px; flex:1; overflow:hidden;">
|
||||
<p class="txt">今天日志体现了「高频迭代 + 持续落库」节奏,节拍集中在技能升级、工作台同步、平台接入优化三条线。</p>
|
||||
<img src="file:///Users/karuo/Documents/卡若Ai的文件夹/图片/daily_summary_reading_ai.png" style="width:100%;height:320px;object-fit:cover;border-radius:14px;margin-top:12px;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3 5 文件清单 -->
|
||||
<div class="slide" id="slide-3">
|
||||
<h2 class="h2" style="margin-bottom:18px;">本次总结文件(不超过 5 个)</h2>
|
||||
<div class="card" style="padding:20px 24px;">
|
||||
<p class="txt">1) `运营中枢/工作台/gitea_push_log.md`:今日同步节奏与范围</p>
|
||||
<p class="txt">2) `.../PPT制作/SKILL.md`:PPT v5.0,强制每页配图+图标</p>
|
||||
<p class="txt">3) `.../Next AI Draw/SKILL.md`:AI 架构图/流程图能力</p>
|
||||
<p class="txt">4) `.../next-ai-draw-io_基因胶囊吸收.md`:GitHub 项目吸收记录</p>
|
||||
<p class="txt">5) `.../卡若个人介绍/SKILL.md`:个人介绍标准输出能力</p>
|
||||
</div>
|
||||
<div style="display:flex; gap:16px; margin-top:16px;">
|
||||
<div class="card" style="flex:1; padding:16px 20px;">
|
||||
<p class="tag">阅读结论 A</p>
|
||||
<p class="txt">能力已从「做 PPT」升级到「做内容 + 做图 + 做叙事」。</p>
|
||||
</div>
|
||||
<div class="card" style="flex:1; padding:16px 20px;">
|
||||
<p class="tag">阅读结论 B</p>
|
||||
<p class="txt">Next AI Draw 已具备并入 PPT 体系的可执行路径。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4 流程图 -->
|
||||
<div class="slide" id="slide-4">
|
||||
<h2 class="h2" style="margin-bottom:16px;">核心流程图:日志与阅读内容如何沉淀为可交付 PPT</h2>
|
||||
<div style="display:flex; gap:16px; flex:1;">
|
||||
<div class="card" style="flex:1.15; padding:18px;">
|
||||
<div style="display:flex; justify-content:space-between; align-items:center; gap:8px;">
|
||||
<div class="card" style="padding:12px 14px; width:23%; text-align:center;"><p class="txt" style="font-size:16px;">日志采集</p></div>
|
||||
<p class="txt" style="font-size:22px;">→</p>
|
||||
<div class="card" style="padding:12px 14px; width:23%; text-align:center;"><p class="txt" style="font-size:16px;">阅读提炼</p></div>
|
||||
<p class="txt" style="font-size:22px;">→</p>
|
||||
<div class="card" style="padding:12px 14px; width:23%; text-align:center;"><p class="txt" style="font-size:16px;">流程建模</p></div>
|
||||
<p class="txt" style="font-size:22px;">→</p>
|
||||
<div class="card" style="padding:12px 14px; width:23%; text-align:center;"><p class="txt" style="font-size:16px;">PPT交付</p></div>
|
||||
</div>
|
||||
<div class="card" style="margin-top:14px; padding:14px;">
|
||||
<p class="txt" style="font-size:18px;">联动点:Next AI Draw(架构/流程图) + PPT 制作(配图+图标+版式)</p>
|
||||
</div>
|
||||
<div style="display:flex; gap:10px; margin-top:10px;">
|
||||
<div class="card" style="flex:1; padding:12px;"><p class="txt" style="font-size:15px;">输入:日志+5文件</p></div>
|
||||
<div class="card" style="flex:1; padding:12px;"><p class="txt" style="font-size:15px;">处理中:摘要+图示</p></div>
|
||||
<div class="card" style="flex:1; padding:12px;"><p class="txt" style="font-size:15px;">输出:总结PPT</p></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" style="flex:0.85; overflow:hidden;">
|
||||
<img src="file:///Users/karuo/Documents/卡若Ai的文件夹/图片/daily_summary_flow_ai.png" style="width:100%;height:100%;object-fit:cover;">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 5 阅读内容总结 -->
|
||||
<div class="slide" id="slide-5">
|
||||
<h2 class="h2" style="margin-bottom:16px;">阅读内容总结(能力层)</h2>
|
||||
<div class="card" style="padding:20px 24px; margin-bottom:14px;">
|
||||
<p class="txt"><strong>PPT制作 Skill</strong>:已形成「每页配图+图标」硬规则,并可调用流程/架构图能力。</p>
|
||||
<p class="txt"><strong>Next AI Draw Skill</strong>:打通自然语言→图(draw.io/Mermaid)能力,适合中间逻辑页。</p>
|
||||
<p class="txt"><strong>基因胶囊吸收记录</strong>:对 next-ai-draw-io 完成结构化吸收,可复用、可追溯。</p>
|
||||
<p class="txt"><strong>卡若个人介绍 Skill</strong>:沉淀固定人设信息,支持 PPT/短文/一页纸输出。</p>
|
||||
</div>
|
||||
<div class="card" style="padding:16px 20px;">
|
||||
<p class="txt" style="font-size:18px;">结论:今天的核心进展是把「内容能力 + 图示能力 + 交付能力」串成完整闭环。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 6 结果与下一步 -->
|
||||
<div class="slide" id="slide-6" style="justify-content:center;">
|
||||
<h2 class="h2" style="margin-bottom:20px;">结果与下一步</h2>
|
||||
<div class="card" style="padding:24px 28px; margin-bottom:14px;">
|
||||
<p class="txt">✅ 今日成果:日志总结、5 文件阅读总结、流程图、配图版 PPT 一次成型。</p>
|
||||
<p class="txt">✅ 可复用:同模板可直接用于每日复盘/周报/项目阶段汇报。</p>
|
||||
<p class="txt">▶ 下一步:把流程图页升级为可自动替换节点内容的模板化组件。</p>
|
||||
</div>
|
||||
<p class="sub">输出文件:今日日志阅读总结_毛玻璃.pptx</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -63,7 +63,7 @@ def build_ppt(imgs, out_ppt):
|
||||
def main():
|
||||
import argparse
|
||||
ap = argparse.ArgumentParser()
|
||||
ap.add_argument("--html", default="复盘", choices=["复盘", "卡若人设", "纳瓦尔访谈", "天恩乖乖"])
|
||||
ap.add_argument("--html", default="复盘", choices=["复盘", "卡若人设", "纳瓦尔访谈", "天恩乖乖", "今日日志总结"])
|
||||
args = ap.parse_args()
|
||||
if args.html == "卡若人设":
|
||||
html = BASE / "卡若人设PPT_毛玻璃.html"
|
||||
@@ -80,6 +80,11 @@ def main():
|
||||
out_slides = TIANEN_DIR / "乖乖_毛玻璃_slides"
|
||||
out_ppt = TIANEN_DIR / "我和乖乖的故事_高级版.pptx"
|
||||
max_slides = 10
|
||||
elif args.html == "今日日志总结":
|
||||
html = BASE / "今日日志阅读总结PPT_毛玻璃.html"
|
||||
out_slides = OUT_ROOT / "今日日志总结_毛玻璃_slides"
|
||||
out_ppt = OUT_ROOT / "今日日志阅读总结_毛玻璃.pptx"
|
||||
max_slides = 6
|
||||
else:
|
||||
html = BASE / "复盘PPT_毛玻璃.html"
|
||||
out_slides = OUT_ROOT / "复盘_毛玻璃_slides"
|
||||
|
||||
@@ -1,43 +1,96 @@
|
||||
---
|
||||
name: 公司财务
|
||||
description: 芸归喜、卡卡猫等公司主体的收支、月度报表、工资表。仅公司开支,不含家庭。触发词:公司财务、芸归喜、卡卡猫、公司报表、公司开支。
|
||||
description: 公司财务全链路能力:短信银行流水同步、银行卡号分类与同卡号合并去重、统一流水清洗、多维财务报表生成。仅公司收支,不含家庭财务。触发词:公司财务、芸归喜、卡卡猫、中信0405、网商9532、财务统一分析、短信流水。
|
||||
group: 土
|
||||
triggers: 公司财务、芸归喜、卡卡猫、公司报表、公司开支、中信0405、网商9532
|
||||
triggers: 公司财务、芸归喜、卡卡猫、公司报表、公司开支、中信0405、网商9532、财务统一分析、短信流水、银行卡号分类、同卡号去重、多维财务报表
|
||||
owner: 土簿
|
||||
version: "1.0"
|
||||
updated: "2026-02-08"
|
||||
version: "2.0"
|
||||
updated: "2026-02-24"
|
||||
parent: 财务管理
|
||||
---
|
||||
|
||||
# 公司财务
|
||||
|
||||
卡若名下公司主体的财务汇总、月度报表、工资表。**仅含公司收支,不含家庭财务**。
|
||||
卡若公司主体财务能力中心。覆盖**数据同步 → 银行卡号分类 → 同卡号合并去重 → 统一分析 → 多维报表输出**的完整链路。
|
||||
**仅含公司收支,不含家庭财务。**
|
||||
|
||||
## 关联路径
|
||||
## 一、能力边界
|
||||
|
||||
| 项目 | 路径 |
|
||||
|:---|:---|
|
||||
| 月度报表 | `4、财务/报告/`(如 2026年1月财务报表_完整表格.md、2026年2月财务报表_完整表格.md) |
|
||||
| 工资表 | `4、财务/报告/`(如 2026年2月工资表.md) |
|
||||
| 重点机构交易明细 | `4、财务/财务报表/重点机构与主体_交易明细.csv` |
|
||||
| 数据解析脚本 | `4、财务/scripts/parse_feb_2026_data.py` |
|
||||
- 包含:卡卡猫(中信 0405)、芸归喜(网商 9532)、公司短信银行流水、公司统一财务分析
|
||||
- 包含:银行卡号维度分类、同银行卡号合并、同卡号流水去重
|
||||
- 包含:统一流水 CSV、统一统计分析报告、多维财务报表
|
||||
- 不含:家庭财务、鲨鱼记账
|
||||
|
||||
## 核心能力
|
||||
## 二、接口清单(文件 / 脚本 / 输出)
|
||||
|
||||
1. **报表**:生成/更新公司月度财务报表(芸归喜、卡卡猫、云消费、飞书工资)
|
||||
2. **数据来源**:中信 0405(**卡卡猫**)、网商 9532(**芸归喜**)、腾讯云、飞书钱袋子
|
||||
3. **执行**:运行 `parse_feb_2026_data.py [YYYY-MM]` 解析指定月份后更新报表
|
||||
### 2.1 数据输入接口(Data Interface)
|
||||
|
||||
## 报表范围(仅公司)
|
||||
| 接口 | 路径 | 说明 |
|
||||
|:---|:---|:---|
|
||||
| 支付宝原始流水 | `4、财务/alipay_finance_sync/out/alipay_transactions.csv` | 支付宝交易明细(含时间、金额、对方) |
|
||||
| 银行短信原始流水 | `4、财务/sms_finance_sync/out/raw_sms_all_banks.csv` | 从短信提取的银行流水(含 bank-card 维度) |
|
||||
| 公司收支明细 | `4、财务/报告/公司收支全明细_202512-202602.md` | 卡卡猫/芸归喜对公明细(用于同卡号合并) |
|
||||
|
||||
- 云消费(腾讯云)
|
||||
- 卡卡猫(中信 0405)收支
|
||||
- 芸归喜(网商 9532)收支
|
||||
- 飞书·工资/报销
|
||||
- **不含**:家庭、鲨鱼记账
|
||||
### 2.2 能力执行接口(Function Interface)
|
||||
|
||||
## 生成月度报表步骤
|
||||
| 功能接口 | 命令 | 作用 |
|
||||
|:---|:---|:---|
|
||||
| 短信全量同步 | `python3 4、财务/sms_finance_sync/sync_full_history.py --source mac` | 拉取短信流水,识别银行+卡号 |
|
||||
| 财务清洗去重 | `python3 4、财务/finance_analyze_dedup.py` | 合并来源、同卡号去重、输出统一流水 |
|
||||
| 多维报表生成 | `python3 4、财务/generate_finance_report.py` | 生成年度/季度/月度/账户等多维报表 |
|
||||
|
||||
1. 执行 `python3 4、财务/scripts/parse_feb_2026_data.py YYYY-MM` 获取数据
|
||||
2. 更新 `4、财务/报告/YYYY年MM月财务报表_完整表格.md`
|
||||
3. 工资表从飞书钱袋子「2026年卡若公司工资表」同步
|
||||
### 2.3 输出接口(Report Interface)
|
||||
|
||||
| 输出 | 路径 | 说明 |
|
||||
|:---|:---|:---|
|
||||
| 统一流水(含日期时间) | `4、财务/报告/统一流水/统一财务流水_含日期时间.csv` | 全量流水,含账户(银行-卡号)与重复标记 |
|
||||
| 统一流水(去重后) | `4、财务/报告/统一流水/统一财务流水_去重后.csv` | 同卡号合并后去重结果 |
|
||||
| 内容分析汇总 | `4、财务/报告/统一流水/内容分析汇总.md` | 类型、账户分布、去重说明 |
|
||||
| 财务统一统计分析报告 | `4、财务/报告/财务统一统计分析报告.md` | 综合口径主报告 |
|
||||
| 财务报表·多维分析 | `4、财务/报告/财务报表_多维分析.md` | 多维度深度报表 |
|
||||
|
||||
## 三、核心规则(必须执行)
|
||||
|
||||
1. **银行卡号分类**:不同银行分开;同银行不同卡号分开(如 `中信银行-0405`、`网商银行-9532`)
|
||||
2. **同卡号合并**:短信和公司收支中同银行卡号视为同账户(例:卡卡猫 = 中信银行-0405)
|
||||
3. **同卡号去重**:同账户内,`同日期 + 同金额 + 同方向 + 同对方` 直接去重
|
||||
4. **日期时间完整性**:所有统一流水必须包含日期与时间节点
|
||||
|
||||
## 四、标准执行流程
|
||||
|
||||
1. 更新短信流水:`sync_full_history.py`
|
||||
2. 执行清洗去重:`finance_analyze_dedup.py`
|
||||
3. 生成多维报表:`generate_finance_report.py`
|
||||
4. 更新主报告:`财务统一统计分析报告.md`
|
||||
|
||||
## 五、快速执行模板
|
||||
|
||||
```bash
|
||||
cd "/Users/karuo/Documents/个人/4、财务"
|
||||
|
||||
# 1) 短信同步(银行+卡号)
|
||||
cd sms_finance_sync && python3 sync_full_history.py --source mac && cd ..
|
||||
|
||||
# 2) 统一清洗+同卡号合并去重
|
||||
python3 finance_analyze_dedup.py
|
||||
|
||||
# 3) 多维财务报表
|
||||
python3 generate_finance_report.py
|
||||
```
|
||||
|
||||
## 六、验收标准
|
||||
|
||||
- 已按银行-卡号分组统计
|
||||
- 已合并卡卡猫=中信银行-0405
|
||||
- 已完成同卡号去重
|
||||
- 已生成统一流水与多维财务报表
|
||||
- 报表含年度、季度、月度、账户、来源、内容类型、Top 对方等维度
|
||||
|
||||
## 七、基因胶囊打包入口
|
||||
|
||||
```bash
|
||||
cd "/Users/karuo/Documents/个人/卡若AI"
|
||||
python3 "05_卡土(土)/土砖_技能复制/基因胶囊/脚本/gene_capsule.py" pack "公司财务"
|
||||
```
|
||||
|
||||
> 本 Skill 已内嵌完整接口清单与功能清单,打包后会随 `skill_content` 一并进入基因胶囊。
|
||||
|
||||
@@ -123,3 +123,4 @@
|
||||
| 2026-02-24 05:39:42 | 🔄 卡若AI 同步 2026-02-24 05:39 | 更新:水桥平台对接、运营中枢工作台 | 排除 >20MB: 10 个 |
|
||||
| 2026-02-24 05:43:39 | 🔄 卡若AI 同步 2026-02-24 05:43 | 更新:Cursor规则、总索引与入口、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 10 个 |
|
||||
| 2026-02-24 05:49:20 | 🔄 卡若AI 同步 2026-02-24 05:49 | 更新:卡木、总索引与入口、运营中枢工作台 | 排除 >20MB: 10 个 |
|
||||
| 2026-02-24 11:42:10 | 🔄 卡若AI 同步 2026-02-24 11:42 | 更新:金仓、水桥平台对接、运营中枢工作台 | 排除 >20MB: 10 个 |
|
||||
|
||||
@@ -126,3 +126,4 @@
|
||||
| 2026-02-24 05:39:42 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-24 05:39 | 更新:水桥平台对接、运营中枢工作台 | 排除 >20MB: 10 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
| 2026-02-24 05:43:39 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-24 05:43 | 更新:Cursor规则、总索引与入口、运营中枢参考资料、运营中枢工作台 | 排除 >20MB: 10 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
| 2026-02-24 05:49:20 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-24 05:49 | 更新:卡木、总索引与入口、运营中枢工作台 | 排除 >20MB: 10 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
| 2026-02-24 11:42:10 | 成功 | 成功 | 🔄 卡若AI 同步 2026-02-24 11:42 | 更新:金仓、水桥平台对接、运营中枢工作台 | 排除 >20MB: 10 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
|
||||
|
||||
Reference in New Issue
Block a user