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

This commit is contained in:
2026-03-02 02:35:49 +08:00
parent 2c699c1563
commit 1e31a54573
6 changed files with 292 additions and 60 deletions

View File

@@ -1,11 +1,11 @@
---
name: 飞书管理
description: 飞书日志/文档自动写入与知识库管理
triggers: 飞书日志、写入飞书、飞书知识库、飞书运营报表、派对效果数据、104场写入、运营报表填写、派对截图填表发群、Excel写飞书、批量写飞书表格、表格日报、卡若的飞书日志、卡若飞书日志
triggers: 飞书日志、写入飞书、飞书知识库、飞书运营报表、派对效果数据、104场写入、运营报表填写、派对截图填表发群、Excel写飞书、批量写飞书表格、表格日报、卡若的飞书日志、卡若飞书日志、上传json飞书、json上传飞书文档、按原格式上传飞书
owner: 水桥
group: 水
version: "1.2"
updated: "2026-02-25"
version: "1.3"
updated: "2026-03-02"
---
# 飞书日志写入 Skill
@@ -349,6 +349,29 @@ JSON 格式:与 `团队入职流程与新人登记表_feishu_blocks.json` 相
---
## 飞书导出 JSON 按原格式上传
将飞书导出的 JSON 文件(含 `content` + `blocks`**按原有类型**上传为 Wiki 子文档:文档保持文档、多维表格会新建多维表格并嵌入、问卷/思维笔记等按 JSON 内类型还原。
**规则**:原 JSON 里是什么格式就生成什么格式;不把多维表格/看板换成链接,直接生成对应文档或多维表格块。
```bash
# 上传单个导出 JSON默认父节点日记/新研究)
python3 脚本/upload_json_to_feishu_doc.py /path/to/xxx.json
# 指定父节点与标题
python3 脚本/upload_json_to_feishu_doc.py /path/to/xxx.json --parent <wiki_node_token> --title "文档标题"
```
- **block_type 2**:正文 → 正文块
- **block_type 3/4/6**:标题 → 对应标题块
- **block_type 43board/bitable**:多维表格 → 在云空间新建多维表格bitable并将该块嵌入文档
- 其他类型todo、callout 等)按导出结构透传
应用需具备「创建多维表格」权限;若无权限,多维表格块会退化为一段说明文字。
---
## 统一文章上传(强制入口)
用于“本地 Markdown → 飞书 Wiki 文档”的统一发布。
@@ -424,6 +447,7 @@ python3 script.py --arg value
├── feishu_video_clip_README.md
├── wanzhi_feishu_project_sync.py # 玩值电竞→飞书项目同步
├── feishu_wiki_create_doc.py # Wiki 子文档创建(日记/研究)
├── upload_json_to_feishu_doc.py # 飞书导出 JSON 按原格式上传(文档/多维表格/问卷等)
└── .feishu_tokens.json # Token 存储
```

View File

@@ -32,6 +32,7 @@
| 18 | 画廊 | `gallery` | `gallery.imageList[].fileToken`,单图也可用 |
| 19 | 高亮块 | `callout` | `callout.background_color``border_color``emoji_id`(如 sunrise |
| 27 | 图片(导出) | `image` | 导出用;**写入用 12 file**,先 `drive/v1/medias/upload_all` 上传 |
| 43 | 多维表格 | `board`/`bitable` | 导出为 `board.token`;写入用 `bitable.token`。按原格式上传时由 `upload_json_to_feishu_doc.py` 新建多维表格并嵌入 |
---

View File

@@ -1,12 +1,15 @@
#!/usr/bin/env python3
"""
将飞书导出的 JSON 文件(含 content + blocks上传为飞书 Wiki 子文档。
用法: python3 upload_json_to_feishu_doc.py /path/to/水流程规划.json
将飞书导出的 JSON 文件(含 content + blocks按**原有格式**上传为飞书 Wiki 子文档。
- 文档→文档多维表格→多维表格block_type 43 会新建多维表格并嵌入),问卷/思维笔记等按类型还原。
用法: python3 upload_json_to_feishu_doc.py /path/to/xxx.json
可选: --parent <wiki_node_token> --title "文档标题"
"""
import json
import sys
import time
import argparse
import requests
from pathlib import Path
SCRIPT_DIR = Path(__file__).resolve().parent
@@ -18,37 +21,65 @@ from feishu_wiki_create_doc import create_wiki_doc, get_token, CONFIG
DEFAULT_PARENT = "KNf7wA8Rki1NSdkkSIqcdFtTnWb"
def _text_block(content: str):
return {
"block_type": 2,
"text": {
"elements": [{"text_run": {"content": content, "text_element_style": {}}}],
"style": {},
},
}
def _to_api_block(b: dict) -> dict | None:
"""将导出块转为 API 可用的块(去掉 block_id、parent_id保留 block_type 与类型字段)。"""
bt = b.get("block_type")
out = {"block_type": bt}
if bt == 2 and b.get("text"):
out["text"] = b["text"]
elif bt == 3 and b.get("heading1"):
out["heading1"] = b["heading1"]
elif bt == 4 and b.get("heading2"):
out["heading2"] = b["heading2"]
elif bt == 6 and b.get("heading4"):
out["heading4"] = b["heading4"]
elif bt == 17 and b.get("todo"):
out["todo"] = b["todo"]
elif bt == 19 and b.get("callout"):
out["callout"] = b["callout"]
elif bt == 43:
# 多维表格:导出为 board.tokenAPI 为 bitable.token占位后续用新建的 app_token 替换
token = (b.get("board") or b.get("bitable") or {}).get("token", "")
out["_bitable_placeholder"] = True
out["_bitable_token"] = token # 可能为原文档 token同租户可尝试直接嵌
out["bitable"] = {"token": token or "PLACEHOLDER"}
else:
# 其他类型尽量透传类型字段
for key in ("page", "board", "bitable", "sheet", "mindnote", "poll"):
if key in b and not key.startswith("_"):
out[key] = b[key]
break
if "_bitable_placeholder" not in out and "bitable" not in out and "board" in b:
out["_bitable_placeholder"] = True
out["bitable"] = {"token": (b.get("board") or {}).get("token", "PLACEHOLDER")}
return out
def _heading1_block(content: str):
return {
"block_type": 3,
"heading1": {
"elements": [{"text_run": {"content": content, "text_element_style": {}}}],
"style": {},
},
}
def create_bitable_app(access_token: str, name: str, folder_token: str | None = None) -> str | None:
"""在飞书云空间创建多维表格,返回 app_token。"""
url = "https://open.feishu.cn/open-apis/bitable/v1/apps"
headers = {"Authorization": f"Bearer {access_token}", "Content-Type": "application/json"}
payload = {"name": name or "多维表格"}
if folder_token:
payload["folder_token"] = folder_token
r = requests.post(url, headers=headers, json=payload, timeout=30)
data = r.json()
if data.get("code") == 0:
return data.get("data", {}).get("app_token")
return None
def blocks_from_export_json(data: dict) -> tuple[str, list]:
"""
从飞书导出格式content + blocks解析出标题和可写入的 children 列表。
多维表格block_type 43/board会产出占位块需在获得 token 后调用 resolve_bitable_placeholders 替换。
返回 (title, children)。
"""
blocks = data.get("blocks") or []
if not blocks:
title = (data.get("content") or "未命名").split("\n")[0].strip() or "未命名"
return title, [_heading1_block(title)]
return title, [{"block_type": 3, "heading1": {"elements": [{"text_run": {"content": title, "text_element_style": {}}}], "style": {}}}]
# 找根块block_type 1 page 或 parent_id 为空)
root = None
by_id = {}
for b in blocks:
@@ -58,9 +89,8 @@ def blocks_from_export_json(data: dict) -> tuple[str, list]:
if not root:
title = (data.get("content") or "未命名").split("\n")[0].strip() or "未命名"
return title, [_heading1_block(title)]
return title, [{"block_type": 3, "heading1": {"elements": [{"text_run": {"content": title, "text_element_style": {}}}], "style": {}}}]
# 标题:从 page 或 content 第一行取
title = "未命名"
if root.get("page") and root["page"].get("elements"):
for el in root["page"]["elements"]:
@@ -73,7 +103,7 @@ def blocks_from_export_json(data: dict) -> tuple[str, list]:
child_ids = root.get("children") or []
children = []
children.append(_heading1_block(title))
children.append({"block_type": 3, "heading1": {"elements": [{"text_run": {"content": title, "text_element_style": {}}}], "style": {}}})
for bid in child_ids:
b = by_id.get(bid)
@@ -82,24 +112,44 @@ def blocks_from_export_json(data: dict) -> tuple[str, list]:
bt = b.get("block_type")
if bt == 2 and b.get("text"):
els = b["text"].get("elements") or []
content = ""
for el in els:
content += el.get("text_run", {}).get("content", "")
content = content.strip()
if content:
children.append(_text_block(content))
# 空段落可跳过,也可保留一行空
elif bt == 43 and b.get("board"):
# 多维表格/看板API 可能不支持直接插入,用说明占位
token = b["board"].get("token", "")
children.append(_text_block("(原文档含多维表格/看板,可在原链接中查看)"))
# 其他类型可后续扩展
content = "".join(el.get("text_run", {}).get("content", "") for el in els).strip()
if not content:
continue
style = b["text"].get("style", {})
el_style = (b["text"].get("elements") or [{}])[0].get("text_element_style", {})
children.append({"block_type": 2, "text": {"elements": [{"text_run": {"content": content, "text_element_style": el_style}}], "style": style}})
elif bt == 43 and (b.get("board") or b.get("bitable")):
token = (b.get("board") or b.get("bitable") or {}).get("token", "")
children.append({"_bitable_placeholder": True, "block_type": 43, "bitable": {"token": token}, "name": "流量来源"})
elif bt not in (2, 43):
api_block = _to_api_block(b)
if api_block and not api_block.get("_bitable_placeholder"):
children.append(api_block)
return title, children
def resolve_bitable_placeholders(children: list, access_token: str, default_name: str = "多维表格") -> list:
"""将 children 中的 _bitable_placeholder 替换为新建的多维表格块block_type 43 + bitable.token"""
out = []
for i, c in enumerate(children):
if isinstance(c, dict) and c.get("_bitable_placeholder") and c.get("block_type") == 43:
name = c.get("name") or default_name
app_token = create_bitable_app(access_token, name)
if app_token:
out.append({"block_type": 43, "bitable": {"token": app_token}})
time.sleep(0.4)
else:
out.append({"block_type": 2, "text": {"elements": [{"text_run": {"content": "(多维表格创建失败,请手动插入)", "text_element_style": {}}}], "style": {}}})
else:
c_copy = {k: v for k, v in (c or {}).items() if not k.startswith("_")}
if c_copy:
out.append(c_copy)
return out
def main():
ap = argparse.ArgumentParser(description="将飞书导出 JSON 上传为飞书 Wiki 文档")
ap = argparse.ArgumentParser(description="将飞书导出 JSON 按原格式上传为飞书 Wiki 文档")
ap.add_argument("json_path", help="JSON 文件路径(含 content + blocks")
ap.add_argument("--parent", default=DEFAULT_PARENT, help="Wiki 父节点 token")
ap.add_argument("--title", default=None, help="覆盖文档标题(默认从 JSON 解析)")
@@ -117,8 +167,15 @@ def main():
if args.title:
title = args.title
token = get_token(args.parent)
if not token:
print("❌ 无法获取飞书 Token")
sys.exit(1)
children = resolve_bitable_placeholders(children, token, default_name="流量来源")
print("=" * 50)
print(f"📤 上传为飞书文档:{title}")
print(f"📤 上传为飞书文档(按原格式){title}")
print(f" 父节点: {args.parent}")
print(f" 块数: {len(children)}")
print("=" * 50)

View File

@@ -93,34 +93,182 @@ def _font(size: int):
return ImageFont.load_default()
def _radial_gradient(img, cx, cy, r_inner, r_outer, c_center, c_edge):
"""从中心到边缘的径向渐变"""
from PIL import ImageDraw
W, H = img.size
pix = img.load()
for y in range(H):
for x in range(W):
d = ((x - cx) ** 2 + (y - cy) ** 2) ** 0.5
t = min(1.0, max(0.0, (d - r_inner) / (r_outer - r_inner))) if r_outer > r_inner else 0
r = int(c_center[0] + (c_edge[0] - c_center[0]) * t)
g = int(c_center[1] + (c_edge[1] - c_center[1]) * t)
b = int(c_center[2] + (c_edge[2] - c_center[2]) * t)
pix[x, y] = (max(0, min(255, r)), max(0, min(255, g)), max(0, min(255, b)))
def _draw_speed_lines(draw, W, H, n=40, color=(255, 220, 230, 80)):
"""漫画速度线(从一角放射)"""
import random
random.seed(42)
for _ in range(n):
x0, y0 = random.randint(0, W // 3), random.randint(0, H // 3)
dx, dy = random.randint(W // 2, W), random.randint(H // 2, H)
draw.line([(x0, y0), (x0 + dx, y0 + dy)], fill=(color[0], color[1], color[2]), width=2)
def _draw_vignette(img, strength=0.4):
"""四角暗角"""
from PIL import ImageDraw
W, H = img.size
overlay = Image.new("RGBA", (W, H), (0, 0, 0, 0))
draw = ImageDraw.Draw(overlay)
for y in range(H):
for x in range(W):
nx, ny = 2 * x / W - 1, 2 * y / H - 1
d = (nx * nx + ny * ny) ** 0.5
a = int(255 * strength * min(1, d * 1.2))
if a > 0:
draw.point((x, y), fill=(0, 0, 0, a))
out = Image.new("RGB", (W, H))
out.paste(img, (0, 0))
from PIL import Image
out.paste(overlay, (0, 0), overlay)
return out
def generate_with_pil():
"""用 PIL 绘制 5 张漫画风格占位图(渐变+标题+简单构图"""
"""用 PIL 绘制 5 张漫画风格插画(双人剪影+光效+速度线+层次"""
from PIL import Image, ImageDraw
W, H = 1024, 1024
OUT_DIR.mkdir(parents=True, exist_ok=True)
titles = ["场景1 · 蒙眼拥抱", "场景2 · 侧抱", "场景3 · 额相抵", "后续1 · 温柔对视", "后续2 · 并肩"]
colors = [
((180, 100, 120), (80, 40, 60)),
((120, 80, 140), (50, 30, 70)),
((100, 120, 160), (40, 50, 80)),
((140, 160, 180), (60, 70, 90)),
((160, 140, 120), (70, 60, 50)),
# 场景配置:背景中心色、边缘色、剪影色、标题、副标题
scenes = [
{
"center": (220, 160, 200),
"edge": (60, 35, 55),
"silhouette": (45, 30, 45),
"title": "蒙眼拥抱",
"sub": "—— 场景一",
"speed_lines": True,
},
{
"center": (200, 150, 220),
"edge": (50, 40, 70),
"silhouette": (40, 32, 55),
"title": "侧抱",
"sub": "—— 场景二",
"speed_lines": True,
},
{
"center": (210, 170, 230),
"edge": (55, 45, 75),
"silhouette": (42, 35, 58),
"title": "额相抵",
"sub": "—— 场景三",
"speed_lines": True,
},
{
"center": (230, 200, 220),
"edge": (70, 60, 85),
"silhouette": (50, 42, 62),
"title": "温柔对视",
"sub": "—— 后续一",
"speed_lines": False,
},
{
"center": (240, 210, 200),
"edge": (75, 65, 80),
"silhouette": (52, 45, 65),
"title": "并肩",
"sub": "—— 后续二",
"speed_lines": False,
},
]
for (filename, _), title, (c1, c2) in zip(PROMPTS, titles, colors):
for idx, ((filename, _), sc) in enumerate(zip(PROMPTS, scenes)):
out_path = OUT_DIR / filename
img = Image.new("RGB", (W, H))
cx, cy = W // 2, H // 2
_radial_gradient(img, cx, cy, 0, int((W * W + H * H) ** 0.5 * 0.6), sc["center"], sc["edge"])
# 中心柔光
glow = Image.new("RGBA", (W, H), (0, 0, 0, 0))
gdraw = ImageDraw.Draw(glow)
for r in range(350, 100, -15):
alpha = 25 if r > 200 else 15
gdraw.ellipse([cx - r, cy - r, cx + r, cy + r], outline=(255, 245, 255, alpha), width=4)
img.paste(glow, (0, 0), glow)
draw = ImageDraw.Draw(img)
for y in range(H):
t = y / (H - 1)
r = int(c1[0] + (c2[0] - c1[0]) * t)
g = int(c1[1] + (c2[1] - c1[1]) * t)
b = int(c1[2] + (c2[2] - c1[2]) * t)
draw.line([(0, y), (W, y)], fill=(r, g, b))
font = _font(52)
bbox = draw.textbbox((0, 0), title, font=font)
tw = bbox[2] - bbox[0]
draw.text(((W - tw) // 2, H // 2 - 40), title, font=font, fill=(255, 255, 255, 230))
draw.rounded_rectangle([W//4, H//3, 3*W//4, 2*H//3], radius=24, outline=(255, 255, 255, 120), width=3)
s = sc["silhouette"]
if idx == 0:
# 场景1正面拥抱女前男后女有长发+蒙眼带,男环抱)
# 女性剪影:椭圆头+长发轮廓+身体
draw.ellipse([cx - 85, cy - 220, cx + 85, cy - 70], fill=s, outline=(60, 45, 60))
draw.ellipse([cx - 75, cy - 200, cx + 75, cy - 90], fill=(30, 22, 30)) # 蒙眼带区域
draw.polygon([(cx - 95, cy - 80), (cx - 110, cy + 180), (cx - 60, cy + 200), (cx - 50, cy - 60)], fill=s)
draw.polygon([(cx + 95, cy - 80), (cx + 110, cy + 180), (cx + 60, cy + 200), (cx + 50, cy - 60)], fill=s)
draw.ellipse([cx - 70, cy - 30, cx + 70, cy + 120], fill=s)
# 男性剪影:从后环抱
draw.ellipse([cx - 100, cy - 180, cx + 100, cy - 30], fill=(s[0] + 15, s[1] + 12, s[2] + 15))
draw.polygon([(cx - 120, cy - 50), (cx - 130, cy + 220), (cx + 130, cy + 220), (cx + 120, cy - 50)], fill=(s[0] + 15, s[1] + 12, s[2] + 15))
elif idx == 1:
# 场景2侧抱男在侧一手环腰
draw.ellipse([cx - 90, cy - 200, cx + 90, cy - 50], fill=s)
draw.ellipse([cx - 70, cy - 180, cx + 70, cy - 70], fill=(28, 20, 28))
draw.polygon([(cx - 100, cy - 40), (cx - 115, cy + 200), (cx - 55, cy + 210), (cx - 45, cy - 50)], fill=s)
draw.polygon([(cx + 100, cy - 40), (cx + 115, cy + 200), (cx + 55, cy + 210), (cx + 45, cy - 50)], fill=s)
draw.ellipse([cx - 75, cy + 10, cx + 75, cy + 140], fill=s)
# 男性侧影
draw.ellipse([cx + 60, cy - 160, cx + 220, cy + 20], fill=(s[0] + 12, s[1] + 10, s[2] + 12))
draw.polygon([(cx + 80, cy - 20), (cx + 100, cy + 220), (cx + 230, cy + 200), (cx + 200, cy - 40)], fill=(s[0] + 12, s[1] + 10, s[2] + 12))
draw.ellipse([cx + 140, cy - 50, cx + 220, cy + 50], fill=(s[0] + 12, s[1] + 10, s[2] + 12))
elif idx == 2:
# 场景3额相抵、抚发
draw.ellipse([cx - 88, cy - 210, cx + 88, cy - 65], fill=s)
draw.ellipse([cx - 68, cy - 190, cx + 68, cy - 85], fill=(28, 22, 30))
draw.polygon([(cx - 98, cy - 55), (cx - 112, cy + 190), (cx - 52, cy + 200), (cx - 48, cy - 55)], fill=s)
draw.polygon([(cx + 98, cy - 55), (cx + 112, cy + 190), (cx + 52, cy + 200), (cx + 48, cy - 55)], fill=s)
draw.ellipse([cx - 72, cy - 10, cx + 72, cy + 115], fill=s)
draw.ellipse([cx - 95, cy - 175, cx + 95, cy - 25], fill=(s[0] + 10, s[1] + 8, s[2] + 10))
draw.polygon([(cx - 105, cy - 35), (cx - 118, cy + 210), (cx + 118, cy + 210), (cx + 105, cy - 35)], fill=(s[0] + 10, s[1] + 8, s[2] + 10))
elif idx == 3:
# 后续1面对面温柔对视无蒙眼两人相对
draw.ellipse([cx - 200, cy - 180, cx - 20, cy + 20], fill=s) # 女左
draw.polygon([(cx - 210, cy + 10), (cx - 230, cy + 220), (cx - 50, cy + 230), (cx - 30, cy + 30)], fill=s)
draw.ellipse([cx - 180, cy - 30, cx - 40, cy + 100], fill=s)
draw.ellipse([cx + 20, cy - 180, cx + 200, cy + 20], fill=(s[0] + 12, s[1] + 10, s[2] + 12)) # 男右
draw.polygon([(cx + 30, cy + 10), (cx + 50, cy + 230), (cx + 230, cy + 220), (cx + 210, cy + 30)], fill=(s[0] + 12, s[1] + 10, s[2] + 12))
draw.ellipse([cx + 40, cy - 30, cx + 180, cy + 100], fill=(s[0] + 12, s[1] + 10, s[2] + 12))
else:
# 后续2并肩坐两人并排女靠肩
draw.ellipse([cx - 220, cy - 80, cx - 80, cy + 80], fill=s)
draw.polygon([(cx - 230, cy + 50), (cx - 250, cy + 230), (cx - 120, cy + 240), (cx - 100, cy + 60)], fill=s)
draw.ellipse([cx - 210, cy + 30, cx - 100, cy + 180], fill=s)
draw.ellipse([cx + 60, cy - 100, cx + 200, cy + 60], fill=(s[0] + 10, s[1] + 8, s[2] + 12))
draw.polygon([(cx + 90, cy + 40), (cx + 70, cy + 230), (cx + 220, cy + 220), (cx + 210, cy + 50)], fill=(s[0] + 10, s[1] + 8, s[2] + 12))
draw.ellipse([cx + 100, cy + 50, cx + 200, cy + 170], fill=(s[0] + 10, s[1] + 8, s[2] + 12))
if sc.get("speed_lines"):
_draw_speed_lines(draw, W, H, n=55, color=(255, 235, 245))
# 暗角
img = _draw_vignette(img, strength=0.35)
draw = ImageDraw.Draw(img)
font_t = _font(56)
font_s = _font(28)
bbox_t = draw.textbbox((0, 0), sc["title"], font=font_t)
tw = bbox_t[2] - bbox_t[0]
draw.text(((W - tw) // 2, H - 140), sc["title"], font=font_t, fill=(255, 252, 255))
bbox_s = draw.textbbox((0, 0), sc["sub"], font=font_s)
sw = bbox_s[2] - bbox_s[0]
draw.text(((W - sw) // 2, H - 78), sc["sub"], font=font_s, fill=(220, 210, 225))
img.save(out_path, "PNG")
print("OK:", out_path)
return True

View File

@@ -192,3 +192,4 @@
| 2026-03-01 23:41:32 | 🔄 卡若AI 同步 2026-03-01 23:41 | 更新:水桥平台对接、卡木、运营中枢工作台 | 排除 >20MB: 14 个 |
| 2026-03-02 00:14:40 | 🔄 卡若AI 同步 2026-03-02 00:14 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 14 个 |
| 2026-03-02 00:25:52 | 🔄 卡若AI 同步 2026-03-02 00:25 | 更新:水桥平台对接、运营中枢工作台 | 排除 >20MB: 14 个 |
| 2026-03-02 02:30:31 | 🔄 卡若AI 同步 2026-03-02 02:30 | 更新:金仓、水桥平台对接、运营中枢工作台 | 排除 >20MB: 14 个 |

View File

@@ -195,3 +195,4 @@
| 2026-03-01 23:41:32 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-01 23:41 | 更新:水桥平台对接、卡木、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-02 00:14:40 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-02 00:14 | 更新:卡木、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-02 00:25:52 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-02 00:25 | 更新:水桥平台对接、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |
| 2026-03-02 02:30:31 | 成功 | 成功 | 🔄 卡若AI 同步 2026-03-02 02:30 | 更新:金仓、水桥平台对接、运营中枢工作台 | 排除 >20MB: 14 个 | [仓库](http://open.quwanzhi.com:3000/fnvtk/karuo-ai) [百科](http://open.quwanzhi.com:3000/fnvtk/karuo-ai/wiki) |