@puyinkai/xiaobao-cli 0.1.6 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/{api-client-DWbwtQbl.mjs → api-client-CDNjkArS.mjs} +2 -2
  2. package/dist/{api-JZnABA4y.mjs → api-fsHHWWa3.mjs} +5 -4
  3. package/dist/{audio-BHWH6uhw.mjs → audio-CRSMqaKo.mjs} +2 -2
  4. package/dist/{auth-BpzWivxf.mjs → auth-_3hBh87U.mjs} +3 -3
  5. package/dist/cli.mjs +10 -10
  6. package/dist/{consultant-kV5r8Wj8.mjs → consultant-E33hTGUO.mjs} +1 -1
  7. package/dist/{customer-B2OV8BTR.mjs → customer-DcQ83oKD.mjs} +1 -1
  8. package/dist/{focus-BjWD5PRV.mjs → focus-XMRxnHPw.mjs} +1 -1
  9. package/dist/{list-C30zFN6h.mjs → list-B3nN4pd2.mjs} +1 -1
  10. package/dist/{list-CHububT5.mjs → list-CXquxzex.mjs} +1 -1
  11. package/dist/{list-FM3vkQJa.mjs → list-Cc4zcaNz.mjs} +1 -1
  12. package/dist/{list-VpZkzTEE.mjs → list-CnlQdzPp.mjs} +1 -1
  13. package/dist/{list-Bw8dFf8a.mjs → list-CrMOrnS-.mjs} +1 -1
  14. package/dist/{list-h1nuSJiN.mjs → list-DFdDcHFq.mjs} +1 -1
  15. package/dist/{list-CVMSGK08.mjs → list-dm9YaCG1.mjs} +1 -1
  16. package/dist/login-CUUcjWPd.mjs +156 -0
  17. package/dist/{logout-DVJX8_x6.mjs → logout-DP7REhCd.mjs} +2 -1
  18. package/dist/{project-CJkTgGOq.mjs → project-BD0g4oAW.mjs} +1 -1
  19. package/dist/{qa-CQDRFw-g.mjs → qa-CdMcxCE_.mjs} +1 -1
  20. package/dist/{resistance-Ss-eUZoN.mjs → resistance-6_V6At3T.mjs} +1 -1
  21. package/dist/{text-5q8lIWi8.mjs → text-C3Ap6L5n.mjs} +1 -1
  22. package/dist/{token-store-D2umpIk-.mjs → token-store-CXizLE2_.mjs} +37 -1
  23. package/dist/{visit-CUI2ov-H.mjs → visit-DoeECi8w.mjs} +1 -1
  24. package/dist/{whoami-Uv7GBtGB.mjs → whoami-z-76WaCP.mjs} +2 -2
  25. package/package.json +5 -1
  26. package/skills/wangxiaobao-audio-query/SKILL.md +2 -2
  27. package/skills/wangxiaobao-audio-wiki/SKILL.md +4 -4
  28. package/skills/wangxiaobao-customer-focus-query/SKILL.md +2 -2
  29. package/skills/wangxiaobao-customer-query/SKILL.md +2 -2
  30. package/skills/wangxiaobao-customer-resistance-query/SKILL.md +2 -2
  31. package/skills/wangxiaobao-html-to-pdf/SKILL.md +116 -0
  32. package/skills/wangxiaobao-html-to-pdf/scripts/html2pdf.py +132 -0
  33. package/skills/wangxiaobao-html-to-pdf/scripts/html2pdf_exact.py +92 -0
  34. package/skills/wangxiaobao-project-daily-report/SKILL.md +170 -0
  35. package/skills/wangxiaobao-project-daily-report/_meta.json +9 -0
  36. package/skills/wangxiaobao-project-daily-report/references/report_template.html +308 -0
  37. package/skills/wangxiaobao-project-daily-report/scripts/fetch_data.py +219 -0
  38. package/skills/wangxiaobao-project-daily-report/scripts/generate_report.py +1029 -0
  39. package/skills/wangxiaobao-project-daily-report/scripts/run.py +34 -0
  40. package/skills/wangxiaobao-project-weekly-report/SKILL.md +169 -0
  41. package/skills/wangxiaobao-project-weekly-report/scripts/generate_report.py +308 -0
  42. package/skills/wangxiaobao-project-weekly-report/scripts/html2pdf_fast.py +161 -0
  43. package/skills/wangxiaobao-project-weekly-report/scripts/logo_wangai.png +0 -0
  44. package/skills/wangxiaobao-project-weekly-report/scripts/logo_wangxiaobao.png +0 -0
  45. package/skills/wangxiaobao-project-weekly-report/scripts/prepare_data.py +682 -0
  46. package/skills/wangxiaobao-project-weekly-report/scripts/template.py +925 -0
  47. package/skills/wangxiaobao-quick-qa/SKILL.md +2 -2
  48. package/skills/wangxiaobao-shared/SKILL.md +40 -7
  49. package/skills/wangxiaobao-switch-project/SKILL.md +3 -3
  50. package/skills/wangxiaobao-visit-query/SKILL.md +2 -2
  51. package/dist/login-DtDxISE8.mjs +0 -91
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: wangxiaobao-html-to-pdf
3
+ description: 将HTML文件转换为高质量PDF。当用户需要将HTML文件(本地文件或URL)转为PDF时触发此技能。触发词包括:HTML转PDF、生成PDF、导出PDF、convert HTML to PDF、HTML to PDF、把HTML生成PDF、PDF导出。支持完整保留CSS样式、渐变、Grid/Flex布局、背景色等。
4
+ agent_created: true
5
+ ---
6
+
7
+ # HTML to PDF
8
+
9
+ ## Overview
10
+
11
+ 将HTML文件(本地文件或HTTP URL)转换为高质量PDF,使用Playwright无头Chromium渲染引擎,完整保留CSS渐变、Grid/Flex布局、背景色、字体等样式。适用于包含复杂样式的HTML报告、海报、数据可视化页面等场景。
12
+
13
+ ## Prerequisites
14
+
15
+ 运行此技能需要:
16
+ - Python 3.8+
17
+ - Playwright + Chromium
18
+
19
+ 如未安装,先执行:
20
+ ```bash
21
+ pip install playwright
22
+ python3 -m playwright install chromium
23
+ ```
24
+
25
+ ## CLI 参数
26
+
27
+ ```bash
28
+ python3 scripts/html2pdf.py <source> [output] [options]
29
+ ```
30
+
31
+ | 参数 | 说明 |
32
+ |------|------|
33
+ | `source` | HTML文件路径或HTTP/HTTPS URL(必填) |
34
+ | `output` | 输出PDF路径(可选,默认与HTML同名.pdf) |
35
+ | `--width` | 页面宽度(如 `210mm`、`1200px`) |
36
+ | `--height` | 页面高度(如 `297mm`、`1697px`) |
37
+ | `--format` | 标准纸张:`A4`(默认)、`A3`、`Letter` 等 |
38
+ | `--landscape` | 横向模式(A4横向 = 297×210mm) |
39
+
40
+ **页面尺寸优先级**:`--width/--height` > `--landscape` > `--format`
41
+
42
+ ## Workflow
43
+
44
+ ### Step 1: 确认输入
45
+
46
+ 确认用户提供的HTML文件路径或URL:
47
+ - 本地文件:使用文件路径(如 `/path/to/report.html` 或 `report.html`)
48
+ - URL:完整的HTTP/HTTPS地址(如 `https://example.com/page.html`)
49
+
50
+ ### Step 2: 选择页面尺寸
51
+
52
+ 根据HTML设计宽度选择合适的PDF页面尺寸:
53
+
54
+ | 场景 | 参数 | 说明 |
55
+ |------|------|------|
56
+ | 标准报告/A4纵向 | (默认) | A4 210×297mm |
57
+ | 宽屏报告/A4横向 | `--landscape` | A4 横向,适合宽屏HTML |
58
+ | 与HTML设计宽完全匹配 | `--width 1200px --height 1697px` | 自定义尺寸,1:1无缩放 |
59
+ | 其他标准纸张 | `--format A3` | 支持 A3/A2/Letter 等 |
60
+
61
+ ### Step 3: 执行转换
62
+
63
+ ```bash
64
+ # 基本用法(A4纵向)
65
+ python3 scripts/html2pdf.py report.html
66
+
67
+ # 指定输出路径
68
+ python3 scripts/html2pdf.py report.html ./output.pdf
69
+
70
+ # A4 横向(适合宽屏报告)
71
+ python3 scripts/html2pdf.py report.html --landscape
72
+
73
+ # 自定义页面尺寸(与HTML设计宽完全匹配)
74
+ python3 scripts/html2pdf.py report.html --width 1200px --height 1697px
75
+
76
+ # 其他标准纸张
77
+ python3 scripts/html2pdf.py report.html --format A3
78
+ ```
79
+
80
+ ### Step 4: 验证并交付
81
+
82
+ 1. 确认PDF文件已生成(检查文件大小 > 0)
83
+ 2. 使用 `deliver_attachments` 工具交付PDF给用户
84
+ 3. 在回复中说明文件名、大小、保存位置
85
+
86
+ ## PDF参数
87
+
88
+ 默认配置:
89
+ - **纸张格式**:A4(可通过 `--format` / `--landscape` / `--width+--height` 修改)
90
+ - **边距**:上15mm / 下15mm / 左10mm / 右10mm
91
+ - **打印背景**:是(完整保留CSS背景色、渐变)
92
+ - **页眉页脚**:关闭
93
+
94
+ ## 排版一致性建议
95
+
96
+ 为确保PDF与HTML排版完全一致:
97
+ 1. **使用自定义尺寸**:`--width 1200px --height 1697px`(匹配HTML设计宽度)
98
+ 2. **或在HTML中添加打印CSS**:
99
+ ```css
100
+ @page { size: 1200px 1697px; margin: 0; }
101
+ @media print {
102
+ body { margin: 0; -webkit-print-color-adjust: exact; }
103
+ .card { break-inside: avoid; }
104
+ }
105
+ ```
106
+ 3. **A4横向**:`--landscape` 适合大多数宽屏报告
107
+
108
+ ## Troubleshooting
109
+
110
+ | 问题 | 原因 | 解决方案 |
111
+ |------|------|----------|
112
+ | 报错 `playwright` 未找到 | Python环境未安装playwright | 运行 `pip install playwright && python3 -m playwright install chromium` |
113
+ | PDF内容不全 | 页面JS未加载完成 | 增大 `wait_for_timeout` 的等待时间(默认5秒) |
114
+ | 中文字体缺失 | 系统未安装中文字体 | HTML中使用系统字体栈(PingFang SC / Microsoft YaHei) |
115
+ | 文件路径含中文报错 | 路径编码问题 | 使用绝对路径,确保路径格式正确 |
116
+ | PDF排版与HTML不一致 | 页面尺寸不匹配 | 使用 `--width/--height` 指定与HTML设计宽一致的尺寸 |
@@ -0,0 +1,132 @@
1
+ """Convert HTML file to PDF using Playwright (headless Chromium).
2
+
3
+ Supports both local HTML files and HTTP URLs.
4
+ Usage:
5
+ python3 html2pdf.py <html_path_or_url> [output_pdf_path] [options]
6
+
7
+ Options:
8
+ --width <size> Page width (e.g., "210mm", "1200px")
9
+ --height <size> Page height (e.g., "297mm", "1697px")
10
+ --format <fmt> Page format: A4, A3, Letter, etc. (default: A4)
11
+ --landscape Use landscape orientation (297mm x 210mm)
12
+
13
+ Examples:
14
+ python3 html2pdf.py report.html # A4 portrait
15
+ python3 html2pdf.py report.html --landscape # A4 landscape
16
+ python3 html2pdf.py report.html --width 1200px --height 1697px # custom size
17
+ """
18
+
19
+ import sys
20
+ import os
21
+ import argparse
22
+ from pathlib import Path
23
+ from playwright.sync_api import sync_playwright
24
+
25
+
26
+ def html_to_pdf(source: str, pdf_path: str = None, width: str = None, height: str = None, page_format: str = "A4", landscape: bool = False) -> str:
27
+ """
28
+ Convert an HTML file or URL to PDF.
29
+
30
+ Args:
31
+ source: Absolute path to an HTML file, or an HTTP/HTTPS URL.
32
+ pdf_path: Optional output PDF path. Defaults to same name as source with .pdf extension.
33
+ width: Optional page width (e.g., "210mm", "1200px"). Overrides format if set.
34
+ height: Optional page height (e.g., "297mm", "1697px"). Overrides format if set.
35
+ page_format: Page format (A4, A3, Letter, etc.). Ignored if width/height set.
36
+ landscape: If True, use landscape orientation (swaps width/height of format).
37
+
38
+ Returns:
39
+ The absolute path to the generated PDF file.
40
+ """
41
+ is_url = source.startswith("http://") or source.startswith("https://")
42
+
43
+ if not is_url:
44
+ source = os.path.abspath(source)
45
+ if not os.path.exists(source):
46
+ raise FileNotFoundError(f"HTML file not found: {source}")
47
+ file_url = Path(source).as_uri()
48
+ else:
49
+ file_url = source
50
+
51
+ if pdf_path is None:
52
+ if is_url:
53
+ from urllib.parse import urlparse
54
+ path_part = urlparse(source).path
55
+ base_name = Path(path_part).stem or "page"
56
+ pdf_path = os.path.join(os.getcwd(), base_name + ".pdf")
57
+ else:
58
+ pdf_path = source.rsplit(".", 1)[0] + ".pdf"
59
+
60
+ with sync_playwright() as p:
61
+ browser = p.chromium.launch(headless=True)
62
+ page = browser.new_page()
63
+
64
+ # 设置 viewport 尺寸,与 PDF 页面尺寸匹配,避免缩放
65
+ if width and height:
66
+ w_px = int(width.replace("px", "")) if "px" in width else 800
67
+ h_px = int(height.replace("px", "")) if "px" in height else 1100
68
+ page.set_viewport_size({"width": w_px, "height": h_px})
69
+ elif landscape:
70
+ page.set_viewport_size({"width": 1123, "height": 795}) # A4 横向 96dpi
71
+ else:
72
+ page.set_viewport_size({"width": 794, "height": 1123}) # A4 纵向 96dpi
73
+
74
+ # 强制使用 screen 媒体模式渲染(确保 Chart.js 等按屏幕 CSS 渲染)
75
+ page.emulate_media(media="screen")
76
+
77
+ page.goto(file_url, wait_until="networkidle")
78
+ page.wait_for_timeout(8000) # 等待 Chart.js 图表充分渲染(8秒)
79
+
80
+ # Build pdf parameters
81
+ pdf_params = {
82
+ "path": pdf_path,
83
+ "print_background": True,
84
+ "margin": {"top": "15mm", "bottom": "15mm", "left": "10mm", "right": "10mm"},
85
+ "display_header_footer": False,
86
+ }
87
+
88
+ if width and height:
89
+ pdf_params["width"] = width
90
+ pdf_params["height"] = height
91
+ elif landscape:
92
+ pdf_params["width"] = "297mm"
93
+ pdf_params["height"] = "210mm"
94
+ else:
95
+ pdf_params["format"] = page_format
96
+
97
+ page.pdf(**pdf_params)
98
+ browser.close()
99
+
100
+ return pdf_path
101
+
102
+
103
+ if __name__ == "__main__":
104
+ parser = argparse.ArgumentParser(
105
+ description="Convert HTML file or URL to PDF using Playwright (headless Chromium).",
106
+ formatter_class=argparse.RawDescriptionHelpFormatter,
107
+ epilog="""
108
+ Examples:
109
+ python3 html2pdf.py report.html # A4 portrait
110
+ python3 html2pdf.py report.html --landscape # A4 landscape
111
+ python3 html2pdf.py report.html --width 1200px --height 1697px # custom size
112
+ python3 html2pdf.py report.html output.pdf --format A3 # A3 format
113
+ """
114
+ )
115
+ parser.add_argument("source", help="HTML file path or HTTP/HTTPS URL")
116
+ parser.add_argument("output", nargs="?", default=None, help="Output PDF path (default: same name as source)")
117
+ parser.add_argument("--width", help="Page width (e.g., '210mm', '1200px')")
118
+ parser.add_argument("--height", help="Page height (e.g., '297mm', '1697px')")
119
+ parser.add_argument("--format", default="A4", help="Page format: A4, A3, Letter, etc. (default: A4)")
120
+ parser.add_argument("--landscape", action="store_true", help="Use landscape orientation")
121
+
122
+ args = parser.parse_args()
123
+
124
+ result = html_to_pdf(
125
+ source=args.source,
126
+ pdf_path=args.output,
127
+ width=args.width,
128
+ height=args.height,
129
+ page_format=args.format,
130
+ landscape=args.landscape,
131
+ )
132
+ print(f"PDF generated: {result}")
@@ -0,0 +1,92 @@
1
+ """Convert HTML to PDF with exact same layout as browser rendering.
2
+
3
+ Instead of fitting to A4, this script measures the actual rendered content size
4
+ and creates a PDF page that exactly matches, preserving the original layout 1:1.
5
+
6
+ Usage:
7
+ python3 html2pdf_exact.py <html_path_or_url> [output_pdf_path]
8
+ """
9
+
10
+ import sys
11
+ import os
12
+ from pathlib import Path
13
+ from playwright.sync_api import sync_playwright
14
+
15
+
16
+ def html_to_pdf_exact(source: str, pdf_path: str = None) -> str:
17
+ """
18
+ Convert HTML to PDF preserving exact layout.
19
+ Measures rendered content size and uses that as PDF page size.
20
+ """
21
+ is_url = source.startswith("http://") or source.startswith("https://")
22
+
23
+ if not is_url:
24
+ source = os.path.abspath(source)
25
+ if not os.path.exists(source):
26
+ raise FileNotFoundError(f"HTML file not found: {source}")
27
+ file_url = Path(source).as_uri()
28
+ else:
29
+ file_url = source
30
+
31
+ if pdf_path is None:
32
+ if is_url:
33
+ from urllib.parse import urlparse
34
+ path_part = urlparse(source).path
35
+ base_name = Path(path_part).stem or "page"
36
+ pdf_path = os.path.join(os.getcwd(), base_name + ".pdf")
37
+ else:
38
+ pdf_path = source.rsplit(".", 1)[0] + ".pdf"
39
+
40
+ with sync_playwright() as p:
41
+ browser = p.chromium.launch(headless=True)
42
+ # Use a wide viewport to avoid unwanted wrapping
43
+ page = browser.new_page(viewport={"width": 1440, "height": 900})
44
+ page.goto(file_url, wait_until="networkidle")
45
+ page.wait_for_timeout(5000) # Wait for Chart.js to render
46
+
47
+ # Get actual content dimensions
48
+ dims = page.evaluate("""() => {
49
+ const body = document.body;
50
+ const html = document.documentElement;
51
+ const width = Math.max(
52
+ body.scrollWidth, body.offsetWidth,
53
+ html.clientWidth, html.scrollWidth, html.offsetWidth
54
+ );
55
+ const height = Math.max(
56
+ body.scrollHeight, body.offsetHeight,
57
+ html.clientHeight, html.scrollHeight, html.offsetHeight
58
+ );
59
+ return { width: Math.ceil(width), height: Math.ceil(height) };
60
+ }""")
61
+
62
+ content_width = dims["width"]
63
+ content_height = dims["height"]
64
+
65
+ # Add small padding
66
+ pdf_width = content_width + 2
67
+ pdf_height = content_height + 2
68
+
69
+ page.pdf(
70
+ path=pdf_path,
71
+ width=f"{pdf_width}px",
72
+ height=f"{pdf_height}px",
73
+ print_background=True,
74
+ margin={"top": "0mm", "bottom": "0mm", "left": "0mm", "right": "0mm"},
75
+ display_header_footer=False,
76
+ prefer_css_page_size=False,
77
+ )
78
+ browser.close()
79
+
80
+ return pdf_path
81
+
82
+
83
+ if __name__ == "__main__":
84
+ if len(sys.argv) < 2:
85
+ print("Usage: python3 html2pdf_exact.py <html_file_or_url> [output_pdf]")
86
+ sys.exit(1)
87
+
88
+ source_arg = sys.argv[1]
89
+ pdf_arg = sys.argv[2] if len(sys.argv) > 2 else None
90
+
91
+ result = html_to_pdf_exact(source_arg, pdf_arg)
92
+ print(f"PDF generated: {result}")
@@ -0,0 +1,170 @@
1
+ ---
2
+ name: wangxiaobao-project-daily-report
3
+ description: >
4
+ 地产项目营销日报生成器。基于旺小宝 API 拉取来访、客户画像、成交数据,
5
+ 生成结构化 HTML + PDF 日报。触发词:营销日报、项目日报、生成日报、daily report。
6
+ agent_created: true
7
+ ---
8
+
9
+ # 旺小宝项目日报生成技能
10
+
11
+ ## 概述
12
+
13
+ 基于旺小宝API自动拉取数据,生成 `<项目名>` 营销日报HTML+PDF文件(排版完全一致)。
14
+
15
+ ## 功能特性
16
+
17
+ - 自动拉取旺小宝来访数据、客户画像、成交数据
18
+ - 意向等级分析(A/B/C/D)
19
+ - 渠道分布分析(中介/自渠/顺访等)
20
+ - 存量客户复访分析
21
+ - 生成专业排版HTML日报(与参考模板完全一致)
22
+ - **同时生成同名PDF文件,排版与HTML 1:1一致**(需Chrome/Edge)
23
+
24
+ ## 触发词
25
+
26
+ ```
27
+ 营销日报
28
+ 项目日报
29
+ 生成日报
30
+ daily report
31
+ ```
32
+
33
+ ## 使用方法
34
+
35
+ ### 方式一:直接语音/文字命令(推荐)
36
+
37
+ ```
38
+ 生成项目日报
39
+ ```
40
+
41
+ ### 方式二:指定日期
42
+
43
+ ```
44
+ 生成2026年5月19日的项目日报
45
+ ```
46
+
47
+ ### 方式三:本地执行脚本
48
+
49
+ ```bash
50
+ cd <skill目录>/scripts
51
+ python generate_report.py 2026-05-19
52
+ ```
53
+
54
+ 可通过环境变量或命令行参数指定项目:
55
+
56
+ ```bash
57
+ python generate_report.py 2026-05-19 \
58
+ --tenant-id <你的租户ID> \
59
+ --project-id <你的项目ID> \
60
+ --project-name "<项目名>"
61
+ ```
62
+
63
+ ### 方式四:一键运行(自动用昨日日期)
64
+
65
+ ```bash
66
+ python3 run.py # 不带日期参数,自动用昨天的日期
67
+ python3 run.py 2026-05-19 # 也可指定日期,参数原样透传给 generate_report.py
68
+ ```
69
+
70
+ ## 输出文件
71
+
72
+ 每次生成同时产生两个文件,默认写入当前工作目录:
73
+
74
+ ```
75
+ <工作目录>/<项目名>_日报_YYYYMMDD.html
76
+ <工作目录>/<项目名>_日报_YYYYMMDD.pdf
77
+ ```
78
+
79
+ - **HTML**:可直接在浏览器中打开查看、打印
80
+ - **PDF**:由 Chrome/Edge headless 打印生成,排版与 HTML 完全一致,可直接转发
81
+
82
+ ## 日报内容结构
83
+
84
+ | 模块 | 说明 |
85
+ |------|------|
86
+ | KPI概览 | 本月来访、来访进度达成、本月成交、昨日本月来访 |
87
+ | 来访指标 | 月度客储指标、截至昨日来访、完成率、进度达成率 |
88
+ | 来访意向等级 | A级/B级/C级/D级分布及占比 |
89
+ | 销售指标 | 月度销售指标、截至昨日成交、完成率、进度达成率 |
90
+ | 成交意向等级 | 成交客户的意向等级分布 |
91
+ | 来访渠道分布 | 中介/自渠/顺访/约访等渠道统计 |
92
+ | 存量客户汇总 | 近3月未成交客户按渠道分布 |
93
+ | 存量客户明细 | 预计本周复访客户完整信息(10条) |
94
+ | 昨日来访明细 | 昨日来访客户记录 |
95
+ | 顾问来访统计 | 顾问来访排行 |
96
+ | 数据说明 | 数据来源及状态说明 |
97
+
98
+ ## 数据来源
99
+
100
+ | 数据类型 | 来源 | 说明 |
101
+ |---------|------|------|
102
+ | 来访数据 | 旺小宝 `/ai-open/visits/page` | 来访时间、顾问、次数、时长 |
103
+ | 客户画像 | 旺小宝 `/ai-open/customers/page` | 意向等级、渠道、成交状态 |
104
+ | 成交数据 | 旺小宝客户画像 dealStatus=1 | 成交套数 |
105
+ | KPI指标 | 配置项(环境变量/命令行参数) | 来访目标、销售目标 |
106
+
107
+ ## 依赖
108
+
109
+ - 旺小宝OAuth授权(首次使用需授权)
110
+ - Python 3.x(内置urllib,无需额外依赖)
111
+ - Google Chrome 或 Microsoft Edge(用于生成PDF,已安装可跳过)
112
+
113
+ ## 首次使用
114
+
115
+ 1. 如果没有授权旺小宝,系统会提示授权
116
+ 2. 打开授权链接,输入验证码完成授权
117
+ 3. 重新执行生成命令
118
+
119
+ ## 项目配置
120
+
121
+ 项目标识与KPI指标均可配置,优先级为:命令行参数 > 环境变量 > 默认值。
122
+
123
+ ### 方式一:环境变量
124
+
125
+ ```bash
126
+ export XIAOBAO_TENANT_ID="你的租户ID"
127
+ export XIAOBAO_PROJECT_ID="你的项目ID"
128
+ export XIAOBAO_PROJECT_NAME="项目名称"
129
+ export XIAOBAO_MONTH_VISIT_TARGET="500" # 月度来访目标
130
+ export XIAOBAO_MONTH_SALES_TARGET="21000" # 月度销售目标(万元)
131
+ ```
132
+
133
+ ### 方式二:命令行参数
134
+
135
+ ```bash
136
+ python generate_report.py 2026-05-19 \
137
+ --tenant-id <你的租户ID> \
138
+ --project-id <你的项目ID> \
139
+ --project-name "<项目名>" \
140
+ --month-visit-target 500 \
141
+ --month-sales-target 21000
142
+ ```
143
+
144
+ ## 文件结构
145
+
146
+ ```
147
+ wangxiaobao-project-daily-report/
148
+ ├── SKILL.md # 本文档
149
+ ├── _meta.json # Skill元数据
150
+ ├── scripts/
151
+ │ ├── fetch_data.py # 数据拉取脚本
152
+ │ ├── generate_report.py # 主生成脚本
153
+ │ └── run.py # 一键运行入口(默认昨日日期,跨平台)
154
+ └── references/
155
+ └── report_template.html # HTML模板参考
156
+ ```
157
+
158
+ ## 技术细节
159
+
160
+ - 使用Python原生urllib调用API,彻底避免PowerShell中文编码乱码问题
161
+ - HTML模板完全参照参考文件样式
162
+ - PDF由Chrome/Edge headless `--print-to-pdf` 生成,排版与HTML 1:1一致
163
+ - 数据自动关联来访记录与客户画像
164
+ - 客户姓名自动脱敏
165
+ - **PDF打印优化**:
166
+ - 使用 `--print-background` 参数强制打印背景色
167
+ - `@media print` CSS块中强制所有表头元素背景色+文字颜色(`print-color-adjust: exact !important`)
168
+ - 表头文字统一白色(`color: #fff !important`),深色背景确保可读性
169
+ - KPI卡片打印布局使用 `flex-wrap: nowrap`,4个卡片强制1行排列
170
+ - 所有 `.section-title` / `.table-header td` / `.table-header-peach` 等表头类均有独立打印样式声明
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "wangxiaobao-project-daily-report",
3
+ "displayName": "旺小宝项目日报生成器",
4
+ "description": "地产项目营销日报生成器,基于旺小宝API实时数据",
5
+ "version": "1.0.0",
6
+ "author": "xiaobao-cli",
7
+ "tags": ["地产", "日报", "旺小宝", "营销"],
8
+ "created": "2026-05-21"
9
+ }