Private
Public Access
1
0

新增:文档体系重构+CHANGELOG补充+发布产物清理

This commit is contained in:
2026-05-01 22:22:06 +08:00
parent 3e1a540b83
commit 6eaaa56eb6
164 changed files with 40346 additions and 64 deletions

View File

@@ -50,7 +50,7 @@ npm install
npm run build
```
这会生成 `web/dist` 目录,包含前端构建产物。
这会生成 `frontend/dist` 目录,包含前端构建产物。
### 4. 开发模式运行
@@ -79,7 +79,7 @@ wails dev
## 常见问题
### 问题1找不到 web/dist 目录
### 问题1找不到 frontend/dist 目录
**解决**:需要先构建前端
```bash

View File

@@ -38,7 +38,7 @@ go-desk/
├── wails.json # Wails 配置文件
├── go.mod # Go 模块依赖
├── go.sum # Go 依赖校验
├── web/ # 前端代码目录
├── frontend/ # 前端代码目录
│ ├── package.json # 前端依赖配置
│ ├── package-lock.json # 依赖锁定文件
│ ├── vite.config.js # Vite 构建配置
@@ -62,8 +62,8 @@ go-desk/
**目录说明:**
- `app.go`: 定义应用结构体和方法,供前端调用
- `main.go`: 程序入口,配置窗口、资源等
- `web/`: 前端 Vue 项目,使用 Vite 构建
- `web/dist/`: 前端构建产物,会被嵌入到 Go 二进制文件
- `frontend/`: 前端 Vue 项目,使用 Vite 构建
- `frontend/dist/`: 前端构建产物,会被嵌入到 Go 二进制文件
- `build/`: 应用图标等构建资源
## 配置调整
@@ -87,7 +87,7 @@ cd web
npm install --save @arco-design/web-vue
```
### 3. 修改 `web/src/main.js`
### 3. 修改 `frontend/src/main.js`
```javascript
import { createApp } from 'vue'
@@ -101,7 +101,7 @@ app.use(ArcoVue)
app.mount('#app')
```
### 4. 修改 `web/src/App.vue`
### 4. 修改 `frontend/src/App.vue`
```vue
<template>
@@ -217,7 +217,7 @@ import (
"github.com/wailsapp/wails/v2/pkg/options/assetserver"
)
//go:embed all:web/dist
//go:embed all:frontend/dist
var assets embed.FS
func main() {
@@ -280,7 +280,7 @@ wails build -platform linux/amd64
## 注意事项
1. **前端构建**:每次修改前端代码后需要重新构建 `npm run build`Wails 会使用 `web/dist` 目录
1. **前端构建**:每次修改前端代码后需要重新构建 `npm run build`Wails 会使用 `frontend/dist` 目录
2. **Go 方法暴露**:在 `app.go` 中定义的方法会自动暴露给前端,通过 `window.go.main.MethodName` 调用
3. **热重载**开发模式下Go 代码修改需要重启 `wails dev`,前端代码修改需要重新构建
4. **资源嵌入**:使用 `//go:embed` 将前端构建产物嵌入到 Go 二进制文件中

View File

@@ -252,7 +252,7 @@ go-desk/
│ └── filesystem/
│ └── fs.go # 文件系统操作
├── app.go # 添加系统调用方法
└── web/src/
└── frontend/src/
└── components/
├── SystemInfo.vue # 系统信息组件
└── FileSystem.vue # 文件系统组件

View File

@@ -37,7 +37,7 @@
### 6. 前端错误处理可能不够完善 ⚠️
**位置**`go-desk/web/src/views/db-cli/composables/useSqlExecution.ts`
**位置**`go-desk/frontend/src/views/db-cli/composables/useSqlExecution.ts`
**问题**:错误处理中使用了 `error.toString()`,可能在某些情况下无法正确显示错误信息。

View File

@@ -352,7 +352,7 @@ func (a *App) GetIndexes(connectionId uint, database, tableName string) ([]map[s
### 2. 前端实现Vue
#### 表结构展示组件
**文件**: `go-desk/web/src/views/db-cli/components/TableStructure.vue`
**文件**: `go-desk/frontend/src/views/db-cli/components/TableStructure.vue`
```vue
<template>
@@ -589,7 +589,7 @@ onMounted(() => {
```
#### 集成到主页面
**文件**: `go-desk/web/src/views/db-cli/index.vue`
**文件**: `go-desk/frontend/src/views/db-cli/index.vue`
```vue
<!-- 表结构对话框 -->

View File

@@ -24,7 +24,7 @@
### 2.1 核心实现 ✅
#### useStructureEdit.ts ✅
- **位置**`go-desk/web/src/views/db-cli/composables/useStructureEdit.ts`
- **位置**`go-desk/frontend/src/views/db-cli/composables/useStructureEdit.ts`
- **功能**
- ✅ 编辑模式状态管理
- ✅ 编辑数据管理(字段、索引)
@@ -33,7 +33,7 @@
- ✅ 字段/索引操作方法
#### ResultPanel.vue ✅
- **位置**`go-desk/web/src/views/db-cli/components/ResultPanel.vue`
- **位置**`go-desk/frontend/src/views/db-cli/components/ResultPanel.vue`
- **功能**
- ✅ 添加结构操作栏
- ✅ 模式切换按钮
@@ -41,7 +41,7 @@
- ✅ 根据模式显示不同按钮
#### index.vue ✅
- **位置**`go-desk/web/src/views/db-cli/index.vue`
- **位置**`go-desk/frontend/src/views/db-cli/index.vue`
- **功能**
- ✅ 集成 useStructureEdit
- ✅ 传递 editMode 到 ResultPanel

View File

@@ -47,7 +47,7 @@
**行动步骤**
1. **创建ContextMenu组件**
- 位置:`go-desk/web/src/views/db-cli/components/ContextMenu.vue`
- 位置:`go-desk/frontend/src/views/db-cli/components/ContextMenu.vue`
- 使用Arco Design Dropdown或自定义实现
- 实现菜单定位、显示、隐藏逻辑

View File

@@ -273,5 +273,5 @@ components/
## 十、相关文档
- [前端布局样式系统设计.md](../需求设计/前端布局样式系统设计.md)
- [ConnectionTree.vue](../../../../go-desk/web/src/views/db-cli/components/ConnectionTree.vue)
- [ConnectionTree.vue](../../../../go-desk/frontend/src/views/db-cli/components/ConnectionTree.vue)

View File

@@ -4,7 +4,7 @@
**文档版本**v2.0
**维护者**JueChen
**更新日期**2026-01-28
**源码路径**`go-desk/web/src/views/db-cli/`
**源码路径**`go-desk/frontend/src/views/db-cli/`
---

View File

@@ -984,7 +984,7 @@ const handleEditorResultDividerMouseDown = (e: MouseEvent) => {
### 8.5 滚动条处理
#### 全局滚动条样式
系统使用统一的滚动条样式(定义在 `web/src/style.css`
系统使用统一的滚动条样式(定义在 `frontend/src/style.css`
```css
/* Webkit浏览器 (Chrome, Safari, Edge) */

View File

@@ -0,0 +1,69 @@
# Git 集成方案
> 调研日期2026-04-11
> 状态:已调研,待实现
## 1. 判定 Git 仓库
从目标路径逐级向上查找 `.git` 目录:
```bash
git -C <path> rev-parse --is-inside-work-tree
# 返回 "true" = 是 git 仓库
```
Go 实现:`filepath.Walk` 向上遍历,检查 `.git` 目录存在性。
## 2. 可实现功能
| 功能 | 难度 | 命令 |
|------|------|------|
| 文件状态(修改/新增/删除/未跟踪) | 低 | `git status --porcelain=v1 <file>` |
| 文件/文件夹提交历史 | 低 | `git log --oneline -20 -- <path>` |
| 当前文件与 HEAD 的 diff | 中 | `git diff HEAD -- <file>` |
| 某行代码 blame | 低 | `git blame <file>` |
| 当前分支名 | 低 | `git branch --show-current` |
## 3. 实现架构
### Go 后端(~200 行)
```
internal/git/
├── git.go # 核心逻辑:判定仓库、执行命令、解析输出
├── status.go # 文件状态查询
├── history.go # 提交历史
├── diff.go # 文件差异
└── blame.go # 行级追溯
```
关键接口设计:
- `IsGitRepo(path string) bool` — 判定是否为 git 仓库
- `GetFileStatus(path string) (string, error)` — 返回 M/A/D/? 状态码
- `GetFileHistory(path string, limit int) ([]Commit, error)` — 提交历史
- `GetFileDiff(path string) (string, error)` — diff 文本
- `BlameFile(path string) ([]BlameLine, error)` — blame 结果
### 前端(~100 行)
- **文件列表**:图标列增加 git 状态小标记M=修改, A=新增, D=删除, ?=未跟踪)
- **右键菜单**git 仓库内显示「查看历史」「查看 Diff」「Blame」等选项
- **弹窗组件**:提交历史列表 / Diff 查看 / Blame 视图
### 调用方式
Go 侧通过 `os/exec.Command("git", "-C", repoPath, ...)` 执行系统 git 命令,
解析 stdout 返回结构化数据给前端。
## 4. 前提条件
- 系统需安装 GitWindows 上基本都有)
- 仅在有 `.git` 的目录下激活相关功能
- 大文件/二进制文件不做 diff/blame
## 5. 注意事项
- `git -C <path>` 确保 git 命令在正确仓库上下文执行
- `--porcelain=v1` 输出格式稳定,适合程序解析
- 中文路径需注意编码UTF-8
- 性能:避免频繁调用 git 命令,考虑缓存结果

View File

@@ -0,0 +1,320 @@
# 文件操作增强:多选 / 复制粘贴剪切 / 移动
> 状态:方案设计完成,待实施
> 日期2026-04-12
## 一、现状
| 功能 | 前端 | 后端 | 状态 |
|------|------|------|------|
| **多选** (Ctrl+Click / Shift+Click) | 无,单选 `selectedFileItem: FileItem \| null` | N/A | **缺失** |
| **全选** (Ctrl+A) | 无 | N/A | **缺失** |
| **复制文件** (Ctrl+C) | TODO stub弹"暂未实现" | 无 API | **缺失** |
| **剪切文件** (Ctrl+X) | 无 | 无 API | **缺失** |
| **粘贴文件** (Ctrl+V) | 仅支持图片粘贴 | 无 API | **部分** |
| **移动文件** | TODO stub弹"暂未实现" | 无 API | **缺失** |
| **重命名** (F2) | 完整 | 完整 | 已完成 |
| **删除** (Del) | 完整(含回收站) | 完整 | 已完成 |
| **右键菜单 Copy/Cut/Paste** | 无菜单项 | N/A | 缺失 |
### 关键发现
1. `useFileOperations.ts``copy()``move()` 已有函数签名但都是 TODO stub
2. 回收站模块 (`recycle_bin.go`) 内部有 `copyRecursively`/`copyFile`/`copyDirectory` 私有方法可复用
3. 快捷键已有 F5/F2/Del/Ctrl+S 等 12 个,缺 Ctrl+C/V/X/A 四个
4. 右键菜单只有:新建文件、新建文件夹、系统打开、重命名、删除 — 缺复制/剪切/粘贴/移动
## 二、方案架构
```
┌─────────────────────────────────────────────┐
│ 前端 (Vue 3) │
│ │
│ 1. 多选状态管理 (selectedFiles: FileItem[]) │
│ 2. 剪贴板状态 (clipboard: {op, files[]}) │
│ 3. FileListPanel: Ctrl+Click / Shift+Click │
│ 4. ContextMenu: +Copy / Cut / Paste 项 │
│ 5. 快捷键: Ctrl+C / V / X / A │
└──────────────────┬──────────────────────────┘
│ window.go.main.App.*
┌──────────────────▼──────────────────────────┐
│ 后端 (Go) │
│ │
│ 6. App.CopyPath(src, dst) → FileSystemService │
│ 7. App.MovePath(src, dst) → os.Rename │
│ 8. 复用 recycle_bin.go 的 copy 辅助函数 │
└─────────────────────────────────────────────┘
```
## 三、实施步骤
### Step 1后端 — 新增 Copy / Move API
**文件**: `internal/filesystem/service.go`
新增两个公开方法(复用已有的私有 copy 函数):
```go
// CopyPath 复制文件或目录
func (s *FileSystemService) CopyPath(src, dst string) error {
return copyRecursively(src, dst)
}
// MovePath 移动文件或目录(跨盘需 copy+delete
func (s *FileSystemService) MovePath(src, dst string) error {
// 同盘: os.Rename (原子操作)
// 跨盘: copyRecursively + DeletePathWithContext
}
```
**文件**: `app.go`
新增两个绑定方法 + 请求结构体:
```go
type CopyMoveRequest struct {
Src string `json:"src"`
Dst string `json:"dst"`
}
func (a *App) CopyPath(req CopyMoveRequest) error {
return a.filesystem.CopyPath(req.Src, req.Dst)
}
func (a *App) MovePath(req CopyMoveRequest) error {
return a.filesystem.MovePath(req.Src, req.Dst)
}
```
**文件**: `frontend/src/api/system.ts`
```ts
export async function copyPath(src: string, dst: string): Promise<void>
export async function movePath(src: string, dst: string): Promise<void>
```
### Step 2前端 — 多选状态管理
**文件**: `frontend/src/components/FileSystem/index.vue`
核心改动:`selectedFileItem: FileItem | null``selectedFiles: FileItem[]`
```ts
// 改前
const selectedFileItem = ref<FileItem | null>(null)
// 改后
const selectedFiles = ref<FileItem[]>([])
const selectedFileItem = computed(() => selectedFiles.value[0] || null) // 兼容现有单选逻辑
```
**文件**: `frontend/src/types/file-system.ts`
`FileListPanelConfig.selectedFileItem` 类型改为 `selectedFiles: FileItem[]`
**文件**: `frontend/src/components/FileSystem/components/FileListPanel.vue`
改造行点击支持多选:
```ts
const handleRowClick = (record: FileItem, ev: MouseEvent) => {
if (target.closest('.arco-btn') || target.closest('.arco-input-wrapper')) return
if (ev.ctrlKey || ev.metaKey) {
emit('toggleSelect', record) // Ctrl+Click: 切换选中
} else if (ev.shiftKey && props.selectedFiles.length > 0) {
emit('rangeSelect', record) // Shift+Click: 范围选择
} else {
emit('fileClick', record) // 普通点击: 单选
}
}
```
`getRowClassName` 改为匹配数组:
```ts
const getRowClassName = (record: FileItem): string => [
props.selectedFiles.some(f => f.path === record.path) && 'row-selected',
props.config.editingFilePath === record.path && 'row-editing'
].filter(Boolean).join(' ')
```
Props 变更:
```ts
// 改前
selectedFileItem: FileItem | null
// 改后
selectedFiles: FileItem[]
```
新增 Emits:
```ts
(e: 'toggleSelect', file: FileItem): void
(e: 'rangeSelect', file: FileItem): void
```
### Step 3前端 — 剪贴板状态(应用级)
**新建文件**: `frontend/src/components/FileSystem/composables/useClipboard.ts`
```ts
type ClipboardOp = 'copy' | 'cut'
interface ClipboardState {
op: ClipboardOp | null
files: FileItem[] // 源文件列表
sourceDir: string // 来源目录
}
const clipboard = reactive<ClipboardState>({
op: null, files: [], sourceDir: '',
})
export function useClipboard() {
const copy = (files: FileItem[]) => { /* ... */ }
const cut = (files: FileItem[]) => { /* ... */ }
const clear = () => { clipboard.op = null; clipboard.files = [] }
const canPaste = computed(() => clipboard.op !== null && clipboard.files.length > 0)
return { clipboard, copy, cut, clear, canPaste }
}
```
### Step 4前端 — 右键菜单扩展
**文件**: `frontend/src/components/FileSystem/components/ContextMenu.vue`
文件菜单追加 Copy / Cut
```vue
<div class="context-menu-item" @click="handleCopy">
<span>📋</span><span>复制</span><span class="shortcut">Ctrl+C</span>
</div>
<div class="context-menu-item" @click="handleCut">
<span></span><span>剪切</span><span class="shortcut">Ctrl+X</span>
</div>
<div class="context-menu-divider"></div>
<!-- 现有重命名/删除保持不变 -->
```
空白区域菜单追加 Paste
```vue
<div class="context-menu-divider"></div>
<div class="context-menu-item" :disabled="!canPaste" @click="handlePaste">
<span>📌</span><span>粘贴</span><span class="shortcut">Ctrl+V</span>
</div>
```
新增 Props: `selectedCount?: number`, `canPaste?: boolean`
新增 Emits: `'action': 'copy' | 'cut' | 'paste'`
### Step 5前端 — 快捷键扩展
**文件**: `frontend/src/components/FileSystem/index.vue``handleKeyDown`
在 Delete 处理之后追加:
```ts
// Ctrl+C 复制
if ((event.ctrlKey || event.metaKey) && event.key === 'c' && selectedFiles.value.length > 0) {
event.preventDefault(); handleCopy(); return
}
// Ctrl+X 剪切
if ((event.ctrlKey || event.metaKey) && event.key === 'x' && selectedFiles.value.length > 0) {
event.preventDefault(); handleCut(); return
}
// Ctrl+V 粘贴
if ((event.ctrlKey || event.metaKey) && event.key === 'v') {
event.preventDefault(); await handlePaste(); return
}
// Ctrl+A 全选
if ((event.ctrlKey || event.metaKey) && event.key === 'a') {
event.preventDefault()
selectedFiles.value = [...fileList.value]
return
}
```
### Step 6前端 — 操作执行逻辑
**文件**: `frontend/src/components/FileSystem/composables/useFileOperations.ts`
实现 `copy()``move()`(替换 TODO stub
```ts
const copy = async (fromPath: string, toPath: string): Promise<void> => {
await copyPathApi(fromPath, toPath)
Message.success('复制完成')
}
const move = async (fromPath: string, toPath: string): Promise<void> => {
await movePathApi(fromPath, toPath)
Message.success('移动完成')
}
```
**文件**: `frontend/src/components/FileSystem/index.vue`
核心处理函数:
```ts
const { clipboard, copy: clipCopy, cut: clipCut, canPaste } = useClipboard()
const handleCopy = () => {
clipCopy(selectedFiles.value)
Message.info(`已复制 ${selectedFiles.value.length}`)
}
const handleCut = () => {
clipCut(selectedFiles.value)
Message.info(`已剪切 ${selectedFiles.value.length}`)
}
const handlePaste = async () => {
for (const file of clipboard.files) {
const dst = filePath.value + '/' + file.name
clipboard.op === 'cut'
? await fileOps.move(file.path, dst)
: await fileOps.copy(file.path, dst)
}
if (clipboard.op === 'cut') clipClear()
loadDirectory(filePath.value)
}
const handleToggleSelect = (file: FileItem) => { /* 切换单项 */ }
const handleRangeSelect = (file: FileItem) => { /* 范围选择 */ }
// handleContextMenuAction 扩展
case 'copy': handleCopy(); break
case 'cut': handleCut(); break
case 'paste': await handlePaste(); break
```
## 四、改动文件清单
| 文件 | 改动类型 | 说明 |
|------|---------|------|
| `internal/filesystem/service.go` | 修改 | 新增 `CopyPath()``MovePath()` |
| `app.go` | 修改 | 新增绑定方法 + `CopyMoveRequest` 结构体 |
| `frontend/src/api/system.ts` | 修改 | 新增 `copyPath()``movePath()` |
| `frontend/src/types/file-system.ts` | 修改 | `selectedFileItem``selectedFiles` 数组 |
| `frontend/src/components/FileSystem/composables/useClipboard.ts` | **新建** | 剪贴板 composable |
| `frontend/src/components/FileSystem/composables/useFileOperations.ts` | 修改 | 实现 copy/move TODO |
| `frontend/src/components/FileSystem/components/FileListPanel.vue` | 修改 | 多选行点击 + 行样式 |
| `frontend/src/components/FileSystem/components/ContextMenu.vue` | 修改 | 追加 Copy/Cut/Paste 菜单项 |
| `frontend/src/components/FileSystem/index.vue` | 修改 | 多选状态 + 快捷键 + 操作函数 |
**9 个文件**1 个新建 + 8 个修改)
## 五、验证标准
1. **Ctrl+Click** 切换单文件选中状态,高亮多行
2. **Shift+Click** 选中范围文件
3. **Ctrl+A** 全选当前目录所有文件
4. **Ctrl+C** 复制选中文件 → 提示"N 项已复制"
5. **Ctrl+X** 剪切选中文件 → 提示"N 项已剪切"
6. **Ctrl+V** 在目标目录粘贴 → 文件出现
7. **右键菜单** 显示 Copy / Cut / Paste空白区
8. **跨目录粘贴** 正确复制到目标路径
9. **剪切粘贴** 源文件消失(移动效果)
10. **大文件夹** 复制不卡顿Go io.Copy 流式)
## 六、不做(明确边界)
- **拖拽移动文件** — 本轮不做,后续可加
- **外部文件粘贴** — 不支持从系统资源管理器粘贴到 u-deskWails 限制)
- **进度条** — 大文件复制暂不加进度条
- **撤销(Ctrl+Z)** — 仅保留编辑器内容重置,不做操作历史撤销

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,126 @@
# GO-DESK-8: Wails v3 迁移变更分析
> 范围: `44847e0`(v0.4.0) → `f54bf1c`(fs-only-v3) | 提交数: 1 | 日期: 2026-05-01
## 变更总览
| 类别 | 数量 | 说明 |
|------|------|------|
| 重命名 | 77 | web/ → frontend/git rename历史保留 |
| 新增 | 94 | v3 构建模板 + bindings + 新文件 |
| 删除 | 4 | 旧文件clipboard png、md5、v2 transport/types |
| 修改 | 10 | 核心代码适配 v3 API |
| **合计** | **185** | **+7,772 / -918 行** |
---
## 一、框架升级(核心)
### Wails v2 → v3 API 映射
| v2 (旧) | v3 (新) | 文件 |
|---------|---------|------|
| `wails.Run(&options.App{...})` | `application.New()` + `Window.NewWithOptions()` | main.go |
| `options.App.Bind: []interface{}{app}` | `Services: []application.Service{application.NewService(app)}` | main.go |
| `AssetServer: &assetserver.Options{}` | `Assets: application.AssetOptions{Handler, Middleware}` | main.go |
| `app.Startup(ctx)` / `app.Shutdown(ctx)` | `app.ServiceStartup(ctx, opts)` / `app.ServiceShutdown()` | app.go |
| `runtime.Window(ctx)` | `a.mainWindow`(手动注入) | app.go |
| `runtime.*` 函数调用 | `window.*` 方法 + v3-bindings 自动生成 | 前端 |
| `//go:embed all:web/dist` | `//go:embed all:frontend/dist` | main.go |
### main.go 实质性变更
- **Middleware 中间件**: 拦截 `/wails/custom.js` 返回空 200消除控制台 404
- **DevTools**: 延迟 2s 调用 `window.OpenDevTools()`production + devtools build tag
- **窗口主题**: Windows CustomTheme 配置亮/暗模式标题栏颜色
### app.go 实质性变更
- **新增** `SetMainWindow()` — v3 需要手动注入窗口引用
- **新增** `SetWindowTitleBarColor()` — v3 窗口主题色动态切换
- **新增** `sync.Mutex` — 并发安全保护 mainWindow
- **生命周期**: `Startup/Shutdown``ServiceStartup/ServiceShutdown`(返回 error
- **错误处理**: panic → return error符合 Go 惯例)
---
## 二、前端代码修改(有业务逻辑变化的)
### App.vue (+375/-60 行)
- Tabs padding-top 覆盖Arco Design 默认 16px → 0
- import 路径更新:`@/wailsjs/v3-bindings/u-desk/app`
- 窗口控制方法改用 v3 binding 导入
### Sidebar.vue (+406 行)
- **新架构**: 双区块折叠(收藏夹 + 帮助文档),各自独立 header + content
- **滚动优化**: `.sidebar overflow:hidden` + 收藏内容区 `overflow-y:auto` 内部滚动
- **帮助区块**: 固定底部 `flex-shrink:0`,默认展开
- 折叠动画: max-height + opacity CSS transition
### useFavorites.ts (+259 行)
- **修复**: `longPressTimer` const → let解决 Assignment to constant variable TypeError
### stores/ (config/theme/update)
- **config.ts**: Wails v3 绑定加载方式调整
- **theme.ts**: 窗口主题色通过 v3 API 设置
- **update.ts**: 更新检查逻辑适配 v3 事件系统
### wails-transport.ts (+121 行)
- **全新**: v3 transport 层实现(替代 v2 的 runtime 调用)
### UpdateNotification.vue / UpdatePanel.vue
- 事件监听从 v2 runtime 改为 v3 OffAll/events 模式
---
## 三、依赖变更
```diff
- github.com/wailsapp/wails/v2 v2.12.0
+ github.com/wailsapp/wails/v3 v3.0.0-alpha.80
- go 1.25.6
+ go 1.26
+ github.com/wailsapp/wails/v3/pkg/w32 # Win32 直接调用
+ dario.cat/mergo v1.0.2 # 结构体合并
```
移除: `go-toast/v2`v3 自带通知)、`gosod`/`slicer`v2 工具库)
---
## 四、新增构建基础设施94 个文件,均为 Wails v3 标准模板)
以下由 `wails3 task generate` 自动生成,无自定义逻辑:
| 目录 | 用途 |
|------|------|
| `build/config.yml` | 项目配置dev mode executes 流水线) |
| `Taskfile.yml` | 根级任务定义dev/build/run |
| `build/android/` | Android 构建模板Gradle + Java Bridge |
| `build/darwin/` | macOS 构建Info.plist + Icons |
| `build/ios/` | iOS 构建Xcode project |
| `build/linux/` | Linux 构建AppImage + nfpm |
| `build/docker/` | Docker 交叉编译 |
| `build/windows/nsis/` | NSIS 安装包脚本 |
| `build/windows/msix/` | MSIX 打包配置 |
| `frontend/src/wailsjs/v3-bindings/` | v3 TypeScript 绑定(自动生成) |
| `frontend/bindings/` | v3 绑定副本(备用路径) |
---
## 五、删除项4 个文件)
| 文件 | 原因 |
|------|------|
| `cmd/agent/clipboard_*.png` | 截图残留,已归档到 `.archive/` |
| `web/package.json.md5` | 旧完整性校验文件 |
| `web/src/api/wails-transport.ts` | v2 版本,已被 frontend 下新版替代 |
| `web/src/types/window.d.ts` | v2 类型声明,已被 frontend 下新版替代 |
---
## 六、风险点
1. **alpha.80 稳定性**: Wails v3 仍为 alpha部分 API 可能后续 breaking change
2. **OpenDevTools sleep hack**: 2s 硬编码延迟不够可靠,待 OnDomReady 稳定后替换
3. **v2 bindings 残留**: `frontend/src/wailsjs/wailsjs/`v2仍随重命名保留在 frontend/ 下,如不再使用应清理