mcpField
J
jeecg-onlreport

jeecg-onlreport

github.com/jeecgbootデータ・データベース24444 回インストール2 週間前に更新
リポジトリ

jeecg-onlreport について

SQL や自然言語の要件から JeecgBoot Online レポートを作成・照会・編集するスキルです。フィールドとパラメーターの設定を支援し、API 変更の前に内容の提示と確認を求めます。

主な機能

  1. 01レポート一覧と設定の確認
  2. 02SQL や要件からのレポート作成
  3. 03フィールド、パラメーター、SQL の編集
  4. 04SQL の解析による項目とパラメーターの抽出
  5. 05フィールド名に基づく設定の推定

活用シーン

  1. 01既存レポートの項目とパラメーターの確認
  2. 02読み取り専用 SQL レポートの作成
  3. 03レポート項目やクエリの調整

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jeecgboot/skills --skill jeecg-onlreport

インストール後、Claude Code で/jeecg-onlreportを入力して読み込まれたか確認します。

同梱ファイルreferences/api_schema.mdscripts/onlreport_api.py

詳細

JeecgBoot Online レポート AI 自動生成ツール

自然言語で記述されたレポート要件を Online レポート設定に変換し、API を通じて自動的に作成/編集/照会します。

重要:このスキルは「Online レポート」(SQL 駆動の読み取り専用データレポート)を扱います。Online フォーム(cgform)やデザイナーフォーム(desform)は対象外です。

主な機能

操作説明
レポートの照会システム内のすべての Online レポートを一覧表示し、フィールドとパラメーターの設定を確認します
レポートの新規作成自然言語の要件または SQL からレポートを作成します
レポートの編集既存レポートのフィールド、パラメーター、SQL を変更します

Step 0: 認証情報の収集

操作のたびに、以下の情報を収集する必要があります(ユーザーがすでに提示している場合は省略します)。

  1. API アドレス — JeecgBoot バックエンドのアドレス。例:https://boot3.jeecg.com/jeecgboot
  2. X-Access-Token — JWT トークン。ブラウザーの F12 → Network → 任意のリクエストの Request Headers からコピーします

ユーザーが提示していない場合は、次のように案内します。

JeecgBoot バックエンドのアドレスと X-Access-Token を提示してください。


Step 1: 操作タイプの判定

ユーザーの意図に基づいて操作タイプを判定します。

ユーザーの意図を示すキーワード操作
レポートを一覧表示 / レポートを照会 / すべてのレポートを表示 / どんなレポートがあるかレポートの照会 → Step 2
作成 / 新規作成 / 作って / レポートを生成レポートの新規作成 → Step 3
変更 / 編集 / フィールドを変更 / フィールドを追加 / フィールドを削除レポートの編集 → Step 4

⚠️ メニューへの追加とロールへの権限付与は任意の操作であり、デフォルトで実行してはいけません。

  • ユーザーが「レポートを作成」とだけ指定した場合は、create_report + validate_report のみを実行します。メニューへの追加やロールへの権限付与は行いません
  • ユーザーが「メニューに追加」「メニューを紐付ける」「xxx ロールに権限を付与」などのキーワードを明示した場合に限り、publish_report または create_and_publish を呼び出します
  • このルールに違反すると、ユーザーの意図を超えた操作や、不要なメニュー記録の作成が発生します。また、権限リスト全体を取得するため、処理時間が大幅に増加します

Step 2: レポートの照会

API の初期化(共通エントリーポイント):すべての Python 操作の前に、desform_utils と同様に init_api を呼び出す必要があります。

import sys
sys.path.insert(0, r'<skill目录>/scripts')
from onlreport_api import init_api
init_api('<api_base>', '<token>')

後から必要に応じてインポートします:list_all_reports_table, list_fields_by_code_table, list_reports, query_report, list_fields, list_params, parse_sql, create_report, edit_report, gen_id, create_menu, get_role_id_by_code, grant_menu_to_role, add_data_rule, query_data_rules

2.1 クイック一覧(シンタックスシュガー)

推奨する方法です。list_all_reports_table() を呼び出すと、ページネーションで自動的に全レポートを巡回し、名前/コード/SQL を表形式で一括取得します。

from onlreport_api import init_api, list_all_reports_table
init_api('<api_base>', '<token>')
list_all_reports_table()

Markdown テーブルが返されます。フィールドは 3 つ(レポート名、レポートコード、レポート SQL)のみで、AI がそのまま使用できます。

| 报表名称 | 报表编码 | 报表 SQL |
|----------|----------|----------|
| 关联报表查询 | fz_sql | SELECT u.id, u.username ... |
| ... | ... | ... |

または CLI を使用します。

python "<skill目录>/scripts/onlreport_api.py" \
    --api-base <URL> --token <TOKEN> -a list-table
2.2 コードでフィールドを検索(シンタックスシュガー)

推奨する方法です。list_fields_by_code_table(code) を呼び出すと、レポートコードからフィールドを直接検索できます。

from onlreport_api import init_api, list_fields_by_code_table
init_api('<api_base>', '<token>')
list_fields_by_code_table('fz_sql')

Markdown テーブルが返されます。フィールドは 3 つ(フィールドコード、フィールドテキスト、フィールドタイプ)のみで、ページネーションも自動的に行われます。

| 字段编码 | 字段文本(显示名) | 字段类型 |
|----------|-----------------|----------|
| id | ID | String |
| username | username | String |
| realname | realname | String |

または CLI を使用します。

python "<skill目录>/scripts/onlreport_api.py" \
    --api-base <URL> --token <TOKEN> -a fields-table --code fz_sql

基盤となる API:GET /online/cgreport/item/listByHeadCode?headCode={code}

2.3 レポート詳細の照会

ユーザーがレポート ID またはコードを指定した後、順番に照会します。

GET /online/cgreport/head/queryById?id={headId}        # 报表头配置
GET /online/cgreport/item/listByHeadId?headId={headId}  # 字段列表
GET /online/cgreport/param/listByHeadId?headId={headId}  # 参数列表

ユーザーが参考にできるよう、設定全体を表示し、変更が必要かどうかを尋ねます。


Step 3: レポートの新規作成

3.1 要件の収集

ユーザーの説明から以下を抽出します。

情報入手元例
レポートコード (code)自動的に snake_case 形式で生成sales_report
レポート名 (name)ユーザーが指定「売上集計レポート」
SQL 文 (cgrSql)ユーザーが SQL を提示、または要件を説明SELECT ... FROM ...
データソース (dbSource)ユーザーが指定。空の場合はデフォルトsecond_db

作成前に、レポートコードが一意であることを必ず確認します。check_code_available(code) を呼び出すか、次のインターフェースを直接呼び出します。

GET /sys/duplicate/check?tableName=onl_cgreport_head&fieldName=code&fieldVal={code}

success: true はコードが使用可能であることを示し、false はすでに使用されていることを示します。その場合は別のコードを使用します。create_report() の内部では、このチェックが自動的に実行されます。

SQL の入手方法は 2 通りあります。

  1. ユーザーが SQL を直接提示する → そのまま使用します
  2. ユーザーが要件を説明する → テーブル名とフィールドをユーザーに確認する必要があります(parseSql を呼び出して検証します)
3.2 parseSql を呼び出してフィールドを解析

フィールドとパラメーターの一覧を取得するため、まず parseSql を呼び出す必要があります。

GET /online/cgreport/head/parseSql?sql={urlEncodedSql}&dbKey={dbKey}

返される構造には、フィールド一覧 fields[] とパラメーター一覧 params[] が含まれます。

parseSql を先に呼び出す必要があるのはなぜですか? SQL 内の ${paramName} はパラメーター一覧として解析され、フィールド一覧は後続の items 設定を構成するための基準になるためです。

parseSql が失敗した場合の対処

SQL に複雑な関数(例:name like concat('%','${username}','%'))が含まれていると、解析に失敗することがあります。対処方法は次のとおりです。

  1. まず問題の条件を取り除き、簡略化した SQL で解析します
  2. 解析に成功した後、SQL パラメータータブでパラメーター名(例:${username} に対応する username)を手動で追加します
  3. 最終保存時には、cgrSql に元の完全な SQL を使用します
3.3 フィールド設定の自動化

フィールド名の意味に基づいて、各フィールドの設定を自動的に推定します。

フィールド共通属性

searchMode の説明:有効な値は single(単一値検索)と group(範囲検索)の2つだけです。String 型の single 検索は、バックエンドで自動的に LIKE によるあいまい検索が実行されます。Date/Datetime 型では group を使用して範囲選択を実現します。辞書が設定されている場合、ドロップダウン選択が自動的に有効になります。

