--- name: siyuan description: 思源笔记 API 集成。通过自然语言创建、编辑、搜索笔记,管理笔记本和文档树。当用户提到思源笔记、SiYuan、笔记管理、知识库相关任务时自动激活。 --- # 思源笔记 API 集成 Skill ## 环境变量配置(必须) 本 skill 通过环境变量读取思源笔记连接信息,不同用户/组织配置不同的值。 **在 `~/.claude/settings.json` 中配置:** ```json { "env": { "SIYUAN_URL": "${SIYUAN_URL}", "SIYUAN_TOKEN": "your-api-token-here" } } ``` 或在项目级 `.claude/settings.json` 中配置(优先级更高)。 **检查配置是否就绪:** 执行任何思源操作前,先确认环境变量已设置: ```bash echo "URL: ${SIYUAN_URL:-未配置}" echo "TOKEN: ${SIYUAN_TOKEN:+已配置}" ``` 如果未配置,提示用户在 `~/.claude/settings.json` 的 `env` 中添加 `SIYUAN_URL` 和 `SIYUAN_TOKEN`。 --- ## 🔐 保存���禁:敏感��息脱敏 **保存任何内容到思源笔记前,必须先完成脱敏处理。** ### 脱敏规则 | 敏感类型 | 识别模式 | 脱敏方式 | 示例 | |---------|---------|---------|------| | 密码 | `密码`/`password`/`passwd` 附近的值 | 保留首尾各2字符,中间替换为 `****` | `zh****26` | | API Token | 长随机字符串(>16位) | 保留前4后4,中间 `...` | `mkea...0jxqy` | | SSH 私钥内容 | `-----BEGIN` 开头 | 整体替换为 `[SSH私钥-已脱敏]` | | | IP + 端口组合 | `x.x.x.x:port` | 保留,但标注"内网" | `47.93.23.182`(阿里云内网)| | 访问码/PIN | `访问码`/`accessAuthCode` 附近 | 同密码规则 | `Si****26` | ### 脱敏示例 ``` 原文: 密码: zhiyun2026 脱敏: 密码: zh****26 原文: API Token: mkea1080c0x0jxqy 脱敏: API Token: mkea...0jxqy 原文: sshpass -p 'zhiyun2026' ssh root@... 脱敏: sshpass -p '***' ssh root@... ``` ### 执行检查清单 保存笔记前逐项确认: - [ ] 文档中无明文密码 - [ ] 文档中无完整 API Token / Bearer Token - [ ] 文档中无 SSH 私钥内容 - [ ] 代码示例中的凭据已替换为占位符(如 ``) - [ ] 命令行示例中的 `-p 'xxx'` 已脱敏 > 如用户明确要求保留明文(如自用私有笔记本),须先得到用户确认再保存。 --- ## ⚠️ 强制规则 **创建文档前必须先查询是否存在!** ```python # ❌ 错误:直接创建,会产生重复文档 api.create_doc(notebook_id, "/文档路径", content) # ✅ 正确:使用 upsert 模式 api.upsert_doc(notebook_id, "/文档路径", content) ``` `createDocWithMd` API 每次调用都会创建新文档,即使路径相同也会产生重复。必须使用 upsert 模式(先查询后创建/更新)。 --- ## 功能概述 - **笔记本管理**: 创建、列出、删除笔记本 - **文档操作**: 创建、编辑、删除、移动文档 - **内容编辑**: 插入/更新/删除块内容 - **搜索功能**: 全文搜索、SQL 查询 - **导入导出**: Markdown 导入导出 - **资源管理**: 上传附件、图片 --- ## API 基础 ### 请求格式 所有 API 请求使用 POST 方法,需携带 Token: ```bash curl -X POST ${SIYUAN_URL}/api/xxx \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"param": "value"}' ``` ### 响应格式 ```json { "code": 0, // 0 表示成功 "msg": "", // 错误信息 "data": {} // 返回数据 } ``` --- ## 自然语言操作示例 | 用户说 | 执行操作 | |--------|----------| | "创建一个笔记本叫工作日志" | 创建笔记本 | | "在工作日志里新建一篇笔记" | 创建文档 | | "搜索包含'会议'的笔记" | 全文搜索 | | "列出所有笔记本" | 获取笔记本列表 | | "把这段内容添加到今日笔记" | 追加内容 | | "删除这篇笔记" | 删除文档 | --- ## 常用 API ### 笔记本操作 #### 列出所有笔记本 ```bash curl -X POST ${SIYUAN_URL}/api/notebook/lsNotebooks \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{}' ``` #### 创建笔记本 ```bash curl -X POST ${SIYUAN_URL}/api/notebook/createNotebook \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"name": "笔记本名称"}' ``` #### 删除笔记本 ```bash curl -X POST ${SIYUAN_URL}/api/notebook/removeNotebook \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"notebook": "笔记本ID"}' ``` --- ### 文档操作 > **重要**: 创建文档前必须先检查是否已存在同名文档!`createDocWithMd` 每次调用都会创建新文档,即使路径相同也会产生重复。请优先使用下方的"创建或更新文档"流程。 #### 创建或更新文档(推荐) 先查询文档是否存在,再决定创建还是更新: ```bash # 1. 先查询是否存在(按路径精确匹配) DOC_PATH="/网络管理/家庭Tailscale网络" EXISTING=$(curl -s -X POST ${SIYUAN_URL}/api/query/sql \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d "{\"stmt\": \"SELECT id FROM blocks WHERE type='d' AND hpath='${DOC_PATH}' LIMIT 1\"}" \ | jq -r '.data[0].id // empty') if [ -n "$EXISTING" ]; then # 2a. 存在则更新 curl -s -X POST ${SIYUAN_URL}/api/block/updateBlock \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d "{\"id\": \"${EXISTING}\", \"dataType\": \"markdown\", \"data\": \"# 更新的内容\"}" else # 2b. 不存在则创建 curl -s -X POST ${SIYUAN_URL}/api/filetree/createDocWithMd \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"notebook": "笔记本ID", "path": "/网络管理/家庭Tailscale网络", "markdown": "# 新内容"}' fi ``` #### 创建文档 (仅新建时使用) ```bash curl -X POST ${SIYUAN_URL}/api/filetree/createDocWithMd \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "notebook": "笔记本ID", "path": "/文档路径/文档名", "markdown": "# 标题\n\n正文内容..." }' ``` #### 获取文档内容 ```bash curl -X POST ${SIYUAN_URL}/api/filetree/getDoc \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"id": "文档ID"}' ``` #### 删除文档 ```bash curl -X POST ${SIYUAN_URL}/api/filetree/removeDoc \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"notebook": "笔记本ID", "path": "/文档路径"}' ``` #### 重命名文档 ```bash curl -X POST ${SIYUAN_URL}/api/filetree/renameDoc \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"notebook": "笔记本ID", "path": "/旧路径", "title": "新标题"}' ``` --- ### 块操作 #### 插入块 ```bash curl -X POST ${SIYUAN_URL}/api/block/insertBlock \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "dataType": "markdown", "data": "要插入的内容", "previousID": "前一个块ID" }' ``` #### 更新块 ```bash curl -X POST ${SIYUAN_URL}/api/block/updateBlock \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "dataType": "markdown", "data": "更新后的内容", "id": "块ID" }' ``` #### 删除块 ```bash curl -X POST ${SIYUAN_URL}/api/block/deleteBlock \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"id": "块ID"}' ``` --- ### 搜索 #### 全文搜索 ```bash curl -X POST ${SIYUAN_URL}/api/search/fullTextSearchBlock \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "query": "搜索关键词", "page": 1 }' ``` #### SQL 查询 ```bash curl -X POST ${SIYUAN_URL}/api/query/sql \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "stmt": "SELECT * FROM blocks WHERE content LIKE '\''%关键词%'\'' LIMIT 10" }' ``` --- ### 导入导出 #### 导出 Markdown ```bash curl -X POST ${SIYUAN_URL}/api/export/exportMdContent \ -H "Authorization: Token ${SIYUAN_TOKEN}" \ -H "Content-Type: application/json" \ -d '{"id": "文档ID"}' ``` --- ## Python 封装 ```python import os import requests from typing import Optional, Dict, Any class SiYuanAPI: """思源笔记 API 封装""" def __init__(self, base_url: str = None, token: str = None): base_url = base_url or os.environ.get("SIYUAN_URL", "") token = token or os.environ.get("SIYUAN_TOKEN", "") self.base_url = base_url self.headers = { "Authorization": f"Token {token}", "Content-Type": "application/json" } def _post(self, endpoint: str, data: Dict = None) -> Dict[str, Any]: """发送 POST 请求""" url = f"{self.base_url}/api/{endpoint}" response = requests.post(url, headers=self.headers, json=data or {}) result = response.json() if result.get("code") != 0: raise Exception(f"API Error: {result.get('msg')}") return result.get("data") # === 笔记本操作 === def list_notebooks(self) -> list: """列出所有笔记本""" data = self._post("notebook/lsNotebooks") return data.get("notebooks", []) def create_notebook(self, name: str) -> Dict: """创建笔记本""" return self._post("notebook/createNotebook", {"name": name}) def remove_notebook(self, notebook_id: str) -> None: """删除笔记本""" self._post("notebook/removeNotebook", {"notebook": notebook_id}) # === 文档操作 === def find_doc_by_path(self, path: str) -> Optional[str]: """根据路径查找文档,返回文档 ID(不存在返回 None)""" sql = f"SELECT id FROM blocks WHERE type='d' AND hpath='{path}' LIMIT 1" result = self.sql_query(sql) return result[0]["id"] if result else None def create_doc(self, notebook_id: str, path: str, markdown: str) -> str: """创建文档,返回文档 ID(注意:会创建新文档,即使同名文档已存在)""" return self._post("filetree/createDocWithMd", { "notebook": notebook_id, "path": path, "markdown": markdown }) def upsert_doc(self, notebook_id: str, path: str, markdown: str) -> str: """创建或更新文档(推荐使用) - 如果文档已存在,更新内容 - 如果文档不存在,创建新文档 返回文档 ID """ existing_id = self.find_doc_by_path(path) if existing_id: self.update_block(existing_id, markdown) return existing_id else: return self.create_doc(notebook_id, path, markdown) def get_doc(self, doc_id: str) -> Dict: """获取文档内容""" return self._post("filetree/getDoc", {"id": doc_id}) def remove_doc(self, notebook_id: str, path: str) -> None: """删除文档""" self._post("filetree/removeDoc", {"notebook": notebook_id, "path": path}) # === 块操作 === def insert_block(self, data: str, previous_id: str = None, parent_id: str = None) -> Dict: """插入块""" payload = {"dataType": "markdown", "data": data} if previous_id: payload["previousID"] = previous_id if parent_id: payload["parentID"] = parent_id return self._post("block/insertBlock", payload) def update_block(self, block_id: str, data: str) -> Dict: """更新块""" return self._post("block/updateBlock", { "dataType": "markdown", "data": data, "id": block_id }) def delete_block(self, block_id: str) -> None: """删除块""" self._post("block/deleteBlock", {"id": block_id}) # === 搜索 === def search(self, query: str, page: int = 1) -> Dict: """全文搜索""" return self._post("search/fullTextSearchBlock", {"query": query, "page": page}) def sql_query(self, sql: str) -> list: """SQL 查询""" return self._post("query/sql", {"stmt": sql}) # === 导出 === def export_md(self, doc_id: str) -> str: """导出文档为 Markdown""" data = self._post("export/exportMdContent", {"id": doc_id}) return data.get("content", "") # === 发布到云文档 === def publish_to_feishu(self, doc_id: str, doc_name: str, folder_token: str = None) -> dict: """ 将思源文档发布到飞书云文档 Args: doc_id: 思源文档ID doc_name: 飞书文档名称 folder_token: 飞书文件夹token(可选) Returns: dict: {"url": "飞书文档链接", "document_id": "飞书文档ID"} """ # 1. 导出Markdown content = self.export_md(doc_id) if not content: raise Exception("导出Markdown失败") # 2. 调用飞书API创建文档 # 需要配合 feishu-doc MCP 或直接调用飞书API # 这里返回内容,由调用方决定如何发布 return { "content": content, "doc_name": doc_name, "source_doc_id": doc_id } # 使用示例 if __name__ == "__main__": api = SiYuanAPI() # 列出笔记本 notebooks = api.list_notebooks() for nb in notebooks: print(f"- {nb['name']} ({nb['id']})") # 创建或更新笔记(推荐) notebook_id = notebooks[0]["id"] doc_id = api.upsert_doc(notebook_id, "/测试笔记", "# 标题\n\n这是测试内容") print(f"文档 ID: {doc_id}") # 再次调用不会创建重复文档 doc_id = api.upsert_doc(notebook_id, "/测试笔记", "# 标题\n\n更新后的内容") print(f"更新后文档 ID: {doc_id}") # 同一个 ID # 搜索 results = api.search("测试") print(f"搜索结果: {len(results.get('blocks', []))} 条") ``` --- ## 常见场景 ### 场景 1: 创建每日笔记 ```python from datetime import datetime api = SiYuanAPI() today = datetime.now().strftime("%Y-%m-%d") markdown = f"""# {today} 工作日志 ## 今日任务 - [ ] 任务1 - [ ] 任务2 ## 会议记录 ## 备注 """ # 获取或创建日记笔记本 notebooks = api.list_notebooks() diary_nb = next((nb for nb in notebooks if nb["name"] == "日记"), None) if not diary_nb: diary_nb = api.create_notebook("日记")["notebook"] # 使用 upsert_doc 避免重复创建 doc_id = api.upsert_doc(diary_nb["id"], f"/{today}", markdown) print(f"每日笔记: {doc_id}") ``` ### 场景 2: 批量导入 Markdown 文件 ```python from pathlib import Path api = SiYuanAPI() notebook_id = "目标笔记本ID" md_folder = "/path/to/markdown/files" for md_file in Path(md_folder).glob("*.md"): with open(md_file, "r", encoding="utf-8") as f: content = f.read() doc_name = md_file.stem # 使用 upsert_doc 支持增量导入,避免重复 doc_id = api.upsert_doc(notebook_id, f"/{doc_name}", content) print(f"导入: {doc_name} -> {doc_id}") ``` ### 场景 3: 搜索并汇总 ```python api = SiYuanAPI() # 搜索所有包含"会议"的内容 results = api.search("会议") blocks = results.get("blocks", []) print(f"找到 {len(blocks)} 条相关内容:") for block in blocks[:10]: print(f"- {block.get('content', '')[:50]}...") ``` ### 场景 4: 发布合同到飞书云文档 ```python from siyuan import SiYuanAPI api = SiYuanAPI() # 1. 从思源笔记导出合同内容 contract_doc_id = "20260202080355-2c0vgac" # 合同文档 ID markdown_content = api.export_md(contract_doc_id) # 2. 使用飞书 MCP 创建云文档 # 调用 feishu-doc MCP 的 create_and_write_document 工具 # - title: "物流服务合同-妗晨与名风" # - content: markdown_content # - folder_token: (可选,指定目标文件夹) # 3. 完整的发布函数 def publish_to_feishu(doc_id: str, doc_title: str = None) -> dict: """ 将思源笔记文档发布到飞书云文档 Args: doc_id: 思源笔记文档 ID doc_title: 飞书文档标题(可选,默认使用原文档标题) Returns: dict: {"siyuan_doc_id": str, "content": str, "feishu_url": str} """ api = SiYuanAPI() # 导出 Markdown 内容 content = api.export_md(doc_id) # 获取原文档标题(如果未指定) if not doc_title: doc_info = api.get_block(doc_id) doc_title = doc_info.get("content", "未命名文档") # 返回准备好的内容,由调用者使用 feishu-doc MCP 创建 return { "siyuan_doc_id": doc_id, "doc_title": doc_title, "content": content } # 使用示例 result = publish_to_feishu("20260202080355-2c0vgac", "物流服务合同-妗晨与名风-2026") print(f"准备发布: {result['doc_title']}") print(f"内容长度: {len(result['content'])} 字符") # 然后调用 feishu-doc MCP: # mcp__feishu-doc__create_and_write_document( # title=result["doc_title"], # content=result["content"] # ) ``` **工作流说明**: 1. **创建合同** (biz-contract 技能) → 生成合同 Markdown 文本 2. **存储到思源** (siyuan 技能) → 保存到"商务合同"笔记本,便于预览和修改 3. **发布到飞书** (feishu-doc MCP) → 导出并创建飞书云文档 **商务合同笔记本配置**: | 配置项 | 值 | |--------|-----| | 笔记本名称 | 商务合同 | | 笔记本 ID | `20260202080313-kjtgg1j` | | 路径规范 | `/{合同类型}/{甲方简称}-{乙方简称}-{年份}` | --- ## 注意事项 - API Token 需要保密,不要提交到代码仓库 - 删除操作不可恢复,谨慎使用 - 大批量操作建议添加延时,避免服务器压力 - 思源笔记数据存储在 `/vol1/1000/Docker/siyuan/` (飞牛OS) --- ## 文档编写规范 > **重要**: 本章节规范所有通过 API 创建的思源笔记文档的编写标准。确保文档的可追溯性和完整性。 ### 时间戳格式要求 **强制规则**: 所有时间相关的记录必须包含完整的时间戳,而不仅仅是日期。 #### ✅ 正确示例 ```markdown ## 事件概述 - **发生时间**: 2026-01-15 00:00:00 - 00:46:00 CST - **创建时间**: 2026-01-15 07:30:00 ACDT - **最后更新**: 2026-01-15 07:35:00 ACDT - **验证时间**: 2026-01-15 08:00:00 CST ## 配置变更 **变更时间**: 2026-01-15 01:12:00 CST **生效时间**: 2026-01-15 01:15:00 CST ``` #### ❌ 错误示例 ```markdown - **发生时间**: 2026-01-15 - **创建时间**: 2026-01-15 - **最后更新**: 今天 - **验证时间**: 早上 ``` #### 时间格式规范 | 场景 | 格式 | 示例 | |------|------|------| | 精确时间点 | `YYYY-MM-DD HH:MM:SS TZ` | `2026-01-15 02:00:01 CST` | | 时间范围 | `YYYY-MM-DD HH:MM:SS - HH:MM:SS TZ` | `2026-01-15 00:00:00 - 00:46:00 CST` | | 跨天时间范围 | `YYYY-MM-DD HH:MM:SS - YYYY-MM-DD HH:MM:SS TZ` | `2026-01-15 23:00:00 - 2026-01-16 01:00:00 CST` | **时区标注**: - CST: 中国标准时间 (服务器时间、生产环境) - ACDT: 澳大利亚中部夏令时 (au-dev 本地开发时间) - UTC: 协调世界时 (国际标准) ### 文档元信息要求 所有运维、技术类笔记文档必须在开头包含元信息: ```markdown # 文档标题 **创建时间**: YYYY-MM-DD HH:MM:SS TZ **创建人**: qiudl / Claude **最后更新**: YYYY-MM-DD HH:MM:SS TZ **文档状态**: ✅ 已完成 / 🔄 进行中 / ⚠️ 待验证 / ❌ 已废弃 **相关项目**: 项目名称 **标签**: #运维 #数据库 #备份 --- [正文内容...] ``` ### 事件记录规范 记录重大事件或故障时必须包含: 1. **事件时间**: 完整的开始和结束时间(精确到秒) 2. **严重程度**: P0/P1/P2/P3 3. **影响范围**: 具体说明受影响的系统和用户 4. **事件描述**: 清晰简洁的事件说明 5. **恢复过程**: 详细的恢复步骤和时间点 6. **恢复完成时间**: 精确的恢复完成时间 7. **根本原因**: RCA (Root Cause Analysis) 8. **预防措施**: 包含完成时间的预防措施 9. **相关文档**: 链接到相关技术文档或代码仓库 **模板**: ```markdown # YYYY-MM-DD 事件标题 ## 事件概述 - **发生时间**: YYYY-MM-DD HH:MM:SS - HH:MM:SS TZ - **严重程度**: P0 - 数据丢失 / P1 - 服务中断 / P2 - 性能下降 / P3 - 功能异常 - **影响范围**: 具体描述 - **根本原因**: 简短说明 - **恢复状态**: ✅ 已完全恢复 / 🔄 部分恢复 / ❌ 未恢复 --- ## 时间线 ``` YYYY-MM-DD HH:MM:SS - 事件发生 YYYY-MM-DD HH:MM:SS - 发现问题 YYYY-MM-DD HH:MM:SS - 开始处理 YYYY-MM-DD HH:MM:SS - 恢复完成 YYYY-MM-DD HH:MM:SS - 验证通过 ``` ## 详细过程 [详细描述...] ## 恢复步骤 1. **步骤 1** (执行时间: HH:MM:SS) - 具体操作 - 结果验证 2. **步骤 2** (执行时间: HH:MM:SS) - 具体操作 - 结果验证 ## 预防措施 1. ✅ 措施 1 (完成时间: YYYY-MM-DD HH:MM:SS TZ) 2. ✅ 措施 2 (完成时间: YYYY-MM-DD HH:MM:SS TZ) 3. ⏳ 措施 3 (计划完成: YYYY-MM-DD) ## 相关资源 - 相关代码: [链接] - 监控面板: [链接] - 技术文档: [链接] --- **创建时间**: YYYY-MM-DD HH:MM:SS TZ **创建人**: qiudl **最后验证**: YYYY-MM-DD HH:MM:SS TZ **文档状态**: ✅ 已完成 ``` ### 技术方案文档规范 记录技术方案、架构设计时应包含: ```markdown # 方案标题 **提出时间**: YYYY-MM-DD HH:MM:SS TZ **提出人**: 姓名 **评审时间**: YYYY-MM-DD HH:MM:SS TZ **批准时间**: YYYY-MM-DD HH:MM:SS TZ **实施时间**: YYYY-MM-DD HH:MM:SS - HH:MM:SS TZ **状态**: 📝 草稿 / 🔍 评审中 / ✅ 已批准 / 🚀 实施中 / ✅ 已完成 ## 背景 [为什么需要这个方案...] ## 目标 [期望达到的目标...] ## 技术方案 [具体的技术实现...] ## 时间规划 | 阶段 | 开始时间 | 结束时间 | 负责人 | 状态 | |------|---------|---------|--------|------| | 需求分析 | YYYY-MM-DD HH:MM | YYYY-MM-DD HH:MM | 姓名 | ✅ | | 方案设计 | YYYY-MM-DD HH:MM | YYYY-MM-DD HH:MM | 姓名 | 🔄 | | 开发实施 | YYYY-MM-DD HH:MM | YYYY-MM-DD HH:MM | 姓名 | ⏳ | ## 风险评估 [可能的风险和应对措施...] ## 验收标准 - [ ] 标准 1 (验证时间: ________) - [ ] 标准 2 (验证时间: ________) --- **最后更新**: YYYY-MM-DD HH:MM:SS TZ ``` ### 会议记录规范 记录技术会议、评审会议时应包含: ```markdown # YYYY-MM-DD 会议标题 **会议时间**: YYYY-MM-DD HH:MM:SS - HH:MM:SS TZ **会议地点**: 线上/线下 **参会人员**: 姓名1, 姓名2, 姓名3 **记录人**: 姓名 **会议类型**: 技术评审 / 方案讨论 / 故障复盘 / 周会 ## 议题 1. 议题 1 2. 议题 2 3. 议题 3 ## 讨论记录 ### 议题 1: [标题] **讨论时间**: HH:MM - HH:MM [讨论内容...] **决议**: - 决定 1 - 决定 2 ### 议题 2: [标题] [...] ## 待办事项 | 任务 | 负责人 | 截止时间 | 状态 | |------|--------|---------|------| | 任务 1 | 姓名 | YYYY-MM-DD HH:MM | ⏳ | | 任务 2 | 姓名 | YYYY-MM-DD HH:MM | ✅ | ## 下次会议 **计划时间**: YYYY-MM-DD HH:MM:SS TZ **议题预告**: [...] --- **记录完成时间**: YYYY-MM-DD HH:MM:SS TZ ``` ### 操作日志规范 记录手动运维操作时应包含: ```markdown ## YYYY-MM-DD HH:MM 操作记录 **操作时间**: YYYY-MM-DD HH:MM:SS TZ **操作人**: qiudl / Claude **操作类型**: 数据库操作 / 服务重启 / 配置变更 / 部署发布 **操作内容**: 简短描述 ### 详细步骤 1. **步骤 1** (HH:MM:SS) ```bash 具体命令 ``` 结果: [...] 2. **步骤 2** (HH:MM:SS) ```bash 具体命令 ``` 结果: [...] ### 验证结果 **验证时间**: YYYY-MM-DD HH:MM:SS TZ **验证结果**: ✅ 成功 / ❌ 失败 / ⚠️ 部分成功 [验证详情...] ### 回滚方案 如需回滚,执行以下步骤: ```bash 回滚命令 ``` --- **记录时间**: YYYY-MM-DD HH:MM:SS TZ ``` ### 检查清单 在创建或更新思源笔记文档时,请检查: - [ ] 所有时间记录都包含完整时间戳(精确到秒) - [ ] 所有时间戳都标注了时区(CST/ACDT/UTC) - [ ] 文档包含元信息(创建时间、创建人、状态) - [ ] 事件记录包含完整的时间范围和时间线 - [ ] 技术方案包含各阶段的时间规划 - [ ] 会议记录包含会议时间和记录完成时间 - [ ] 操作日志包含操作时间、验证时间 - [ ] 所有时间使用 24 小时制 - [ ] 时间格式一致(YYYY-MM-DD HH:MM:SS TZ) - [ ] 跨天操作明确标注日期变化 ### 为什么需要完整时间戳 1. **故障排查**: 精确时间有助于关联服务器日志和追踪问题根源 2. **时间顺序**: 明确事件的先后关系,构建完整的时间线 3. **性能分析**: 精确计算操作耗时,识别性能瓶颈 4. **审计追踪**: 完整的操作记录,满足合规要求 5. **跨时区协作**: 明确时区避免混淆(澳洲团队 vs 中国服务器) 6. **自动化集成**: 便于后续工具提取时间信息进行分析 7. **知识沉淀**: 便于后续查阅和学习,理解决策的时间背景 ### 常见错误和修正 | 错误写法 | 正确写法 | 说明 | |---------|---------|------| | 今天下午 | 2026-01-15 14:30:00 CST | 避免模糊表述 | | 凌晨 | 2026-01-15 02:00:00 CST | 明确具体时间 | | 2026-01-15 | 2026-01-15 14:30:00 CST | 补充时分秒 | | 14:30 | 2026-01-15 14:30:00 CST | 补充日期和时区 | | 昨天 | 2026-01-14 HH:MM:SS CST | 使用具体日期 | | 刚才 | 2026-01-15 14:28:00 CST | 记录精确时间 | --- **规范创建时间**: 2026-01-15 07:45:00 ACDT **最后更新时间**: 2026-01-15 07:45:00 ACDT