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:
@@ -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日
|
||||
@@ -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.js:v22.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
|
||||
```
|
||||
@@ -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] 图片上传测试通过
|
||||
@@ -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 支持识别以下格式的图片引用:
|
||||
- `` - 普通 Markdown 图片语法
|
||||
- `` - 相对路径
|
||||
- `` - 绝对路径(Vault 根目录)
|
||||
- `` - 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; // 保留原路径
|
||||
}
|
||||
```
|
||||
@@ -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](测试)
|
||||
@@ -1,33 +0,0 @@
|
||||
# Markdown 文件导入功能检查清单
|
||||
|
||||
## 代码实现检查
|
||||
|
||||
- [ ] `src/commands/import-markdown.ts` 文件创建完成
|
||||
- [ ] 文件选择器正确实现(仅显示 .md 文件)
|
||||
- [ ] 文件读取和解析逻辑正确
|
||||
- [ ] 文章创建逻辑正确调用 Halo API
|
||||
- [ ] `src/modals/file-preview-modal.ts` 文件创建完成
|
||||
- [ ] 文件内容预览正确显示
|
||||
- [ ] frontmatter 信息正确显示
|
||||
- [ ] 导入/取消按钮功能正常
|
||||
- [ ] "导入后发布"选项功能正常
|
||||
|
||||
## 集成检查
|
||||
|
||||
- [ ] `src/main.ts` 中命令注册完成
|
||||
- [ ] 命令名称符合国际化规范
|
||||
- [ ] 命令在命令面板中可见
|
||||
|
||||
## 国际化检查
|
||||
|
||||
- [ ] 英文文案添加完成
|
||||
- [ ] 简体中文文案添加完成
|
||||
- [ ] 繁体中文文案添加完成
|
||||
|
||||
## 测试检查
|
||||
|
||||
- [ ] 编译通过无错误
|
||||
- [ ] 插件文件正确复制到 Obsidian 插件目录
|
||||
- [ ] 文件选择器测试通过
|
||||
- [ ] 导入功能测试通过(创建草稿)
|
||||
- [ ] 导入功能测试通过(导入并发布)
|
||||
@@ -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
|
||||
```
|
||||
|
||||
请求体格式与发布功能相同。
|
||||
@@ -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 插件目录
|
||||
- [ ] 同步状态面板测试通过(需要手动测试)
|
||||
- [ ] 同步历史功能测试通过(需要手动测试)
|
||||
@@ -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. 使用指南文档(用户教育)
|
||||
@@ -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
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 NAS(N100 处理器,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 LTS(64 位) |
|
||||
| **系统盘** | 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 开发 |
|
||||
|
||||
> ⚠️ 不要开放 22(SSH)的源 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 Dashboard(Windows 本地)
|
||||
|
||||
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 Desktop(Windows)**:
|
||||
|
||||
打开 Docker Desktop → 右上角齿轮(Settings)→ Docker Engine,将上面的 `registry-mirrors` 配置合并到现有 JSON 中,点击 "Apply & Restart"。
|
||||
|
||||
---
|
||||
|
||||
*本文由河南理工大学人工智能协会整理*
|
||||
*2026年5月*
|
||||
@@ -402,7 +402,7 @@ Git是分布式版本控制系统,这意味着每个开发者的电脑上都
|
||||
**本地仓库 vs 远程仓库**
|
||||
|
||||
| 特性 | 本地仓库 | 远程仓库 |
|
||||
|------|---------|---------|
|
||||
| -------- | ------------ | ------------------ |
|
||||
| **位置** | 你的电脑 | 服务器(GitHub/Gitee等) |
|
||||
| **用途** | 日常开发和提交 | 团队共享和备份 |
|
||||
| **操作** | `git commit` | `git push/pull` |
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user