Help us shape the future of Go! Take the 2026 Go Developer Survey

dq

package module
v0.6.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 16 Imported by: 0

README

gf-mate — GoFrame v2 全能 AI 陪伴助手 (Copilot & 数据分析)

简体中文 | English

Go Reference CI Release GoFrame Go Version

给任何 GoFrame v2 项目一键注入随行智能伙伴与「自然语言查数 + 数据智能分析」能力。 自带可嵌入任意前端系统的悬浮陪伴小窗组件,AI 自动根据意图与数据形态选择表格/柱状/折线/饼图/指标卡精准呈现。

gf-mate Web Component Preview

极简快速集成:不用手写字段,mate.FromStruct(&entity.X{}) 反射 GoFrame 模型即得数据集; 或者 Mode: "all" 全库自动注册,一行代码都不用写。


目录


特性

能力 说明
零手写字段 反射 GoFrame entity(orm/json tag)自动生成字段定义,dq tag 可选补语义
两种注册模式 whitelist(显式注册,默认,最安全)或 all(全库自动注册,零代码)
AI 自然语言查询 OpenAI 兼容协议(base_url + api_key + model),无厂商锁定
AI 写 SQL AI 直接写只读 SQL(批量提交,一次多条),JOIN/窗口函数/CTE/UNION 任意复杂度
AI 自动选渲染 根据数据形状自动输出表格/柱状/折线/饼图/指标卡,无需用户手动选
默认深度思考 思考模式默认开启(reasoning_content 流式输出),可配置关闭/调强度
安全铁律 五道只读门禁:单语句 / SELECT-WITH 开头 / 写关键字黑名单 / 表白名单 / 强制 LIMIT + 超时
可嵌入前端 单文件 Web Component <dq-assistant>,一行 <script> 嵌入 React/Vue/原生
SSE 流式 标准 OpenAI chat.completion.chunk,工具调用过程在答案区可见
多数据库 MySQL / DM8(达梦)开箱即用,方言层可扩展

快速开始(5 分钟)

1. 引入依赖
go get github.com/strugglerx/gf-mate
2. 初始化 + 注册数据集
package main

import (
    "context"
    "os"

    "github.com/gogf/gf/v2/frame/g"
    "github.com/gogf/gf/v2/net/ghttp"

    mate "github.com/strugglerx/gf-mate"
)

func main() {
    ctx := context.Background()

    // 1. 初始化(复用宿主 g.DB(),支持 DM8/MySQL/PgSQL/SQLite)
    mate.Init(g.DB(), &mate.Config{
        Assistant: mate.AssistantConfig{
            Enabled: os.Getenv("DQ_LLM_KEY") != "",
            BaseURL: "https://api.deepseek.com/v1", // 任意 OpenAI 兼容端点
            APIKey:  os.Getenv("DQ_LLM_KEY"),
            Model:   "deepseek-chat",
        },
    })

    // 2. 注册业务模型(FromStruct 自动反射字段,零手写 schema)
    ds, _ := mate.FromStruct(&entity.Project{})
    mate.Register(*ds)

    // 3. 挂载路由(/mate 下自动提供 SSE 问答 API 与嵌入式前端小窗)
    s := g.Server()
    s.Group("/mate", func(group *ghttp.RouterGroup) {
        mate.Bind(ctx, group, s)
    })
    s.Run()
}
3. 嵌入前端(任意 HTML / React / Vue 页面)
<script src="/mate/dist/dq-widget.js" data-dq-base="/mate"></script>

页面右下角出现悬浮气泡,点开即 AI 问答面板。详见嵌入前端。


注册数据集(三种方式)

方式一:反射 GoFrame entity(推荐,零手写字段)

mate.FromStruct(&entity.X{}) 从 ORM 模型反射字段,一张表一个调用,循环即可注册任意多张:

// 注册多张表:循环 FromStruct
for _, e := range []interface{}{
    &entity.MiniappProject{},
    &entity.MiniappInspection{},
    &entity.MiniappContractor{},
    &entity.MiniappBuilding{},
} {
    ds, _ := mate.FromStruct(e)
    mate.Register(*ds)
}

反射规则:

