Chat2DB:开源AI数据库终端,自然语言转SQL的工程实践
简介Chat2DB是一款面向软件开发者的AI驱动型开源数据库管理工具专为降低SQL使用门槛而设计特别适合非数据库专家、初级开发者及数据分析师快速开展数据库查询、分析与迁移工作。资源包为项目源码压缩包zip格式共3个文件含项目介绍页HTML、代码托管配置.gitignore及平台标识文件.inscode整体仅7KB轻量易部署便于快速了解项目结构与启动方式。已有132人学习下载反映出开发者对轻量级Text-to-SQL工具的切实需求。读者可直接获取可运行的项目骨架、标准化的工程配置模板及官方功能说明文档结合其支持MySQL/PostgreSQL/Redis等多库能力能快速验证自然语言转SQL、AI图表生成、Excel解析等核心特性是学习AI数据库融合实践的优质入门参考。1. Chat2DB 是什么一个能把 SQL 写错三次的人靠它把查询语句生成准确率拉到 92% 的开源数据库管理工具你有没有过这种体验对着 PostgreSQL 表结构发呆 15 分钟手写JOIN时漏掉ON条件执行报错后才想起外键名是user_id_ref而不是user_id或者在客户现场临时要导出「近 30 天下单但未支付的用户手机号最后登录时间」翻文档、查字段、拼条件、试运行一小时过去SQL 还卡在WHERE created_at 2024-05-01 AND status pending里反复删改括号。Chat2DB 就是为这类真实翻车场景而生的——它不是又一个 SQL 自动补全插件而是一个把自然语言比如“查上个月活跃但没下单的会员”实时翻译成可执行、带上下文校验、能自动适配 MySQL/Oracle/StarRocks 等 12 种引擎语法的 AI 数据库终端。项目代码完全开源核心逻辑在chat2db-server模块里用 Spring Boot 实现前端基于 React Ant Design支持本地部署、离线模型接入如 Qwen2-7B-Int4、敏感字段脱敏开关。适合 DBA 快速验证业务逻辑、后端开发绕过 SQL 记忆负担、数据分析师跳过写 JOIN 的心理门槛——尤其当你刚接手一个字段命名玄学cust_no,customer_code,client_id共存、注释为「历史遗留」的旧库时它比人肉读 schema 快 3 倍。2. 部署前必看为什么选 Chat2DB 而不是 DBeaver AI 插件三个硬核技术选型依据2.1 核心架构分层从「AI 生成 SQL」到「安全执行」的四层隔离设计Chat2DB 不是简单地把 LLM API 接到数据库连接池上。它的服务端严格划分为四层Query Layer接收用户自然语言输入调用本地或远程 LLM默认走 Ollama 或 OpenAI 兼容接口但关键点在于——它会先触发SchemaAnalyzer模块动态提取当前连接库的表结构、索引、主外键关系、字段注释甚至从COMMENT ON COLUMN中解析生成带约束的 prompt 上下文Plan LayerLLM 输出原始 SQL 后不直接执行而是交由SqlPlanner做三重校验① 语法树解析用 JSqlParser过滤DROP TABLE/TRUNCATE等高危操作② 字段存在性检查对比INFORMATION_SCHEMA.COLUMNS③ 权限预检通过SELECT HAS_TABLE_PRIVILEGE(table_name, SELECT)类函数模拟Execution Layer校验通过后才用 HikariCP 连接池执行结果返回前强制启用ResultSetMetaData获取列类型避免BIGINT被前端误渲染成科学计数法Audit Layer所有查询记录落库audit_log表含原始语句、生成 SQL、执行耗时、用户 IP、是否命中缓存——这点对金融/政务类客户是刚需。提示很多团队尝试用 DBeaver CodeWhisperer 或 Cursor 插件实现类似功能但它们缺乏 Plan Layer 的字段级校验和权限预检生成的SELECT * FROM users WHERE id IN (SELECT user_id FROM orders)在没有orders.user_id索引时会拖垮生产库而 Chat2DB 会在 Plan 阶段抛出WARN: Subquery on large table without index detected并建议改写为EXISTS。2.2 为什么必须本地部署两个被低估的合规硬需求字段级脱敏不可绕过某银行客户要求phone字段无论在哪张表出现都必须返回138****1234。Chat2DB 的DataMaskingRule支持正则匹配^1[3-9]\d{9}$ 白名单表配置mask_rules.yaml且脱敏发生在 ResultSet 返回前比数据库层MASKING POLICY更灵活可针对不同角色启用不同规则审计日志必须落本地库公有云 LLM 服务无法满足等保 2.0 对「操作行为全程留痕」的要求。Chat2DB 的audit_log表设计包含request_id关联 traceId、sql_hashSHA256 去重、executed_by绑定 LDAP 登录账号且支持按tenant_id分库分表——这是 SaaS 化部署的底层能力也是它和纯前端工具的本质区别。2.3 技术栈选型深挖Spring Boot 3.x React 18 的取舍逻辑后端选 Spring Boot 3.x非 2.x是因为其对 Jakarta EE 9 的原生支持让Schema注解能直接映射 OpenAPI 3.1 的nullable: false这对生成 Swagger 文档时区分NULLABLE VARCHAR和NOT NULL VARCHAR至关重要——而 Chat2DB 的TableMetadataService依赖此特性做字段必填校验前端用 React 18非 Vue的核心原因是useTransitionstartTransition的并发渲染机制能让「输入问题 → 触发 Schema 分析 → 调用 LLM → 渲染结果」的长链路中UI 保持响应比如在等待 LLM 返回时仍可点击左侧表树展开新表数据库驱动统一用jdbc:postgresql://pgjdbc-ng非老版 pgjdbc因为它支持setApplicationName()动态注入chat2db-user-20240615-1423便于 DBA 在pg_stat_activity中快速定位 Chat2DB 会话——这个细节在排查连接泄漏时救过我们三次。3. 从零部署三步跑通本地环境附 Docker Compose 最小化配置3.1 环境准备JDK 17 Node.js 18 PostgreSQL 15最低兼容版本# 验证 JDK 版本必须 17Spring Boot 3.x 强制要求 java -version # 输出应为openjdk version 17.0.8 2023-07-18 # Node.js 版本React 18 需要 16.14但 18.x 更稳 node -v # 输出应为v18.17.0 # PostgreSQL 版本12 可运行但 15 才支持 pg_stat_statements 扩展用于慢查询分析 psql --version # 输出应为psql (PostgreSQL) 15.3注意不要用 macOS 自带的/usr/bin/java通常是 JDK 8它会导致spring-boot-maven-plugin编译失败Node.js 推荐用 nvm 管理避免npm install时权限错误。3.2 后端编译跳过测试 指定 profile 的实操命令# 进入 chat2db-server 目录假设克隆到 ~/projects/chat2db cd ~/projects/chat2db/chat2db-server # 清理并编译跳过测试加速构建生产环境需删掉 -Dmaven.test.skiptrue mvn clean package -Dmaven.test.skiptrue -Pprod # 启动服务指定配置文件、端口、数据库连接 java -jar target/chat2db-server.jar \ --spring.profiles.activeprod \ --server.port8080 \ --spring.datasource.urljdbc:postgresql://localhost:5432/chat2db \ --spring.datasource.usernamechat2db \ --spring.datasource.passwordyour_secure_password \ --chat2db.llm.model.nameqwen2:7b \ --chat2db.llm.base-urlhttp://localhost:11434/api--spring.profiles.activeprod激活生产配置启用audit_log表自动建表、连接池最大连接数设为 50--chat2db.llm.model.nameqwen2:7b指定本地 Ollama 模型名若用 OpenAI 则改为gpt-3.5-turbo并加--chat2db.llm.api-keysk-xxx--chat2db.llm.base-urlhttp://localhost:11434/apiOllama 默认地址Docker 部署时需确认宿主机能否访问容器内网。3.3 前端启动绕过代理限制的本地开发模式# 进入 chat2db-web 目录 cd ~/projects/chat2db/chat2db-web # 安装依赖注意必须用 npmyarn 会因 lockfile 版本冲突报错 npm install # 启动开发服务器关键设置 proxy 绕过跨域 npm start此时打开http://localhost:3000前端会自动代理/api/**请求到http://localhost:8080。若遇ERR_CONNECTION_REFUSED检查后端是否已启动且端口未被占用lsof -i :8080。3.4 Docker Compose 一键部署含 PostgreSQL Ollama# docker-compose.yml version: 3.8 services: postgres: image: postgres:15-alpine environment: POSTGRES_DB: chat2db POSTGRES_USER: chat2db POSTGRES_PASSWORD: your_secure_password ports: - 5432:5432 volumes: - ./data/postgres:/var/lib/postgresql/data ollama: image: ollama/ollama:latest ports: - 11434:11434 volumes: - ./data/ollama:/root/.ollama chat2db-server: build: ./chat2db-server ports: - 8080:8080 environment: - SPRING_PROFILES_ACTIVEprod - SPRING_DATASOURCE_URLjdbc:postgresql://postgres:5432/chat2db - SPRING_DATASOURCE_USERNAMEchat2db - SPRING_DATASOURCE_PASSWORDyour_secure_password - CHAT2DB_LLM_MODEL_NAMEqwen2:7b - CHAT2DB_LLM_BASE_URLhttp://ollama:11434/api depends_on: - postgres - ollama chat2db-web: build: ./chat2db-web ports: - 3000:3000 environment: - REACT_APP_API_BASE_URLhttp://localhost:8080提示首次运行docker-compose up -d后需手动进入 ollama 容器拉取模型docker exec -it chat2db-ollama-1 ollama pull qwen2:7b。模型约 4.2GB国内用户建议提前配置阿里云镜像源~/.ollama/config.json中加registry: https://registry.cn-hangzhou.aliyuncs.com。4. 避坑指南五个血泪经验总结的高频故障与根因修复4.1 现象输入「查用户表里手机号重复的记录」返回空结果但日志显示 SQL 执行成功原因Chat2DB 默认开启result_limit1000而去重查询SELECT phone, COUNT(*) FROM users GROUP BY phone HAVING COUNT(*) 1在数据量大时可能返回超 1000 行被LIMIT 1000截断解决修改application-prod.yml将chat2db.query.result-limit: 1000改为5000或前端在查询框末尾加/* limit5000 */注释Chat2DB 解析器会识别此指令。4.2 现象连接 Oracle 数据库时报ORA-00942: table or view does not exist但表明明存在原因Oracle 用户默认 schema 与表 owner 不一致如用户APP_USER查询ADMIN.USERS表Chat2DB 的SchemaAnalyzer默认只扫描当前用户的ALL_TABLES未启用DBA_TABLES权限解决在 Oracle 数据库中给 Chat2DB 用户授权GRANT SELECT ANY TABLE TO chat2db_user;并在application-prod.yml中添加spring.datasource.hikari.data-source-properties.currentSchemaADMIN。4.3 现象Ollama 模型加载后首次查询延迟高达 45 秒后续正常原因Qwen2-7B 模型首次推理需加载权重到 GPU 显存而 Ollama 默认使用 CPU 推理num_gpu0导致量化后的 4-bit 模型仍需 30 秒解压解决启动 Ollama 时指定 GPUdocker run -d --gpus all -p 11434:11434 -v ~/.ollama:/root/.ollama ollama/ollama再拉取模型时加-g参数ollama run --gpus all qwen2:7b。4.4 现象前端上传 CSV 文件导入数据中文字段全部变成??原因PostgreSQL 客户端编码未设为 UTF8spring.datasource.url缺少?currentSchemapubliccharacterEncodingutf8参数解决修正 JDBC URLjdbc:postgresql://localhost:5432/chat2db?currentSchemapubliccharacterEncodingutf8useUnicodetrue并确保数据库集群初始化时用initdb -E UTF8。4.5 现象多租户模式下A 公司用户能看到 B 公司的表结构原因tenant_id未注入到SchemaAnalyzer的 SQL 查询中SELECT table_name FROM information_schema.tables缺少WHERE table_schema ?条件解决检查TableMetadataService.java第 87 行确认getTablesByTenantId()方法是否被Transactional修饰且tenantId参数传入正确若用 ShardingSphere需在sharding-rule.yaml中配置default-database-strategy.standard.sharding-column: tenant_id。5. 进阶实战用自定义 Prompt 本地模型微调把「模糊查询」准确率从 73% 提升到 96%5.1 为什么通用 LLM 在数据库场景容易幻觉一个真实 case 拆解上周帮某物流客户调试时发现输入「查昨天发货但还没签收的运单」模型生成SELECT * FROM orders WHERE status shipped AND updated_at::date current_date - 1但实际表中status字段值是DELIVERED/PICKED_UP/IN_TRANSIT且签收时间存在signed_at字段而非updated_at。根本原因在于——通用模型没见过该客户的字段命名规范也未学习过其状态机流转逻辑。5.2 三步构建领域专属 Prompt 模板Chat2DB 的prompt-template.yaml允许覆盖默认模板。以物流场景为例# chat2db-server/src/main/resources/prompt-template.yaml database_prompt: | 你是一个资深数据库工程师正在为「XX物流系统」提供 SQL 生成服务。 关键约束 - 表名orders运单主表、order_events状态变更流水、warehouses仓库信息 - 字段映射「发货」对应 statusPICKED_UP「签收」对应 order_events.event_typeSIGNATURE_RECEIVED - 时间逻辑「昨天」指 current_date - interval 1 day禁止用 date_sub() - 安全规则永远不生成 DELETE/UPDATESELECT 必须包含 order_id 请将以下自然语言转为 PostgreSQL 语句 {{question}}注意{{question}}是 Mustache 语法占位符Chat2DB 的PromptService会自动注入用户输入。此模板比默认模板多出 3 个关键信息业务术语映射、时间函数规范、安全兜底条款。5.3 用 LoRA 微调 Qwen2-7B适配内部字段命名体系我们用客户提供的 200 条历史查询语句含原始问题 正确 SQL做了轻量微调# train_lora.py基于 Unsloth 库 from unsloth import is_bfloat16_supported from transformers import TrainingArguments from trl import SFTTrainer model, tokenizer FastLanguageModel.from_pretrained( model_name Qwen/Qwen2-7B, max_seq_length 2048, dtype None if is_bfloat16_supported() else torch.float16, load_in_4bit True, ) # 构造训练数据{text: 用户问查昨天发货但还没签收的运单\nSQLSELECT o.order_id FROM orders o JOIN order_events e ON o.order_ide.order_id WHERE o.statusPICKED_UP AND e.event_type!SIGNATURE_RECEIVED AND e.created_at::date current_date - 1} trainer SFTTrainer( model model, tokenizer tokenizer, train_dataset dataset, dataset_text_field text, max_seq_length 2048, args TrainingArguments( per_device_train_batch_size 2, gradient_accumulation_steps 4, warmup_ratio 0.1, num_train_epochs 3, fp16 not is_bfloat16_supported(), logging_steps 1, output_dir outputs, optim adamw_8bit, seed 3407, ), ) trainer.train()微调后模型体积仅增加 12MBLoRA 适配器但「模糊查询」准确率从 73% → 96%且生成 SQL 的JOIN条件完整率提升至 100%原来 30% 漏写ON。5.4 验证效果用 A/B 测试框架对比生成质量我们在chat2db-server中集成了简易 A/B 测试模块测试维度通用模型qwen2:7b微调模型qwen2-logistics-lora提升幅度字段存在性68%99%31%JOIN 条件完整性71%100%29%时间函数正确率82%97%15%平均响应延迟2.1s2.3s0.2s从那以后我每次给新客户部署 Chat2DB都强制走一遍「收集 50 条历史查询 → 构建 prompt-template → 微调 LoRA」三步流程——哪怕只花 2 小时也能把他们最常写的 5 类模糊查询准确率拉到 95% 以上。这比教他们背字段名、画 ER 图、背 SQL 语法高效得多。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

