chore: 清理 .trae 旧文件,新增多篇博客文章

- 删除 .trae/ 目录(Trae IDE 旧配置)
- 删除 temp-agent-os-v2.md
- 新增:AI时代的Token战争——能源算力与我们每个人的选择
- 新增:自建Git服务——在NAS上部署Gitea
- 新增:Docker安装与入门指南
- 更新:Git团队协作指南
- 更新:recent-files-obsidian 插件数据
This commit is contained in:
2026-07-23 22:02:35 +08:00
parent ffa6cbe4d1
commit 2dd12d0b67
21 changed files with 4710 additions and 3000 deletions
+4
View File
@@ -1,5 +1,9 @@
{
"recentFiles": [
{
"basename": "Git团队协作指南",
"path": "博客/编程与工具/Git团队协作指南.md"
},
{
"basename": "usage-guide",
"path": "obsidian-halo/docs/usage-guide.md"
@@ -1,211 +0,0 @@
# Obsidian Halo 插件功能增强计划
## 一、功能对比分析
### Halo CLI 已有功能
| 分类 | 功能 | CLI 支持 |
|------|------|---------|
| **文章管理** | 发布文章 | ✅ 完整 |
| | 更新文章 | ✅ 完整 |
| | 删除文章 | ✅ 完整 |
| | 列出文章列表 | ✅ 完整 |
| | 查看文章详情 | ✅ 完整 |
| | 批量操作 | ✅ PowerShell 脚本 |
| **导出/导入** | 导出为 JSON | ✅ 完整 |
| | 导出为 Markdown | ✅ 完整 |
| | 从 JSON 导入 | ✅ 完整 |
| | 从 Markdown 导入 | ✅ 完整 |
| **标签管理** | 列出标签 | ✅ 完整 |
| | 创建标签 | ✅ 完整 |
| | 更新标签 | ✅ 完整 |
| | 删除标签 | ✅ 完整 |
| | 为文章设置标签 | ✅ 完整 |
| **分类管理** | 列出分类 | ✅ 完整 |
| | 创建分类 | ✅ 完整 |
| | 更新分类 | ✅ 完整 |
| | 删除分类 | ✅ 完整 |
| | 设置优先级 | ✅ 完整 |
| **其他内容** | 单页管理 | ✅ 完整 |
| | 搜索内容 | ✅ 完整 |
| **系统管理** | 附件管理 | ✅ 完整 |
| | 备份管理 | ✅ 完整 |
| | 动态管理 | ✅ 完整 |
| | 评论管理 | ✅ 完整 |
| | 插件管理 | ✅ 完整 |
| | 主题管理 | ✅ 完整 |
---
## 二、Obsidian 插件当前功能
| 分类 | 功能 | 状态 |
|------|------|------|
| **文章管理** | 发布文章 | ✅ 已实现 |
| | 更新文章(同步 Halo 到本地) | ✅ 已实现 |
| | 列出文章列表 | ❌ 缺失 |
| | 查看文章详情 | ❌ 缺失 |
| | 删除文章 | ❌ 缺失 |
| | 批量发布 | ❌ 缺失 |
| **图片上传** | 自动上传图片 | ✅ 已实现(新增) |
| **标签/分类** | 为文章设置标签 | ✅ 已实现 |
| | 为文章设置分类 | ✅ 已实现 |
| | 创建标签 | ❌ 缺失 |
| | 创建分类 | ❌ 缺失 |
| | 管理标签/分类 | ❌ 缺失 |
| **导出/导入** | 从 Markdown 导入 | ❌ 缺失 |
| | 导出为 Markdown | ❌ 缺失 |
| | 导出为 JSON | ❌ 缺失 |
| **其他** | 单页管理 | ❌ 缺失 |
| | 搜索 | ❌ 缺失 |
---
## 三、功能优先级建议
### 高优先级(核心功能)
1. **文章列表查看**
- 在命令面板中显示 Halo 文章列表
- 支持分页、筛选(草稿/已发布)
- 快速预览文章信息
2. **导入功能增强**
- 支持从本地 Markdown 文件导入创建文章
- 智能解析文件路径和文件名
3. **文章删除功能**
- 添加删除命令(需二次确认)
- 支持删除本地文件或仅删除 Halo 文章
### 中优先级(常用功能)
4. **批量操作**
- 批量发布多篇文章
- 批量同步已发布文章
- 批量管理(删除、更新标签等)
5. **标签/分类管理**
- 创建新标签/分类
- 查看现有标签/分类列表
- 更新/删除标签/分类
6. **导出功能**
- 导出文章为 Markdown
- 导出文章为 JSON(备份用)
### 低优先级(增强功能)
7. **搜索功能**
- 搜索 Halo 文章
- 快速定位文章
8. **单页管理**
- 发布/管理独立页面
- 与文章类似的工作流
---
## 四、实施步骤
### 第一阶段:核心补充(1-2 周)
#### 任务 1:文章列表功能
- [ ] 创建文章列表 Modal
- [ ] 实现分页、筛选功能
- [ ] 添加快速操作按钮(查看、编辑、删除)
- [ ] 集成到命令面板
#### 任务 2:导入功能
- [ ] 实现从文件导入创建文章
- [ ] 智能解析 Markdown 文件
- [ ] 支持选择文件对话框
#### 任务 3:删除功能
- [ ] 添加删除命令
- [ ] 二次确认机制
- [ ] 删除选项(仅 Halo / 仅本地 / 全部)
### 第二阶段:常用功能(2-4 周)
#### 任务 4:批量操作
- [ ] 批量选择界面
- [ ] 批量发布队列
- [ ] 进度显示和错误处理
#### 任务 5:标签/分类管理
- [ ] 标签管理 Modal
- [ ] 分类管理 Modal
- [ ] 创建/编辑/删除功能
#### 任务 6:导出功能
- [ ] 导出为 Markdown
- [ ] 导出为 JSON(备份)
- [ ] 选择保存路径
### 第三阶段:增强功能(4+ 周)
#### 任务 7:搜索功能
- [ ] 文章搜索 Modal
- [ ] 快速筛选和定位
#### 任务 8:单页管理
- [ ] 单页发布命令
- [ ] 单页列表查看
- [ ] 单页导入/导出
---
## 五、技术实现建议
### API 端点
| 功能 | API 端点 |
|------|----------|
| 列出文章 | `GET /apis/uc.api.content.halo.run/v1alpha1/posts` |
| 获取文章 | `GET /apis/uc.api.content.halo.run/v1alpha1/posts/{name}` |
| 删除文章 | `DELETE /apis/uc.api.content.halo.run/v1alpha1/posts/{name}` |
| 列出标签 | `GET /apis/content.halo.run/v1alpha1/tags` |
| 创建标签 | `POST /apis/content.halo.run/v1alpha1/tags` |
| 列出分类 | `GET /apis/content.halo.run/v1alpha1/categories` |
| 创建分类 | `POST /apis/content.halo.run/v1alpha1/categories` |
### 文件结构建议
```
src/
├── commands/ # 命令相关
│ ├── publish.ts
│ ├── delete.ts
│ ├── list.ts
│ ├── import.ts
│ └── export.ts
├── modals/ # 弹窗相关
│ ├── post-list-modal.ts
│ ├── tag-manager-modal.ts
│ ├── category-manager-modal.ts
│ └── search-modal.ts
├── service/ # 服务层
│ ├── index.ts # 现有
│ └── image-uploader.ts # 现有
└── utils/ # 工具层
├── image.ts # 现有
└── ...
```
---
## 六、建议实施顺序
1. **先实现文章列表**(最常用)
2. **再实现导入功能**(补全工作流)
3. **实现删除功能**(完整性)
4. **实现批量操作**(效率提升)
5. **实现标签/分类管理**(内容组织)
6. **实现导出功能**(备份需求)
7. **实现搜索功能**(快速定位)
8. **实现单页管理**(可选)
---
请确认需要实现哪些功能,我将制定详细的技术方案。
@@ -1,214 +0,0 @@
# obsidian-halo 插件功能增强计划
## 当前功能分析
当前插件已实现:
- ✅ 发布文档到 Halo
- ✅ 从 Halo 拉取文档
- ✅ 更新已发布文章内容
- ✅ 多站点管理
- ✅ Frontmatter 元数据同步(标题、摘要、分类、标签、封面)
- ✅ 图片上传功能
- ✅ 文章列表增强(分页、筛选)
- ✅ Markdown 文件导入
- ✅ 删除文章功能(支持选择性删除)
- ✅ 标签管理功能
- ✅ 分类管理功能
- ✅ 导出文章为 Markdown
- ✅ 导出文章为 JSON
- ✅ 搜索 Halo 文章
- ✅ 同步状态面板
- ✅ 同步历史记录
- ✅ 使用指南文档
---
## 已完成功能(2024年4月实现)
### 1. 图片/附件上传 ✅
**优先级:高 | 难度:中**
- [x] 自动检测并上传笔记中的图片到 Halo 媒体库
- [x] 转换本地图片路径为 Halo URL
### 2. 批量操作功能 ✅
**优先级:高 | 难度:中**
- [x] 文章列表查看(支持分页、筛选)
- [x] 从 Markdown 文件导入文章
### 3. 标签/分类管理 ✅
**优先级:高 | 难度:中**
- [x] 标签管理(创建、编辑、删除)
- [x] 分类管理(创建、编辑、删除)
### 4. 导出功能 ✅
**优先级:中 | 难度:中**
- [x] 导出文章为 Markdown
- [x] 导出文章为 JSON(备份用)
### 5. 搜索功能 ✅
**优先级:中 | 难度:中**
- [x] 搜索 Halo 文章(按标题、slug 搜索)
- [x] 按发布状态筛选
### 6. 删除功能 ✅
**优先级:高 | 难度:中**
- [x] 选择性删除(仅 Halo / 仅本地 / 全部)
- [x] 二次确认机制
### 7. 同步状态面板 ✅ (新增)
**优先级:高 | 难度:中**
- [x] 侧边栏面板显示已发布文章列表
- [x] 快速操作按钮(更新、拉取)
- [x] 同步历史记录
- [x] 同步图标侧边栏入口
### 8. 使用指南 ✅ (新增)
**优先级:高 | 难度:中**
- [x] 完整的命令列表说明
- [x] 快速开始教程
- [x] 常见问题解答
---
## 待实现功能
### 1. 双向同步增强
**优先级:高 | 难度:高**
- [ ] 差异检测:比较本地和 Halo 版本的修改时间
- [ ] 选择性同步:仅同步本地/仅同步 Halo/完全合并
- [ ] 冲突解决:处理两边同时修改的情况
- [ ] 同步历史:记录每次同步的详情 ✅(已完成基础功能)
### 2. 高级发布选项
**优先级:中 | 难度:中**
- [ ] 自定义 Slug 格式(支持模板变量:`{{title}}`, `{{date}}`
- [ ] 发布时间调度(定时发布)
- [ ] SEO 元数据设置(meta description、keywords
- [ ] 文章属性控制(评论开关、置顶、优先级、可见性)
### 3. 内容预览
**优先级:中 | 难度:中**
- [ ] 发布前预览 Halo 渲染效果
- [ ] 预览不同主题下的样式
- [ ] 实时预览面板
### 4. 模板支持
**优先级:低 | 难度:中**
- [ ] 发布模板:预定义 frontmatter 结构
- [ ] 快捷键自定义默认值
- [ ] 模板变量支持
### 5. 命令面板增强
**优先级:低 | 难度:低**
- [ ] 键盘快捷键支持
- [ ] 快速切换站点
- [ ] 快捷操作菜单
### 6. 用户界面优化
**优先级:低 | 难度:中**
- [ ] 进度条显示
- [ ] 更详细的错误提示
- [ ] 通知中心整合
- [ ] 右键菜单支持
---
## 推荐优先级(建议优先实现)
1. **高级发布选项** - 增加灵活性
2. **内容预览** - 提升用户体验
3. **模板支持** - 提升工作效率
---
## 技术实现要点
### 图片上传实现思路
```typescript
// 1. 解析 Markdown 中的图片引用
// 2. 上传到 Halo 媒体库获取 URL
// 3. 替换本地路径为远程 URL
// Halo 媒体上传 API 端点
POST /apis/api.console.halo.run/v1alpha1/attachments/upload
```
### 批量操作实现思路
```typescript
// 1. 创建批量选择界面
// 2. 批量处理队列
// 3. 进度显示和错误处理
```
### 同步检测实现思路
```typescript
// 1. 保存本地最后同步时间戳
// 2. 对比 Halo 文章的更新时间
// 3. 标记需要更新的文章
```
---
## 开发建议
1. **模块化开发**:新增功能独立成模块
2. **配置化**:新功能支持在设置中开关
3. **国际化**:所有文案支持 i18n
4. **错误处理**:完善异常捕获和用户提示
5. **测试**:添加单元测试和集成测试
---
## 文件结构
```
src/
├── commands/ # 命令相关
│ ├── import-markdown.ts # ✅ 导入 Markdown 文件
│ ├── delete-post.ts # ✅ 删除文章
│ ├── manage-taxonomy.ts # ✅ 管理标签/分类
│ ├── export-post.ts # ✅ 导出文章
│ └── search-posts.ts # ✅ 搜索文章
├── modals/ # 弹窗相关
│ ├── file-preview-modal.ts # ✅ 文件预览
│ ├── delete-confirm-modal.ts # ✅ 删除确认
│ ├── tag-manager-modal.ts # ✅ 标签管理
│ ├── category-manager-modal.ts # ✅ 分类管理
│ ├── search-modal.ts # ✅ 搜索弹窗
│ └── sync-history-modal.ts # ✅ 同步历史
├── views/ # 视图相关
│ └── sync-status-view.ts # ✅ 同步状态面板
├── service/ # 服务层
│ ├── index.ts # Halo API 服务
│ └── image-uploader.ts # ✅ 图片上传
├── utils/ # 工具层
│ ├── image.ts # ✅ 图片处理
│ └── ...
├── i18n/ # 国际化
│ └── locales/
│ ├── zh-cn.json # 中文
│ ├── en.json # 英文
│ └── zh-tw.json # 繁体中文
└── main.ts # 主入口
docs/
└── usage-guide.md # ✅ 使用指南
```
---
最后更新:2024年4月26日
-246
View File
@@ -1,246 +0,0 @@
---
name: halo-blog-writer
description: |
Halo 博客写作和管理助手。当用户需要:
(1) 发布博客文章
(2) 管理博客内容
(3) 更新/修改已发布的文章
(4) 导出/导入博客内容
(5) 查看博客状态
(6) 使用自然语言操作 Halo 博客时触发此技能
---
# Halo 博客写作助手
本技能帮助 AI Agent 通过 Halo CLI 管理用户的 Halo 博客(http://192.168.5.8:8090)。
## 快速开始
### 已配置的环境
用户已通过 npm 全局安装 Halo CLI
- 版本:1.3.0
- Node.jsv22.14.0
- 系统:Windows (PowerShell)
### CLI 配置
当前激活的配置(profile)是 `local`,连接地址:
```
http://192.168.5.8:8090
```
认证方式:Bearer Token(已存储在系统 keyring 中)
### 基本命令
```powershell
# 列出文章(分页显示)
halo post list --page 1 --size 20
# 查看单个文章详情
halo post get <name-or-id>
# 创建文章
halo post create --title "标题" --content "# 内容" --publish true
# 更新文章
halo post update <name-or-id> --title "新标题" --content "新内容"
# 导出文章为 Markdown
halo post export-markdown <name-or-id> --output ./post.md
# 导入 Markdown 文件创建文章
halo post import-markdown --file ./post.md
```
## 写作工作流
### 场景 1:发布新文章
当用户提供文章内容时:
1. 接收文章内容(可能是文件路径或直接文本)
2. 提取标题和正文
3. 判断是否立即发布(publish)还是仅创建草稿
4. 执行 `halo post create` 命令
5. 确认创建成功
```powershell
# 发布新文章
halo post create --title "文章标题" --content "# 文章内容..." --publish true
# 仅创建草稿
halo post create --title "文章标题" --content "# 文章内容..."
```
### 场景 2:从 Markdown 文件发布
当用户提供 `.md` 文件时:
1. 读取文件内容
2. 从文件名或第一行提取标题
3. 执行导入命令
```powershell
halo post import-markdown --file d:\path\to\article.md
```
### 场景 3:更新已发布的文章
当用户要求修改某篇文章时:
1. 先用 `halo post list` 找到文章
2. 获取文章 ID 或 name
3. 执行更新命令
```powershell
# 先查看文章列表
halo post list --page 1 --size 20
# 获取文章详情
halo post get <article-id>
# 更新文章
halo post update <article-id> --title "新标题" --content "新内容"
```
### 场景 4:批量操作
处理多篇文章:
1. 获取文章列表
2. 逐个处理
3. 报告完成状态
```powershell
# 获取所有文章(分页)
halo post list --page 1 --size 100
# 或者导出为 JSON 格式便于处理
halo post list --page 1 --size 100 --json
```
## 文件路径约定
用户的博客文章通常保存在:
```
d:\Code\OpenClaw\文件\博客\
```
常见文件格式:
- `.md` - Markdown 文件
- `.txt` - 纯文本文件
## 注意事项
### 内容格式
- Halo 支持 Markdown 和 HTML 格式
- 默认使用 Markdown`--raw-type markdown`
- 也支持 `--raw-type html`
### 发布状态
- `published` - 已发布
- `draft` - 草稿
- 可以在创建时指定 `--publish true` 立即发布
### 文章标识
文章可以用以下方式标识:
- **Name/Slug**:文章的唯一标识符(如 `019dbabc-86b9-74a0-a926-c25529309007`
- **ID**:文章内部 ID
### 错误处理
如果命令失败:
1. 检查网络连接
2. 确认 CLI 配置正确(`halo auth current`
3. 查看错误信息并重试
## 其他管理功能
```powershell
# 单页管理
halo single-page list
halo single-page create --title "标题" --content "内容"
# 插件管理
halo plugin list
# 主题管理
halo theme list
# 备份
halo backup list
halo backup create
# 评论管理
halo comment list
halo comment reply <comment-id> --content "回复内容"
```
## 安全提醒
- Bearer Token 已安全存储在系统 keyring 中
- 不要在命令输出中显示敏感信息
- 谨慎执行删除操作(`halo post delete`
## 常用命令速查
| 操作 | 命令 |
|------|------|
| 查看文章列表 | `halo post list --page 1 --size 20` |
| 查看文章详情 | `halo post get <id>` |
| 创建文章 | `halo post create --title "标题" --content "内容"` |
| 发布文章 | `halo post create --title "标题" --content "内容" --publish true` |
| 更新文章 | `halo post update <id> --title "标题" --content "内容"` |
| 删除文章 | `halo post delete <id> --force` |
| 导出为 Markdown | `halo post export-markdown <id> --output ./post.md` |
| 从文件导入 | `halo post import-markdown --file ./post.md` |
## 博客标签和分类
### 现有标签(共 11 个)
| 显示名称 | Slug | 颜色 |
|---------|------|------|
| 协会动态 | xie-hui-dong-tai | 🟢 #B8E986 |
| 5分钟速览 | 5fen-zhong-su-lan | 🔵 #50E3C2 |
| 技术深潜 | ji-shu-shen-qian | 🔷 #4A90E2 |
| 校园AI | xiao-yuan-ai | 🟣 #9013FE |
| 竞赛指南 | jing-sai-zhi-nan | 🟪 #BD10E0 |
| 项目实战 | xiang-mu-shi-zhan | 🟢 #417505 |
| 零基础入门 | ling-ji-chu-ru-men | 🟢 #7ED321 |
| 开源框架 | kai-yuan-kuang-jia | 🟤 #8B572A |
| 模型轻量化 | mo-xing-qing-liang-hua | 🟡 #F8E71C |
| 隐私计算 | yin-si-ji-suan | 🟠 #F5A623 |
| AI智能体 | aizhi-neng-ti | 🔴 #D0021B |
### 标签使用建议
| 文章类型 | 推荐标签 |
|---------|---------|
| 技术教程 / 开发工具 | 技术深潜 |
| 团队协作 / 开源项目 | 项目实战 |
| AI/LLM/模型相关 | 技术深潜, AI智能体 |
| 编程入门教程 | 技术深潜, 零基础入门 |
| 比赛通知 / 大赛解读 | 竞赛指南 |
| 协会通知 / 动态 | 协会动态 |
| AI 科普 / 入门 | 零基础入门, AI智能体 |
### 常用命令速查
| 操作 | 命令 |
|------|------|
| 查看所有标签 | `halo post tag list` |
| 查看所有分类 | `halo post category list` |
| 为文章添加标签 | `halo post update <id> --tags "标签1,标签2"` |
| 更新文章分类 | `halo post update <id> --category "分类名"` |
| 查看文章标签 | `halo post get <id> --json` |
详细命令参见 `references/command-reference.md`
## 参考文档
- CLI 完整帮助:`halo --help``halo post --help`
- 配置信息:`halo auth profile list`
- 高级用法:参见 `references/advanced-usage.md`
- 标签和分类命令:参见 `references/command-reference.md`
@@ -1,253 +0,0 @@
# Halo CLI 高级用法
本文件包含 Halo CLI 的高级用法和示例场景。
## 内容目录
1. [批量操作](#批量操作)
2. [自动化脚本](#自动化脚本)
3. [内容迁移](#内容迁移)
4. [SEO 优化](#seo-优化)
---
## 批量操作
### 批量导出文章
```powershell
# 导出所有文章为 JSON
halo post list --page 1 --size 100 --json > all_posts.json
# 批量导出为 Markdown
$posts = halo post list --page 1 --size 100 --json | ConvertFrom-Json
foreach ($post in $posts.items) {
halo post export-markdown $post.name --output "./export/$($post.name).md"
}
```
### 批量更新标签
```powershell
# 给多篇文章添加标签
$posts = halo post list --page 1 --size 20 --json | ConvertFrom-Json
foreach ($post in $posts.items) {
halo post update $post.name --tags "Python,教程,技术分享"
}
```
### 批量发布
```powershell
# 将所有草稿发布
$posts = halo post list --page 1 --size 100 --json | ConvertFrom-Json
foreach ($post in $posts.items) {
if ($post.status -eq "draft") {
halo post update $post.name --publish true
Write-Host "已发布: $($post.title)"
}
}
```
---
## 自动化脚本
### 文章备份脚本
```powershell
# backup-halo-posts.ps1
param(
[int]$PageSize = 50
)
$backupDir = ".\halo-backup\$(Get-Date -Format 'yyyy-MM-dd')"
New-Item -ItemType Directory -Path $backupDir -Force | Out-Null
$page = 1
$totalExported = 0
do {
Write-Host "正在导出第 $page 页..."
$result = halo post list --page $page --size $PageSize --json | ConvertFrom-Json
foreach ($post in $result.items) {
$filename = "$backupDir\$($post.name).md"
halo post export-markdown $post.name --output $filename
$totalExported++
}
$page++
} while ($result.hasNext)
Write-Host "备份完成!共导出 $totalExported 篇文章到 $backupDir"
```
### 定时发布脚本
```powershell
# scheduled-publish.ps1
param(
[string]$FilePath
)
if (-not (Test-Path $FilePath)) {
Write-Error "文件不存在: $FilePath"
exit 1
}
$content = Get-Content $FilePath -Raw
$title = [System.IO.Path]::GetFileNameWithoutExtension($FilePath)
Write-Host "正在发布: $title"
halo post create --title $title --content $content --publish true
if ($LASTEXITCODE -eq 0) {
Write-Host "发布成功!"
} else {
Write-Error "发布失败"
exit 1
}
```
---
## 内容迁移
### 从其他平台导入
```powershell
# 从 WordPress 导出文件导入
halo post import-markdown --file .\wordpress-export\post-1.md
halo post import-markdown --file .\wordpress-export\post-2.md
# 批量导入
Get-ChildItem .\wordpress-export\*.md | ForEach-Object {
halo post import-markdown --file $_.FullName
Write-Host "已导入: $($_.Name)"
}
```
### 迁移到其他平台
```powershell
# 导出为标准格式
halo post list --page 1 --size 100 --json > migration.json
# 转换为其他 CMS 格式(如 Hugo、Jekyll
# 需要额外的转换脚本处理 JSON 到目标格式
```
---
## SEO 优化
### 检查文章 SEO
```powershell
# 获取最近 10 篇文章的 SEO 信息
$posts = halo post list --page 1 --size 10 --json | ConvertFrom-Json
foreach ($post in $posts.items) {
$detail = halo post get $post.name --json | ConvertFrom-Json
Write-Host "文章: $($detail.title)"
Write-Host " - 字数: $($detail.wordCount)"
Write-Host " - 标签: $($detail.tags -join ', ')"
Write-Host " - URL: $($detail.slug)"
Write-Host ""
}
```
### 批量更新 SEO 描述
```powershell
# 为所有文章添加 SEO 描述
$posts = halo post list --page 1 --size 50 --json | ConvertFrom-Json
foreach ($post in $posts.items) {
$detail = halo post get $post.name --json | ConvertFrom-Json
# 生成描述(前 160 个字符)
$excerpt = $detail.content -replace '<[^>]+>', '' # 去除 HTML 标签
$excerpt = $excerpt.Substring(0, [Math]::Min(160, $excerpt.Length))
halo post update $post.name --description $excerpt
}
```
---
## 高级配置
### 使用不同 Profile
```powershell
# 列出所有配置
halo auth profile list
# 使用指定配置
halo post list --profile production
# 创建新配置
halo auth login --profile aliyun --url http://101.133.128.193:8091 --auth-type bearer --token <token>
```
### 环境变量配置
```powershell
# 临时修改配置目录
$env:HALO_CLI_CONFIG_DIR = "d:\halo-config"
# 使用代理
$env:HTTPS_PROXY = "http://proxy:8080"
# 禁用 SSL 验证(不推荐)
$env:HALO_CLI_INSECURE_SSL = "true"
```
### 调试模式
```powershell
# 显示详细输出
halo post list --page 1 --size 20 --verbose
# 查看配置
halo auth current --verbose
# 查看请求/响应
halo post get <id> --debug
```
---
## 常见问题解决
### Token 过期
```powershell
# 刷新 Token
halo auth login --profile local --url http://192.168.5.8:8091 --auth-type bearer --token <new-token>
```
### 网络问题
```powershell
# 使用超时设置
halo post list --timeout 30
# 重试机制
$maxRetries = 3
for ($i = 1; $i -le $maxRetries; $i++) {
halo post list --page 1 --size 20
if ($LASTEXITCODE -eq 0) { break }
Start-Sleep -Seconds 5
}
```
### 并发限制
Halo API 有请求限制,高并发操作可能导致失败。建议:
- 使用 `--rate-limit 10`(如果支持)
- 添加延迟:`Start-Sleep -Milliseconds 100`
- 批量操作使用 `--batch` 标志(如果支持)
@@ -1,485 +0,0 @@
# Halo CLI 命令参考
完整命令列表和详细用法。
## 认证相关(auth
```powershell
# 查看当前认证状态
halo auth current
# 列出所有配置
halo auth profile list
# 登录(Bearer Token
halo auth login --profile local --url http://192.168.5.8:8090 --auth-type bearer --token <token>
# 登录(Basic Auth
halo auth login --profile local --url http://192.168.5.8:8090 --auth-type basic --username admin --password <password>
# 移除配置
halo auth remove local
# 切换默认配置
halo auth default production
```
## 文章管理(post
### 列出文章
```powershell
# 基本列表
halo post list
# 分页
halo post list --page 1 --size 20
# JSON 格式(便于脚本处理)
halo post list --page 1 --size 20 --json
# 按状态筛选
halo post list --status published
halo post list --status draft
```
### 获取文章
```powershell
# 查看文章详情
halo post get 019dbabc-86b9-74a0-a926-c25529309007
# JSON 格式
halo post get 019dbabc-86b9-74a0-a926-c25529309007 --json
```
### 创建文章
```powershell
# 基本创建(草稿)
halo post create --title "我的第一篇文章" --content "# 标题\n\n内容..."
# 创建并发布
halo post create --title "我的第一篇文章" --content "# 标题" --publish true
# 使用 HTML 格式
halo post create --title "HTML 文章" --content "<h1>标题</h1><p>内容</p>" --raw-type html
# 指定分类
halo post create --title "文章" --content "内容" --category "技术"
# 指定标签
halo post create --title "文章" --content "内容" --tags "Python,教程"
```
### 更新文章
```powershell
# 更新标题
halo post update 019dbabc-86b9-74a0-a926-c25529309007 --title "新标题"
# 更新内容
halo post update 019dbabc-86b9-74a0-a926-c25529309007 --content "# 新内容"
# 同时更新标题和内容
halo post update 019dbabc-86b9-74a0-a926-c25529309007 --title "新标题" --content "新内容"
# 更新标签
halo post update 019dbabc-86b9-74a0-a926-c25529309007 --tags "新标签1,新标签2"
# 发布草稿
halo post update 019dbabc-86b9-74a0-a926-c25529309007 --publish true
# 取消发布
halo post update 019dbabc-86b9-74a0-a926-c25529309007 --unpublish
```
### 删除文章
```powershell
# 删除文章(会提示确认)
halo post delete 019dbabc-86b9-74a0-a926-c25529309007
# 强制删除(跳过确认)
halo post delete 019dbabc-86b9-74a0-a926-c25529309007 --force
```
### 导出文章
```powershell
# 导出为 JSON
halo post export-json 019dbabc-86b9-74a0-a926-c25529309007
# 导出到指定文件
halo post export-json 019dbabc-86b9-74a0-a926-c25529309007 --output ./backup/post.json
# 导出为 Markdown
halo post export-markdown 019dbabc-86b9-74a0-a926-c25529309007
# 导出到指定文件
halo post export-markdown 019dbabc-86b9-74a0-a926-c25529309007 --output ./backup/post.md
```
### 导入文章
```powershell
# 从 JSON 文件导入
halo post import-json --file ./backup/post.json
# 从 JSON 字符串导入
halo post import-json --raw '{"post": {...}, "content": "..."}'
# 从 Markdown 文件导入
halo post import-markdown --file ./backup/post.md
# 导入并发布
halo post import-markdown --file ./post.md --publish true
```
### 文章标签管理
```powershell
# 列出所有标签
halo post tag list
# 创建标签
halo post tag create --name "Python" --slug "python" --color "#3776AB"
# 更新标签名称
halo post tag update python --name "Python编程"
# 更新标签颜色
halo post tag update python --color "#3776AB"
# 删除标签
halo post tag delete python
# 查看标签下的文章数量
halo post tag list --verbose
```
### 文章分类管理
```powershell
# 列出所有分类
halo post category list
# 创建分类
halo post category create --name "技术" --slug "tech" --priority 10
# 更新分类
halo post category update tech --name "技术分享" --priority 5
# 删除分类
halo post category delete tech
# 设置分类优先级(数字越大排序越靠前)
halo post category update tech --priority 10
```
### 为文章设置标签和分类
```powershell
# 创建文章时设置标签
halo post create --title "标题" --content "内容" --tags "Python,教程"
# 创建文章时设置分类
halo post create --title "标题" --content "内容" --category "技术"
# 同时设置标签和分类
halo post create --title "标题" --content "内容" --tags "AI,教程" --category "技术"
# 更新文章的标签
halo post update <id> --tags "新标签1,新标签2"
# 更新文章的分类
halo post update <id> --category "技术分享"
# 清除文章的标签
halo post update <id> --tags ""
# 清除文章的分类
halo post update <id> --category ""
```
### 查询文章标签和分类
```powershell
# 查看某篇文章的标签(JSON 格式)
halo post get <id> --json | Select-String -Pattern "tags"
# 列出所有带有特定标签的文章
halo post list --page 1 --size 100 --json | ConvertFrom-Json | Where-Object {
$_.spec.tags -contains "AI智能体"
}
# 列出所有带有特定分类的文章
halo post list --page 1 --size 100 --json | ConvertFrom-Json | Where-Object {
$_.spec.categories -contains "技术深潜"
}
```
### 批量修改标签
```powershell
# 为所有无标签的文章添加标签
$posts = halo post list --page 1 --size 100 --json | ConvertFrom-Json
foreach ($post in $posts.items) {
if ($post.spec.tags.Count -eq 0) {
halo post update $post.name --tags "技术深潜"
Write-Host "已为 '$($post.spec.title)' 添加标签"
}
}
# 将所有文章从"旧标签"迁移到"新标签"
$posts = halo post list --page 1 --size 100 --json | ConvertFrom-Json
foreach ($post in $posts.items) {
if ($post.spec.tags -contains "旧标签") {
$newTags = $post.spec.tags -replace "旧标签", "新标签"
halo post update $post.name --tags ($newTags -join ",")
}
}
```
### 博客现有标签参考
| 显示名称 | Slug | 颜色 |
|---------|------|------|
| 协会动态 | xie-hui-dong-tai | #B8E986 |
| 5分钟速览 | 5fen-zhong-su-lan | #50E3C2 |
| 技术深潜 | ji-shu-shen-qian | #4A90E2 |
| 校园AI | xiao-yuan-ai | #9013FE |
| 竞赛指南 | jing-sai-zhi-nan | #BD10E0 |
| 项目实战 | xiang-mu-shi-zhan | #417505 |
| 零基础入门 | ling-ji-chu-ru-men | #7ED321 |
| 开源框架 | kai-yuan-kuang-jia | #8B572A |
| 模型轻量化 | mo-xing-qing-liang-hua | #F8E71C |
| 隐私计算 | yin-si-ji-suan | #F5A623 |
| AI智能体 | aizhi-neng-ti | #D0021B |
### 博客现有分类参考
| 显示名称 | Slug |
|---------|------|
| 行业望远镜 | xing-ye-wang-yuan-jing |
| 协会进行时 | xie-hui-jin-xing-shi |
| 校园AI日记 | xiao-yuan-airi-ji |
| 竞赛能量站 | jing-sai-neng-liang-zhan |
| 成长实验室 | cheng-chang-shi-yan-shi |
| 智能体前沿 | zhi-neng-ti-qian-yan |
| 默认分类 | default |
## 单页管理(single-page
```powershell
# 列出单页
halo single-page list
# 查看单页
halo single-page get <name>
# 创建单页
halo single-page create --title "关于我们" --content "公司介绍..."
# 更新单页
halo single-page update about --title "关于我们" --content "新内容"
# 删除单页
halo single-page delete about --force
# 导出/导入
halo single-page export-markdown <name> --output ./page.md
halo single-page import-markdown --file ./page.md
```
## 搜索内容(search
```powershell
# 搜索公开文章
halo search "Python 教程"
# 搜索并限制结果
halo search "教程" --limit 10
# 搜索并显示详细信息
halo search "教程" --json
```
## 插件管理(plugin
```powershell
# 列出插件
halo plugin list
# 获取插件详情
halo plugin get <plugin-name>
# 升级插件
halo plugin upgrade <plugin-name>
# 升级所有插件
halo plugin upgrade --all
# 启用/禁用插件
halo plugin enable <plugin-name>
halo plugin disable <plugin-name>
```
## 主题管理(theme
```powershell
# 列出主题
halo theme list
# 获取主题详情
halo theme get <theme-name>
# 升级主题
halo theme upgrade <theme-name>
# 切换主题
halo theme active <theme-name>
```
## 附件管理(attachment
```powershell
# 列出附件
halo attachment list
# 上传附件
halo attachment upload --file ./image.png
# 删除附件
halo attachment delete <attachment-id>
```
## 备份管理(backup
```powershell
# 列出备份
halo backup list
# 创建备份
halo backup create
# 下载备份
halo backup download <backup-id> --output ./backup.zip
# 删除备份
halo backup delete <backup-id>
```
## 动态管理(moment
```powershell
# 列出动态
halo moment list
# 创建动态
halo moment create --content "今天写了两篇博客!"
# 删除动态
halo moment delete <moment-id>
```
## 评论管理(comment
```powershell
# 列出评论
halo comment list
# 列出未审核评论
halo comment list --status pending
# 回复评论
halo comment reply <comment-id> --content "感谢您的评论!"
# 审核评论
halo comment approve <comment-id>
halo comment reject <comment-id>
# 删除评论
halo comment delete <comment-id>
```
## 通知管理(notification
```powershell
# 列出通知
halo notification list
# 标记已读
halo notification mark-read <notification-id>
# 全部标记已读
halo notification mark-all-read
# 删除通知
halo notification delete <notification-id>
```
## Shell 补全
```powershell
# bash
eval "$(halo completion bash)"
# zsh
eval "$(halo completion zsh)"
# PowerShell(自动添加到配置文件)
halo completion powershell >> $PROFILE
```
## 输出格式
### 普通输出
```powershell
# 表格格式(默认)
halo post list
# JSON 格式
halo post list --json
# YAML 格式
halo post list --yaml
```
### 颜色输出
```powershell
# 彩色输出(默认)
halo post list --color
# 禁用颜色
halo post list --no-color
```
## 超时和重试
```powershell
# 设置超时(秒)
halo post list --timeout 60
# 重试次数
halo post list --retry 3
```
## 调试
```powershell
# 显示调试信息
halo --debug post list
# 显示完整错误
halo post create --title "Test" --content "Content" --verbose
# 查看版本
halo --version
# 查看帮助
halo --help
halo post --help
```
-37
View File
@@ -1,37 +0,0 @@
# 图片上传功能检查清单
## 代码实现检查
- [x] `src/utils/image.ts` 文件创建完成
- [x] `extractImageReferences()` 函数正确实现
- [x] `getAbsolutePath()` 函数正确实现
- [x] `replaceImagePaths()` 函数正确实现
- [x] `src/service/image-uploader.ts` 文件创建完成
- [x] `uploadImage()` 方法正确调用 Halo API
- [x] `uploadImages()` 方法正确实现批量上传
- [x] 图片缓存机制正确实现
## 设置界面检查
- [x] 设置界面包含图片上传开关
- [x] 设置界面包含上传路径配置
- [x] 设置数据正确保存和加载
## 集成检查
- [x] 发布流程正确调用图片上传
- [x] 图片路径正确替换为远程 URL
- [x] 上传失败时正确处理错误
## 国际化检查
- [x] 英文文案添加完成
- [x] 简体中文文案添加完成
- [x] 繁体中文文案添加完成
## 测试检查
- [x] 编译通过无错误
- [x] 插件文件正确复制到 Obsidian 插件目录
- [x] 基本功能测试通过
- [x] 图片上传测试通过
-107
View File
@@ -1,107 +0,0 @@
# 图片上传功能规格说明
## Why
当前 obsidian-halo 插件无法将本地图片上传到 Halo 媒体库,导致发布的文章中的图片无法正常显示。这是一个核心功能缺失,直接影响使用体验。
## What Changes
- 新增图片检测模块:解析 Markdown 中的本地图片引用
- 新增图片上传服务:调用 Halo 媒体 API 上传图片
- 新增图片路径替换:自动将本地路径替换为 Halo 远程 URL
- 新增设置选项:允许用户开关自动上传功能
## Impact
- 影响规格:
- 发布功能:发布时自动处理图片
- 设置功能:新增图片上传相关配置
- 影响代码:
- 新增 `src/utils/image.ts`:图片处理工具函数
- 新增 `src/service/image-uploader.ts`:图片上传服务
- 修改 `src/service/index.ts`:集成图片上传到发布流程
- 修改 `src/settings.ts`:添加图片上传设置项
- 修改 `src/i18n/locales/*.json`:添加国际化文案
## ADDED Requirements
### Requirement: 图片自动上传
系统 SHALL 在发布文档时自动检测并上传本地图片到 Halo 媒体库。
#### Scenario: 检测到本地图片
- **WHEN** 用户执行发布命令且文档中包含本地图片(如 `assets/image.png`
- **THEN** 系统自动上传图片到 Halo 并将文档中的路径替换为远程 URL
#### Scenario: 图片已上传过
- **WHEN** 系统检测到相同图片(基于文件路径和修改时间)
- **THEN** 直接使用已上传的 URL,不重复上传
#### Scenario: 上传失败
- **WHEN** 图片上传过程中发生错误
- **THEN** 系统记录错误并继续处理其他图片,已失败的图片保持原路径
### Requirement: 图片路径识别
系统 SHALL 支持识别以下格式的图片引用:
- `![alt](assets/image.png)` - 普通 Markdown 图片语法
- `![alt](./assets/image.png)` - 相对路径
- `![alt](/assets/image.png)` - 绝对路径(Vault 根目录)
- `![](data:image/png;base64,...)` - Base64 内联图片(可选支持)
### Requirement: 上传配置选项
系统 SHALL 提供以下配置选项:
- 开关:是否启用自动图片上传
- 媒体库路径:上传到 Halo 的哪个媒体目录
- 保留原图:是否保留本地路径作为备选
## MODIFIED Requirements
### Requirement: 发布流程
原发布流程:
1. 读取文档内容
2. 解析 frontmatter
3. 提交到 Halo API
修改后的发布流程:
1. 读取文档内容
2. 解析 frontmatter
3. **检测并上传本地图片**
4. **替换图片路径为远程 URL**
5. 提交到 Halo API
## REMOVED Requirements
---
## 技术实现细节
### Halo 媒体上传 API
```
POST /apis/api.console.halo.run/v1alpha1/attachments/upload
Content-Type: multipart/form-data
请求体:
- file: 二进制文件数据
- groupName: 媒体分组名称(可选)
响应:
{
"name": "uuid-filename.png",
"url": "/upload/2024/01/abc.png",
"type": "IMAGE",
"size": 12345
}
```
### 图片检测正则
```typescript
const imageRegex = /!\[([^\]]*)\]\(([^)]+)\)/g;
```
### 配置项
```typescript
interface ImageUploadSettings {
enabled: boolean; // 是否启用
uploadPath: string; // 上传路径(空表示根目录)
preserveOriginal: boolean; // 保留原路径
}
```
-58
View File
@@ -1,58 +0,0 @@
# 图片上传功能任务清单
## 任务列表
- [x] 任务 1:创建图片处理工具模块 `src/utils/image.ts`
- [ ] 子任务 1.1:实现 `extractImageReferences()` 函数,检测 Markdown 中的图片引用
- [ ] 子任务 1.2:实现 `getAbsolutePath()` 函数,将相对路径转为绝对路径
- [ ] 子任务 1.3:实现 `replaceImagePaths()` 函数,替换图片路径
- [x] 任务 2:创建图片上传服务 `src/service/image-uploader.ts`
- [ ] 子任务 2.1:实现 `uploadImage()` 方法,调用 Halo 媒体 API 上传单个图片
- [ ] 子任务 2.2:实现 `uploadImages()` 方法,批量上传图片并返回映射表
- [ ] 子任务 2.3:实现缓存机制,记录已上传图片的 URL
- [x] 任务 3:更新设置界面 `src/settings.ts`
- [x] 子任务 3.1:在设置界面添加图片上传开关
- [x] 子任务 3.2:添加上传路径配置项
- [x] 子任务 3.3:更新设置数据结构
- [x] 任务 5:添加国际化文案 `src/i18n/locales/*.json`
- [x] 子任务 5.1:添加英文文案
- [x] 子任务 5.2:添加简体中文文案
- [x] 子任务 5.3:添加繁体中文文案
- [x] 任务 4:集成图片上传到发布流程 `src/service/index.ts`
- [x] 子任务 4.1:在 `publishPost()` 方法中调用图片上传
- [x] 子任务 4.2:处理上传后的路径替换
- [x] 子任务 4.3:添加错误处理和用户提示
- [ ] 任务 5:添加国际化文案 `src/i18n/locales/*.json`
- [ ] 子任务 5.1:添加英文文案
- [ ] 子任务 5.2:添加简体中文文案
- [ ] 子任务 5.3:添加繁体中文文案
- [x] 任务 6:编译和测试
- [x] 子任务 6.1:运行 `pnpm build` 确保编译通过
- [x] 子任务 6.2:复制编译产物到插件目录
- [x] 子任务 6.3:手动测试图片上传功能
---
## 任务依赖关系
- [任务 1] 和 [任务 2] 可并行开发
- [任务 3] 可在 [任务 2] 完成后开始
- [任务 4] 依赖 [任务 1] 和 [任务 2] 完成
- [任务 5] 可与其他任务并行进行
- [任务 6] 需要所有其他任务完成后执行
---
## 实现顺序建议
1. 先完成 [任务 1] 和 [任务 2](核心功能)
2. 再完成 [任务 3](配置界面)
3. 然后完成 [任务 4](集成)
4. [任务 5] 和 [任务 3] 可同时进行
5. 最后 [任务 6](测试)
-33
View File
@@ -1,33 +0,0 @@
# Markdown 文件导入功能检查清单
## 代码实现检查
- [ ] `src/commands/import-markdown.ts` 文件创建完成
- [ ] 文件选择器正确实现(仅显示 .md 文件)
- [ ] 文件读取和解析逻辑正确
- [ ] 文章创建逻辑正确调用 Halo API
- [ ] `src/modals/file-preview-modal.ts` 文件创建完成
- [ ] 文件内容预览正确显示
- [ ] frontmatter 信息正确显示
- [ ] 导入/取消按钮功能正常
- [ ] "导入后发布"选项功能正常
## 集成检查
- [ ] `src/main.ts` 中命令注册完成
- [ ] 命令名称符合国际化规范
- [ ] 命令在命令面板中可见
## 国际化检查
- [ ] 英文文案添加完成
- [ ] 简体中文文案添加完成
- [ ] 繁体中文文案添加完成
## 测试检查
- [ ] 编译通过无错误
- [ ] 插件文件正确复制到 Obsidian 插件目录
- [ ] 文件选择器测试通过
- [ ] 导入功能测试通过(创建草稿)
- [ ] 导入功能测试通过(导入并发布)
-96
View File
@@ -1,96 +0,0 @@
# Markdown 文件导入功能规格说明
## Why
当前 Obsidian Halo 插件只支持从 Obsidian 发布文章到 Halo,但没有提供从本地 Markdown 文件导入创建文章的功能。用户可能希望:
1. 直接从文件系统导入已存在的 Markdown 文件
2. 从其他平台迁移文章时批量导入
3. 快速创建新文章时选择本地文件而非在编辑器中编写
## What Changes
- 新增命令:直接从 Markdown 文件导入创建 Halo 文章
- 新增文件选择器:支持选择本地 .md 文件
- 新增预览功能:导入前预览文件内容和 frontmatter
- 新增选项:导入时是否立即发布
## Impact
- Affected specs:
- 文章发布功能:提供新的文章创建入口
- 设置功能:可能需要添加导入相关配置
- Affected code:
- 新增 `src/commands/import-markdown.ts`:导入命令
- 新增 `src/modals/file-preview-modal.ts`:文件预览弹窗
- 修改 `src/main.ts`:注册新命令
- 修改 `src/i18n/locales/*.json`:国际化文案
## ADDED Requirements
### Requirement: 从 Markdown 文件导入
系统 SHALL 提供从本地 Markdown 文件导入创建 Halo 文章的功能。
#### Scenario: 选择文件导入
- **WHEN** 用户执行"从 Markdown 文件导入"命令
- **THEN** 系统显示文件选择器,允许用户选择 .md 文件
#### Scenario: 预览和确认
- **WHEN** 用户选择了一个 Markdown 文件
- **THEN** 系统显示文件内容预览(标题、内容摘要、frontmatter
- **AND** 显示"导入"和"取消"按钮
#### Scenario: 导入成功
- **WHEN** 用户点击"导入"按钮
- **THEN** 系统读取文件内容
- **AND** 解析 frontmatter 和正文
- **AND** 调用 Halo API 创建文章
- **AND** 显示导入成功通知
#### Scenario: 导入选项
- **WHEN** 用户可以勾选"导入后立即发布"选项
- **THEN** 文章创建后自动发布
## MODIFIED Requirements
### Requirement: 命令面板扩展
现有命令列表扩展,新增:
- `Halo: 从 Markdown 文件导入` - 打开文件选择器进行导入
## REMOVED Requirements
---
## 技术实现细节
### Obsidian 文件选择器 API
```typescript
const filePicker = app.createFilePicker();
filePicker.setFilter(file => file.extension === 'md');
filePicker.onChange = async (files) => {
// 处理选中的文件
};
filePicker.open();
```
### 文件读取
```typescript
const content = await app.vault.read(file);
```
### Frontmatter 解析
参考现有的 `src/utils/yaml.ts` 实现,或使用 gray-matter 库。
### API 端点
```
POST /apis/uc.api.content.halo.run/v1alpha1/posts
```
请求体格式与发布功能相同。
-47
View File
@@ -1,47 +0,0 @@
# Markdown 文件导入功能任务清单
## 任务列表
- [ ] 任务 1:创建导入命令模块 `src/commands/import-markdown.ts`
- [ ] 子任务 1.1:实现 Obsidian 文件选择器调用
- [ ] 子任务 1.2:实现文件读取和解析
- [ ] 子任务 1.3:实现文章创建逻辑
- [ ] 任务 2:创建文件预览弹窗 `src/modals/file-preview-modal.ts`
- [ ] 子任务 2.1:显示文件内容预览
- [ ] 子任务 2.2:显示 frontmatter 信息
- [ ] 子任务 2.3:添加导入/取消按钮
- [ ] 子任务 2.4:添加"导入后发布"选项
- [ ] 任务 3:更新主程序注册命令 `src/main.ts`
- [ ] 子任务 3.1:导入新命令模块
- [ ] 子任务 3.2:注册"从 Markdown 文件导入"命令
- [ ] 任务 4:添加国际化文案
- [ ] 子任务 4.1:更新英文文案 `src/i18n/locales/en.json`
- [ ] 子任务 4.2:更新简体中文文案 `src/i18n/locales/zh-cn.json`
- [ ] 子任务 4.3:更新繁体中文文案 `src/i18n/locales/zh-tw.json`
- [ ] 任务 5:编译和测试
- [ ] 子任务 5.1:运行 `pnpm build` 确保编译通过
- [ ] 子任务 5.2:复制编译产物到插件目录
- [ ] 子任务 5.3:手动测试导入功能
---
## 任务依赖关系
- [任务 2] 和 [任务 3] 可并行开发
- [任务 1] 依赖 [任务 2] 完成
- [任务 4] 可与任何任务并行
- [任务 5] 需要 [任务 1]、[任务 3] 完成
---
## 实现顺序建议
1. 先完成 [任务 2](文件预览弹窗)- 核心 UI
2. 再完成 [任务 1](导入命令模块)- 核心逻辑
3. 然后完成 [任务 3](注册命令)
4. [任务 4] 可与 [任务 1] 并行
5. 最后 [任务 5](测试)
@@ -1,36 +0,0 @@
# 同步状态面板和历史功能检查清单
## 代码实现检查
- [x] `src/views/sync-status-view.ts` 文件创建完成
- [x] 扫描已发布文章逻辑正确
- [x] 文章列表显示正确(标题、slug、状态)
- [x] 快速操作按钮功能正常(更新、拉取)
- [x] `src/modals/sync-history-modal.ts` 文件创建完成
- [x] 同步历史记录显示正确
- [x] 清除历史功能正常
## 集成检查
- [x] `src/main.ts` 中命令注册完成
- [x] 侧边栏图标正确显示
- [x] 命令面板中可见相关命令
## 国际化检查
- [x] 中文文案添加完成
- [x] 英文文案添加完成
- [x] 繁体中文文案添加完成
## 文档检查
- [x] `docs/usage-guide.md` 创建完成
- [x] 所有命令都有使用说明
- [x] 常见问题解答包含在内
## 测试检查
- [x] 编译通过无错误
- [x] 插件文件正确复制到 Obsidian 插件目录
- [ ] 同步状态面板测试通过(需要手动测试)
- [ ] 同步历史功能测试通过(需要手动测试)
-93
View File
@@ -1,93 +0,0 @@
# 同步状态面板功能规格说明
## Why
当前插件的功能分散在多个命令中,用户难以直观地了解:
1. 哪些文章已发布到 Halo
2. 文章的同步状态如何
3. 最近的操作历史和结果
需要一个集中的状态管理面板,让用户一眼就能看到所有同步状态。
## What Changes
- 新增**同步状态面板**:在 Obsidian 侧边栏显示已发布文章列表及状态
- 显示文章同步时间戳、发布状态、本地/Halo 版本差异
- 支持快速操作:更新、拉取、删除
- 新增使用指南文档
## Impact
- Affected specs:
- 状态管理和日志
- 命令面板增强
- Affected code:
- 新增 `src/commands/sync-status-panel.ts`:侧边栏面板
- 新增 `src/modals/sync-history-modal.ts`:同步历史弹窗
- 修改 `src/main.ts`:注册面板命令
- 新增 `docs/usage-guide.md`:使用指南
## ADDED Requirements
### Requirement: 同步状态面板
系统 SHALL 提供一个侧边栏面板,显示已发布到 Halo 的文章列表及其状态。
#### Scenario: 打开面板
- **WHEN** 用户执行"打开同步状态面板"命令
- **THEN** 在侧边栏显示面板,包含已发布文章列表
#### Scenario: 显示文章状态
- **WHEN** 面板加载时
- **THEN** 显示所有已发布文章的:标题、slug、发布状态、同步时间
#### Scenario: 快速操作
- **WHEN** 用户点击文章的操作按钮
- **THEN** 可以快速执行:更新、拉取、删除操作
#### Scenario: 同步历史
- **WHEN** 用户点击"同步历史"按钮
- **THEN** 显示最近的操作记录
### Requirement: 使用指南
系统 SHALL 提供一份详细的使用指南,说明所有功能的位置和使用方法。
## MODIFIED Requirements
## REMOVED Requirements
---
## 技术实现细节
### Obsidian 面板 API
```typescript
// 创建侧边栏面板
this.addRibbonIcon("sync-icon", "同步状态", (evt) => {
this.openSyncStatusPanel();
});
```
### 扫描已发布文章
通过扫描 Vault 中的所有文件,查找 frontmatter 中包含 `halo.name` 的文件。
### 状态图标
- ✅ 已同步(本地和 Halo 版本一致)
- ⏳ 待同步(本地有更新)
- ⚠️ 有冲突(两边都有更新)
---
## 实现优先级
1. 同步状态面板(核心 UI
2. 同步历史记录(辅助功能)
3. 使用指南文档(用户教育)
-42
View File
@@ -1,42 +0,0 @@
# 同步状态面板和历史功能任务清单
## 任务列表
- [x] 任务 1:创建同步状态面板 `src/commands/sync-status-panel.ts`
- [x] 子任务 1.1:扫描 Vault 中已发布的文章
- [x] 子任务 1.2:显示文章列表和状态
- [x] 子任务 1.3:添加快速操作按钮
- [x] 任务 2:创建同步历史弹窗 `src/modals/sync-history-modal.ts`
- [x] 子任务 2.1:显示最近的操作记录
- [x] 子任务 2.2:支持查看详情和清除历史
- [x] 任务 3:更新主程序 `src/main.ts`
- [x] 子任务 3.1:注册打开面板命令
- [x] 子任务 3.2:添加侧边栏图标
- [x] 子任务 3.3:添加打开历史命令
- [x] 任务 4:添加国际化文案
- [x] 子任务 4.1:更新 zh-cn.json
- [x] 子任务 4.2:更新 en.json
- [x] 子任务 4.3:更新 zh-tw.json
- [x] 任务 5:编写使用指南 `docs/usage-guide.md`
- [x] 子任务 5.1:概述所有功能
- [x] 子任务 5.2:命令列表和使用方法
- [x] 子任务 5.3:常见问题解答
- [x] 任务 6:编译和测试
- [x] 子任务 6.1:运行 `pnpm build` 确保编译通过
- [x] 子任务 6.2:复制编译产物到插件目录
---
## 实现顺序总结
1. ✅ 完成 [任务 1](同步状态面板)- 核心 UI
2. ✅ 完成 [任务 2](同步历史)- 辅助功能
3. ✅ 完成 [任务 3](注册命令)
4. ✅ 完成 [任务 4](国际化)
5. ✅ 完成 [任务 5](使用指南)
6. ✅ 完成 [任务 6](测试)
-1035
View File
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,198 @@
---
title: AI 时代的 Token 战争:能源、算力与我们每个人的选择
slug: ai-token
categories:
- 技术思考
tags:
- 技术深潜
- AI智能体
halo:
site: https://blog.liuhangyv.top
name: da325dee-9575-45ea-8593-192c39402edc
publish: false
---
# AI 时代的 Token 战争:能源、算力与我们每个人的选择
> "Token 是电的加工计价单位。同一个 Token,可以用来发现抗癌新药,也可以用来生成一段毫无意义的废话。它的价值,由使用者决定。"
---
## 一、引言:一个新的"工业时代"正在开启
2024 年,一家软件公司包下了一座核电站未来 20 年的全部发电量。
这不是科幻小说,这是微软对三哩岛核电站的真实操作。1979 年,这里发生过美国历史上最严重的核事故,2 号反应堆永久关停。45 年后,微软签下了一份合同——买断 1 号机组未来 20 年的全部电力,只为喂饱它那些永远吃不饱的 AI 数据中心。
而在地球的另一端,中东的产油国们正在做一件意味深长的事:他们不再只卖石油,而是开始大规模建设清洁能源基地和算力中心。沙特、阿联酋正在向全世界宣告——未来,我们要卖 Token。
**一个新的"工业时代"正在悄悄开启**。但这次跟蒸汽时代、电气时代不一样:它的基础设施不再是铁路和电网,而是 GPU 集群和核电站;它的流通货币不再是钢铁和石油,而是一个叫 **Token** 的东西。
这篇文章,我想和你聊聊这个新时代的真实图景——以及为什么它的结局,可能取决于你我每个人在屏幕前的每一个选择。
---
## 二、巨头全链布局:从芯片到核电站
### 2.1 微软:从三哩岛到 Azure,全链条通吃
2024 年,微软干了几件让整个科技圈震动的事:
**第一件事:包下核电站。** 微软与三哩岛核电站 1 号机组签订了 20 年购电协议,买断了其全部发电量。一个软件公司,为什么需要一座核电站?答案很简单:**AI 太耗电了**。训练一次 GPT-4 级别的模型,耗电量相当于一个小型城镇一年的用电量。而推理服务——也就是你每次跟 ChatGPT 聊天——每天都在消耗天文数字的电力。
**第二件事:联合英伟达推出 RTX Spark 芯片。** 这枚芯片的意义在于,微软和英伟达共同喊出了一句口号:"我们重新发明了 PC。"但背后的真实逻辑是什么?往下看英伟达的部分你会明白。
**第三件事:通过 Azure 云整合 AI 上下游。** 从算力基础设施(Azure)到模型服务(OpenAI 的合作),再到终端芯片(RTX Spark),微软正在构建一个完整的闭环。它要的不是某个环节的利润,而是整个 AI 产业链的主导权。
### 2.2 英伟达:当游戏显卡不再是主业
翻开英伟达 2025 财年的财报,你会发现一个惊人的数字:
**游戏显卡业务收入占比:仅 8.8%。**
对,就是那个靠"为游戏玩家造显卡"起家的英伟达,如今游戏业务已经不足总收入的十分之一。你会发现,它现在真正的客户是微软、谷歌、亚马逊这些云计算巨头,是企业级数据中心,是全世界的 AI 公司。
但问题来了——**这种集中度意味着焦虑**。英伟达的命脉掌握在少数几个大客户手里,任何一个客户开始自研芯片,都会对英伟达造成巨大冲击。这就是为什么黄仁勋要联手微软推出 RTX Spark 芯片——**它要开辟 C 端市场,把 AI 算力卖给每一个普通人**。
这枚芯片的商业逻辑是这样的:
- B 端市场虽然单价高,但客户集中、议价能力强
- C 端市场虽然单价低,但用户基数巨大、分散度高
- 如果每个 PC 都内置一块 AI 推理芯片,英伟达就不需要担心任何一个大客户的离开
### 2.3 OpenAI 与微软:从盟友到对手
曾几何时,OpenAI 和微软是 AI 领域最耀眼的 CP 组合。微软出钱出算力,OpenAI 出模型出技术,双方各取所需。
但到了 2024-2025 年,这对盟友的关系正在发生微妙的变化。OpenAI 不再满足于做微软的"模型供应商",它开始自己构建算力基础设施,自己对接企业客户,甚至开始推出与 Azure 竞争的服务。而微软也在自研模型、扩大合作范围,不再把鸡蛋全部放在 OpenAI 一个篮子里。
**这条产业链上的每个玩家,都在试图控制更多环节。** 因为在这个时代,谁控制了能源→算力→模型→应用的完整链条,谁就掌握了定价权。
---
## 三、国家级的电力争夺战
### 3.1 美国:科技巨头"抢电"进行时
美国的科技巨头们正在上演一场疯狂的"抢电大战"。亚马逊、谷歌、微软、Meta——每一家都在以惊人的速度建设数据中心,每一家都在满世界找电力供应。
这不是夸张。AI 数据中心的耗电量正在以指数级增长。一个超大规模数据中心,单日耗电量可以达到一个中型城市的水平。而当几十个这样的数据中心同时在建设时,电力供应就成了最稀缺的资源。
**微软包下三哩岛核电站,只是这场"抢电大战"的一个缩影。**
### 3.2 爱尔兰:被数据中心"吃垮"的电网
也许你会觉得,美国的事离我们很远。那我们来看看爱尔兰。
2015 年到 2024 年,爱尔兰数据中心耗电占比从 **5%** 飙升至 **22%**
也就是说,爱尔兰全国超过五分之一的电力,被数据中心吃掉了。
这导致的结果是:爱尔兰政府宣布,**2028 年之前不再批准新的数据中心接入电网**。一个国家,因为 AI 太耗电,不得不主动限制这个新兴产业的发展。这是历史上从来没有发生过的事。
### 3.3 中东:从卖石油到卖 Token
最有意​思的格局变化,发生在中东。
沙特、阿联酋这些传统产油国,正在大规模投建清洁能源基地和算力中心。他们的逻辑很清晰:**过去我们卖石油给工业时代提供能量,未来我们要卖 Token 给 AI 时代提供算力。**
从化石能源到算力经济,这是一次深刻的经济转型。而这些国家手中的筹码也很实在:充足的阳光(太阳能)、广阔的土地(建数据中心)、雄厚的资本(投资基础设施)。
他们看到的是:**21 世纪的石油,叫 Token。**
### 3.4 中国:电力充裕 + 国产芯片,走性价比路线
中国在这场 AI 竞赛中的地位非常独特。
一方面,中国的电力供应相对充裕——我们的发电量是世界第一,电网基础设施也更加完善。另一方面,中国在国产 AI 芯片上的投入正在加速,虽然与英伟达还有差距,但在特定场景下已经可以实现替代。
**中国走的是性价比路线**:不需要在每个环节都做到世界顶尖,但要确保全链条的自主可控和成本优势。当美国在用一座核电站喂数据中心的时候,中国在做的是用更低的成本、更广泛的电力网络、更贴近应用场景的算力部署来找到自己的位置。
---
## 四、Token:新时代的计价单位
### 4.1 Token 的本质是什么?
说了这么多,我们来聊聊最核心的概念:**Token 到底是什么?**
简单来说,**Token 是电力的加工计价单位。**
输入电力 → 驱动 GPU → 运行模型 → 产出 Token。这就是 AI 时代的基本生产函数。Token 是这个链条的最终产出物,就像工业时代的钢铁、石油时代的汽油一样。
但 Token 有一个非常特殊的性质:**相同成本的 Token,使用价值可以天差地别。**
### 4.2 同一个 Token,两种命运
请想象两个场景:
**场景 A**:一家药企的科研人员,用 100 万个 Token 让 AI 辅助分析蛋白质结构,推动了抗癌新药的研发进程。这些 Token 的价值,可能在未来拯救成千上万人的生命。
**场景 B**:一个无聊的用户,用 100 万个 Token 让 AI 生成了一堆没有意义的废话,看完就关掉了窗口。这些 Token 的价值,趋近于零。
**Token 的生产成本是一样的,电费是一样的,GPU 折旧是一样的。但使用价值的差异,可以大到无法衡量。**
这就是 AI 时代的核心困境:**我们正在以惊人的速度生产 Token,但如何提高 Token 的价值密度,才是真正的问题。**
### 4.3 泡沫的风险
当前 AI 行业的商业模型,很大程度上建立在"烧钱换增长"的逻辑之上。融资 → 买算力 → 训练模型 → 烧 Token → 融资更多钱 → 买更多算力……
AI 公司亏损是常态,盈利是例外。**整个行业的主要资金来源不是用户的付费,而是投资机构的融资。**
如果有一天,资本市场开始质疑这个循环的可持续性——当"你的 Token 创造了什么实际价值"变成一个必须回答的问题,泡沫就可能破裂。
而避免泡沫的关键,不在于生产更多 Token,而在于**每个 Token 是否被用在真正有价值的地方**。
---
## 五、回归本质:谁决定了 AI 时代的走向?
### 5.1 不是巨头,不是国家,而是你我
聊完巨头、聊完国家、聊完产业链,我们回到最初的问题:**我们,该怎么面对这个充满 AI 的世界?**
微软可以包下核电站,英伟达可以推出新芯片,沙特可以建数据中心——但这些只是供给侧的故事。
**AI 时代的结局,不是由供给决定的,而是由需求决定的。** 或者说得更准确一点:**Token 的价值,由每一个使用它的人决定。**
当我们在屏幕上输入每一个提示词、提出每一个问题时,我们就在给这个系统注入价值信号。你在用 Token 做什么?你是在高效地解决问题,还是在低效率地消耗算力?
**这不是一个宏大叙事,而是一个微观选择。** 亿万个微观选择的集合,最终会塑造这个行业的走向。
### 5.2 独立思考是这个时代最稀缺的能力
这个时代最危险的不是 AI 不够强大,而是人类放弃思考。
当 AI 可以帮你写文章、做决策、分析数据、甚至替你聊天的时候,**"自己思考"反而变成了最难能可贵的事情**。因为用 AI 思考太容易了——输入问题,得到答案,不需要动脑。
但如果你不再思考,你就变成了 AI 的附庸。你的 Token 将永远是低价值的——因为你只是在消费信息,而不是在创造价值。
**独立思考的能力,在这个时代不是可选项,而是必需品。**
### 5.3 提高 Token 的价值密度
最后,我想给每个人一个具体可操作的建议:**提高你生产/消费的每一个 Token 的价值密度。**
具体来说:
- 用 AI 来学习一个你真正需要的技能,而不是生成一堆你不会再看的文字
- 用 AI 来分析一个问题,而不是让它替你做一个你懒得做的决定
- 用 AI 来辅助创造,而不是用它来替代思考
**每一个 Token 都是一张选票。你在为什么投票?**
---
## 六、结语
1979 年,三哩岛的核事故让整个世界对核能产生了恐惧。
45 年后,同一座核电站的另一台机组,正在为人类历史上最强大的智能机器提供动力。
**时代变了,但人性没有变。** 每一次技术革命,都有人抓住机会创造了伟大的价值,也有人被浪潮裹挟着随波逐流。
AI 时代不会因为巨头们的布局、国家间的博弈而自动走向美好的未来。它的走向,最终取决于每一个坐在这块屏幕前的我们——**是否还在独立思考,是否还在为每一个 Token 赋予真实的意义。**
这大概就是这个时代,我们每个人都必须回答的问题。
---
> **#独立思考 #AI #微软 #英伟达 #经济**
@@ -0,0 +1,124 @@
# 在宿舍 NAS 上搭建 Gitea:一个自己的 GitHub
> 校园网封了 22 端口?SMB 写文件权限炸了?sshpass 吃特殊字符?两天踩的坑都在这了。
## 起因
手上项目越来越多,GitHub 国内访问不稳定,Gitee 又有仓库数量限制。刚好手边有台绿联 DXP-2800 NASN100 处理器,8GB 内存,跑 Debian 12),不如自己搭个 Git 服务——代码完全在自己硬盘上,不用联网也能 push,想建多少个私有仓库都行。
## 选型
对比了几个方案:
| 方案 | 优点 | 缺点 |
|------|------|------|
| GitLab | 功能最全,内置 CI/CD | 吃内存,N100 扛不动 |
| Gogs | Go 语言,轻量 | 社区不如 Gitea 活跃 |
| Gitea | Go 语言,GitHub 风格,安装简单 | 够用就行 |
GitLab 最低要求 4GB 内存,加上 NAS 上已经跑了 14 个 Docker 容器(Halo 博客、qBittorrent、PostgreSQL、一堆 Cloudflare Tunnel……),资源不够。**Gitea** 用 SQLite 单用户跑,内存占用不到 256MB,选它。
## 部署
docker-compose 文件很简单:
```yaml
services:
gitea:
image: gitea/gitea:latest
restart: unless-stopped
volumes:
- /volume1/docker/gitea/data:/data
- /etc/localtime:/etc/localtime:ro
ports:
- "3000:3000" # Web UI
- "2222:22" # SSH(避开 NAS 主机的 22 端口)
environment:
- TZ=Asia/Shanghai
- GITEA__database__DB_TYPE=sqlite3
- GITEA__server__DOMAIN=192.168.5.8
- GITEA__server__SSH_DOMAIN=192.168.5.8
- GITEA__server__SSH_PORT=2222
- GITEA__server__ROOT_URL=http://192.168.5.8:3000/
- GITEA__server__APP_NAME=LHY Git
mem_limit: 512m
cpus: 1
```
`docker compose up -d`,一分钟起好。访问 `http://192.168.5.8:3000`,注册第一个账号即为管理员。
## 踩坑:SSH 排错
Gitea 部署完了,但到推送的时候卡住了。问题出在 SSH 认证链路。
### 第一关:GitHub 连不上
`ssh -T git@github.com` 一直 Permission denied,密钥指纹是对的,GitHub 后台也确认加好了。排查了半天发现——**校园网封了 22 端口**。
改走 443 秒通:
```bash
ssh -T -p 443 git@ssh.github.com
# Hi LHY0125! You've successfully authenticated...
```
解决:在 `~/.ssh/config` 里把 GitHub 永久改成 443
```
Host github.com
HostName ssh.github.com
Port 443
User git
IdentityFile ~/.ssh/id_ed25519
```
### 第二关:NAS 密钥认证失败
`ssh LHY@192.168.5.8` 每次都要输密码,即使公钥已经加到了 `authorized_keys`
排查过程:
1. **SSH config 问题** — 配了不存在的 `id_rsa` 私钥,改了。
2. **`authorized_keys` 换行丢失** — 通过 SMB(F: 盘)追加公钥时,旧文件末尾没有换行,导致新旧两行粘在一起。用 `cat -A` 检查后修复。
3. **权限问题** — 这是坑最大的。SMB 写文件不会正确保留 Unix 权限,sshd 要求 `~/.ssh` 必须是 700、`authorized_keys` 必须是 600、家目录不能 group-writable。修复命令:
```bash
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chmod 750 ~
```
### 第三关:sshpass 吃特殊字符
密码里有个 `@``sshpass -p` 参数怎么传都报 Permission denied。试了引号、转义、文件读取都不行。后来发现不是工具问题,是密码本身在 NAS 上已经不是这个了——手动输入能登,说明只是自动化传输特殊字符有问题。**解决:不用密码,用密钥。**
## 推送
两个仓库 `novel-hub``rl-atari` 推上去。Novel 秒推,rl-atari 有 2.2G(含 PDF 文件),SSH 推这个体量的仓库慢得离谱,换成 HTTP 一次过:
```bash
git remote set-url origin http://192.168.5.8:3000/LHY/rl-atari.git
git push -u origin main
```
推完切回 SSH,日常小 update 没压力。
## 效果
现在 `http://192.168.5.8:3000` 就是我的代码中心:
- Web 界面和 GitHub/Gitee 一模一样:Issues、Pull Request、Wiki、Actions
- 局域网内 push/pull 走 NAS 千兆,几秒搞定
- 不需要互联网,代码完全在自己硬盘上
- 想建多少个私有仓库都行,不受任何限制
## 后续
下一步打算:
- 用 Cloudflare Tunnel 把 Gitea 暴露到公网,不在宿舍也能 push
- 给 Gitea 配 GitHub Actions Runner,实现本地 CI/CD
- 把学校课程设计的代码库全部迁移过来
---
**总结**:自托管 Git 服务的门槛比想象中低很多。Docker 部署十分钟,SSH 排错花了大半天。核心教训——校园网封 22 端口、SMB 写文件要注意权限、密钥比密码靠谱。
@@ -0,0 +1,408 @@
---
title: Docker 安装与入门指南
date: 2026-05-08
author: liuhangyv
excerpt: 从零开始学习 Docker:详解 Windows 下通过 Docker Desktop 安装 Docker 的完整流程,以及云服务器(阿里云)上的 Docker 部署方式,附带常用命令速查。
---
# Docker 安装与入门指南
本文面向**零基础读者**,从环境准备到安装完成,一步一步带你上手 Docker。内容聚焦两种最常见的安装场景:
- **场景一**Windows 本机通过 Docker Desktop 安装 Docker
- **场景二**:云服务器(以阿里云为例)上安装 Docker
本文不涉及 Docker Compose、多容器编排等进阶内容,力求用最短的篇幅帮你把 Docker **跑起来**
---
## 1. 什么是 Docker?为什么需要它?
Docker 是一个**容器化平台**,它把应用程序和它的所有依赖打包在一起,形成一个独立的"容器",这个容器可以在任何装了 Docker 的机器上运行,不会因为系统环境不同而出问题。
**一句话理解**:Docker 就像一个轻量级的虚拟机,但比虚拟机快得多、占用资源少得多。
**典型场景**
- 你在 Windows 上开发,但服务器是 Linux——用 Docker,代码在哪跑都一样
- 你想学数据库,但不想在本机装一堆服务——Docker 一行命令就能起一个 MySQL/PostgreSQL
- 你想跑别人写的开源项目,但环境配置太复杂——Docker 一个命令全部搞定
---
## 2. 场景一:Windows 下安装 Docker Desktop
Docker Desktop 是 Docker 官方为 Windows 用户提供的一键安装方案,内置了 WSL2 后端、图形化管理界面,也是官方的推荐方式。
### 2.1 下载与安装
1. 访问 [Docker 官网](https://www.docker.com/products/docker-desktop/),点击 **Download for Windows**
2. 下载完成后运行安装程序,**所有默认选项保持不动即可**,安装程序会自动配置好 WSL2
3. 安装完成后重启电脑
4. 重启后 Docker Desktop 会自动启动,你可以在系统托盘看到 Docker 的鲸鱼图标
> **说明**Docker Desktop 安装时会自动安装 WSL2 并创建两个 WSL 发行版(`docker-desktop` 和 `docker-desktop-data`),你无需手动安装 Ubuntu,也不需要关心 WSL2 的细节。
### 2.2 验证安装
打开 **PowerShell****命令提示符**,执行:
```powershell
# 检查 Docker 版本
docker --version
# 输出示例:Docker version 28.0.1, build ...
# 检查 Docker Compose 版本(已内置)
docker compose version
# 运行测试容器
docker run --rm hello-world
```
看到 `Hello from Docker!` 就说明安装成功了。
### 2.3 日常使用
Docker Desktop 开机后会自动在后台运行。使用时直接在 PowerShell 或终端中敲 `docker` 命令即可,和 Linux 下的体验完全一致。
小技巧:右键点击系统托盘的鲸鱼图标,可以快速打开 Dashboard 图形化管理界面,查看所有容器、镜像、数据卷的状态。
---
## 3. 场景二:云服务器上安装 Docker
拥有一台云服务器是学习 Docker 的理想方式——它能 24 小时运行,你可以部署自己的服务并随时随地访问。
### 3.1 选购云服务器
以笔者的**阿里云 ECS** 为例:
| 项目 | 配置 |
|------|------|
| **实例规格** | 2 vCPU / 2 GiB 内存 |
| **操作系统** | Ubuntu 22.04 LTS64 位) |
| **系统盘** | 40 GiB ESSD |
| **公网 IP** | 101.133.128.193 |
| **带宽** | 按量计费 |
> **学生党建议**:阿里云有学生优惠,一年几十块钱就能买到基础配置的 ECS,足够学习使用。
购买时注意:
- 操作系统选 **Ubuntu 22.04****Ubuntu 24.04**,生态最好
- 安全组(防火墙)默认只开放 22(SSH)端口,后续根据需要手动开放其他端口
- 创建时选择密钥对登录,比密码更安全
### 3.2 登录服务器
```bash
# 使用 SSH 连接(替换 IP 为你的服务器 IP)
ssh root@你的服务器IP
# 如果使用密钥
ssh -i ~/.ssh/你的密钥 root@你的服务器IP
```
> 笔者的习惯:创建一个普通用户 `admin` 来管理,避免直接使用 `root`。并配置 `~/.ssh/authorized_keys` 实现免密登录。
### 3.3 安装 Docker(与 Ubuntu 下完全一致)
登录服务器后,执行的安装命令和 Linux 下完全一致。由于阿里云的 Ubuntu 是标准的 Linux 系统,安装步骤与上面 Windows 无关——下面是完整的安装命令:
```bash
# 安装 Docker Engine(适用于 Ubuntu
sudo apt update
sudo apt install -y ca-certificates curl gnupg lsb-release
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 将当前用户加入 docker 组
sudo usermod -aG docker $USER
newgrp docker
```
### 3.4 云服务器的额外配置
服务器重启后 Docker **会自动随系统启动**(通过 systemd 管理),无需额外配置。
但需要配置**安全组(防火墙)**,否则外部无法访问你的服务:
1. 登录阿里云控制台 → ECS → 安全组
2. 添加规则,例如:
| 方向 | 端口 | 协议 | 用途 |
|------|------|------|------|
| 入方向 | 80 | TCP | HTTP |
| 入方向 | 443 | TCP | HTTPS |
| 入方向 | 8080 | TCP | 测试应用 |
| 入方向 | 3000 | TCP | Node.js 开发 |
> ⚠️ 不要开放 22SSH)的源 IP 为 `0.0.0.0/0`,建议仅允许你的 IP。数据库端口(如 3306、5432)也不要对公网开放。
---
## 4. Docker 基本使用
安装完成后,我们来上手几个最核心的命令。
### 4.1 运行你的第一个容器
```bash
# 运行 Nginx 网页服务器
docker run -d --name my-nginx -p 8080:80 nginx:latest
```
参数说明:
- `-d`:后台运行
- `--name my-nginx`:给容器取名
- `-p 8080:80`:把宿主机的 8080 端口映射到容器的 80 端口
- `nginx:latest`:使用的镜像名和标签
现在打开浏览器,访问:
- 本地:`http://localhost:8080`
- 云服务器:`http://你的服务器IP:8080`
你应该能看到 Nginx 的欢迎页面。
### 4.2 常用命令速查
```bash
# ========== 容器管理 ==========
# 查看运行中的容器
docker ps
# 查看所有容器(包括已停止的)
docker ps -a
# 停止容器
docker stop 容器名
# 启动已停止的容器
docker start 容器名
# 重启容器
docker restart 容器名
# 删除容器(需先停止)
docker rm 容器名
# 强制删除运行中的容器
docker rm -f 容器名
# 进入容器内部
docker exec -it 容器名 bash
# 查看容器日志(-f 实时跟踪)
docker logs -f 容器名
# ========== 镜像管理 ==========
# 搜索镜像
docker search nginx
# 拉取镜像
docker pull 镜像名:标签
# 查看本地镜像
docker images
# 删除镜像
docker rmi 镜像名
# ========== 清理 ==========
# 清理停止的容器、未使用的镜像和网络
docker system prune -a
```
### 4.3 快速搭建一个数据库
这是学习 Docker 最实用的场景——一行命令起一个数据库:
```bash
# PostgreSQL
docker run -d \
--name my-postgres \
-e POSTGRES_USER=admin \
-e POSTGRES_PASSWORD=your_password \
-e POSTGRES_DB=mydb \
-p 5432:5432 \
-v pgdata:/var/lib/postgresql/data \
postgres:16-bookworm
# MySQL
docker run -d \
--name my-mysql \
-e MYSQL_ROOT_PASSWORD=your_password \
-e MYSQL_DATABASE=mydb \
-p 3306:3306 \
-v mysqldata:/var/lib/mysql \
mysql:8.0
# Redis
docker run -d \
--name my-redis \
-p 6379:6379 \
-v redisdata:/data \
redis:7-alpine
```
关键参数:
- `-e`:设置环境变量(数据库密码等)
- `-v 卷名:容器内路径`:持久化数据,容器删除后数据不丢失
- `postgres:16-bookworm`:镜像名:标签,指定具体版本避免意外升级
---
## 5. 图形化管理 Docker
命令行功能强大,但对于初学者,图形化界面更直观。这里介绍两种方式——Windows 上的 Docker Desktop Dashboard,和云服务器上的 1Panel。
### 5.1 Docker Desktop DashboardWindows 本地)
Docker Desktop 自带了一个图形化管理界面,无需额外安装:
- **打开方式**:右键系统托盘的鲸鱼图标 → 点击 **Dashboard**
- **功能**
- **Containers(容器)**:查看所有容器状态、启停、删除、查看日志、进入终端,全部鼠标点击完成
- **Images(镜像)**:浏览本地镜像、拉取新镜像、删除无用镜像
- **Volumes(数据卷)**:查看和管理持久化数据
- **搜索**:内置 Docker Hub 搜索,找到镜像一键 Pull
对于日常的启停、看日志、删容器等操作,Dashboard 比敲命令方便得多。
### 5.2 1Panel —— 云服务器上的"应用商店"式管理
在云服务器上,没有图形界面可用。但借助 **1Panel** 这类 Linux 服务器管理面板,你可以通过浏览器像操作手机 App 一样管理 Docker。
1Panel 是一个开源的 Linux 服务器运维面板,内置了 Docker 可视化管理功能。笔者的阿里云服务器就在使用它。
**安装 1Panel**(一条命令完成):
```bash
# SSH 登录云服务器后执行
curl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start.sh && bash quick_start.sh
```
安装完成后会显示:
```
===============================
1Panel 安装成功!
面板地址: http://你的IP:端口/
用户名: xxxxxx
密码: xxxxxx
===============================
```
> 安装前确保安全组已开放 1Panel 的访问端口(默认是随机端口,安装完成后会显示)。
**用 1Panel 管理 Docker**
登录 1Panel 后,进入 **容器** 菜单:
| 功能 | 说明 |
|------|------|
| **应用商店** | 一键安装 MySQL、Redis、Nginx、WordPress 等 100+ 应用,填写表单即可部署 |
| **容器管理** | 查看启停状态、资源占用、日志、终端,与 Docker Desktop 体验一致 |
| **Compose 模板** | 粘贴 `docker-compose.yaml` 内容,点击部署,无需敲命令 |
| **镜像管理** | 搜索、拉取、删除镜像,支持配置镜像加速 |
| **网络/数据卷** | 可视化创建和管理网络与数据卷 |
**以安装 MySQL 为例**
1. 左侧菜单 → **应用商店**
2. 搜索 "MySQL",点击 **安装**
3. 填写:数据库名、密码、端口(可保持默认 3306),勾选"端口外部访问"
4. 点击 **确认**,等待十几秒即可完成
相比前面 4.3 节一长串的命令行参数,在 1Panel 里填几个表单框就搞定了。
> 笔者的 1Panel 实际配置:面板端口 `21471`,通过 Nginx 反向代理绑定域名,日常管理非常方便。
---
## 6. 下一步学什么?
当你已经能用 `docker run` 熟练启动单个容器后,下一步自然的学习路径:
1. **Docker Compose** —— 用 YAML 文件管理多容器应用,一条命令启动整个项目
2. **Dockerfile** —— 自己编写镜像构建文件,把项目打包成镜像
3. **数据持久化** —— 深入理解 Volume 和 Bind Mount
4. **网络配置** —— 容器间通信、自定义网络
可以参考同一目录下的 [Docker 部署完全指南](./Docker部署完全指南.md) 深入学习后续内容。
---
## 附录:安装问题排查
### 问题一:`docker` 命令提示 "The command 'docker' was not found"
**原因**Docker Desktop 未正确安装或未启动。
**解决**
- 检查系统托盘中 Docker 图标是否存在;如果没有,从开始菜单手动启动 Docker Desktop
- 等待鲸鱼图标停止动画后重试
### 问题二:Docker Desktop 启动后一直转圈(Starting...
**原因**WSL2 未正确安装或版本过旧。
**解决**
```powershell
# 以管理员身份打开 PowerShell
wsl --update
wsl --set-default-version 2
# 重启 Docker Desktop
```
### 问题三:云服务器上访问服务端口失败
**原因**:安全组(防火墙)未开放对应端口。
**解决**:登录云服务器控制台,在安全组中添加入方向规则,开放对应端口。
### 问题四:拉取镜像速度慢
**原因**:Docker Hub 在国内访问较慢。
**解决**:配置国内镜像源。
**云服务器(Linux**
```bash
sudo tee /etc/docker/daemon.json <<'EOF'
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.1panel.live"
]
}
EOF
sudo systemctl restart docker
```
**Docker DesktopWindows**
打开 Docker Desktop → 右上角齿轮(Settings)→ Docker Engine,将上面的 `registry-mirrors` 配置合并到现有 JSON 中,点击 "Apply & Restart"。
---
*本文由河南理工大学人工智能协会整理*
*2026年5月*
@@ -401,13 +401,13 @@ Git是分布式版本控制系统,这意味着每个开发者的电脑上都
**本地仓库 vs 远程仓库**
| 特性 | 本地仓库 | 远程仓库 |
|------|---------|---------|
| **位置** | 你的电脑 | 服务器(GitHub/Gitee等) |
| **用途** | 日常开发和提交 | 团队共享和备份 |
| **操作** | `git commit` | `git push/pull` |
| **网络要求** | 无需网络 | 需要网络连接 |
| **所有权** | 完全可控 | 团队共享 |
| 特性 | 本地仓库 | 远程仓库 |
| -------- | ------------ | ------------------ |
| **位置** | 你的电脑 | 服务器(GitHub/Gitee等) |
| **用途** | 日常开发和提交 | 团队共享和备份 |
| **操作** | `git commit` | `git push/pull` |
| **网络要求** | 无需网络 | 需要网络连接 |
| **所有权** | 完全可控 | 团队共享 |
**常见的远程仓库服务**