---
slug: "luban-config-skill"
source_type: "skill_md"
source_url: "https://cdn.jsdelivr.net/gh/AshramC/Luban-Config-Skill@main/SKILL.md"
repo: "https://github.com/AshramC/Luban-Config-Skill"
source_file: "SKILL.md"
branch: "main"
---
---
name: luban-config-editor
description: Luban游戏配置表编辑器。当用户上传Excel文件并请求"修改配置表"、"编辑Luban表格"、"更新游戏配置"、"查看配置数据"时触发。支持符合Luban格式（含##var和##type行）的Excel表格的查询、更新、插入和删除操作。
---

# Luban 配置表编辑器 (v2.1)

采用 **"Query (精读) + Patch (微修)"** 模式处理 Luban 格式 Excel 配置表。

## ⚠️ 强制约束

**严禁直接使用 pandas/openpyxl 操作 Excel 文件。**

必须通过脚本完成所有操作：
- `scripts/query.py` — 查询（摘要/条件/分页/列裁剪）
- `scripts/patch.py` — 修改（update/insert/delete + Diff预览）

## 核心原则

1. **最小化读取**：严禁无理由全量拉取。必须用 `--columns` 裁剪列，用 `--limit/--offset` 分页
2. **内存逻辑**：工具只负责基础筛选，复杂判断（如 `age > 10`）由 LLM 在读取数据后内存处理
3. **预览先行**：修改前优先用 `--dry_run` 查看 Diff
4. **原子修改**：Patch 中只包含主键和真正变化的字段

## 前置条件

```bash
pip install pandas openpyxl --break-system-packages
```

## 支持的数据类型

### 基础类型

| 类型定义 | 说明 | Excel示例 | Python映射 |
|----------|------|-----------|------------|
| `int`, `int32`, `long` | 整数 | `100` | `int` |
| `byte`, `short` | 小整数 | `255` | `int` |
| `datetime` | 时间戳 | `1704067200` | `int` |
| `float`, `double` | 浮点数 | `3.14` | `float` |
| `bool` | 布尔值 | `true` / `1` / `yes` / `on` | `bool` |
| `string`, `text` | 文本字符串 | `hello` | `str` |

> **Bool兼容性**：读取时兼容 `true/false`, `1/0`, `yes/no`, `t/f`, `on/off`（不区分大小写）

### 容器类型

| 类型定义 | Excel格式 | Python映射 |
|----------|-----------|------------|
| `array,int` | `1,2,3` | `[1, 2, 3]` |
| `list,string` | `a,b,c` | `["a", "b", "c"]` |
| `set,int` | `1,2,3` | `[1, 2, 3]` |
| `(array#sep=\|),int` | `1\|2\|3` | `[1, 2, 3]` |
| `map,int,string` | `1:a,2:b` | `{1: "a", 2: "b"}` |
| `(map#sep=\|),int,int` | `1:10\|2:20` | `{1: 10, 2: 20}` |

> **Map KV分隔符**：读取时兼容 `_`、`:`、`=`，写入时统一使用 `:`

## 标准操作步骤

### 第一步：结构侦察

获取表名、主键、列名列表：

```bash
python scripts/query.py --excel_path "data.xlsx" --summary
```

输出示例：
```json
{
  "Items": {
    "rows": 2000,
    "pk": "id",
    "fields": [
      {"name": "id", "type": "int"},
      {"name": "rewards", "type": "map,int,int"}
    ]
  }
}
```

### 第二步：外科手术式读取

**场景A：已知主键**
```bash
python scripts/query.py --excel_path "data.xlsx" --sheet Items --where "id=1001"
```

**场景B：批量扫描（必须裁剪+分页）**
```bash
python scripts/query.py --excel_path "data.xlsx" --sheet Items --columns "id,name" --limit 100 --offset 0
```

### 第三步：生成Patch

```python
import json

patch = {
    "Items": {
        "update": [
            {"id": 102, "active": False},
            {"id": 103, "rewards": {1001: 5, 1002: 10}}  # Map类型
        ],
        "insert": [
            {"id": 201, "name": "新道具", "tags": ["vip", "test"]}  # Array类型
        ],
        "delete": [103, 104]
    }
}

with open('patch.json', 'w', encoding='utf-8') as f:
    json.dump(patch, f, ensure_ascii=False, indent=2)
```

### 第四步：安全预览

```bash
python scripts/patch.py --excel_path "data.xlsx" --patch_path patch.json --dry_run
```

输出 Diff：
```json
{
  "Items": {
    "updated": 2,
    "diff": [
      "UPDATE pk=102: active: True -> False",
      "UPDATE pk=103: rewards: 1001:3,1002:5 -> 1001:5,1002:10"
    ]
  }
}
```

**必须检查 Diff**：是否修改了错误的行？值的变化是否合理？

### 第五步：执行

```bash
python scripts/patch.py --excel_path "data.xlsx" --patch_path patch.json
```

## Query 参数速查

| 参数 | 说明 | 示例 |
|------|------|------|
| `--summary` | 获取所有Sheet结构 | `--summary` |
| `--sheet` | 指定Sheet名 | `--sheet Items` |
| `--where` | 主键条件 | `--where "id=1001"` |
| `--columns` | 只返回指定列 | `--columns "id,name"` |
| `--limit` | 最大返回行数 | `--limit 100` |
| `--offset` | 跳过前N行 | `--offset 100` |

## Patch 格式规范

```json
{
  "SheetName": {
    "update": [{"pk": value, "field1": newValue}],
    "insert": [{"pk": value, "field1": value, ...}],
    "delete": [pk1, pk2, ...]
  }
}
```

| 操作 | 说明 |
|------|------|
| update | 必须含主键，只写变更字段，智能跳过无变化字段 |
| insert | 必须含主键和必要字段 |
| delete | 主键列表，软删除（标记#DELETED#） |

## JSON生成规范

**禁止手写JSON字符串，必须用 dict + json.dump**

```python
# ❌ 严禁
json_str = '{"name": "他说"你好""}'

# ✅ 正确
data = {"name": '他说"你好"'}
json.dump(data, f, ensure_ascii=False)
```

## 常见场景策略

| 场景 | ❌ 错误做法 | ✅ 正确做法 |
|------|------------|------------|
| 全表搜索 | 一次性query全表 | 分批 `--limit 100 --offset N` |
| 修改某列 | 读取整行 `select *` | 只读主键+目标列 `--columns "id,gold"` |
| 验证结果 | 修改后query全表 | 查看 `--dry_run` 的 diff 字段 |