来源 规则
orm:"col" tag 取真实列名;无则字段名转 snake_case
Go 类型 string→string、数值→number、时间→datetime
角色推断 数值字段→measure(count/sum/avg/max/min)、其余→dimension
dq:"label=,role=,type=,agg=,enum=,desc=" 覆盖默认推断
dq:"-" 跳过该字段
自动跳过 *_json 列、DeletedAt 软删字段

给 AI 补语义(可选但推荐):反射结果是英文/占位标签,用 dq tag 补中文与枚举,AI 才能问得准:

type OrderSemantic struct {
    Id       string  `orm:"id"        dq:"label=订单ID,role=measure,agg=count"`
    Status   string  `orm:"status"    dq:"label=订单状态,type=enum,enum=paid:已支付|pending:待付款|cancelled:已取消"`
    Category string  `orm:"category"  dq:"label=商品类目,type=enum,enum=electronics:数码数科|clothing:服饰鞋包"`
    Amount   float64 `orm:"amount"    dq:"label=销售金额,role=measure,agg=sum"`
    // ...
}

ds, _ := mate.FromStruct(&OrderSemantic{}, func(o *mate.FromStructOptions) {
    o.Name = "order"
    o.Table = "biz_order"
    o.Label = "业务订单"
    o.Description = "电商/业务订单主表。status:paid=已支付,pending=待付款..."
})
mate.Register(*ds)
方式二:全库自动注册(all 模式,零代码)
mate.Init(g.DB(), &mate.Config{ Mode: "all" })

自动读系统元数据(MySQL 走 INFORMATION_SCHEMA,DM8 走 USER_TABLES), 把当前库所有表一次注册。支持排除表:

mate.Init(g.DB(), &mate.Config{
    Mode:          "all",
    ExcludeTables: []string{"sys_log", "audit_trail"}, // 跳过不想暴露的表
})

⚠️ all 模式暴露全库,仅适合内网/受信环境;生产建议 whitelist。

方式三:手动定义(精细控制)
mate.Register(mate.Dataset{
    Name:  "order",
    Table: "biz_order",
    Label: "业务订单",
    Description: "业务订单明细主表。",
    Fields: []mate.Field{
        {Name: "id", Label: "订单ID", Role: mate.RoleMeasure, Type: "number", Aggs: []string{"count"}},
        {Name: "status", Label: "订单状态", Role: mate.RoleDimension, Type: "enum",
            Enum: []mate.EnumItem{{Value: "paid", Label: "已支付"}, {Value: "pending", Label: "待付款"}}},
        {Name: "category", Label: "商品类目", Role: mate.RoleDimension, Type: "enum"},
    },
})

HTTP API 参考

挂载后(mate.Bind)暴露以下路由:

方法 路径 说明
GET /dq/datasets 列出所有已注册数据集(名称/标签/描述)
GET /dq/datasets/:name/schema 取某数据集的字段元数据
POST /dq/assistant/chat AI 助手对话(SSE 流式)
AI 对话(SSE 流式)
curl -N -X POST http://localhost:8200/dq/assistant/chat \
  -H 'Content-Type: application/json' \
  -d '{"message":"统计一下项目状态分布"}'

返回标准 OpenAI chat.completion.chunk SSE 流:


data: {"choices":[{"delta":{"content":"我来帮您统计..."},"finish_reason":null,"index":0}],...}
data: {"object":"agent.event","x_agent":{"type":"tool_start","name":"get_schema",...}}
data: {"choices":[{"delta":{"content":"\`\`\`render\n{\"type\":\"chart_bar\",...}\n\`\`\`"},"finish_reason":null,"index":0}],...}
data: {"choices":[{"delta":{},"finish_reason":"stop","index":0}],...}
data: [DONE]
  • 思考流:delta.reasoning_content(DeepSeek 标准字段)
  • 工具调用:agent.event 扩展事件(tool_start/tool_end),答案区可见
  • 渲染卡片:LLM 在正文里输出 ```render 围栏包裹的 JSON,前端解析渲染
  • 任何 OpenAI SDK 客户端可直接对接

AI 助手

工作原理
  1. 用户自然语言提问 → 发给 LLM(OpenAI 兼容协议,思考模式默认开启)
  2. LLM 只看到数据集元数据 + 可查表清单(看不到连接信息)
  3. LLM 通过 sql_query 工具批量提交只读 SQL(一次多条,效率高),服务端五道门禁校验后执行
  4. 工具循环在服务端内部消化(maxToolCallsPerTurn 上限)
  5. LLM 根据数据形状自动选择渲染类型,输出 ```render 围栏 JSON
  6. 前端解析渲染为表格/柱状/折线/饼图/指标卡
渲染类型(AI 自动选择)
类型 适用场景
data_table 明细/多列数据
chart_bar 分类对比(如各状态项目数)
chart_line 时间趋势
chart_pie 占比分布
metric_cards 关键指标(总数/均值/最大)
配置
Assistant: mate.AssistantConfig{
    Enabled:             os.Getenv("DQ_LLM_KEY") != "",
    BaseURL:             "https://your-llm/v1",   // OpenAI 兼容端点
    APIKey:              os.Getenv("DQ_LLM_KEY"), // 密钥永远走环境变量
    Model:               "your-model",
    MaxToolCallsPerTurn: 8,    // 单轮最大工具调用次数
    RequestTimeoutSec:   180,  // 单次请求超时
    MaxContextChars:     24000, // 上下文截断上限
    EnableThinking:      nil,   // 思考模式:nil=默认开启;传 false 关闭
    ReasoningEffort:     "",    // 思考强度:low / high / max(空=模型默认)
}
只读 SQL 门禁(核心机制)

AI 的唯一查数通道是 sql_query 工具:批量提交只读 SELECT(单次最多 10 条,逐条独立校验与返回),支持任意复杂查询——多表 JOIN、窗口函数、CTE、子查询、UNION。

RawSQL: mate.RawSQLConfig{
    Enabled:    nil,   // 默认开启(AI 唯一查数通道);显式传 false 关闭
    MaxRows:    500,   // 无顶层 LIMIT 时自动追加
    TimeoutSec: 30,    // 单条 SQL 超时
},

五道安全防线:

  1. 单语句:只允许一条语句(多分号拒绝)
  2. 只读门禁:必须 SELECT/WITH 开头,全文词边界匹配拒绝写关键字(INSERT/UPDATE/DELETE/DROP/GRANT/CALL/SET 等 25+ 个)
  3. 表白名单:FROM/JOIN 引用的表必须全部在已注册数据集的表白名单内(CTE 名豁免)
  4. 行数上限:无顶层 LIMIT 时强制追加 LIMIT maxRows
  5. 超时:单条 SQL 强制超时,防全表扫描拖死数据库

注意:AI 可读白名单表的任意列(无字段级限制),行级权限需通过控制注册哪些表来实现;生产环境建议给插件配一个只读数据库账号,物理层面双保险。


嵌入前端(任意系统)

方式一:<gf-mate> 自定义标签(Web Component,推荐)

无论在原生 HTML、Vue、React 还是 Angular 中,引入 dq-widget.js 后,即可像原生 HTML 标签一样直接声明使用:

<script src="/mate/dist/dq-widget.js"></script>

<!-- 1. 浮动气泡模式(默认悬浮在右下角) -->
<gf-mate 
  base="/mate" 
  title="业务数据智囊" 
  color="#4f46e5">
</gf-mate>

<!-- 2. 页面内嵌模式(Inline,直接作为页面普通块级组件平铺展示) -->
<div style="width: 480px; height: 600px; border-radius: 12px; overflow: hidden;">
  <gf-mate 
    inline 
    base="/mate" 
    title="分析工作台" 
    color="#059669">
  </gf-mate>
</div>

<gf-mate> 属性一览:

属性 类型 说明 示例
base / api string 后端服务基础路径 /mate
title string 自定义助手名称与欢迎语 数据分析专家
color string 自定义主题色(支持 HEX / RGB) #4f46e5 / #059669
inline boolean 内嵌模式:开启后取消悬浮球,直接充满父容器作为页面工作台 <gf-mate inline>
open boolean 页面加载后默认自动展开面板(仅浮动模式有效) <gf-mate open>
examples string 自定义推荐问题(逗号分隔或 JSON 数组) 统计今日订单,查询近7天趋势

方式二:script 标签直接引入(极简零侵入)
<!-- 基础用法:引入即生效,右下角自动生成浮动气泡 -->
<script src="/mate/dist/dq-widget.js" data-dq-base="/mate"></script>

<!-- 自定义标题与品牌主题色 -->
<script src="/mate/dist/dq-widget.js" 
  data-dq-base="/mate" 
  data-dq-title="智慧工程助手" 
  data-dq-color="#059669">
</script>
参数 说明 示例
data-dq-base 后端服务基础路径 /mate
data-dq-title 自定义小窗标题与欢迎语 智慧工程助手(默认:AI 数据助手)
data-dq-color 自定义主题色(支持 HEX / RGB) #059669 / #2563eb
data-dq-open 页面加载后默认展开小窗 data-dq-open

页面右下角出现悬浮气泡,点开即 AI 问答面板。零样式污染:面板内容在 Shadow DOM 中,不影响宿主页面样式。


方式三:JS API(React / Vue / 原生编程式调用)
// React / Vue / 任意框架
import "/mate/dist/dq-widget.js";

// 可传入自定义配置手动挂载
window.DQWidget.mount({
  title: "客服数据大脑",
  color: "#7c3aed"
});

window.DQWidget.open();   // 打开面板
window.DQWidget.close();  // 关闭面板
window.DQWidget.toggle(); // 切换开合
方式四:iframe(完全沙箱隔离)
<iframe src="/mate/widget.html?title=工程助手&color=%23059669" style="position:fixed;right:20px;bottom:20px;width:420px;height:640px;border:none;z-index:9999"></iframe>

方式五:Vue 3 官方推荐高级富渲染组件(@struggler/smart-ai-renderer)

如果您的系统是 Vue 3 体系(如后台管理系统、内嵌 BI 看板),需要将 AI 对话与图表卡片深度无缝嵌入在业务页面内部,推荐直接使用官方配套的高级富渲染 npm 包:

npm install @struggler/smart-ai-renderer
# 或 pnpm add @struggler/smart-ai-renderer

gf-mate 后端输出的 data_table、chart_bar、chart_line、chart_pie、metric_cards 等渲染协议与该组件 100% 原生互通,且自带完整强大的 Naive UI 和 ECharts 富交互能力:

<script setup>
import { ref } from 'vue'
import { ChatMessageRenderer } from '@struggler/smart-ai-renderer'
import '@struggler/smart-ai-renderer/style.css'

const content = ref('')
const streaming = ref(false)

async function queryAI(prompt) {
  streaming.value = true
  const res = await fetch('/mate/assistant/chat', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ message: prompt })
  })
  // 消费标准 OpenAI SSE 流,将 delta.content 追加至 content.value
  // ...
  streaming.value = false
}
</script>

<template>
  <!-- 直接渲染 gf-mate 的图表与 markdown 内容 -->
  <ChatMessageRenderer 
    :content="content" 
    :streaming="streaming" 
    :theme="{ brand: '#4f46e5', radiusMd: '8px' }" 
  />
</template>
跨域

插件内置 CORS 中间件:回显 Origin + Access-Control-Allow-Credentials + OPTIONS 预检。 宿主页面与插件不同源时无需额外配置。


配置参考

mate.Init(g.DB(), &mate.Config{
    Mode:           "whitelist",            // whitelist | all
    ExcludeTables:  []string{"sys_log"},    // all 模式下排除的表
    IncludeSchemas: []string{"public"},     // all 模式下只注册这些 schema(非空时)
    Assistant:      mate.AssistantConfig{ /* 见上 */ },
    Render:         mate.RenderConfig{ EnabledTypes: []string{"data_table","chart_bar","chart_line","chart_pie","metric_cards"} },
})
配置项 默认 说明
Mode whitelist 白名单(显式注册)或 all(全库自动)
ExcludeTables [] all 模式下排除的表名
IncludeSchemas [] all 模式下只注册这些 schema(非空时生效)
CORSOrigins [] 跨域来源白名单。为空时回显任意 Origin 并允许携带 Cookie(仅建议内网/开发环境);生产环境应配置允许的宿主域名,如 ["https://host.example.com"]
RawSQL.Enabled false AI 原生 SQL 模式(只读门禁,见「AI 助手」章)
RawSQL.MaxRows 500 原生 SQL 强制行数上限
RawSQL.TimeoutSec 30 原生 SQL 执行超时
Assistant.Enabled false 是否启用 AI
Assistant.BaseURL — OpenAI 兼容端点
Assistant.APIKey — 密钥,永远从环境变量读取
Assistant.Model — 模型名
Assistant.MaxToolCallsPerTurn 8 单轮最大工具调用次数
Assistant.RequestTimeoutSec 180 单次 LLM 请求超时(长思考/大上下文建议 ≥300)
Assistant.MaxContextChars 24000 上下文截断上限
Assistant.Resolver nil 动态 LLM 端点:每次对话前调用,返回 mate.LLMEndpoint{BaseURL,APIKey,Model};非 nil 即视为启用,优先于静态配置。返回 error 时对话接口 503
Assistant.SystemPromptAppend "" 宿主自定义提示词,拼到内置 system prompt 末尾。用于声明方言语法(如 DM8 的 TO_CHAR/SYSDATE)、业务口径、字段约定,减少模型试错、加快响应
Render.EnabledTypes 全部 5 种 允许的渲染类型
宿主集成要点(v0.5.0+)

动态凭据(后台配置中心):宿主有自己的配置中心时用 Resolver,改配置无需重启:

Assistant: mate.AssistantConfig{
    Resolver: func(ctx context.Context) (mate.LLMEndpoint, error) {
        // 从宿主配置中心读取;BaseURL 可为根路径或完整的 .../chat/completions
        return mate.LLMEndpoint{BaseURL: url, APIKey: key, Model: model}, nil
    },
},

敏感列:手机号、证件号等列用 DenyColumns 声明,SQL 门禁拒绝任何提及这些列的语句,并拒绝对该表 SELECT * / alias.*:

ds, _ := mate.FromStruct(&entity.Project{}, func(o *mate.FromStructOptions) {
    o.DenyColumns = []string{"client_phone", "id_card_no"}
})

Bearer Token 鉴权:mate.Bind 挂到宿主鉴权分组,脚本用 mate.BindWidget 挂到公开分组(<script> 带不了请求头,脚本已 go:embed 进二进制):

s.Group("/api/admin/mate", func(g *ghttp.RouterGroup) { mate.BindWidget(g) })                  // 公开:/dist/dq-widget.js
s.Group("/api/admin/mate", func(g *ghttp.RouterGroup) { g.Middleware(auth); mate.Bind(ctx, g) }) // 鉴权

自定义提示词:宿主库有方言或业务口径时,用 SystemPromptAppend 一次性告知,避免模型反复试错:

Assistant: mate.AssistantConfig{
    SystemPromptAppend: "数据库为达梦 DM8:按天分组用 TO_CHAR(col,'YYYY-MM-DD')," +
        "近 N 天过滤用 col >= SYSDATE - N;created_at 为记录创建时间。",
},

浮动面板可缩放:浮动气泡模式下,面板左上角有拖拽手柄,可自由调整宽高(受最小 320×360 约束)。

前端给 <gf-mate> 的 headers 属性传对象或函数,每次请求前求值(Token 续期后自动生效):

const el = document.createElement("gf-mate")
el.setAttribute("base", "/api/admin/mate")
el.headers = () => ({ Authorization: `Bearer ${getToken()}` })
document.body.appendChild(el)

完整示例

示例 说明
examples/server 单表演示:Playground + widget 完整界面
examples/rebuild-integration miniapp-rebuild 集成:-all 全库自动注册,或 FromStruct 反射注册
cd examples/rebuild-integration

# 方式一:FromStruct 反射注册演示表
export DQ_LLM_KEY='your-key'   # 不设置则 AI 关闭,仅查询
go run .

# 方式二:全库自动注册(120 张表)
go run . -all

# 打开 http://localhost:8200/dq/