フィールド名のパターンfieldTxt(中国語名)fieldTypeisShowisSearchsearchModeisOrderisTotal
id / 主キーIDString0(非表示)null-null-
name / title名称/タイトルString11singlenull-
code / noコード/番号String11singlenull-
statusステータスString11singlenull-
type / category種類/分類String11singlenull-
amount / money / price / fee金額/費用/価格BigDecimal1null-1"1"
count / qty / num / number数量Integer1null-1"1"
date / sale_date日付Date11group1-
time / datetime時刻Datetime11group1-
create_by / update_by作成者/更新者String0(非表示)null-null-
create_time / update_time作成日時/更新日時Datetime1null-1-
sex性別String11singlenull-
age年齢Integer1null-null-
emailメールアドレスString1null-null-
phone / mobile / tel電話番号/携帯電話番号String1null-null-
address住所String1null-null-
remark / description / content備考/説明String1null-null-
dept / org部門/組織String11singlenull-
sys_org_code / tenant_idシステムフィールドString0(非表示)null-null-
画像/添付ファイルフィールド画像Image1null-null-

parseSql が返す fieldType は通常 String です。AI はフィールド名の意味に基づいて、正しい型(Date/Datetime/BigDecimal/Integer/Long/Image など)に修正する必要があります。

isOrder/isSearch が null の場合は「いいえ」を意味します。0 は使用しないでください。フロントエンドの表示に影響する可能性があります。

辞書設定(dictCode)

通常の辞書(辞書 code を入力):

  • よく使われるシステム辞書:sex、priority、valid_status、urgent_level、yn

SQL 辞書(別のテーブルを検索):形式は SELECT id 'value', name 'text' FROM table_name に固定されており、フィールドの別名は value と text でなければなりません:

SELECT username AS value, realname AS text FROM sys_user

replaceVal の形式(エクスポート時のテキスト置換):表示テキスト_データベース値 をカンマで区切ります。例:男_1,女_2

グループヘッダー(groupTitle)

同じグループに属する複数のフィールドに同じ groupTitle を設定すると、複数段のヘッダーを実現できます:

{"fieldName": "q1_amount", "groupTitle": "第一季度"}
{"fieldName": "q1_count",  "groupTitle": "第一季度"}
フィールドリンク(fieldHref)

次の構文に対応しています:

用途例
メニューパスへの遷移/system/user または /system/user?sex=1
Vue コンポーネントへの遷移/jeecg/helloworld.vue?id=${id}
外部リンクへの遷移http://jeecg.com?id=${id}
動的パラメーター(現在の行のフィールド値)http://jeecg.com?sex=${sex}
JS 式(二重波括弧)/account/center?name=${name}&age={{${age} + 100}}
現在ログイン中のユーザーの Token を取得http://api.example.com?token={{ACCESS_TOKEN}}

Step 4: レポートを編集する

4.1 既存の設定を照会する
  1. ユーザーからレポート ID またはコードを受け取ります
  2. queryById、listByHeadId(フィールド)、listByHeadId(パラメーター)を順に呼び出します
  3. 既存の設定を表示します
4.2 変更内容を確認する

ユーザーの要望に基づいて、次の内容を確認します:

  • 変更が必要なフィールド(isShow/isSearch/orderNum など)
  • 追加または削除が必要なフィールド
  • SQL の調整が必要かどうか
4.3 editAll リクエストを構築する

editAll は PUT メソッドを使用します(POST ではありません)。

新規作成と同様ですが、次の点に注意してください:

  • head.id = 既存のレポート ID(必須)
  • deleteItemIds = 削除するフィールド ID をカンマで連結したもの
  • deleteParamIds = 削除するパラメーター ID をカンマで連結したもの
パラメーターを置き換える完全な手順

編集時にパラメーターを置き換える必要がある場合(パラメーターなしからありに変更する場合や、パラメーター設定を変更する場合など)は、次の手順で行います:

  1. 古いパラメーター一覧を照会し、すべての古いパラメーター ID を収集します
  2. 新しいパラメーターオブジェクトには id(gen_id() で生成)と headId(レポート ID)を含める必要があります
  3. payload に deleteParamIds を設定して古いパラメーターを削除し、params に新しいパラメーターを渡します
