# lzwcai-mcpskills-generate-reports

用户提供 **docx 模板 + JSON 数据**，本包负责渲染成 docx，并可选做样式迁移。

本包**不内置模板**，模板完全由调用方维护。

## 安装

```powershell
cd lzwcai_mcpskills_generate_reports
pip install -e .
```

## Python API

### 渲染文档

```python
from lzwcai_mcpskills_generate_reports import generate

out_path = generate(
    data="data.json",              # dict 或 JSON 文件路径
    template="./模板.docx",        # 用户自己的 docx 模板路径
    out_path="_out/报价方案.docx",
    style_ref="./用户样式.docx",   # 可选：把用户模板的 theme/字体套过来
)
```

### 扫描模板占位符

```python
from lzwcai_mcpskills_generate_reports import scan_template

result = scan_template("./模板.docx")
print(result)
# {
#   "placeholders": ["project_title", "contact_person", "equipments", ...],
#   "blocks": [
#       {"type": "for", "iterator": "eq", "variable": "equipments"},
#       {"type": "if", "condition": "show_layout"},
#       ...
#   ]
# }
```

## 命令行

```powershell
# 渲染
generate-report generate --template ./模板.docx --data data.json --out _out/报价方案.docx

# 扫描占位符
generate-report scan --template ./模板.docx

# 样式迁移
generate-report generate --template ./模板.docx --data data.json --style-ref ./用户样式.docx --out _out/报价方案_定制.docx
```

## MCP Server

本包同时提供 MCP Server（stdio 模式），把渲染引擎暴露成 3 个 MCP 工具：

| 工具 | 说明 | 必填参数 |
|------|------|----------|
| `generate_report` | 模板 + 数据 → 渲染输出 docx，返回输出文件绝对路径 | `template`, `data`, `out`（可选 `style_ref`） |
| `scan_template` | 扫描模板占位符与 for/if 块结构 | `template` |
| `validate_report_data` | 校验数据契约（不渲染） | `data` |

其中 `data` 既可以传 JSON 对象，也可以传指向 JSON 文件的路径字符串。

### 启动

```powershell
# 安装后用 console script 启动
lzwcai-mcpskills-generate-reports

# 或直接运行入口模块
python main.py
```

### MCP 客户端配置示例

```json
{
  "mcpServers": {
    "generate-reports": {
      "command": "lzwcai-mcpskills-generate-reports"
    }
  }
}
```

> stdio 模式下 stdout 被 MCP 协议占用，所有日志写入 `logs/` 目录与 stderr。

## 数据契约（QuoteData）

```json
{
  "project_title": "大米罐装线",
  "contact_person": "张经理",
  "contact_phone": "138-0000-0000",
  "requirements": ["要求1", "要求2"],
  "layout_image": "",
  "layout_title": "整线布局尺寸图",
  "equipments": [
    {
      "index": "四",
      "name": "自动理瓶机",
      "images": [""],
      "features": [{"title": "特点", "lines": ["说明"]}],
      "params": [{"k": "材料", "v": "不锈钢"}]
    }
  ],
  "quote_items": [
    {"name": "设备名", "qty": "一套", "image": "", "desc": "说明", "price": "面议"}
  ]
}
```

图片字段约定：路径/URL → 真实图；`""` → 默认占位图；`None` → 不显示。

## 目录结构

```
lzwcai_mcpskills_generate_reports/
├── pyproject.toml
├── README.md
├── templates/                              # 用户模板（示例，不在包内）
│   └── standard/
│       ├── template.docx
│       └── meta.json
├── samples/                                # 示例数据（不在包内）
│   └── sample_data.json
└── lzwcai_mcpskills_generate_reports/      # Python 包
    ├── __init__.py                         # 公共 API 入口
    ├── cli.py                              # 命令行
    ├── pipeline.py                         # 总入口
    ├── schema.py                           # 数据契约 + 校验器
    ├── render_quote.py                     # 渲染引擎
    ├── style_transfer.py                   # 样式迁移
    └── template_scanner.py                 # 模板占位符扫描
```

## 模板约定

- 使用 [Jinja2](https://jinja.palletsprojects.com/) 语法写占位符，如 `{{ project_title }}`、`{% for eq in equipments %}`。
- 模板文件旁的 `meta.json`（可选）声明图片字段宽度，例如：

```json
{
  "image_fields": {
    "layout_image":          {"width_mm": 160},
    "equipments[].images[]": {"width_mm": 120},
    "quote_items[].image":   {"width_mm": 30}
  }
}
```

-  BUSINESS 逻辑（内置模板维护、模板市场等）交给包外的上层系统处理。
