Files
pinmap-to-pinlist/Code/docs/modification-assessment.md
Agent 836ad20515 v1.1.0: 增加交互提示、路径输入、窗口属性配置
- main.py: 增加show_banner()启动说明、各阶段[INFO]日志、结果摘要、任意键退出
- file_selector.py: 重写为路径输入→验证→空输入弹窗回退→不存在循环重试
- run.bat: 新建启动脚本(chcp 65001, mode con cols=80 lines=20, color 0B, title固定署名, pause)
- Code/docs/modification-assessment.md: 修改需求评估文档
2026-05-25 17:29:19 +08:00

472 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# PinMAP → PinList 转换器 — 修改需求评估
> **版本**: v1.0
> **日期**: 2026-05-25
> **评估人**: 脚本架构师 (Script Architect)
> **状态**: 待审批
---
## 1. 修改需求总览
| 编号 | 需求 | 优先级 | 复杂度 |
|------|------|--------|--------|
| R1 | 增加交互提示(启动说明、详细日志、结果摘要) | 高 | 低 |
| R2 | 文件选择方式调整(路径输入 → 弹窗回退 → 报错重试) | 高 | 低 |
| R3 | 窗口属性UTF-8 编码、固定窗口、颜色、署名、pause | 高 | 低 |
---
## 2. 逐项需求分析
### 2.1 需求 R1增加交互提示
**现状**
- 当前 `main.py` 启动即进入文件选择,无任何说明
- 日志输出已有 `[INFO]``[WARN]``[ERROR]``[FATAL]` 分级,但粒度不够细
- 转换完成后直接 `return` 退出,窗口瞬间关闭(双击 bat 运行时)
**修改目标**
1. **启动 Banner**:显示程序名称、功能说明、版本信息、署名
2. **详细日志**:在 Excel 读取、PinMAP 解析、验证、生成、写入各阶段增加 `[INFO]` 日志
3. **结果摘要**:转换完成后不立即退出,显示统计摘要,等待用户确认后退出
**具体改动**
```
启动 Banner 示例:
╔══════════════════════════════════════════════════════════╗
║ PinMAP → PinList 转换器 ║
║ 自动将 Excel PinMAP 文件转换为 PinList ║
║ ║
║ 版本: v1.0.1 ║
║ -By: LeeQwQ ║
╚══════════════════════════════════════════════════════════╝
详细日志示例:
[INFO] 正在读取文件: C:\Users\test\sample_4x4.xlsx
[INFO] 文件读取完成,共 16 个非空单元格
[INFO] 正在解析 PinMAP 结构...
[INFO] 解析完成: 4x4 方形,共 12 个Pin
[INFO] 封装信息: QFN-12
[INFO] 正在验证数据...
[INFO] 验证通过0 个错误2 个警告
[INFO] 正在生成 PinList...
[INFO] 正在写入输出文件...
[SUCCESS] 转换完成!
结果摘要示例:
═══════════════════════════════════════════════════════════
转换结果摘要
═══════════════════════════════════════════════════════════
输入文件: C:\Users\test\sample_4x4.xlsx
输出文件: C:\Users\test\sample_4x4_PinList.xlsx
封装信息: QFN-12
Pin 数量: 12
错误数量: 0
警告数量: 2
═══════════════════════════════════════════════════════════
按任意键退出...
```
### 2.2 需求 R2文件选择方式调整
**现状**
- 当前 `file_selector.py``select_file()` 函数:
- 有命令行参数 → 直接使用
- 无命令行参数 → 直接弹出 tkinter 文件对话框
- 无 GUI 环境 → 回退到命令行参数
- **问题**:用户没有"输入路径"的机会,直接跳到了弹窗
**修改目标**
新的文件选择流程:
```
┌─────────────────────────────────────────┐
│ 1. 提示用户输入文件路径 │
│ "请输入 PinMAP 文件路径: " │
├─────────────────────────────────────────┤
│ 2a. 用户输入了路径 │
│ ├─ 路径存在? → 使用该路径 │
│ └─ 路径不存在? → 报错 + 返回步骤 1 │
│ 2b. 用户直接回车(空输入) │
│ → 弹出 tkinter 文件选择对话框 │
│ ├─ 选择了文件? → 使用该路径 │
│ └─ 取消了? → 返回 None │
└─────────────────────────────────────────┘
```
**具体改动**
- 修改 `file_selector.py` 中的 `select_file()` 函数
- 新增路径验证逻辑(`os.path.exists()` + 文件扩展名检查)
- 新增循环重试逻辑(路径不存在时提示重新输入,最多重试 N 次或无限重试)
- 保留 tkinter 弹窗作为空输入时的回退方案
### 2.3 需求 R3窗口属性
**现状**
- 项目没有 bat 启动脚本
- 用户通过 `python main.py``python main.py input.xls` 直接运行
- 窗口属性完全依赖用户 CMD 默认设置
**修改目标**
创建 `run.bat` 作为标准启动入口,配置窗口属性。
**bat 脚本内容**
```bat
@ECHO OFF
chcp 65001
title PinMAP转PinList -By:LeeQwQ
mode con cols=80 lines=20
color 0B
cls
python main.py %*
pause
EXIT
```
**属性说明**
| 属性 | 命令 | 效果 |
|------|------|------|
| 编码 | `chcp 65001` | 设置 UTF-8 编码,正确显示中文 |
| 窗口标题 | `title PinMAP转PinList -By:LeeQwQ` | 固定署名 |
| 窗口大小 | `mode con cols=80 lines=20` | 80列 × 20行可见区域 |
| 颜色 | `color 0B` | 黑底(0) + 青字(B/浅蓝) |
| 清屏 | `cls` | 启动时清除历史输出 |
| 暂停退出 | `pause` | 转换完成后等待按键 |
**关于"支持往上滑看历史 log 输出信息"**
- `mode con lines=20` 设置的是**可见窗口行数**20行不是缓冲区大小
- Windows CMD 默认的**屏幕缓冲区高度**为 300 行
- 即使可见区域只有 20 行,用户仍可以通过鼠标滚轮或滚动条向上滚动查看历史输出
- 如果需要更大的缓冲区,可额外设置:`mode con cols=80 lines=20` 后,缓冲区默认 300 行已足够
- 如需显式指定缓冲区(可选):可通过注册表或 `mode con` 的缓冲区参数,但通常不需要
**关于"报错时重新输入(不退出)"**
- R2 的文件选择循环已覆盖此场景(路径不存在时返回重试)
- 其他阶段的错误(文件读取失败、结构错误等)仍会退出,但 `pause` 确保窗口不关闭,用户可以看到错误信息
---
## 3. 影响模块列表
| 模块 | 文件 | 影响程度 | 修改内容 | 关联需求 |
|------|------|---------|---------|---------|
| **入口流程** | `src/main.py` | **高** | 增加启动 Banner、详细日志、结果摘要、任意键退出 | R1, R3 |
| **文件选择** | `src/file_selector.py` | **高** | 重写 `select_file()`:路径输入 → 验证 → 弹窗回退 → 循环重试 | R2 |
| **启动脚本** | `run.bat`(新建) | **中** | 创建 bat 启动脚本,配置窗口属性 | R3 |
| **工具函数** | `src/utils.py` | 无 | 无需修改 | — |
| **数据模型** | `src/models.py` | 无 | 无需修改 | — |
| **Excel 读写** | `src/xls_reader.py`<br>`src/xlsx_reader.py`<br>`src/xlsx_writer.py` | 无 | 无需修改 | — |
| **PinMAP 解析** | `src/pinmap_parser.py` | 无 | 无需修改 | — |
| **数据验证** | `src/validator.py` | 无 | 无需修改 | — |
| **PinList 生成** | `src/pinlist_generator.py` | 无 | 无需修改 | — |
**总结**:仅需修改 **2 个现有文件** + 新建 **1 个 bat 脚本**,其余 6 个核心业务模块完全不受影响。
---
## 4. 技术方案
### 4.1 R1 技术方案:交互提示
#### 4.1.1 启动 Banner
`main.py``main()` 函数开头添加:
```python
def show_banner():
"""显示程序启动 Banner"""
print("=" * 56)
print(" PinMAP → PinList 转换器")
print(" 自动将 Excel PinMAP 文件转换为 PinList")
print()
print(" 版本: v1.0.1")
print(" -By: LeeQwQ")
print("=" * 56)
print()
```
#### 4.1.2 详细日志
在现有流程的每个阶段增加日志输出:
```python
# 文件读取前
print(f"[INFO] 正在读取文件: {filepath}")
# 文件读取后
print(f"[INFO] 文件读取完成,共 {len(cells)} 个非空单元格")
# PinMAP 解析前
print(f"[INFO] 正在解析 PinMAP 结构...")
# 验证前
print(f"[INFO] 正在验证数据...")
# 验证后(已有)
print(f"[INFO] 验证通过,{len(validation.errors)} 个错误,{len(validation.warnings)} 个警告")
# 生成前
print(f"[INFO] 正在生成 PinList...")
# 写入前
print(f"[INFO] 正在写入输出文件: {output_path}")
```
#### 4.1.3 结果摘要 + 任意键退出
`main()` 末尾(所有成功/失败分支)添加:
```python
def show_summary(input_path, output_path, pinlist, validation):
"""显示转换结果摘要"""
print()
print("=" * 56)
print(" 转换结果摘要")
print("=" * 56)
print(f" 输入文件: {input_path}")
print(f" 输出文件: {output_path}")
print(f" 封装信息: {pinlist.package_info}")
print(f" Pin 数量: {len(pinlist.rows)}")
print(f" 错误数量: {len(validation.errors)}")
print(f" 警告数量: {len(validation.warnings)}")
print("=" * 56)
def wait_for_exit():
"""等待用户按键后退出"""
try:
import msvcrt
print("\n按任意键退出...")
msvcrt.getch() # Windows 专属,无需回车
except ImportError:
input("\n按 Enter 键退出...") # 跨平台回退
```
**技术要点**
- 使用 `msvcrt.getch()` 实现 Windows 上的"任意键退出"(无需按 Enter
- 跨平台回退使用 `input()`
- 结果摘要仅在成功转换时显示;错误时直接显示错误信息 + 等待退出
### 4.2 R2 技术方案:文件选择方式调整
#### 4.2.1 新的 `select_file()` 流程
```python
def select_file() -> Optional[str]:
"""
文件选择流程:
1. 提示用户输入文件路径
2. 空输入 → 弹出 tkinter 文件对话框
3. 有输入但路径不存在 → 报错 + 重新输入
4. 有输入且路径存在 → 返回路径
"""
while True:
# Step 1: 用户输入路径
filepath = input("请输入 PinMAP 文件路径(直接回车使用文件选择器): ").strip()
# Step 2: 空输入 → 弹窗
if not filepath:
return _select_file_dialog()
# Step 3: 路径验证
if not os.path.exists(filepath):
print(f"[ERROR] 文件不存在: {filepath}")
print("请重新输入...")
continue
# Step 4: 扩展名检查
if not filepath.lower().endswith(('.xls', '.xlsx')):
print(f"[WARN] 文件扩展名不是 .xls 或 .xlsx是否继续")
confirm = input("输入 Y 继续,其他键重新输入: ").strip().upper()
if confirm != 'Y':
continue
return filepath
```
#### 4.2.2 弹窗回退函数
```python
def _select_file_dialog() -> Optional[str]:
"""弹出 tkinter 文件选择对话框"""
try:
import tkinter
import tkinter.filedialog
root = tkinter.Tk()
root.withdraw()
root.attributes("-topmost", True)
filepath = tkinter.filedialog.askopenfilename(
title="选择 PinMAP 文件",
filetypes=[
("Excel 文件", "*.xls *.xlsx"),
("所有文件", "*.*"),
],
)
root.destroy()
return str(filepath) if filepath else None
except (ImportError, Exception):
print("[ERROR] 无法打开文件选择器,请手动输入路径")
return None
```
**技术要点**
- 使用 `while True` 循环实现路径不存在时的重试
- 扩展名检查为 WARN 级别(允许用户强制继续)
- 弹窗回退函数独立封装,保持代码清晰
### 4.3 R3 技术方案:窗口属性
#### 4.3.1 创建 `run.bat`
在项目根目录创建 `run.bat`
```bat
@ECHO OFF
chcp 65001 >nul
title PinMAP转PinList -By:LeeQwQ
mode con cols=80 lines=20
color 0B
cls
python main.py %*
pause
EXIT
```
**说明**
- `chcp 65001 >nul`:静默设置 UTF-8 编码,避免输出 `Active code page: 65001` 干扰界面
- `%*`:透传所有命令行参数(如 `run.bat input.xls`
- `pause`:确保窗口不自动关闭
- `EXIT`:按键后退出 CMD
#### 4.3.2 关于"支持往上滑看历史 log"
- Windows CMD 默认屏幕缓冲区高度为 **300 行**
- `mode con lines=20` 仅设置可见窗口为 20 行,**不影响缓冲区**
- 用户可通过鼠标滚轮或滚动条向上滚动查看完整日志历史
- 如需显式增大缓冲区(可选),可在 bat 中通过 PowerShell 设置,但通常 300 行已足够
#### 4.3.3 关于"报错时重新输入(不退出)"
- R2 的文件选择循环已覆盖"路径不存在"场景
- 其他阶段报错(文件读取失败、结构错误等)会退出 `main()` 但被 `pause` 拦截
- 窗口不会关闭,用户可阅读错误信息后按任意键退出
---
## 5. 任务拆分建议
### 5.1 拆分方案
由于修改范围小2 个文件 + 1 个新文件),**建议不拆分**,由单个编码 Agent 完成。
| 子任务 | 文件 | 预估工作量 | 依赖 |
|--------|------|-----------|------|
| T1: 交互提示 | `src/main.py` | 30 分钟 | 无 |
| T2: 文件选择调整 | `src/file_selector.py` | 20 分钟 | 无 |
| T3: 启动脚本 | `run.bat` | 5 分钟 | 无 |
**总计预估**:约 1 小时
### 5.2 推荐编码 Agent
**Python 编码 Agent**(单个 Agent 即可完成)
理由:
1. 修改不涉及核心业务逻辑(解析、验证、生成)
2. 纯 Python 标准库实现,无第三方依赖
3. bat 脚本简单,任何 Agent 均可完成
4. 拆分反而增加沟通成本
### 5.3 开发顺序
```
T2文件选择 → T1交互提示 → T3启动脚本 → 集成测试
```
理由T2 和 T1 都修改 `main.py`,建议先完成 T2file_selector.py 独立),再合并 T1 到 main.py避免冲突。
---
## 6. 风险评估
| 风险 | 影响 | 概率 | 缓解措施 |
|------|------|------|---------|
| `msvcrt.getch()` 在非 Windows 平台不可用 | 低 | 低 | 已设计跨平台回退(`input()` |
| tkinter 在无 GUI 环境不可用 | 低 | 低 | 已设计回退到路径输入模式 |
| `mode con lines=20` 窗口过小导致日志被截断 | 中 | 中 | 缓冲区默认 300 行,可滚动查看;如需调整可修改 lines 参数 |
| 用户输入路径含特殊字符(空格、中文) | 低 | 中 | Python `os.path.exists()` 和 Excel 读写引擎已支持 Unicode |
| bat 脚本中 `python` 命令不在 PATH 中 | 中 | 中 | 可在 bat 中使用 `py` 命令替代Windows Python Launcher |
### 6.1 技术难点
**无重大技术难点**。所有需求均使用 Python 标准库实现:
- 交互提示:`print()` + `input()` + `msvcrt`
- 文件选择:`os.path.exists()` + `tkinter.filedialog`
- 窗口属性bat 内置命令
### 6.2 兼容性考虑
| 场景 | 处理方式 |
|------|---------|
| 双击 `run.bat` 运行 | 正常流程,窗口不关闭 |
| `run.bat input.xls` 带参数 | `%*` 透传,跳过文件选择 |
| 直接 `python main.py`(不用 bat | 交互提示仍生效,但窗口属性不生效(预期行为) |
| 无 GUI 环境(服务器/远程桌面) | 文件选择回退到路径输入模式 |
| 非 Windows 平台 | `msvcrt` 回退到 `input()`bat 不适用 |
---
## 7. 修改后目录结构
```
pinmap-to-pinlist/
├── Code/
│ ├── src/
│ │ ├── main.py # ✏️ 修改:增加 Banner、日志、摘要
│ │ ├── file_selector.py # ✏️ 修改:重写 select_file()
│ │ ├── xls_reader.py # (不变)
│ │ ├── xlsx_reader.py # (不变)
│ │ ├── pinmap_parser.py # (不变)
│ │ ├── validator.py # (不变)
│ │ ├── pinlist_generator.py # (不变)
│ │ ├── xlsx_writer.py # (不变)
│ │ ├── models.py # (不变)
│ │ └── utils.py # (不变)
│ └── docs/
│ ├── architecture-design.md # (不变)
│ └── modification-assessment.md # 🆕 本文档
├── run.bat # 🆕 新建:启动脚本
├── Test/
└── Releases/
```
---
## 8. 总结
| 项目 | 内容 |
|------|------|
| 修改文件数 | 2 个现有 + 1 个新建 |
| 影响核心模块 | 无(仅修改入口和文件选择) |
| 技术难度 | 低 |
| 预估工作量 | ~1 小时 |
| 推荐 Agent | Python 编码 Agent单个 |
| 风险等级 | 低 |
**结论**:修改需求清晰、范围可控、无技术难点,建议直接分配给单个编码 Agent 执行。
---
*文档结束 — 请审批后进入编码阶段*