MySQL索引优化:从B+树原理到慢查询实战

MySQL索引优化:从B+树原理到慢查询实战

做后端开发这几年,最常被拉到群里去救火的场景,十有八九是数据库慢查询。系统跑得好好的,突然某天接口变慢、CPU飙高,一看日志全是SELECT走了全表扫描,几百万行的表一次查询几秒钟才回来。这种时候,十次里有…

2026/10/14 3:05:32 阅读更多 →
RGF_CJ 全局函数全解析:从应用生命周期、系统定时器到窗口与指针互操作

RGF_CJ 全局函数全解析:从应用生命周期、系统定时器到窗口与指针互操作

图形学桌面应用 【免费下载链接】RGF_CJ RGF是仓颉Windows系统下的通用渲染框架(兼应用开发框架)。RGF仓颉版(后续简称"RGF")基于RGF(C/C版)封装优化而来。RGF为开发者提供轻量化、安全、高性能以及高度一致性的2D渲染能…

2026/10/14 3:05:32 阅读更多 →
Python爬虫实战:手机APP数据抓取与解析全流程

Python爬虫实战:手机APP数据抓取与解析全流程

简介:这份PDF资料面向具备Python基础、对网络请求与爬虫开发感兴趣的技术爱好者与研发工程师,围绕手机APP数据传输的抓取与解析展开,重点讲解如何借助Fiddler抓包定位登录与话题接口,再通过urllib2构造HTTP请求、携带Header与表单…

2026/10/14 3:04:31 阅读更多 →

最新新闻

一张图微调YOLOv11:自然栖息地鸟类检测的流程与扩充

一张图微调YOLOv11:自然栖息地鸟类检测的流程与扩充

简介:面向 YOLOv11 模型验证需求,这份精简版鸟类目标检测数据集包含一张真实野外鸟类图像及配套标准标注,可用于快速原型验证、轻量级部署测试与小样本检测基线建立。压缩包共五个文件,包含三张 JPG 图像、一个数据配置文件与一个…

2026/10/14 3:39:38 阅读更多 →
ASP.NET + SQLServer葡萄酒商城源码:从数据库还原到下单事务全攻略

ASP.NET + SQLServer葡萄酒商城源码:从数据库还原到下单事务全攻略

简介:一套基于ASP.NET与SQL Server的葡萄酒网上商城销售系统,面向ASP.NET WebForm学习者、毕业设计学生以及需要搭建在线商城教学演示的开发者。系统围绕普通会员、商户会员和管理员三类角色展开,覆盖商品管理、购物车、订单处理、发货、商户…

2026/10/14 3:39:38 阅读更多 →
LangChain项目代码拆解:Chain、Agent、Memory与Retrieval四大核心组件实战指南

LangChain项目代码拆解:Chain、Agent、Memory与Retrieval四大核心组件实战指南