old_params = api_request(f'/online/cgreport/param/listByHeadId?headId={head_id}')['result']
delete_param_ids = ','.join(p['id'] for p in old_params) if old_params else None

new_params = [
    {"id": gen_id(), "headId": head_id, "paramName": "log_type", "paramTxt": "日志类型", "paramValue": "1", "orderNum": 1}
]

payload = {
    "head": {...},
    "items": items,
    "params": new_params,
    "deleteParamIds": delete_param_ids   # 有旧参数时必传,否则会重复
}

注意:editAll の params 内の各レコードには id と headId が必要です。そうでない場合、保存後にパラメーターが有効になりません。新規作成時(create_report)の params には、これら2つのフィールドを含めなくてもかまいません。


Step 5: 概要を表示して確認する

API の実行前に、以下の概要を必ず表示し、ユーザーの確認を待ってください:

## Online 报表配置摘要

- 报表编码:sales_report
- 报表名称:销售统计报表
- 数据源:默认
- 目标环境:https://boot3.jeecg.com/jeecgboot

### SQL 语句
SELECT s.id, s.name, s.amount, s.sale_date, s.status
FROM biz_sales s WHERE 1=1

### 字段配置

| 序号 | 字段名 | 显示名称 | 类型 | 显示 | 查询 | 排序 | 合计 |
|------|--------|---------|------|------|------|------|------|
| 0 | id | ID | String | 否 | 否 | 否 | - |
| 1 | name | 名称 | String | 是 | 单值 | 否 | - |
| 2 | amount | 金额 | BigDecimal | 是 | 否 | 是 | 是 |
| 3 | sale_date | 销售日期 | Date | 是 | 范围 | 是 | - |
| 4 | status | 状态 | String | 是 | 单值 | 否 | - |

### 参数
| 参数名 | 显示名称 | 默认值 |
|--------|---------|--------|
| (无) | | |

确认以上配置?(y/n)

Step 6: API を呼び出す

ユーザーの確認後に実行します。Python を使用して API を呼び出します(Windows 環境では curl で日本語を扱うとエラーになります):

Windows 执行环境(强制规则,违反会让用户吐槽"执行太慢")

现象:Windows 的 Bash tool 会把 python / python -c / skill 脚本当作长命令自动 run_in_background,tool 立即返回 background ID,真正输出要等完成通知——把毫秒级调用放大到数秒。

规则:

  • Windows(platform=win32) → 用 Bash tool 调用 powershell -Command "python xxx.py",同步返回。
  • Linux / macOS → 用 Bash tool 直接调用 python xxx.py。
  • 任何平台都不用 curl:跨平台不一致,Windows Bash 下同样被后台化。

脚本执行前强制检查(3 项,缺一不可):

  1. ✅ Windows 下用 powershell -Command "python xxx.py",不是直接 python xxx.py
  2. ✅ 脚本已写入 .py 文件(禁止 python -c 内联代码)
  3. ✅ 脚本第一行已加编码声明:import sys; sys.stdout.reconfigure(encoding='utf-8')(防 GBK 崩溃重试)

Windows 正确示例:

Bash: powershell -Command "python <skill_base_dir>/scripts/onlreport_api.py --api-base ... --token ..."

<skill_base_dir> 是本 SKILL.md 所在目录,运行时用实际路径替换。

Windows 错误示例(会被后台化,用户立即感知到"卡"):

Bash: python onlreport_api.py ...     ← 返回 "Command running in background with ID: xxx"
Bash: python -c "..."                  ← 同上
Bash: curl -X POST ...                 ← 同上

调用方式:import onlreport_api,调用 init_api 初始化后直接使用封装函数,无需修改脚本文件。

import sys
sys.path.insert(0, r'<skill目录>/scripts')
from onlreport_api import init_api, parse_sql, create_report, gen_id
init_api('<api_base>', '<token>')

脚本中封装了以下操作:

查询类

  • list_reports() — 查询报表列表
  • list_all_reports_table() — 查询所有报表(Markdown 表格,自动分页)
  • list_fields_by_code_table(code) — 按编码查字段(Markdown 表格)
  • query_report(head_id) — 查询报表头
  • list_fields(head_id) — 查询字段列表
  • list_params(head_id) — 查询参数列表
  • get_report_id_by_code(code) — 按编码获取报表 ID
  • parse_sql(sql, db_key) — 解析 SQL 字段

创建 / 编辑

  • create_report(code, name, sql, db_source, items, params) — 创建报表,返回含 head_id 的 dict
  • edit_report(...) — 编辑报表(PUT editAll)

发布流程(高级语法糖,推荐优先使用)

  • validate_report(head_id) — 验证 SQL 是否可执行,返回 True/False
  • publish_report(head_id, name, role_code='admin', parent_id='') — 验证 SQL + 创建菜单 + 授权角色,三步合一
  • create_and_publish(code, name, sql, items, params=[], db_source='', role_code='admin', parent_id='') — 全流程一键完成:创建报表 + 验证 + 建菜单 + 授权

字段构建辅助

  • build_item(field_name, field_txt, ...) — 按字段名语义自动推断类型/查询/显示,支持手动覆盖任意属性

菜单 & 权限

  • create_menu(head_id, name, parent_id='') — 创建报表菜单
  • get_role_id_by_code(role_code) — 按角色编码获取角色 ID
  • grant_menu_to_role(role_id, menu_id) — 追加授权菜单给角色
  • add_data_rule(menu_id, role_id, rule_name, rule_column, rule_conditions, rule_value) — 完整四步数据规则配置

build_item 用法示例(推荐,替代手写 dict)
from onlreport_api import init_api, build_item, create_and_publish
init_api('<api_base>', '<token>')

items = [
    build_item('id',          'ID',       order_num=0),          # 自动隐藏
    build_item('username',    '用户名',   order_num=1),          # 自动单值查询
    build_item('status',      '状态',     order_num=2),          # 自动 dictCode=valid_status
    build_item('amount',      '金额',     order_num=3),          # 自动 BigDecimal + 合计
    build_item('create_time', '创建时间', order_num=4),          # 自动 Datetime + 可排序
    # 手动覆盖
    build_item('email', '邮箱', order_num=5, field_href='mailto:${email}'),
    build_item('sex',   '性别', order_num=6, dict_code='sex'),
]

# 一键:建报表 + 验证 SQL + 建菜单 + 授权 admin
head_id = create_and_publish('my_report', '我的报表', 'SELECT ... FROM ...', items)
build_item 自动推断规则
字段名关键词自动推断结果
id隐藏(isShow=0)
create_by / update_by / sys_org_code / org_code隐藏
avatar / photo / image / pic / imgImage 类型
amount / money / price / fee / costBigDecimal,isTotal='1'
count / qty / num / quantityInteger,isTotal='1'
birthday / *_dateDate,范围查询(group)
*_time / *_datetimeDatetime,可排序
create_time / update_timeDatetime,可排序,不查询
sexdictCode=sex
statusdictCode=valid_status
name / title / code / no单值查询(single)

所有推断值均可通过参数覆盖,例:build_item('status', '状态', dict_code='my_dict')


# 手动构造 items 原始写法(不推荐,优先使用 build_item)
items = [
    {
        "id": gen_id(),         # 雪花 ID,19位数字字符串
        "headId": None,
        "fieldName": "name",
        "fieldTxt": "名称",
        "fieldWidth": None,
        "fieldType": "String",
        "searchMode": "single",  # 单值查询;范围查询用 "group"
        "isOrder": None,         # 不排序用 null,排序用 1
        "isSearch": 1,
        "dictCode": None,
        "fieldHref": None,
        "isShow": 1,
        "orderNum": 1,
        "replaceVal": None,
        "isTotal": None,         # 不合计用 null,合计用 "1"(字符串)
        "groupTitle": None,
        "createBy": None,
        "createTime": None,
        "updateBy": None,
        "updateTime": None
    }
]

关键约束:

  1. Windows 必须用 powershell -Command "python xxx.py",不要用 python xxx.py 或 curl
  2. 写临时 .py 脚本时用 Write 工具,脚本首行加 import sys; sys.stdout.reconfigure(encoding='utf-8'),执行后删除临时文件
  3. 字段 ID 用 gen_id() 生成(雪花格式 19 位数字字符串)
  4. parseSql 返回的 fieldType 全是 String,需根据上表语义修正(或直接用 build_item 自动推断)
  5. isOrder/isSearch 的"否"值为 null,不要用 0
  6. isTotal 的"是"值为字符串 "1",不是数字 1
  7. 合计行仅在表内有数据时才显示;表内无数据时合计行不出现,属正常现象,录入数据后即可看到
  8. 合计只统计数字值;字段含空值/null/非数字内容时会显示"包含非数字内容"提示

Step 7: 验证报表 SQL 可用性

报表创建成功后,必须立即调用以下接口验证 SQL 执行正常,否则报表预览会出现 500 错误:

GET /online/cgreport/api/getColumnsAndData/{headId}
url = f'{base}/online/cgreport/api/getColumnsAndData/{head_id}'
req = urllib.request.Request(url, headers={'X-Access-Token': token})
with urllib.request.urlopen(req, timeout=10) as resp:
    data = json.loads(resp.read())
    if data.get('success'):
        result = data.get('result', {})
        columns = result.get('columns', [])
        rows = result.get('rows', [])
        print(f'验证通过:{len(columns)} 个字段,{len(rows)} 行数据')
    else:
        print('验证失败:', data.get('message'))

常见失败原因及修复:

错误信息原因修复方式
Unknown column 'xxx' in 'field list'SQL 引用了表中不存在的字段(如多租户字段 tenant_id 在非多租户版本中不存在)从 SQL 和字段配置中删除该字段,用 editAll 更新
Table 'xxx' doesn't exist表名错误或数据源配置有误检查 SQL 中的表名和 dbSource
syntax errorSQL 语法错误修正 SQL 语句

验证失败时,用 editAll(PUT)修复 SQL 和字段配置后,再次调用验证,直到返回 success: true。


Step 8: 生成菜单 SQL

报表创建成功后,脚本会自动调用 print_menu_sql(head_id, name) 输出菜单 SQL。

本地环境自动执行规则:如果 API_BASE 以 http://127.0.0.1 或 http://localhost 开头(不区分大小写),自动执行 MySQL 插入菜单:

mysql -h127.0.0.1 -P3306 -uroot -proot jeecgboot3 -e "INSERT INTO sys_permission (...) VALUES (...);"
  • 如果 MySQL 失败,回退为输出 SQL 让用户手动执行
  • 数据库参数默认 mysql -h127.0.0.1 -P3306 -uroot -proot jeecgboot3

菜单配置说明:

  • 前端组件固定为:modules/online/cgreport/auto/OnlCgreportAutoMain
  • 报表访问路径:/online/cgreport/{headId}
  • 也可在「系统管理 → 菜单管理」手工新增菜单,粘贴上述配置地址,「是否是路由菜单」设为否

输出结果模板

## Online 报表操作成功

- 报表编码:{code}
- 报表名称:{name}
- 字段数量:{N} 个
- 参数数量:{M} 个
- 目标环境:{API_BASE}
- 菜单 SQL:{已自动执行 ✓ / 需手动执行}

### 菜单 SQL
INSERT INTO sys_permission (...) VALUES (...);

### 后续操作
1. ✅ 调用 `/online/cgreport/api/getColumnsAndData/{headId}` 验证 SQL 执行正常
2. 打开 JeecgBoot 后台 → Online报表
3. 找到该报表,点击「功能测试」预览效果
4. 如菜单未自动执行,手动执行上方 SQL 或在后台手动添加
5. 可在「编辑」中调整字段显示/查询/排序等配置

SQL 高级特性

参数化查询(Velocity 模板)

在 SQL 中使用 Velocity 模板语法定义参数(parseSql 会自动解析 ${paramName} 为参数列表):

SELECT * FROM biz_sales
WHERE 1=1
${#if($startDate != '')} AND sale_date >= '$startDate' ${#end}
${#if($endDate != '')} AND sale_date <= '$endDate' ${#end}
${#if($status != '')} AND status = '$status' ${#end}

对应的 params 配置(新增时可不带 id/headId,editAll 编辑时必须带):

[
  {"paramName": "startDate", "paramTxt": "开始日期", "paramValue": "", "orderNum": 1},
  {"paramName": "endDate",   "paramTxt": "结束日期", "paramValue": "", "orderNum": 2},
  {"paramName": "status",    "paramTxt": "状态",     "paramValue": "", "orderNum": 3}
]

editAll 编辑时的完整格式(需加 id 和 headId):

{"id": gen_id(), "headId": head_id, "paramName": "status", "paramTxt": "状态", "paramValue": "", "orderNum": 1}

URL 带参访问:获取报表配置地址后,将 ${sex} 替换为实际值访问:

/online/cgreport/{headId}?sex=1
系统变量

在 SQL 中用 #{变量名} 引用当前登录用户信息,实现数据隔离:

SELECT * FROM sys_user WHERE username = '#{sys_user_code}'
变量说明
#{sys_user_code}当前登录用户账号
#{sys_user_name}当前登录用户真实姓名
#{sys_date}当前系统日期
#{sys_time}当前系统时间
#{sys_org_code}当前登录用户部门编号
#{sys_base_path}当前 Java 服务 basePath
排序配置
  • MySQL 及非 SQL Server 数据库:直接在 SQL 中添加 ORDER BY 即可
  • SQL Server 数据库:不允许 SQL 内含 ORDER BY,必须通过 URL 参数传递:
/online/cgreport/{headId}?column=age,name&order=desc
URL 参数说明
column排序字段,多个用逗号分隔
order排序方式:desc(倒序)/ asc(正序)

菜单创建与角色授权

报表创建后,通过 API 完成菜单注册和角色授权的完整流程:

1. 创建菜单
POST /sys/permission/add
{
  "id": "{headId}",
  "name": "报表名称",
  "parentId": "",
  "url": "/online/cgreport/{headId}",
  "component": "modules/online/cgreport/auto/OnlCgreportAutoMain",
  "isRoute": 1,
  "isLeaf": "1",
  "keepAlive": 0,
  "hidden": 0,
  "hideTab": 0,
  "status": "1",
  "menuType": 1,
  "sortNo": 1.0,
  "alwaysShow": 0,
  "internalOrExternal": false,
  "permsType": "0",
  "ruleFlag": 0
}
2. 查找角色 ID
GET /sys/role/list?pageNo=1&pageSize=50

返回 records[],找到目标角色的 id(管理员 roleCode=admin)。

3. 查询角色已有权限
GET /sys/permission/queryRolePermission?roleId={roleId}

返回权限 ID 数组(可能高达千条)。

4. 追加权限并保存
POST /sys/permission/saveRolePermission
Content-Type: application/json
{
  "roleId": "{roleId}",
  "permissionIds": "id1,id2,...,{新菜单headId}",
  "lastPermissionIds": "id1,id2,..."
}

注意:必须用 JSON body(application/json)发送,不支持 form 表单或 URL 参数。权限 ID 列表可能很长(>1000),不能放 URL。


数据权限配置

Online 报表支持通过「数据规则」过滤报表数据,仅展示符合条件的数据。

配置路径:菜单管理 → 找到报表菜单 → 更多 → 数据规则

注意事项:

  • 规则字段不限于报表查询字段,表中任意字段均可使用
  • 字符串参数必须用单引号引起来(例如:'admin'),否则视为数字
  • 支持系统上下文变量,需加单引号(例如:'#{sys_user_code}')
  • 不支持带 ? 参数的菜单配置数据规则;如有需要,单独创建一个不带参数的隐藏菜单用于数据规则配置
通过 API 配置数据规则

前提:角色必须先有该菜单的权限,否则授权数据规则时会报"请先保存角色菜单权限!"。先调用 grant_menu_to_role(role_id, menu_id) 或手动授权菜单。

Step 1:创建规则(默认未启用)

POST /sys/permission/addPermissionRule
{"permissionId":"{menuId}","ruleName":"规则名称","ruleColumn":"sex","ruleConditions":"!=","ruleValue":"'1'"}

⚠️ addPermissionRule 返回的 result 为 null,不含规则 ID! 创建后必须调用以下接口查询刚创建的规则 ID:

GET /sys/permission/queryPermissionRule?permissionId={menuId}

按 ruleName 匹配且 status == null 找到目标规则,取其 id。 add_data_rule() 函数已内置此逻辑,直接调用函数即可。

Step 2:启用规则(status:"1" 才生效,缺少此步规则不生效)

POST /sys/permission/editPermissionRule
{"id":"{ruleId}","permissionId":"{menuId}","ruleName":"规则名称","ruleColumn":"sex","ruleConditions":"!=","ruleValue":"'1'","status":"1"}

Step 3:将规则授权给指定角色(此步骤才真正让规则对角色生效)

POST /sys/role/datarule
{"permissionId":"{menuId}","roleId":"{roleId}","dataRuleIds":"{ruleId1},{ruleId2}"}

多个规则 ID 用逗号分隔。缺少此步骤,规则虽已创建并启用,但不会对任何角色生效。

Step 4:验证规则已对角色生效

GET /sys/role/datarule/{menuId}/{roleId}

返回结构:

  • datarule[]:该菜单下配置的所有数据规则列表
  • drChecked:已授权给该角色的规则 ID,逗号分隔

drChecked 中包含规则 ID 说明授权成功。

完整流程小结
0. grant_menu_to_role(role_id, menu_id)            → 前提:确保角色有菜单权限
1. POST /sys/permission/addPermissionRule          → 创建规则(默认未启用,result 为 null)
   GET  /sys/permission/queryPermissionRule         → 查询列表获取真实规则 ID
2. POST /sys/permission/editPermissionRule         → 启用规则(status:"1")
3. POST /sys/role/datarule                         → 授权给角色(才真正生效)
4. GET  /sys/role/datarule/{menuId}/{roleId}       → 验证授权结果
修改已有数据规则

使用 editPermissionRule 可修改规则名称、字段、条件、值(保持 status:"1"):

POST /sys/permission/editPermissionRule
{"id":"{ruleId}","permissionId":"{menuId}","ruleName":"新名称","ruleColumn":"birthday","ruleConditions":"=","ruleValue":"'2024-04-11'","status":"1"}
删除数据规则
DELETE /sys/permission/deletePermissionRule?id={ruleId}
ruleConditions 条件值

条件选项来自系统字典 rule_conditions,可通过 GET /sys/dict/getDictItems/rule_conditions 查询完整列表。

常用条件示例:

条件ruleValue 示例说明
='2024-04-11'等于(字符串必须加单引号)
!='1'不等于
>='2024-01-01'大于等于
<='2024-12-31'小于等于
like'%admin%'模糊匹配
in'1','2','3'包含多值
USE_SQL_RULESusername != 'admin'自定义 SQL 表达式,ruleColumn 无需填写,ruleValue 直接写 WHERE 子句(不含 WHERE 关键字)
ruleValue 系统变量

ruleValue 支持以下系统上下文变量(自动替换为当前登录用户信息):

变量说明
#{sys_user_code}登录用户账号
#{sys_user_name}登录用户名称
#{sys_date}当前日期
#{sys_time}当前时间
#{sys_org_code}登录用户部门编码
#{sys_multi_org_code}用户拥有的所有部门编码
#{tenant_id}登录用户所属租户

字符串类型的系统变量需加单引号:'#{sys_user_code}'


数据导出

Online 报表支持导出功能,默认分 sheet 导出,每个 sheet 最多 1 万条数据。


错误处理

错误原因解决方案
401 / 认证失败Token 过期重新从浏览器 F12 获取 X-Access-Token
报表编码已存在code 重复换一个 code,或用 editAll 编辑
parseSql 失败SQL 含复杂函数或语法问题去掉问题条件后解析,再手工添加参数
SQL 注入风险包含危险语句不要在 SQL 中使用 DROP/DELETE/UPDATE
禁止 select *系统开启了 disableSelectAll改为指定具体字段
中文乱码用了 curl必须用 Python urllib

与其他 Skill 的区别

Skill产出物适用场景
jeecg-onlreportOnline 报表(SQL 驱动,只读数据展示)数据查询、统计分析、数据导出
jeecg-onlformOnline 表单(元数据驱动,CRUD)数据录入管理
jeecg-codegenJava + Vue3 代码需要自定义业务逻辑的模块
jeecg-desform设计器表单 JSON数据采集、审批表单

API 快速参考

详细 API schema 参见 references/api_schema.md。

操作API
列出报表GET /online/cgreport/head/list
查报表详情GET /online/cgreport/head/queryById?id={id}
查字段列表GET /online/cgreport/item/listByHeadId?headId={id}
按编码查字段GET /online/cgreport/item/listByHeadCode?headCode={code}
查参数列表GET /online/cgreport/param/listByHeadId?headId={headId}
解析 SQLGET /online/cgreport/head/parseSql?sql={sql}&dbKey={key}
创建报表POST /online/cgreport/head/add
编辑报表PUT /online/cgreport/head/editAll

コメント