安全设计

  1. 只读门禁(五道防线):单语句 / SELECT-WITH 开头 + 写关键字黑名单(词边界匹配)/ 表白名单 / 强制 LIMIT / 超时,AI 提交的每条 SQL 逐一校验。
  2. 表级控制:whitelist 模式只开放显式注册的表;all 模式可用 ExcludeTables 排除敏感表——这是行级/字段级控制的主要手段。
  3. AI 隔离:AI 只接触数据集元数据 + 可查表清单,看不到连接串。
  4. 密钥管理:密钥仅从环境变量 DQ_LLM_KEY 读取,代码/配置/文档中永不出现。
  5. 只读账号建议:生产环境给插件配只读数据库账号,物理层面双保险。

常见问题 FAQ

Q: 能注册多张表吗? A: 能。mate.Register 一次注册一个数据集,循环调用即可;FromStruct 一张表一次调用;Mode: "all" 则一次注册全库。

Q: AI 助手需要什么模型? A: 任何 OpenAI 兼容协议模型(DeepSeek、通义、智谱、本地 vLLM 等)。只需 BaseURL + APIKey + Model 三项配置。

Q: 不配 LLM key 能用吗? A: AI 是核心功能,不配 key 时助手关闭,插件只剩数据集注册与 schema 查询接口。

Q: 支持哪些数据库? A: MySQL、DM8(达梦)开箱即用;AI 写标准 SQL,其他库只要 gdb 驱动可用即可。

Q: 前端能嵌入 Vue/React 吗? A: 能。单文件 Web Component <dq-assistant> 无框架依赖,script 标签或 JS API 均可,Shadow DOM 隔离不污染宿主样式。

Q: AI 会不会写 DELETE/UPDATE 破坏数据? A: 不会。五道门禁在执行前拦截:非 SELECT/WITH 开头、含写关键字(词边界)、非白名单表、多语句全部拒绝,且强制超时。建议再配只读数据库账号双保险。

Q: 如何限制 AI 能查的数据范围? A: 控制注册哪些表(whitelist 模式显式注册 / all 模式 ExcludeTables 排除敏感表)。未注册的表 AI 完全不可见、不可查。

Q: 查询很慢怎么办? A: 调低 RawSQL.MaxRows/TimeoutSec;为常用过滤/分组字段建索引;all 模式全库注册在表多时启动较慢(有进度日志)。


License

MIT

Documentation

Overview

Package dq 是 gf-mate 插件的对外门面。

使用方式(嵌入 GoFrame 宿主):

dq.Init(g.DB(), nil)                 // 初始化,使用默认配置
dq.Register(model.Dataset{...})      // 注册数据集(白名单模式的唯一入口)
dq.Bind(ctx, group)                  // 挂载路由到宿主 server group

Index

Constants

View Source
const (
	RoleDimension = model.RoleDimension
	RoleMeasure   = model.RoleMeasure
)

RoleDimension / RoleMeasure 字段角色。

View Source
const (
	// DefaultMode 默认白名单模式:只开放显式 Register 的数据集。
	DefaultMode = "whitelist"
)

默认配置常量。

Variables

This section is empty.

Functions

func AddSource added in v0.4.0

func AddSource(name string, db gdb.DB) error

AddSource 注册命名数据源(多数据库支持)。 例如宿主配置了两个库:dq.AddSource("go", g.DB("go")), 之后 Register 的数据集声明 Source: "go" 即自动路由到该库。 必须在 Init 之后调用;重复注册同名源返回错误。

func Bind

func Bind(ctx context.Context, group *ghttp.RouterGroup, server ...*ghttp.Server) error

Bind 挂载路由到宿主 server group,prefix 如 "/dq"。

鉴权说明:插件不负责鉴权,路由直接挂到传入的 group; 宿主应自行在 group 上挂中间件(如 g.Middleware.CORS、登录鉴权), 插件只提供数据能力,不做任何权限判断。

静态资源:可选传入 server(如 g.Server())用于把 frontend/ 目录 挂到 group 前缀下(AddStaticPath)。不传 server 时跳过静态资源挂载。 注意:ghttp 的静态文件优先级高于动态路由,因此 /dq/ 会命中静态首页。

func BindWidget added in v0.5.0

func BindWidget(group *ghttp.RouterGroup) error