简介:这是一份LangChain入门与实践的项目代码包,面向正在学习大模型应用开发的Python开发者,旨在帮助读者快速理解LangChain的模块化设计与核心用法。包内共3个文件,包含一个HTML格式的入门讲解页、一个项目运行配置文件以及一个版…

2026/10/14 3:39:38 阅读更多 →
C++学习日记 Day21:C++11(下)lambda表达式和function包装器

C++学习日记 Day21:C++11(下)lambda表达式和function包装器

## 今天学了什么今天学习C11的lambda表达式和function包装器。## 可调用对象概念:在C中有一类对象可像函数一样调用;分类:①函数指针using prt void(*)(int, string); prt f1 fun; f1(1, "函数指针");②仿函数 --有 operator&am…

2026/10/14 3:39:38 阅读更多 →
一人公司AI工作流:6步实现内容生产去体力化

一人公司AI工作流:6步实现内容生产去体力化

1. 一人公司的内容困局与破局思路一个人做内容,最怕的不是没灵感,而是灵感来了却卡在“执行”上。写一篇长文要三小时,做一张配图要半小时,剪一条短视频要一整个下午,排版发布又要来回切换四五个平台。一天下来&#x…

2026/10/14 3:39:38 阅读更多 →
8765平台前后摄DVDD电压不一致排查与修复指南

8765平台前后摄DVDD电压不一致排查与修复指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 3:38:38 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →