=== 一、/queries 打开 MySQL 实例报 500 ===
现象:GET /api/v1/redis/5/dbs → 500
后端日志 redis: invalid reply: "J\x00\x00\x00\n"
("J\x00\x00\x00" 是 MySQL 握手包,说明用 Redis 协议连了 3306)
根因:SchemaSidebar 是 mysql/redis 共用的组件,其中
const redisDbs = useRedisDbs(Number(instanceId));
是无条件调用(React hooks 不能条件调用),而 useRedisDbs 内部
只看 instanceId 就请求 /redis/{id}/dbs →
MySQL 实例也发 Redis 请求 → 后端用 Redis 协议连 MySQL → 500。
修复(前后端双保险):
1. useRedisDbs 增加 enabled 参数(默认 true),false 时不发请求并复位 [0]/false
2. SchemaSidebar 传 isRedis:useRedisDbs(Number(instanceId), isRedis)
3. redis.go getRedisClient 前置校验 DBType != "redis" 直接返回
4. resp 包新增 UserFacingError / UserFacing(),InternalErr 识别后返回
400 + 可读原因(不再把所有错误笼统包装成 500 "服务器内部错误")
验证:
GET /redis/5/dbs(MySQL)→ 400
{"code":"bad_request","detail":"实例「pre-mysql-只读」的类型是 mysql,
不是 redis。Redis 接口只适用于 redis 实例;MySQL/PostgreSQL 请使用
/api/v1/instances/5/databases 等对应接口"}
GET /instances/5/databases → 200
GET /redis/4/dbs(Redis 集群)→ 200 {"cluster":true,"dbs":[0]}
=== 二、左侧栏点表不生成 SELECT ===
原交互:单击=展开/折叠,双击=执行 SELECT,Alt+点击=插入表名。
需求:单击表 → 在右侧编辑器生成 SELECT * FROM <db>.<table>
修复:
1. SchemaSidebar 表节点:箭头图标包 data-chevron 单独触发展开/折叠;
点表名区域 → onInsert(previewSelectSql(...) + ';\n')
Alt+点击仍为只插表名;双击仍为直接执行
2. QueriesPage onInsert:生成的文本以 SELECT 开头时「替换」编辑器内容
(原来一律追加,会和上一条语句拼成非法 SQL);表名/字段名仍追加
=== 三、SQL 编辑器光标同时在多行闪烁 ===
根因:.cm-cursor 强制了 height:1.25em !important + marginTop:0.15em,
而 .cm-line 行高是 1.55em,光标高度溢出到相邻行,视觉上像两行同时闪。
修复:光标样式只保留颜色与 1.5px 宽度,height/marginTop 交回 CodeMirror 自行计算。
镜像:lghost/opsxsql:latest + v0.1
React + TypeScript + Vite
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
Currently, two official plugins are available:
- @vitejs/plugin-react uses Babel (or oxc when used in rolldown-vite) for Fast Refresh
- @vitejs/plugin-react-swc uses SWC for Fast Refresh
React Compiler
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see this documentation.
Expanding the ESLint configuration
If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Remove tseslint.configs.recommended and replace with this
tseslint.configs.recommendedTypeChecked,
// Alternatively, use this for stricter rules
tseslint.configs.strictTypeChecked,
// Optionally, add this for stylistic rules
tseslint.configs.stylisticTypeChecked,
// Other configs...
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])
You can also install eslint-plugin-react-x and eslint-plugin-react-dom for React-specific lint rules:
// eslint.config.js
import reactX from 'eslint-plugin-react-x'
import reactDom from 'eslint-plugin-react-dom'
export default defineConfig([
globalIgnores(['dist']),
{
files: ['**/*.{ts,tsx}'],
extends: [
// Other configs...
// Enable lint rules for React
reactX.configs['recommended-typescript'],
// Enable lint rules for React DOM
reactDom.configs.recommended,
],
languageOptions: {
parserOptions: {
project: ['./tsconfig.node.json', './tsconfig.app.json'],
tsconfigRootDir: import.meta.dirname,
},
// other options...
},
},
])