Compare commits

...

44 Commits

Author SHA1 Message Date
liumangmang
48f04577dc feat: 更新4月待办任务状态:巡视报告配置异常补充前端修复说明,linx80 excel问题标记为已完成 2026-04-09 11:03:45 +08:00
liumangmang
2b118d7409 feat: 新增4月待办:告警阈值xml导入限制功能 2026-04-03 15:40:15 +08:00
liumangmang
8d824d12cd feat: 标记3月待办#8贵州大唐机器人告警复检需求为已完成 2026-04-03 10:26:32 +08:00
liumangmang
26a6db037a feat: 标记4月待办巡视报告配置异常任务为已完成 2026-04-03 10:11:30 +08:00
liumangmang
26f2215955 feat: 标记3月待办16、21号任务为已完成 2026-04-02 20:33:52 +08:00
liumangmang
e3bf2f6870 feat: 新增4月待办:修复现场linx80 excel打开失败问题 2026-04-02 11:26:31 +08:00
liumangmang
f90e7a6566 feat: 修复所有缺失图标,新增4月待办,更新3月待办内容 2026-04-02 10:06:09 +08:00
liumangmang
19635c9c76 docs: 新增待办任务22-优化服务调用失败异常反馈 2026-03-30 19:41:21 +08:00
liumangmang
3a2af24c94 docs: 调整任务16位置,从已完成移至待启动 2026-03-30 19:26:40 +08:00
liumangmang
9e59e1dbea docs: 完成XFCE终端快捷指令文章 2026-03-30 17:11:36 +08:00
liumangmang
6c7e911364 docs: 添加自定义配置和总结 2026-03-30 17:05:56 +08:00
liumangmang
6ac8a8c824 docs: 添加高级功能类快捷键 2026-03-30 17:04:40 +08:00
liumangmang
b4d9e15a65 docs: 添加显示调整类快捷键 2026-03-30 17:03:29 +08:00
liumangmang
5e88779532 docs: 添加编辑操作类快捷键 2026-03-30 17:02:11 +08:00
liumangmang
4738fb6c84 docs: 添加基础导航类快捷键 2026-03-30 17:01:10 +08:00
liumangmang
4b511285b9 docs: 创建XFCE终端快捷指令文章框架 2026-03-30 16:59:53 +08:00
liumangmang
d685a22b60 docs(work): 更新第20项录像回放权限问题修复为已完成 2026-03-30 15:43:39 +08:00
liumangmang
158270b3b0 docs(work): 更新第12项超期逻辑和红外温度矩阵功能同步为已完成 2026-03-30 11:22:26 +08:00
liumangmang
9b88b06e4c refactor(work): 重构待办事项为按月目录结构并更新3月待办 2026-03-30 11:10:03 +08:00
b5769edf7e docs(frontend-tools): add advanced vscode workflow and config guide 2026-03-30 02:38:04 +08:00
2068733f0d docs(frontend-tools): add vscode quick start for command palette and settings json 2026-03-30 00:41:49 +08:00
liumangmang
9b37932b46 docs(work): 新增删除点位关联阈值告警待办 2026-03-27 15:24:07 +08:00
liumangmang
7959ed9943 docs(work): 新增声纹模型模板必填项待办 2026-03-27 11:22:35 +08:00
liumangmang
cf637d29bb docs(work): 更新待办事项 2026-03-26 18:03:13 +08:00
liumangmang
dc6e69ae00 docs: update docker port and compose version 2026-03-26 17:18:19 +08:00
liumangmang
4967356f22 docs: add docker deploy instructions 2026-03-26 17:10:50 +08:00
liumangmang
1a0c14c683 feat: add make targets for docker deploy 2026-03-26 16:56:48 +08:00
liumangmang
a1bf9e1d4b feat: add compose service for production deploy 2026-03-26 16:53:17 +08:00
liumangmang
7238aa9ca5 feat: add docker build for static site 2026-03-26 16:45:03 +08:00
liumangmang
38a7c7956e docs(work): 更新待办事项状态与新增巡视任务 2026-03-26 14:33:39 +08:00
liumangmang
89f79774ff docs(blog): 新增 Linux 内存优化指南并更新工作区侧边栏 2026-03-20 22:21:28 +08:00
liumangmang
87ace8cbe8 feat(work): 优化待办事项页面清单展示体验 2026-03-20 22:21:28 +08:00
97ea3e4df0 docs(ai): 拆分 Superpowers 模块并添加重定向 2026-03-16 23:08:45 +08:00
daae331fd0 docs(ai): 新增 OpenCode superpowers 文章并更新侧边栏 2026-03-16 22:40:17 +08:00
liumangmang
dfcbc51391 docs(ai): 新增 Claude Code 工作流总结并统一目录结构 2026-03-11 19:53:26 +08:00
liumangmang
e0941914e3 docs(blog): 记录 Caddy 认证并更新内容 2026-03-11 10:26:16 +08:00
a1c824446b docs(openclaw): 完善个人部署实战指南 2026-03-10 01:12:24 +08:00
liumangmang
e765565a70 docs(blog): 按博客风格整理三篇技术文档 2026-03-09 14:09:19 +08:00
d70de00176 feat(docs): 添加AI工具相关文章 2026-03-08 00:57:08 +08:00
liumangmang
8cf81f6055 docs(project-summary): 新增 TCPClientTester 打包与启动工作总结 2026-03-06 17:32:31 +08:00
d0510e0c92 feat(docs): 添加AI工具导航栏及侧边栏内容
- 在导航栏配置中新增AI入口,图标为机器人
- 在侧边栏添加AI相关文档分组OpenCode,包含opencode-cli和opencode-tui
- 添加ChatGPT、OpenClaw、iFlow等AI工具文档链接
- 配置简化主页侧边栏显示,关闭默认侧边栏显示
2026-03-06 03:07:01 +08:00
86c8d8c512 feat(vuepress): 配置vite打包器及本地搜索功能
- 使用 viteBundler 配置 Vite,添加 SCSS 预处理器选项
- 启用主题的本地搜索功能以提升用户体验
- 更新 devDependencies,新增 @vuepress/plugin-search 并升级 sass-embedded 版本
- 优化导航栏样式,调整 .vp-navbar .auto-link 相关 CSS
- 重构 Java SDKMAN 和 Maven 版本管理文档,完善指令说明和操作步骤
- 修改 sidebar 配置,增加根路径禁用侧边栏显示
2026-03-06 02:07:36 +08:00
liumangmang
83dc5bf7c6 docs(project-summary): 新增项目总结文档及内容
- 添加了“项目总结”侧边栏项,支持目录折叠,方便访问汇总内容
- 新增Cursor进阶指南文档,详解Agent模式、Composer与快捷键等高级功能
- 编写权限管理系统文档,包含系统设计、权限架构及详细使用说明
- 新添服务总线学习文档,解析@BusService注解与CGLIB动态代理机制
- 录制回放权限配置说明,新增录像回放权限位及权限隔离策略
- 提供数据库配置脚本及实施步骤,确保权限配置准确高效
2026-03-05 11:54:52 +08:00
liumangmang
eaab26940d docs(SVN): 补充 SVN 仓库地址变更(Relocate)使用指南
- 新增使用命令行执行 svn relocate 的详细步骤和参数说明
- 添加验证 relocate 成功的方法,即使用 svn info 查看 URL更新情况
- 说明 IntelliJ IDEA 中执行 Relocate 的操作流程
- 列出使用 Relocate 时的注意事项,包含提交更改、备份、权限和证书等
- 解答常见问题,如 "Repository UUID mismatch" 和 relocate 后无法更新的解决办法
2026-02-10 10:26:10 +08:00
51 changed files with 6937 additions and 25 deletions

5
.dockerignore Normal file
View File

@@ -0,0 +1,5 @@
node_modules
dist
src/.vuepress/dist
.git
*.log

1
.gitignore vendored
View File

@@ -13,6 +13,7 @@ src/.vuepress/dist/
# IDE
.idea/
.vscode/
.worktrees/
*.swp
*.swo
*~

13
Dockerfile Normal file
View File

@@ -0,0 +1,13 @@
FROM node:20-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run docs:build
FROM nginx:1.25-alpine
COPY --from=build /app/src/.vuepress/dist /usr/share/nginx/html

7
Makefile Normal file
View File

@@ -0,0 +1,7 @@
.PHONY: up down
up:
docker compose up -d --build
down:
docker compose down

View File

@@ -42,6 +42,24 @@ npm run docs:build
构建产物将生成在 `src/.vuepress/dist` 目录
### Docker 部署
需要先安装 Docker 和 Docker Compose v2。
启动服务:
```bash
make up
```
访问 `http://localhost:51888/` 即可查看站点。
停止服务:
```bash
make down
```
### 清除缓存开发
```bash
@@ -74,3 +92,29 @@ npm run docs:clean-dev
## 📄 License
MIT License
## 🔐 站点访问认证Caddy
本站部署在家用服务器,通过云服务器的 Caddy 作为公网入口;访问认证(登录)已在 Caddy 层统一开启,因此无需在 VuePress/前端实现认证逻辑。
要点:
- **认证位置**:云服务器 `Caddyfile`(整站 `basicauth` / 或按路径规则)
- **原因**:静态站前端登录无法真正保护资源;在反代入口做认证才有效
- **参考命令**(生成 bcrypt 密码哈希):
```bash
caddy hash-password --plaintext 'your-strong-password'
```
- **参考配置**(整站认证):
```caddyfile
example.com {
basicauth {
youruser <bcrypt-hash>
}
reverse_proxy 127.0.0.1:<upstream>
}
```

8
docker-compose.yml Normal file
View File

@@ -0,0 +1,8 @@
services:
myblog:
image: myblog:latest
build:
context: .
ports:
- '51888:80'
restart: unless-stopped

View File

@@ -0,0 +1,109 @@
# OpenCode Superpowers Overview Implementation Plan
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add one new blog post that summarizes `obra/superpowers` (OpenCode-first) + update the AI/OpenCode sidebar entry, matching this blog's writing style.
**Architecture:** One new Markdown article under `src/ai/` plus a small ordering update in `src/.vuepress/sidebar.ts`. Use upstream README as the source-of-truth for workflow + install commands.
**Tech Stack:** VuePress v2 + vuepress-theme-hope, Markdown, TypeScript config.
---
### Task 1: Gather upstream command strings + permalinks
**Files:**
- Read: `~/.config/opencode/superpowers/README.md`
- [ ] **Step 1: Get upstream repo HEAD SHA (for permalinks)**
Run:
```bash
git -C "$HOME/.config/opencode/superpowers" rev-parse HEAD
```
Expected: prints a 40-char SHA.
- [ ] **Step 2: Identify exact upstream snippets to copy**
From upstream `README.md`:
- Installation commands (Claude Code official + marketplace, Cursor, Codex, OpenCode, Gemini)
- Update command (Claude Code)
- Verify Installation paragraph
- Basic Workflow list
---
### Task 2: Create the new overview post
**Files:**
- Create: `src/ai/opencode-superpowers-overview.md`
- [ ] **Step 1: Add frontmatter + title + `<!-- more -->`**
Requirements:
- Chinese
- Major headings `## 一、二、三...`
- Use `---` thematic breaks between major sections
- [ ] **Step 2: Add sections per spec**
Include:
- What it is (1 screen)
- Upstream Basic Workflow (7 steps; step 4 includes "subagent-driven-development or executing-plans")
- Skill map (if/then) + links to existing posts:
- `src/ai/opencode-superpowers.md`
- `src/ai/opencode-skills-playbook.md`
- Install/Verify/Update quick reference with strict fenced-block counts:
- 5 install blocks (Claude/Cursor/Codex/OpenCode/Gemini)
- 1 verify block (2 lines)
- 3 update blocks (Claude/OpenCode/Gemini)
- Cursor + Codex updates as plain text notes (no fenced blocks)
---
### Task 3: Update sidebar order
**Files:**
- Modify: `src/.vuepress/sidebar.ts`
- [ ] **Step 1: Insert new link under AI -> OpenCode**
Insert before the existing:
- `text: "superpowers"`
- `link: "opencode-superpowers.md"`
New item:
- `text: "superpowers-总览"`
- `link: "opencode-superpowers-overview.md"`
Ensure final order:
1) `opencode.md`
2) `opencode-tui.md`
3) `opencode-superpowers-overview.md`
4) `opencode-superpowers.md`
5) `opencode-skills-playbook.md`
---
### Task 4: Verify build
**Files:**
- None
- [ ] **Step 1: Run production build**
Run:
```bash
npm run docs:build
```
Expected: `success VuePress build completed`.

View File

@@ -0,0 +1,211 @@
# OpenCode Superpowers Overview Blog Post - Design
**Date:** 2026-03-16
**Goal:** Write one blog post that summarizes https://github.com/obra/superpowers in my blog style, with OpenCode as the primary viewpoint, plus a short install/verify/update quick reference for other platforms.
**Audience:** Self-use / quick reference. Readers already use terminals and can run commands. Minimal storytelling, maximal usability.
**Non-Goals:**
- Rewriting all upstream docs.
- Duplicating detailed OpenCode install steps already covered in `src/ai/opencode-superpowers.md`.
- Teaching Git basics or agent fundamentals.
---
## Placement
- New article path: `src/ai/opencode-superpowers-overview.md`
- Sidebar: `src/.vuepress/sidebar.ts` under AI -> OpenCode
**Modify file:** `src/.vuepress/sidebar.ts`
- Ordering inside the OpenCode group (final):
- `opencode.md`
- `opencode-tui.md`
- `opencode-superpowers-overview.md` (new)
- `opencode-superpowers.md`
- `opencode-skills-playbook.md`
**Exact sidebar edit:** in `src/.vuepress/sidebar.ts` under `"/ai/"` -> `text: "OpenCode"` -> `children`, insert a new item before the existing `superpowers` link:
- `text: "superpowers-总览"`
- `link: "opencode-superpowers-overview.md"`
Insertion point must be immediately before the existing item:
- `text: "superpowers"`
- `link: "opencode-superpowers.md"`
---
## Content Outline (Blog Style)
### Frontmatter
- `title`: OpenCode Superpowers框架总览与上手路线
- `icon`: `mdi:rocket-launch-outline`
- `date`: 2026-03-16
- `category` (YAML list):
- `AI`
- `开发工具`
- `tag` (YAML list):
- `OpenCode`
- `Superpowers`
- `Skills`
- `工作流`
### Required Structure (match this blog)
The actual blog post must use:
- `#` title + `<!-- more -->`
- Markdown thematic breaks (`---`) between major sections (these are NOT the frontmatter `---` delimiters)
- Major headings as `## 一、二、三...` (Chinese numbered)
Heading format requirement:
- Use `## 一、...` `## 二、...` ... (Chinese numeral + `、`)
Recommended outline:
- `## 一、它是什么1 屏)`
- `---`
- `## 二、上游 Basic Workflow按上游 7 步原样列出)`
- `---`
- `## 三、技能选择速查if/then + 指路)`
- `---`
- `## 四、安装与验证速查OpenCode 为主 + 其他平台命令速查)`
- `---`
- `## 五、更新与排障(按平台)`
### Intro (1 screen)
- Superpowers = skills + initial instructions + workflow discipline.
- Key value: forces an agent to ask, plan, verify; not "jump to code".
### Upstream "Basic Workflow" (match upstream)
The section title must clearly say this list is the upstream default workflow.
Upstream list (7 items) - item text and order must match upstream README "The Basic Workflow" section:
1) `brainstorming`
2) `using-git-worktrees`
3) `writing-plans`
4) `subagent-driven-development` (or `executing-plans`)
5) `test-driven-development`
6) `requesting-code-review`
7) `finishing-a-development-branch`
After the list, add a short "常用配套" note (not part of the upstream numbered workflow):
- `systematic-debugging`
- `verification-before-completion`
Each step gets 1-2 lines in Chinese explaining "this step prevents X" (keep skill names in backticks unchanged).
Note: upstream step 4 includes `executing-plans` as the no-subagent option; keep the step title aligned with upstream wording, then explain when to use each.
### 3. Skill Map (quick decision)
Tiny "if/then" list for choosing a skill, and then point readers to `src/ai/opencode-skills-playbook.md` for full step-by-step.
Also address naming/prefix confusion explicitly:
- Load by the exact name shown in your environment.
- If your environment shows `superpowers/<name>`, load with prefix; otherwise load the bare name.
Link to existing posts (avoid duplication):
- `src/ai/opencode-superpowers.md` (installation / verification / Windows gotchas)
- `src/ai/opencode-skills-playbook.md` (scenarios with steps)
### 4. Installation Quick Reference (multi-platform)
Keep it short: minimal command(s) + one link to details.
**Source of truth requirement:** all install/update commands must be copied verbatim from upstream `obra/superpowers` docs (no guessing).
For each command block, add one upstream source link pointing to the exact upstream section you copied from.
Prefer GitHub permalinks pinned to a commit SHA (so the post stays verifiable even if upstream changes).
Fallback: if you cannot determine a SHA in the current environment, link to the upstream file on `main` and label it as "un-pinned".
**Anti-duplication guardrail (OpenCode):**
- Do NOT include OpenCode manual symlink/junction steps in this post.
- Only include the upstream one-liner (Fetch and follow...) and link to `src/ai/opencode-superpowers.md` for the full manual steps.
Do NOT copy the one-sentence "Clone ... then symlink ..." quick install from `docs/README.opencode.md` into this overview post.
The post must include these platform commands (verbatim from upstream at a pinned SHA):
- Claude Code: official marketplace install + update
- Cursor: plugin install command as shown in upstream README (typically `/add-plugin superpowers` in Cursor Agent chat)
- Codex: install instruction (points to upstream `.codex/INSTALL.md`)
- OpenCode: install instruction (points to upstream `.opencode/INSTALL.md`) + link to `src/ai/opencode-superpowers.md`
- Gemini CLI: extension install + update
Add a dedicated "Verify Installation" subsection (inspired by upstream): start a new session, ask for a task that should trigger a skill, confirm it auto-invokes.
Make verify copy-pastable:
- Example verification prompt (copy-paste): `帮我做一个需求拆解,但先选择并加载一个合适的 superpowers skill 再继续。`
- Expected: the assistant triggers a skill workflow (asks clarifying questions / produces a plan) instead of jumping straight to implementation.
**Command blocks requirement (actionability):**
- Provide one fenced block per platform (`text` or `bash`). Inside the block, include ONLY copy-pastable commands/instructions. Put the platform label outside the fenced block.
Make the block structure explicit:
- Exactly 5 install blocks (Claude Code / Cursor / Codex / OpenCode / Gemini CLI)
- Exactly 3 update blocks (Claude Code / OpenCode / Gemini CLI)
- Cursor + Codex updates are short plain-text notes (no code block)
- Exactly 1 verify block (shared across platforms):
- line 1: copy/paste verification prompt
- line 2: what to look for
No extra fenced blocks are allowed inside Install/Update/Verify sections beyond the counts listed (notes must be plain text outside fences).
Other sections may use fenced blocks if needed, but this post should keep them minimal.
### 5. Updating / Troubleshooting
Make this actionable by platform (1 line update + 1 line verify):
Important constraint: do not introduce inline commands here. All install/update commands must live inside the fenced command blocks defined in the "Command blocks requirement" section.
"Restart OpenCode" must be written as an exact action: fully quit the running opencode process (TUI/CLI) and launch it again.
Also include update notes to complete the "by platform" promise:
- Cursor: short note about Cursor plugin update mechanism; if unsure, reinstall using the same install command from the install blocks, then verify by triggering a skill.
- Codex: short note that re-running the same upstream Codex install instruction is equivalent to updating, then verify by triggering a skill.
Troubleshooting should be short and point to existing detailed sections in `src/ai/opencode-superpowers.md`.
Duplication guardrail (enforced): the overview post may include the upstream OpenCode one-liner install instruction + a link to `src/ai/opencode-superpowers.md`, but must not reproduce the full manual symlink walkthrough.
---
## Sources
- Upstream: https://github.com/obra/superpowers
- Upstream OpenCode doc: https://github.com/obra/superpowers/blob/main/docs/README.opencode.md
---
## Acceptance Criteria
- File exists: `src/ai/opencode-superpowers-overview.md`
- Contains: frontmatter + `#` title + `<!-- more -->`
- Structure: uses `---` separators and `## 一/二/三...` numbered headings
- Includes exactly 5 install fenced blocks, exactly 3 update fenced blocks, and exactly 1 verify fenced block, per the "Command blocks requirement" section
- Each install/update command block has a nearby upstream source link.
- Preferred: a GitHub permalink pinned to a commit SHA
- Fallback: an "un-pinned" link to `main` clearly labeled
- Upstream workflow section matches upstream 7-step basic workflow (and separates "配套技能" clearly)
- Does not repeat manual OpenCode symlink steps; instead links to `src/ai/opencode-superpowers.md`
- Sidebar updated: `src/.vuepress/sidebar.ts` includes `opencode-superpowers-overview.md` under AI -> OpenCode in the specified final order
- Build passes: `npm run docs:build`

View File

@@ -0,0 +1,75 @@
# Docker deployment (make up/down)
## Context
- Project: VuePress v2 static blog (Vite).
- Goal: one-command production deployment and teardown via `make up` and `make down`.
- Hosting: root path `/`.
- Port mapping: host `6666` -> container `80`.
## Goals
- Provide a reproducible, production-grade deployment using Docker.
- Keep operator commands minimal (`make up`, `make down`).
- Ensure build failures fail fast and are visible.
## Non-goals
- No development-mode container (`vuepress-vite dev`).
- No additional runtime dependencies besides Docker.
- No advanced orchestration (k8s, swarm).
## Assumptions
- Docker Engine and Docker Compose v2 are available on the host.
- `package-lock.json` is present; builds use `npm ci`.
## Proposed architecture
- Multi-stage Docker image:
- Stage 1 (build): Node image installs dependencies and runs `docs:build`.
- Stage 2 (run): Nginx serves the generated static files.
- `docker-compose.yml` manages a single service (e.g., `myblog`).
- `Makefile` wraps compose commands for consistent UX.
## Components
### Dockerfile
- Base images: `node:20-alpine` (build), `nginx:1.25-alpine` (run).
- Stage 1:
- Workdir set to app root.
- Copy `package.json` + `package-lock.json`, run `npm ci`.
- Copy source and run `npm run docs:build`.
- Stage 2:
- Copy `src/.vuepress/dist/` to `/usr/share/nginx/html`.
- Use default Nginx config for root `/`.
### .dockerignore
- Exclude: `node_modules`, `dist`, `src/.vuepress/dist`, `.git`, `*.log`.
### docker-compose.yml
- Service name: `myblog`.
- Build context: repository root.
- Image name: `myblog:latest`.
- Port mapping: `6666:80`.
- Restart policy: `unless-stopped`.
### Makefile
- `make up`: `docker compose up -d --build`.
- `make down`: `docker compose down`.
- Optional commands (if desired later): `make logs`, `make ps`, `make rebuild`.
## Runtime flow
1. Operator runs `make up`.
2. Docker builds image (install deps -> build static site).
3. Nginx container starts and serves static files.
4. Operator runs `make down` to stop and remove the service.
## Error handling
- Build failures (dependency install or VuePress build) cause `make up` to fail and exit.
- Compose output provides the error details for diagnosis.
## Verification
- Access `http://<host>:6666/` and confirm the site loads.
- Optional: `docker compose logs -f` for runtime inspection.
## Security / operations
- No secrets are required.
- Container only exposes HTTP on port 80 inside the compose network.
## Open questions
- None. All required inputs confirmed (production mode, root path, port 6666).

View File

@@ -13,8 +13,9 @@
},
"devDependencies": {
"@vuepress/bundler-vite": "2.0.0-rc.22",
"@vuepress/plugin-git": "^2.0.0-rc.99",
"sass-embedded": "~1.80.0",
"@vuepress/plugin-git": "2.0.0-rc.99",
"@vuepress/plugin-search": "2.0.0-rc.99",
"sass-embedded": "^1.87.0",
"vue": "^3.5.13",
"vuepress": "2.0.0-rc.22",
"vuepress-theme-hope": "2.0.0-rc.85"

View File

@@ -1,11 +1,11 @@
import { defineUserConfig } from "vuepress";
import { getDirname, path } from "vuepress/utils";
import {defineUserConfig} from "vuepress";
import {viteBundler} from "@vuepress/bundler-vite";
import {getDirname, path} from "vuepress/utils";
import theme from "./theme.js";
const __dirname = getDirname(import.meta.url);
import theme from "./theme.js";
export default defineUserConfig({
base: "/",
@@ -13,6 +13,18 @@ export default defineUserConfig({
title: "氓氓小栈",
description: "氓氓小栈",
theme,
bundler: viteBundler({
viteOptions: {
css: {
preprocessorOptions: {
scss: {
quietDeps: true,
silenceDeprecations: ["if-function"],
},
},
},
},
}),
alias: {
"@theme-hope/modules/blog/components/BlogHero": path.resolve(
__dirname,

View File

@@ -1,4 +1,4 @@
import { navbar } from "vuepress-theme-hope";
import {navbar} from "vuepress-theme-hope";
export default navbar([
"/",
@@ -22,4 +22,9 @@ export default navbar([
icon: "mdi:toolbox",
link: "/tools/",
},
{
text: "AI",
icon: "mdi:robot-outline",
link: "/ai/",
},
]);

View File

@@ -1,4 +1,4 @@
import { sidebar } from "vuepress-theme-hope";
import {sidebar} from "vuepress-theme-hope";
export default sidebar({
"/programming/": [
@@ -194,10 +194,40 @@ export default sidebar({
prefix: "log/",
children: "structure",
},
{
text: "项目总结",
collapsible: true,
expanded: false,
icon: "mdi:book-open-page-variant",
prefix: "project-summary/",
children: "structure",
},
{
text: "常用记录",
icon: "mdi:star",
link: "/work/常用.md",
},
{
text: "待办事项",
icon: "fa6-solid:list-check",
collapsible: true,
children: [
{
text: "待办首页",
icon: "mdi:home-outline",
link: "/work/todo/",
},
{
text: "4月待办",
icon: "mdi:calendar-month",
link: "/work/todo/2026-04.md",
},
{
text: "3月待办",
icon: "mdi:calendar-month",
link: "/work/todo/2026-03.md",
},
],
}
],
"/apps/": [
@@ -222,5 +252,96 @@ export default sidebar({
"06MobaXterm.md"
],
},
]
],
"/ai/": [
{
text: "OpenCode",
icon: "fa6-solid:code",
collapsible: true,
children: [
{
text: "opencode-cli",
icon: "fa6-solid:terminal",
link: "opencode.md",
},
{
text: "opencode-tui",
icon: "fa6-solid:desktop",
link: "opencode-tui.md",
},
],
},
{
text: "Superpowers",
icon: "fa6-solid:rocket",
collapsible: true,
prefix: "superpowers/",
children: [
{
text: "superpowers-总览",
icon: "fa6-solid:eye",
link: "opencode-superpowers-overview.md",
},
{
text: "superpowers",
icon: "fa6-solid:bolt",
link: "opencode-superpowers.md",
},
{
text: "skills-使用方案汇总",
icon: "fa6-solid:book",
link: "opencode-skills-playbook.md",
},
],
},
{
text: "Claude Code",
icon: "fa6-solid:code-branch",
collapsible: true,
children: [
{
text: "多分支工作流实战总结2026",
icon: "fa6-solid:code-merge",
link: "claude-code-branch-workflow-2026.md",
},
],
},
{
text: "ChatGPT",
icon: "fa6-solid:comments",
collapsible: true,
children: [
{
text: "chatgpt-使用记录与实践",
icon: "fa6-solid:message",
link: "chatgpt.md",
},
],
},
{
text: "OpenClaw",
icon: "fa6-solid:robot",
collapsible: true,
children: [
{
text: "openclaw-24h在线部署实战",
icon: "fa6-solid:server",
link: "openclaw.md",
},
],
},
{
text: "iFlow",
icon: "fa6-solid:diagram-project",
collapsible: true,
children: [
{
text: "iflow-流程编排实践记录",
icon: "fa6-solid:flow-chart",
link: "iflow.md",
},
],
},
],
"/": false,
});

View File

@@ -11,3 +11,112 @@
color: #DC143C!important; // 可选:也可自定义作者名颜色
}
.vp-navbar .auto-link {
display: inline-flex;
align-items: center;
gap: 0.3em;
}
.vp-navbar .auto-link .icon,
.vp-navbar .auto-link .vp-icon {
flex-shrink: 0;
}
.todo-page {
--todo-border: rgba(220, 20, 60, 0.2);
--todo-accent: rgba(220, 20, 60, 0.08);
--todo-card-bg: rgba(255, 255, 255, 0.85);
.theme-hope-content {
h1 {
margin-bottom: 0.8rem;
font-size: clamp(1.9rem, 2.6vw, 2.3rem);
letter-spacing: 0.02em;
}
blockquote {
margin: 0.9rem 0 1.2rem;
padding: 0.85rem 1rem;
border-radius: 0.8rem;
border: 1px solid var(--todo-border);
background: linear-gradient(135deg, var(--todo-accent), rgba(220, 20, 60, 0.03));
p {
margin: 0;
line-height: 1.6;
}
}
hr {
margin: 1.6rem 0;
opacity: 0.45;
}
h2 {
margin: 1.5rem 0 0.8rem;
padding-left: 0.65rem;
border-left: 4px solid #dc143c;
font-size: clamp(1.2rem, 2.1vw, 1.45rem);
}
h3 {
margin: 0.85rem 0 0;
padding: 0.85rem 1rem;
border: 1px solid var(--todo-border);
border-bottom: 0;
border-radius: 0.85rem 0.85rem 0 0;
background: var(--todo-card-bg);
line-height: 1.4;
.header-anchor {
opacity: 0;
}
}
h3 + ul {
margin: 0 0 0.95rem;
padding: 0.8rem 1rem 0.95rem 1.25rem;
border: 1px solid var(--todo-border);
border-top: 0;
border-radius: 0 0 0.85rem 0.85rem;
background: var(--todo-card-bg);
box-shadow: 0 8px 18px -18px rgba(220, 20, 60, 0.55);
li {
margin: 0.2rem 0;
}
}
details {
margin-top: 0.6rem;
border: 1px dashed var(--todo-border);
border-radius: 0.8rem;
padding: 0.5rem 0.75rem;
background: rgba(220, 20, 60, 0.03);
summary {
cursor: pointer;
font-weight: 600;
}
}
}
}
@media (max-width: 768px) {
.todo-page .theme-hope-content {
h2 {
margin-top: 1.2rem;
padding-left: 0.5rem;
}
h3 {
padding: 0.75rem 0.8rem;
font-size: 1.02rem;
}
h3 + ul {
padding: 0.7rem 0.8rem 0.8rem 1.1rem;
margin-bottom: 0.8rem;
}
}
}

View File

@@ -98,6 +98,9 @@ export default hopeTheme(
// 启用博客功能
blog: true,
// 启用本地搜索
search: true,
// 组件配置
components: {
components: ["Badge", "VPCard"],
@@ -113,4 +116,4 @@ export default hopeTheme(
// 自定义主题配置
custom: true
}
);
);

View File

@@ -8,8 +8,8 @@ tagline: ''
#heroImage: logo/transparentLogo.png
#heroImageDark: logo/transparentLogo.png
#heroAlt: 可爱小熊猫
bgImage: bg/day.png
bgImageDark: bg/night.png
bgImage: bg/bgImage.jpg
bgImageDark: bg/bgImage.jpg
heroFullScreen: true
icon: house

23
src/ai/README.md Normal file
View File

@@ -0,0 +1,23 @@
---
title: AI 工具导航
icon: mdi:robot-outline
date: 2026-03-06
category:
- AI
tag:
- AI
- 工具
---
# AI 工具导航
这里整理常用的 AI 工具记录。
<!-- more -->
- OpenCode CLI 实战指南
- OpenCode TUI 实战指南
- Claude Code 多分支工作流实战总结2026
- ChatGPT 使用记录与实践
- OpenClaw 个人 24 小时在线部署实战
- iFlow 流程编排实践记录

17
src/ai/chatgpt.md Normal file
View File

@@ -0,0 +1,17 @@
---
title: ChatGPT 使用记录与实践
icon: mdi:chat-processing-outline
date: 2026-03-06
category:
- AI
tag:
- ChatGPT
---
# ChatGPT 使用记录与实践
ChatGPT 使用记录与实践。
<!-- more -->
后续补充:提问模板、工作流和常见问题。

View File

@@ -0,0 +1,193 @@
---
title: Claude Code 多分支工作流实战总结2026
icon: mdi:source-branch
date: 2026-03-11
category:
- AI
- 开发工具
tag:
- ClaudeCode
- Git
- Worktree
- AI编程
- 工作流
---
# Claude Code 多分支工作流实战总结2026
这篇是对一篇 Claude Code 工作流文章的中文实战整理版。
核心结论很直接:不要在一个分支里让 AI 连续改代码,要用“任务隔离 +
并行执行 + 人工验收”的方式把效率和可控性同时拉起来。
<!-- more -->
---
## 一、为什么单分支跑 AI 容易翻车
文章先指出了一个常见误区:在 `main`(或同一个功能分支)里持续让 AI
修改,短期快,后期很容易失控。
典型问题有 3 个:
1. 上下文污染:修 A 时顺手改了 B/Cdiff 越滚越大。
2. 任务串行:只能一个任务一个任务排队,浪费 AI 并行能力。
3. 协作困难:主分支被污染后,团队很难判断哪些改动可合并、可回滚。
一句话:单分支的主要代价不是慢,而是不可控。
---
## 二、核心原则:一个任务,一个分支
更稳的做法是把每个任务放到独立分支,让 AI 在隔离环境工作。
```bash
# 不建议:直接在 main 上跑
git checkout main
claude
# 建议:每个任务独立分支
git checkout -b claude/fix-login-bug
claude
```
建议统一前缀,方便识别 AI 分支:
- `claude/feat-xxx`
- `claude/fix-xxx`
- `claude/refactor-xxx`
- `claude/exp-xxx`
这样在 PR 列表里,一眼就能区分 AI 产出的变更。
---
## 三、进一步提速:用 git worktree 做并行
如果你一次要推进多个任务,`git worktree` 是关键工具:
同一仓库开多个工作目录,每个目录绑定一个分支,多个 Claude 实例并行跑。
```bash
git worktree add ../myproj-feature-a claude/feature-a
git worktree add ../myproj-feature-b claude/feature-b
git worktree add ../myproj-fix-c claude/fix-c
```
然后在不同终端分别运行 Claude
```bash
# 终端 1
cd ../myproj-feature-a && claude
# 终端 2
cd ../myproj-feature-b && claude
# 终端 3
cd ../myproj-fix-c && claude
```
你负责统筹和验收AI 负责并行执行。
---
## 四、上下文管理:给 AI 刚刚好的信息
文章给了 3 个高频技巧,实用性很强。
### 1`CLAUDE.md` 保持精简
别写成项目百科,重点写“当前任务约束 + 必须遵守的架构规则”。
推荐结构:
- 可改范围(哪些目录能动)
- 禁改范围(哪些目录不能动)
- 验收标准(测试、风格、安全约束)
- 架构红线(必须走哪一层、禁止直连什么)
### 2用 `/compact` 控制会话长度
长对话容易导致注意力发散,子任务完成后执行一次压缩更稳。
```text
/compact
```
如果模型明显跑偏,可考虑清空后重给最小上下文再继续。
### 3用 `--resume` 续接中断任务
```bash
claude --resume
```
第二天可直接接续昨天上下文,减少重复沟通成本。
---
## 五、可复用的 5 步工作流模板
### Step 1先建分支再开始任务
```bash
git checkout -b claude/JIRA-1234-user-profile-api
```
### Step 2先让 AI 给实施计划,再执行
先对齐“目标、边界、参考实现、验收条件”,避免直接开改导致返工。
### Step 3并行执行人工做 Code Review
```bash
git diff main
```
重点看:
- 是否改了不该改的文件
- 逻辑是否符合需求
- 是否引入安全或稳定性风险
### Step 4测试通过后再合并
```bash
npm test
# 或项目实际测试命令
```
### Step 5任务结束及时清理
```bash
git worktree remove ../myproj-feature-a
git branch -d claude/JIRA-1234-user-profile-api
```
---
## 六、团队落地建议(可直接抄)
1. 统一 AI 分支命名规范。
2. 给 AI 分支单独准备 PR 模板。
3. 在仓库维护共享 `CLAUDE.md`,降低团队上手成本。
4. 把“人工 Review + 测试通过”设为合并前置条件。
---
## 七、总结
这套方法本质上是在做一件事:
把“AI 的执行力”和“人的决策权”拆开。
- AI 负责生成和修改
- 你负责边界、评审、验收和最终合并
如果你现在还在一个分支里连续跑 Claude Code最先该改的不是提示词
而是 Git 工作流。
---
## 参考
- 原文https://blog.ccino.org/p/claude-code-branch-workflow-secrets-2026/

17
src/ai/iflow.md Normal file
View File

@@ -0,0 +1,17 @@
---
title: iFlow 流程编排实践记录
icon: mdi:sitemap-outline
date: 2026-03-06
category:
- AI
tag:
- iFlow
---
# iFlow 流程编排实践记录
iFlow 使用记录与实践。
<!-- more -->
后续补充:流程编排、集成方式与落地经验。

248
src/ai/openclaw.md Normal file
View File

@@ -0,0 +1,248 @@
---
title: OpenClaw 个人 24 小时在线部署实战
icon: mdi:robot-outline
date: 2026-03-10
category:
- AI
- 部署实践
tag:
- OpenClaw
- Telegram
- 飞书
- Linux
---
# OpenClaw 个人 24 小时在线部署实战
最近把 OpenClaw 在个人 Linux 机器上完整跑通了。
这篇不是理想教程,而是可复现的真实部署记录:初始化、守护进程常驻、
渠道接入、Web 搜索和安全收紧。
<!-- more -->
适合人群:
- 个人单用户场景
- 希望 24 小时在线
- 想接 Telegram 或飞书
- 想一次把常见坑踩完
---
## 一、初始化与守护进程安装
先执行初始化:
```bash
openclaw onboard --install-daemon
```
如果流程卡在风险确认,可以补上:
```bash
openclaw onboard --install-daemon --accept-risk --non-interactive --flow quickstart
```
安装后重点确认:
```bash
systemctl --user status openclaw-gateway.service --no-pager
```
看到 `active (running)` 基本就对了。
---
## 二、24 小时在线关键:开启 linger
如果希望退出登录后仍运行、重启后自动恢复,必须开启 `linger`
```bash
sudo loginctl enable-linger <你的用户名>
loginctl show-user <你的用户名> -p Linger
```
目标是 `Linger=yes`
不开 `linger` 的典型现象:退出图形会话或 SSH 后user service 会停掉。
---
## 三、Dashboard token 报错处理(高频坑)
常见报错:
> unauthorized: gateway token missing
处理方式:
```bash
openclaw dashboard --no-open
```
复制输出的完整 URL包含 `#token=...`)到浏览器打开。
如果是旧标签页,先关闭再开新链接。
---
## 四、模型配置确认
检查当前默认模型:
```bash
openclaw models status --plain
openclaw models list
```
如果模型已配置但仍无法工作,优先排查这三项:
- 网关 token
- 渠道配对状态
- 工具权限策略
---
## 五、Telegram 接入(个人单用户推荐)
最短流程:
1.`@BotFather` 创建 bot拿到 token
2. 运行配置向导
```bash
openclaw configure --section channels
```
3. 选择 Telegram建议 `dmPolicy=pairing`
4. 重启网关
```bash
systemctl --user restart openclaw-gateway.service
```
5. 私聊机器人后审批配对码
```bash
openclaw pairing list telegram
openclaw pairing approve telegram <CODE>
```
---
## 六、飞书接入(真实坑点)
如果遇到报错:
> 未检测到应用连接信息,请确保长连接建立成功后再保存配置
重点检查:
- 飞书应用是否已发布版本
- 机器人能力是否开启
- 事件订阅是否为长连接,且包含 `im.message.receive_v1`
- 应用可用范围是否包含你自己的账号
实践上建议先在 OpenClaw 侧加渠道,再回飞书保存长连接,成功率更高。
---
## 七、开启 Web 能力:`web_fetch` 与 `web_search`
先开基础配置:
```bash
openclaw config set tools.web.fetch.enabled true
openclaw config set tools.web.search.enabled true
```
Gemini 搜索示例:
```bash
openclaw config set tools.web.search.provider '"gemini"'
openclaw config set tools.web.search.gemini.apiKey '"AIza...你的key..."'
systemctl --user restart openclaw-gateway.service
```
---
## 八、核心坑:有 key 也搜不了
当时现象是 key 已配置,但 `web_search` 仍提示不可用。
根因:工具策略限制,`tools.profile: coding` 默认不包含 `group:web`
临时打通方式:
```bash
openclaw config set tools.profile '"full"'
systemctl --user restart openclaw-gateway.service
```
`full` 权限面比较大,建议只作为排障手段,跑通后再收紧。
---
## 九、安全加固(强烈建议)
先做检查:
```bash
openclaw security audit --deep
openclaw doctor
```
我最后收敛到这组配置:
- 工具权限从 `full` 降回 `coding`
- 显式插件白名单,防止任意扩展加载
- 清理重复或社区扩展,仅保留稳定内置插件
- 关闭不必要的飞书文档创建能力
- 收紧 `~/.openclaw` 目录权限
关键命令:
```bash
openclaw config set tools.profile '"coding"'
openclaw config set plugins.allow '["feishu","telegram"]'
openclaw config set channels.feishu.tools.doc false
systemctl --user restart openclaw-gateway.service
```
最终安全摘要降到 `0 critical`(仅保留 loopback 场景可接受告警)。
---
## 十、密钥安全:暴露后立即轮换
如果你在聊天、日志或截图里暴露过 API key建议立刻轮换。
以 Gemini 为例:
1.`https://aistudio.google.com/apikey` 新建 key
2. 删除旧 key
3. 更新 OpenClaw 配置并重启
---
## 十一、日常运维命令(常用)
```bash
openclaw status
openclaw logs --follow
systemctl --user status openclaw-gateway.service --no-pager
openclaw security audit --deep
```
---
## 结语
这套下来,个人单用户场景基本就稳定了:
- 24 小时在线
- Telegram / 飞书可用
- Web 能力可用
- 安全面可控
建议先追求稳、可恢复、最小权限,再逐步加功能;
不要一上来就长期 `full` 权限常驻。

179
src/ai/opencode-tui.md Normal file
View File

@@ -0,0 +1,179 @@
---
title: OpenCode TUI 实战指南
icon: mdi:monitor-dashboard
date: 2026-03-06
category:
- AI
- 开发工具
tag:
- OpenCode
- TUI
- AI编程
---
# OpenCode TUI 实战指南
这篇文章基于 OpenCode 官方文档的 TUI 章节,聚焦终端交互界面的
高频用法:怎么聊、怎么调、怎么把会话真正用起来。
<!-- more -->
---
## 一、先启动 TUI
直接在当前目录启动:
```bash
opencode
```
或者指定项目目录启动:
```bash
opencode /path/to/project
```
进入后就能直接提问,例如:
```text
先给我快速总结一下这个仓库结构和技术栈。
```
---
## 二、两个最实用的输入能力
### 2.1 `@` 文件引用
在消息里用 `@` 引用文件OpenCode 会做模糊匹配并把文件内容带入上下文。
```text
@src/.vuepress/config.ts 这个配置里有哪些容易踩坑的点?
```
适合代码审查、定位问题、讲解现有实现。
### 2.2 `!` Bash 命令
输入 `!` 开头的内容,会按 shell 命令执行并把输出注入会话。
```text
!git status
!npm run docs:build
```
这个能力非常适合“边看代码边验证”。
---
## 三、必须掌握的斜杠命令
### 3.1 会话与整理
```text
/new
/sessions
/compact
```
- `/new`:开新会话(清空当前上下文)。
- `/sessions`:快速切换历史会话。
- `/compact`:压缩上下文,长对话时很有用。
### 3.2 可视化与排障
```text
/details
/thinking
/models
```
- `/details`:显示或隐藏工具执行细节。
- `/thinking`:切换推理块显示(仅控制展示)。
- `/models`:查看可用模型并确认当前选择。
### 3.3 输出与分享
```text
/export
/share
/unshare
```
- `/export`:导出当前对话为 Markdown。
- `/share`:分享当前会话。
- `/unshare`:取消分享。
---
## 四、`undo` / `redo` 的正确理解
```text
/undo
/redo
```
这两个命令不仅会撤销或重做消息,也会回滚或恢复文件变更。
注意:它依赖 Git 管理改动,所以项目目录最好是一个 Git 仓库。
---
## 五、编辑器联动(很建议配)
`/editor``/export` 都依赖 `EDITOR` 环境变量。
Linux / macOS 示例:
```bash
export EDITOR="code --wait"
```
如果你使用 `vim` / `nvim` / `nano` 也可以直接设置对应命令。
推荐使用带 `--wait` 的 GUI 编辑器,这样 TUI 会等待你编辑完成再返回。
---
## 六、TUI 配置项(滚动最常用)
可以在配置文件中设置:
```json
{
"$schema": "https://opencode.ai/config.json",
"tui": {
"scroll_speed": 3,
"scroll_acceleration": {
"enabled": true
}
}
}
```
- `scroll_speed`:滚动速度(最小 `1`)。
- `scroll_acceleration.enabled`:类 macOS 滚动加速。
当加速开启时,会覆盖 `scroll_speed` 的效果。
---
## 七、一套我常用的 TUI 习惯
1. 先用 `@` 精准挂载关键文件,再提任务。
2. 单次只做一类改动,必要时 `/compact`
3. 关键节点 `/export`,形成可复盘记录。
4. 大改前先确认 Git 状态,便于 `/undo` 使用。
5. 需要自动化时再切到 `opencode run`
---
## 八、结语
TUI 的核心不是“会聊天”,而是把上下文、命令执行和文件改动放在同一条工作流里。
如果你平时就在终端里开发OpenCode TUI 会比网页对话更顺手。
> 参考文档:
> https://opencode.ai/docs/zh-cn/tui/

218
src/ai/opencode.md Normal file
View File

@@ -0,0 +1,218 @@
---
title: OpenCode CLI 实战指南
icon: mdi:application-braces-outline
date: 2026-03-06
category:
- AI
- 开发工具
tag:
- OpenCode
- CLI
- AI编程
---
# OpenCode CLI 实战指南
这篇文章基于 OpenCode 官方文档的 CLI 章节,整理出一套更偏实战的
使用方式:先跑起来,再把它接入日常开发流程。
<!-- more -->
---
## 一、先有一个可用的 OpenCode CLI
OpenCode 在不带参数运行时会进入 TUI终端交互界面
```bash
opencode
```
如果你只想快速问一个问题,不进 TUI直接用 `run`
```bash
opencode run "解释一下 Go 的 context 使用场景"
```
这两个入口就够你先开始:
- `opencode`:适合持续交互、改代码、看上下文。
- `opencode run ...`:适合脚本、自动化、一次性问答。
---
## 二、我最常用的 CLI 命令
### 2.1 会话与续接
```bash
# 继续上一次会话
opencode -c
# 指定会话 ID 继续
opencode -s <session-id>
# 在继续时分叉一个新分支会话
opencode -c --fork
```
当你在做“同一任务的不同方案”时,`--fork` 非常好用。
### 2.2 非交互执行(脚本友好)
```bash
# 一次性执行
opencode run "为当前仓库生成提交说明"
# 继续历史会话执行
opencode run -c "继续刚才的重构任务"
# 指定模型
opencode run -m anthropic/claude-sonnet-4 "审查这次变更"
# 附件文件
opencode run -f README.md "总结这份文档"
```
### 2.3 模型与认证
```bash
# 登录模型提供商(会写入本地凭据文件)
opencode auth login
# 查看已登录提供商
opencode auth ls
# 查看可用模型
opencode models
# 刷新模型缓存
opencode models --refresh
```
### 2.4 MCP 相关
```bash
# 添加 MCP 服务
opencode mcp add
# 查看 MCP 列表和状态
opencode mcp ls
# OAuth 认证
opencode mcp auth
```
如果你把外部工具接到 OpenCodeMCP 是关键路径。
---
## 三、一个顺手的工作流(推荐)
我现在更常用这套顺序:
1. `opencode` 进入 TUI先理解项目结构。
2. 用自然语言给任务边界(目标、限制、验收)。
3. 小步执行:每次只改一类问题。
4. 关键节点用 `session list` 记录上下文。
5. 需要批处理时切到 `opencode run`
相关命令:
```bash
# 查看会话
opencode session list
# 导出会话(便于复盘)
opencode export <session-id>
# 从 JSON 或分享链接导入
opencode import <file-or-url>
```
---
## 四、服务化与远程连接
当你希望“一个后端 + 多端连接”时:
```bash
# 启动无界面服务
opencode serve
# 启动 web 版本
opencode web --port 4096 --hostname 0.0.0.0
# 其他终端附着到服务
opencode attach http://127.0.0.1:4096
```
这样可以减少重复冷启动,尤其是 MCP 场景更明显。
---
## 五、几个高频实用命令
```bash
# 统计 token 和费用
opencode stats --days 7 --models 5
# 查看全局帮助
opencode -h
# 查看版本
opencode -v
# 升级
opencode upgrade
```
卸载前建议先 dry run
```bash
opencode uninstall --dry-run
```
---
## 六、环境变量里最值得记住的几个
```bash
# 为 serve / web 打开基础认证
export OPENCODE_SERVER_PASSWORD="your-password"
# 指定配置目录
export OPENCODE_CONFIG_DIR="$HOME/.config/opencode"
# 关闭自动更新检查
export OPENCODE_DISABLE_AUTOUPDATE=true
# 启用实验特性总开关
export OPENCODE_EXPERIMENTAL=true
```
建议:实验变量只在测试环境开,不要直接进生产脚本。
---
## 七、踩坑提醒
1. `run` 很方便,但复杂任务建议先进 TUI 再拆步骤。
2. 多提供商混用时,模型名要写 `provider/model` 全名。
3. `serve` / `web` 对外开放时,优先配 `OPENCODE_SERVER_PASSWORD`
4. MCP 连接异常先看 `opencode mcp ls``opencode mcp debug <name>`
---
## 八、结语
如果你是第一次用 OpenCode先记住三条就够了
- `opencode`:主入口(交互式)。
- `opencode run`:自动化入口(非交互)。
- `opencode auth login` + `opencode models`:先把模型链路打通。
后面再逐步接入 MCP、会话导入导出、以及 `serve/web` 的多端协作。
> 参考文档:
> https://opencode.ai/docs/zh-cn/cli/

View File

@@ -0,0 +1,314 @@
---
title: OpenCode Superpowers编码 + 写博客 skills 使用方案(自用版)
icon: mdi:checklist
date: 2026-03-16
category:
- AI
- 开发工具
tag:
- OpenCode
- Superpowers
- Skills
- 工作流
redirectFrom:
- /ai/opencode-skills-playbook.html
- /ai/opencode-skills-playbook
---
# OpenCode Superpowers编码 + 写博客 skills 使用方案(自用版)
这篇不解释太多背景,目标是:我在写博客和写代码时,如何用 Superpowers
这套 skills 把工作流“固定下来”,减少跑偏与返工。
<!-- more -->
---
## 一、先记住一句话:先定方向,再列步骤,最后做验证
我把 skills 当成“工作流开关”,只要记住这 3 句就够用了:
- 不确定怎么做:`brainstorming`(先把方向定清楚)
- 知道要做什么但步骤多:`writing-plans`(把步骤写成清单)
- 说“做完了”之前:`verification-before-completion`(把验证跑完再收工)
后面所有场景,基本都是这 3 个的排列组合。
---
## 二、最小前提:你得先能加载到这些 skills
我默认你已经按 Superpowers 的方式装好(仓库 + 插件 + skills symlink并且
OpenCode 已重启。
在对话里直接加载某个 skill注意这里的名字通常不带 `superpowers/` 前缀):
```text
use skill tool to load brainstorming
```
如果你想确认当前可用 skills可以让 OpenCode 输出“当前环境已暴露的技能列表”。
---
## 三、三种场景:按步骤直接照做
下面每个场景我都写成“第 1 步 / 第 2 步 / 第 3 步...”。
你只要把 `use skill tool to load ...` 复制到 OpenCode 里就行。
---
## 四、场景 1写新项目从 0 到能跑)
目标:把事情做成,而不是先把代码写漂亮。
第 1 步先把需求说清楚brainstorming
这一部的目的:把“我想做什么”说成“我到底要交付什么”,避免一上来就写错方向。
```text
use skill tool to load brainstorming
```
我常用输入:
```text
我要做一个新项目:<一句话描述>。
请你:
1) 只问我 1 个最关键澄清问题
2) 给 2-3 种方案对比(含取舍)
3) 给你推荐的方案(写清楚为什么)
```
第 2 步把落地步骤写成清单writing-plans
这一部的目的:把任务拆成你能按部就班执行的步骤,并且每一步都有验证方法。
```text
use skill tool to load writing-plans
```
我会要求它至少写清:
- 要建/要改哪些文件(精确路径)
- 每一步怎么验证(命令)
第 3 步按计划执行executing-plans
这一部的目的:按清单逐步推进,避免“想到哪改到哪”,也方便中途停下来复盘。
```text
use skill tool to load executing-plans
```
第 4 步跑验证确认真能用verification-before-completion
这一部的目的:用实际命令证明项目能跑/能构建,而不是凭感觉说完成。
```text
use skill tool to load verification-before-completion
```
第 5 步收尾finishing-a-development-branch
这一部的目的:决定怎么合并/怎么交付/怎么清理临时分支,让工作可结束、可回滚。
```text
use skill tool to load finishing-a-development-branch
```
---
## 五、场景 2改已有项目新增/修 bug/重构)
这个场景的关键是:先判断你现在是哪一类工作。
第 1 步:先选“起手 skill”二选一
这一部的目的:先选对“模式”。改功能和排障的思路完全不同,起手选错会浪费时间。
- 需求/改功能(容易跑偏):用 `brainstorming`
```text
use skill tool to load brainstorming
```
- 报错/构建失败/线上行为不对:用 `systematic-debugging`
```text
use skill tool to load systematic-debugging
```
第 2 步把修改拆成可执行清单writing-plans
这一部的目的:把改动限制在可控范围里,避免无意改到无关文件。
```text
use skill tool to load writing-plans
```
第 3 步:如果是“新增功能 / 修 bug”优先用 TDDtest-driven-development可选但推荐
这一部的目的:先把预期行为写成测试(或可复现步骤),让修改有明确的对错标准。
```text
use skill tool to load test-driven-development
```
第 4 步按计划执行executing-plans
这一部的目的:按步骤做小改动、频繁验证,减少一次性大改带来的风险。
```text
use skill tool to load executing-plans
```
第 5 步完成前必须验证verification-before-completion
这一部的目的:在提交/合并前用证据确认“真的修好/真的没破坏”。
```text
use skill tool to load verification-before-completion
```
第 6 步需要更稳就做一次评审requesting-code-review可选
这一部的目的:让 AI 用审查视角检查逻辑、边界、改动范围,帮你补漏。
```text
use skill tool to load requesting-code-review
```
第 7 步收尾finishing-a-development-branch
这一部的目的:把任务“结束干净”:合并策略明确、分支/工作区清理到位。
```text
use skill tool to load finishing-a-development-branch
```
---
## 六、场景 3写博客到当前这个博客VuePress
目标:按我博客风格产出一篇能构建通过的文章。
第 1 步先把文章的边界定清楚brainstorming
这一部的目的:确定文章要写给谁、要解决什么问题、最终交付什么文件。
```text
use skill tool to load brainstorming
```
我常用输入:
```text
把这篇文章整理到我的 VuePress 博客(当前仓库)里。
要求:
1) 中文,偏实战
2) 要有 frontmatter + <!-- more -->
3) 命令块可复制,少废话
4) 产物1 篇 Markdown + 如需要更新 sidebar
5) 验收npm run docs:build 通过
```
第 2 步:先写提纲 + 文件清单writing-plans
这一部的目的:先把结构定住(标题/小节/命令块),写作时不跑题。
```text
use skill tool to load writing-plans
```
第 3 步:按清单写文章/改 sidebarexecuting-plans
这一部的目的:按提纲逐段落地,并确保目录/导航能找到文章。
```text
use skill tool to load executing-plans
```
第 4 步构建验证verification-before-completion
这一部的目的:用构建结果证明“文章不会把站点打挂”。
```text
use skill tool to load verification-before-completion
```
对本仓库最关键的验收命令就是:
```bash
npm run docs:build
```
第 5 步需要更稳就让它做一次“编辑校对”requesting-code-review可选
这一部的目的:检查表达是否清晰、命令是否危险/错误、是否遗漏验收。
```text
use skill tool to load requesting-code-review
```
---
## 七、并行提效(可选):任务隔离 + 多任务并发
如果你同时推进多个任务(例如:写两篇文章 + 修一个构建问题),建议用这两件事:
1) `using-git-worktrees`:把任务隔离到不同 worktree避免 diff 越滚越大。
2) `dispatching-parallel-agents`:把互不依赖的子任务拆开并行跑。
加载方式:
```text
use skill tool to load using-git-worktrees
use skill tool to load dispatching-parallel-agents
```
---
## 八、附录:我常复制的提示词块
### 6.1 整理外部文章到博客
```text
请把这篇文章整理成我的博客风格VuePress
要求:
1) 中文输出,分段用 ---,小节用“## 一/二/三”。
2) 必须包含 frontmattertitle/date/category/tag/icon和 <!-- more -->。
3) 内容偏实战:命令、坑点、验证步骤优先。
4) 不要照搬原文结构,按“我会怎么用”重组。
5) 产物是 1 篇 Markdown给出建议文件名
```
### 6.2 改代码前先要执行计划
```text
先不要改代码。
请输出一个可执行的实施计划:
- 要改的文件路径清单
- 每一步做什么
- 每一步如何验证(命令)
- 最后必须给出完整的验收命令集合
```
### 6.3 构建失败/运行报错时的排障输入
```text
我遇到一个错误,请按系统化排障流程来。
复现步骤:
1) ...
2) ...
期望行为:...
实际行为:...
错误输出(完整粘贴):
...
```

View File

@@ -0,0 +1,210 @@
---
title: OpenCode Superpowers框架总览与上手路线
icon: mdi:rocket-launch-outline
date: 2026-03-16
category:
- AI
- 开发工具
tag:
- OpenCode
- Superpowers
- Skills
- 工作流
redirectFrom:
- /ai/opencode-superpowers-overview.html
- /ai/opencode-superpowers-overview
---
# OpenCode Superpowers框架总览与上手路线
Superpowers 不是“又一套提示词”,而是一套给编码代理用的开发方法:
强制先澄清、先写计划、再执行、最后验证。
这篇以 OpenCode 为主视角,把上游仓库 `obra/superpowers` 的核心要点整理成一篇
可直接照着用的速查。
<!-- more -->
---
## 一、它是什么1 屏)
一句话Superpowers = skills 库 + 强制工作流 + 初始指令注入,让代理按流程做事。
它主要解决三类问题:
1. 还没想清楚就开写:越写越偏,返工成本高。
2. 任务太大没拆分改动越滚越大diff 失控。
3. 没验证就宣布完成:靠感觉收工,最后还是你来擦屁股。
上游仓库:`https://github.com/obra/superpowers`
---
## 二、上游 Basic Workflow按上游 7 步列出)
下面这一段的“步骤名称与顺序”对齐上游 README 的 `The Basic Workflow`
我在每一步后面加一行白话解释,方便快速理解。
1. **brainstorming** - Activates before writing code. Refines rough ideas through questions, explores alternatives, presents design in sections for validation. Saves design document.
白话:先问清楚需求边界,给方案对比,并写成可复用的设计稿,避免直接开写。
2. **using-git-worktrees** - Activates after design approval. Creates isolated workspace on new branch, runs project setup, verifies clean test baseline.
白话:把任务隔离到独立分支/工作区,避免污染主分支,也方便并行做多个任务。
3. **writing-plans** - Activates with approved design. Breaks work into bite-sized tasks (2-5 minutes each). Every task has exact file paths, complete code, verification steps.
白话:把“要做什么”拆成清单:改哪些文件、每一步怎么验收,尽量 2-5 分钟一个小步。
4. **subagent-driven-development** or **executing-plans** - Activates with plan. Dispatches fresh subagent per task with two-stage review (spec compliance, then code quality), or executes in batches with human checkpoints.
白话:按计划执行。能并行就并行(子代理),不行就分批执行并留检查点。
5. **test-driven-development** - Activates during implementation. Enforces RED-GREEN-REFACTOR: write failing test, watch it fail, write minimal code, watch it pass, commit. Deletes code written before tests.
白话:先让测试失败,再写最小实现让它通过;不写测试的代码宁可删掉重来。
6. **requesting-code-review** - Activates between tasks. Reviews against plan, reports issues by severity. Critical issues block progress.
白话:每个阶段都做一次对计划的审查,避免悄悄偏离。
7. **finishing-a-development-branch** - Activates when tasks complete. Verifies tests, presents options (merge/PR/keep/discard), cleans up worktree.
白话:收尾:验证、决定合并方式、清理分支/工作区。
来源(上游 README
`https://github.com/obra/superpowers/blob/363923f74aa9cd7b470c0aaa73dee629a8bfdc90/README.md#L101`
常用配套(不在上面 7 步编号里,但非常高频):
- `systematic-debugging`:遇到错误/异常时,用系统化方式定位根因。
- `verification-before-completion`:在你说“完成了”之前,用证据证明它真的完成了。
---
## 三、技能选择速查(我实际怎么选)
我自己选 skill 很简单:先选模式,再推进。
- 不确定需求边界、方案不明确:先用 `brainstorming`
- 目标明确但步骤多:用 `writing-plans` 把执行清单写出来。
- 执行过程中卡住(构建失败/行为异常):切到 `systematic-debugging`
- 准备说“好了”:用 `verification-before-completion` 跑验证再收工。
关于加载 skill 的名字:以你当前环境输出为准。
如果你的环境里显示 `superpowers/<name>`,就带前缀加载;否则加载裸名。
本博客里我已经把 OpenCode 的安装与“场景化步骤卡片”写成两篇:
- 安装/验证/排障:`opencode-superpowers.md`
- 编码 + 写博客的步骤卡片:`opencode-skills-playbook.md`
---
## 四、安装与验证速查OpenCode 为主 + 其他平台)
### 4.1 安装(每个平台 1 个命令块)
Claude Code
```text
/plugin install superpowers@claude-plugins-official
/plugin marketplace add obra/superpowers-marketplace
/plugin install superpowers@superpowers-marketplace
```
来源:
`https://github.com/obra/superpowers/blob/363923f74aa9cd7b470c0aaa73dee629a8bfdc90/README.md#L31`
Cursor
```text
/add-plugin superpowers
```
来源:
`https://github.com/obra/superpowers/blob/363923f74aa9cd7b470c0aaa73dee629a8bfdc90/README.md#L55`
Codex
```text
Fetch and follow instructions from https://raw.githubusercontent.com/obra/superpowers/refs/heads/main/.codex/INSTALL.md
```
来源:
`https://github.com/obra/superpowers/blob/363923f74aa9cd7b470c0aaa73dee629a8bfdc90/README.md#L65`
OpenCode
```text
Fetch and follow instructions from https://raw.githubusercontent.com/obra/superpowers/refs/heads/main/.opencode/INSTALL.md
```
来源:
`https://github.com/obra/superpowers/blob/363923f74aa9cd7b470c0aaa73dee629a8bfdc90/README.md#L75`
如果你要按“手动 clone + symlink”方式装含 Windows 权限坑),直接看:`opencode-superpowers.md`
Gemini CLI
```bash
gemini extensions install https://github.com/obra/superpowers
```
来源:
`https://github.com/obra/superpowers/blob/363923f74aa9cd7b470c0aaa73dee629a8bfdc90/README.md#L85`
### 4.2 验证1 个命令块,两行)
```text
帮我做一个需求拆解,但先选择并加载一个合适的 superpowers skill 再继续。
预期:它会先进入某个 skill 的流程(提澄清问题/给计划/要求验证),而不是直接开写。
```
参考来源(上游 Verify Installation 段落):
`https://github.com/obra/superpowers/blob/363923f74aa9cd7b470c0aaa73dee629a8bfdc90/README.md#L97`
---
## 五、更新与排障(按平台)
### 5.1 更新3 个命令块)
Claude Code
```text
/plugin update superpowers
```
来源:
`https://github.com/obra/superpowers/blob/363923f74aa9cd7b470c0aaa73dee629a8bfdc90/README.md#L165`
OpenCode
```bash
cd ~/.config/opencode/superpowers
git pull
```
来源(上游 OpenCode 文档 Updating 段落):
`https://github.com/obra/superpowers/blob/363923f74aa9cd7b470c0aaa73dee629a8bfdc90/docs/README.opencode.md#L193`
更新后要彻底退出并重启 OpenCode把正在运行的 opencode 进程关掉,再重新启动)。
Gemini CLI
```bash
gemini extensions update superpowers
```
来源:
`https://github.com/obra/superpowers/blob/363923f74aa9cd7b470c0aaa73dee629a8bfdc90/README.md#L91`
Cursor通常按 Cursor 的插件更新机制自动更新;不确定时可以按“安装命令”重装一次,然后按第 4 节的验证方式确认技能会触发。
Codex通常重新执行一次上游 Codex 安装指令即可视为更新,然后按第 4 节的验证方式确认技能会触发。
### 5.2 OpenCode 常见排障入口
如果你是 OpenCode 用户,遇到下面这类问题:
- 插件似乎没加载
- skills 找不到
- Windows symlink/junction 权限报错
建议直接看我这篇的“验证与排障”段落:`opencode-superpowers.md`

View File

@@ -0,0 +1,228 @@
---
title: OpenCode + Superpowers技能插件安装与用法
icon: mdi:power-plug
date: 2026-03-16
category:
- AI
- 开发工具
tag:
- OpenCode
- Superpowers
- 插件
- Skills
redirectFrom:
- /ai/opencode-superpowers.html
- /ai/opencode-superpowers
---
# OpenCode + Superpowers技能插件安装与用法
Superpowers 是一套给 OpenCode 增强“技能skills体系”的插件与技能包
把常用的提示词/工作流封装成可复用技能,并在每次对话时自动注入必要的引导上下文。
<!-- more -->
---
## 一、它解决什么问题
在 OpenCode 里你当然可以直接对话、直接改代码;但当你需要把一套稳定的工作方式
例如代码审查、需求拆解、写作规范、某语言最佳实践复用到每个项目时skills
会更顺手。
Superpowers 主要提供:
- 一个 OpenCode 插件:启动时自动注入 superpowers 的引导上下文。
- 一组技能:通过 OpenCode 的 `skill` 工具发现/加载。
- 适配逻辑:把部分为其他代理写的技能说明,映射到 OpenCode 的工具体系。
---
## 二、快速安装(把话直接丢给 OpenCode
如果你希望“让 OpenCode 帮你完成安装”,可以直接在对话里说:
```text
Clone https://github.com/obra/superpowers to ~/.config/opencode/superpowers, then create directory ~/.config/opencode/plugins, then symlink ~/.config/opencode/superpowers/.opencode/plugins/superpowers.js to ~/.config/opencode/plugins/superpowers.js, then symlink ~/.config/opencode/superpowers/skills to ~/.config/opencode/skills/superpowers, then restart opencode.
```
你也可以按下面手动安装(更可控,适合第一次装)。
---
## 三、手动安装macOS / Linux
前置条件:
- 已安装 OpenCode
- 已安装 Git
执行:
```bash
# 1) 安装(或更新)
if [ -d ~/.config/opencode/superpowers ]; then
cd ~/.config/opencode/superpowers && git pull
else
git clone https://github.com/obra/superpowers.git ~/.config/opencode/superpowers
fi
# 2) 创建目录
mkdir -p ~/.config/opencode/plugins ~/.config/opencode/skills
# 3) 清理旧链接(重复安装时安全)
rm -f ~/.config/opencode/plugins/superpowers.js
rm -rf ~/.config/opencode/skills/superpowers
# 4) 建立链接
ln -s ~/.config/opencode/superpowers/.opencode/plugins/superpowers.js ~/.config/opencode/plugins/superpowers.js
ln -s ~/.config/opencode/superpowers/skills ~/.config/opencode/skills/superpowers
```
然后重启 OpenCode。
---
## 四、手动安装Windows
Windows 的重点在“符号链接权限”。你需要满足其一:
- 启用 Developer Mode开发者模式
- 用管理员权限运行终端。
建议优先用 PowerShell命令更清晰
### 4.1 Command Prompt管理员
```bat
:: 1) 安装
git clone https://github.com/obra/superpowers.git "%USERPROFILE%\\.config\\opencode\\superpowers"
:: 2) 创建目录
mkdir "%USERPROFILE%\\.config\\opencode\\plugins" 2>nul
mkdir "%USERPROFILE%\\.config\\opencode\\skills" 2>nul
:: 3) 清理旧链接
del "%USERPROFILE%\\.config\\opencode\\plugins\\superpowers.js" 2>nul
rmdir "%USERPROFILE%\\.config\\opencode\\skills\\superpowers" 2>nul
:: 4) 插件 symlink需要开发者模式或管理员
mklink "%USERPROFILE%\\.config\\opencode\\plugins\\superpowers.js" "%USERPROFILE%\\.config\\opencode\\superpowers\\.opencode\\plugins\\superpowers.js"
:: 5) skills 用 junction通常更稳
mklink /J "%USERPROFILE%\\.config\\opencode\\skills\\superpowers" "%USERPROFILE%\\.config\\opencode\\superpowers\\skills"
```
### 4.2 PowerShell管理员或开发者模式
```powershell
# 1) 安装
git clone https://github.com/obra/superpowers.git "$env:USERPROFILE\\.config\\opencode\\superpowers"
# 2) 创建目录
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\\.config\\opencode\\plugins" | Out-Null
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\\.config\\opencode\\skills" | Out-Null
# 3) 清理旧链接
Remove-Item "$env:USERPROFILE\\.config\\opencode\\plugins\\superpowers.js" -Force -ErrorAction SilentlyContinue
Remove-Item "$env:USERPROFILE\\.config\\opencode\\skills\\superpowers" -Force -ErrorAction SilentlyContinue
# 4) 插件 symlink
New-Item -ItemType SymbolicLink -Path "$env:USERPROFILE\\.config\\opencode\\plugins\\superpowers.js" -Target "$env:USERPROFILE\\.config\\opencode\\superpowers\\.opencode\\plugins\\superpowers.js" | Out-Null
# 5) skills junction
New-Item -ItemType Junction -Path "$env:USERPROFILE\\.config\\opencode\\skills\\superpowers" -Target "$env:USERPROFILE\\.config\\opencode\\superpowers\\skills" | Out-Null
```
---
## 五、验证安装是否成功
macOS / Linux
```bash
ls -l ~/.config/opencode/plugins/superpowers.js
ls -l ~/.config/opencode/skills/superpowers
```
WindowsCommand Prompt
```bat
dir /AL "%USERPROFILE%\\.config\\opencode\\plugins"
dir /AL "%USERPROFILE%\\.config\\opencode\\skills"
```
看到 `<SYMLINK>``<JUNCTION>` 即表示链接生效。
---
## 六、开始使用:列出并加载技能
### 6.1 列出当前可用 skills
在 OpenCode 中让它调用原生 `skill` 工具:
```text
use skill tool to list skills
```
### 6.2 加载某个技能
```text
use skill tool to load superpowers/brainstorming
```
加载后,你可以直接让它按该 skill 的工作方式来执行任务(例如:先问澄清问题、再拆
步骤、再写代码/写文档)。
---
## 七、skills 的来源与优先级(理解后更好排查)
OpenCode 会从这些位置发现 skills优先级从高到低
1. 项目内:`.opencode/skills/`
2. 个人目录:`~/.config/opencode/skills/`
3. Superpowers`~/.config/opencode/skills/superpowers/`(通常是 symlink 指向仓库里的 `skills/`
你可以把团队约定写成“项目 skill”把通用习惯写成“个人 skill”。
---
## 八、更新与常见问题
### 8.1 更新
```bash
cd ~/.config/opencode/superpowers
git pull
```
更新后重启 OpenCode。
### 8.2 插件没生效
排查顺序建议:
1. 插件文件是否存在:`~/.config/opencode/superpowers/.opencode/plugins/superpowers.js`
2. 链接是否正确:`~/.config/opencode/plugins/superpowers.js`
3. 看日志(更直接):
```bash
opencode run "test" --print-logs --log-level DEBUG
```
### 8.3 Windows 报 `Cannot find module`
常见原因是 Git Bash 下 `ln` 行为不符合预期(可能变成复制文件)。
建议直接用 `mklink` + `/J`junction按本文 Windows 安装步骤重建链接。
---
## 九、结语
如果你已经把 OpenCode 用在日常开发里Superpowers 的价值在于:
把“可复用的工作流”变成技能,并且跨项目一致。
> 参考文档(原文):
> https://github.com/obra/superpowers/blob/main/docs/README.opencode.md

View File

@@ -0,0 +1,104 @@
---
title: 远程 C++ 项目一键全量构建
icon: mdi:language-cpp
date: 2026-03-09
category:
- C++
- 后端
- Linux
tag:
- C++
- 编译
- Makefile
- SSH
---
这篇文章整理一次远程 C++ 项目编译流程:从 SSH 连接、路径核对,到将全量构建固化为 `build.sh`,把重复手工操作改成一条可复用命令。
<!-- more -->
# 远程 C++ 项目一键全量构建
## 1. 场景信息
- 目标主机:`10.6.223.0`
- 项目根目录:`/home/sunri/PRS-7950/V1.00_2024`
- C++ 源码目录:`/home/sunri/PRS-7950/V1.00_2024/src_cxx`
## 2. 先确认连接与路径
先验证 SSH 连通性:
```bash
ssh 10.6.223.0
```
连接后可用 `hostname` 确认机器身份。
这次排查中,一个关键点是目录名确认:
- 错误路径:`/home/sunri/PRS-7950/V1.00_2024/src_cx`
- 正确路径:`/home/sunri/PRS-7950/V1.00_2024/src_cxx`
编译前先核对路径,通常比盲目调整编译参数更有效。
## 3. 执行增量编译
在源码目录执行:
```bash
make -j"$(nproc)"
```
说明:
- `-j"$(nproc)"` 表示按 CPU 核心数并行编译
- 若出现 `Nothing to be done for 'first'`,通常表示该目标已是最新状态(增量构建正常现象)
## 4. 固化为一键全量构建脚本
`src_cxx` 下创建 `build.sh`
```bash
#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$SCRIPT_DIR"
echo "[build] Cleaning project..."
make clean
echo "[build] Building project (full rebuild)..."
make -j"$(nproc)"
echo "[build] Done."
```
赋予执行权限:
```bash
chmod +x build.sh
```
## 5. 日常使用方式
```bash
cd /home/sunri/PRS-7950/V1.00_2024/src_cxx
./build.sh
```
脚本固定执行两步:
1. `make clean`
2. `make -j"$(nproc)"`
## 6. 小结
这套流程的核心不是命令复杂度,而是标准化:
- 先确认路径和环境
- 再把全量构建流程脚本化
后续交付或排障时,只需要统一执行 `./build.sh` 即可降低沟通与操作成本。

View File

@@ -2,9 +2,7 @@
title: 使用 SDKMAN 管理 Java 和 Maven 多版本
icon: mdi:package-variant
date: 2026-02-04
category:
- 实用工具
- JAVA
category: JAVA
tag:
- SDKMAN
- Java
@@ -174,14 +172,39 @@ sdk enable auto_env
sdk list installed
```
### 2. 查看特定工具的所有版本
### 2. 查看特定工具的在线可用版本
```bash
sdk list java
sdk list maven
```
### 3. 卸载不需要的版本
说明:`sdk list java``sdk list maven` 展示的是远程可安装版本,不是本机已安装版本。
### 3. 查看本机已安装版本与当前生效版本
```bash
# 查看当前生效版本SDKMAN 视角)
sdk current
sdk current java
sdk current maven
# 查看命令实际生效版本(系统视角)
java -version
mvn -version
which java
which mvn
# 查看 SDKMAN 本机已安装版本目录
ls -1 ~/.sdkman/candidates/java
ls -1 ~/.sdkman/candidates/maven
# 查看 current 软链接实际指向
ls -l ~/.sdkman/candidates/java/current
ls -l ~/.sdkman/candidates/maven/current
```
### 4. 卸载不需要的版本
```bash
# 卸载 Java 11
@@ -191,13 +214,13 @@ sdk uninstall java 11.0.21-tem
sdk uninstall maven 3.8.8
```
### 4. 更新 SDKMAN
### 5. 更新 SDKMAN
```bash
sdk selfupdate
```
### 5. 查看帮助
### 6. 查看帮助
```bash
sdk help

View File

@@ -0,0 +1,603 @@
---
title: Cursor 进阶指南
icon: mdi:rocket-launch
date: 2026-02-04
category:
- 开发工具
- 前端
tag:
- Cursor
- AI编程
- 进阶技巧
- Agent
---
# Cursor 进阶指南
本指南整理自Cursor官方文档涵盖Agent模式、Composer、快捷键配置、Context管理等高级功能帮助开发者充分发挥Cursor的AI编程能力。
<!-- more -->
---
## 一、Agent 模式详解
### 1.1 Agent 是什么
Agent是Cursor的AI助手核心功能能够独立完成复杂的编码任务、执行终端命令和修改代码。通过`Cmd+I`Mac`Ctrl+I`Windows打开侧边栏Agent面板。
### 1.2 Agent 模式类型
| 模式 | 描述 | 适用场景 |
|------|------|----------|
| **Agent** | 自主决策完成复杂任务 | 大型重构、多文件修改 |
| **Composer** | 协作式生成代码 | 新功能开发、代码生成 |
| **Chat** | 对话式问答 | 问题解答、代码解释 |
### 1.3 Agent 基本用法
```bash
# 启动交互式会话
agent
# 带初始提示启动
agent "重构auth模块使用JWT认证"
# 非交互模式适合脚本和CI/CD
agent -p "Your prompt here"
# JSON输出格式
agent --print --output-format json "Your prompt here"
```
### 1.4 模式切换
- **快捷键**`Cmd+.` 快速切换模式
- **UI操作**Agent界面中的模式下拉菜单
- **自定义**:可在设置中配置模式切换快捷键
---
## 二、Composer 功能深度使用
### 2.1 Composer 核心能力
Composer是Cursor的代码生成引擎支持
- 多文件同时生成
- 智能依赖分析
- 代码一致性维护
- 上下文感知生成
### 2.2 Composer 最佳实践
```markdown
## 高效提示词结构
### 1. 明确任务目标
"创建一个用户认证模块包含登录、注册、JWT token验证"
### 2. 指定技术栈
"使用TypeScript遵循项目现有的代码风格"
### 3. 说明约束条件
"不引入新的第三方依赖使用现有的express框架"
### 4. 分步骤执行
"第一步:设计数据库模型
第二步:创建路由
第三步:实现中间件"
```
### 2.3 Composer 生成策略
| 策略 | 说明 | 使用建议 |
|------|------|----------|
| **增量生成** | 在现有代码基础上添加 | 小改动、新功能扩展 |
| **全量生成** | 创建完整的代码文件 | 新模块、复杂功能 |
| **重构生成** | 重写现有代码 | 性能优化、架构升级 |
---
## 三、快捷键配置与自定义
### 3.1 常用快捷键速查
| 功能 | Mac | Windows | 说明 |
|------|-----|---------|------|
| Agent面板 | `Cmd+I` | `Ctrl+I` | 打开AI助手 |
| Composer | `Cmd+L` | `Ctrl+L` | 代码生成 |
| Chat | `Cmd+J` | `Ctrl+J` | 对话问答 |
| Terminal | `` Cmd+` `` | `` Ctrl+` `` | 终端面板 |
| 命令面板 | `Cmd+Shift+P` | `Ctrl+Shift+P` | VS Code命令 |
| 文件搜索 | `Cmd+P` | `Ctrl+P` | 快速打开文件 |
### 3.2 自定义快捷键配置
通过`Cmd+Shift+J`打开Cursor设置进入`Keyboard Shortcuts`进行配置:
```json
{
"key": "cmd+m",
"command": "cursor.generateGitCommitMessage",
"description": "生成Git提交信息"
}
```
### 3.3 Tab 智能提示自定义
在Keyboard Shortcuts设置中搜索`Accept Cursor Tab Suggestions`,可自定义接受和拒绝建议的按键。
---
## 四、Context 管理与配置
### 4.1 Context 是什么
Context是Cursor理解项目背景的关键提供AI代码生成所需的上下文信息。
### 4.2 Context 类型
| 类型 | 描述 | 添加方式 |
|------|------|----------|
| **代码库** | 当前项目的所有代码 | 自动索引 |
| **选定代码** | 当前选中的代码片段 | 手动选择 |
| **文件** | 整个文件内容 | 拖拽或添加 |
| **URL** | 网页内容 | 粘贴链接 |
| **文档** | 项目文档、API文档 | 文件添加 |
| **Git Diff** | 代码变更对比 | 自动读取 |
### 4.3 Context 最佳实践
```markdown
## 有效提供Context的方法
### ✅ 推荐做法
- 提供清晰的代码文件
- 添加相关依赖的文档链接
- 说明代码的业务背景
- 展示期望的代码风格
### ❌ 避免做法
- 提供过多无关代码
- 缺少必要的上下文说明
- 混合不相关的功能需求
```
### 4.4 Cursor CLI Context 配置
```json
{
"version": 1,
"editor": { "vimMode": false },
"permissions": {
"allow": ["Shell(ls)", "Shell(echo)", "Read(src/**/*.ts)"],
"deny": ["Shell(rm)", "Read(.env*)"]
}
}
```
---
## 五、MCP 与 Skills 扩展
### 5.1 MCP (Model Context Protocol)
MCP是Cursor的扩展协议允许AI访问外部工具和数据源。
#### 主要功能
| 功能 | 描述 |
|------|------|
| **工具调用** | 执行外部工具操作 |
| **数据访问** | 连接外部数据源 |
| **API集成** | 调用第三方API |
#### 配置示例
```json
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": { "GITHUB_TOKEN": "your-token" }
},
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
}
}
}
```
### 5.2 Skills 自定义
Skills是Cursor的自定义技能扩展用于扩展AI能力。
#### Skills 结构
```
~/.cursor/skills/
├── skills/
│ ├── my-custom-skill/
│ │ ├── skill.json
│ │ ├── prompts.py
│ │ └── actions.py
│ └── another-skill/
└── config.json
```
#### Skill 配置示例
```json
{
"name": "database-schema-generator",
"version": "1.0.0",
"description": "根据需求生成数据库Schema",
"commands": [
{
"name": "generate-schema",
"description": "生成数据库表结构"
}
]
}
```
---
## 六、Rules 配置与个性化
### 6.1 Rules 是什么
Rules是Cursor的行为规范配置控制AI代码生成的行为、风格和限制。
### 6.2 Rules 配置位置
- **全局配置**`~/.cursor/rules/`
- **项目配置**:项目根目录`.cursor/rules/`
- **文件级别**`.cursor/rules/filename.md`
### 6.3 Rules 编写示例
```markdown
---
name: vue-style-guide
description: Vue 3 组件开发规范
scope: src/**/*.vue
---
# Vue 3 组件开发规范
## 代码风格
- 使用 `<script setup>` 语法
- 组件名使用 PascalCase
- Props 定义使用 TypeScript 接口
## 命名规范
- 组件文件PascalCase
- 组件变量camelCase
- 常量UPPER_SNAKE_CASE
## 最佳实践
- 优先使用组合式API
- Props 应该始终被验证
- 事件使用 emits 选项定义
```
### 6.4 Rules 优先级
| 位置 | 优先级 | 说明 |
|------|--------|------|
| 文件级别 | 最高 | 只对单个文件生效 |
| 项目级别 | 中 | 对整个项目生效 |
| 全局级别 | 最低 | 默认行为 |
---
## 七、API 与集成
### 7.1 Cursor API 基础
#### 认证配置
```bash
# 设置API密钥
export CURSOR_API_KEY="your-api-key"
```
#### 基础调用
```bash
# Analytics API 示例
curl -X GET "https://api.cursor.com/analytics/team/dau" \
-H "Authorization: Bearer YOUR_API_KEY"
```
### 7.2 API 最佳实践
#### 1. 分页使用
```bash
# 大团队超过100用户使用分页防止超时
curl -X GET "https://api.cursor.com/analytics/users" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d "page=1&per_page=100"
```
#### 2. 缓存策略
```bash
# 初始请求
curl -X GET "https://api.cursor.com/analytics/team/dau" \
-H "Authorization: Bearer YOUR_API_KEY" \
-D headers.txt
# 响应包含: ETag: "abc123xyz"
# 后续请求使用缓存
curl -X GET "https://api.cursor.com/analytics/team/dau" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "If-None-Match: \"abc123xyz\""
```
#### 3. 性能优化
| 优化点 | 说明 |
|--------|------|
| 合理日期范围 | 1-3个月为最佳 |
| 用户过滤 | 使用users参数减少查询 |
| ETag缓存 | 减少不必要的数据传输 |
| 批量请求 | 合并多个API调用 |
---
## 八、终端与 Agent 集成
### 8.1 终端环境配置
#### Zsh 配置优化
```zsh
# ~/.zshrc — 当Cursor Agent运行时禁用Powerlevel10k主题
if [[ -n "$CURSOR_AGENT" ]]; then
# 跳过主题初始化以获得更好兼容性
else
[[ -r ~/.p10k.zsh ]] && source ~/.p10k.zsh
fi
```
### 8.2 Agent 终端权限
```json
{
"permissions": {
"allow": [
"Shell(ls)",
"Shell(git)",
"Shell(npm run *)",
"Read(src/**/*.ts)",
"Write(package.json)"
],
"deny": [
"Shell(rm -rf *)",
"Read(.env*)",
"Write(**/*.key)"
]
}
}
```
---
## 九、从 VS Code 迁移
### 9.1 一键导入
1. 打开Cursor设置 (`Cmd+Shift+J`)
2. 进入 `General > Account`
3. 在"VS Code Import"下点击Import按钮
### 9.2 导入内容
| 项目 | 说明 |
|------|------|
| 设置 | 编辑器配置、主题 |
| 扩展 | 已安装的插件 |
| 快捷键 | 键盘映射 |
| 代码片段 | Snippets |
### 9.3 手动迁移项目
```bash
# 在Cursor中打开VS Code项目目录
cd /path/to/vscode/project
cursor .
```
---
## 十、高级技巧与最佳实践
### 10.1 高效提示词技巧
```markdown
## 结构化提示词模板
### 任务描述
[简要说明要做什么]
### 上下文
[提供相关的代码和文档]
### 要求
1. [具体要求1]
2. [具体要求2]
3. [具体要求3]
### 约束
- [限制条件1]
- [限制条件2]
### 期望输出
[描述期望的代码风格和结构]
```
### 10.2 Agent 模式选择
| 场景 | 推荐模式 | 原因 |
|------|----------|------|
| 理解代码逻辑 | Chat | 交互式问答 |
| 新功能开发 | Composer | 代码生成 |
| 复杂重构 | Agent | 自主决策 |
| Bug修复 | Agent + Chat | 分析+修复 |
### 10.3 性能优化建议
```markdown
## 提升响应速度
### 1. 精简Context
- 只添加相关文件
- 避免过大的文件
- 使用文件摘要而非全文
### 2. 明确任务范围
- 分解复杂任务为小步骤
- 避免模糊的指令
- 提供具体示例
### 3. 利用Rules
- 定义项目代码规范
- 配置常用代码模式
- 减少重复说明
```
### 10.4 常见问题解决
| 问题 | 解决方案 |
|------|----------|
| AI回答不准确 | 提供更多上下文 |
| 生成代码有误 | 指定代码风格Rules |
| 响应速度慢 | 精简Context范围 |
| 格式错误 | 使用代码块标记 |
---
## 十一、Git 集成
### 11.1 提交信息生成
配置快捷键生成Git提交信息
```json
{
"key": "cmd+m",
"command": "cursor.generateGitCommitMessage"
}
```
### 11.2 代码审查辅助
- 使用Agent分析代码变更
- 生成审查报告
- 建议改进方案
---
## 十二、CLI 高级用法
### 12.1 非交互式使用
```bash
# 管道输入
echo "修复登录bug" | agent -p --print
# 脚本集成
#!/bin/bash
agent -p "在第$LINE行添加日志" --print
```
### 12.2 输出格式控制
| 格式 | 用途 |
|------|------|
| `text` | 可读文本(默认) |
| `json` | 程序处理 |
| `stream-json` | 流式JSON |
```bash
agent --print --output-format json "Your prompt"
```
---
## 十三、团队协作
### 13.1 共享配置
| 配置项 | 共享方式 |
|--------|----------|
| Rules | 提交到代码仓库 |
| Settings | Settings Sync |
| 快捷键 | 导出JSON分享 |
### 13.2 团队最佳实践
```markdown
## 团队Cursor配置建议
### 1. 统一代码规范
- 创建项目级Rules
- 定义代码风格指南
- 配置导入规则
### 2. 共享快捷键
- 统一常用操作快捷键
- 避免冲突
- 文档化自定义快捷键
### 3. Agent模式规范
- 定义使用场景
- 明确审批流程
- 代码审查标准
```
---
## 十四、资源与支持
### 14.1 官方资源
| 资源 | 链接 |
|------|------|
| 官网 | cursor.com |
| 文档 | docs.cursor.com |
| 社区 | forum.cursor.com |
| GitHub | github.com/cursor |
### 14.2 学习路径
```
入门 → 进阶 → 专家
↓ ↓ ↓
基础 Agent 团队
用法 Rules 规模化
配置 MCP 定制化
```
---
## 十五、总结
1. **Agent模式**:根据任务复杂度选择合适的模式
2. **Context管理**:精准提供上下文信息
3. **Rules配置**:定义项目代码规范
4. **快捷键优化**:提升工作效率
5. **团队协作**:标准化配置共享
6. **持续学习**:关注官方文档更新
---
> 最后更新2026年2月
> 参考文档cursor.com/docs

View File

@@ -0,0 +1,210 @@
---
title: VSCode 进阶:命令面板工作流与配置治理
icon: simple-icons:visualstudiocode
date: 2026-03-30
category:
- 开发工具
- 前端
tag:
- VSCode
- 命令面板
- settings.json
- keybindings.json
- Windows
- Linux
---
# VSCode 进阶:命令面板工作流与配置治理
这篇是入门篇的下一步,目标是把 VSCode 从“会用”升级到“高效、可维护”。
重点只讲三块:
1. 命令面板的进阶工作流
2. 配置文件分层治理User / Workspace / Profile
3. 可复用的进阶 JSON 模板
<!-- more -->
## 1. 命令面板进阶:把常用动作变成肌肉记忆
命令面板入口不变:`Ctrl + Shift + P`Windows / Linux
建议只记住下面这组高频命令:
1. `>Preferences: Open User Settings (JSON)`
2. `>Preferences: Open Workspace Settings (JSON)`
3. `>Preferences: Open Keyboard Shortcuts (JSON)`
4. `>Tasks: Configure Task`
5. `>Developer: Reload Window`
6. `>Profiles: Create Profile`
7. `>Extensions: Show Installed Extensions`
实战思路:遇到任何需求,先用命令面板搜“动词 + 目标”,比如 `open settings json``create profile`
## 2. 配置治理模型:谁该放在哪里
### 2.1 User settings全局
- Windows: `%APPDATA%\\Code\\User\\settings.json`
- Linux: `~/.config/Code/User/settings.json`
放“个人偏好”:字体、自动保存、终端默认 shell、编辑体验。
### 2.2 Workspace settings项目
- 项目路径:`.vscode/settings.json`
放“项目约束”:缩进、格式化策略、特定语言规则、排除目录。
### 2.3 Profile场景
Profile 适合“多工作模式”用户,例如:
- `Frontend`:前端开发扩展 + 偏好
- `Backend`:后端开发扩展 + 偏好
- `Minimal`:低干扰写作/阅读模式
建议:
- 固定偏好放 User
- 项目规范放 Workspace
- 场景差异放 Profile
## 3. keybindings.json给命令面板加速
打开方式:
- `Ctrl + Shift + P`
- 输入 `Open Keyboard Shortcuts (JSON)`
示例Windows / Linux 通用):
```json
[
{
"key": "ctrl+alt+r",
"command": "workbench.action.reloadWindow"
},
{
"key": "ctrl+alt+,",
"command": "workbench.action.openSettingsJson"
},
{
"key": "ctrl+alt+t",
"command": "workbench.action.tasks.runTask"
}
]
```
注意如果快捷键冲突VSCode 会以后定义或更具体 `when` 条件为准。
## 4. 进阶 settings.json 模板Windows + Linux
下面模板建议放在 User 级,并按你环境微调:
```json
{
"editor.fontSize": 14,
"editor.lineHeight": 1.7,
"editor.tabSize": 2,
"editor.wordWrap": "on",
"editor.minimap.enabled": false,
"editor.bracketPairColorization.enabled": true,
"files.autoSave": "onFocusChange",
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"files.watcherExclude": {
"**/.git/objects/**": true,
"**/node_modules/**": true,
"**/dist/**": true
},
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "explicit"
},
"terminal.integrated.defaultProfile.windows": "PowerShell",
"terminal.integrated.defaultProfile.linux": "bash",
"workbench.startupEditor": "none",
"workbench.editor.enablePreview": false,
"workbench.tree.indent": 16
}
```
如果你不用 Prettier`editor.defaultFormatter` 改成你实际使用的扩展 ID。
## 5. Workspace 模板:把项目规范写死
建议每个项目都放一个最小 `.vscode/settings.json`
```json
{
"editor.tabSize": 2,
"editor.insertSpaces": true,
"editor.detectIndentation": false,
"files.eol": "\n"
}
```
这样团队成员打开项目时,基础编辑行为就能统一。
## 6. 命令面板 + Task一键执行项目动作
进阶建议:把常用命令(如构建、测试)写进 Task再通过命令面板触发。
`.vscode/tasks.json` 示例:
```json
{
"version": "2.0.0",
"tasks": [
{
"label": "docs:build",
"type": "shell",
"command": "npm run docs:build",
"group": "build",
"problemMatcher": []
}
]
}
```
触发方式:
1. `Ctrl + Shift + P`
2. 输入 `Run Task`
3. 选择 `docs:build`
## 7. 常见坑与排查
### 7.1 改了配置却没生效
先执行 `Developer: Reload Window`,再验证。
### 7.2 User 和 Workspace 打架
按“项目优先”原则,检查 `.vscode/settings.json` 是否覆盖了 User。
### 7.3 JSON 报错
确保:
- 不要尾逗号
- 全部键名和字符串使用双引号
- 文件是合法 JSON不是 JSONC 风格时不要写注释)
## 8. 进阶完成标准
- [ ] 能通过命令面板完成设置、任务、重载
- [ ] 能区分 User / Workspace / Profile 三层职责
- [ ] 有自己的 `keybindings.json` 高频快捷键
- [ ] 有项目级 `.vscode/settings.json` 规范
- [ ] 能用 `tasks.json` 一键触发常用命令
做到这 5 点VSCode 就从“编辑器”变成你的“稳定开发操作台”。

View File

@@ -0,0 +1,180 @@
---
title: VSCode 使用入门:命令面板与 settings.json
icon: simple-icons:visualstudiocode
date: 2026-03-30
category:
- 开发工具
- 前端
tag:
- VSCode
- 命令面板
- settings.json
- Windows
- Linux
---
# VSCode 使用入门:命令面板与 settings.json
这是一篇极速 15 分钟上手指南,重点只讲三件事:
1. VSCode 的基本概念
2. 命令面板怎么高频使用
3. 不进图形化设置,直接改 `settings.json`
<!-- more -->
## 1. 先认识 4 个核心概念
### 1.1 编辑器 vs 工作区
- **编辑器**:你看到和编辑代码的窗口。
- **工作区Workspace**:当前打开的项目(一个或多个文件夹)。
### 1.2 配置分层(最重要)
VSCode 的设置是分层生效的:
1. **默认设置Default**VSCode 内置。
2. **用户设置User**:你机器上的全局偏好。
3. **工作区设置Workspace**:只对当前项目生效。
如果同一个键同时存在,通常是 `Workspace` 覆盖 `User`
### 1.3 命令面板Command Palette
命令面板是 VSCode 的“统一入口”。
- Windows/Linux`Ctrl + Shift + P`
- 也可按 `F1`
你可以在这里执行几乎所有操作,包括打开 JSON 配置。
### 1.4 扩展不是“额外功能”,而是能力层
VSCode 本体很轻,很多语言能力来自扩展。
但本篇先不讲扩展安装,先把命令面板和配置体系打通。
## 2. 命令面板:先会这 6 条命令
`Ctrl + Shift + P` 后直接输入:
1. `>` + `Reload Window`:重载窗口,配置变更后常用。
2. `>Developer: Reload Window`:同上,完整命令名。
3. `>Preferences: Open User Settings (JSON)`:打开全局配置。
4. `>Preferences: Open Workspace Settings (JSON)`:打开项目配置。
5. `>Preferences: Open Default Settings (JSON)`:查看默认值(只读参考)。
6. `>Files: Auto Save`:快速切自动保存策略。
技巧:命令面板支持模糊搜索,你记不全命令名也能找到。
## 3. settings.json 到底放哪
### 3.1 用户配置(全局)
- Windows: `%APPDATA%\\Code\\User\\settings.json`
- Linux: `~/.config/Code/User/settings.json`
建议:全局偏好(字体、自动保存、格式化默认行为)放这里。
### 3.2 工作区配置(项目级)
- 项目根目录:`.vscode/settings.json`
建议:和项目强相关的配置放这里(例如某项目缩进、格式化器、排除目录)。
## 4. 用命令面板打开 JSON 配置(不进图形设置)
### 4.1 打开用户配置
1. `Ctrl + Shift + P`
2. 输入 `Open User Settings (JSON)`
3. 回车
### 4.2 打开工作区配置
1. `Ctrl + Shift + P`
2. 输入 `Open Workspace Settings (JSON)`
3. 回车
如果项目里没有 `.vscode/settings.json`VSCode 会帮你创建。
## 5. 可直接粘贴的入门模板
下面这份建议先放在 **User settings.json**,适用于 Windows + Linux。
```json
{
"editor.fontSize": 14,
"editor.tabSize": 2,
"editor.wordWrap": "on",
"editor.minimap.enabled": false,
"files.autoSave": "onFocusChange",
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll": "explicit"
},
"terminal.integrated.defaultProfile.windows": "PowerShell",
"terminal.integrated.defaultProfile.linux": "bash",
"files.exclude": {
"**/.DS_Store": true,
"**/node_modules": true,
"**/.git": false
}
}
```
说明:
- `formatOnSave` 依赖你安装并启用对应语言的格式化扩展。
- `source.fixAll` 设为 `explicit` 更稳,避免每次保存都触发过多修复。
- `terminal.integrated.defaultProfile.*` 按你的本机实际 shell 调整。
## 6. User 与 Workspace 怎么分
推荐这套规则:
-`User`:你个人习惯,跨项目都想保留。
-`Workspace`:只在当前项目生效的规则。
示例:某项目要求 4 空格缩进,就写到该项目 `.vscode/settings.json`
```json
{
"editor.tabSize": 4,
"editor.insertSpaces": true
}
```
## 7. 常见问题JSON 配置方式)
### 7.1 配置不生效
`Ctrl + Shift + P` 执行 `Developer: Reload Window`,再验证。
### 7.2 JSON 报错(逗号、引号)
`settings.json` 必须是合法 JSON。重点检查
- 最后一项后面不要多逗号
- 键名和字符串值要用双引号
### 7.3 不确定某个键该写什么
用命令面板打开 `Default Settings (JSON)` 搜索对应键,按默认文档写。
## 8. 15 分钟上手清单
- [ ] 会用 `Ctrl + Shift + P` 打开命令面板
- [ ] 会打开 `User Settings (JSON)`
- [ ] 会打开 `Workspace Settings (JSON)`
- [ ] 能区分 User 与 Workspace 的生效范围
- [ ] 粘贴并调整一份可用的 `settings.json`
- [ ] 配置不生效时会执行 `Reload Window`
完成以上 6 项,你已经跨过 VSCode 入门阶段。

View File

@@ -338,3 +338,73 @@ sudo iptables -A INPUT -p tcp --dport 48080 -j DROP
> 这是在类似"只能通过某台中间机访问 SVN"情况下的最佳实践。
---
## 十一 SVN 仓库地址变更Relocate
当 SVN 服务器地址发生变化(如 IP 变更、端口变更或域名变更)时,需要使用 `svn relocate` 命令更新本地工作副本的仓库地址,而无需重新检出代码。
### 11.1 使用命令行 Relocate
如果你习惯使用终端CMD, PowerShell, Bash可以使用 `svn relocate` 命令。
**步骤**
1. 打开终端,`cd` 进入你的项目目录
2. 执行以下命令:
```bash
svn relocate https://10.6.220.216:48080/svn/houtai/ https://10.6.221.149:48080/svn/houtai/
```
**参数说明**
- 第一个 URL旧的仓库地址
- 第二个 URL新的仓库地址
或者,如果你已经在项目根目录下,通常只需要简写新地址:
```bash
svn relocate https://10.6.221.149:48080/svn/houtai/
```
### 11.2 验证 Relocate 是否成功
```bash
svn info
```
查看输出中的 `URL:` 字段是否已更新为新地址。
### 11.3 IDEA 中 Relocate
如果你使用 IntelliJ IDEA
1. 打开项目,点击菜单 `VCS``Subversion``Relocate`
2. 在弹出的对话框中:
- **From URL**:旧地址
- **To URL**:新地址
3. 点击 **OK** 完成切换
### 11.4 注意事项
| 注意点 | 说明 |
| :--- | :--- |
| **先提交本地修改** | relocate 前确保没有未提交的更改,避免冲突 |
| **备份工作副本** | 重要项目建议先备份,防止意外 |
| **检查权限** | 新地址需要相同的 SVN 认证权限 |
| **SSL 证书** | 如果新地址证书不同,需要重新信任 |
| **Relocate vs Switch** | Relocate 用于服务器地址变更Switch 用于在同一仓库内切换分支 |
### 11.5 常见问题
**Q: 提示 "Repository UUID mismatch"**
A: 表示新旧地址指向的仓库不是同一个。确认地址是否正确,或者是否需要重新检出。
**Q: Relocate 后无法更新?**
A: 检查:
- 新地址是否可访问
- 认证信息是否正确
- 防火墙是否放行了新端口
---

View File

@@ -0,0 +1,104 @@
#!/bin/bash
# Swap空间扩展脚本
# 将 /swapfile 从 8GB 扩展到 24GB
set -e # 遇到错误立即退出
echo "=========================================="
echo "Swap空间扩展脚本"
echo "=========================================="
echo ""
# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# 检查是否有sudo权限
if ! sudo -n true 2>/dev/null; then
echo -e "${YELLOW}此脚本需要sudo权限请输入密码${NC}"
fi
echo "步骤 1/7: 显示当前swap状态"
echo "----------------------------------------"
swapon --show
free -h
echo ""
read -p "确认要继续吗这将临时关闭swap空间 (y/n): " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${RED}操作已取消${NC}"
exit 1
fi
echo ""
echo "步骤 2/7: 关闭现有 /swapfile"
echo "----------------------------------------"
sudo swapoff /swapfile
echo -e "${GREEN}✓ 已关闭 /swapfile${NC}"
echo ""
echo "步骤 3/7: 删除旧的 swapfile"
echo "----------------------------------------"
sudo rm /swapfile
echo -e "${GREEN}✓ 已删除旧文件${NC}"
echo ""
echo "步骤 4/7: 创建新的 24GB swapfile"
echo "----------------------------------------"
echo "使用 fallocate 快速创建约需10-30秒..."
sudo fallocate -l 24G /swapfile
echo -e "${GREEN}✓ 已创建 24GB swapfile${NC}"
echo ""
echo "步骤 5/7: 设置文件权限"
echo "----------------------------------------"
sudo chmod 600 /swapfile
echo -e "${GREEN}✓ 权限已设置为 600${NC}"
echo ""
echo "步骤 6/7: 格式化为swap"
echo "----------------------------------------"
sudo mkswap /swapfile
echo -e "${GREEN}✓ 格式化完成${NC}"
echo ""
echo "步骤 7/7: 启用新的swapfile"
echo "----------------------------------------"
sudo swapon /swapfile
echo -e "${GREEN}✓ 已启用新的swapfile${NC}"
echo ""
echo "=========================================="
echo "扩展完成当前swap状态"
echo "=========================================="
swapon --show
echo ""
free -h
echo ""
# 检查 /etc/fstab 配置
echo "----------------------------------------"
echo "检查 /etc/fstab 配置..."
echo "----------------------------------------"
if grep -q "^/swapfile" /etc/fstab; then
echo -e "${GREEN}✓ /etc/fstab 已包含 swapfile 配置${NC}"
else
echo -e "${YELLOW}⚠ /etc/fstab 中未找到 swapfile 配置${NC}"
read -p "是否添加到 /etc/fstab 以确保重启后生效?(y/n): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
echo -e "${GREEN}✓ 已添加到 /etc/fstab${NC}"
fi
fi
echo ""
echo "=========================================="
echo -e "${GREEN}所有操作完成!${NC}"
echo "=========================================="
echo "总Swap空间: ~31GB (24GB swapfile + 7.3GB zram)"
echo ""

View File

@@ -0,0 +1,166 @@
#!/bin/bash
# 内存策略优化脚本
# 1. 调整 swappiness 到 40
# 2. 安装并启用 earlyoom
set -e
echo "=========================================="
echo "内存策略优化脚本"
echo "=========================================="
echo ""
# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m'
# 检查sudo权限
if ! sudo -n true 2>/dev/null; then
echo -e "${YELLOW}此脚本需要sudo权限请输入密码${NC}"
fi
echo -e "${BLUE}优化项目:${NC}"
echo "1. 调整 vm.swappiness 从 10 到 40"
echo " - 更好地利用高性能zram"
echo " - 释放更多物理内存给活跃进程"
echo ""
echo "2. 安装 earlyoom"
echo " - 防止系统因内存耗尽而卡死"
echo " - 内存不足时提前终止占用最多的进程"
echo ""
read -p "确认要继续吗?(y/n): " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${RED}操作已取消${NC}"
exit 1
fi
echo ""
echo "=========================================="
echo "优化 1/2: 调整 swappiness"
echo "=========================================="
echo ""
echo "当前 swappiness 值:"
sysctl vm.swappiness
echo ""
echo "步骤 1: 临时调整 swappiness 到 40"
echo "----------------------------------------"
sudo sysctl vm.swappiness=40
echo -e "${GREEN}✓ 临时调整完成(立即生效)${NC}"
echo ""
echo "步骤 2: 永久保存配置"
echo "----------------------------------------"
# 备份配置文件
if [ -f /etc/sysctl.conf ]; then
sudo cp /etc/sysctl.conf /etc/sysctl.conf.backup.$(date +%Y%m%d_%H%M%S)
echo -e "${GREEN}✓ 已备份 /etc/sysctl.conf${NC}"
fi
# 更新或添加 swappiness 配置
if grep -q "^vm.swappiness" /etc/sysctl.conf; then
sudo sed -i 's/^vm.swappiness=.*/vm.swappiness=40/' /etc/sysctl.conf
echo -e "${GREEN}✓ 已更新 /etc/sysctl.conf 中的 swappiness${NC}"
else
echo "vm.swappiness=40" | sudo tee -a /etc/sysctl.conf > /dev/null
echo -e "${GREEN}✓ 已添加 swappiness 配置到 /etc/sysctl.conf${NC}"
fi
echo ""
echo "验证配置:"
sysctl vm.swappiness
grep "vm.swappiness" /etc/sysctl.conf
echo ""
echo "=========================================="
echo "优化 2/2: 安装 earlyoom"
echo "=========================================="
echo ""
# 检查是否已安装
if dpkg -l | grep -q "^ii.*earlyoom"; then
echo -e "${YELLOW}⚠ earlyoom 已安装${NC}"
ALREADY_INSTALLED=true
else
echo "步骤 1: 安装 earlyoom"
echo "----------------------------------------"
sudo apt update
sudo apt install -y earlyoom
echo -e "${GREEN}✓ earlyoom 安装完成${NC}"
echo ""
ALREADY_INSTALLED=false
fi
echo "步骤 2: 配置 earlyoom"
echo "----------------------------------------"
# 创建配置文件
sudo tee /etc/default/earlyoom > /dev/null <<'EOF'
# earlyoom configuration
# Minimum available memory (in percent)
# Kill processes when available memory drops below this
EARLYOOM_ARGS="-m 5 -s 10 --avoid '(^|/)(init|systemd|Xorg|sshd)$' --prefer '(^|/)(java|chrome|firefox|vmware)$'"
# -m 5: Kill when available memory < 5%
# -s 10: Kill when swap free < 10%
# --avoid: Never kill these critical processes
# --prefer: Prefer to kill these memory-hungry processes
EOF
echo -e "${GREEN}✓ 已配置 earlyoom${NC}"
echo ""
echo "配置内容:"
cat /etc/default/earlyoom
echo ""
echo "步骤 3: 启用并启动 earlyoom 服务"
echo "----------------------------------------"
sudo systemctl enable earlyoom
sudo systemctl restart earlyoom
sleep 1
echo -e "${GREEN}✓ earlyoom 服务已启动${NC}"
echo ""
echo "服务状态:"
sudo systemctl status earlyoom --no-pager -l
echo ""
echo "=========================================="
echo -e "${GREEN}优化完成!${NC}"
echo "=========================================="
echo ""
echo -e "${BLUE}优化结果总结:${NC}"
echo ""
echo "1. ✅ swappiness 已调整到 40"
echo " - 当前值: $(sysctl -n vm.swappiness)"
echo " - 配置文件: /etc/sysctl.conf"
echo " - 重启后自动生效"
echo ""
echo "2. ✅ earlyoom 已安装并运行"
echo " - 服务状态: $(systemctl is-active earlyoom)"
echo " - 内存阈值: 可用内存 < 5% 时触发"
echo " - Swap阈值: 可用swap < 10% 时触发"
echo ""
echo -e "${BLUE}当前内存状态:${NC}"
free -h
echo ""
echo -e "${BLUE}预期效果:${NC}"
echo "✓ 系统会更积极地使用高性能zram"
echo "✓ 物理内存得到更好的利用"
echo "✓ 内存不足时earlyoom会提前介入"
echo "✓ 避免系统因内存耗尽而卡死"
echo ""
echo -e "${GREEN}所有优化已完成!${NC}"
echo ""

View File

@@ -0,0 +1,145 @@
#!/bin/bash
# 纯zram Swap配置脚本
# 禁用文件swap使用zram作为唯一swap
set -e
echo "=========================================="
echo "纯zram Swap配置脚本"
echo "=========================================="
echo ""
# 颜色定义
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m'
# 检查sudo权限
if ! sudo -n true 2>/dev/null; then
echo -e "${YELLOW}此脚本需要sudo权限请输入密码${NC}"
fi
echo "当前swap状态"
echo "----------------------------------------"
swapon --show
free -h
zramctl
echo ""
echo -e "${BLUE}配置说明:${NC}"
echo "- 将zram从25%提升到80%物理内存约23GB"
echo "- 禁用文件swap (/swapfile)"
echo "- 使用zstd压缩算法压缩比约3-4倍"
echo "- 预计可用swap空间70-90GB压缩后"
echo ""
read -p "确认要继续吗?(y/n): " -n 1 -r
echo ""
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${RED}操作已取消${NC}"
exit 1
fi
echo ""
echo "步骤 1/6: 关闭所有swap"
echo "----------------------------------------"
sudo swapoff -a
echo -e "${GREEN}✓ 已关闭所有swap${NC}"
echo ""
echo "步骤 2/6: 备份zram配置"
echo "----------------------------------------"
sudo cp /etc/default/zramswap /etc/default/zramswap.backup.$(date +%Y%m%d_%H%M%S)
echo -e "${GREEN}✓ 已备份到 /etc/default/zramswap.backup.*${NC}"
echo ""
echo "步骤 3/6: 更新zram配置"
echo "----------------------------------------"
sudo tee /etc/default/zramswap > /dev/null <<'EOF'
# Compression algorithm selection
# zstd provides best compression ratio
ALGO=zstd
# Use 80% of physical RAM for zram
# With ~30GB RAM, this gives ~24GB zram
# With 3-4x compression, effective swap: 70-90GB
PERCENT=80
# Higher priority than file-based swap
PRIORITY=100
EOF
echo -e "${GREEN}✓ 已更新配置80% RAM, zstd算法${NC}"
cat /etc/default/zramswap
echo ""
echo "步骤 4/6: 重启zram服务"
echo "----------------------------------------"
sudo systemctl restart zramswap.service
sleep 2
echo -e "${GREEN}✓ zram服务已重启${NC}"
echo ""
echo "步骤 5/6: 禁用文件swap"
echo "----------------------------------------"
if [ -f /swapfile ]; then
# 从fstab中注释掉swapfile
if grep -q "^/swapfile" /etc/fstab; then
sudo sed -i.backup 's|^/swapfile|#/swapfile|' /etc/fstab
echo -e "${GREEN}✓ 已在 /etc/fstab 中禁用 /swapfile${NC}"
fi
read -p "是否删除 /swapfile 文件以释放磁盘空间?(y/n): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
sudo rm /swapfile
echo -e "${GREEN}✓ 已删除 /swapfile (释放8GB磁盘空间)${NC}"
else
echo -e "${YELLOW}⚠ 保留 /swapfile 文件${NC}"
fi
else
echo -e "${YELLOW}⚠ 未找到 /swapfile${NC}"
fi
echo ""
echo "步骤 6/6: 验证配置"
echo "----------------------------------------"
echo ""
echo "Swap设备列表"
swapon --show
echo ""
echo "内存状态:"
free -h
echo ""
echo "zram详细信息"
zramctl
echo ""
# 计算压缩比
ZRAM_INFO=$(zramctl --raw --noheadings)
DISKSIZE=$(echo "$ZRAM_INFO" | awk '{print $3}')
DATA=$(echo "$ZRAM_INFO" | awk '{print $4}')
COMPR=$(echo "$ZRAM_INFO" | awk '{print $5}')
echo "=========================================="
echo -e "${GREEN}配置完成!${NC}"
echo "=========================================="
echo ""
echo -e "${BLUE}zram统计信息${NC}"
echo "- 分配大小: $DISKSIZE"
echo "- 实际数据: $DATA"
echo "- 压缩后: $COMPR"
if [ ! -z "$DATA" ] && [ ! -z "$COMPR" ]; then
echo "- 当前压缩比: 约 $(echo "$DATA $COMPR" | awk '{printf "%.1f", $1/$2}'):1"
fi
echo ""
echo -e "${BLUE}优势:${NC}"
echo "✓ 性能内存级swap比文件swap快100倍+"
echo "✓ 寿命无磁盘写入延长SSD寿命"
echo "✓ 容量压缩后可提供70-90GB有效swap空间"
echo "✓ 效率zstd算法提供最佳压缩比"
echo ""
echo -e "${YELLOW}注意:重启后配置自动生效${NC}"
echo ""

View File

@@ -0,0 +1,209 @@
---
title: Linux Mint XFCE 终端常用快捷指令完全指南
icon: simple-icons:linuxmint
date: 2026-03-30
category:
- Linux
tag:
- Linux Mint
- XFCE
- 终端
- 快捷键
- 效率提升
---
# Linux Mint XFCE 终端常用快捷指令完全指南
XFCE 终端是 Linux Mint XFCE 桌面环境默认的命令行工具,熟练掌握其快捷键可以极大提升工作效率。本文整理了最实用的 XFCE 终端快捷键,涵盖导航、编辑、显示调整等各个方面,帮助你更高效地使用终端。
<!-- more -->
## 一、基础导航类快捷键
### 1.1 标签页管理
| 快捷键 | 功能描述 | 使用场景 |
|--------|----------|----------|
| `Ctrl+Shift+T` | 新建标签页 | 需要同时运行多个命令时 |
| `Ctrl+PgUp` / `Ctrl+PgDown` | 切换到上一个/下一个标签页 | 在多个标签页间快速切换 |
| `Alt+数字键` | 切换到指定序号标签页 | 直接跳转到特定标签页 |
| `Ctrl+Shift+W` | 关闭当前标签页 | 清理不再需要的终端会话 |
| `Ctrl+Shift+R` | 重命名当前标签页 | 为标签页设置描述性名称 |
### 1.2 窗口管理
| 快捷键 | 功能描述 | 使用场景 |
|--------|----------|----------|
| `Ctrl+Shift+N` | 新建终端窗口 | 需要独立的终端窗口 |
| `Ctrl+Shift+O` | 水平分割窗口 | 同时查看或操作多个内容 |
| `Ctrl+Shift+E` | 垂直分割窗口 | 并排对比或操作 |
| `Ctrl+Shift+Q` | 关闭终端窗口 | 退出终端应用程序 |
### 1.3 滚动与导航
| 快捷键 | 功能描述 | 使用场景 |
|--------|----------|----------|
| `Shift+PgUp` / `Shift+PgDown` | 向上/向下滚动页面 | 查看历史输出内容 |
| `Ctrl+Shift+K` | 清除终端内容 | 清理终端界面 |
| `Ctrl+Shift+F` | 查找文本 | 在终端输出中搜索内容 |
## 二、编辑操作类快捷键
### 2.1 基础移动快捷键
| 快捷键 | 功能描述 | 使用场景 |
|--------|----------|----------|
| `Ctrl + A` | 回到行首 | 快速定位到命令开头修改 |
| `Ctrl + E` | 回到行尾 | 快速定位到命令结尾补充参数 |
| `Ctrl + B` / 左箭头 | 向左移动一个字符 | 字符级微调光标位置 |
| `Ctrl + F` / 右箭头 | 向右移动一个字符 | 字符级微调光标位置 |
| `Alt + B` | 向左移动一个单词 | 快速按单词跳转编辑长命令 |
| `Alt + F` | 向右移动一个单词 | 快速按单词跳转编辑长命令 |
| `Esc + B` | 向左移动一个单词 | Alt+B被终端菜单抢占时的替代方案 |
| `Esc + F` | 向右移动一个单词 | Alt+F被终端菜单抢占时的替代方案 |
### 2.2 删除快捷键
| 快捷键 | 功能描述 | 使用场景 |
|--------|----------|----------|
| `Ctrl + U` | 删除到行首 | 快速清空当前输入的命令 |
| `Ctrl + K` | 删除到行尾 | 删除光标后面不需要的内容 |
| `Ctrl + W` | 删除前一个单词 | 快速删除最近输入的错误单词 |
| `Ctrl + D` | 删除当前字符 | 删除光标下的字符 |
| `Backspace` | 删除前一个字符 | 常规删除操作 |
### 2.3 历史命令操作
| 快捷键 | 功能描述 | 使用场景 |
|--------|----------|----------|
| `上/下箭头` | 浏览命令历史 | 重复执行之前的命令 |
| `Ctrl + R` | 反向搜索历史命令 | 快速查找之前执行过的命令 |
| `Ctrl + G` | 退出历史搜索模式 | 取消历史搜索返回正常输入 |
### 2.4 文本选择与操作
| 快捷键 | 功能描述 | 使用场景 |
|--------|----------|----------|
| `Ctrl+Shift+C` | 复制选中文本 | 复制终端中的命令或输出 |
| `Ctrl+Shift+V` | 粘贴剪贴板内容 | 粘贴命令或文本到终端 |
| `Ctrl+Shift+A` | 全选当前行 | 快速复制整行内容 |
| `Ctrl+Shift+左/右箭头` | 按单词移动光标 | 快速编辑长命令 |
### 2.5 查找与替换
| 快捷键 | 功能描述 | 使用场景 |
|--------|----------|----------|
| `Ctrl+Shift+F` | 打开查找对话框 | 在终端内容中搜索文本 |
| `F3` | 查找下一个匹配项 | 继续搜索相同内容 |
| `Shift+F3` | 查找上一个匹配项 | 反向搜索匹配项 |
## 三、显示调整类快捷键
### 3.1 字体与缩放
| 快捷键 | 功能描述 | 使用场景 |
|--------|----------|----------|
| `Ctrl+加号 (+)` | 放大字体 | 改善可读性 |
| `Ctrl+减号 (-)` | 缩小字体 | 显示更多内容 |
| `Ctrl+0` | 重置字体大小 | 恢复默认设置 |
### 3.2 配色方案与透明度
| 快捷键 | 功能描述 | 使用场景 |
|--------|----------|----------|
| `F11` | 全屏切换 | 专注于终端操作 |
| `Ctrl+Shift+I` | 切换光标形状 | 适应个人偏好 |
| `Ctrl+Shift+G` | 切换全局菜单 | 节省屏幕空间 |
> 💡 **小贴士**:可以自定义配色方案,前往 "编辑" → "首选项" → "外观" 设置自己喜欢的主题颜色。
## 四、高级功能类快捷键
### 4.1 书签管理
| 快捷键 | 功能描述 | 使用场景 |
|--------|----------|----------|
| `Ctrl+Shift+B` | 添加当前目录为书签 | 快速访问常用目录 |
| `Ctrl+B` | 打开书签管理器 | 跳转到已保存的书签 |
| `F2` | 编辑当前标签页书签 | 更新书签信息 |
### 4.2 布局与多列显示
| 快捷键 | 功能描述 | 使用场景 |
|--------|----------|----------|
| `Ctrl+Shift+O` | 水平分割标签页 | 并排查看不同内容 |
| `Ctrl+Shift+E` | 垂直分割标签页 | 对比或参考操作 |
| `Ctrl+Shift+Q` | 关闭分割窗格 | 恢复单个视图 |
> 🎯 **高效技巧**:使用 `Ctrl+Shift+T` 新建标签页后,配合 `Alt+数字键` 快速切换,可以像使用浏览器一样高效管理多个终端会话。
## 五、自定义快捷键配置
### 5.1 修改快捷键配置文件
XFCE 终端的快捷键配置文件位于:
`~/.config/xfce4/terminal/accels.scm`
可以通过编辑此文件来自定义快捷键:
```bash
# 备份原配置文件
cp ~/.config/xfce4/terminal/accels.scm ~/.config/xfce4/terminal/accels.scm.backup
# 编辑配置文件
nano ~/.config/xfce4/terminal/accels.scm
# 示例:修改新建标签页快捷键为 Ctrl+T
# 原内容: (gtk_accel_path "<Actions>/terminal-window/tab-new" "<Primary><Shift>t")
# 修改为: (gtk_accel_path "<Actions>/terminal-window/tab-new" "<Primary>t")
```
重启终端或按 `Ctrl+Shift+R` 重载配置使更改生效。
### 5.2 解决Alt快捷键被抢占问题
XFCE 终端默认会将 `Alt + 字母` 组合键作为菜单访问快捷键,会导致 Bash 的 `Alt + F``Alt + B` 等行编辑快捷键失效,可通过以下设置解决:
**推荐方案(禁用所有菜单访问键):**
1. 打开终端 → **编辑****首选项**Preferences
2. 切换到 **高级**Advanced标签
3. **勾选****禁用所有菜单访问键**Disable all menu access keys
**效果:**
- `Alt + F``Alt + B` 等 Bash 行编辑快捷键恢复正常
- 同时会禁用 `Alt + F`(文件菜单)、`Alt + E`(编辑菜单)等菜单访问快捷键
**替代方案(不关闭菜单快捷键):**
- 使用 `Esc + F` 代替 `Alt + F` 向右跳一个单词
- 使用 `Esc + B` 代替 `Alt + B` 向左跳一个单词
> 💡 **记忆技巧**
> - `Ctrl` 系列快捷键:多用于**字符**级别操作A=开头, E=结尾, B=后退, F=前进)
> - `Alt` 系列快捷键:多用于**单词**级别操作B=back, F=forward
> - `Esc` 可以代替 Alt当 Alt 被系统/应用抢占时)
## 六、总结与推荐
### 6.1 最常用快捷键(强烈建议掌握)
1. **导航类**
- `Ctrl+Shift+T` - 新建标签页
- `Ctrl+PgUp` / `Ctrl+PgDown` - 切换标签页
- `Alt+数字键` - 直接跳转标签页
2. **编辑类**
- `Ctrl+Shift+C` / `Ctrl+Shift+V` - 复制粘贴
- `Ctrl+R` - 搜索历史命令
3. **显示类**
- `Ctrl+加号/减号` - 字体缩放
- `F11` - 全屏切换
### 6.2 学习建议
1. **循序渐进**:先掌握最常用的 5-10 个快捷键
2. **结合实际**:在日常使用中刻意练习
3. **定期复习**:创建自己的快捷键备忘清单
4. **个性化**:根据个人习惯调整快捷键配置
> 📚 **扩展阅读**:可以通过 `man xfce4-terminal` 查看完整的官方手册,了解更多高级功能和配置选项。

View File

@@ -0,0 +1,222 @@
---
title: 内存优化完全指南
icon: simple-icons:linuxmint
date: 2026-03-20
category:
- Linux
tag:
- Linux Mint
- 内存优化
- 性能调优
- zram
- earlyoom
---
# Linux Mint 内存优化完全指南
这篇记录一次真实的 Linux Mint 内存优化过程从内存告急、Swap 打满,到切换纯 zram、调整内核策略、加上 OOM 保护,最终把系统稳定性和响应速度拉回到优秀状态。
<!-- more -->
## 一 问题背景
### 1.1 初始状态
排查时的核心数据:
- **物理内存**: 29GB
- **已使用**: 25GB (86%)
- **可用内存**: 3.5GB
- **Swap**: 15GB几乎耗尽
### 1.2 主要问题
| 问题 | 严重程度 | 影响 |
|------|---------|------|
| Swap 完全耗尽 | 🔴 严重 | 系统响应明显变慢 |
| 可用内存过低 | 🔴 严重 | 高负载场景容易卡顿 |
| 长时间残留会话 | 🟡 中等 | 持续吃内存、吃 CPU |
| 文件 Swap | 🟡 中等 | 磁盘 IO 成为瓶颈 |
### 1.3 内存占用分析
常用定位命令:
```bash
# 查看内存概览
free -h
# 查看内存占用 TOP 10 进程
ps aux --sort=-%mem | head -11
```
观察到的主要内存占用:
- IntelliJ IDEA: 约 4.9GB
- VMware 虚拟机: 约 4GB
- 多个 IDE/AI 工具常驻进程
- 多个 OpenCode 会话并行
---
## 二 优化流程
### 2.1 清理僵尸进程
#### 2.1.1 识别僵尸会话
判断标准:
- 进程对应终端显示 `(deleted)`
- 运行时间很长,但无人交互
- `w` / `who` 中找不到对应活跃终端
```bash
# 看会话是否还挂着真实终端
for pid in $(pgrep -f "\.opencode$"); do
echo "=== PID: $pid ==="
ps -p "$pid" -o pid,etime,%cpu,%mem,cmd --no-headers
lsof -p "$pid" 2>/dev/null | grep -E "pts/|tty" | head -3
echo
done
# 优雅终止僵尸会话
kill -15 <PID1> <PID2>
```
清理后,可用内存和 Swap 都会明显回升。
---
### 2.2 从文件 Swap 切换到纯 zram
#### 2.2.1 为什么选 zram
性能差异(体感非常明显):
| 类型 | 速度 | 延迟 | 寿命影响 |
|------|------|------|---------|
| zram | 内存级 | <1ms | 无磁盘写入 |
| 文件 Swap (SSD) | 磁盘级 | 10-100ms | 增加 SSD 写入 |
| 文件 Swap (HDD) | 磁盘级 | 100-1000ms | 响应更慢 |
zram 的关键收益:
- 性能更高:比文件 Swap 快很多
- 压缩率高:常见 3:1 到 4:1
- 磁盘更友好:减少持续写入
#### 2.2.2 检查当前 zram
```bash
zramctl
swapon --show
```
本文案例中,最终将 zram 配到物理内存的 80%,并保留 `zstd` 算法。
---
### 2.3 调整内存策略参数
#### 2.3.1 关键参数
```bash
# 当前策略
sysctl vm.swappiness
sysctl vm.vfs_cache_pressure
```
本文做的策略调整:
- `vm.swappiness=40`(默认 10 偏保守zram 场景下可更积极)
- 保持 `vfs_cache_pressure=100`
#### 2.3.2 增加 OOM 保护
安装并启用 earlyoom避免内存耗尽导致系统“假死”
```bash
sudo apt update
sudo apt install -y earlyoom
sudo systemctl enable --now earlyoom
```
---
## 三 三个脚本(可复用)
为了复盘方便,把这次整理后的脚本放到博客目录:
- `src/programming/linux/Linux_Mint/scripts/setup_zram_only.sh`
- `src/programming/linux/Linux_Mint/scripts/optimize_memory_policy.sh`
- `src/programming/linux/Linux_Mint/scripts/expand_swap.sh`
### 3.1 setup_zram_only.sh
用途:禁用文件 Swap启用纯 zram80%)。
```bash
./src/programming/linux/Linux_Mint/scripts/setup_zram_only.sh
```
### 3.2 optimize_memory_policy.sh
用途:把 swappiness 调到 40并安装 earlyoom。
```bash
./src/programming/linux/Linux_Mint/scripts/optimize_memory_policy.sh
```
### 3.3 expand_swap.sh
用途:保留文件 Swap 的场景下扩容到 24G备用方案
```bash
./src/programming/linux/Linux_Mint/scripts/expand_swap.sh
```
---
## 四 执行顺序建议
推荐顺序:
1. 先做僵尸进程清理(立刻见效)
2. 再切换纯 zram性能提升
3. 最后调策略和 OOM 保护(长期稳定)
---
## 五 验证清单
### 5.1 配置验证
```bash
free -h
swapon --show
zramctl
sysctl vm.swappiness
systemctl is-active earlyoom
```
### 5.2 目标状态
- 可用内存明显提升
- Swap 不再长时间打满
- zram 算法为 `zstd`
- `vm.swappiness=40`
- `earlyoom` 处于 `active`
---
## 六 本次优化结果
本文案例最终状态:
- 内存从高压恢复到健康余量
- Swap 从几乎打满恢复到可控状态
- 系统在多工具并行场景下更稳定
- 交互延迟和卡顿体感明显改善
如果你也是 Linux Mint 开发机、工具常驻多、会话长时间运行,这一套流程可以直接复用。

View File

@@ -1,6 +1,6 @@
---
title: Linux 应用安装与快捷方式
icon: mdi:application-box
icon: fa6-solid:box-open
date: 2025-12-22
category:
- Linux 基础

View File

@@ -0,0 +1,118 @@
---
title: VNC 单脚本管理与批量下发
icon: mdi:remote-desktop
date: 2026-03-09
category:
- Linux
tag:
- VNC
- 运维
- Bash
- SSH
---
本文记录一次 VNC 运维落地方案:在单机用 `vnc_ctl.sh` 统一管理服务生命周期,再通过 `deploy_to_desktop.sh` 按 IP 列表批量下发到多台 Linux 机器。
<!-- more -->
# VNC 单脚本管理与批量下发
## 1. 目标场景
示例目标机器:
- `10.6.223.223`
- `10.6.220.165`
- `10.6.221.8`
- `10.6.223.233`
统一目标:
1. 在远程桌面生成 `vnc_ctl.sh`
2. 后台运行 `x0vncserver`
3. 提供开机自启能力
4. 支持状态检查与一键停止
5. 支持批量下发,减少重复操作
## 2. 管理脚本设计
主脚本:`vnc_ctl.sh`
支持命令:
- `start`:启动 VNC
- `stop`:停止 VNC
- `check`:检查进程、端口、密码文件与日志
- `restart`:重启服务
- `install-autostart`:安装 `@reboot` 自启
- `remove-autostart`:移除自启
核心思路:
- 通过 `pgrep` 精确匹配 `x0vncserver` 参数定位进程
- 使用 `nohup` 后台运行并记录日志
- 通过 `crontab` 注入 `@reboot` 行实现开机拉起
示例(启动命令段):
```bash
nohup x0vncserver \
-display ":0" \
-passwordfile "$HOME/.vnc/passwd" \
-rfbport "5900" \
-nevershared \
-idletimeout 0 \
>>"$HOME/.vnc/x0vncserver-5900.log" 2>&1 &
```
## 3. 批量下发脚本
下发脚本:`deploy_to_desktop.sh`
用途:把本地脚本按 IP 列表分发到远程桌面目录,并自动加执行权限。
示例命令:
```bash
./deploy_to_desktop.sh -f ./vnc_ctl.sh -i 10.6.223.233,10.6.220.165 -u sunri
```
脚本默认行为:
- 目标目录默认为 `/home/<user>/Desktop`
- 使用 SSH/SCP 分发
- 分发后自动执行 `chmod +x`
## 4. 推荐使用流程
```bash
chmod +x ./vnc_ctl.sh ./deploy_to_desktop.sh
./deploy_to_desktop.sh -f ./vnc_ctl.sh -i 10.6.223.233,10.6.220.165 -u sunri
```
远程执行示例:
```bash
ssh sunri@10.6.220.165 "/home/sunri/Desktop/vnc_ctl.sh install-autostart && /home/sunri/Desktop/vnc_ctl.sh start && /home/sunri/Desktop/vnc_ctl.sh check"
```
## 5. 测试结论
- `10.6.220.165`:下发成功,脚本存在且可执行
- `10.6.223.233`:下发失败,原因为 SSH 认证失败(`Permission denied`
## 6. 常见问题排查
- 缺少密码文件:在目标机执行 `vncpasswd`
- 端口未监听:检查 `~/.vnc/x0vncserver-5900.log`
- 开机自启未生效:检查 `crontab -l``@reboot ... vnc_ctl.sh start ...`
- 无法下发:先手动验证 `ssh <user>@<ip>`
## 7. 小结
该方案把 VNC 运维拆成两个可复用脚本:
- 单机统一管理生命周期
- 多机统一批量下发
适合内网多台 Linux 机器的日常维护与快速复制部署。

View File

@@ -12,8 +12,6 @@ title: MobaXterm
MobaXterm工具实用教程
<!-- more -->
1. 去官网安装正版软件比如23.6版本[MobaXterm free Xserver and tabbed SSH client for Windows](https://mobaxterm.mobatek.net/)
2. 打开这个网站,输入信息:[MobaXterm Keygen](https://inused.github.io/pages/file/tool/MobaXtermKeygen.html)
3. 将自动下载的Custom.mxtpro文件放入到[mobaxterm]的目录下
4. [重启软件]即已完成注册
1. 去官网安装正版软件,比如 23.6 版本:[MobaXterm free Xserver and tabbed SSH client for Windows](https://mobaxterm.mobatek.net/)
2. 优先使用官方提供的免费版本或购买专业版授权,避免使用非官方激活工具。
3. 按官方引导完成安装后重启软件,确认终端和会话配置可正常保存。

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

View File

@@ -0,0 +1,9 @@
---
title: 项目总结
index: false
icon: mdi:book-open-page-variant
category:
- 工作
---
<Catalog />

View File

@@ -0,0 +1,113 @@
---
title: AlgoSimulation 打包与交付记录
icon: mdi:package-variant-closed
date: 2026-03-09
category:
- 工作
- 项目总结
tag:
- AlgoSimulation
- C++
- Linux
- 打包部署
---
本文记录 AlgoSimulation 在目标机器上的编译、依赖修正与独立目录打包过程,重点是 OpenSSL 符号版本冲突的定位与处理。
<!-- more -->
# AlgoSimulation 打包与交付记录
## 1. 目标与环境
- 编译目标:`/home/sunri/IdeaProjects/V2.00/src_cxx/99_TestTool/AlgoSimulation`
- 编译机:`10.6.221.8`
- 参考机:`10.6.220.186`
- 约束:`08_Preview` 已同步完成,本次仅处理编译、链接与打包
## 2. 基础编译流程
```bash
export PRJHOME=/home/sunri/IdeaProjects/V2.00
export CYGHOME=/home/sunri/08_Preview/linx80
cd /home/sunri/IdeaProjects/V2.00/src_cxx/99_TestTool/AlgoSimulation
qmake AlgoSimulation.pro
make -j4
```
## 3. 链接问题与修正
链接阶段出现 OpenSSL 相关符号版本不匹配(`OPENSSL_1_1_0d`)。
原因是 `libmosquitto``libcurl``libssh2` 依赖的 OpenSSL 版本,与系统默认搜索到的 `libssl/libcrypto` 不一致。
修正方式:通过 `qmake` 注入链接参数,显式指定 `gmssl` 库并关闭 `as-needed` 提前裁剪。
```bash
export PRJHOME=/home/sunri/IdeaProjects/V2.00
export CYGHOME=/home/sunri/08_Preview/linx80
cd /home/sunri/IdeaProjects/V2.00/src_cxx/99_TestTool/AlgoSimulation
make clean
qmake "QMAKE_LFLAGS+=-Wl,--no-as-needed" \
"LIBS+=/usr/local/gmssl/lib/libssl.so.1.1 /usr/local/gmssl/lib/libcrypto.so.1.1" \
AlgoSimulation.pro
make -j4
```
编译产物:`/home/sunri/IdeaProjects/V2.00/binary/linx80/bin/AlgoSimulation`
## 4. 独立目录打包
目标目录:`/home/sunri/Desktop/AlgoSimulation_tool`
```bash
TOOL=/home/sunri/Desktop/AlgoSimulation_tool
BIN=/home/sunri/IdeaProjects/V2.00/binary/linx80/bin/AlgoSimulation
rm -rf "$TOOL"
mkdir -p "$TOOL/bin" "$TOOL/lib"
cp -f "$BIN" "$TOOL/bin/"
ldd "$BIN" | awk '/=> \/home\/sunri\// {print $3} /=> \/usr\/local\/gmssl\// {print $3}' | sort -u | while read -r so; do
cp -f "$so" "$TOOL/lib/"
done
cp -f /usr/local/gmssl/lib/libssl.so.1.1 "$TOOL/lib/"
cp -f /usr/local/gmssl/lib/libcrypto.so.1.1 "$TOOL/lib/"
```
启动脚本 `run_AlgoSimulation.sh`
```bash
#!/usr/bin/env bash
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
export LD_LIBRARY_PATH="$SCRIPT_DIR/lib:${LD_LIBRARY_PATH:-}"
exec "$SCRIPT_DIR/bin/AlgoSimulation" "$@"
```
## 5. 验证结果
缺库检查:
```bash
LD_LIBRARY_PATH=/home/sunri/Desktop/AlgoSimulation_tool/lib \
ldd /home/sunri/Desktop/AlgoSimulation_tool/bin/AlgoSimulation | grep "not found"
```
- 结果:无输出(未发现缺失依赖)
启动冒烟:
- 在无图形会话环境下提示 `cannot connect to X server`
- 结论:当前阻塞点是图形环境,不是依赖缺失
## 6. 交付清单
- `/home/sunri/Desktop/AlgoSimulation_tool/bin/AlgoSimulation`
- `/home/sunri/Desktop/AlgoSimulation_tool/lib/`
- `/home/sunri/Desktop/AlgoSimulation_tool/run_AlgoSimulation.sh`
## 7. 后续建议
若后续仍出现符号版本或缺库问题,优先按缺失项从 `10.6.220.186` 精准补齐,避免全量同步带来的不可控差异。

View File

@@ -0,0 +1,185 @@
---
icon: mdi:lan-connect
date: 2026-03-06
category:
- 工作
- 项目总结
tag:
- TCPClientTester
- 打包部署
- Linux
title: TCPClientTester 打包与启动工作总结
---
TCPClientTester 打包与启动工作总结
<!-- more -->
# TCPClientTester 打包与启动工作总结
> 本文整理了 TCPClientTester 在目标机器 `10.6.221.8` 的编译、打包、部署、启动验证及问题修复过程,用于后续复用与交接。
---
## 1. 背景与目标
- 目标:在 `10.6.221.8` 上完成 TCPClientTester 的可独立运行打包。
- 输出:桌面工具目录 `/home/sunri/Desktop/tool`,包含可执行程序、配置资源、依赖库和启动脚本。
- 结果:通过 `DISPLAY=:0` 启动验证,程序可正常拉起。
---
## 2. 编译前准备
### 2.1 同步依赖目录
从参考机 `10.6.220.186` 同步 `08_Preview` 到目标机:
```bash
ssh 10.6.220.186 'tar czf - -C /home/sunri 08_Preview' | ssh 10.6.221.8 'tar xzf - -C /home/sunri'
```
### 2.2 环境变量
```bash
export PRJHOME=/home/sunri/IdeaProjects/V2.00
export CYGHOME=/home/sunri/08_Preview/linx80
```
---
## 3. 编译流程
```bash
cd /home/sunri/IdeaProjects/V2.00/src_cxx/99_TestTool/TCPClientTester
PRJHOME="$PRJHOME" CYGHOME="$CYGHOME" qmake TCPClientTester.pro
PRJHOME="$PRJHOME" CYGHOME="$CYGHOME" make -j4
```
编译产物:
- `/home/sunri/IdeaProjects/V2.00/binary/linx80/bin/tcptester`
---
## 4. 打包目录规范
目标目录:`/home/sunri/Desktop/tool`
建议结构:
- `tool/bin/tcptester`
- `tool/lib/`(运行依赖库)
- `tool/config/`(配置与资源)
- `tool/run_tcptester.sh`(统一启动脚本)
---
## 5. 文件拷贝与依赖收集
### 5.1 程序与配置资源
```bash
TOOL=/home/sunri/Desktop/tool
SRC=/home/sunri/IdeaProjects/V2.00/src_cxx/99_TestTool/TCPClientTester
BIN=/home/sunri/IdeaProjects/V2.00/binary/linx80/bin/tcptester
rm -rf "$TOOL"
mkdir -p "$TOOL/bin" "$TOOL/lib" "$TOOL/config"
cp -f "$BIN" "$TOOL/bin/"
cp -f "$SRC/basic.xml" "$TOOL/config/"
cp -f "$SRC/TCPClientTester_zh_CN.qm" "$TOOL/config/"
for d in mainStationFile model res uploadFile lib "边缘节点一键测试" "巡视设备一键测试" "主站一键测试"; do
[ -d "$SRC/$d" ] && cp -a "$SRC/$d" "$TOOL/config/"
done
```
### 5.2 依赖库自动拷贝
```bash
ldd "$BIN" | awk '/=> \/home\/sunri\// {print $3}' | sort -u | while read -r so; do
cp -f "$so" "$TOOL/lib/"
done
```
---
## 6. 启动脚本与验证
### 6.1 启动脚本
```bash
cat > /home/sunri/Desktop/tool/run_tcptester.sh <<'EOF'
#!/usr/bin/env bash
set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
export LD_LIBRARY_PATH="$SCRIPT_DIR/lib:${LD_LIBRARY_PATH:-}"
export TCPCLIENTTESTER_LANG="${TCPCLIENTTESTER_LANG:-zh_CN}"
cd "$SCRIPT_DIR/config"
exec "$SCRIPT_DIR/bin/tcptester" "$@"
EOF
chmod +x /home/sunri/Desktop/tool/run_tcptester.sh
```
### 6.2 启动验证
```bash
env DISPLAY=:0 /home/sunri/Desktop/tool/run_tcptester.sh
```
持续运行验证(返回 `124` 表示进程在运行):
```bash
timeout 8s env DISPLAY=:0 /home/sunri/Desktop/tool/run_tcptester.sh
echo $?
```
---
## 7. 问题定位与修复
### 7.1 问题现象
- 程序启动时在 `CBasecfgManger::getLanguage()` 处触发段错误(`SIGSEGV`)。
### 7.2 修复方案
- 修改 `main.cpp`,避免调用崩溃路径。
- 改为从环境变量读取语言:`TCPCLIENTTESTER_LANG`
- 默认值设置为 `zh_CN`,保障无环境变量时可正常启动。
修复文件:
- `/home/sunri/IdeaProjects/V2.00/src_cxx/99_TestTool/TCPClientTester/main.cpp`
---
## 8. 常用命令速查
中文启动:
```bash
/home/sunri/Desktop/tool/run_tcptester.sh
```
英文启动:
```bash
TCPCLIENTTESTER_LANG=en_US /home/sunri/Desktop/tool/run_tcptester.sh
```
检查缺失依赖:
```bash
ldd /home/sunri/Desktop/tool/bin/tcptester | grep "not found"
```
---
## 9. 交付结论
- 已完成从编译到独立目录打包的全流程。
- 启动脚本已固化依赖路径与语言参数,便于现场快速使用。
- 崩溃问题已通过入口语言加载逻辑调整规避,当前版本可稳定启动。

View File

@@ -0,0 +1,225 @@
---
icon: mdi:video-outline
date: 2026-03-05
category:
- 工作
- 项目总结
tag:
- 权限配置
- 录像回放
title: 录像回放权限配置说明
---
录像回放权限配置说明
<!-- more -->
# 录像回放权限配置说明
## 概述
根据系统权限说明文档中的权限隔离原则为录像回放相关功能设置了单独的权限位权限位21RECORD_PLAYBACK实现与实时监控权限的独立控制。
## 修改内容
### 1. 权限常量定义
**文件**: `platapp/04_sunri-web-patrol/sunri-web-center-utils/src/main/java/com/sunri/constant/RightConstant.java`
**修改内容**: 添加录像回放权限常量
```java
// 录像回放: 操作员,对应实时监控->录像回放相关界面的浏览、查询权限
public static final int RECORD_PLAYBACK = 21;
```
同时更新了操作员权限注释,增加 `RECORD_PLAYBACK` 权限位。
### 2. Controller API权限注解更新
#### 2.1 HighDefinitionVideoEquipmentController.java
**文件**: `platapp/04_sunri-web-patrol/sunri-web-center-cygbusiness/cygbusiness-model/src/main/java/com/sunri/model/controller/account/HighDefinitionVideoEquipmentController.java`
**修改的API方法**:
- `getVideoFileList` - 录像-获取文件列表
- `getVideoFileUrl` - 录像-获取回放地址
- `stopVideoFileUrl` - 录像-停止回放/推流
- `videoPlayBackControl` - 录像-回放控制
- `videoProgress` - 录像-进度获取
- `getAfterCalibrationStartTime` - 录像-获取校准后开始时间
**权限变更**: 从 `@ApiRight(value = {REAL_TIME_MONITORING})` 改为 `@ApiRight(value = {RECORD_PLAYBACK})`
#### 2.2 ResourceController.java
**文件**: `platapp/04_sunri-web-patrol/sunri-web-center-standalone/standalone-patrol/src/main/java/com/sunri/controller/ResourceController.java`
**修改的API方法**:
- `downloadVideoChunk` - 下载文件到浏览器(分片)
- `getDownloadChunkSize` - 获取下载文件分片数
**权限变更**: 从 `@ApiRight(value = {REAL_TIME_MONITORING, ALGORITHM_VERIFICATION})` 改为 `@ApiRight(value = {REAL_TIME_MONITORING, RECORD_PLAYBACK, ALGORITHM_VERIFICATION})`
#### 2.3 HighDefinitionVideoMonitorController.java
**文件**: `platapp/04_sunri-web-patrol/sunri-web-center-cygbusiness/cygbusiness-model/src/main/java/com/sunri/model/controller/monitor/HighDefinitionVideoMonitorController.java`
**修改的API方法**:
- `videoDownload` - 录像-开始下载/手动录像
**权限变更**: 从 `@ApiRight(value = {DEVICE_CONTROL})` 改为 `@ApiRight(value = {RECORD_PLAYBACK})`
### 3. 数据库配置脚本
```sql
-- 录像回放权限配置脚本
-- 功能为录像回放相关功能添加权限位21RECORD_PLAYBACK的单独控制
-- 1. 添加录像回放权限常量到 cfg_auth_const 表
INSERT INTO cfg_auth_const (right, description, create_time, update_time)
VALUES (21, '录像回放', NOW(), NOW())
ON DUPLICATE KEY UPDATE description = '录像回放', update_time = NOW();
-- 2. 查找录像回放相关的菜单ID
-- SELECT id, name, nodeid, url FROM cfg_menu WHERE name LIKE '%录像%' OR name LIKE '%回放%';
-- 3. 为录像回放菜单绑定权限位21按实际菜单修改
-- INSERT INTO cfg_resource_right (resource_id, right)
-- VALUES (7, 21)
-- ON DUPLICATE KEY UPDATE right = 21;
-- INSERT INTO cfg_resource_right (resource_id, right)
-- SELECT id, 21 FROM cfg_menu WHERE nodeid = 'LXHF'
-- ON DUPLICATE KEY UPDATE right = 21;
-- 4. 更新角色权限配置(示例)
-- UPDATE user_role_info SET role_authority = role_authority | 2097152 WHERE role_name = '操作员';
-- UPDATE user_role_info SET role_authority = role_authority | 2097216 WHERE role_name = '监控操作员';
-- UPDATE user_role_info SET role_authority = role_authority | 2097152 WHERE role_name = '录像查询员';
-- 5. 验证配置
-- SELECT * FROM cfg_auth_const WHERE right = 21;
-- SELECT mr.*, m.name, m.nodeid FROM cfg_resource_right mr JOIN cfg_menu m ON mr.resource_id = m.id WHERE mr.right = 21;
-- SELECT role_id, role_name, role_authority, (role_authority & 2097152) > 0 AS has_record_playback_permission FROM user_role_info;
-- 回滚SQL
-- DELETE FROM cfg_auth_const WHERE right = 21;
-- DELETE FROM cfg_resource_right WHERE right = 21;
-- UPDATE user_role_info SET role_authority = role_authority & ~2097152 WHERE role_authority & 2097152 > 0;
```
## 权限隔离优势
通过将录像回放权限从实时监控权限中独立出来,实现了以下优势:
| 场景 | 实时监控权限(6) | 录像回放权限(21) | 说明 |
|------|----------------|------------------|------|
| 实时监控员 | ✅ | ❌ | 只能查看实时监控画面 |
| 录像查询员 | ❌ | ✅ | 只能查看历史录像回放 |
| 监控操作员 | ✅ | ✅ | 既能看实时监控也能看录像回放 |
| 数据分析员 | ❌ | ✅ | 只能进行录像数据分析 |
## 实施步骤
### 代码修改(已完成)
1. ✅ 在 `RightConstant.java` 中添加 `RECORD_PLAYBACK = 21` 常量
2. ✅ 更新录像回放相关API的权限注解
3. ✅ 创建数据库配置脚本
### 数据库配置(需要手动执行)
1. 备份数据库
2. 执行上文中的 SQL 配置脚本
3. 根据实际菜单数据确认录像回放菜单的ID或nodeid
4. 更新角色权限配置
5. 验证配置是否正确
### 系统部署
1. 编译代码
2. 部署应用
3. 执行数据库配置脚本
4. 相关用户重新登录以获取新权限
## 权限位计算
- **权限位21的值**: 2^21 = 2,097,152
- **实时监控权限位6的值**: 2^6 = 64
- **同时拥有实时监控和录像回放权限**: 64 + 2,097,152 = 2,097,216
### 角色权限配置示例
```sql
-- 操作员:增加录像回放权限
UPDATE user_role_info SET role_authority = role_authority | 2097152 WHERE role_name = '操作员';
-- 监控操作员:拥有实时监控和录像回放权限
UPDATE user_role_info SET role_authority = role_authority | 2097216 WHERE role_name = '监控操作员';
-- 录像查询员:只拥有录像回放权限
UPDATE user_role_info SET role_authority = role_authority | 2097152 WHERE role_name = '录像查询员';
```
## 注意事项
1. **数据库备份**: 执行数据库脚本前,请务必备份数据库
2. **菜单确认**: 脚本中的菜单ID需要根据实际情况进行确认和修改
3. **角色权限**: 角色权限配置需要根据实际业务需求进行调整
4. **用户登录**: 修改角色权限后,相关用户需要重新登录才能生效
5. **权限测试**: 部署后请进行全面的权限测试,确保权限控制正确
## 回滚方案
如需回滚,请执行以下操作:
1. 恢复代码版本
2. 执行上文中的回滚 SQL 脚本
3. 重新部署应用
4. 相关用户重新登录
## 验证方法
### 代码验证
```bash
# 搜索所有使用RECORD_PLAYBACK权限的API
grep -r "RECORD_PLAYBACK" --include="*.java" platapp/
```
### 数据库验证
```sql
-- 查看权限常量
SELECT * FROM cfg_auth_const WHERE right = 21;
-- 查看菜单权限绑定
SELECT mr.*, m.name, m.nodeid
FROM cfg_resource_right mr
JOIN cfg_menu m ON mr.resource_id = m.id
WHERE mr.right = 21;
-- 查看角色权限
SELECT role_id, role_name, role_authority,
(role_authority & 2097152) > 0 AS has_record_playback_permission
FROM user_role_info;
```
### 功能验证
1. 创建只拥有录像回放权限的用户角色
2. 使用该角色登录系统
3. 验证只能访问录像回放功能,不能访问实时监控功能
4. 创建只拥有实时监控权限的用户角色
5. 使用该角色登录系统
6. 验证只能访问实时监控功能,不能访问录像回放功能
## 相关文档
- 权限管理系统文档.md: 完整的权限管理说明文档
## 版本信息
- **修改日期**: 2026-03-05
- **修改人员**: 系统管理员
- **版本**: 1.0.0
- **状态**: 已完成代码修改和数据库配置

View File

@@ -0,0 +1,202 @@
---
icon: mdi:transit-connection-variant
date: 2026-03-05
category:
- 工作
- 项目总结
tag:
- 服务总线
- CGLIB
- 权限系统
title: 服务总线学习
---
服务总线学习
<!-- more -->
# @BusService 注解与 CGLIB 动态代理机制学习记录
## 1. 概述
本次学习深入探讨了 `@BusService` 注解配合 CGLIB 动态代理实现的无本地实现接口代理机制,了解了服务总线架构中客户端如何通过动态代理调用远程服务。
## 2. @BusService 注解的作用
### 2.1 注解定义
`@BusService` 注解位于 `/platform/00_depends/00_sunri-bus-service-dependency-thrift/src/main/java/com/sunri/annotation/BusService.java`,包含以下关键属性:
- `name()` - 服务名称(如 "cygdevopsweb"
- `dataclass()` - 数据类别(如 "statistic"
- `app()` - 应用名称
- `datatype()` - 数据类型
### 2.2 注解处理流程
1. **扫描**`ServiceBusBeanAutoDefinitionConfig.definitionConsumer()` 方法扫描带有 `@BusService` 注解的接口
2. **验证**:检查注解有效性、服务名称、排除列表等
3. **过滤**:确保接口属于指定包名且未重复注册
## 3. CGLIB 动态代理机制
### 3.1 代理对象创建位置
`ServiceBusBeanAutoDefinitionConfig.java` 第409-445行的循环中
```java
if (c.isInterface()) { // 409行
if (!c.getName().contains(pkgname)) { // 410-412行
continue;
}
// ... 验证逻辑 ...
// Bean构建
BusService service = (BusService) c.getAnnotation(BusService.class); // 417行
if (service == null || "".equals(service.name()) || exclude.contains(service.name())) {
continue;
}
// 创建服务信息
ServiceInfo serviceInfo = new ServiceInfo(); // 425行
serviceInfo.setPaname(StringUtils.isEmpty(service.app()) ? busClientConfig.getPaname() : service.app());
serviceInfo.setServname(service.name());
// ... 设置其他服务信息
// 注册Bean定义
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(c); // 434行
GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();
definition.getPropertyValues().add("interfaceClass", c); // 436行
definition.getPropertyValues().add("serviceInfo", serviceInfo); // 437行
definition.getPropertyValues().add("clientManager", clientManager); // 438行
definition.setBeanClass(BusClientFactoryBean.class); // 439行
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);
String name = toLowerCaseFirstOne(c.getSimpleName()); // 442行
dbf.registerBeanDefinition(name, definition); // 443行
}
```
### 3.2 BusClientFactoryBean 核心实现
位于 `/platform/00_depends/00_sunri-bus-service-dependency-thrift/src/main/java/com/sunri/client/mapper/BusClientFactoryBean.java`
```java
@Override
public T getObject() throws Exception {
enhancer.setSuperclass(interfaceClass); // 29行 设置要代理的接口
interceptor.setClientManager(clientManager); // 30行 设置客户端管理器
interceptor.setServiceInfo(serviceInfo); // 31行 设置服务信息
enhancer.setCallback(interceptor); // 32行 设置拦截器
return (T) enhancer.create(); // 33行 创建代理对象
}
```
### 3.3 BusClientInterceptor 拦截器
位于 `/platform/00_depends/00_sunri-bus-service-dependency-thrift/src/main/java/com/sunri/client/mapper/BusClientInterceptor.java`
- 拦截所有接口方法调用
- 将本地方法调用转换为远程服务调用
- 通过 Thrift 协议发送到远程服务端
## 4. Spring Bean 生命周期集成
### 4.1 Bean 定义注册
- **触发位置**`ServiceBusBeanAutoDefinitionConfig.postProcessBeanDefinitionRegistry()`
- **执行时机**Spring 容器启动时,在 `BeanDefinitionRegistryPostProcessor` 阶段
- **结果**:将每个带 `@BusService` 注解的接口注册为由 `BusClientFactoryBean` 创建的 Bean
### 4.2 属性自动注入机制
`ServiceBusBeanAutoDefinitionConfig.definitionConsumer()` 第436-438行
```java
definition.getPropertyValues().add("interfaceClass", c); // 接口类
definition.getPropertyValues().add("serviceInfo", serviceInfo); // 服务信息
definition.getPropertyValues().add("clientManager", clientManager); // 客户端管理器
```
Spring 框架内部通过反射机制自动调用对应的 setter 方法:
- `setInterfaceClass()` → 注入接口类
- `setServiceInfo()` → 注入服务信息
- `setClientManager()` → 注入客户端管理器
### 4.3 Bean 实例化
当应用通过 `@Autowired``context.getBean()` 获取接口实例时:
1. Spring 发现该 Bean 由 `BusClientFactoryBean` 创建
2. 调用 `BusClientFactoryBean.getObject()`
3. CGLIB 创建动态代理对象
4. 返回代理对象给应用
## 5. 工作流程总结
```
应用启动 → ServiceBusBeanAutoDefinitionConfig 扫描 @BusService 注解的接口
为每个接口创建 BusClientFactoryBean 定义并注册到 Spring 容器
应用代码获取接口实例 (@Autowired 或 getBean)
Spring 调用 BusClientFactoryBean.getObject()
CGLIB 创建接口的动态代理对象
应用调用接口方法时由 BusClientInterceptor 拦截
拦截器将方法调用转换为远程服务调用
通过 Thrift 协议发送到远程服务端执行
返回结果给调用方
```
## 6. 关键特点
### 6.1 透明性
- 客户端代码无需关心底层网络通信
- 接口调用如同本地调用一样简单
### 6.2 解耦性
- 客户端只依赖接口定义
- 无需知道服务实现的位置和细节
### 6.3 动态性
- 运行时动态生成代理类
- 支持灵活的服务定位和负载均衡
## 7. Spring FactoryBean属性注入机制
### 7.1 RegisterCenterClientFactoryBean属性注入流程
**调用位置**`ServiceBusBeanAutoDefinitionConfig.postProcessBeanDefinitionRegistry()` 第211-218行
**实现机制**
1. **属性值设置**:通过`BeanDefinition.getPropertyValues().add()`方法设置属性
2. **自动注入**Spring容器在Bean创建过程中自动调用对应的setter方法
3. **多态引用**`private RegisterCenterClient client`字段声明为接口类型,运行时指向`RegisterCenterDefaultClient`实例
**上下文依赖**
- 依赖Spring的Bean生命周期管理
-需要BeanDefinitionRegistryPostProcessor阶段的支持
- 依赖属性编辑器和类型转换机制
### 7.2完整调用链
```java
// 1. 创建Bean定义
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(RegisterCenterClient.class);
GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();
// 2. 设置属性值(关键步骤)
definition.getPropertyValues().add("interfaceClass", RegisterCenterClient.class);
definition.getPropertyValues().add("client", zkClient); // zkClient是RegisterCenterDefaultClient实例
// 3.指定FactoryBean类
definition.setBeanClass(RegisterCenterClientFactoryBean.class);
// 4. Spring内部调用setter方法
// setInterfaceClass(RegisterCenterClient.class)
// setClient(RegisterCenterDefaultClient实例)
// 5. getObject()返回具体实现
@Override
public T getObject() throws Exception {
return (T) client; // 返回RegisterCenterDefaultClient实例
}
```
## 8.技术栈
- **CGLIB**:用于动态代理类生成
- **Spring Framework**:用于 Bean 生命周期管理和依赖注入
- **Thrift**:用于远程服务通信协议
- **Zookeeper**:用于服务注册与发现
- **Curator**用于Zookeeper客户端连接管理

File diff suppressed because it is too large Load Diff

177
src/work/todo/2026-03.md Normal file
View File

@@ -0,0 +1,177 @@
---
icon: fa6-solid:list-check
date: 2026-03-23
pageClass: todo-page
category:
- 待办
tag:
- 任务清单
title: 3月待办2026-03
---
3月待办事项记录
<!-- more -->
# 待办清单2026-03
> 最后更新: 2026-04-02
> 统计: 已完成 17 项、已提交 0 项、待测试 0 项、部分完成 0 项、待确认 1 项、未开始 3 项、已取消 1 项
## 清单总览
- 当前优先: 13待确认、14未开始
- 本周建议推进: 7、9、14未开始
- 已归档完成: 1、2、3、4、5、8、10、11、12、15、16、17、18、19、20、21、22
## 状态说明
<Badge text="已完成" type="tip" /> <Badge text="已提交" type="tip" /> <Badge text="待测试" type="info" /> <Badge text="待提交" type="warning" /> <Badge text="部分完成" type="note" /> <Badge text="待确认" type="warning" /> <Badge text="未开始" type="danger" /> <Badge text="已取消" type="warning" />
---
## 当前优先
### 13. V2.00的250985版本是否同步至其他系统 <Badge text="待确认" type="warning" />
- **描述**: 待确认V2.00的250985版本是否需要同步至其他系统
- **下一步**: 与产品/版本负责人确认同步范围和目标版本
---
## 待启动
### 7. [全部版本] WEB端重新开发实现C++开发的桌面端算法标记功能 <Badge text="未开始" type="danger" />
- **描述**: WEB端重新开发实现算法标记功能
- **下一步**: 先产出交互方案和接口清单
### 9. [智能巡视-7950] V2.00所有版本同步至2024后问题修复 <Badge text="未开始" type="danger" />
- **描述**:
- 最新的2024未发送算法资源请求
- 其余问题待测试
- **下一步**: 先复现资源请求问题,再统一修复策略
### 14. [智慧场站-7050] 瀚高数据库适配验证 <Badge text="未开始" type="danger" />
- **创建日期**: 2026-03-23
- **描述**: 验证7050系统对瀚高数据库的兼容性与适配结果整理问题清单
- **下一步**: 明确验证范围(安装、连接、读写、迁移脚本、性能基线)并安排验证
---
## 已完成归档
<details>
<summary>展开查看已完成事项12项</summary>
### 1. 2.00适配的立即执行时间为空是否需要同步其他版本 <Badge text="已完成" type="tip" />
- **描述**: 已同步至3个版本完成
### 2. 静默监视中多个请求类型的问题 <Badge text="已完成" type="tip" />
- **描述**: 已完成并同步到3个版本
### 3. 7050历史三维打包问题 <Badge text="已完成" type="tip" />
- **描述**: 7050项目历史三维打包问题已修复已完成并归档
### 4. 2.00修复的250941版本同步到7050 <Badge text="已完成" type="tip" />
- **描述**: 2.00版本修复的250941问题已同步到7050项目
### 5. 排查/alarm/silent/query/hisSilentAlarm/list的stationAlarmStatistics为空 <Badge text="已完成" type="tip" />
- **描述**: 已完成并和其他版本同步
### 10. [智慧场站-7050] 联动新需求开发 <Badge text="已完成" type="tip" />
- **描述**: 联动新需求开发已完成
### 11. [智能巡视-7950] 打包脚本调整 <Badge text="已完成" type="tip" />
- **描述**: 3个版本都已适配打包脚本复制Common依赖目录
### 12. [智能巡视-7950] 超期逻辑和红外温度矩阵功能同步 <Badge text="已完成" type="tip" />
- **描述**: 红外温度矩阵功能已同步到V2.00版本,超期逻辑已同步
- **完成情况**: 已完成,所有功能已同步
### 15. 调整了go打包脚本的taos依赖库获取位置 <Badge text="已完成" type="tip" />
- **完成日期**: 2026-03-23
- **描述**: 已调整go打包脚本中taos依赖库的获取位置并完成验证
### 17. [智能巡视-7950] getLatestHisTask接口查询方案调整 <Badge text="已完成" type="tip" />
- **创建日期**: 2026-03-26
- **描述**: 调整`@RequestMapping(value = "/getLatestHisTask", method = RequestMethod.GET)`获取最新一条巡视任务及点位信息的查询策略3个版本需同步
- **方案调整**: 默认查询今天正在执行的任务若不存在则默认查询最新一条历史记录3个版本同步
- **完成情况**: 已完成3个版本已同步
### 18. [智慧场站-7050] 调整声纹模型模板必填项 <Badge text="已完成" type="tip" />
- **创建日期**: 2026-03-27
- **描述**: 调整7050声纹模型模板必填项
- **必填项**: 设备名称、设备编码、投运时间、设备IP、通信协议、通信端口
- **完成情况**: 已完成
### 19. [智慧场站-7050] 删除点位时同步清理关联阈值告警 <Badge text="已完成" type="tip" />
- **创建日期**: 2026-03-27
- **描述**: 删除点位时排查是否存在关联的阈值告警,如存在则需要同步删除
- **完成情况**: 已完成,已梳理点位与阈值告警关联关系,实现删除点位时同步清理关联阈值告警功能
- **需求截图**:
![删除点位关联阈值告警需求截图](../assets/Snipaste_2026-03-27_15-12-26.png)
### 20. [智慧场站-7050] 录像回放权限问题修复 <Badge text="已完成" type="tip" />
- **创建日期**: 2026-03-27
- **原话**:
- 没有录像回放这个,这里是不是修改下,默认的更新后要有的,哪个现场不需要再给他取消,要不然其它正常的现场一更新程序,全给录像回放整没了
- 给操作员配上录像回放权限后admin登录咋没有录像回放的菜单
- **完成情况**: 已完成
- **备注**: 新站默认权限包含录像回放,老站需要手动配置下录像权限
### 16. [智能巡视-7950] 超期和终止任务增加结束时间3个版本 <Badge text="已完成" type="tip" />
- **创建日期**: 2026-03-26
- **描述**: 超期任务和终止任务都需要增加任务结束时间且3个版本均需同步
- **完成情况**: 已完成3个版本数据库表结构和业务逻辑已同步更新
### 21. [智慧场站-7050] 反向联动菜单放出与联动开关灯实现 <Badge text="已完成" type="tip" />
- **创建日期**: 2026-03-27
- **描述**: 反向联动菜单放出 + 反向联动实现联动开灯关灯
- **完成情况**: 已完成,反向联动触发条件、开关灯联动逻辑与菜单权限配置已实现并验证
### 8. [智慧场站-7050] 完成贵州大唐机器人告警复检需求开发 <Badge text="已完成" type="tip" />
- **描述**: 7050项目机器人告警复检需求开发已完成等待测试
- **完成情况**: 已完成联调与回归测试,告警复检流程和边界场景验证通过
### 22. [全部版本] 优化服务调用失败异常反馈 <Badge text="已完成" type="tip" />
- **创建日期**: 2026-03-30
- **描述**: 优化服务调用失败时的异常反馈机制,在日志中附带详细的错误信息,便于快速定位问题
- **完成情况**: 已完成全版本优化日志已在ServiceClientPool、ClientManager、BusClientInterceptor等关键类中增强了异常信息包含服务名、方法名、参数、错误原因、调用链路等可快速定位问题
</details>
---
## 已取消归档
<details>
<summary>展开查看已取消事项1项</summary>
### 6. [智能巡视-7950] 巡视结果上报和确认功能优化 <Badge text="已取消" type="warning" />
- **描述**:
- 巡视结果上报需要加确认状态、确认时间、是否告警
- 巡视结果确认需要加告警相关信息
- **处理结果**: 更新已取消,无需处理
</details>

129
src/work/todo/2026-04.md Normal file
View File

@@ -0,0 +1,129 @@
---
icon: fa6-solid:list-check
date: 2026-04-01
pageClass: todo-page
category:
- 待办
tag:
- 任务清单
title: 4月待办2026-04
---
4月待办事项记录
<!-- more -->
# 待办清单2026-04
> 最后更新: 2026-04-02
> 统计: 已完成 2 项、未开始 2 项
## 清单总览
- 当前优先: 2未开始
## 状态说明
<Badge text="已完成" type="tip" /> <Badge text="已提交" type="tip" /> <Badge text="待测试" type="info" /> <Badge text="待提交" type="warning" /> <Badge text="部分完成" type="note" /> <Badge text="待确认" type="warning" /> <Badge text="未开始" type="danger" /> <Badge text="已取消" type="warning" />
---
## 当前优先
### 1. 巡视报告配置异常需要修复 <Badge text="已完成" type="tip" />
- **描述**: 巡视报告配置异常,在这里设置筛选搜索修改设置之后,同一主设备下其它点的设置就变成空的了
- **错误日志**:
```
2026-03-31 19:16:52.944 [TThreadPoolServer WorkerProcess-6] ERROR com.sunri.model.pipeline.DictatePipeline - DictatePipeline start, 处理异常 {}
java.lang.IllegalStateException: Duplicate key PatrolReportDevicePointRecord(id=37327, mainDeviceId=2198, devicePointId=104250, reportSn=1, standardValue=正常)
at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
at java.util.HashMap.merge(HashMap.java:1254)
at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1384)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566)
at com.sunri.model.supersysmodel.pipeline.PatrolReportDevicePointRecordPipeLine.handle(PatrolReportDevicePointRecordPipeLine.java:44)
at com.sunri.model.supersysmodel.pipeline.ObjectVerifyPipeline.proceed(ObjectVerifyPipeline.java:35)
at com.sunri.model.supersysmodel.pipeline.PatrolReportDevicePointRecordPipeLine.proceed(PatrolReportDevicePointRecordPipeLine.java:19)
at com.sunri.model.pipeline.DictatePipeline.start(DictatePipeline.java:23)
at com.sunri.model.pipeline.DictatePipeline.skip(DictatePipeline.java:43)
at com.sunri.model.pipeline.DictatePipeline.start(DictatePipeline.java:32)
at com.sunri.model.pipeline.DictatePipeline.skip(DictatePipeline.java:43)
at com.sunri.model.pipeline.DictatePipeline.start(DictatePipeline.java:32)
at com.sunri.model.pipeline.DictatePipeline.skip(DictatePipeline.java:43)
at com.sunri.model.pipeline.DictatePipeline.start(DictatePipeline.java:32)
at com.sunri.model.pipeline.DictatePipeline.skip(DictatePipeline.java:43)
at com.sunri.model.pipeline.DictatePipeline.start(DictatePipeline.java:32)
at com.sunri.model.pipeline.DictatePipeline.skip(DictatePipeline.java:43)
at com.sunri.model.pipeline.DictatePipeline.start(DictatePipeline.java:32)
at com.sunri.model.pipeline.DictatePipeline.skip(DictatePipeline.java:43)
at com.sunri.model.pipeline.DictatePipeline.start(DictatePipeline.java:32)
at com.sunri.model.pipeline.DictatePipeline.skip(DictatePipeline.java:43)
at com.sunri.model.pipeline.DictatePipeline.start(DictatePipeline.java:32)
at com.sunri.model.pipeline.DictatePipeline.skip(DictatePipeline.java:43)
at com.sunri.model.pipeline.DictatePipeline.start(DictatePipeline.java:32)
at com.sunri.model.pipeline.DictatePipeline.skip(DictatePipeline.java:43)
at com.sunri.model.pipeline.DictatePipeline.start(DictatePipeline.java:32)
at com.sunri.model.pipeline.DictatePipeline.skip(DictatePipeline.java:43)
at com.sunri.model.pipeline.DictatePipeline.start(DictatePipeline.java:32)
at com.sunri.model.pipeline.DictatePipeline.skip(DictatePipeline.java:43)
at com.sunri.model.pipeline.DictatePipeline.start(DictatePipeline.java:32)
at com.sunri.model.supersysmodel.pipeline.DevicePointManager.pointImport(DevicePointManager.java:62)
at com.sunri.model.supersysmodel.SuperSysModelConfiguration.readExcelBytes(SuperSysModelConfiguration.java:2419)
at com.sunri.model.supersysmodel.SuperSysModelConfiguration.devicePointImport(SuperSysModelConfiguration.java:2495)
at com.sunri.service.impl.supersysmodel.SuperSysModelServiceImpl.devicePointImport(SuperSysModelServiceImpl.java:172)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sunri.server.mapper.handler.ByteArrayMethodHandler.proceed(ByteArrayMethodHandler.java:108)
at com.sunri.pipeline.Pipeline.start(Pipeline.java:26)
at com.sunri.pipeline.Pipeline.skip(Pipeline.java:43)
at com.sunri.pipeline.Pipeline.start(Pipeline.java:32)
at com.sunri.server.dispatch.Func.proceed(Func.java:152)
at com.sunri.server.service.impl.RequestServiceImpl.doExec(RequestServiceImpl.java:43)
at com.sunri.server.message.handler.RequestHandler.proceed(RequestHandler.java:30)
at com.sunri.pipeline.Pipeline.start(Pipeline.java:26)
at com.sunri.pipeline.Pipeline.skip(Pipeline.java:43)
at com.sunri.pipeline.Pipeline.start(Pipeline.java:32)
at com.sunri.server.processor.ServerProcessor.doExec(ServerProcessor.java:36)
at com.sunri.server.service.RequestService$Processor$doExec.getResult(RequestService.java:155)
at com.sunri.server.service.RequestService$Processor$doExec.getResult(RequestService.java:135)
at org.apache.thrift.ProcessFunction.process(ProcessFunction.java:38)
at org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:38)
at com.sunri.server.processor.ServerProcessorFactory$RequestServiceProcessor.process(ServerProcessorFactory.java:74)
at org.apache.thrift.TMultiplexedProcessor.process(TMultiplexedProcessor.java:138)
at org.apache.thrift.server.TThreadPoolServer$WorkerProcess.run(TThreadPoolServer.java:250)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
2026-03-31 19:16:52.945 [TThreadPoolServer WorkerProcess-6] INFO com.sunri.model.pipeline.DictatePipeline - [流水线完成] PatrolReportDevicePointRecordPipeLine 处理耗时: 34ms
```
- **完成方案**:
1. 后端:将 PatrolReportDevicePointRecordPipeLine 的去重与处理维度统一改为 devicePointId 全局唯一(跨主设备同点位仅保留最大 id 并删除其余),再基于保留记录更新/插入以彻底避免 Duplicate key。
2. 前端:修复筛选搜索修改设置后同主设备下其他点位配置为空的显示问题
- **完成情况**: 前后端均已修复并验证,同一主设备下多点位配置保存和显示正常
### 2. 与姬工讨论上海导出五通报表的问题 <Badge text="未开始" type="danger" />
- **描述**: 姬工安排讨论上海项目导出五通报表相关需求与问题
- **下一步**:
1. 提前梳理现有报表导出功能逻辑
2. 预约时间与姬工同步讨论细节
### 3. 修复现场linx80 excel打开失败问题 <Badge text="已完成" type="tip" />
- **描述**: 现场linx80设备导出的Excel文件打开失败
- **完成情况**: 经排查为现场系统软件版本过低导致,无需修复,建议升级系统软件版本即可解决
### 4. 告警阈值xml导入限制同一个点位统一各类型只能有一条记录 <Badge text="未开始" type="danger" />
- **描述**: 韩磊要求新增告警阈值xml导入限制同一个点位各类型阈值只能有一条记录
- **下一步**:
1. 梳理现有告警阈值xml导入逻辑
2. 新增同点位同类型阈值重复校验
3. 验证导入功能正常且限制生效

15
src/work/todo/README.md Normal file
View File

@@ -0,0 +1,15 @@
---
icon: mdi:checklist
category:
- 待办
tag:
- 任务清单
title: 待办事项
---
按月份维护待办事项。
## 月度清单
- [4月待办2026-04](./2026-04.md)
- [3月待办2026-03](./2026-03.md)

13
src/work/待办事项.md Normal file
View File

@@ -0,0 +1,13 @@
---
icon: mdi:checklist
category:
- 待办
tag:
- 任务清单
title: 待办事项
---
待办事项已按月份维护。
- 待办首页:[/work/todo/](/work/todo/)
- 3月待办[/work/todo/2026-03.md](/work/todo/2026-03.md)