BindWidget 把内嵌的 widget 脚本挂到 group 下的 /dist/dq-widget.js。

与 Bind 分开挂载:<script> 标签加载脚本时带不了 Authorization 头,宿主通常把 脚本挂到不鉴权的分组,对话与数据集接口仍由 Bind 挂到鉴权分组。脚本本身不含 任何数据与配置,公开访问不泄露业务信息。

func Engine

func Engine() (*queryengine.Engine, error)

Engine 返回内部查询引擎(供测试与高级用法)。

func FromStruct

func FromStruct(s interface{}, opts ...func(*FromStructOptions)) (*model.Dataset, error)

FromStruct 从 GoFrame entity(ORM struct)反射生成 Dataset 草稿,零手写字段。

小白快速集成:把 model 指针传入即得字段定义,无需手写 Fields 列表。 反射规则见 model.FromStruct 文档:

  • orm tag 取真实列名;无 orm tag 用字段名 snake_case。
  • Go 类型映射 Field.Type(string→string、数值→number、时间→datetime)。
  • 数值字段默认 measure(count/sum/avg/max/min),其余 dimension。
  • dq tag 覆盖语义:dq:"label=状态,role=dimension,type=enum,enum=paid:已支付"。
  • dq:"-" 跳过字段;默认跳过 *_json 与 DeletedAt。

返回的 Dataset 仅含元数据,未注册;调用 Register 注册。

func Init

func Init(db gdb.DB, cfg *Config) error

Init 初始化插件。db 传宿主的 g.DB() 或 g.DB("name");cfg 可为 nil 用默认值。 重复调用返回错误(幂等保护)。 当 cfg.Mode == "all" 时,初始化后自动执行全库表注册(见 SetMode)。

func Inspect

func Inspect(ctx context.Context, table string) (*model.Dataset, error)

Inspect 读表结构生成 Dataset 草稿(人再补 Label/Role/Enum)。 表名会先过白名单校验,再作为参数绑定进元数据查询(只读系统视图)。

func InspectAndRegister

func InspectAndRegister(ctx context.Context, table string) error

InspectAndRegister 读表结构生成 Dataset 草稿并直接注册(all 模式的核心动作)。

func Register

func Register(ds model.Dataset) error

Register 注册数据集(白名单模式的唯一入口)。 多数据源场景:ds.Source 填逻辑源名(对应 AddSource 注册的名称),空 = 默认源。 必须在 Init 之后调用。

func SetMode

func SetMode(mode string) error

SetMode 热切换 whitelist/all。

all:查 INFORMATION_SCHEMA.TABLES(DM8 用 ALL_TABLES)列出当前库所有表,
    跳过 cfg.ExcludeTables、只取 cfg.IncludeSchemas(非空时),逐个 InspectAndRegister。
whitelist:清空 registry,由宿主重新 Register(插件不保留任何自动注册的数据集)。

func WidgetJS added in v0.5.0

func WidgetJS() []byte

WidgetJS 返回内嵌的 dq-widget.js 内容(宿主需要自行托管脚本时使用)。

Types

type AssistantConfig

type AssistantConfig struct {
	Enabled             bool   `json:"enabled"`
	BaseURL             string `json:"baseUrl"`
	APIKey              string `json:"apiKey"`
	Model               string `json:"model"`
	MaxToolCallsPerTurn int    `json:"maxToolCallsPerTurn"`
	RequestTimeoutSec   int    `json:"requestTimeoutSec"`
	MaxContextChars     int    `json:"maxContextChars"`
	EnableThinking      *bool  `json:"enableThinking,omitempty"`  // 是否开启深度思考(默认开启)
	ReasoningEffort     string `json:"reasoningEffort,omitempty"` // 思考强度:low / high / max

	// SystemPromptAppend 宿主自定义提示词,拼到内置 system prompt 末尾。
	// 用于声明方言语法、业务口径、字段约定等,减少模型试错、提升响应速度。
	SystemPromptAppend string `json:"systemPromptAppend,omitempty"`

	// Resolver 每次对话前动态解析 LLM 端点(宿主从后台配置中心读取凭据时使用,
	// 改配置无需重启)。非 nil 时视为已启用,并优先于 BaseURL/APIKey/Model 静态配置;
	// 返回 error 时对话接口返回 503,错误文案原样透出(宿主应保证文案不含密钥)。
	Resolver func(ctx context.Context) (LLMEndpoint, error) `json:"-"`
}

AssistantConfig AI 助手配置。

type Config

type Config struct {
	Mode           string   `json:"mode"` // whitelist|all
	ExcludeTables  []string `json:"excludeTables"`
	IncludeSchemas []string `json:"includeSchemas"`
	// CORSOrigins 跨域来源白名单。非空时只回显列表内的 Origin;
	// 为空(默认)回显任意 Origin 并允许携带 Cookie——仅建议内网/开发环境使用。
	CORSOrigins []string        `json:"corsOrigins"`
	RawSQL      RawSQLConfig    `json:"rawSql"` // 原生 SQL 模式(默认开启,AI 唯一查数通道)
	Assistant   AssistantConfig `json:"assistant"`
	Render      RenderConfig    `json:"render"`
}

Config 插件配置。

func DefaultConfig

func DefaultConfig() *Config

DefaultConfig 返回默认配置。

type Dataset

type Dataset = model.Dataset

Dataset 数据集元数据(白名单来源)。

type EnumItem

type EnumItem = model.EnumItem

EnumItem 枚举取值项。

type Field

type Field = model.Field

Field 字段元数据。

type FromStructOptions

type FromStructOptions = model.FromStructOptions

FromStructOptions 反射选项,见 model.FromStructOptions。

type LLMEndpoint added in v0.5.0

type LLMEndpoint struct {
	BaseURL string
	APIKey  string
	Model   string
}

LLMEndpoint 动态解析出的 OpenAI 兼容端点。 BaseURL 可以是根路径(如 https://api.deepseek.com/v1,自动拼 /chat/completions), 也可以是以 /chat/completions 结尾的完整地址(原样使用)。

type RawSQLConfig

type RawSQLConfig struct {
	Enabled    *bool `json:"enabled,omitempty"` // nil = 默认开启;显式 false 才关闭
	MaxRows    int   `json:"maxRows"`           // 强制行数上限,默认 500
	TimeoutSec int   `json:"timeoutSec"`        // 单条 SQL 超时(秒),默认 30
}

RawSQLConfig 原生 SQL 模式配置(AI 写 SQL、只读门禁,默认开启——这是 AI 的唯一查数通道)。 开启后 AI 助手可通过 sql_query 工具提交任意复杂度的只读 SELECT (JOIN/窗口函数/CTE/子查询均可),过五道安全防线后执行。 注意:此模式绕过 RowScope 行级权限与字段白名单,仅建议可信内网环境开启。

type RenderConfig

type RenderConfig struct {
	EnabledTypes []string `json:"enabledTypes"`
}

RenderConfig 渲染模板配置。

Directories

Path Synopsis
examples
server command
gf-mate 演示宿主(demo host)。
gf-mate 演示宿主(demo host)。
internal
controller
Package controller 提供 gf-mate 插件的 HTTP API 层。
Package controller 提供 gf-mate 插件的 HTTP API 层。
logic/assistant
Package assistant AI 助手:LLM 工具调用循环 → 查询引擎 → 组织回答。
Package assistant AI 助手:LLM 工具调用循环 → 查询引擎 → 组织回答。
logic/queryengine
sqlguard.go AI 原生 SQL 门禁:只读校验。
sqlguard.go AI 原生 SQL 门禁:只读校验。
logic/registry
Package registry 数据集注册表:内存存储 + 读写锁,白名单模式的唯一入口。
Package registry 数据集注册表:内存存储 + 读写锁,白名单模式的唯一入口。
model
Package model 定义数据查询插件的数据模型:数据集元数据(表白名单 + schema 来源)与查询结果。
Package model 定义数据查询插件的数据模型:数据集元数据(表白名单 + schema 来源)与查询结果。
render
Package render 定义 AI 助手渲染协议:5 种渲染模板的 JSON 结构常量与校验。
Package render 定义 AI 助手渲染协议:5 种渲染模板的 JSON 结构常量与校验。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL