refactor(homepage): 官网/文档/定价源码迁出程序 + 新增独立授权与激活页 /license
- 官网源码归拢到 homepage/(index/pricing/license + docs.html + content/ + assets/ + docs-assets/),
删除程序内 go:embed 的 server/internal/{site,docs},后端只静态托管 homepage/dist 做本地预览
(dist 缺失时打 warn 日志,不再内置兜底;/home 别名保留供 GUI openExternal 使用)
- 文档 manifest 按现网口径重建:MCP 页标记 hidden(不再进侧栏与搜索)、补 快捷键 页、校正 updated 日期
- 新增独立静态页 /license:交付与激活四步(邮件交付授权码)、LIC- 在线 与 LICOFF- 离线 对比、
授权服务器 licence.rlwj.cn 通信范围说明、授权类型与价格、10 条授权 FAQ
- tools/homepage-build 支持 hidden 页与可选单页,产出 <name>.html 与 <name>/index.html
- 导航/页脚接入 /license,跨页锚点补 / 前缀,页脚底栏文案同步为静态站口径
- 产物零漂移:12 页文档与现网逐字节一致(仅 mcp 隐藏页自身侧栏/上下页行为随之收敛)
This commit is contained in:
1 parent
2c0bfafd8d
commit
bf377f3b55
42 files changed
+1926
-752
No files matched your search
@@ -1,4 +1,4 @@
|
||||
.PHONY: install web gui all server stop status build-web test test-go test-ui desktop
|
||||
.PHONY: install web gui all server stop status build-web test test-go test-ui desktop homepage
|
||||
|
||||
install:
|
||||
npm install
|
||||
@@ -24,6 +24,10 @@ status:
|
||||
desktop:
|
||||
./run.sh desktop
|
||||
|
||||
# homepage = 官网/文档/定价静态站构建(源在 homepage/,产物 homepage/dist)
|
||||
homepage:
|
||||
scripts/build-homepage.sh
|
||||
|
||||
build-web:
|
||||
npm run build:ui
|
||||
|
||||
|
||||
File renamed without changes.
@@ -6,29 +6,27 @@ OpsxDB 是一款**本地优先**的桌面数据库工作台,面向运维与开
|
||||
|
||||
| 能力 | 说明 |
|
||||
| --- | --- |
|
||||
| 多驱动连库 | MySQL 族 / PostgreSQL 族 / SQL Server / Oracle / SQLite / Redis,native Go 驱动编译内置 |
|
||||
| 连接选择器 | 搜索 / 分类 / 最近 / 图标网格;粘贴连接 URL 一键填入表单 |
|
||||
| SQL 工作台 | CodeMirror 编辑器、⌘/Ctrl+Enter 执行语句或选区、多 Tab、可拖分栏 |
|
||||
| 对象树 | 懒加载库 / 表 / 列;点表名直接看前 100 行 |
|
||||
| 结果处理 | 一键复制 / CSV / 生成 INSERT;双击单元格复制;截断有提示 |
|
||||
| Redis 工作台 | 编辑器执行 PING / GET / SET / DEL / KEYS,键空间浏览 |
|
||||
| 安全通道 | 每连接独立配置 SSL/TLS 与 SSH 隧道;密码本机混淆存储 |
|
||||
| AI 面板 | Ask 生成/解释/优化;Agent 真查库(与 MCP 同源只读工具) |
|
||||
| 18 种数据库 | 关系型 / NoSQL / 时序·搜索 / 国产库,全部端到端验收;常用引擎原生内置 |
|
||||
| 连接选择器 | 搜索 / 分类 / 最近 / 图标网格;粘贴连接 URL 一键填入表单;连接颜色标记区分环境 |
|
||||
| SQL 工作台 | CodeMirror 编辑器、⌘/Ctrl+Enter 执行语句或选区、多 Tab、可拖分栏、格式化、执行历史 |
|
||||
| 对象树 | 懒加载库 / 表 / 列 / 索引 / 触发器;点表名直接看前 100 行;右键管理对象 |
|
||||
| 结果处理 | 单元格编辑回写 / 右键复制(值·行·JSON·INSERT)/ CSV·JSON·INSERT 导出 / 过滤构建器 / 分页 |
|
||||
| Redis 工作台 | 单机 / Sentinel / Cluster;键树浏览(SCAN 游标)、TTL、Hash/JSON 编辑、危险命令拦截 |
|
||||
| 安全通道 | 每连接独立配置 SSL/TLS 与 SSH 隧道;后端本机监听 + 访问令牌 |
|
||||
| AI 助手 | 生成 / 解释 / 优化 / 修复 / 方言转换 / 样例;OpenAI 兼容协议 + SSE 流式输出 |
|
||||
| 危险操作防护 | DROP / TRUNCATE / 无 WHERE 的 UPDATE·DELETE 执行前确认 |
|
||||
| 桌面唯一形态 | 桌面 GUI(Tauri 2),本地后端随应用自动拉起 |
|
||||
|
||||
## 支持的数据库
|
||||
|
||||
| 家族 | 覆盖 | 默认端口 |
|
||||
| --- | --- | --- |
|
||||
| MySQL 族 | MySQL · MariaDB · TiDB · OceanBase · PolarDB · TDSQL | 3306 |
|
||||
| PostgreSQL 族 | PostgreSQL · GaussDB / openGauss · 人大金仓 | 5432 |
|
||||
| SQL Server | 原生协议直连 | 1433 |
|
||||
| Oracle | 纯 Go 驱动 go-ora(不引入 JVM) | 1521 |
|
||||
| SQLite | 本地文件库 | — |
|
||||
| Redis | 命令执行 + 键管理 | 6379 |
|
||||
| 家族 | 覆盖 |
|
||||
| --- | --- |
|
||||
| 关系型 | MySQL · MariaDB · TiDB · PostgreSQL · SQL Server · Oracle · SQLite |
|
||||
| NoSQL | Redis · MongoDB |
|
||||
| 时序 / 搜索 | Elasticsearch · ZooKeeper · InfluxDB |
|
||||
| 国产库 | 达梦 DM · OceanBase · GaussDB / openGauss · PolarDB · TDSQL · Kingbase |
|
||||
|
||||
> **提示**:达梦 DM8、MongoDB、ZooKeeper、Elasticsearch、InfluxDB 已列入路线,规划 agent 按需接入。
|
||||
> 逐引擎的接入方式、默认端口与能力边界见《[驱动支持](/docs/drivers)》;全部 18 引擎均已实测验收。
|
||||
|
||||
## 为什么选 OpsxDB
|
||||
|
||||
@@ -20,6 +20,7 @@ npm install
|
||||
## 2. 新建连接
|
||||
|
||||
1. 打开应用,进入**连接选择器**,选择数据库类型(如 MySQL);
|
||||
|
||||
2. 或者直接粘贴连接 URL,点「填入」自动拆解字段:
|
||||
|
||||
```
|
||||
@@ -33,6 +34,7 @@ npm install
|
||||
## 3. 第一次查询
|
||||
|
||||
1. 左侧对象树展开库,**点表名**直接查看前 100 行(展开表可看列结构);
|
||||
|
||||
2. 打开 SQL 编辑器,输入:
|
||||
|
||||
```sql
|
||||
@@ -40,6 +42,7 @@ npm install
|
||||
```
|
||||
|
||||
3. 按 **⌘/Ctrl + Enter** 执行当前语句(或选中的片段);
|
||||
|
||||
4. 结果面板支持**复制 / 导出 CSV / 生成 INSERT**,双击单元格即复制。
|
||||
|
||||
## 4. 验证服务
|
||||
@@ -24,6 +24,8 @@ OpsxDB 的界面为「高频操作」设计:从打开应用到看到数据,
|
||||
|
||||
- 点**表名**:直接打开前 100 行数据;
|
||||
- 展开**表**:查看列结构;
|
||||
- **右键表**:打开表 / 查看 DDL / 生成 SQL(SELECT·INSERT·UPDATE·DELETE)/ 重命名 / 克隆表结构·克隆表(含数据)/ 清空 / 截断 / 删除 —— 危险项红色并二次确认;
|
||||
- **右键库**:新建查询 / 新建表(生成 CREATE TABLE 模板到编辑器)/ 复制 / 设为默认库 / 刷新 / 删除库;
|
||||
- Redis:按键分隔符编文件夹,点键打开类型化详情(TTL / JSON / 增删字段);
|
||||
- 库列表懒加载,大实例也不卡。
|
||||
|
||||
File renamed without changes.
@@ -0,0 +1,49 @@
|
||||
OpsxDB 当前支持 18 种数据库,覆盖关系型、NoSQL、时序/搜索与国产库,全部经真实实例端到端验收(ready + verified)。常用引擎以原生 Go 驱动编译内置,开箱即用;JVM 系数据库通过 Agent 桥按需接入。
|
||||
|
||||
## 完整支持矩阵
|
||||
|
||||
| 数据库 | 类型 | 接入方式 | 默认端口 | 状态 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| MySQL | 关系型 | 原生内置 | 3306 | ✅ 已验收 |
|
||||
| MariaDB | 关系型 | 原生内置 | 3307 | ✅ 已验收 |
|
||||
| TiDB | 关系型 | 原生内置 | 4000 | ✅ 已验收 |
|
||||
| PostgreSQL | 关系型 | 原生内置 | 5432 | ✅ 已验收 |
|
||||
| SQL Server | 关系型 | 原生内置 | 1433 | ✅ 已验收 |
|
||||
| Oracle | 关系型 | 原生内置(go-ora,不引入 JVM) | 1521 | ✅ 已验收 |
|
||||
| SQLite | 关系型 | 原生内置(本地文件) | — | ✅ 已验收 |
|
||||
| MongoDB | NoSQL | Agent 桥(官方驱动) | 27017 | ✅ 已验收 |
|
||||
| Redis | NoSQL | 原生内置 | 6379 | ✅ 已验收 |
|
||||
| Elasticsearch | 时序/搜索 | 原生内置(SQL API) | 9200 | ✅ 已验收 |
|
||||
| ZooKeeper | 时序/搜索 | Agent 桥 | 2181 | ✅ 已验收 |
|
||||
| InfluxDB | 时序/搜索 | 原生内置(Flux) | 8086 | ✅ 已验收 |
|
||||
| 达梦 DM | 国产库 | Agent 桥(JDBC) | 5236 | ✅ 已验收 |
|
||||
| OceanBase | 国产库 | 原生内置(MySQL 协议族) | 2881 | ✅ 已验收 |
|
||||
| GaussDB / openGauss | 国产库 | 原生内置(PG 协议族) | 5432 | ✅ 已验收 |
|
||||
| PolarDB | 国产库 | 原生内置(MySQL 协议族) | 3306 | ✅ 已验收 |
|
||||
| TDSQL | 国产库 | 原生内置(MySQL 协议族) | 3306 | ✅ 已验收 |
|
||||
| Kingbase | 国产库 | 原生内置(PG 协议族) | 54321 | ✅ 已验收 |
|
||||
|
||||
## 协议族复用
|
||||
|
||||
MySQL 族(MySQL / MariaDB / TiDB / OceanBase / PolarDB / TDSQL)共用同一原生驱动,PostgreSQL 族(PostgreSQL / GaussDB / openGauss / Kingbase)同理 —— 同族引擎的连接体验与能力完全一致,仅默认端口不同。
|
||||
|
||||
## Agent 桥驱动(按需下载)
|
||||
|
||||
MongoDB、ZooKeeper、达梦通过 JVM Agent 桥接入:
|
||||
|
||||
- 首次使用时在**驱动管理器**按需下载对应组件,版本固定并做 sha256 校验(Gitee 主源 + GitHub 备源);
|
||||
- 商业数据库(如达梦官方 JDBC)不代下,需自备 jar 放入驱动目录;
|
||||
- Agent 进程随会话池化管理,崩溃自动摘除重建,应用退出级联清理。
|
||||
|
||||
## 各引擎能力边界
|
||||
|
||||
| 引擎 | 浏览 | 执行 | 写入 | 说明 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 关系型全家 | 库/表/视图/存储过程/索引/外键/触发器 | SQL | ✅(含结果集编辑回写) | MySQL 族附执行计划 |
|
||||
| Redis | 键树(SCAN 游标)/ TTL | 命令编辑器 | ✅ | 单机 / Sentinel / Cluster 三模式;危险命令族拦截 |
|
||||
| MongoDB | 库/集合 | `db.coll.find()` DSL | ✅(增删改单文档) | 官方驱动经 Agent 桥 |
|
||||
| ZooKeeper | 路径树 | GET / SET | ✅(写动词二次确认) | 经 Agent 桥 |
|
||||
| Elasticsearch | 索引浏览 | SQL API | 只读 | 官方 JDBC 付费,故走原生 SQL API |
|
||||
| InfluxDB | org/bucket 浏览 | Flux 脚本 | 只读 | 用户=org、密码=token |
|
||||
|
||||
> **说明(Oracle)**:go-ora 纯 Go 驱动,无需安装 Java;Apple Silicon 容器环境起 Oracle XE 会遇到 ORA-00442 属环境限制,x86 或真实实例不受影响。
|
||||
@@ -0,0 +1,47 @@
|
||||
SQL 工作台是日常使用率最高的界面,所有交互围绕「快」设计。
|
||||
|
||||
## 执行模型
|
||||
|
||||
- **⌘/Ctrl + Enter**:执行光标所在的**当前语句**;有选区时执行**选区**;
|
||||
- 不是「整页脚本」模式 —— 多条语句互不干扰,想跑哪句把光标放哪;
|
||||
- Redis 连接共用同一编辑器,按**行**执行命令(见 [Redis 工作台](redis)),不另开 CLI;
|
||||
- 执行在会话上运行,连接断开后自动提示。
|
||||
|
||||
## 多 Tab 与分栏
|
||||
|
||||
- 每个查询一个 Tab,并行执行互不阻塞;
|
||||
- 编辑器 / 结果区可拖动分栏,长查询时编辑器不被结果挤占;
|
||||
- Tab 与布局持久化,重开应用保持原样。
|
||||
|
||||
## 对象树联动
|
||||
|
||||
- 左侧对象树懒加载库 / 表 / 列;
|
||||
- **点表名 = 打开表工作台**(前 100 行 + 条件过滤 + 结构分页),并回填 SELECT;
|
||||
- 展开表看列名与类型,写 SQL 时可对照。
|
||||
|
||||
## 查询历史
|
||||
|
||||
- 本地留存最近 200 条(不上传、不同步);
|
||||
- **相同语句自动去重置顶** —— 历史即「最近用过的不同语句」,高频查询永远在第一条;
|
||||
- 点击条目回填编辑器;悬停出现 **▶** 按钮,回填并直接重跑;
|
||||
- 顶部过滤框支持按语句内容或连接名搜索;
|
||||
- 条目显示时间、连接名、行数与耗时;失败的语句红色标出。
|
||||
|
||||
## 危险 SQL 防护
|
||||
|
||||
执行以下语句前会弹确认框:
|
||||
|
||||
| 类型 | 规则 |
|
||||
| --- | --- |
|
||||
| 删除对象 | DROP / TRUNCATE |
|
||||
| 全表更新 | 无 WHERE 的 UPDATE / DELETE |
|
||||
|
||||
> **注意**:确认框只拦「明确危险」的模式,不替代事务与备份习惯;生产库操作请配合审批流程。
|
||||
|
||||
## 快捷键
|
||||
|
||||
| 快捷键 | 动作 |
|
||||
| --- | --- |
|
||||
| ⌘/Ctrl + Enter | 执行当前语句 / 选区 |
|
||||
| 双击结果单元格 | 复制单元格内容 |
|
||||
| Esc | 关闭弹层 / 取消确认 |
|
||||
@@ -0,0 +1,40 @@
|
||||
查询跑完只是开始,把结果带走才算完成 —— OpsxDB 给了三条最快路径。
|
||||
|
||||
## 三种取数方式
|
||||
|
||||
| 方式 | 用途 |
|
||||
| --- | --- |
|
||||
| **复制** | 直接进剪贴板,贴到群聊 / 文档 / 表格 |
|
||||
| **CSV** | 导出标准 CSV 文件,Excel / Numbers 直接打开 |
|
||||
| **INSERT** | 把结果行生成为 INSERT 语句,直接可在别的库回放 |
|
||||
|
||||
## 表数据工作台(关系库)
|
||||
|
||||
从对象树打开表后,结果区按 DBeaver / DBX 的数据编辑器组织,而不是只有一张裸网格:
|
||||
|
||||
- **工具栏**:刷新、增行、删行、提交(有主键才写回);
|
||||
- **条件过滤**:列 + 运算符(= ≠ > < 包含 空…)+ 值,可加多条 AND;应用后重查,SQL 回填编辑器;
|
||||
- **本页搜索**:不打库,只过滤当前结果;
|
||||
- **列头**:列名 + 类型色 + 主键标记,悬停看注释。
|
||||
|
||||
## 表结构
|
||||
|
||||
「结构」分页签:列 / 索引 / 外键 / 触发器 / DDL。MySQL 族、PostgreSQL 族、SQLite、SQL Server、Oracle 都拉元数据;DDL 可复制或插入编辑器。
|
||||
|
||||
## 单元格操作
|
||||
|
||||
- **双击单元格**:进入编辑(有主键时写回);长文本可展开;
|
||||
- 列头点击排序(仅当前页)。
|
||||
|
||||
## 截断提示
|
||||
|
||||
为保护界面与内存,超大结果集会按阈值截断展示:
|
||||
|
||||
- 结果面板顶部显示「已截断」提示与实际行数;
|
||||
- 需要完整数据时,缩小查询范围(加 LIMIT / WHERE)或使用导出。
|
||||
|
||||
> **提示**:默认「点表名看前 100 行」就是截断策略的一部分 —— 快速浏览用 100 行,精确取数写 WHERE。
|
||||
|
||||
## 与 AI 面板联动
|
||||
|
||||
写不出来的查询可以直接在 AI 面板用自然语言描述(「查最近 7 天下单但未支付的用户」),生成 SQL 后放回编辑器执行,见《AI 助手》。
|
||||
@@ -8,14 +8,14 @@ SQL 工作台已经有:多 Tab、⌘/Ctrl+Enter、查询历史、书签、危
|
||||
|
||||
因此:
|
||||
|
||||
| | SQL | Redis |
|
||||
| | SQL | Redis |
|
||||
| --- | --- | --- |
|
||||
| 输入框 | 同一 CodeMirror | 同一 CodeMirror(占位/补全换成命令) |
|
||||
| 切分 | 分号语句 | **按行**(`SET k "a;b"` 不会被分号拆开) |
|
||||
| 执行 | ⌘/Ctrl+Enter 当前语句或选区 | ⌘/Ctrl+Enter 当前行或选区 |
|
||||
| 结果 | 结果表 | 命令结果表;从对象树打开键则进入键详情 |
|
||||
|
||||
独立 CLI Tab、单行命令与输出日志可在后续评估,不属于当前主路径。
|
||||
Another Redis Desktop Manager 的独立 CLI Tab、opsxsql 的单行命令 + 输出日志,列为后续 P1,不是现在的主路径。
|
||||
|
||||
## 键空间浏览
|
||||
|
||||
@@ -28,7 +28,7 @@ SQL 工作台已经有:多 Tab、⌘/Ctrl+Enter、查询历史、书签、危
|
||||
|
||||
## 键详情
|
||||
|
||||
Hash/List/Set 键详情支持:
|
||||
对标 Another Redis Desktop Manager 的 Hash/List/Set 视图:
|
||||
|
||||
- 类型徽章、键名(回车重命名)、TTL(回车或「保存 TTL」,`-1` 永久)、刷新、导出还原命令、删除;
|
||||
- **结构**表:Hash 为 ID / Field / Value,JSON 值自动美化;可新增字段、编辑、删除;
|
||||
File renamed without changes.
@@ -0,0 +1,39 @@
|
||||
AI 面板的目标:让「写不出的 SQL」和「看不懂的 SQL」不再阻塞你。
|
||||
|
||||
侧栏支持 **Ask | Agent**:Ask 只生成 SQL;Agent 调用与 MCP 同源的只读工具真查库。外部编辑器可用 `npx @rlwj-lab/opsxdb-mcp` 接入(见应用内《AI 助手》文档)。
|
||||
|
||||
## 六种动作
|
||||
|
||||
| 动作 | 用途 |
|
||||
| --- | --- |
|
||||
| 生成 | 自然语言 → SQL(「查最近 7 天下单但未支付的用户」) |
|
||||
| 解释 | 把一段复杂 SQL 翻译成中文说明 |
|
||||
| 优化 | 分析慢查询,给出索引 / 改写建议 |
|
||||
| 修复 | 报错信息 + SQL → 修正版本 |
|
||||
| 方言 | MySQL ↔ PostgreSQL 等跨方言转换 |
|
||||
| 样例 | 按表结构生成示例查询 |
|
||||
|
||||
## 使用方式
|
||||
|
||||
1. 连接库后打开右侧 AI 面板;
|
||||
2. 选择动作,输入需求或粘贴 SQL(可附上对象树上下文);
|
||||
3. 生成结果一键放回编辑器,⌘/Ctrl + Enter 执行。
|
||||
|
||||
> **提示**:生成的 SQL 依旧走危险语句确认流程 —— AI 产出与手写 SQL 同等对待,不放宽防护。
|
||||
|
||||
## 接入真实模型
|
||||
|
||||
AI 面板支持任何 **OpenAI 兼容协议**的服务(OpenAI / DeepSeek / 通义 / 本地 vLLM 等),回复以 **SSE 流式**逐字输出,等待模型时不再面对空白。
|
||||
|
||||
配置入口(二选一):
|
||||
|
||||
1. AI 面板右上角「**配置**」:填 Base URL、API Key、模型名,保存后可一键测试;
|
||||
2. 配置文件 `~/.opsxdb/ai.json`(权限 0600),或环境变量 `OPSXDB_AI_PROVIDER / OPSXDB_AI_BASE_URL / OPSXDB_AI_API_KEY / OPSXDB_AI_MODEL`。
|
||||
|
||||
> **说明**:未配置 API Key 时回落本地 stub(离线占位,内容为模板演示);AI Key 保存后服务端只回显掩码(`sk-***`)。
|
||||
|
||||
## 数据流向承诺
|
||||
|
||||
- 默认只发送你明确提交的内容(附当前库表结构上下文,不含连接凭据);
|
||||
- 可完全关闭 AI 功能(顶栏隐藏面板即可,无后台请求);
|
||||
- 使用云端模型时在界面上明确标识,生成 SQL 依旧走危险语句确认流程。
|
||||
@@ -1,51 +1,40 @@
|
||||
## 产品形态
|
||||
|
||||
**Q:能在浏览器里操作数据库吗?**
|
||||
**Q:能在浏览器里操作数据库吗?**
|
||||
不能。OpsxDB 客户端唯一形态是桌面 App(Tauri 2);浏览器只承载官网与文档(由本地后端 `:8788` 内置提供)。开发时的 `:5174` 只是桌面 devUrl 的资产服务,不是网页客户端。
|
||||
|
||||
**Q:官网和文档部署在哪?**
|
||||
**Q:官网和文档部署在哪?**
|
||||
就内置在你运行的那个二进制里:`http://127.0.0.1:8788/` 是官网,`/docs` 是文档;无需额外部署。
|
||||
|
||||
**Q:怎么打安装包?**
|
||||
**Q:怎么打安装包?**
|
||||
`./run.sh package` 产出 Tauri 安装包(DMG)并内嵌 sidecar 后端二进制。
|
||||
|
||||
## 数据与安全
|
||||
|
||||
**Q:我的连接密码存在哪?**
|
||||
**Q:我的连接密码存在哪?**
|
||||
本机,混淆存储;查询只带会话 ID,密码不会随请求重复上送,也不会同步到云端。
|
||||
|
||||
**Q:会上传我的 SQL 或查询结果吗?**
|
||||
不会。没有遥测、没有账号、没有云依赖;AI 功能当前为本地 stub,接入模型服务时会明确标注数据流向。
|
||||
**Q:会上传我的 SQL 或查询结果吗?**
|
||||
不会。没有遥测、没有账号、没有云依赖。AI 助手为可选功能:只有你主动配置了模型服务并主动提问时,才会把当次请求(含库表结构上下文,不含连接凭据)发给你指定的服务地址。
|
||||
|
||||
**Q:能在公司内网用吗?**
|
||||
**Q:能在公司内网用吗?**
|
||||
能。单二进制 + 内置静态页,无外部依赖;默认只监听回环地址,对外需显式配置。
|
||||
|
||||
## 驱动相关
|
||||
|
||||
**Q:Oracle 能用吗?**
|
||||
**Q:Oracle 能用吗?**
|
||||
驱动代码就绪(go-ora 纯 Go 实现,无需 JVM),但本机 docker 验收在 Apple Silicon 上受镜像限制未通过(ORA-00442),需 x86 环境或真库完成验收,详见《驱动支持》。
|
||||
|
||||
**Q:达梦 / MongoDB 什么时候支持?**
|
||||
**Q:达梦 / MongoDB 什么时候支持?**
|
||||
已列入路线:长尾库(达梦、MongoDB、ZooKeeper、ES、InfluxDB)规划 agent 按需接入,驱动分发走独立仓库并校验 sha256。
|
||||
|
||||
**Q:MySQL 族 / PG 族的国产库怎么连?**
|
||||
**Q:MySQL 族 / PG 族的国产库怎么连?**
|
||||
协议兼容直接复用家族驱动:TiDB / OceanBase / PolarDB / TDSQL 选对应类型(MySQL 协议);GaussDB / Kingbase 走 PostgreSQL 表单。注意各自默认端口与用户名差异。
|
||||
|
||||
## 其他
|
||||
|
||||
**Q:和 OpsxAPI 是什么关系?**
|
||||
**Q:和 OpsxAPI 是什么关系?**
|
||||
同一团队的姊妹项目:OpsxAPI 是接口工作台,OpsxDB 是数据库工作台,共用一套 monorepo 脚手架(web + Gin + 可选 Tauri),产品面各自独立。
|
||||
|
||||
**Q:快捷键有哪些?**
|
||||
**Q:快捷键有哪些?**
|
||||
核心就一个:⌘/Ctrl + Enter 执行当前语句或选区;双击结果单元格复制。完整列表见《SQL 工作台》。
|
||||
|
||||
|
||||
## 如何把 OpsxDB 接到 Cursor?
|
||||
|
||||
安装并配置 MCP:
|
||||
|
||||
```bash
|
||||
npx @rlwj-lab/opsxdb-mcp
|
||||
```
|
||||
|
||||
在 Cursor 的 `mcp.json` 中指向该命令(或本机构建的 `bin/opsxdb-mcp`),并在设置 → MCP 勾选允许访问的连接。新配置默认允许读写与危险 SQL,写入须确认;详见《MCP 接入》。
|
||||
@@ -0,0 +1,48 @@
|
||||
快捷键是 OpsxDB 的第一等操作方式 —— 高频动作全部可以不碰鼠标完成。
|
||||
|
||||
> Windows / Linux 上 `⌘` 对应 `Ctrl`。
|
||||
|
||||
## 全局与工作台
|
||||
|
||||
| 快捷键 | 动作 |
|
||||
| --- | --- |
|
||||
| `⌘ Enter` | 执行当前语句或选区(自动按语句切分) |
|
||||
| `⌘ P` | 快速跳转:模糊搜索库 / 表,Enter 直达数据 |
|
||||
| `⌘ T` | 新建查询 Tab |
|
||||
| `⌘ W` | 关闭当前查询(有未保存改动会确认) |
|
||||
| `⌘ 1–9` | 切到第 N 个查询 |
|
||||
| `Ctrl Tab` | 循环切换查询 |
|
||||
| `Alt ↑ / ↓` | 上一条 / 下一条语句(编辑器内) |
|
||||
| `⌘ ⇧ F` | 聚焦对象树过滤框 |
|
||||
| `F5` | 刷新对象树 |
|
||||
| `⌘ B` | 显示 / 隐藏 AI 面板 |
|
||||
| `⌘ /` | 快捷键帮助 |
|
||||
|
||||
## 结果网格
|
||||
|
||||
| 快捷键 / 操作 | 动作 |
|
||||
| --- | --- |
|
||||
| `↑` `↓` | 上下移动选中行 |
|
||||
| `PgUp` `PgDn` | 翻页移动 |
|
||||
| `Home` `End` | 跳到首行 / 末行 |
|
||||
| 双击单元格 / `Enter` | 进入单元格编辑 |
|
||||
| `Delete` `Backspace` | 清空选中格(进入编辑) |
|
||||
| `⌘ Z`(编辑中) | 撤销本格改动,恢复进入编辑前的值 |
|
||||
| `Esc` | 取消编辑 / 关闭弹层与菜单 |
|
||||
| `Ctrl/⌘ + C` | 复制选中单元格值(无列选中时复制整行 TSV) |
|
||||
| 右键单元格 | 编辑 / 复制单元格值 / 复制行(TSV · JSON · INSERT)/ 查看全文 |
|
||||
| 多格复制粘贴 | 与 Excel 互通:复制区域后直接粘贴进网格批量暂存 |
|
||||
| 双击分栏分隔条 | 结果区最大化 / 还原 |
|
||||
|
||||
## 对象树
|
||||
|
||||
| 操作 | 动作 |
|
||||
| --- | --- |
|
||||
| 双击表名 | 打开表工作台(看前 100 行) |
|
||||
| 右键库 | 新建查询 / 浏览对象 / 复制 / 设为默认库 / 刷新 / 删除库 |
|
||||
| 右键表 / 视图 | 查看数据 / 查看 DDL / 复制 / 清空截断 / 删除表 |
|
||||
| `↑` `↓` `→` `←` `Enter` | 键盘导航(展开 / 收起 / 进入) |
|
||||
|
||||
## SQL 编辑器右键
|
||||
|
||||
编辑器内右键可完成:执行选中语句、执行当前语句、查看数据、查看 DDL、剪切 / 复制 / 粘贴 / 全选 —— 系统默认菜单被替换,不再跳出「Look Up / 检查元素」。
|
||||
File renamed without changes.
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"productVersion": "0.1",
|
||||
"groups": [
|
||||
{
|
||||
"name": "开始使用",
|
||||
"pages": [
|
||||
{ "file": "01-intro.md", "slug": "intro", "title": "产品介绍", "updated": "2026-09-23" },
|
||||
{ "file": "02-quickstart.md", "slug": "quickstart", "title": "快速开始", "updated": "2026-09-20" },
|
||||
{ "file": "03-interface.md", "slug": "interface", "title": "界面导览", "updated": "2026-09-20" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "连接与驱动",
|
||||
"pages": [
|
||||
{ "file": "04-connect.md", "slug": "connect", "title": "新建连接", "updated": "2026-09-20" },
|
||||
{ "file": "05-drivers.md", "slug": "drivers", "title": "驱动支持", "updated": "2026-09-23" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SQL 工作台",
|
||||
"pages": [
|
||||
{ "file": "06-workbench.md", "slug": "workbench", "title": "SQL 工作台", "updated": "2026-09-20" },
|
||||
{ "file": "07-results.md", "slug": "results", "title": "结果与导出", "updated": "2026-09-20" },
|
||||
{ "file": "08-redis.md", "slug": "redis", "title": "Redis 工作台", "updated": "2026-09-20" }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "安全与 AI",
|
||||
"pages": [
|
||||
{ "file": "09-security.md", "slug": "security", "title": "安全设计", "updated": "2026-09-20" },
|
||||
{ "file": "10-ai.md", "slug": "ai", "title": "AI 助手", "updated": "2026-09-23" },
|
||||
{ "file": "13-mcp.md", "slug": "mcp", "title": "MCP 接入", "updated": "2026-10-15", "hidden": true }
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "参考",
|
||||
"pages": [
|
||||
{ "file": "11-faq.md", "slug": "faq", "title": "常见问题", "updated": "2026-09-20" },
|
||||
{ "file": "12-shortcuts.md", "slug": "shortcuts", "title": "快捷键", "updated": "2026-09-23" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Vendored
+1
-1
@@ -1 +1 @@
|
||||
[{"Slug":"intro","Title":"产品介绍","Group":"开始使用","Text":"OpsxDB 是一款 本地优先 的桌面数据库工作台,面向运维与开发:连库、写 SQL、看结果,全在本机完成。 主交付形态是可安装的桌面应用(Tauri 2),本地 Go 后端随应用自动启动;同一套界面也可用单个二进制在 Web / 内网部署。数据全部保存在本机,不经过任何第三方服务器。 功能总览 能力 说明 18 种数据库 关系型 / NoSQL / 时序·搜索 / 国产库,全部端到端验收;常用引擎原生内置 连接选择器 搜索 / 分类 / 最近 / 图标网格;粘贴连接 URL 一键填入表单;连接颜色标记区分环境 SQL 工作台 CodeMirror 编辑器、⌘/Ctrl+Enter 执行语句或选区、多 Tab、可拖分栏、格式化、执行历史 对象树 懒加载库 / 表 / 列 / 索引 / 触发器;点表名直接看前 100 行;右键管理对象 结果处理 单元格编辑回写 / 右键复制(值·行·JSON·INSERT)/ CSV·JSON·INSERT 导出 / 过滤构建器 / 分页 Redis 工作台 单机 / Sentinel / Cluster;键树浏览(SCAN 游标)、TTL、Hash/JSON 编辑、危险命令拦截 安全通道 每连接独立配置 SSL/TLS 与 SSH 隧道;后端本机监听 + 访问令牌 AI 助手 生成 / 解释 / 优化 / 修复 / 方言转换 / 样例;OpenAI 兼容协议 + SSE 流式输出 危险操作防护 DROP / TRUNCATE / 无 WHERE 的 UPDATE·DELETE 执行前确认 桌面唯一形态 桌面 GUI(Tauri 2),本地后端随应用自动拉起 支持的数据库 家族 覆盖 关系型 MySQL · MariaDB · TiDB · PostgreSQL · SQL Server · Oracle · SQLite NoSQL Redis · MongoDB 时序 / 搜索 Elasticsearch · ZooKeeper · InfluxDB 国产库 达梦 DM · OceanBase · GaussDB / openGauss · PolarDB · TDSQL · Kingbase 逐引擎的接入方式、默认端口与能力边界见《 》;全部 18 引擎均已实测验收。 为什么选 OpsxDB 数据主权 :连接配置与查询历史只存在本机;后端默认仅监听 127.0.0.1。 开箱即用 :桌面版双击即用,本地后端随应用自动拉起;官网与文档也由它内置提供。 为快设计 :点表即看数据、⌘Enter 即执行、结果三键取走(复制 / CSV / INSERT)。 轻量克制 :一个 Go 二进制 + 一份前端,内网可部署,无遥测无账号。 提示 :想马上动手?直接看下一章《快速开始》,30 秒连上第一个库。"},{"Slug":"quickstart","Title":"快速开始","Group":"开始使用","Text":"本章从零到出结果:起服务 → 建连接 → 执行第一条 SQL。 1. 启动 桌面版(主交付形态)双击 OpsxDB 应用即可,本地后端随应用自动拉起。 从源码运行(开发): 注意 :客户端只在桌面 App 里运行。 起的 是桌面 devUrl 的资产服务,不是浏览器客户端;浏览器只用于官网 与文档 (后端 直接提供)。 2. 新建连接 1. 打开应用,进入 连接选择器 ,选择数据库类型(如 MySQL); 2. 或者直接粘贴连接 URL,点「填入」自动拆解字段: 3. 点 测试 验证连通性,再点 保存并连接 。 连接配置保存在本机,密码混淆存储;后续查询只携带会话 ID,不再上送账密。 3. 第一次查询 1. 左侧对象树展开库, 点表名 直接查看前 100 行(展开表可看列结构); 2. 打开 SQL 编辑器,输入: 3. 按 ⌘/Ctrl + Enter 执行当前语句(或选中的片段); 4. 结果面板支持 复制 / 导出 CSV / 生成 INSERT ,双击单元格即复制。 4. 验证服务 5. 手边没有数据库? 本地还没有可连的库?用仓库自带的辅助脚本一键起一个(需要 Docker,一次只起一个): 各驱动的验收状态见《驱动支持》。"},{"Slug":"interface","Title":"界面导览","Group":"开始使用","Text":"OpsxDB 的界面为「高频操作」设计:从打开应用到看到数据,路径越短越好。 连接选择器 启动后的第一个界面: 搜索 :按名称快速过滤已保存的连接; 分类 :关系型 / NoSQL / 国产库 / 时序·搜索 分组浏览; 最近 :最近使用的连接排在最前; 图标网格 :按数据库类型直选,未就绪的类型会标注「未就绪」(仅可保存配置); URL 填入 :粘贴 点「填入」,字段自动拆解。 工作台布局 连接成功后进入工作台,三栏结构: 区域 内容 左侧 连接列表 + 对象树(库 → 表 → 列,懒加载) 中部 SQL 编辑器(多 Tab)+ 结果面板,可拖动分栏 右侧 AI 面板(生成 / 解释 / 优化 / 修复 / 方言 / 样例) 对象树 点 表名 :直接打开前 100 行数据; 展开 表 :查看列结构; 右键表 :打开表 / 查看 DDL / 生成 SQL(SELECT·INSERT·UPDATE·DELETE)/ 重命名 / 克隆表结构·克隆表(含数据)/ 清空 / 截断 / 删除 —— 危险项红色并二次确认; 右键库 :新建查询 / 新建表Line truncated
|
||||
[{"Slug":"intro","Title":"产品介绍","Group":"开始使用","Text":"OpsxDB 是一款 本地优先 的桌面数据库工作台,面向运维与开发:连库、写 SQL、看结果,全在本机完成。 主交付形态是可安装的桌面应用(Tauri 2),本地 Go 后端随应用自动启动;同一套界面也可用单个二进制在 Web / 内网部署。数据全部保存在本机,不经过任何第三方服务器。 功能总览 能力 说明 18 种数据库 关系型 / NoSQL / 时序·搜索 / 国产库,全部端到端验收;常用引擎原生内置 连接选择器 搜索 / 分类 / 最近 / 图标网格;粘贴连接 URL 一键填入表单;连接颜色标记区分环境 SQL 工作台 CodeMirror 编辑器、⌘/Ctrl+Enter 执行语句或选区、多 Tab、可拖分栏、格式化、执行历史 对象树 懒加载库 / 表 / 列 / 索引 / 触发器;点表名直接看前 100 行;右键管理对象 结果处理 单元格编辑回写 / 右键复制(值·行·JSON·INSERT)/ CSV·JSON·INSERT 导出 / 过滤构建器 / 分页 Redis 工作台 单机 / Sentinel / Cluster;键树浏览(SCAN 游标)、TTL、Hash/JSON 编辑、危险命令拦截 安全通道 每连接独立配置 SSL/TLS 与 SSH 隧道;后端本机监听 + 访问令牌 AI 助手 生成 / 解释 / 优化 / 修复 / 方言转换 / 样例;OpenAI 兼容协议 + SSE 流式输出 危险操作防护 DROP / TRUNCATE / 无 WHERE 的 UPDATE·DELETE 执行前确认 桌面唯一形态 桌面 GUI(Tauri 2),本地后端随应用自动拉起 支持的数据库 家族 覆盖 关系型 MySQL · MariaDB · TiDB · PostgreSQL · SQL Server · Oracle · SQLite NoSQL Redis · MongoDB 时序 / 搜索 Elasticsearch · ZooKeeper · InfluxDB 国产库 达梦 DM · OceanBase · GaussDB / openGauss · PolarDB · TDSQL · Kingbase 逐引擎的接入方式、默认端口与能力边界见《 》;全部 18 引擎均已实测验收。 为什么选 OpsxDB 数据主权 :连接配置与查询历史只存在本机;后端默认仅监听 127.0.0.1。 开箱即用 :桌面版双击即用,本地后端随应用自动拉起;官网与文档也由它内置提供。 为快设计 :点表即看数据、⌘Enter 即执行、结果三键取走(复制 / CSV / INSERT)。 轻量克制 :一个 Go 二进制 + 一份前端,内网可部署,无遥测无账号。 提示 :想马上动手?直接看下一章《快速开始》,30 秒连上第一个库。"},{"Slug":"quickstart","Title":"快速开始","Group":"开始使用","Text":"本章从零到出结果:起服务 → 建连接 → 执行第一条 SQL。 1. 启动 桌面版(主交付形态)双击 OpsxDB 应用即可,本地后端随应用自动拉起。 从源码运行(开发): 注意 :客户端只在桌面 App 里运行。 起的 是桌面 devUrl 的资产服务,不是浏览器客户端;浏览器只用于官网 与文档 (后端 直接提供)。 2. 新建连接 1. 打开应用,进入 连接选择器 ,选择数据库类型(如 MySQL); 2. 或者直接粘贴连接 URL,点「填入」自动拆解字段: 3. 点 测试 验证连通性,再点 保存并连接 。 连接配置保存在本机,密码混淆存储;后续查询只携带会话 ID,不再上送账密。 3. 第一次查询 1. 左侧对象树展开库, 点表名 直接查看前 100 行(展开表可看列结构); 2. 打开 SQL 编辑器,输入: 3. 按 ⌘/Ctrl + Enter 执行当前语句(或选中的片段); 4. 结果面板支持 复制 / 导出 CSV / 生成 INSERT ,双击单元格即复制。 4. 验证服务 5. 手边没有数据库? 本地还没有可连的库?用仓库自带的辅助脚本一键起一个(需要 Docker,一次只起一个): 各驱动的验收状态见《驱动支持》。"},{"Slug":"interface","Title":"界面导览","Group":"开始使用","Text":"OpsxDB 的界面为「高频操作」设计:从打开应用到看到数据,路径越短越好。 连接选择器 启动后的第一个界面: 搜索 :按名称快速过滤已保存的连接; 分类 :关系型 / NoSQL / 国产库 / 时序·搜索 分组浏览; 最近 :最近使用的连接排在最前; 图标网格 :按数据库类型直选,未就绪的类型会标注「未就绪」(仅可保存配置); URL 填入 :粘贴 点「填入」,字段自动拆解。 工作台布局 连接成功后进入工作台,三栏结构: 区域 内容 左侧 连接列表 + 对象树(库 → 表 → 列,懒加载) 中部 SQL 编辑器(多 Tab)+ 结果面板,可拖动分栏 右侧 AI 面板(生成 / 解释 / 优化 / 修复 / 方言 / 样例) 对象树 点 表名 :直接打开前 100 行数据; 展开 表 :查看列结构; 右键表 :打开表 / 查看 DDL / 生成 SQL(SELECT·INSERT·UPDATE·DELETE)/ 重命名 / 克隆表结构·克隆表(含数据)/ 清空 / 截断 / 删除 —— 危险项红色并二次确认; 右键库 :新建查询 / 新建表Line truncated
|
||||
@@ -35,6 +35,8 @@
|
||||
<a href="#features">功能</a>
|
||||
<a href="#drivers">驱动</a>
|
||||
<a href="#security">安全</a>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权</a>
|
||||
<a href="#download">下载</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">文档</a>
|
||||
</nav>
|
||||
@@ -52,7 +54,7 @@
|
||||
<h1>一个窗口,<br>管好<em>全公司的数据库</em></h1>
|
||||
<p class="hero-sub">
|
||||
连库、写 SQL、看结果,全在本机完成。<br>
|
||||
MySQL / PostgreSQL / SQL Server / Oracle / SQLite / Redis 内置驱动,
|
||||
MySQL / PostgreSQL / SQL Server / Oracle / SQLite / Redis 内置驱动,TiDB · OceanBase · GaussDB · 人大金仓同协议直连,
|
||||
SSH 隧道与 SSL 加密直达内网库,AI 帮你把 SQL 写得又快又稳。
|
||||
</p>
|
||||
<div class="hero-actions">
|
||||
@@ -151,35 +153,11 @@
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-table"/></svg></div><div><h3>结果随手取</h3><p>结果集一键复制 / 导出 CSV / 生成 INSERT;双击单元格即复制,截断行数有提示。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-tree"/></svg></div><div><h3>对象树与表数据</h3><p>懒加载库 / 表 / 列;点表名直接看前 100 行,展开表即看列结构。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-database"/></svg></div><div><h3>Redis 工作台</h3><p>编辑器直接执行 <code>PING</code> / <code>GET</code> / <code>SET</code> / <code>KEYS</code>,键空间浏览、TTL 管理。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-sparkles"/></svg></div><div><h3>AI / MCP</h3><p>Ask 写 SQL;Agent 操作授权连接,写入前逐次确认。设置 → MCP 复制 Cursor / Claude 配置。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-sparkles"/></svg></div><div><h3>AI / MCP</h3><p>Ask 写 SQL;Agent 真查白名单库。可用 <code>npx @rlwj-lab/opsxdb-mcp</code> 接到 Cursor(默认只读)。</p></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<!-- ===================== AI / MCP ===================== -->
|
||||
<section class="section" id="mcp">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">AI / MCP:桌面连库,助手真查库</h2>
|
||||
<p class="sec-sub">MCP-first:Cursor、Claude Code 与侧栏 Agent 共用同一套只读工具与安全策略。</p>
|
||||
<div class="grid g3">
|
||||
<div class="card">
|
||||
<h3>本地优先</h3>
|
||||
<p>连接与策略在本机 <code>~/.opsxdb</code>;查询不经公网中转。默认 <strong>只读</strong>,写操作需显式开启并确认。</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>一键接入</h3>
|
||||
<p><code>npm i -g @rlwj-lab/opsxdb-mcp</code>,在设置 → MCP 复制客户端片段。详见 <a href="/docs/mcp" target="_blank" rel="noopener">MCP 接入文档</a>。</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>Ask | Agent</h3>
|
||||
<p>Ask 只生成 SQL;Agent 多轮调工具查白名单库,步骤时间线可流式展示,结果可插入编辑器或结果区。</p>
|
||||
</div>
|
||||
</div>
|
||||
<p class="footnote" style="margin-top:1.25rem">安全边界:连接白名单、危险 SQL 拦截、审计日志。可写为可选能力,见文档说明。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===================== 驱动矩阵 ===================== -->
|
||||
<section class="section" id="drivers">
|
||||
<div class="wrap">
|
||||
@@ -271,11 +249,9 @@
|
||||
<div class="faq">
|
||||
<details open><summary>我的连接密码保存在哪?安全吗?</summary><p>全部保存在本机(混淆存储),查询时只携带会话 ID,密码不会随每次请求上送,也不会同步到任何云端。</p></details>
|
||||
<details><summary>能在浏览器里操作数据库吗?</summary><p>不能。客户端唯一形态是桌面应用(Tauri 2);浏览器只承载官网与文档,由后端 :8788 内置提供。开发时的 :5174 只是桌面 devUrl 的资产服务。</p></details>
|
||||
<details><summary>OpsxDB 适合哪些场景?</summary><p>OpsxDB 面向运维与开发的日常高频操作(连库、点表、写 SQL、取结果),界面密度和快捷键为「快」设计;本地优先、后端随桌面应用拉起、内置中文文档。重度管理功能(ER 图、数据比对等)在路线图中。</p></details>
|
||||
<details><summary>和 DBeaver / Navicat 有什么差别?</summary><p>OpsxDB 面向运维与开发的日常高频操作(连库、点表、写 SQL、取结果),界面密度和快捷键为「快」设计;本地优先、后端随桌面应用拉起、内置中文文档。重度管理功能(ER 图、数据比对等)在路线图中。</p></details>
|
||||
<details><summary>Oracle 支持好了吗?</summary><p>驱动代码已就绪(纯 Go 的 go-ora,无需 JVM),但本机 docker 验收在 Apple Silicon 上受镜像限制未通过,需 x86 环境或真库完成验收,详见文档《驱动支持》。</p></details>
|
||||
<details><summary>AI 功能需要联网吗?</summary><p>配置云端模型(如 DeepSeek)时,提问与结构上下文会发往该服务;可改用本地兼容端点。MCP / Agent 查库在本机执行;Agent 写入前需确认具体命令。</p></details>
|
||||
<details><summary>如何把 Cursor / Claude 接到 OpsxDB?</summary><p>安装 <code>@rlwj-lab/opsxdb-mcp</code> 并构建 Go 二进制,在桌面 <strong>设置 → MCP</strong> 勾选连接白名单、复制对应客户端配置。完整步骤见 <a href="/docs/mcp" target="_blank" rel="noopener">MCP 接入</a>。</p></details>
|
||||
|
||||
<details><summary>AI 功能需要联网吗?</summary><p>配置云端模型(如 DeepSeek)时,提问与结构上下文会发往该服务;可改用本地兼容端点。MCP / Agent 查库始终在本机执行,默认只读。</p></details>
|
||||
<details><summary>支持达梦 / MongoDB 吗?</summary><p>已列入路线:常用库 native 内置,长尾库(达梦、MongoDB、ZooKeeper、ES、InfluxDB)规划 agent 按需接入,驱动分发走独立仓库并校验 sha256。</p></details>
|
||||
</div>
|
||||
</div>
|
||||
@@ -308,8 +284,9 @@
|
||||
</div>
|
||||
<div>
|
||||
<h4>资源</h4>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权与激活</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">用户文档</a>
|
||||
<a href="/docs/mcp" target="_blank" rel="noopener">MCP 接入</a>
|
||||
<a href="/docs/drivers" target="_blank" rel="noopener">驱动验收状态</a>
|
||||
<a href="/docs/faq" target="_blank" rel="noopener">常见问题</a>
|
||||
</div>
|
||||
@@ -320,7 +297,7 @@
|
||||
<a href="/docs/quickstart" target="_blank" rel="noopener">快速开始</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bar">© 2026 OpsxDB · 本页由单二进制内置提供(/ · /home)</div>
|
||||
<div class="footer-bar">© 2026 OpsxDB · <a href="/pricing">定价</a> · <a href="/license">授权与激活</a> · <a href="/docs" target="_blank" rel="noopener">文档</a></div>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
Vendored
+5
-2
@@ -36,7 +36,8 @@
|
||||
<a href="#drivers">驱动</a>
|
||||
<a href="#security">安全</a>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="#download">下载</a>
|
||||
<a href="/license">授权</a>
|
||||
<a href="#download">下载</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">文档</a>
|
||||
</nav>
|
||||
<div class="nav-cta">
|
||||
@@ -283,6 +284,8 @@
|
||||
</div>
|
||||
<div>
|
||||
<h4>资源</h4>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权与激活</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">用户文档</a>
|
||||
<a href="/docs/drivers" target="_blank" rel="noopener">驱动验收状态</a>
|
||||
<a href="/docs/faq" target="_blank" rel="noopener">常见问题</a>
|
||||
@@ -294,7 +297,7 @@
|
||||
<a href="/docs/quickstart" target="_blank" rel="noopener">快速开始</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bar">© 2026 OpsxDB · 本页由单二进制内置提供(/ · /home)</div>
|
||||
<div class="footer-bar">© 2026 OpsxDB · <a href="/pricing">定价</a> · <a href="/license">授权与激活</a> · <a href="/docs" target="_blank" rel="noopener">文档</a></div>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
|
||||
Vendored
+212
@@ -0,0 +1,212 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>授权与激活 · OpsxDB</title>
|
||||
<meta name="description" content="OpsxDB 授权与激活说明:付款后邮件交付授权码(LIC-),在「设置 → 授权」粘贴即完成激活;生产内网可用 LICOFF- 离线许可证,一机一码、支持自助解绑换机。">
|
||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%2264%22%20y2%3D%2264%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22%23059669%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%2306B6D4%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%2264%22%20height%3D%2264%22%20rx%3D%2214%22%20fill%3D%22url%28%23g%29%22%2F%3E%3Cg%20stroke%3D%22%23fff%22%20stroke-width%3D%224.5%22%20fill%3D%22none%22%20stroke-linecap%3D%22round%22%3E%3Cellipse%20cx%3D%2232%22%20cy%3D%2220%22%20rx%3D%2215%22%20ry%3D%226.5%22%2F%3E%3Cpath%20d%3D%22M17%2020v24c0%203.6%206.7%206.5%2015%206.5s15-2.9%2015-6.5V20%22%2F%3E%3Cpath%20d%3D%22M17%2032c0%203.6%206.7%206.5%2015%206.5s15-2.9%2015-6.5%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E">
|
||||
<link rel="stylesheet" href="/site/assets/site.css">
|
||||
<style>
|
||||
/* 授权页专用样式(lic- 前缀,避免与站点既有类冲突) // Logan.Li */
|
||||
.lic-hero{padding:72px 0 30px;text-align:center;}
|
||||
.lic-hero h1{font-size:clamp(28px,4.5vw,42px);margin:12px 0 10px;}
|
||||
.lic-hero .lead{max-width:780px;margin:0 auto;font-size:15px;line-height:1.9;opacity:.75;}
|
||||
.lic-chip{display:inline-flex;align-items:center;gap:8px;padding:7px 16px;border-radius:999px;border:1px solid var(--green,#059669);color:var(--green,#059669);font-size:13px;font-weight:600;}
|
||||
.lic-steps{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px 16px;margin:22px 0 0;}
|
||||
@media (max-width:720px){.lic-steps{grid-template-columns:1fr;}}
|
||||
.lic-step{position:relative;border:1px solid var(--border);border-radius:calc(var(--radius,14px) + 2px);padding:22px 18px 18px;background:var(--bg);}
|
||||
.lic-step .n{position:absolute;top:-11px;left:18px;background:var(--green,#059669);color:#fff;font-size:11.5px;font-weight:700;padding:2px 10px;border-radius:999px;letter-spacing:.03em;}
|
||||
.lic-step h3{margin:4px 0 8px;font-size:15.5px;}
|
||||
.lic-step p{margin:0;font-size:13.5px;line-height:1.9;opacity:.78;}
|
||||
.lic-cmp-wrap{overflow-x:auto;margin-top:20px;}
|
||||
.lic-cmp{width:100%;min-width:640px;border-collapse:collapse;font-size:14px;background:var(--bg);}
|
||||
.lic-cmp th,.lic-cmp td{border-bottom:1px solid var(--border);padding:12px;text-align:left;vertical-align:top;}
|
||||
.lic-cmp thead th{font-size:13.5px;letter-spacing:.02em;}
|
||||
.lic-cmp tbody th{width:132px;font-weight:600;color:var(--text-3,#98a2b3);}
|
||||
.lic-cmp code{font-family:var(--mono,monospace);font-size:12.5px;background:rgba(127,127,127,.14);padding:1px 5px;border-radius:4px;}
|
||||
.lic-faq{max-width:880px;margin:0 auto;}
|
||||
.lic-faq details{border-bottom:1px solid var(--border);padding:15px 4px;}
|
||||
.lic-faq summary{cursor:pointer;font-weight:600;font-size:15px;list-style:none;display:flex;justify-content:space-between;gap:12px;align-items:center;}
|
||||
.lic-faq summary::after{content:"+";opacity:.5;font-size:18px;line-height:1;}
|
||||
.lic-faq details[open] summary::after{content:"–";}
|
||||
.lic-faq details p{margin:10px 0 2px;font-size:14px;line-height:1.9;opacity:.78;}
|
||||
.lic-note{max-width:880px;margin:16px auto 0;font-size:13px;line-height:1.9;opacity:.68;}
|
||||
.lic-cta{text-align:center;max-width:680px;margin:0 auto;}
|
||||
.lic-cta .btns{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin-top:20px;}
|
||||
.lic-scope{max-width:880px;margin:24px auto 0;font-size:13.5px;line-height:1.95;opacity:.78;}
|
||||
.lic-scope li{margin:6px 0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header class="nav">
|
||||
<div class="nav-inner">
|
||||
<a class="brand" href="/">
|
||||
<span class="brand-logo"><svg width="30" height="30" viewBox="0 0 64 64" aria-label="OpsxDB"><defs><linearGradient id="lg-site" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#059669"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-site)"/><g stroke="#fff" stroke-width="4.5" fill="none" stroke-linecap="round"><ellipse cx="32" cy="20" rx="15" ry="6.5"/><path d="M17 20v24c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5V20"/><path d="M17 32c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5"/></g></svg></span>
|
||||
<span class="brand-name">OpsxDB</span>
|
||||
</a>
|
||||
<nav class="nav-links">
|
||||
<a href="/#features">功能</a>
|
||||
<a href="/#drivers">驱动</a>
|
||||
<a href="/#security">安全</a>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权</a>
|
||||
<a href="/#download">下载</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">文档</a>
|
||||
</nav>
|
||||
<div class="nav-cta">
|
||||
<a class="btn btn-primary" href="/docs/quickstart" target="_blank" rel="noopener">快速开始 →</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="lic-hero">
|
||||
<span class="lic-chip">30 天免费试用 · 首次启动自动开始 · 无需注册</span>
|
||||
<h1>授权与激活</h1>
|
||||
<p class="lead">一次说清四件事:怎么买、授权码怎么交付、程序里怎么激活、换机与断网怎么办。授权绑定设备而非账号,全流程不需要注册。</p>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">交付与激活:四步</h2>
|
||||
<p class="sec-sub">从下单到激活通常当天完成,最短几分钟。</p>
|
||||
<div class="lic-steps">
|
||||
<div class="lic-step">
|
||||
<span class="n">STEP 1</span>
|
||||
<h3>下单确认</h3>
|
||||
<p>邮件说明产品、授权类型(包年 / 永久 / 团队席位)与设备数量。支持对公转账与开具发票,工作日当天回复。</p>
|
||||
</div>
|
||||
<div class="lic-step">
|
||||
<span class="n">STEP 2</span>
|
||||
<h3>邮件交付授权码</h3>
|
||||
<p>付款确认后即刻签发,授权码以邮件送达你的邮箱:联网用 <code>LIC-</code> 前缀的在线授权码,隔离内网用 <code>LICOFF-</code> 前缀的离线许可证。</p>
|
||||
</div>
|
||||
<div class="lic-step">
|
||||
<span class="n">STEP 3</span>
|
||||
<h3>应用内激活</h3>
|
||||
<p>打开「设置 → 授权」,粘贴授权码点击激活。程序连接授权服务器 <code>licence.rlwj.cn</code> 登记本机设备并回写一次性激活令牌,此后每 7 天自动校验一次。</p>
|
||||
</div>
|
||||
<div class="lic-step">
|
||||
<span class="n">STEP 4</span>
|
||||
<h3>换机与续期</h3>
|
||||
<p>在本机自助解绑即可把席位迁到新机器,每年免费换绑 2 次;到期前 30 天邮件提醒,续期后签发新授权码替换即可。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section alt">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">两种激活方式</h2>
|
||||
<p class="sec-sub">能联网就用在线授权码,完全不出网就用离线许可证——功能与有效期一致。</p>
|
||||
<div class="lic-cmp-wrap">
|
||||
<table class="lic-cmp">
|
||||
<thead>
|
||||
<tr><th>对比项</th><th>在线授权码 <code>LIC-</code></th><th>离线许可证 <code>LICOFF-</code></th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><th>是否联网</th><td>激活时联网一次,之后每 7 天校验一次</td><td>全程无需联网,本地验签</td></tr>
|
||||
<tr><th>设备绑定</th><td>绑定设备 ID,一机一码</td><td>绑定设备 ID,一机一码</td></tr>
|
||||
<tr><th>断网可用</th><td>激活后可连续离线使用 30 天</td><td>始终有效,与网络无关</td></tr>
|
||||
<tr><th>有效期</th><td>包年 365 天;永久授权长期有效</td><td>单张最长 365 天,可续签</td></tr>
|
||||
<tr><th>换绑</th><td>应用内自助解绑,每年免费换绑 2 次</td><td>邮件换取新证并解绑旧设备</td></tr>
|
||||
<tr><th>适合场景</th><td>办公网、开发机、云主机</td><td>生产内网、专有云、隔离环境</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="lic-scope">
|
||||
<p><b>授权服务器会收到什么?</b>客户端只与 <code>licence.rlwj.cn</code>(443)通信,用于设备登记与周期校验,只发送授权码与设备标识(设备 ID、设备名称)——不发送连接串、库表名、SQL 语句与查询结果等任何业务数据。服务端返回 Ed25519 签名,客户端本地验签,验签失败按未授权处理。</p>
|
||||
<ul>
|
||||
<li>内网只放行白名单出网:把 <code>licence.rlwj.cn</code> 加入白名单,或直接使用离线许可证。</li>
|
||||
<li>授权服务器不可达:按宽限期继续可用,业务不会当场中断;恢复网络后自动补校验。</li>
|
||||
<li>不想让客户端出网:一律选离线许可证,客户端永不发起网络请求。</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">授权类型与价格</h2>
|
||||
<p class="sec-sub">个人非商业用途免费;工作中的商业用途需要授权。</p>
|
||||
<div class="lic-cmp-wrap">
|
||||
<table class="lic-cmp">
|
||||
<thead>
|
||||
<tr><th>授权</th><th>价格</th><th>设备数</th><th>包含</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><th>个人 · 非商业</th><td>¥0</td><td>不涉及授权</td><td>日常连库、写 SQL、看结果;商业用途需购买授权</td></tr>
|
||||
<tr><th>专业版 · 包年</th><td>¥99 / 年</td><td>3 台</td><td>全部内置驱动(含国产库)、SQL 执行与导出转储、SSH 隧道与 SSL、AI SQL 助手、设备自助解绑</td></tr>
|
||||
<tr><th>专业版 · 永久</th><td>¥199 一次性</td><td>5 台</td><td>包年全部能力,一次买断、无续费</td></tr>
|
||||
<tr><th>团队版</th><td>¥99 / 人 / 年</td><td>按席位,5 席起</td><td>个人版全部能力 + 共享连接库(自托管)、驱动离线包分发、优先支持</td></tr>
|
||||
<tr><th>企业私有化</th><td>¥6,000 / 年(标价)</td><td>单法人不限席位</td><td>内网部署、数据不出企业、远程部署协助、定制开发通道</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="lic-note">完整功能对比、让利与组合报价见 <a href="/pricing">定价页</a>。表中为标价,成交可按规模与场景议价。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section alt">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">授权常见问题</h2>
|
||||
<div class="lic-faq">
|
||||
<details><summary>授权码多久能收到?</summary><p>付款确认后即刻签发并邮件发出,工作日通常当天完成(含开票需求)。邮件里就是完整授权码,无需注册账号或登录任何后台。</p></details>
|
||||
<details><summary>授权绑定设备还是账号?</summary><p>绑定设备。每台机器有唯一设备 ID,一个授权码按授权的设备数占座,与账号无关;团队版按席位签发多个授权码,组织内可转移。</p></details>
|
||||
<details><summary>换电脑 / 重装系统后设备 ID 变了怎么办?</summary><p>旧机还在:在「设置 → 授权」点解绑,腾出席位后在新机激活。旧机已不在手:邮件与我们说明(附授权码后四位与新设备 ID),由我们在授权后台释放旧设备。每年免费换绑 2 次。</p></details>
|
||||
<details><summary>断网了授权会失效吗?</summary><p>不会。离线许可证本地自验,永不联网也有效;在线授权码激活后可连续离线使用 30 天,超时后联网校验一次即可继续。授权服务器不可达时按宽限期放行,不会打断正在执行的查询。</p></details>
|
||||
<details><summary>生产内网完全不出网,怎么激活?</summary><p>改用离线许可证(<code>LICOFF-</code>):在应用内导出本机机器码,邮件发我们换取离线证,本地导入即完成激活,全程不需要客户端联网——数据库连接与查询本来就在本机完成。</p></details>
|
||||
<details><summary>续期怎么操作?</summary><p>到期前 30 天我们会邮件提醒。付款后签发新的授权码,在「设置 → 授权」里替换旧码即可,同一台设备无需先解绑;永久授权无需续期。</p></details>
|
||||
<details><summary>试用期结束后我的连接配置和数据还在吗?</summary><p>都在。授权只控制专业功能是否可用,本机连接配置、查询历史与 ~/.opsxdb 下的数据不做任何改动;试用结束后个人非商业用途可继续使用,购买授权后专业功能立即恢复。</p></details>
|
||||
<details><summary>激活失败怎么排查?</summary><p>先在「设置 → 授权」看当前状态与到期时间。若提示无效或不匹配,请把授权码后四位、设备 ID 与报错截图一并发邮件,我们核对授权服务器上的记录后处理(常见原因是设备数已占满或授权码输漏字符)。</p></details>
|
||||
<details><summary>能开发票、走对公转账吗?</summary><p>可以。个人与企业均可开具发票,支持对公转账、多产品捆绑与批量授权;邮件说明抬头与税号即可。</p></details>
|
||||
<details><summary>三个产品(OpsxDB / OpsxAPI / OpsXShell)要分别买吗?</summary><p>三个产品独立授权、独立计价;它们共用同一套授权体系(同一个设备 ID 规则与同一个授权服务器)。多产品组合、团队或教育用途可邮件说明需求,给捆绑价。</p></details>
|
||||
</div>
|
||||
<p class="lic-note">本页更新于 2026-10-16,授权口径与授权服务器 <code>licence.rlwj.cn</code> 实际配置一致。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="wrap lic-cta">
|
||||
<h2 class="sec-title">准备好购买授权</h2>
|
||||
<p class="sec-sub">邮件说明产品、授权类型与设备数,当天回复并开票。</p>
|
||||
<div class="btns">
|
||||
<a class="btn btn-primary" href="mailto:hello@opsxapi.dev?subject=OpsxDB%20%E6%8E%88%E6%9D%83%E4%B8%8E%E6%BF%80%E6%B4%BB%E5%92%A8%E8%AF%A2">邮件咨询购买</a>
|
||||
<a class="btn btn-ghost" href="/#download">还没装?立即下载</a>
|
||||
</div>
|
||||
<p class="lic-note">付款后当场发放授权码(LIC-),粘贴到「设置 → 授权」即完成激活——整个流程无需注册账号。</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrap footer-grid">
|
||||
<div>
|
||||
<div class="brand"><span class="brand-logo"><svg width="30" height="30" viewBox="0 0 64 64" aria-label="OpsxDB"><defs><linearGradient id="lg-foot" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#059669"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-foot)"/><g stroke="#fff" stroke-width="4.5" fill="none" stroke-linecap="round"><ellipse cx="32" cy="20" rx="15" ry="6.5"/><path d="M17 20v24c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5V20"/><path d="M17 32c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5"/></g></svg></span><span class="brand-name">OpsxDB</span></div>
|
||||
<p class="footer-desc">本地优先的桌面数据库工作台。<br>数据在自己手里,才是真的效率工具。</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4>产品</h4>
|
||||
<a href="/#features">功能特性</a>
|
||||
<a href="/#drivers">数据库支持</a>
|
||||
<a href="/#download">下载与形态</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>资源</h4>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权与激活</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">用户文档</a>
|
||||
<a href="/docs/faq" target="_blank" rel="noopener">常见问题</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>安全</h4>
|
||||
<a href="/#security">安全设计</a>
|
||||
<a href="/docs/security" target="_blank" rel="noopener">SSL 与 SSH 隧道</a>
|
||||
<a href="/docs/quickstart" target="_blank" rel="noopener">快速开始</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bar">© 2026 OpsxDB · <a href="/pricing">定价</a> · <a href="/license">授权与激活</a></div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
Vendored
+212
@@ -0,0 +1,212 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>授权与激活 · OpsxDB</title>
|
||||
<meta name="description" content="OpsxDB 授权与激活说明:付款后邮件交付授权码(LIC-),在「设置 → 授权」粘贴即完成激活;生产内网可用 LICOFF- 离线许可证,一机一码、支持自助解绑换机。">
|
||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%2264%22%20y2%3D%2264%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22%23059669%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%2306B6D4%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%2264%22%20height%3D%2264%22%20rx%3D%2214%22%20fill%3D%22url%28%23g%29%22%2F%3E%3Cg%20stroke%3D%22%23fff%22%20stroke-width%3D%224.5%22%20fill%3D%22none%22%20stroke-linecap%3D%22round%22%3E%3Cellipse%20cx%3D%2232%22%20cy%3D%2220%22%20rx%3D%2215%22%20ry%3D%226.5%22%2F%3E%3Cpath%20d%3D%22M17%2020v24c0%203.6%206.7%206.5%2015%206.5s15-2.9%2015-6.5V20%22%2F%3E%3Cpath%20d%3D%22M17%2032c0%203.6%206.7%206.5%2015%206.5s15-2.9%2015-6.5%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E">
|
||||
<link rel="stylesheet" href="/site/assets/site.css">
|
||||
<style>
|
||||
/* 授权页专用样式(lic- 前缀,避免与站点既有类冲突) // Logan.Li */
|
||||
.lic-hero{padding:72px 0 30px;text-align:center;}
|
||||
.lic-hero h1{font-size:clamp(28px,4.5vw,42px);margin:12px 0 10px;}
|
||||
.lic-hero .lead{max-width:780px;margin:0 auto;font-size:15px;line-height:1.9;opacity:.75;}
|
||||
.lic-chip{display:inline-flex;align-items:center;gap:8px;padding:7px 16px;border-radius:999px;border:1px solid var(--green,#059669);color:var(--green,#059669);font-size:13px;font-weight:600;}
|
||||
.lic-steps{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px 16px;margin:22px 0 0;}
|
||||
@media (max-width:720px){.lic-steps{grid-template-columns:1fr;}}
|
||||
.lic-step{position:relative;border:1px solid var(--border);border-radius:calc(var(--radius,14px) + 2px);padding:22px 18px 18px;background:var(--bg);}
|
||||
.lic-step .n{position:absolute;top:-11px;left:18px;background:var(--green,#059669);color:#fff;font-size:11.5px;font-weight:700;padding:2px 10px;border-radius:999px;letter-spacing:.03em;}
|
||||
.lic-step h3{margin:4px 0 8px;font-size:15.5px;}
|
||||
.lic-step p{margin:0;font-size:13.5px;line-height:1.9;opacity:.78;}
|
||||
.lic-cmp-wrap{overflow-x:auto;margin-top:20px;}
|
||||
.lic-cmp{width:100%;min-width:640px;border-collapse:collapse;font-size:14px;background:var(--bg);}
|
||||
.lic-cmp th,.lic-cmp td{border-bottom:1px solid var(--border);padding:12px;text-align:left;vertical-align:top;}
|
||||
.lic-cmp thead th{font-size:13.5px;letter-spacing:.02em;}
|
||||
.lic-cmp tbody th{width:132px;font-weight:600;color:var(--text-3,#98a2b3);}
|
||||
.lic-cmp code{font-family:var(--mono,monospace);font-size:12.5px;background:rgba(127,127,127,.14);padding:1px 5px;border-radius:4px;}
|
||||
.lic-faq{max-width:880px;margin:0 auto;}
|
||||
.lic-faq details{border-bottom:1px solid var(--border);padding:15px 4px;}
|
||||
.lic-faq summary{cursor:pointer;font-weight:600;font-size:15px;list-style:none;display:flex;justify-content:space-between;gap:12px;align-items:center;}
|
||||
.lic-faq summary::after{content:"+";opacity:.5;font-size:18px;line-height:1;}
|
||||
.lic-faq details[open] summary::after{content:"–";}
|
||||
.lic-faq details p{margin:10px 0 2px;font-size:14px;line-height:1.9;opacity:.78;}
|
||||
.lic-note{max-width:880px;margin:16px auto 0;font-size:13px;line-height:1.9;opacity:.68;}
|
||||
.lic-cta{text-align:center;max-width:680px;margin:0 auto;}
|
||||
.lic-cta .btns{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin-top:20px;}
|
||||
.lic-scope{max-width:880px;margin:24px auto 0;font-size:13.5px;line-height:1.95;opacity:.78;}
|
||||
.lic-scope li{margin:6px 0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header class="nav">
|
||||
<div class="nav-inner">
|
||||
<a class="brand" href="/">
|
||||
<span class="brand-logo"><svg width="30" height="30" viewBox="0 0 64 64" aria-label="OpsxDB"><defs><linearGradient id="lg-site" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#059669"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-site)"/><g stroke="#fff" stroke-width="4.5" fill="none" stroke-linecap="round"><ellipse cx="32" cy="20" rx="15" ry="6.5"/><path d="M17 20v24c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5V20"/><path d="M17 32c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5"/></g></svg></span>
|
||||
<span class="brand-name">OpsxDB</span>
|
||||
</a>
|
||||
<nav class="nav-links">
|
||||
<a href="/#features">功能</a>
|
||||
<a href="/#drivers">驱动</a>
|
||||
<a href="/#security">安全</a>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权</a>
|
||||
<a href="/#download">下载</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">文档</a>
|
||||
</nav>
|
||||
<div class="nav-cta">
|
||||
<a class="btn btn-primary" href="/docs/quickstart" target="_blank" rel="noopener">快速开始 →</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="lic-hero">
|
||||
<span class="lic-chip">30 天免费试用 · 首次启动自动开始 · 无需注册</span>
|
||||
<h1>授权与激活</h1>
|
||||
<p class="lead">一次说清四件事:怎么买、授权码怎么交付、程序里怎么激活、换机与断网怎么办。授权绑定设备而非账号,全流程不需要注册。</p>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">交付与激活:四步</h2>
|
||||
<p class="sec-sub">从下单到激活通常当天完成,最短几分钟。</p>
|
||||
<div class="lic-steps">
|
||||
<div class="lic-step">
|
||||
<span class="n">STEP 1</span>
|
||||
<h3>下单确认</h3>
|
||||
<p>邮件说明产品、授权类型(包年 / 永久 / 团队席位)与设备数量。支持对公转账与开具发票,工作日当天回复。</p>
|
||||
</div>
|
||||
<div class="lic-step">
|
||||
<span class="n">STEP 2</span>
|
||||
<h3>邮件交付授权码</h3>
|
||||
<p>付款确认后即刻签发,授权码以邮件送达你的邮箱:联网用 <code>LIC-</code> 前缀的在线授权码,隔离内网用 <code>LICOFF-</code> 前缀的离线许可证。</p>
|
||||
</div>
|
||||
<div class="lic-step">
|
||||
<span class="n">STEP 3</span>
|
||||
<h3>应用内激活</h3>
|
||||
<p>打开「设置 → 授权」,粘贴授权码点击激活。程序连接授权服务器 <code>licence.rlwj.cn</code> 登记本机设备并回写一次性激活令牌,此后每 7 天自动校验一次。</p>
|
||||
</div>
|
||||
<div class="lic-step">
|
||||
<span class="n">STEP 4</span>
|
||||
<h3>换机与续期</h3>
|
||||
<p>在本机自助解绑即可把席位迁到新机器,每年免费换绑 2 次;到期前 30 天邮件提醒,续期后签发新授权码替换即可。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section alt">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">两种激活方式</h2>
|
||||
<p class="sec-sub">能联网就用在线授权码,完全不出网就用离线许可证——功能与有效期一致。</p>
|
||||
<div class="lic-cmp-wrap">
|
||||
<table class="lic-cmp">
|
||||
<thead>
|
||||
<tr><th>对比项</th><th>在线授权码 <code>LIC-</code></th><th>离线许可证 <code>LICOFF-</code></th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><th>是否联网</th><td>激活时联网一次,之后每 7 天校验一次</td><td>全程无需联网,本地验签</td></tr>
|
||||
<tr><th>设备绑定</th><td>绑定设备 ID,一机一码</td><td>绑定设备 ID,一机一码</td></tr>
|
||||
<tr><th>断网可用</th><td>激活后可连续离线使用 30 天</td><td>始终有效,与网络无关</td></tr>
|
||||
<tr><th>有效期</th><td>包年 365 天;永久授权长期有效</td><td>单张最长 365 天,可续签</td></tr>
|
||||
<tr><th>换绑</th><td>应用内自助解绑,每年免费换绑 2 次</td><td>邮件换取新证并解绑旧设备</td></tr>
|
||||
<tr><th>适合场景</th><td>办公网、开发机、云主机</td><td>生产内网、专有云、隔离环境</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="lic-scope">
|
||||
<p><b>授权服务器会收到什么?</b>客户端只与 <code>licence.rlwj.cn</code>(443)通信,用于设备登记与周期校验,只发送授权码与设备标识(设备 ID、设备名称)——不发送连接串、库表名、SQL 语句与查询结果等任何业务数据。服务端返回 Ed25519 签名,客户端本地验签,验签失败按未授权处理。</p>
|
||||
<ul>
|
||||
<li>内网只放行白名单出网:把 <code>licence.rlwj.cn</code> 加入白名单,或直接使用离线许可证。</li>
|
||||
<li>授权服务器不可达:按宽限期继续可用,业务不会当场中断;恢复网络后自动补校验。</li>
|
||||
<li>不想让客户端出网:一律选离线许可证,客户端永不发起网络请求。</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">授权类型与价格</h2>
|
||||
<p class="sec-sub">个人非商业用途免费;工作中的商业用途需要授权。</p>
|
||||
<div class="lic-cmp-wrap">
|
||||
<table class="lic-cmp">
|
||||
<thead>
|
||||
<tr><th>授权</th><th>价格</th><th>设备数</th><th>包含</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><th>个人 · 非商业</th><td>¥0</td><td>不涉及授权</td><td>日常连库、写 SQL、看结果;商业用途需购买授权</td></tr>
|
||||
<tr><th>专业版 · 包年</th><td>¥99 / 年</td><td>3 台</td><td>全部内置驱动(含国产库)、SQL 执行与导出转储、SSH 隧道与 SSL、AI SQL 助手、设备自助解绑</td></tr>
|
||||
<tr><th>专业版 · 永久</th><td>¥199 一次性</td><td>5 台</td><td>包年全部能力,一次买断、无续费</td></tr>
|
||||
<tr><th>团队版</th><td>¥99 / 人 / 年</td><td>按席位,5 席起</td><td>个人版全部能力 + 共享连接库(自托管)、驱动离线包分发、优先支持</td></tr>
|
||||
<tr><th>企业私有化</th><td>¥6,000 / 年(标价)</td><td>单法人不限席位</td><td>内网部署、数据不出企业、远程部署协助、定制开发通道</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="lic-note">完整功能对比、让利与组合报价见 <a href="/pricing">定价页</a>。表中为标价,成交可按规模与场景议价。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section alt">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">授权常见问题</h2>
|
||||
<div class="lic-faq">
|
||||
<details><summary>授权码多久能收到?</summary><p>付款确认后即刻签发并邮件发出,工作日通常当天完成(含开票需求)。邮件里就是完整授权码,无需注册账号或登录任何后台。</p></details>
|
||||
<details><summary>授权绑定设备还是账号?</summary><p>绑定设备。每台机器有唯一设备 ID,一个授权码按授权的设备数占座,与账号无关;团队版按席位签发多个授权码,组织内可转移。</p></details>
|
||||
<details><summary>换电脑 / 重装系统后设备 ID 变了怎么办?</summary><p>旧机还在:在「设置 → 授权」点解绑,腾出席位后在新机激活。旧机已不在手:邮件与我们说明(附授权码后四位与新设备 ID),由我们在授权后台释放旧设备。每年免费换绑 2 次。</p></details>
|
||||
<details><summary>断网了授权会失效吗?</summary><p>不会。离线许可证本地自验,永不联网也有效;在线授权码激活后可连续离线使用 30 天,超时后联网校验一次即可继续。授权服务器不可达时按宽限期放行,不会打断正在执行的查询。</p></details>
|
||||
<details><summary>生产内网完全不出网,怎么激活?</summary><p>改用离线许可证(<code>LICOFF-</code>):在应用内导出本机机器码,邮件发我们换取离线证,本地导入即完成激活,全程不需要客户端联网——数据库连接与查询本来就在本机完成。</p></details>
|
||||
<details><summary>续期怎么操作?</summary><p>到期前 30 天我们会邮件提醒。付款后签发新的授权码,在「设置 → 授权」里替换旧码即可,同一台设备无需先解绑;永久授权无需续期。</p></details>
|
||||
<details><summary>试用期结束后我的连接配置和数据还在吗?</summary><p>都在。授权只控制专业功能是否可用,本机连接配置、查询历史与 ~/.opsxdb 下的数据不做任何改动;试用结束后个人非商业用途可继续使用,购买授权后专业功能立即恢复。</p></details>
|
||||
<details><summary>激活失败怎么排查?</summary><p>先在「设置 → 授权」看当前状态与到期时间。若提示无效或不匹配,请把授权码后四位、设备 ID 与报错截图一并发邮件,我们核对授权服务器上的记录后处理(常见原因是设备数已占满或授权码输漏字符)。</p></details>
|
||||
<details><summary>能开发票、走对公转账吗?</summary><p>可以。个人与企业均可开具发票,支持对公转账、多产品捆绑与批量授权;邮件说明抬头与税号即可。</p></details>
|
||||
<details><summary>三个产品(OpsxDB / OpsxAPI / OpsXShell)要分别买吗?</summary><p>三个产品独立授权、独立计价;它们共用同一套授权体系(同一个设备 ID 规则与同一个授权服务器)。多产品组合、团队或教育用途可邮件说明需求,给捆绑价。</p></details>
|
||||
</div>
|
||||
<p class="lic-note">本页更新于 2026-10-16,授权口径与授权服务器 <code>licence.rlwj.cn</code> 实际配置一致。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="wrap lic-cta">
|
||||
<h2 class="sec-title">准备好购买授权</h2>
|
||||
<p class="sec-sub">邮件说明产品、授权类型与设备数,当天回复并开票。</p>
|
||||
<div class="btns">
|
||||
<a class="btn btn-primary" href="mailto:hello@opsxapi.dev?subject=OpsxDB%20%E6%8E%88%E6%9D%83%E4%B8%8E%E6%BF%80%E6%B4%BB%E5%92%A8%E8%AF%A2">邮件咨询购买</a>
|
||||
<a class="btn btn-ghost" href="/#download">还没装?立即下载</a>
|
||||
</div>
|
||||
<p class="lic-note">付款后当场发放授权码(LIC-),粘贴到「设置 → 授权」即完成激活——整个流程无需注册账号。</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrap footer-grid">
|
||||
<div>
|
||||
<div class="brand"><span class="brand-logo"><svg width="30" height="30" viewBox="0 0 64 64" aria-label="OpsxDB"><defs><linearGradient id="lg-foot" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#059669"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-foot)"/><g stroke="#fff" stroke-width="4.5" fill="none" stroke-linecap="round"><ellipse cx="32" cy="20" rx="15" ry="6.5"/><path d="M17 20v24c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5V20"/><path d="M17 32c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5"/></g></svg></span><span class="brand-name">OpsxDB</span></div>
|
||||
<p class="footer-desc">本地优先的桌面数据库工作台。<br>数据在自己手里,才是真的效率工具。</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4>产品</h4>
|
||||
<a href="/#features">功能特性</a>
|
||||
<a href="/#drivers">数据库支持</a>
|
||||
<a href="/#download">下载与形态</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>资源</h4>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权与激活</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">用户文档</a>
|
||||
<a href="/docs/faq" target="_blank" rel="noopener">常见问题</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>安全</h4>
|
||||
<a href="/#security">安全设计</a>
|
||||
<a href="/docs/security" target="_blank" rel="noopener">SSL 与 SSH 隧道</a>
|
||||
<a href="/docs/quickstart" target="_blank" rel="noopener">快速开始</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bar">© 2026 OpsxDB · <a href="/pricing">定价</a> · <a href="/license">授权与激活</a></div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
Vendored
+13
-10
@@ -45,16 +45,17 @@
|
||||
</svg>
|
||||
<header class="nav">
|
||||
<div class="nav-inner">
|
||||
<a class="brand" href="/home">
|
||||
<a class="brand" href="/">
|
||||
<span class="brand-logo"><svg width="30" height="30" viewBox="0 0 64 64" aria-label="OpsxDB"><defs><linearGradient id="lg-site" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#059669"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-site)"/><g stroke="#fff" stroke-width="4.5" fill="none" stroke-linecap="round"><ellipse cx="32" cy="20" rx="15" ry="6.5"/><path d="M17 20v24c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5V20"/><path d="M17 32c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5"/></g></svg></span>
|
||||
<span class="brand-name">OpsxDB</span>
|
||||
</a>
|
||||
<nav class="nav-links">
|
||||
<a href="#features">功能</a>
|
||||
<a href="#drivers">驱动</a>
|
||||
<a href="#security">安全</a>
|
||||
<a href="/#features">功能</a>
|
||||
<a href="/#drivers">驱动</a>
|
||||
<a href="/#security">安全</a>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="#download">下载</a>
|
||||
<a href="/license">授权</a>
|
||||
<a href="/#download">下载</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">文档</a>
|
||||
</nav>
|
||||
<div class="nav-cta">
|
||||
@@ -163,24 +164,26 @@
|
||||
</div>
|
||||
<div>
|
||||
<h4>产品</h4>
|
||||
<a href="#features">功能特性</a>
|
||||
<a href="#drivers">数据库支持</a>
|
||||
<a href="#download">下载与形态</a>
|
||||
<a href="/#features">功能特性</a>
|
||||
<a href="/#drivers">数据库支持</a>
|
||||
<a href="/#download">下载与形态</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>资源</h4>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权与激活</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">用户文档</a>
|
||||
<a href="/docs/drivers" target="_blank" rel="noopener">驱动验收状态</a>
|
||||
<a href="/docs/faq" target="_blank" rel="noopener">常见问题</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>安全</h4>
|
||||
<a href="#security">安全设计</a>
|
||||
<a href="/#security">安全设计</a>
|
||||
<a href="/docs/security" target="_blank" rel="noopener">SSL 与 SSH 隧道</a>
|
||||
<a href="/docs/quickstart" target="_blank" rel="noopener">快速开始</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bar">© 2026 OpsxDB · 本页由单二进制内置提供(/ · /home)</div>
|
||||
<div class="footer-bar">© 2026 OpsxDB · <a href="/pricing">定价</a> · <a href="/license">授权与激活</a> · <a href="/docs" target="_blank" rel="noopener">文档</a></div>
|
||||
</footer>
|
||||
<script>
|
||||
document.querySelectorAll('.toggle').forEach(function(t){
|
||||
|
||||
Vendored
+202
@@ -0,0 +1,202 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>授权与定价 · OpsxDB</title>
|
||||
<meta name="description" content="OpsxDB 定价:30 天全功能试用;专业版 ¥99/年或 ¥199 永久,团队版 ¥99/人/年,企业私有化 ¥6,000/年。支持在线授权与离线激活。">
|
||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%2264%22%20y2%3D%2264%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22%23059669%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%2206B6D4%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%2264%22%20height%3D%2264%22%20rx%3D%2214%22%20fill%3D%22url(%23g)%22%2F%3E%3Cg%20stroke%3D%22%23fff%22%20stroke-width%3D%224.5%22%20fill%3D%22none%22%20stroke-linecap%3D%22round%22%3E%3Cellipse%20cx%3D%2232%22%20cy%3D%2220%22%20rx%3D%2215%22%20ry%3D%226.5%22%2F%3E%3Cpath%20d%3D%22M17%2020v24c0%203.6%206.7%206.5%2015%206.5s15-2.9%2015-6.5V20%22%2F%3E%3Cpath%20d%3D%22M17%2032c0%203.6%206.7%206.5%2015%206.5s15-2.9%2015-6.5%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E">
|
||||
<link rel="stylesheet" href="/site/assets/site.css">
|
||||
<style>
|
||||
.trial-hero{padding:72px 0 28px;text-align:center;}
|
||||
.trial-hero h1{font-size:clamp(28px,4.5vw,44px);margin:14px 0 10px;}
|
||||
.trial-hero .lead{max-width:720px;margin:0 auto;opacity:.75;line-height:1.8;}
|
||||
.trial-strip{display:inline-flex;gap:8px;align-items:center;padding:7px 16px;border-radius:999px;border:1px solid var(--accent,#2563eb);color:var(--accent,#2563eb);font-size:13px;font-weight:600;}
|
||||
.toggle{display:inline-flex;border:1px solid var(--border,#d8dee9);border-radius:999px;padding:3px;gap:2px;margin:14px auto 0;}
|
||||
.toggle button{border:0;background:transparent;padding:6px 18px;border-radius:999px;font-size:13px;font-weight:600;color:inherit;opacity:.65;cursor:pointer;}
|
||||
.toggle button.on{background:var(--accent,#2563eb);color:#fff;opacity:1;}
|
||||
.price-num b{font-size:34px;}
|
||||
.faq{max-width:820px;margin:0 auto;}
|
||||
.faq details{border-bottom:1px solid var(--border,#e5e9f0);padding:16px 4px;}
|
||||
.faq summary{cursor:pointer;font-weight:600;font-size:15px;list-style:none;display:flex;justify-content:space-between;align-items:center;}
|
||||
.faq summary::after{content:"+";font-size:18px;opacity:.5;}
|
||||
.faq details[open] summary::after{content:"–";}
|
||||
.faq details p{margin:10px 0 2px;opacity:.72;line-height:1.85;font-size:14px;}
|
||||
.indie{text-align:center;opacity:.7;font-size:14px;line-height:1.9;max-width:560px;margin:0 auto;}
|
||||
.act-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px;margin-top:22px;text-align:left;}
|
||||
.act-grid .card h3{display:flex;align-items:center;gap:8px;margin:0 0 6px;font-size:15px;}
|
||||
.act-grid .card p{margin:0;opacity:.7;font-size:13px;line-height:1.8;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">
|
||||
<symbol id="i-database" viewBox="0 0 24 24"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14a9 3 0 0 0 18 0V5"/><path d="M3 12a9 3 0 0 0 18 0"/></symbol>
|
||||
<symbol id="i-shield-check" viewBox="0 0 24 24"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/></symbol>
|
||||
<symbol id="i-terminal" viewBox="0 0 24 24"><polyline points="4 17 10 11 4 5"/><line x1="12" x2="20" y1="19" y2="19"/></symbol>
|
||||
<symbol id="i-table" viewBox="0 0 24 24"><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M3 9h18"/><path d="M3 15h18"/><path d="M9 3v18"/><path d="M15 3v18"/></symbol>
|
||||
<symbol id="i-tree" viewBox="0 0 24 24"><path d="M13 10h7a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z"/><path d="M13 21h7a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z"/><path d="M3 5a2 2 0 0 0 2 2h3"/><path d="M3 3v13a2 2 0 0 0 2 2h3"/></symbol>
|
||||
<symbol id="i-zap" viewBox="0 0 24 24"><path d="M15.914 4a1.5 1.5 0 00-2.474-1.561l-9 9A1.5 1.5 0 005.5 14h4.002a.5.5 0 01.471.666L8.086 20a1.5 1.5 0 002.475 1.56l9-9A1.5 1.5 0 0018.5 10h-3.997a.5.5 0 01-.472-.667z"/></symbol>
|
||||
<symbol id="i-sparkles" viewBox="0 0 24 24"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/><path d="M20 3v4"/><path d="M22 5h-4"/></symbol>
|
||||
<symbol id="i-key" viewBox="0 0 24 24"><circle cx="7.5" cy="15.5" r="5.5"/><path d="m21 2-9.6 9.6"/><path d="m15.5 7.5 3 3L22 7l-3-3"/></symbol>
|
||||
<symbol id="i-monitor" viewBox="0 0 24 24"><rect width="20" height="14" x="2" y="3" rx="2"/><line x1="8" x2="16" y1="21" y2="21"/><line x1="12" x2="12" y1="17" y2="21"/></symbol>
|
||||
<symbol id="i-server" viewBox="0 0 24 24"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"/><rect width="20" height="8" x="2" y="14" rx="2" ry="2"/><line x1="6" x2="6.01" y1="6" y2="6"/><line x1="6" x2="6.01" y1="18" y2="18"/></symbol>
|
||||
<symbol id="i-clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></symbol>
|
||||
<symbol id="i-clipboard" viewBox="0 0 24 24"><rect width="8" height="4" x="8" y="2" rx="1" ry="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/></symbol>
|
||||
</svg>
|
||||
<header class="nav">
|
||||
<div class="nav-inner">
|
||||
<a class="brand" href="/">
|
||||
<span class="brand-logo"><svg width="30" height="30" viewBox="0 0 64 64" aria-label="OpsxDB"><defs><linearGradient id="lg-site" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#059669"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-site)"/><g stroke="#fff" stroke-width="4.5" fill="none" stroke-linecap="round"><ellipse cx="32" cy="20" rx="15" ry="6.5"/><path d="M17 20v24c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5V20"/><path d="M17 32c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5"/></g></svg></span>
|
||||
<span class="brand-name">OpsxDB</span>
|
||||
</a>
|
||||
<nav class="nav-links">
|
||||
<a href="/#features">功能</a>
|
||||
<a href="/#drivers">驱动</a>
|
||||
<a href="/#security">安全</a>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权</a>
|
||||
<a href="/#download">下载</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">文档</a>
|
||||
</nav>
|
||||
<div class="nav-cta">
|
||||
<a class="btn btn-primary" href="/docs/quickstart" target="_blank" rel="noopener">快速开始 →</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main>
|
||||
<section class="trial-hero">
|
||||
<span class="trial-strip"><svg class="i"><use href="#i-rocket"/></svg> 30 天免费试用 · 首次启动自动开始 · 无需注册</span>
|
||||
<h1>授权与定价</h1>
|
||||
<p class="lead">OpsxDB 对个人非商业用途永久免费;在工作中商用需要授权。授权绑定设备,支持在线激活(LIC-)与完全离线激活(LICOFF-)。</p>
|
||||
</section>
|
||||
|
||||
<section class="section" style="padding-top:26px">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">先试用,再决定</h2>
|
||||
<p class="sec-sub">下载即含 30 天全功能试用;激活支持在线与离线两种方式。</p>
|
||||
<div class="act-grid">
|
||||
<div class="card"><h3><svg class="i"><use href="#i-rocket"/></svg>30 天全功能试用</h3><p>首次启动自动开始;无需注册、无需信用卡。试用期覆盖全部连接与 AI 能力。</p></div>
|
||||
<div class="card"><h3><svg class="i"><use href="#i-globe"/></svg>在线授权 LIC-</h3><p>联网激活并绑定设备;支持自助解绑换机;激活后可连续离线使用 30 天。</p></div>
|
||||
<div class="card"><h3><svg class="i"><use href="#i-shield-check"/></svg>离线许可证 LICOFF-</h3><p>Ed25519 自包含签名,绑定设备;完全无网络也能激活,适合隔离内网环境。</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section alt">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">选择适合的授权</h2>
|
||||
<p class="sec-sub">个人版可选年付或一次性买断;团队按席位;私有化面向单法人不限席位。</p>
|
||||
<div class="pricing three">
|
||||
<div class="price-card">
|
||||
<div class="plan">专业版</div>
|
||||
<div class="toggle" data-mode="year"><button class="on" data-mode="year">¥99 / 年</button><button data-mode="life">永久 ¥199</button></div>
|
||||
<div class="price price-num"><b data-price="year">¥99</b><b data-price="life" style="display:none">¥199</b><span>/ 年</span></div>
|
||||
<div class="plan-sub">包年 3 台 / 永久 5 台设备</div>
|
||||
<ul>
|
||||
<li>全部内置驱动连接(含国产库)</li>
|
||||
<li>SQL 执行 / 结果导出 / 转储</li>
|
||||
<li>SSH 隧道与 SSL 加密</li>
|
||||
<li>AI SQL 助手(自带 Key)</li>
|
||||
<li>设备可自助解绑迁移</li>
|
||||
</ul>
|
||||
<a class="btn btn-primary" href="mailto:hello@opsxapi.dev?subject=OpsxDB%20%E4%B8%AA%E4%BA%BA%E7%89%88%E8%B4%AD%E4%B9%B0">购买咨询</a>
|
||||
</div>
|
||||
<div class="price-card featured">
|
||||
<div class="plan-tag">团队首选</div>
|
||||
<div class="plan">团队版</div>
|
||||
<div class="price price-num"><b>¥99</b><span>/ 人 / 年</span></div>
|
||||
<div class="plan-sub">按席位 · 5 席起 · 组织内可转移</div>
|
||||
<ul>
|
||||
<li>个人版全部能力</li>
|
||||
<li>共享连接库(自托管)</li>
|
||||
<li>统一驱动离线包分发</li>
|
||||
<li>优先技术支持</li>
|
||||
<li>1 年免费升级</li>
|
||||
</ul>
|
||||
<a class="btn btn-primary" href="mailto:hello@opsxapi.dev?subject=OpsxDB%20%E5%9B%A2%E9%98%9F%E7%89%88%E8%B4%AD%E4%B9%B0">联系商务</a>
|
||||
</div>
|
||||
<div class="price-card enterprise">
|
||||
<div class="plan-tag dark">私有化 · 不限席位</div>
|
||||
<div class="plan">企业私有化版</div>
|
||||
<div class="price price-num"><b>¥6,000</b><span>/ 年 · 标价</span></div>
|
||||
<div class="plan-sub">单法人不限席位 · 支持买断</div>
|
||||
<ul>
|
||||
<li>内网部署,数据不出企业</li>
|
||||
<li>团队版全部能力</li>
|
||||
<li>远程部署协助</li>
|
||||
<li>定制开发通道(另行报价)</li>
|
||||
</ul>
|
||||
<a class="btn btn-dark" href="mailto:hello@opsxapi.dev?subject=OpsxDB%20%E7%A7%81%E6%9C%89%E5%8C%96%E8%B4%AD%E4%B9%B0">获取报价</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="deal-note" style="text-align:center">支付后当场发放授权码(LIC-),粘贴到「设置 → 授权」即完成激活——整个流程无需注册账号;许可证一机一码绑定设备,每年可免费换绑 2 次。<br>购买咨询邮件请注明「OpsxDB」——Opsx 系列同一位开发者,多产品捆绑可议价。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">常见问题</h2>
|
||||
<div class="faq">
|
||||
<details><summary>试用是怎么计算的?</summary><p>30 天全功能试用,从应用首次启动那一刻自动开始——无需注册账号,无需信用卡。试用期结束后,个人非商业用途可继续使用;在工作中的商业用途需要购买授权。</p></details>
|
||||
<details><summary>在线授权和离线激活有什么区别?</summary><p>在线授权码(LIC- 前缀):联网激活,绑定设备,支持在设置中自助解绑换机;激活后可连续离线使用最长 30 天。离线许可证(LICOFF- 前缀):同样绑定设备,但采用 Ed25519 自包含签名,在完全无网络的环境也能激活——适合隔离内网。两种方式在「设置 → 授权」中粘贴即用。</p></details>
|
||||
<details><summary>一个授权能用几台设备?</summary><p>授权绑定设备而非订阅账号。个人版最多 3 台设备;设备可以在「设置 → 授权」中解绑后迁移到新机器。</p></details>
|
||||
<details><summary>断网了授权会失效吗?</summary><p>离线许可证(LICOFF-)本地自验,永不联网也有效。在线授权(LIC-)容忍连续 30 天离线,超过后需联网重新验证一次。</p></details>
|
||||
<details><summary>退款政策是怎样的?</summary><p>自付款之日起 30 天内无理由全额退款——先用起来,不满意直接退。</p></details>
|
||||
<details><summary>怎么购买?</summary><p>邮件咨询购买(请注明 OpsxDB),当天回复;支持对公转账与开票。团队与私有化支持按规模议价。</p></details>
|
||||
<details><summary>三个产品(OpsxAPI / OpsxDB / OpsXShell)要分别买吗?</summary><p>三个产品独立授权、独立计价。多产品组合或学生优惠可直接邮件说明需求,给捆绑价。</p></details>
|
||||
<details><summary>授权包含哪些升级?</summary><p>年付授权含 1 年免费升级;终身授权包含后续版本更新。</p></details>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section alt">
|
||||
<div class="wrap indie">
|
||||
<p><b>独立开发,认真长跑。</b><br>Opsx 系列工具由独立开发者打造,每一份授权的收入都直接投入产品迭代——没有投资人,也没有广告。</p>
|
||||
<p style="margin-top:14px"><a class="btn btn-primary" href="/#download">还没装?立即下载</a></p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<footer class="footer">
|
||||
<div class="wrap footer-grid">
|
||||
<div>
|
||||
<div class="brand"><span class="brand-logo"><svg width="30" height="30" viewBox="0 0 64 64" aria-label="OpsxDB"><defs><linearGradient id="lg-foot" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#059669"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-foot)"/><g stroke="#fff" stroke-width="4.5" fill="none" stroke-linecap="round"><ellipse cx="32" cy="20" rx="15" ry="6.5"/><path d="M17 20v24c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5V20"/><path d="M17 32c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5"/></g></svg></span><span class="brand-name">OpsxDB</span></div>
|
||||
<p class="footer-desc">本地优先的桌面数据库工作台。<br>数据在自己手里,才是真的效率工具。</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4>产品</h4>
|
||||
<a href="/#features">功能特性</a>
|
||||
<a href="/#drivers">数据库支持</a>
|
||||
<a href="/#download">下载与形态</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>资源</h4>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权与激活</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">用户文档</a>
|
||||
<a href="/docs/drivers" target="_blank" rel="noopener">驱动验收状态</a>
|
||||
<a href="/docs/faq" target="_blank" rel="noopener">常见问题</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>安全</h4>
|
||||
<a href="/#security">安全设计</a>
|
||||
<a href="/docs/security" target="_blank" rel="noopener">SSL 与 SSH 隧道</a>
|
||||
<a href="/docs/quickstart" target="_blank" rel="noopener">快速开始</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bar">© 2026 OpsxDB · <a href="/pricing">定价</a> · <a href="/license">授权与激活</a> · <a href="/docs" target="_blank" rel="noopener">文档</a></div>
|
||||
</footer>
|
||||
<script>
|
||||
document.querySelectorAll('.toggle').forEach(function(t){
|
||||
t.addEventListener('click', function(e){
|
||||
if(e.target.tagName!=='BUTTON')return;
|
||||
t.querySelectorAll('button').forEach(function(b){b.classList.remove('on')});
|
||||
e.target.classList.add('on');
|
||||
t.dataset.mode = e.target.dataset.mode;
|
||||
t.closest('.price-card').querySelectorAll('[data-price]').forEach(function(el){
|
||||
el.style.display = el.dataset.price===t.dataset.mode ? '' : 'none';
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,304 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>OpsxDB — 本地优先的桌面数据库工作台</title>
|
||||
<meta name="description" content="OpsxDB:连库、写 SQL、看结果,全在本机完成。MySQL / PostgreSQL / SQL Server / Oracle / SQLite / Redis 一个窗口管完,SSH 隧道与 SSL 加密,AI 辅助写 SQL。">
|
||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%2264%22%20y2%3D%2264%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22%23059669%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%2206B6D4%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%2264%22%20height%3D%2264%22%20rx%3D%2214%22%20fill%3D%22url(%23g)%22%2F%3E%3Cg%20stroke%3D%22%23fff%22%20stroke-width%3D%224.5%22%20fill%3D%22none%22%20stroke-linecap%3D%22round%22%3E%3Cellipse%20cx%3D%2232%22%20cy%3D%2220%22%20rx%3D%2215%22%20ry%3D%226.5%22%2F%3E%3Cpath%20d%3D%22M17%2020v24c0%203.6%206.7%206.5%2015%206.5s15-2.9%2015-6.5V20%22%2F%3E%3Cpath%20d%3D%22M17%2032c0%203.6%206.7%206.5%2015%206.5s15-2.9%2015-6.5%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E">
|
||||
<link rel="stylesheet" href="/site/assets/site.css">
|
||||
</head>
|
||||
<body>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">
|
||||
<symbol id="i-database" viewBox="0 0 24 24"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14a9 3 0 0 0 18 0V5"/><path d="M3 12a9 3 0 0 0 18 0"/></symbol>
|
||||
<symbol id="i-shield-check" viewBox="0 0 24 24"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/></symbol>
|
||||
<symbol id="i-terminal" viewBox="0 0 24 24"><polyline points="4 17 10 11 4 5"/><line x1="12" x2="20" y1="19" y2="19"/></symbol>
|
||||
<symbol id="i-table" viewBox="0 0 24 24"><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M3 9h18"/><path d="M3 15h18"/><path d="M9 3v18"/><path d="M15 3v18"/></symbol>
|
||||
<symbol id="i-tree" viewBox="0 0 24 24"><path d="M13 10h7a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z"/><path d="M13 21h7a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z"/><path d="M3 5a2 2 0 0 0 2 2h3"/><path d="M3 3v13a2 2 0 0 0 2 2h3"/></symbol>
|
||||
<symbol id="i-zap" viewBox="0 0 24 24"><path d="M15.914 4a1.5 1.5 0 00-2.474-1.561l-9 9A1.5 1.5 0 005.5 14h4.002a.5.5 0 01.471.666L8.086 20a1.5 1.5 0 002.475 1.56l9-9A1.5 1.5 0 0018.5 10h-3.997a.5.5 0 01-.472-.667z"/></symbol>
|
||||
<symbol id="i-sparkles" viewBox="0 0 24 24"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/><path d="M20 3v4"/><path d="M22 5h-4"/></symbol>
|
||||
<symbol id="i-key" viewBox="0 0 24 24"><circle cx="7.5" cy="15.5" r="5.5"/><path d="m21 2-9.6 9.6"/><path d="m15.5 7.5 3 3L22 7l-3-3"/></symbol>
|
||||
<symbol id="i-monitor" viewBox="0 0 24 24"><rect width="20" height="14" x="2" y="3" rx="2"/><line x1="8" x2="16" y1="21" y2="21"/><line x1="12" x2="12" y1="17" y2="21"/></symbol>
|
||||
<symbol id="i-server" viewBox="0 0 24 24"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"/><rect width="20" height="8" x="2" y="14" rx="2" ry="2"/><line x1="6" x2="6.01" y1="6" y2="6"/><line x1="6" x2="6.01" y1="18" y2="18"/></symbol>
|
||||
<symbol id="i-clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></symbol>
|
||||
<symbol id="i-clipboard" viewBox="0 0 24 24"><rect width="8" height="4" x="8" y="2" rx="1" ry="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/></symbol>
|
||||
</svg>
|
||||
|
||||
<!-- ===================== 导航 ===================== -->
|
||||
<header class="nav">
|
||||
<div class="nav-inner">
|
||||
<a class="brand" href="/home">
|
||||
<span class="brand-logo"><svg width="30" height="30" viewBox="0 0 64 64" aria-label="OpsxDB"><defs><linearGradient id="lg-site" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#059669"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-site)"/><g stroke="#fff" stroke-width="4.5" fill="none" stroke-linecap="round"><ellipse cx="32" cy="20" rx="15" ry="6.5"/><path d="M17 20v24c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5V20"/><path d="M17 32c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5"/></g></svg></span>
|
||||
<span class="brand-name">OpsxDB</span>
|
||||
</a>
|
||||
<nav class="nav-links">
|
||||
<a href="#features">功能</a>
|
||||
<a href="#drivers">驱动</a>
|
||||
<a href="#security">安全</a>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权</a>
|
||||
<a href="#download">下载</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">文档</a>
|
||||
</nav>
|
||||
<div class="nav-cta">
|
||||
<a class="btn btn-primary" href="/docs/quickstart" target="_blank" rel="noopener">快速开始 →</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- ===================== Hero ===================== -->
|
||||
<section class="hero">
|
||||
<div class="hero-inner">
|
||||
<div class="hero-copy">
|
||||
<div class="hero-badge"><svg class="i"><use href="#i-sparkles"/></svg> v0.1 · 桌面 GUI · 数据 100% 本机</div>
|
||||
<h1>一个窗口,<br>管好<em>全公司的数据库</em></h1>
|
||||
<p class="hero-sub">
|
||||
连库、写 SQL、看结果,全在本机完成。<br>
|
||||
MySQL / PostgreSQL / SQL Server / Oracle / SQLite / Redis 内置驱动,TiDB · OceanBase · GaussDB · 人大金仓同协议直连,
|
||||
SSH 隧道与 SSL 加密直达内网库,AI 帮你把 SQL 写得又快又稳。
|
||||
</p>
|
||||
<div class="hero-actions">
|
||||
<a class="btn btn-primary btn-lg" href="#download">下载桌面版</a>
|
||||
<a class="btn btn-ghost btn-lg" href="/docs/quickstart" target="_blank" rel="noopener">30 秒连上第一个库 →</a>
|
||||
</div>
|
||||
<div class="hero-pills">
|
||||
<span>本地优先</span><span>SSH 隧道</span><span>SSL 加密</span><span>国产库兼容</span><span>AI / MCP</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 工作台示意(纯 CSS 绘制) -->
|
||||
<div class="mock" aria-hidden="true">
|
||||
<div class="mock-titlebar"><i></i><i></i><i></i><span>OpsxDB · prod-mysql</span></div>
|
||||
<div class="mock-body">
|
||||
<div class="mock-side">
|
||||
<div class="mock-search"></div>
|
||||
<div class="mock-item conn"><i class="dot on"></i>prod-mysql</div>
|
||||
<div class="mock-item conn"><i class="dot on"></i>pg-analytics</div>
|
||||
<div class="mock-item conn"><i class="dot"></i>sqlite-demo</div>
|
||||
<div class="mock-group">shop(库)</div>
|
||||
<div class="mock-item active"><svg class="mi"><use href="#i-table"/></svg> orders</div>
|
||||
<div class="mock-item"><svg class="mi"><use href="#i-table"/></svg> users</div>
|
||||
<div class="mock-item"><svg class="mi"><use href="#i-table"/></svg> products</div>
|
||||
</div>
|
||||
<div class="mock-main">
|
||||
<div class="mock-tabs"><span class="tab on">orders · 前 100 行</span><span class="tab">query-2</span></div>
|
||||
<div class="mock-sql">
|
||||
<pre><span class="kw">SELECT</span> id, user_id, amount, status
|
||||
<span class="kw">FROM</span> orders
|
||||
<span class="kw">WHERE</span> created_at > <span class="str">'2026-09-01'</span>
|
||||
<span class="kw">ORDER BY</span> id <span class="kw">DESC</span> <span class="kw">LIMIT</span> <span class="num">100</span>;</pre>
|
||||
</div>
|
||||
<div class="mock-grid">
|
||||
<span class="gh">id</span><span class="gh">user_id</span><span class="gh">amount</span><span class="gh">status</span>
|
||||
<span>9f2a</span><span>u_1024</span><span>¥ 1,299.00</span><span class="ok">PAID</span>
|
||||
<span>9f29</span><span>u_0987</span><span>¥ 89.00</span><span class="ok">PAID</span>
|
||||
<span>9f28</span><span>u_2333</span><span>¥ 459.00</span><span class="warn">PENDING</span>
|
||||
<span>9f27</span><span>u_1024</span><span>¥ 3,280.00</span><span class="ok">PAID</span>
|
||||
</div>
|
||||
<div class="mock-status"><span class="ok">✓ 100 行 · 38ms</span><span>MySQL 8 · 127.0.0.1:3306</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 数据统计条 -->
|
||||
<div class="stats">
|
||||
<div class="stats-inner">
|
||||
<div class="stat"><b>7</b><span>内置驱动</span></div>
|
||||
<div class="stat"><b>18</b><span>可连数据库</span></div>
|
||||
<div class="stat"><b>0</b><span>数据外发</span></div>
|
||||
<div class="stat"><b>1</b><span>个二进制内置官网与文档</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===================== 为什么选 ===================== -->
|
||||
<section class="section">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">为什么运维和开发选 OpsxDB</h2>
|
||||
<p class="sec-sub">不把生产库连到别人的云上 —— 这是我们做这款工具的出发点。</p>
|
||||
<div class="grid g4">
|
||||
<div class="card">
|
||||
<div class="card-icon"><svg class="i-lg"><use href="#i-shield-check"/></svg></div>
|
||||
<h3>本地优先,数据主权</h3>
|
||||
<p>连接配置、查询历史全部保存在本机,服务只监听 127.0.0.1,不经过任何第三方服务器。</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-icon"><svg class="i-lg"><use href="#i-database"/></svg></div>
|
||||
<h3>六类库一个窗口</h3>
|
||||
<p>MySQL 族 / PostgreSQL 族 / SQL Server / Oracle / SQLite / Redis 统一工作台,切换零负担。</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-icon"><svg class="i-lg"><use href="#i-key"/></svg></div>
|
||||
<h3>安全通道直达内网</h3>
|
||||
<p>每个连接可独立配置 SSL/TLS 与 SSH 隧道,跳板机后面的库也能安全直连。</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-icon"><svg class="i-lg"><use href="#i-sparkles"/></svg></div>
|
||||
<h3>AI 写 SQL,也能查库</h3>
|
||||
<p>Ask 生成/解释/优化;Agent 用与 MCP 同源的只读工具真查库。Cursor 可 <code>npx @rlwj-lab/opsxdb-mcp</code> 接入。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===================== 功能 ===================== -->
|
||||
<section class="section alt" id="features">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">开箱即用的专业能力</h2>
|
||||
<p class="sec-sub">为「每天都要碰库的人」设计的工作台密度。</p>
|
||||
<div class="grid g3">
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-terminal"/></svg></div><div><h3>连接选择器</h3><p>搜索 / 分类 / 最近 / 图标网格;粘贴 <code>mysql://user:pass@host:3306/db</code> 一键填入表单。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-zap"/></svg></div><div><h3>SQL 工作台</h3><p>CodeMirror 编辑器,⌘/Ctrl+Enter 执行当前语句或选区,多 Tab 并行,可拖分栏。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-table"/></svg></div><div><h3>结果随手取</h3><p>结果集一键复制 / 导出 CSV / 生成 INSERT;双击单元格即复制,截断行数有提示。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-tree"/></svg></div><div><h3>对象树与表数据</h3><p>懒加载库 / 表 / 列;点表名直接看前 100 行,展开表即看列结构。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-database"/></svg></div><div><h3>Redis 工作台</h3><p>编辑器直接执行 <code>PING</code> / <code>GET</code> / <code>SET</code> / <code>KEYS</code>,键空间浏览、TTL 管理。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-sparkles"/></svg></div><div><h3>AI / MCP</h3><p>Ask 写 SQL;Agent 真查白名单库。可用 <code>npx @rlwj-lab/opsxdb-mcp</code> 接到 Cursor(默认只读)。</p></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===================== 驱动矩阵 ===================== -->
|
||||
<section class="section" id="drivers">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">数据库支持</h2>
|
||||
<p class="sec-sub">常用库 native Go 驱动编译内置;长尾库规划 agent 按需接入。</p>
|
||||
<div class="grid g3">
|
||||
<div class="proto"><h3><svg class="i"><use href="#i-database"/></svg> MySQL 族</h3><p>MySQL · MariaDB · TiDB · OceanBase · PolarDB · TDSQL<span class="port">:3306</span></p></div>
|
||||
<div class="proto"><h3><svg class="i"><use href="#i-database"/></svg> PostgreSQL 族</h3><p>PostgreSQL · GaussDB / openGauss · 人大金仓<span class="port">:5432</span></p></div>
|
||||
<div class="proto"><h3><svg class="i"><use href="#i-database"/></svg> SQL Server</h3><p>原生协议直连,SSL 可选<span class="port">:1433</span></p></div>
|
||||
<div class="proto"><h3><svg class="i"><use href="#i-database"/></svg> Oracle</h3><p>纯 Go 驱动 go-ora,不引入 JVM<span class="port">:1521</span></p></div>
|
||||
<div class="proto"><h3><svg class="i"><use href="#i-database"/></svg> SQLite</h3><p>本地文件库,填路径即连<span class="port">file</span></p></div>
|
||||
<div class="proto"><h3><svg class="i"><use href="#i-zap"/></svg> Redis</h3><p>连接即可执行命令与键管理<span class="port">:6379</span></p></div>
|
||||
</div>
|
||||
<div class="badges">
|
||||
<span class="more">规划中 · agent 按需接入:达梦 DM8 · MongoDB · ZooKeeper · Elasticsearch · InfluxDB</span>
|
||||
</div>
|
||||
<p class="footnote">驱动验收状态(本机 docker 实测)见 <a href="/docs/drivers" target="_blank" rel="noopener">文档 · 驱动支持</a>。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===================== 安全 ===================== -->
|
||||
<section class="section alt" id="security">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">安全是默认项,不是选项</h2>
|
||||
<p class="sec-sub">连生产库的工具,必须先过安全这一关。</p>
|
||||
<div class="grid g3">
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-key"/></svg></div><div><h3>密码不出本机</h3><p>连接密码本机混淆存储;查询只带 <code>sessionId</code>,账密不再每次上送。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-shield-check"/></svg></div><div><h3>SSL / TLS 每库可配</h3><p>按连接独立开启 TLS,证书校验策略随库配置。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-server"/></svg></div><div><h3>SSH 隧道</h3><p>跳板机场景一条隧道直达内网库,无需暴露公网端口。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-monitor"/></svg></div><div><h3>仅监听回环</h3><p>后端默认绑定 127.0.0.1,对外服务需显式开启。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-clipboard"/></svg></div><div><h3>危险 SQL 确认</h3><p>DROP / TRUNCATE / 无 WHERE 的 UPDATE·DELETE 执行前二次确认。</p></div></div>
|
||||
<div class="card row"><div class="card-icon"><svg class="i-lg"><use href="#i-clock"/></svg></div><div><h3>查询历史本地留存</h3><p>历史只存在本机,随时回跳重跑,不上传不同步。</p></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===================== 下载 / 形态 ===================== -->
|
||||
<section class="section" id="download">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">三种形态,同一套体验</h2>
|
||||
<p class="sec-sub">客户端唯一形态是桌面 GUI;官网与文档内置在同一个 Go 二进制里。</p>
|
||||
<div class="pricing three">
|
||||
<div class="price-card featured">
|
||||
<div class="plan-tag">推荐 · 主交付</div>
|
||||
<div class="plan">桌面版</div>
|
||||
<div class="price"><b>Tauri 2</b></div>
|
||||
<div class="plan-sub">macOS(Apple Silicon / Intel)· Windows 规划中</div>
|
||||
<ul>
|
||||
<li>✓ 双击启动,本地后端随应用自动拉起</li>
|
||||
<li>✓ DMG 安装包内置 sidecar,无需手动起服务</li>
|
||||
<li>✓ 连接 / 查询 / 结果全功能</li>
|
||||
<li>✓ 数据 100% 留在本机</li>
|
||||
</ul>
|
||||
<a class="btn btn-primary" href="/docs/quickstart" target="_blank" rel="noopener">从源码构建</a>
|
||||
</div>
|
||||
<div class="price-card">
|
||||
<div class="plan">官网 + 文档</div>
|
||||
<div class="price"><b>内置</b></div>
|
||||
<div class="plan-sub">随二进制提供,无需部署</div>
|
||||
<ul>
|
||||
<li>✓ 官网 <code>/</code> 与文档 <code>/docs</code> 内置于后端</li>
|
||||
<li>✓ 文档支持全文搜索 / 打印 / 导出 PDF</li>
|
||||
<li>✓ 浏览器只看站点与文档,不承载客户端</li>
|
||||
<li>✓ 随版本发布自动更新</li>
|
||||
</ul>
|
||||
<a class="btn btn-primary" href="/docs" target="_blank" rel="noopener">浏览文档</a>
|
||||
</div>
|
||||
<div class="price-card enterprise">
|
||||
<div class="plan-tag dark">内网部署</div>
|
||||
<div class="plan">企业内网版</div>
|
||||
<div class="price"><b>无外联</b></div>
|
||||
<div class="plan-sub">数据不出企业网</div>
|
||||
<ul>
|
||||
<li>✓ 单二进制 + 静态页,内网任意主机部署</li>
|
||||
<li>✓ 默认仅回环监听,对外需显式配置</li>
|
||||
<li>✓ SSH 隧道 / TLS 直达内网数据库</li>
|
||||
<li>✓ 无遥测、无账号、无云依赖</li>
|
||||
</ul>
|
||||
<a class="btn btn-dark" href="/docs/security" target="_blank" rel="noopener">安全设计</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===================== FAQ ===================== -->
|
||||
<section class="section alt" id="faq">
|
||||
<div class="wrap narrow">
|
||||
<h2 class="sec-title">常见问题</h2>
|
||||
<div class="faq">
|
||||
<details open><summary>我的连接密码保存在哪?安全吗?</summary><p>全部保存在本机(混淆存储),查询时只携带会话 ID,密码不会随每次请求上送,也不会同步到任何云端。</p></details>
|
||||
<details><summary>能在浏览器里操作数据库吗?</summary><p>不能。客户端唯一形态是桌面应用(Tauri 2);浏览器只承载官网与文档,由后端 :8788 内置提供。开发时的 :5174 只是桌面 devUrl 的资产服务。</p></details>
|
||||
<details><summary>和 DBeaver / Navicat 有什么差别?</summary><p>OpsxDB 面向运维与开发的日常高频操作(连库、点表、写 SQL、取结果),界面密度和快捷键为「快」设计;本地优先、后端随桌面应用拉起、内置中文文档。重度管理功能(ER 图、数据比对等)在路线图中。</p></details>
|
||||
<details><summary>Oracle 支持好了吗?</summary><p>驱动代码已就绪(纯 Go 的 go-ora,无需 JVM),但本机 docker 验收在 Apple Silicon 上受镜像限制未通过,需 x86 环境或真库完成验收,详见文档《驱动支持》。</p></details>
|
||||
<details><summary>AI 功能需要联网吗?</summary><p>配置云端模型(如 DeepSeek)时,提问与结构上下文会发往该服务;可改用本地兼容端点。MCP / Agent 查库始终在本机执行,默认只读。</p></details>
|
||||
<details><summary>支持达梦 / MongoDB 吗?</summary><p>已列入路线:常用库 native 内置,长尾库(达梦、MongoDB、ZooKeeper、ES、InfluxDB)规划 agent 按需接入,驱动分发走独立仓库并校验 sha256。</p></details>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===================== CTA ===================== -->
|
||||
<section class="cta">
|
||||
<div class="wrap">
|
||||
<h2>把数据库客户端收回自己手里</h2>
|
||||
<p>30 秒连上第一个库;官网与文档都由你手里的这个二进制提供。</p>
|
||||
<div class="hero-actions center">
|
||||
<a class="btn btn-inverse btn-lg" href="/docs/quickstart" target="_blank" rel="noopener">快速开始 ↗</a>
|
||||
<a class="btn btn-outline btn-lg" href="/docs" target="_blank" rel="noopener">阅读文档</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ===================== Footer ===================== -->
|
||||
<footer class="footer">
|
||||
<div class="wrap footer-grid">
|
||||
<div>
|
||||
<div class="brand"><span class="brand-logo"><svg width="30" height="30" viewBox="0 0 64 64" aria-label="OpsxDB"><defs><linearGradient id="lg-foot" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#059669"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-foot)"/><g stroke="#fff" stroke-width="4.5" fill="none" stroke-linecap="round"><ellipse cx="32" cy="20" rx="15" ry="6.5"/><path d="M17 20v24c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5V20"/><path d="M17 32c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5"/></g></svg></span><span class="brand-name">OpsxDB</span></div>
|
||||
<p class="footer-desc">本地优先的桌面数据库工作台。<br>数据在自己手里,才是真的效率工具。</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4>产品</h4>
|
||||
<a href="#features">功能特性</a>
|
||||
<a href="#drivers">数据库支持</a>
|
||||
<a href="#download">下载与形态</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>资源</h4>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权与激活</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">用户文档</a>
|
||||
<a href="/docs/drivers" target="_blank" rel="noopener">驱动验收状态</a>
|
||||
<a href="/docs/faq" target="_blank" rel="noopener">常见问题</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>安全</h4>
|
||||
<a href="#security">安全设计</a>
|
||||
<a href="/docs/security" target="_blank" rel="noopener">SSL 与 SSH 隧道</a>
|
||||
<a href="/docs/quickstart" target="_blank" rel="noopener">快速开始</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bar">© 2026 OpsxDB · <a href="/pricing">定价</a> · <a href="/license">授权与激活</a> · <a href="/docs" target="_blank" rel="noopener">文档</a></div>
|
||||
</footer>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,212 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>授权与激活 · OpsxDB</title>
|
||||
<meta name="description" content="OpsxDB 授权与激活说明:付款后邮件交付授权码(LIC-),在「设置 → 授权」粘贴即完成激活;生产内网可用 LICOFF- 离线许可证,一机一码、支持自助解绑换机。">
|
||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%2264%22%20y2%3D%2264%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22%23059669%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%22%2306B6D4%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%2264%22%20height%3D%2264%22%20rx%3D%2214%22%20fill%3D%22url%28%23g%29%22%2F%3E%3Cg%20stroke%3D%22%23fff%22%20stroke-width%3D%224.5%22%20fill%3D%22none%22%20stroke-linecap%3D%22round%22%3E%3Cellipse%20cx%3D%2232%22%20cy%3D%2220%22%20rx%3D%2215%22%20ry%3D%226.5%22%2F%3E%3Cpath%20d%3D%22M17%2020v24c0%203.6%206.7%206.5%2015%206.5s15-2.9%2015-6.5V20%22%2F%3E%3Cpath%20d%3D%22M17%2032c0%203.6%206.7%206.5%2015%206.5s15-2.9%2015-6.5%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E">
|
||||
<link rel="stylesheet" href="/site/assets/site.css">
|
||||
<style>
|
||||
/* 授权页专用样式(lic- 前缀,避免与站点既有类冲突) // Logan.Li */
|
||||
.lic-hero{padding:72px 0 30px;text-align:center;}
|
||||
.lic-hero h1{font-size:clamp(28px,4.5vw,42px);margin:12px 0 10px;}
|
||||
.lic-hero .lead{max-width:780px;margin:0 auto;font-size:15px;line-height:1.9;opacity:.75;}
|
||||
.lic-chip{display:inline-flex;align-items:center;gap:8px;padding:7px 16px;border-radius:999px;border:1px solid var(--green,#059669);color:var(--green,#059669);font-size:13px;font-weight:600;}
|
||||
.lic-steps{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px 16px;margin:22px 0 0;}
|
||||
@media (max-width:720px){.lic-steps{grid-template-columns:1fr;}}
|
||||
.lic-step{position:relative;border:1px solid var(--border);border-radius:calc(var(--radius,14px) + 2px);padding:22px 18px 18px;background:var(--bg);}
|
||||
.lic-step .n{position:absolute;top:-11px;left:18px;background:var(--green,#059669);color:#fff;font-size:11.5px;font-weight:700;padding:2px 10px;border-radius:999px;letter-spacing:.03em;}
|
||||
.lic-step h3{margin:4px 0 8px;font-size:15.5px;}
|
||||
.lic-step p{margin:0;font-size:13.5px;line-height:1.9;opacity:.78;}
|
||||
.lic-cmp-wrap{overflow-x:auto;margin-top:20px;}
|
||||
.lic-cmp{width:100%;min-width:640px;border-collapse:collapse;font-size:14px;background:var(--bg);}
|
||||
.lic-cmp th,.lic-cmp td{border-bottom:1px solid var(--border);padding:12px;text-align:left;vertical-align:top;}
|
||||
.lic-cmp thead th{font-size:13.5px;letter-spacing:.02em;}
|
||||
.lic-cmp tbody th{width:132px;font-weight:600;color:var(--text-3,#98a2b3);}
|
||||
.lic-cmp code{font-family:var(--mono,monospace);font-size:12.5px;background:rgba(127,127,127,.14);padding:1px 5px;border-radius:4px;}
|
||||
.lic-faq{max-width:880px;margin:0 auto;}
|
||||
.lic-faq details{border-bottom:1px solid var(--border);padding:15px 4px;}
|
||||
.lic-faq summary{cursor:pointer;font-weight:600;font-size:15px;list-style:none;display:flex;justify-content:space-between;gap:12px;align-items:center;}
|
||||
.lic-faq summary::after{content:"+";opacity:.5;font-size:18px;line-height:1;}
|
||||
.lic-faq details[open] summary::after{content:"–";}
|
||||
.lic-faq details p{margin:10px 0 2px;font-size:14px;line-height:1.9;opacity:.78;}
|
||||
.lic-note{max-width:880px;margin:16px auto 0;font-size:13px;line-height:1.9;opacity:.68;}
|
||||
.lic-cta{text-align:center;max-width:680px;margin:0 auto;}
|
||||
.lic-cta .btns{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin-top:20px;}
|
||||
.lic-scope{max-width:880px;margin:24px auto 0;font-size:13.5px;line-height:1.95;opacity:.78;}
|
||||
.lic-scope li{margin:6px 0;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<header class="nav">
|
||||
<div class="nav-inner">
|
||||
<a class="brand" href="/">
|
||||
<span class="brand-logo"><svg width="30" height="30" viewBox="0 0 64 64" aria-label="OpsxDB"><defs><linearGradient id="lg-site" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#059669"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-site)"/><g stroke="#fff" stroke-width="4.5" fill="none" stroke-linecap="round"><ellipse cx="32" cy="20" rx="15" ry="6.5"/><path d="M17 20v24c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5V20"/><path d="M17 32c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5"/></g></svg></span>
|
||||
<span class="brand-name">OpsxDB</span>
|
||||
</a>
|
||||
<nav class="nav-links">
|
||||
<a href="/#features">功能</a>
|
||||
<a href="/#drivers">驱动</a>
|
||||
<a href="/#security">安全</a>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权</a>
|
||||
<a href="/#download">下载</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">文档</a>
|
||||
</nav>
|
||||
<div class="nav-cta">
|
||||
<a class="btn btn-primary" href="/docs/quickstart" target="_blank" rel="noopener">快速开始 →</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<section class="lic-hero">
|
||||
<span class="lic-chip">30 天免费试用 · 首次启动自动开始 · 无需注册</span>
|
||||
<h1>授权与激活</h1>
|
||||
<p class="lead">一次说清四件事:怎么买、授权码怎么交付、程序里怎么激活、换机与断网怎么办。授权绑定设备而非账号,全流程不需要注册。</p>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">交付与激活:四步</h2>
|
||||
<p class="sec-sub">从下单到激活通常当天完成,最短几分钟。</p>
|
||||
<div class="lic-steps">
|
||||
<div class="lic-step">
|
||||
<span class="n">STEP 1</span>
|
||||
<h3>下单确认</h3>
|
||||
<p>邮件说明产品、授权类型(包年 / 永久 / 团队席位)与设备数量。支持对公转账与开具发票,工作日当天回复。</p>
|
||||
</div>
|
||||
<div class="lic-step">
|
||||
<span class="n">STEP 2</span>
|
||||
<h3>邮件交付授权码</h3>
|
||||
<p>付款确认后即刻签发,授权码以邮件送达你的邮箱:联网用 <code>LIC-</code> 前缀的在线授权码,隔离内网用 <code>LICOFF-</code> 前缀的离线许可证。</p>
|
||||
</div>
|
||||
<div class="lic-step">
|
||||
<span class="n">STEP 3</span>
|
||||
<h3>应用内激活</h3>
|
||||
<p>打开「设置 → 授权」,粘贴授权码点击激活。程序连接授权服务器 <code>licence.rlwj.cn</code> 登记本机设备并回写一次性激活令牌,此后每 7 天自动校验一次。</p>
|
||||
</div>
|
||||
<div class="lic-step">
|
||||
<span class="n">STEP 4</span>
|
||||
<h3>换机与续期</h3>
|
||||
<p>在本机自助解绑即可把席位迁到新机器,每年免费换绑 2 次;到期前 30 天邮件提醒,续期后签发新授权码替换即可。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section alt">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">两种激活方式</h2>
|
||||
<p class="sec-sub">能联网就用在线授权码,完全不出网就用离线许可证——功能与有效期一致。</p>
|
||||
<div class="lic-cmp-wrap">
|
||||
<table class="lic-cmp">
|
||||
<thead>
|
||||
<tr><th>对比项</th><th>在线授权码 <code>LIC-</code></th><th>离线许可证 <code>LICOFF-</code></th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><th>是否联网</th><td>激活时联网一次,之后每 7 天校验一次</td><td>全程无需联网,本地验签</td></tr>
|
||||
<tr><th>设备绑定</th><td>绑定设备 ID,一机一码</td><td>绑定设备 ID,一机一码</td></tr>
|
||||
<tr><th>断网可用</th><td>激活后可连续离线使用 30 天</td><td>始终有效,与网络无关</td></tr>
|
||||
<tr><th>有效期</th><td>包年 365 天;永久授权长期有效</td><td>单张最长 365 天,可续签</td></tr>
|
||||
<tr><th>换绑</th><td>应用内自助解绑,每年免费换绑 2 次</td><td>邮件换取新证并解绑旧设备</td></tr>
|
||||
<tr><th>适合场景</th><td>办公网、开发机、云主机</td><td>生产内网、专有云、隔离环境</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="lic-scope">
|
||||
<p><b>授权服务器会收到什么?</b>客户端只与 <code>licence.rlwj.cn</code>(443)通信,用于设备登记与周期校验,只发送授权码与设备标识(设备 ID、设备名称)——不发送连接串、库表名、SQL 语句与查询结果等任何业务数据。服务端返回 Ed25519 签名,客户端本地验签,验签失败按未授权处理。</p>
|
||||
<ul>
|
||||
<li>内网只放行白名单出网:把 <code>licence.rlwj.cn</code> 加入白名单,或直接使用离线许可证。</li>
|
||||
<li>授权服务器不可达:按宽限期继续可用,业务不会当场中断;恢复网络后自动补校验。</li>
|
||||
<li>不想让客户端出网:一律选离线许可证,客户端永不发起网络请求。</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">授权类型与价格</h2>
|
||||
<p class="sec-sub">个人非商业用途免费;工作中的商业用途需要授权。</p>
|
||||
<div class="lic-cmp-wrap">
|
||||
<table class="lic-cmp">
|
||||
<thead>
|
||||
<tr><th>授权</th><th>价格</th><th>设备数</th><th>包含</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><th>个人 · 非商业</th><td>¥0</td><td>不涉及授权</td><td>日常连库、写 SQL、看结果;商业用途需购买授权</td></tr>
|
||||
<tr><th>专业版 · 包年</th><td>¥99 / 年</td><td>3 台</td><td>全部内置驱动(含国产库)、SQL 执行与导出转储、SSH 隧道与 SSL、AI SQL 助手、设备自助解绑</td></tr>
|
||||
<tr><th>专业版 · 永久</th><td>¥199 一次性</td><td>5 台</td><td>包年全部能力,一次买断、无续费</td></tr>
|
||||
<tr><th>团队版</th><td>¥99 / 人 / 年</td><td>按席位,5 席起</td><td>个人版全部能力 + 共享连接库(自托管)、驱动离线包分发、优先支持</td></tr>
|
||||
<tr><th>企业私有化</th><td>¥6,000 / 年(标价)</td><td>单法人不限席位</td><td>内网部署、数据不出企业、远程部署协助、定制开发通道</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="lic-note">完整功能对比、让利与组合报价见 <a href="/pricing">定价页</a>。表中为标价,成交可按规模与场景议价。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section alt">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">授权常见问题</h2>
|
||||
<div class="lic-faq">
|
||||
<details><summary>授权码多久能收到?</summary><p>付款确认后即刻签发并邮件发出,工作日通常当天完成(含开票需求)。邮件里就是完整授权码,无需注册账号或登录任何后台。</p></details>
|
||||
<details><summary>授权绑定设备还是账号?</summary><p>绑定设备。每台机器有唯一设备 ID,一个授权码按授权的设备数占座,与账号无关;团队版按席位签发多个授权码,组织内可转移。</p></details>
|
||||
<details><summary>换电脑 / 重装系统后设备 ID 变了怎么办?</summary><p>旧机还在:在「设置 → 授权」点解绑,腾出席位后在新机激活。旧机已不在手:邮件与我们说明(附授权码后四位与新设备 ID),由我们在授权后台释放旧设备。每年免费换绑 2 次。</p></details>
|
||||
<details><summary>断网了授权会失效吗?</summary><p>不会。离线许可证本地自验,永不联网也有效;在线授权码激活后可连续离线使用 30 天,超时后联网校验一次即可继续。授权服务器不可达时按宽限期放行,不会打断正在执行的查询。</p></details>
|
||||
<details><summary>生产内网完全不出网,怎么激活?</summary><p>改用离线许可证(<code>LICOFF-</code>):在应用内导出本机机器码,邮件发我们换取离线证,本地导入即完成激活,全程不需要客户端联网——数据库连接与查询本来就在本机完成。</p></details>
|
||||
<details><summary>续期怎么操作?</summary><p>到期前 30 天我们会邮件提醒。付款后签发新的授权码,在「设置 → 授权」里替换旧码即可,同一台设备无需先解绑;永久授权无需续期。</p></details>
|
||||
<details><summary>试用期结束后我的连接配置和数据还在吗?</summary><p>都在。授权只控制专业功能是否可用,本机连接配置、查询历史与 ~/.opsxdb 下的数据不做任何改动;试用结束后个人非商业用途可继续使用,购买授权后专业功能立即恢复。</p></details>
|
||||
<details><summary>激活失败怎么排查?</summary><p>先在「设置 → 授权」看当前状态与到期时间。若提示无效或不匹配,请把授权码后四位、设备 ID 与报错截图一并发邮件,我们核对授权服务器上的记录后处理(常见原因是设备数已占满或授权码输漏字符)。</p></details>
|
||||
<details><summary>能开发票、走对公转账吗?</summary><p>可以。个人与企业均可开具发票,支持对公转账、多产品捆绑与批量授权;邮件说明抬头与税号即可。</p></details>
|
||||
<details><summary>三个产品(OpsxDB / OpsxAPI / OpsXShell)要分别买吗?</summary><p>三个产品独立授权、独立计价;它们共用同一套授权体系(同一个设备 ID 规则与同一个授权服务器)。多产品组合、团队或教育用途可邮件说明需求,给捆绑价。</p></details>
|
||||
</div>
|
||||
<p class="lic-note">本页更新于 2026-10-16,授权口径与授权服务器 <code>licence.rlwj.cn</code> 实际配置一致。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="wrap lic-cta">
|
||||
<h2 class="sec-title">准备好购买授权</h2>
|
||||
<p class="sec-sub">邮件说明产品、授权类型与设备数,当天回复并开票。</p>
|
||||
<div class="btns">
|
||||
<a class="btn btn-primary" href="mailto:hello@opsxapi.dev?subject=OpsxDB%20%E6%8E%88%E6%9D%83%E4%B8%8E%E6%BF%80%E6%B4%BB%E5%92%A8%E8%AF%A2">邮件咨询购买</a>
|
||||
<a class="btn btn-ghost" href="/#download">还没装?立即下载</a>
|
||||
</div>
|
||||
<p class="lic-note">付款后当场发放授权码(LIC-),粘贴到「设置 → 授权」即完成激活——整个流程无需注册账号。</p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="wrap footer-grid">
|
||||
<div>
|
||||
<div class="brand"><span class="brand-logo"><svg width="30" height="30" viewBox="0 0 64 64" aria-label="OpsxDB"><defs><linearGradient id="lg-foot" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#059669"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-foot)"/><g stroke="#fff" stroke-width="4.5" fill="none" stroke-linecap="round"><ellipse cx="32" cy="20" rx="15" ry="6.5"/><path d="M17 20v24c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5V20"/><path d="M17 32c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5"/></g></svg></span><span class="brand-name">OpsxDB</span></div>
|
||||
<p class="footer-desc">本地优先的桌面数据库工作台。<br>数据在自己手里,才是真的效率工具。</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4>产品</h4>
|
||||
<a href="/#features">功能特性</a>
|
||||
<a href="/#drivers">数据库支持</a>
|
||||
<a href="/#download">下载与形态</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>资源</h4>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权与激活</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">用户文档</a>
|
||||
<a href="/docs/faq" target="_blank" rel="noopener">常见问题</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>安全</h4>
|
||||
<a href="/#security">安全设计</a>
|
||||
<a href="/docs/security" target="_blank" rel="noopener">SSL 与 SSH 隧道</a>
|
||||
<a href="/docs/quickstart" target="_blank" rel="noopener">快速开始</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bar">© 2026 OpsxDB · <a href="/pricing">定价</a> · <a href="/license">授权与激活</a></div>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,202 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>授权与定价 · OpsxDB</title>
|
||||
<meta name="description" content="OpsxDB 定价:30 天全功能试用;专业版 ¥99/年或 ¥199 永久,团队版 ¥99/人/年,企业私有化 ¥6,000/年。支持在线授权与离线激活。">
|
||||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%3E%3Cdefs%3E%3ClinearGradient%20id%3D%22g%22%20x1%3D%220%22%20y1%3D%220%22%20x2%3D%2264%22%20y2%3D%2264%22%20gradientUnits%3D%22userSpaceOnUse%22%3E%3Cstop%20offset%3D%220%22%20stop-color%3D%22%23059669%22%2F%3E%3Cstop%20offset%3D%221%22%20stop-color%3D%2206B6D4%22%2F%3E%3C%2FlinearGradient%3E%3C%2Fdefs%3E%3Crect%20width%3D%2264%22%20height%3D%2264%22%20rx%3D%2214%22%20fill%3D%22url(%23g)%22%2F%3E%3Cg%20stroke%3D%22%23fff%22%20stroke-width%3D%224.5%22%20fill%3D%22none%22%20stroke-linecap%3D%22round%22%3E%3Cellipse%20cx%3D%2232%22%20cy%3D%2220%22%20rx%3D%2215%22%20ry%3D%226.5%22%2F%3E%3Cpath%20d%3D%22M17%2020v24c0%203.6%206.7%206.5%2015%206.5s15-2.9%2015-6.5V20%22%2F%3E%3Cpath%20d%3D%22M17%2032c0%203.6%206.7%206.5%2015%206.5s15-2.9%2015-6.5%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E">
|
||||
<link rel="stylesheet" href="/site/assets/site.css">
|
||||
<style>
|
||||
.trial-hero{padding:72px 0 28px;text-align:center;}
|
||||
.trial-hero h1{font-size:clamp(28px,4.5vw,44px);margin:14px 0 10px;}
|
||||
.trial-hero .lead{max-width:720px;margin:0 auto;opacity:.75;line-height:1.8;}
|
||||
.trial-strip{display:inline-flex;gap:8px;align-items:center;padding:7px 16px;border-radius:999px;border:1px solid var(--accent,#2563eb);color:var(--accent,#2563eb);font-size:13px;font-weight:600;}
|
||||
.toggle{display:inline-flex;border:1px solid var(--border,#d8dee9);border-radius:999px;padding:3px;gap:2px;margin:14px auto 0;}
|
||||
.toggle button{border:0;background:transparent;padding:6px 18px;border-radius:999px;font-size:13px;font-weight:600;color:inherit;opacity:.65;cursor:pointer;}
|
||||
.toggle button.on{background:var(--accent,#2563eb);color:#fff;opacity:1;}
|
||||
.price-num b{font-size:34px;}
|
||||
.faq{max-width:820px;margin:0 auto;}
|
||||
.faq details{border-bottom:1px solid var(--border,#e5e9f0);padding:16px 4px;}
|
||||
.faq summary{cursor:pointer;font-weight:600;font-size:15px;list-style:none;display:flex;justify-content:space-between;align-items:center;}
|
||||
.faq summary::after{content:"+";font-size:18px;opacity:.5;}
|
||||
.faq details[open] summary::after{content:"–";}
|
||||
.faq details p{margin:10px 0 2px;opacity:.72;line-height:1.85;font-size:14px;}
|
||||
.indie{text-align:center;opacity:.7;font-size:14px;line-height:1.9;max-width:560px;margin:0 auto;}
|
||||
.act-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:14px;margin-top:22px;text-align:left;}
|
||||
.act-grid .card h3{display:flex;align-items:center;gap:8px;margin:0 0 6px;font-size:15px;}
|
||||
.act-grid .card p{margin:0;opacity:.7;font-size:13px;line-height:1.8;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" style="display:none" aria-hidden="true">
|
||||
<symbol id="i-database" viewBox="0 0 24 24"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14a9 3 0 0 0 18 0V5"/><path d="M3 12a9 3 0 0 0 18 0"/></symbol>
|
||||
<symbol id="i-shield-check" viewBox="0 0 24 24"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/><path d="m9 12 2 2 4-4"/></symbol>
|
||||
<symbol id="i-terminal" viewBox="0 0 24 24"><polyline points="4 17 10 11 4 5"/><line x1="12" x2="20" y1="19" y2="19"/></symbol>
|
||||
<symbol id="i-table" viewBox="0 0 24 24"><rect width="18" height="18" x="3" y="3" rx="2"/><path d="M3 9h18"/><path d="M3 15h18"/><path d="M9 3v18"/><path d="M15 3v18"/></symbol>
|
||||
<symbol id="i-tree" viewBox="0 0 24 24"><path d="M13 10h7a1 1 0 0 0 1-1V6a1 1 0 0 0-1-1h-2.5a1 1 0 0 1-.8-.4l-.9-1.2A1 1 0 0 0 15 3h-2a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z"/><path d="M13 21h7a1 1 0 0 0 1-1v-3a1 1 0 0 0-1-1h-2.9a1 1 0 0 1-.88-.55l-.42-.85a1 1 0 0 0-.92-.6H13a1 1 0 0 0-1 1v5a1 1 0 0 0 1 1Z"/><path d="M3 5a2 2 0 0 0 2 2h3"/><path d="M3 3v13a2 2 0 0 0 2 2h3"/></symbol>
|
||||
<symbol id="i-zap" viewBox="0 0 24 24"><path d="M15.914 4a1.5 1.5 0 00-2.474-1.561l-9 9A1.5 1.5 0 005.5 14h4.002a.5.5 0 01.471.666L8.086 20a1.5 1.5 0 002.475 1.56l9-9A1.5 1.5 0 0018.5 10h-3.997a.5.5 0 01-.472-.667z"/></symbol>
|
||||
<symbol id="i-sparkles" viewBox="0 0 24 24"><path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/><path d="M20 3v4"/><path d="M22 5h-4"/></symbol>
|
||||
<symbol id="i-key" viewBox="0 0 24 24"><circle cx="7.5" cy="15.5" r="5.5"/><path d="m21 2-9.6 9.6"/><path d="m15.5 7.5 3 3L22 7l-3-3"/></symbol>
|
||||
<symbol id="i-monitor" viewBox="0 0 24 24"><rect width="20" height="14" x="2" y="3" rx="2"/><line x1="8" x2="16" y1="21" y2="21"/><line x1="12" x2="12" y1="17" y2="21"/></symbol>
|
||||
<symbol id="i-server" viewBox="0 0 24 24"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"/><rect width="20" height="8" x="2" y="14" rx="2" ry="2"/><line x1="6" x2="6.01" y1="6" y2="6"/><line x1="6" x2="6.01" y1="18" y2="18"/></symbol>
|
||||
<symbol id="i-clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></symbol>
|
||||
<symbol id="i-clipboard" viewBox="0 0 24 24"><rect width="8" height="4" x="8" y="2" rx="1" ry="1"/><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/></symbol>
|
||||
</svg>
|
||||
<header class="nav">
|
||||
<div class="nav-inner">
|
||||
<a class="brand" href="/">
|
||||
<span class="brand-logo"><svg width="30" height="30" viewBox="0 0 64 64" aria-label="OpsxDB"><defs><linearGradient id="lg-site" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#059669"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-site)"/><g stroke="#fff" stroke-width="4.5" fill="none" stroke-linecap="round"><ellipse cx="32" cy="20" rx="15" ry="6.5"/><path d="M17 20v24c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5V20"/><path d="M17 32c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5"/></g></svg></span>
|
||||
<span class="brand-name">OpsxDB</span>
|
||||
</a>
|
||||
<nav class="nav-links">
|
||||
<a href="/#features">功能</a>
|
||||
<a href="/#drivers">驱动</a>
|
||||
<a href="/#security">安全</a>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权</a>
|
||||
<a href="/#download">下载</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">文档</a>
|
||||
</nav>
|
||||
<div class="nav-cta">
|
||||
<a class="btn btn-primary" href="/docs/quickstart" target="_blank" rel="noopener">快速开始 →</a>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<main>
|
||||
<section class="trial-hero">
|
||||
<span class="trial-strip"><svg class="i"><use href="#i-rocket"/></svg> 30 天免费试用 · 首次启动自动开始 · 无需注册</span>
|
||||
<h1>授权与定价</h1>
|
||||
<p class="lead">OpsxDB 对个人非商业用途永久免费;在工作中商用需要授权。授权绑定设备,支持在线激活(LIC-)与完全离线激活(LICOFF-)。</p>
|
||||
</section>
|
||||
|
||||
<section class="section" style="padding-top:26px">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">先试用,再决定</h2>
|
||||
<p class="sec-sub">下载即含 30 天全功能试用;激活支持在线与离线两种方式。</p>
|
||||
<div class="act-grid">
|
||||
<div class="card"><h3><svg class="i"><use href="#i-rocket"/></svg>30 天全功能试用</h3><p>首次启动自动开始;无需注册、无需信用卡。试用期覆盖全部连接与 AI 能力。</p></div>
|
||||
<div class="card"><h3><svg class="i"><use href="#i-globe"/></svg>在线授权 LIC-</h3><p>联网激活并绑定设备;支持自助解绑换机;激活后可连续离线使用 30 天。</p></div>
|
||||
<div class="card"><h3><svg class="i"><use href="#i-shield-check"/></svg>离线许可证 LICOFF-</h3><p>Ed25519 自包含签名,绑定设备;完全无网络也能激活,适合隔离内网环境。</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section alt">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">选择适合的授权</h2>
|
||||
<p class="sec-sub">个人版可选年付或一次性买断;团队按席位;私有化面向单法人不限席位。</p>
|
||||
<div class="pricing three">
|
||||
<div class="price-card">
|
||||
<div class="plan">专业版</div>
|
||||
<div class="toggle" data-mode="year"><button class="on" data-mode="year">¥99 / 年</button><button data-mode="life">永久 ¥199</button></div>
|
||||
<div class="price price-num"><b data-price="year">¥99</b><b data-price="life" style="display:none">¥199</b><span>/ 年</span></div>
|
||||
<div class="plan-sub">包年 3 台 / 永久 5 台设备</div>
|
||||
<ul>
|
||||
<li>全部内置驱动连接(含国产库)</li>
|
||||
<li>SQL 执行 / 结果导出 / 转储</li>
|
||||
<li>SSH 隧道与 SSL 加密</li>
|
||||
<li>AI SQL 助手(自带 Key)</li>
|
||||
<li>设备可自助解绑迁移</li>
|
||||
</ul>
|
||||
<a class="btn btn-primary" href="mailto:hello@opsxapi.dev?subject=OpsxDB%20%E4%B8%AA%E4%BA%BA%E7%89%88%E8%B4%AD%E4%B9%B0">购买咨询</a>
|
||||
</div>
|
||||
<div class="price-card featured">
|
||||
<div class="plan-tag">团队首选</div>
|
||||
<div class="plan">团队版</div>
|
||||
<div class="price price-num"><b>¥99</b><span>/ 人 / 年</span></div>
|
||||
<div class="plan-sub">按席位 · 5 席起 · 组织内可转移</div>
|
||||
<ul>
|
||||
<li>个人版全部能力</li>
|
||||
<li>共享连接库(自托管)</li>
|
||||
<li>统一驱动离线包分发</li>
|
||||
<li>优先技术支持</li>
|
||||
<li>1 年免费升级</li>
|
||||
</ul>
|
||||
<a class="btn btn-primary" href="mailto:hello@opsxapi.dev?subject=OpsxDB%20%E5%9B%A2%E9%98%9F%E7%89%88%E8%B4%AD%E4%B9%B0">联系商务</a>
|
||||
</div>
|
||||
<div class="price-card enterprise">
|
||||
<div class="plan-tag dark">私有化 · 不限席位</div>
|
||||
<div class="plan">企业私有化版</div>
|
||||
<div class="price price-num"><b>¥6,000</b><span>/ 年 · 标价</span></div>
|
||||
<div class="plan-sub">单法人不限席位 · 支持买断</div>
|
||||
<ul>
|
||||
<li>内网部署,数据不出企业</li>
|
||||
<li>团队版全部能力</li>
|
||||
<li>远程部署协助</li>
|
||||
<li>定制开发通道(另行报价)</li>
|
||||
</ul>
|
||||
<a class="btn btn-dark" href="mailto:hello@opsxapi.dev?subject=OpsxDB%20%E7%A7%81%E6%9C%89%E5%8C%96%E8%B4%AD%E4%B9%B0">获取报价</a>
|
||||
</div>
|
||||
</div>
|
||||
<p class="deal-note" style="text-align:center">支付后当场发放授权码(LIC-),粘贴到「设置 → 授权」即完成激活——整个流程无需注册账号;许可证一机一码绑定设备,每年可免费换绑 2 次。<br>购买咨询邮件请注明「OpsxDB」——Opsx 系列同一位开发者,多产品捆绑可议价。</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section">
|
||||
<div class="wrap">
|
||||
<h2 class="sec-title">常见问题</h2>
|
||||
<div class="faq">
|
||||
<details><summary>试用是怎么计算的?</summary><p>30 天全功能试用,从应用首次启动那一刻自动开始——无需注册账号,无需信用卡。试用期结束后,个人非商业用途可继续使用;在工作中的商业用途需要购买授权。</p></details>
|
||||
<details><summary>在线授权和离线激活有什么区别?</summary><p>在线授权码(LIC- 前缀):联网激活,绑定设备,支持在设置中自助解绑换机;激活后可连续离线使用最长 30 天。离线许可证(LICOFF- 前缀):同样绑定设备,但采用 Ed25519 自包含签名,在完全无网络的环境也能激活——适合隔离内网。两种方式在「设置 → 授权」中粘贴即用。</p></details>
|
||||
<details><summary>一个授权能用几台设备?</summary><p>授权绑定设备而非订阅账号。个人版最多 3 台设备;设备可以在「设置 → 授权」中解绑后迁移到新机器。</p></details>
|
||||
<details><summary>断网了授权会失效吗?</summary><p>离线许可证(LICOFF-)本地自验,永不联网也有效。在线授权(LIC-)容忍连续 30 天离线,超过后需联网重新验证一次。</p></details>
|
||||
<details><summary>退款政策是怎样的?</summary><p>自付款之日起 30 天内无理由全额退款——先用起来,不满意直接退。</p></details>
|
||||
<details><summary>怎么购买?</summary><p>邮件咨询购买(请注明 OpsxDB),当天回复;支持对公转账与开票。团队与私有化支持按规模议价。</p></details>
|
||||
<details><summary>三个产品(OpsxAPI / OpsxDB / OpsXShell)要分别买吗?</summary><p>三个产品独立授权、独立计价。多产品组合或学生优惠可直接邮件说明需求,给捆绑价。</p></details>
|
||||
<details><summary>授权包含哪些升级?</summary><p>年付授权含 1 年免费升级;终身授权包含后续版本更新。</p></details>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="section alt">
|
||||
<div class="wrap indie">
|
||||
<p><b>独立开发,认真长跑。</b><br>Opsx 系列工具由独立开发者打造,每一份授权的收入都直接投入产品迭代——没有投资人,也没有广告。</p>
|
||||
<p style="margin-top:14px"><a class="btn btn-primary" href="/#download">还没装?立即下载</a></p>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<footer class="footer">
|
||||
<div class="wrap footer-grid">
|
||||
<div>
|
||||
<div class="brand"><span class="brand-logo"><svg width="30" height="30" viewBox="0 0 64 64" aria-label="OpsxDB"><defs><linearGradient id="lg-foot" x1="0" y1="0" x2="64" y2="64" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#059669"/><stop offset="1" stop-color="#06B6D4"/></linearGradient></defs><rect width="64" height="64" rx="14" fill="url(#lg-foot)"/><g stroke="#fff" stroke-width="4.5" fill="none" stroke-linecap="round"><ellipse cx="32" cy="20" rx="15" ry="6.5"/><path d="M17 20v24c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5V20"/><path d="M17 32c0 3.6 6.7 6.5 15 6.5s15-2.9 15-6.5"/></g></svg></span><span class="brand-name">OpsxDB</span></div>
|
||||
<p class="footer-desc">本地优先的桌面数据库工作台。<br>数据在自己手里,才是真的效率工具。</p>
|
||||
</div>
|
||||
<div>
|
||||
<h4>产品</h4>
|
||||
<a href="/#features">功能特性</a>
|
||||
<a href="/#drivers">数据库支持</a>
|
||||
<a href="/#download">下载与形态</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>资源</h4>
|
||||
<a href="/pricing">定价</a>
|
||||
<a href="/license">授权与激活</a>
|
||||
<a href="/docs" target="_blank" rel="noopener">用户文档</a>
|
||||
<a href="/docs/drivers" target="_blank" rel="noopener">驱动验收状态</a>
|
||||
<a href="/docs/faq" target="_blank" rel="noopener">常见问题</a>
|
||||
</div>
|
||||
<div>
|
||||
<h4>安全</h4>
|
||||
<a href="/#security">安全设计</a>
|
||||
<a href="/docs/security" target="_blank" rel="noopener">SSL 与 SSH 隧道</a>
|
||||
<a href="/docs/quickstart" target="_blank" rel="noopener">快速开始</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bar">© 2026 OpsxDB · <a href="/pricing">定价</a> · <a href="/license">授权与激活</a> · <a href="/docs" target="_blank" rel="noopener">文档</a></div>
|
||||
</footer>
|
||||
<script>
|
||||
document.querySelectorAll('.toggle').forEach(function(t){
|
||||
t.addEventListener('click', function(e){
|
||||
if(e.target.tagName!=='BUTTON')return;
|
||||
t.querySelectorAll('button').forEach(function(b){b.classList.remove('on')});
|
||||
e.target.classList.add('on');
|
||||
t.dataset.mode = e.target.dataset.mode;
|
||||
t.closest('.price-card').querySelectorAll('[data-price]').forEach(function(el){
|
||||
el.style.display = el.dataset.price===t.dataset.mode ? '' : 'none';
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
# 官网构建入口:从 homepage/ 源生成 homepage/dist/(纯静态,供 nginx 直接托管)。
|
||||
# 用法: scripts/build-homepage.sh
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
cd "$ROOT/tools/homepage-build"
|
||||
exec go run . -src "$ROOT/homepage" -out "$ROOT/homepage/dist"
|
||||
@@ -1,41 +0,0 @@
|
||||
OpsxDB 的常用数据库驱动以 native Go 驱动编译内置,开箱即用;更多数据库在路线中。
|
||||
|
||||
## 内置驱动
|
||||
|
||||
| 驱动 | 连接库 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| mysql | MySQL · MariaDB · TiDB · OceanBase · PolarDB · TDSQL | 协议族复用,默认端口 3306 |
|
||||
| postgres | PostgreSQL · GaussDB / openGauss · Kingbase | 协议族复用,默认端口 5432 |
|
||||
| sqlserver | SQL Server | 原生协议,默认端口 1433 |
|
||||
| oracle | Oracle | go-ora 纯 Go 驱动,不引入 JVM,端口 1521 |
|
||||
| sqlite | SQLite | 本地文件库,无端口 |
|
||||
| redis | Redis | 默认端口 6379 |
|
||||
|
||||
## 支持状态
|
||||
|
||||
以下为逐项实测的结果 —— 你可以按这个表判断「现在就能连什么」:
|
||||
|
||||
| 数据库 | 连接 | 库表浏览 | 数据操作 | 备注 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| MySQL / MariaDB | ✅ | ✅ | ✅ | MariaDB 默认端口 3307 |
|
||||
| PostgreSQL | ✅ | ✅ | ✅ | GaussDB / 金仓同样适用 |
|
||||
| SQL Server | ✅ | ✅ | ✅ | Apple Silicon 上连接稍慢属正常 |
|
||||
| SQLite | ✅ | ✅ | ✅ | 填本地文件路径即连 |
|
||||
| Redis | ✅ | ✅ | ✅ | 支持命令执行与键管理 |
|
||||
| Oracle | 代码就绪 | ✅ | 待实测 | 见下方说明 |
|
||||
|
||||
> **说明(Oracle)**:驱动已内置(纯 Go 实现,无需安装 Java),库表浏览可用;完整数据操作正在验收中 —— 在 Apple Silicon 的容器环境会遇到 Oracle 限制(ORA-00442),x86 环境或真实数据库不受影响。
|
||||
|
||||
## 暂不支持(规划中)
|
||||
|
||||
| 数据库 | 状态 |
|
||||
| --- | --- |
|
||||
| 达梦 DM8 | 规划中,暂不可用 |
|
||||
| MongoDB | 规划中,暂不可用 |
|
||||
| ZooKeeper / Elasticsearch / InfluxDB | 规划中,暂不可用 |
|
||||
|
||||
> **注意**:选择器中标注「未就绪」的类型仍可保存连接配置,但不能测试 / 连接;开放支持后会随版本更新自动可用。
|
||||
|
||||
## 后续驱动的接入方式
|
||||
|
||||
常用库继续以原生驱动内置;小众数据库(达梦、MongoDB 等)将通过**按需下载**方式接入 —— 首次使用时下载对应驱动组件,版本固定并校验完整性(sha256),不随包体膨胀。
|
||||
@@ -1,66 +0,0 @@
|
||||
SQL 工作台是日常使用率最高的界面,所有交互围绕「快」设计。
|
||||
|
||||
## 执行模型
|
||||
|
||||
- **⌘/Ctrl + Enter**:执行光标所在的**当前语句**;有选区时执行**选区**;
|
||||
- 不是「整页脚本」模式 —— 多条语句互不干扰,想跑哪句把光标放哪;
|
||||
- Redis 连接共用同一编辑器,按**行**执行命令(见 [Redis 工作台](redis)),不另开 CLI;
|
||||
- 执行在会话上运行,连接断开后自动提示。
|
||||
|
||||
## 多 Tab 与分栏
|
||||
|
||||
- 每个查询一个 Tab,并行执行互不阻塞;
|
||||
- 编辑器 / 结果区可拖动分栏,长查询时编辑器不被结果挤占;
|
||||
- Tab 与布局持久化,重开应用保持原样。
|
||||
|
||||
## 对象树联动
|
||||
|
||||
库节点右键「新建查询」会把该库绑定到新标签。表右键可打开前 N 行(1–10000)、复制限定名、生成 SELECT / INSERT;模板打开在新查询中,不覆盖已有草稿。视图不提供 INSERT 模板。
|
||||
|
||||
执行未限定表名的 SQL 时,使用当前查询标签工具条选中的库;各标签独立保存库上下文。MySQL 系列与 SQL Server 执行 `USE 库名` 会先验证目标库,再切换该标签,脚本中的后续语句也使用新库。目标库不存在或无权限时保持原库不变,并停止该批次的后续语句。PostgreSQL 请通过工具条切换数据库;Redis 单机用 DB 选择器或 `SELECT 0`–`SELECT 15`,集群固定 DB0。
|
||||
|
||||
编辑器右键支持格式化选区或全文、注释切换、查找替换,以及复制纯文本或带连接摘要的 SQL。连接摘要不含账号密码。点击已加载元数据中的明确表名,可跳转到 DDL;无法唯一识别、别名或未加载对象会禁用跳转。
|
||||
|
||||
- 左侧对象树懒加载库 / 表 / 列;
|
||||
- **点表名 = 查询前 100 行**,自动生成对应 SQL;
|
||||
- 展开表看列名与类型,写 SQL 时可对照。
|
||||
|
||||
## 查询历史
|
||||
|
||||
- 本地留存最近 200 条(不上传、不同步);
|
||||
- **相同语句自动去重置顶** —— 历史即「最近用过的不同语句」,高频查询永远在第一条;
|
||||
- 点击条目回填编辑器;悬停出现 **▶** 按钮,回填并直接重跑;
|
||||
- 顶部过滤框支持按语句内容或连接名搜索;
|
||||
- 条目显示时间、连接名、行数与耗时;失败的语句红色标出。
|
||||
|
||||
## 危险 SQL 防护
|
||||
|
||||
执行以下语句前会弹确认框:
|
||||
|
||||
| 类型 | 规则 |
|
||||
| --- | --- |
|
||||
| 删除对象 | DROP / TRUNCATE |
|
||||
| 全表更新 | 无 WHERE 的 UPDATE / DELETE |
|
||||
|
||||
> **注意**:确认框只拦「明确危险」的模式,不替代事务与备份习惯;生产库操作请配合审批流程。
|
||||
|
||||
## 快捷键
|
||||
|
||||
| 快捷键 | 动作 |
|
||||
| --- | --- |
|
||||
| ⌘/Ctrl + Enter | 执行当前语句 / 选区 |
|
||||
| 双击结果单元格 | 复制单元格内容 |
|
||||
| Esc | 关闭弹层 / 取消确认 |
|
||||
|
||||
## 按对象浏览结构
|
||||
|
||||
关系库按能力显示「表、视图、存储过程、函数」。展开表可浏览字段,并按需展开索引、外键、触发器;视图可展开字段。元数据分组支持右键刷新,具体对象支持复制名称、定义或详情;失败时可重试,未适配的引擎会明确说明。当前目录查询已接入 MySQL 系列、PostgreSQL 系列和 SQLite。
|
||||
|
||||
表右键的「查看结构」打开字段结构页,「查看 DDL」查看定义,「复制建表 / 视图 SQL」直接复制定义。SELECT / INSERT 模板在新查询中打开;清空、删除仍须危险确认。
|
||||
|
||||
Redis:SQL 工具条可切换单机的 DB0–DB15,展开左侧 DB 后可在该库内搜索;底部搜索框查询当前库。输入普通关键词自动按 `*关键词*` 包含匹配,完整同名 Key 优先显示;也可输入模式(如 `user:*`)。回车或点击搜索才会请求服务端,最多 20 次 SCAN(COUNT 200、最多返回 500 项),不会使用 KEYS 枚举浏览。SCAN 仍有开销;有限搜索无结果不等于不存在,当前暂不提供续扫。集群只有 DB0,左侧直接显示 Key,隐藏多余的库层级。
|
||||
|
||||
Key 树仅在有过期时间时显示 TTL;点开 Key 的底部详情可输入正整数秒保存 TTL,`-1` 设为永久。`0` 秒会立即删除 Key,界面要求使用明确的删除操作。
|
||||
从 SQL 输入区执行 `GET`、`HGETALL`、`TTL` 等单键读取时也会打开键详情,可在底部查看并修改 TTL。
|
||||
|
||||
Redis 集群所有种子及集群公布的节点地址都需要从当前电脑可达。`127.0.0.1:7001 connection refused` 表示本机该端口拒绝连接;检查节点是否启动。若远程集群返回本机地址,应修正服务端 `cluster-announce-ip/port` 与端口映射。
|
||||
@@ -1,35 +0,0 @@
|
||||
查询跑完只是开始,把结果带走才算完成 —— OpsxDB 给了三条最快路径。
|
||||
|
||||
## 三种取数方式
|
||||
|
||||
| 方式 | 用途 |
|
||||
| --- | --- |
|
||||
| **复制** | 直接进剪贴板,贴到群聊 / 文档 / 表格 |
|
||||
| **CSV** | 导出标准 CSV 文件,Excel / Numbers 直接打开 |
|
||||
| **INSERT** | 把结果行生成为 INSERT 语句,直接可在别的库回放 |
|
||||
|
||||
## 单元格操作
|
||||
|
||||
结果上方可筛选已加载的数据,并显示匹配数;筛选不会向数据库发起查询。先显示 500 行,底部「继续显示」可展开更多已加载记录。服务端仍有更多数据时使用分页或完整查询导出。
|
||||
|
||||
NULL、空字符串、空白文本分别展示。右键「查看完整值」可查看和复制长文本或 JSON;只读单元格也可双击查看详情。列头右键可排序、复制列名、适应列宽,双击列边界也可适应内容。选中单元格后可用方向键移动、Ctrl/Cmd+C 复制、Shift+F10 打开菜单。
|
||||
|
||||
右键单元格、行号或列头可复制对应单元格、行或列;行列使用不含表头的 TSV,列复制包含本地筛选后的已加载行并遵循当前排序。NULL 显示为 `NULL`,含制表符/换行的字段会加引号。导出当前结果仍包含当前页全部已加载行,不受本地筛选影响。
|
||||
|
||||
右键还提供当前行 JSON、当前结果 JSON,以及 CSV / JSON 导出。当前行 INSERT 仅在结果明确来自表预览时启用,任意查询不会猜测目标表。导出当前结果不等于导出整张表。
|
||||
|
||||
- **双击单元格**:可写表进入编辑,只读结果打开完整值详情;复制使用右键或 Ctrl/Cmd+C。
|
||||
- 列头即字段名,长文本自动截断显示,完整内容在复制时保留。
|
||||
|
||||
## 截断提示
|
||||
|
||||
结果展示区分已加载记录与数据库中尚未取回的记录:
|
||||
|
||||
- 已加载记录分批显示,底部提示已显示数量,可点击「继续显示」。
|
||||
- 服务端返回更多行提示时,使用分页继续查询;需要完整数据可使用完整查询导出,也可通过 WHERE 缩小查询范围。导出当前结果仅导出已加载的当前页。
|
||||
|
||||
> **提示**:默认「点表名看前 100 行」就是截断策略的一部分 —— 快速浏览用 100 行,精确取数写 WHERE。
|
||||
|
||||
## 与 AI 面板联动
|
||||
|
||||
写不出来的查询可以直接在 AI 面板用自然语言描述(「查最近 7 天下单但未支付的用户」),生成 SQL 后放回编辑器执行,见《AI 助手》。
|
||||
@@ -1,66 +0,0 @@
|
||||
AI 面板的目标:让「写不出的 SQL」和「看不懂的 SQL」不再阻塞你。
|
||||
|
||||
## Ask 的操作
|
||||
|
||||
| 动作 | 用途 |
|
||||
| --- | --- |
|
||||
| 自由提问 | 结合当前 SQL 与库结构回答问题 |
|
||||
| 生成 SQL | 自然语言 → SQL(「查最近 7 天下单但未支付的用户」) |
|
||||
| 解释 | 把一段复杂 SQL 翻译成中文说明 |
|
||||
| 优化 | 分析慢查询,给出索引 / 改写建议 |
|
||||
| 修复 | 报错信息 + SQL → 修正版本 |
|
||||
| 样例 | 按表结构生成示例查询 |
|
||||
|
||||
|
||||
## Ask | Agent
|
||||
|
||||
侧栏输入框下方的下拉框切换模式,默认 Ask:
|
||||
|
||||
| 模式 | 行为 |
|
||||
| --- | --- |
|
||||
| **Ask** | 回答问题或建议 SQL;不执行数据库工具,也不自动改动 SQL 窗口。点击回复里的「复制到 SQL 窗口」后可自行执行 |
|
||||
| **Agent** | 使用与 MCP 同源的工具查询、分析当前编辑器绑定的连接与库(Redis 为当前 DB);展示步骤与结果,可在结果区打开 |
|
||||
|
||||
Agent 支持 openai-chat(DeepSeek 等)、Anthropic messages、OpenAI responses。当前连接须在 `~/.opsxdb/mcp.json` 白名单内;Agent 的工具调用限定在当前连接/库,外部 MCP 客户端仍按自己的白名单运行。数据库账号本身的跨库权限仍由数据库控制。
|
||||
|
||||
默认 **只读**。若将 `mode` 设为 `read_write`,写操作仍须在气泡确认条核对连接、库、语句后点「执行」(一次一刀);切库后原确认失效,模型不能自行带确认令牌。
|
||||
|
||||
## MCP
|
||||
|
||||
把同一套工具暴露给 Cursor / Claude / Codex:
|
||||
|
||||
```bash
|
||||
npm install -g @rlwj-lab/opsxdb-mcp@latest
|
||||
# 另需 Go 二进制,见 MCP 接入文档
|
||||
npx -y @rlwj-lab/opsxdb-mcp
|
||||
```
|
||||
|
||||
在桌面 **设置 → MCP** 可检测安装、切换只读/危险 SQL、勾选连接白名单,并复制 Cursor / Claude Code / VS Code 等配置片段。完整说明见 [MCP 接入](/docs/mcp)。
|
||||
|
||||
白名单写在 `~/.opsxdb/mcp.json` 的 `allowed_connection_ids`;空白名单拒绝全部连接。审计:`~/.opsxdb/logs/mcp-audit.jsonl`。
|
||||
|
||||
侧栏标题旁仅在外部 MCP **近期有调用**时显示绿色「MCP」点;悬停/点击可看最近摘要。
|
||||
|
||||
## 使用方式
|
||||
|
||||
1. 连接库后打开右侧 AI 面板;
|
||||
2. 选择动作,输入需求或粘贴 SQL(可附上对象树上下文);
|
||||
3. 核对生成结果,点击「复制到 SQL 窗口」,再按 ⌘/Ctrl + Enter 执行。
|
||||
|
||||
> **提示**:生成的 SQL 依旧走危险语句确认流程 —— AI 产出与手写 SQL 同等对待,不放宽防护。
|
||||
|
||||
## 配置服务
|
||||
|
||||
点击桌面右上角「设置」,在「大模型 → AI 供应商」选择服务,填写模型、API 密钥和接口地址,再点击「保存」或「测试连接」(测试会先保存配置)。也可以从 AI 面板的设置入口配置。
|
||||
|
||||
支持离线演示和 OpenAI 兼容服务。已保存的 API Key 不回显,留空保存表示保留原密钥。配置加载失败时可重试。
|
||||
|
||||
## 数据流向承诺
|
||||
|
||||
接入模型服务时遵循三条原则:
|
||||
|
||||
- 默认只发送你明确提交的内容(不含连接凭据);
|
||||
- 可完全关闭 AI 功能;
|
||||
- 使用云端模型时在界面上明确标识。
|
||||
|
||||
AI 自动跟随 SQL 编辑器当前连接与数据库(Redis 显示 DB 编号,集群固定 DB0),输入框上方可核对目标。Ask 模式下选择自由提问、生成 SQL、解释、优化、修复或样例后发送;Shift+Enter 换行。切换标签时,晚到的建议只留在回复里,不会改写 SQL 窗口。
|
||||
@@ -1,102 +0,0 @@
|
||||
{
|
||||
"productVersion": "0.1",
|
||||
"groups": [
|
||||
{
|
||||
"name": "开始使用",
|
||||
"pages": [
|
||||
{
|
||||
"file": "01-intro.md",
|
||||
"slug": "intro",
|
||||
"title": "产品介绍",
|
||||
"updated": "2026-09-20"
|
||||
},
|
||||
{
|
||||
"file": "02-quickstart.md",
|
||||
"slug": "quickstart",
|
||||
"title": "快速开始",
|
||||
"updated": "2026-09-20"
|
||||
},
|
||||
{
|
||||
"file": "03-interface.md",
|
||||
"slug": "interface",
|
||||
"title": "界面导览",
|
||||
"updated": "2026-09-20"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "连接与驱动",
|
||||
"pages": [
|
||||
{
|
||||
"file": "04-connect.md",
|
||||
"slug": "connect",
|
||||
"title": "新建连接",
|
||||
"updated": "2026-09-20"
|
||||
},
|
||||
{
|
||||
"file": "05-drivers.md",
|
||||
"slug": "drivers",
|
||||
"title": "驱动支持",
|
||||
"updated": "2026-09-20"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "SQL 工作台",
|
||||
"pages": [
|
||||
{
|
||||
"file": "06-workbench.md",
|
||||
"slug": "workbench",
|
||||
"title": "SQL 工作台",
|
||||
"updated": "2026-09-20"
|
||||
},
|
||||
{
|
||||
"file": "07-results.md",
|
||||
"slug": "results",
|
||||
"title": "结果与导出",
|
||||
"updated": "2026-09-20"
|
||||
},
|
||||
{
|
||||
"file": "08-redis.md",
|
||||
"slug": "redis",
|
||||
"title": "Redis 工作台",
|
||||
"updated": "2026-09-20"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "安全与 AI",
|
||||
"pages": [
|
||||
{
|
||||
"file": "09-security.md",
|
||||
"slug": "security",
|
||||
"title": "安全设计",
|
||||
"updated": "2026-09-20"
|
||||
},
|
||||
{
|
||||
"file": "10-ai.md",
|
||||
"slug": "ai",
|
||||
"title": "AI 助手",
|
||||
"updated": "2026-10-15"
|
||||
},
|
||||
{
|
||||
"file": "12-mcp.md",
|
||||
"slug": "mcp",
|
||||
"title": "MCP 接入",
|
||||
"updated": "2026-10-15"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "参考",
|
||||
"pages": [
|
||||
{
|
||||
"file": "11-faq.md",
|
||||
"slug": "faq",
|
||||
"title": "常见问题",
|
||||
"updated": "2026-09-20"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,264 +0,0 @@
|
||||
// Package docs 在 /docs 路径提供产品用户文档(Markdown 嵌入二进制,SSR 渲染)。
|
||||
package docs
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/yuin/goldmark"
|
||||
"github.com/yuin/goldmark/extension"
|
||||
gmhtml "github.com/yuin/goldmark/renderer/html"
|
||||
)
|
||||
|
||||
//go:embed content assets template.html
|
||||
var files embed.FS
|
||||
|
||||
type PageDef struct {
|
||||
File string `json:"file"`
|
||||
Slug string `json:"slug"`
|
||||
Title string `json:"title"`
|
||||
Updated string `json:"updated,omitempty"`
|
||||
}
|
||||
|
||||
type GroupDef struct {
|
||||
Name string `json:"name"`
|
||||
Pages []PageDef `json:"pages"`
|
||||
}
|
||||
|
||||
type Manifest struct {
|
||||
ProductVersion string `json:"productVersion"`
|
||||
Groups []GroupDef `json:"groups"`
|
||||
}
|
||||
|
||||
// TocItem 本页目录项
|
||||
type TocItem struct {
|
||||
ID string `json:"id"`
|
||||
Level int `json:"level"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
type SearchEntry struct {
|
||||
Slug string `json:"slug"`
|
||||
Title string `json:"title"`
|
||||
Group string `json:"group"`
|
||||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
type NavLink struct {
|
||||
Slug string
|
||||
Title string
|
||||
}
|
||||
|
||||
type Page struct {
|
||||
Slug string
|
||||
Title string
|
||||
Group string
|
||||
Updated string
|
||||
HTML string
|
||||
TOC []TocItem
|
||||
Prev *NavLink
|
||||
Next *NavLink
|
||||
}
|
||||
|
||||
// Handler 文档服务
|
||||
type Handler struct {
|
||||
manifest Manifest
|
||||
pages map[string]*Page
|
||||
order []string
|
||||
searchData []byte
|
||||
tpl string
|
||||
}
|
||||
|
||||
func New() *Handler {
|
||||
h := &Handler{pages: map[string]*Page{}}
|
||||
raw, err := files.ReadFile("content/manifest.json")
|
||||
if err != nil {
|
||||
panic("docs: manifest.json 缺失: " + err.Error())
|
||||
}
|
||||
if err := json.Unmarshal(raw, &h.manifest); err != nil {
|
||||
panic("docs: manifest.json 解析失败: " + err.Error())
|
||||
}
|
||||
tplRaw, err := files.ReadFile("template.html")
|
||||
if err != nil {
|
||||
panic("docs: template.html 缺失: " + err.Error())
|
||||
}
|
||||
h.tpl = string(tplRaw)
|
||||
|
||||
md := goldmark.New(
|
||||
goldmark.WithExtensions(extension.Table, extension.Strikethrough, extension.TaskList),
|
||||
goldmark.WithRendererOptions(gmhtml.WithHardWraps()),
|
||||
)
|
||||
|
||||
search := []SearchEntry{}
|
||||
var prev *NavLink
|
||||
for _, group := range h.manifest.Groups {
|
||||
for _, def := range group.Pages {
|
||||
src, err := files.ReadFile("content/" + def.File)
|
||||
if err != nil {
|
||||
panic("docs: 缺少内容文件 " + def.File)
|
||||
}
|
||||
var buf strings.Builder
|
||||
if err := md.Convert(src, &buf); err != nil {
|
||||
panic("docs: 渲染失败 " + def.File + ": " + err.Error())
|
||||
}
|
||||
body, toc := injectHeadingIDs(buf.String())
|
||||
page := &Page{
|
||||
Slug: def.Slug,
|
||||
Title: def.Title,
|
||||
Group: group.Name,
|
||||
Updated: def.Updated,
|
||||
HTML: body,
|
||||
TOC: toc,
|
||||
Prev: prev,
|
||||
}
|
||||
h.pages[def.Slug] = page
|
||||
h.order = append(h.order, def.Slug)
|
||||
prev = &NavLink{Slug: def.Slug, Title: def.Title}
|
||||
search = append(search, SearchEntry{
|
||||
Slug: def.Slug,
|
||||
Title: def.Title,
|
||||
Group: group.Name,
|
||||
Text: plainText(string(src)),
|
||||
})
|
||||
}
|
||||
}
|
||||
// 下一页链接
|
||||
for i, slug := range h.order {
|
||||
if i+1 < len(h.order) {
|
||||
next := h.pages[h.order[i+1]]
|
||||
h.pages[slug].Next = &NavLink{Slug: next.Slug, Title: next.Title}
|
||||
}
|
||||
}
|
||||
searchJSON, _ := json.Marshal(search)
|
||||
h.searchData = searchJSON
|
||||
return h
|
||||
}
|
||||
|
||||
// Register 注册路由(单一 catch-all,避免静态/参数段冲突)
|
||||
func (h *Handler) Register(r *gin.Engine) {
|
||||
r.GET("/docs", func(c *gin.Context) {
|
||||
c.Redirect(http.StatusFound, "/docs/"+h.order[0])
|
||||
})
|
||||
r.GET("/docs/*path", h.dispatch)
|
||||
}
|
||||
|
||||
func (h *Handler) dispatch(c *gin.Context) {
|
||||
p := strings.Trim(c.Param("path"), "/")
|
||||
switch {
|
||||
case p == "":
|
||||
c.Redirect(http.StatusFound, "/docs/"+h.order[0])
|
||||
case p == "search-data.json":
|
||||
h.SearchData(c)
|
||||
case strings.HasPrefix(p, "assets/"):
|
||||
c.Params = []gin.Param{{Key: "file", Value: "/" + strings.TrimPrefix(p, "assets")}}
|
||||
h.Asset(c)
|
||||
default:
|
||||
// 取第一段作为 slug(忽略子路径)
|
||||
slug := p
|
||||
if i := strings.IndexByte(p, '/'); i >= 0 {
|
||||
slug = p[:i]
|
||||
}
|
||||
c.Params = []gin.Param{{Key: "slug", Value: slug}}
|
||||
h.Page(c)
|
||||
}
|
||||
}
|
||||
|
||||
// Page 渲染文档页
|
||||
func (h *Handler) Page(c *gin.Context) {
|
||||
slug := c.Param("slug")
|
||||
page, ok := h.pages[slug]
|
||||
if !ok {
|
||||
c.Status(http.StatusNotFound)
|
||||
_, _ = c.Writer.WriteString(notFoundHTML(h.order[0])) //nolint:errcheck
|
||||
return
|
||||
}
|
||||
c.Header("Content-Type", "text/html; charset=utf-8")
|
||||
c.Header("Cache-Control", "no-cache")
|
||||
_, _ = c.Writer.WriteString(renderPage(h, page))
|
||||
}
|
||||
|
||||
// SearchData 搜索索引
|
||||
func (h *Handler) SearchData(c *gin.Context) {
|
||||
c.Data(http.StatusOK, "application/json; charset=utf-8", h.searchData)
|
||||
}
|
||||
|
||||
// Asset 静态资源
|
||||
func (h *Handler) Asset(c *gin.Context) {
|
||||
name := path.Clean(c.Param("file"))
|
||||
if strings.Contains(name, "..") {
|
||||
c.Status(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
data, err := files.ReadFile("assets" + name)
|
||||
if err != nil {
|
||||
c.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
switch {
|
||||
case strings.HasSuffix(name, ".css"):
|
||||
c.Header("Content-Type", "text/css; charset=utf-8")
|
||||
case strings.HasSuffix(name, ".js"):
|
||||
c.Header("Content-Type", "application/javascript; charset=utf-8")
|
||||
case strings.HasSuffix(name, ".svg"):
|
||||
c.Header("Content-Type", "image/svg+xml")
|
||||
default:
|
||||
c.Header("Content-Type", "application/octet-stream")
|
||||
}
|
||||
c.Header("Cache-Control", "public, max-age=3600")
|
||||
c.Data(http.StatusOK, "", data)
|
||||
}
|
||||
|
||||
// ManifestExport 供测试使用
|
||||
func (h *Handler) ManifestExport() Manifest { return h.manifest }
|
||||
|
||||
func (h *Handler) FirstSlug() string { return h.order[0] }
|
||||
|
||||
var (
|
||||
hRe = regexp.MustCompile(`(?s)<(h[23])>(.*?)</h[23]>`)
|
||||
tagRe = regexp.MustCompile(`<[^>]+>`)
|
||||
)
|
||||
|
||||
// injectHeadingIDs 给 h2/h3 加锚点 id,并产出目录
|
||||
func injectHeadingIDs(html string) (string, []TocItem) {
|
||||
var toc []TocItem
|
||||
counter := 0
|
||||
out := hRe.ReplaceAllStringFunc(html, func(m string) string {
|
||||
sub := hRe.FindStringSubmatch(m)
|
||||
tag, inner := sub[1], sub[2]
|
||||
counter++
|
||||
id := fmt.Sprintf("sec-%d", counter)
|
||||
text := strings.TrimSpace(tagRe.ReplaceAllString(inner, ""))
|
||||
level := 2
|
||||
if tag == "h3" {
|
||||
level = 3
|
||||
}
|
||||
toc = append(toc, TocItem{ID: id, Level: level, Text: text})
|
||||
return fmt.Sprintf(`<%s id="%s">%s</%s>`, tag, id, inner, tag)
|
||||
})
|
||||
return out, toc
|
||||
}
|
||||
|
||||
var mdNoise = regexp.MustCompile("(?s)```.*?```|`[^`]*`|!\\[[^\\]]*\\]\\([^)]*\\)|\\[[^\\]]*\\]\\([^)]*\\)|[#>*_\\-|]+")
|
||||
|
||||
// plainText 供搜索索引的纯文本
|
||||
func plainText(src string) string {
|
||||
s := mdNoise.ReplaceAllString(src, " ")
|
||||
s = strings.Join(strings.Fields(s), " ")
|
||||
if len(s) > 6000 {
|
||||
s = s[:6000]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func notFoundHTML(home string) string {
|
||||
return fmt.Sprintf(`<!doctype html><html lang="zh-CN"><head><meta charset="utf-8"><title>404 · OpsxDB 文档</title>
|
||||
<link rel="stylesheet" href="/docs/assets/docs.css"></head><body class="doc-404">
|
||||
<div class="wrap"><h1>404</h1><p>文档页面不存在或已被移动。</p><a class="btn" href="%s">返回文档首页</a></div>
|
||||
</body></html>`, home)
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package docs
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func renderPage(h *Handler, p *Page) string {
|
||||
tpl, err := template.New("doc").Parse(h.tpl)
|
||||
if err != nil {
|
||||
return "<!doctype html><meta charset=utf-8><title>error</title>template error: " + template.HTMLEscapeString(err.Error())
|
||||
}
|
||||
|
||||
var sb strings.Builder
|
||||
data := map[string]any{
|
||||
"Manifest": h.manifest,
|
||||
"Page": p,
|
||||
"TOC": p.TOC,
|
||||
"Content": template.HTML(p.HTML), //nolint:gosec —— 内容为内置受信 Markdown
|
||||
}
|
||||
if err := tpl.Execute(&sb, data); err != nil {
|
||||
return "<!doctype html><meta charset=utf-8><title>error</title>render error: " + template.HTMLEscapeString(err.Error())
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package server
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -13,8 +14,6 @@ import (
|
||||
"opsxdb/server/internal/ai"
|
||||
"opsxdb/server/internal/aitools"
|
||||
"opsxdb/server/internal/db"
|
||||
"opsxdb/server/internal/docs"
|
||||
"opsxdb/server/internal/site"
|
||||
)
|
||||
|
||||
// Version 由 cmd/opsxdb 注入,/health 响应携带供桌面 sidecar 版本握手。
|
||||
@@ -28,11 +27,11 @@ func NewRouter(token string) *gin.Engine {
|
||||
r.GET("/health", health)
|
||||
r.GET("/api/health", health)
|
||||
|
||||
// homepage/dist 存在时整站走静态(落地页 + 文档,对齐 opsxapi/opsxshell);
|
||||
// 否则回退内嵌 SSR 文档与官网模板。
|
||||
// 官网/文档/定价已拆分为独立静态站(源在仓库根 homepage/,构建见 scripts/build-homepage.sh);
|
||||
// 本地仅静态托管 homepage/dist 预览,不再内置 go:embed 兜底,与后端二进制彻底解耦。
|
||||
// 产物缺失时打 warn 日志而非崩溃(其余 API 路由不受影响)。// Logan.Li
|
||||
if !mountHomepage(r) {
|
||||
docs.New().Register(r)
|
||||
site.New().Register(r)
|
||||
log.Printf("[warn] homepage/dist 未找到,官网/文档/定价未挂载;请先运行 scripts/build-homepage.sh 生成产物")
|
||||
}
|
||||
|
||||
api := r.Group("/api")
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
// Package site:产品官网落地页(嵌入二进制,深色密度跟工作台)。
|
||||
package site
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
//go:embed template.html assets
|
||||
var files embed.FS
|
||||
|
||||
type Handler struct {
|
||||
html string
|
||||
}
|
||||
|
||||
func New() *Handler {
|
||||
raw, err := files.ReadFile("template.html")
|
||||
if err != nil {
|
||||
panic("site: template.html 缺失: " + err.Error())
|
||||
}
|
||||
return &Handler{html: string(raw)}
|
||||
}
|
||||
|
||||
func (h *Handler) Register(r *gin.Engine) {
|
||||
r.GET("/", h.Page)
|
||||
r.GET("/home", h.Page)
|
||||
r.GET("/index.html", h.Page)
|
||||
r.GET("/site/assets/*file", h.Asset)
|
||||
}
|
||||
|
||||
func (h *Handler) Page(c *gin.Context) {
|
||||
c.Header("Content-Type", "text/html; charset=utf-8")
|
||||
c.Header("Cache-Control", "no-cache")
|
||||
_, _ = c.Writer.WriteString(h.html)
|
||||
}
|
||||
|
||||
func (h *Handler) Asset(c *gin.Context) {
|
||||
name := strings.TrimPrefix(c.Param("file"), "/")
|
||||
if strings.Contains(name, "..") {
|
||||
c.Status(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
data, err := files.ReadFile("assets/" + name)
|
||||
if err != nil {
|
||||
c.Status(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
ct := "application/octet-stream"
|
||||
if strings.HasSuffix(name, ".css") {
|
||||
ct = "text/css; charset=utf-8"
|
||||
}
|
||||
c.Header("Content-Type", ct)
|
||||
c.Header("Cache-Control", "public, max-age=3600")
|
||||
c.Data(http.StatusOK, ct, data)
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
module opsxdb/tools/homepage-build
|
||||
|
||||
go 1.25.0
|
||||
|
||||
require github.com/yuin/goldmark v1.8.6
|
||||
@@ -0,0 +1,2 @@
|
||||
github.com/yuin/goldmark v1.8.6 h1:d0VcaP1sx9GkFVkoW+KtggpGi2KZ965i14b0+bDQST4=
|
||||
github.com/yuin/goldmark v1.8.6/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg=
|
||||
@@ -0,0 +1,228 @@
|
||||
// homepage-build:把 homepage/ 源(落地页 + 定价页 + 文档 md)构建为纯静态站点 homepage/dist/。
|
||||
// 产物可直接部署到任意静态托管(nginx/Pages)——官网与后端二进制彻底解耦。
|
||||
// 用法: go run . [-src homepage] [-out homepage/dist]
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/yuin/goldmark"
|
||||
"github.com/yuin/goldmark/extension"
|
||||
gmhtml "github.com/yuin/goldmark/renderer/html"
|
||||
)
|
||||
|
||||
type PageDef struct {
|
||||
File string `json:"file"`
|
||||
Slug string `json:"slug"`
|
||||
Title string `json:"title"`
|
||||
Updated string `json:"updated,omitempty"`
|
||||
Hidden bool `json:"hidden,omitempty"`
|
||||
}
|
||||
type GroupDef struct {
|
||||
Name string `json:"name"`
|
||||
Pages []PageDef `json:"pages"`
|
||||
}
|
||||
type Manifest struct {
|
||||
ProductVersion string `json:"productVersion"`
|
||||
Groups []GroupDef `json:"groups"`
|
||||
}
|
||||
type TocItem struct {
|
||||
ID string
|
||||
Level int
|
||||
Text string
|
||||
}
|
||||
type SearchEntry struct {
|
||||
Slug, Title, Group, Text string
|
||||
}
|
||||
type NavLink struct {
|
||||
Slug, Title string
|
||||
}
|
||||
type Page struct {
|
||||
Slug, Title, Group, Updated string
|
||||
HTML template.HTML
|
||||
TOC []TocItem
|
||||
Prev, Next *NavLink
|
||||
}
|
||||
|
||||
var (
|
||||
hRe = regexp.MustCompile(`(?s)<(h[23])>(.*?)</h[23]>`)
|
||||
tagRe = regexp.MustCompile(`<[^>]+>`)
|
||||
mdNoise = regexp.MustCompile("(?s)```.*?```|`[^`]*`|!\\[[^\\]]*\\]\\([^)]*\\)|\\[[^\\]]*\\]\\([^)]*\\)|[#>*_\\-|]+")
|
||||
)
|
||||
|
||||
func injectHeadingIDs(html string) (string, []TocItem) {
|
||||
var toc []TocItem
|
||||
counter := 0
|
||||
out := hRe.ReplaceAllStringFunc(html, func(m string) string {
|
||||
sub := hRe.FindStringSubmatch(m)
|
||||
tag, inner := sub[1], sub[2]
|
||||
counter++
|
||||
id := fmt.Sprintf("sec-%d", counter)
|
||||
text := strings.TrimSpace(tagRe.ReplaceAllString(inner, ""))
|
||||
level := 2
|
||||
if tag == "h3" {
|
||||
level = 3
|
||||
}
|
||||
toc = append(toc, TocItem{ID: id, Level: level, Text: text})
|
||||
return fmt.Sprintf(`<%s id="%s">%s</%s>`, tag, id, inner, tag)
|
||||
})
|
||||
return out, toc
|
||||
}
|
||||
|
||||
func plainText(src string) string {
|
||||
s := mdNoise.ReplaceAllString(src, " ")
|
||||
s = strings.Join(strings.Fields(s), " ")
|
||||
if len(s) > 6000 {
|
||||
s = s[:6000]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func must(err error, what string) {
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "[homepage-build] %s: %v\n", what, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func writeFile(path string, content []byte) {
|
||||
must(os.MkdirAll(filepath.Dir(path), 0o755), "mkdir "+path)
|
||||
must(os.WriteFile(path, content, 0o644), "write "+path)
|
||||
fmt.Println("[OK]", path)
|
||||
}
|
||||
|
||||
// visibleManifest 返回去掉 hidden 页的分组清单:模板侧栏、上/下一页、搜索索引都只含可见页。
|
||||
// Logan.Li
|
||||
func visibleManifest(m Manifest) Manifest {
|
||||
vm := Manifest{ProductVersion: m.ProductVersion}
|
||||
for _, g := range m.Groups {
|
||||
ng := GroupDef{Name: g.Name}
|
||||
for _, p := range g.Pages {
|
||||
if !p.Hidden {
|
||||
ng.Pages = append(ng.Pages, p)
|
||||
}
|
||||
}
|
||||
if len(ng.Pages) > 0 {
|
||||
vm.Groups = append(vm.Groups, ng)
|
||||
}
|
||||
}
|
||||
return vm
|
||||
}
|
||||
|
||||
func main() {
|
||||
src := flag.String("src", "homepage", "源目录")
|
||||
out := flag.String("out", "homepage/dist", "产物目录")
|
||||
flag.Parse()
|
||||
|
||||
// 幂等重建:清理上一轮生成的子目录(os.CopyFS 目标已存在会报错)
|
||||
for _, d := range []string{"site", "docs", "pricing", "home"} {
|
||||
must(os.RemoveAll(filepath.Join(*out, d)), "清理 "+d)
|
||||
}
|
||||
|
||||
// 1) 落地页 + 别名 + 可选单页:纯 HTML 直接拷贝
|
||||
raw, err := os.ReadFile(filepath.Join(*src, "index.html"))
|
||||
must(err, "读 index.html")
|
||||
writeFile(filepath.Join(*out, "index.html"), raw)
|
||||
// /home 别名:对齐 nginx try_files $uri/index.html,GUI openExternal("/home") 依赖它
|
||||
writeFile(filepath.Join(*out, "home", "index.html"), raw)
|
||||
|
||||
// 可选单页(pricing / terms / license):根 <name>.html + <name>/index.html
|
||||
// (对齐 nginx location = /pricing|/license → 目录内 index;纯静态服务器上 /pricing/ 亦为 200)// Logan.Li
|
||||
for _, name := range []string{"pricing.html", "terms.html", "license.html"} {
|
||||
b, e := os.ReadFile(filepath.Join(*src, name))
|
||||
if e != nil {
|
||||
continue
|
||||
}
|
||||
writeFile(filepath.Join(*out, name), b)
|
||||
writeFile(filepath.Join(*out, strings.TrimSuffix(name, ".html"), "index.html"), b)
|
||||
}
|
||||
// 站点资源:落地页/定价页引用 /site/assets/*
|
||||
siteAssets := filepath.Join(*src, "assets")
|
||||
if st, _ := os.Stat(siteAssets); st != nil {
|
||||
must(os.CopyFS(filepath.Join(*out, "site", "assets"), os.DirFS(siteAssets)), "拷 site assets")
|
||||
fmt.Println("[OK]", filepath.Join(*out, "site", "assets"))
|
||||
}
|
||||
|
||||
// 2) 文档:manifest → goldmark 渲染 → docs.html 模板(Go html/template)
|
||||
mraw, err := os.ReadFile(filepath.Join(*src, "content", "manifest.json"))
|
||||
must(err, "读 manifest")
|
||||
var manifest Manifest
|
||||
must(json.Unmarshal(mraw, &manifest), "解析 manifest")
|
||||
vis := visibleManifest(manifest)
|
||||
|
||||
tplRaw, err := os.ReadFile(filepath.Join(*src, "docs.html"))
|
||||
must(err, "读 docs.html")
|
||||
tpl, err := template.New("doc").Parse(string(tplRaw))
|
||||
must(err, "解析 docs 模板")
|
||||
md := goldmark.New(goldmark.WithExtensions(extension.Table, extension.Strikethrough, extension.TaskList), goldmark.WithRendererOptions(gmhtml.WithHardWraps()))
|
||||
|
||||
// 可见页顺序(侧栏 / 上下一页 / 搜索)
|
||||
var order []string
|
||||
pages := map[string]*Page{}
|
||||
var search []SearchEntry
|
||||
var prev *NavLink
|
||||
for _, g := range vis.Groups {
|
||||
for _, def := range g.Pages {
|
||||
srcb, err := os.ReadFile(filepath.Join(*src, "content", def.File))
|
||||
must(err, "读文档 "+def.File)
|
||||
var buf strings.Builder
|
||||
must(md.Convert(srcb, &buf), "渲染 "+def.File)
|
||||
body, toc := injectHeadingIDs(buf.String())
|
||||
p := &Page{Slug: def.Slug, Title: def.Title, Group: g.Name, Updated: def.Updated, HTML: template.HTML(body), TOC: toc, Prev: prev}
|
||||
pages[def.Slug] = p
|
||||
order = append(order, def.Slug)
|
||||
prev = &NavLink{Slug: def.Slug, Title: def.Title}
|
||||
search = append(search, SearchEntry{Slug: def.Slug, Title: def.Title, Group: g.Name, Text: plainText(string(srcb))})
|
||||
}
|
||||
}
|
||||
for i, slug := range order {
|
||||
if i+1 < len(order) {
|
||||
n := pages[order[i+1]]
|
||||
pages[slug].Next = &NavLink{Slug: n.Slug, Title: n.Title}
|
||||
}
|
||||
}
|
||||
|
||||
render := func(p *Page) []byte {
|
||||
var sb strings.Builder
|
||||
must(tpl.Execute(&sb, map[string]any{"Manifest": vis, "Page": p, "TOC": p.TOC, "Content": p.HTML}), "渲染模板 "+p.Slug)
|
||||
return []byte(sb.String())
|
||||
}
|
||||
// /docs/ 首页 = 第一篇(静态站无重定向,直接渲染)
|
||||
writeFile(filepath.Join(*out, "docs", "index.html"), render(pages[order[0]]))
|
||||
for _, slug := range order {
|
||||
writeFile(filepath.Join(*out, "docs", slug, "index.html"), render(pages[slug]))
|
||||
}
|
||||
// hidden 页:仍渲染为独立页面(不进侧栏/导航/搜索),供 /docs/<slug> 直达
|
||||
for _, g := range manifest.Groups {
|
||||
for _, def := range g.Pages {
|
||||
if !def.Hidden {
|
||||
continue
|
||||
}
|
||||
srcb, err := os.ReadFile(filepath.Join(*src, "content", def.File))
|
||||
must(err, "读隐藏文档 "+def.File)
|
||||
var buf strings.Builder
|
||||
must(md.Convert(srcb, &buf), "渲染 "+def.File)
|
||||
body, toc := injectHeadingIDs(buf.String())
|
||||
p := &Page{Slug: def.Slug, Title: def.Title, Group: g.Name, Updated: def.Updated, HTML: template.HTML(body), TOC: toc}
|
||||
writeFile(filepath.Join(*out, "docs", def.Slug, "index.html"), render(p))
|
||||
}
|
||||
}
|
||||
sj, _ := json.Marshal(search)
|
||||
writeFile(filepath.Join(*out, "docs", "search-data.json"), sj)
|
||||
|
||||
// docs assets(模板引用 /docs/assets/*)
|
||||
da := filepath.Join(*src, "docs-assets")
|
||||
if st, _ := os.Stat(da); st != nil {
|
||||
must(os.CopyFS(filepath.Join(*out, "docs", "assets"), os.DirFS(da)), "拷 docs assets")
|
||||
fmt.Println("[OK]", filepath.Join(*out, "docs", "assets"))
|
||||
}
|
||||
|
||||
fmt.Printf("[DONE] 落地页 + %d 页文档(+隐藏页)→ %s(纯静态,可部署任意域名)\n", len(order), *out)
|
||||
}
|
||||
Reference in new issue
Block a user