Files
pinmap-to-pinlist/docs/modification-assessment-v1.6.md
Agent 3c5fcff1d5 v1.6.0 修复 PinMAP→PinList 上方引脚丢失 + 双向模板样式 + QFN60 端到端验证
F013: Code/src/pinmap_parser.py 增加 Top 边自动布局检测
F014/F015: 双向模板样式确认
F016/F017: 新增 5 个 QFN60 端到端测试
2026-06-12 20:45:51 +08:00

25 KiB
Raw Blame History

PinMAP ↔ PinList 双向转换器 — v1.6 整改架构评估

版本: v1.6 (针对 F013F017 五项 P0 整改需求) 日期: 2026-06-12 评估人: 脚本架构师 (Script Architect) 状态: 评估完成,待编码实施


1. 需求总览

需求 ID 方向 问题描述 严重级别 当前状态
F013 MAP→List 封装上侧Top引脚全部未被识别 P0 🔴 Bug:解析逻辑硬编码 Top Name/Number 位置假设
F014 List→MAP PinMAP 输出需应用 PinMAP-Template.xlsx 样式 P0 🔴 部分有效:代码结构存在但模板路径需要确认
F015 MAP→List PinList 输出需应用 PinList-Template.xlsx 样式 P0 🔴 部分有效:同上
F016 List→MAP 使用 QFN60 示例验证 List→MAP 转换正确性 P0 🔴 新测试:需设计端到端测试用例
F017 MAP→List 使用 QFN60 示例验证 MAP→List 转换正确性 P0 🔴 新测试:需设计端到端测试用例

执行顺序依赖

F013 (修复解析) ──┬── F015 (MAP→List 模板) ── F017 (MAP→List 验证)
                  │
                  └── F014 (List→MAP 模板) ── F016 (List→MAP 验证)

2. F013 根因分析 — PinMAP→PinList 上方引脚丢失

2.1 问题描述

用户反馈PinMAP→PinList 转换后封装上侧Top引脚全部缺失。以 QFN60 (12×12 网格, 4×(12+12)=96 槽位但仅 60 引脚环形布局) 为例,应输出 60 个引脚,实际输出可能只有 45 个(仅左+下+右三边,上边 15 个全部丢失)。

2.2 关键证据:用户真实 PinMAP 布局

用户提供的 QFN60 PinMAP 片段CSV 格式12×12 网格):

QFN60 6*6*0.85mm ...          ← Row 1 (A1)
,  ,60,59,58,57,56,55,54,53,52,51,50,49,48,47,46,    ← Row 2 (Numbers)
,  ,Pin60,Pin59,...,Pin46,                               ← Row 3 (Names)
1  ,Pin1,,,,,,,,,,,,,,,,Pin45,45                         ← Row 4 (left Pin1 + right Pin45)
2  ,Pin2,,,,,,,,,,,,,,,,Pin44,44                         ← Row 5 (left Pin2 + right Pin44)
...
12 ,Pin12,,,,,,,,,,,,,,,Pin34,34                         ← Row 15 (left Pin12 + right Pin34)
,  ,Pin13,Pin14,...,Pin33,                               ← Row 16 (bottom Names)
,  ,13,14,...,33,                                        ← Row 17 (bottom Numbers)

关键发现:上边 Name 在 Row 3第 3 行),上边 Number 在 Row 2第 2 行)。

2.3 当前解析器硬编码假设 vs 用户实际布局

当前 pinmap_parser.py v1.5.5 的硬编码假设

Number 位置 Name 位置
Top min_row + 1(即 row 1 min_row(即 row 0
Left (r, min_col) (r, min_col + 1)
Bottom (max_row, c) (max_row - 1, c)
Right (r, max_col) (r, max_col - 1)

这个设计假设了 v1.5.5 生成的 PinMAP 布局Name 在 Number 上方一行Name 在 min_rowNumber 在 min_row+1

用户的真实布局

Number 位置 Name 位置
Top Row 2第 2 行) Row 3第 3 行)
Left Col A第 1 列) Col B第 2 列)
Bottom 倒数第 1 行 倒数第 2 行
Right 最右列 次右列

2.4 根因Name 和 Number 相对位置反转

用户 PinMAP 中 Top 边的布局是 Number 在上方、Name 在下方(与当前假设相反)。当前代码:

# pinmap_parser.py 第 114-117 行v1.5.5
# top edge names at (min_row, c) — one row ABOVE the Number row.
for c in range(min_col, max_col + 1):
    name = cells.get((min_row, c), "")
    if name and str(name).strip() and _try_int(name) is None:
        name_map[(min_row + 1, c)] = str(name).strip()

这段代码:

  1. min_row 行查找 Name
  2. 将 Name 映射到 min_row + 1 行的 Number 单元格

但在用户实际布局中,上边 Name 在 min_row + 1Row 3Number 在 min_rowRow 2。由于 Name 查不到Name 在 min_row+1 而非 min_row_try_int(name) 检查会将 Number纯数字如 "60")过滤掉,导致整个上边的 Name 全部未被建立 name_map 映射。

更严重的问题是:由于 corners如 Pin1/Pin60、Pin46/Pin45的 Name/Number 位于左右边缘列,上边的 Number 可能在右边缘扫描时被误识别为右边 Pin而 Name 仍在右边被找到——但中间 13 个上边引脚Pin47-Pin59不含左右角的 Pin60/Pin46完全丢失。

2.5 为什么 v1.5.5 的测试没发现

v1.5.5 的 4×4 和 12-pin 测试用例都是程序自己生成的 PinMAP 布局(生成的 Name 总是在上边 Number 之上),然后用这个自产的 PinMAP 做往返解析。自产的 PinMAP 布局与解析假设一致,因此往返测试全部通过。

但是用户提供的 PinMAP 来自其他渠道(可能是手工绘制或其他工具生成),其布局约定与程序生成的布局方向相反


3. F013 修改方案

3.1 设计原则

PinMAP 解析器必须兼容 "Name 在 Number 上方""Number 在 Name 上方" 两种布局。对于上边而言Name 和 Number 分布在相邻两行,解析器需要智能检测哪一行是 Name、哪一行是 Number。

3.2 检测策略:基于内容特征识别 Name 行 vs Number 行

对于 Top 边,扫描第一行非 A1 数据行和其后一行:

  • Number 行特征:所有单元格(或绝大多数)都是可解析为整数的值(如 "60", "59", ...
  • Name 行特征:所有单元格(或绝大多数)都是非纯数字的字符串(如 "Pin60", "Pin59", ...

如果第一行全是数字Number 在第一行Name 在第二行(用户布局)。 如果第一行全是非数字且非空Name 在第一行Number 在第二行v1.5.5 布局)。

3.3 具体实现

文件Code/src/pinmap_parser.py

修改 Step 2确定边界和 Step 3上边 Name 查找)之间的逻辑,增加 Top 边的自动检测。

# ── Top edge layout detection ─────────────────────────────────
# 检测上边布局:哪种布局由数据内容决定
# 布局 AName 在 min_row上方Number 在 min_row+1下方
#   例Row 1: Pin60 Pin59 ... Pin46, Row 2: 60 59 ... 46
# 布局 BNumber 在 min_row上方Name 在 min_row+1下方
#   例Row 1: 60 59 ... 46, Row 2: Pin60 Pin59 ... Pin46

min_row_for_top = min_row  # 可能是 1A1 被排除后)
top_row_1_cells = []
top_row_2_cells = []

for c in range(min_col, max_col + 1):
    v1 = cells.get((min_row_for_top, c), "")
    v2 = cells.get((min_row_for_top + 1, c), "")
    if v1 and str(v1).strip():
        top_row_1_cells.append(str(v1).strip())
    if v2 and str(v2).strip():
        top_row_2_cells.append(str(v2).strip())

# 检测哪一行是 Number 行
def _is_number_row(values: list[str]) -> bool:
    if not values:
        return False
    numeric = sum(1 for v in values if _try_int(v) is not None)
    return numeric >= len(values) * 0.7  # 70% 以上是数字即为 Number 行

row1_is_number = _is_number_row(top_row_1_cells)
row2_is_number = _is_number_row(top_row_2_cells)

if row1_is_number and not row2_is_number:
    # 布局 BNumber 在上Name 在下(用户实际布局)
    top_number_row = min_row_for_top
    top_name_row = min_row_for_top + 1
elif not row1_is_number and row2_is_number:
    # 布局 AName 在上Number 在下v1.5.5 布局)
    top_name_row = min_row_for_top
    top_number_row = min_row_for_top + 1
elif row1_is_number and row2_is_number:
    # 两行都是数字(异常情况:可能没有 Name 行)
    # 回退到布局 A 假设
    top_name_row = min_row_for_top
    top_number_row = min_row_for_top + 1
else:
    # 两行都不是数字(极异常情况)
    # 回退到布局 A 假设
    top_name_row = min_row_for_top
    top_number_row = min_row_for_top + 1

然后修改 Step 3 中上边 Name 查找和 Step 4d 中的 Top 边 Number 遍历:

# Step 3: 上边 Name 查找(修改后)
# Name 在上边数字行之上/之下的一行
for c in range(min_col, max_col + 1):
    name = cells.get((top_name_row, c), "")
    if name and str(name).strip() and _try_int(name) is None:
        name_map[(top_number_row, c)] = str(name).strip()

# Step 4d: 上边遍历(修改后)
for c in range(max_col, min_col - 1, -1):
    _add_pin(top_number_row, c, "top", max_col - c)

3.4 影响的其他边

左、下、右三边的布局在用户提供的 PinMAP 中是标准的Name 在 Number 内侧一列/一行。但为了一致性可以考虑对下边也增加类似检测Name 在 Number 上方 vs 下方),但当前未收到相关反馈,建议先从简处理,仅在 Top 边出现问题后扩展到其他边。

3.5 修改文件清单F013

文件 修改内容 风险
Code/src/pinmap_parser.py Step 2-3 之间增加 Top 边布局检测;修改上边 Name 查找和 Number 遍历
Code/src/test_pinmap.py 新增测试用例:用户 QFN60 格式的 PinMAP 解析

4. F014 分析 — PinList→PinMAP 样式模板应用

4.1 当前状态

v1.5.5 main.pyrun_list_to_map() 已经:

  1. 调用 _find_pinmap_template_path() 查找模板
  2. 调用 read_template_styles() 解析样式
  3. template_style 传递给 generate_pinmap()write_xlsx_with_style()

搜索路径v1.5.5 已修复):

# main.py _find_pinmap_template_path()
src_dir = os.path.dirname(os.path.abspath(__file__))   # → Code/src/
template_path = os.path.join(src_dir, "Template", "PinMAP-Template.xlsx")
# → Code/src/Template/PinMAP-Template.xlsx ✅

4.2 确认项

  1. 模板文件存在:Code/src/Template/PinMAP-Template.xlsx 已确认存在
  2. 搜索路径正确:优先查找 Code/src/Template/,向后兼容项目根目录和 cwd
  3. 样式提取完整:template_reader.py 提取字体 / 填充 / 边框 / 对齐 / 列宽 / 行高
  4. 样式应用正确:StyledXLSXWriter 将模板样式应用到输出

4.3 用户提到的"模板放在主程序根目录"

用户提到模板应放在"主程序根目录"。主程序根目录 = pinmap-to-pinlist/。当前代码优先查找 Code/src/Template/其次查找项目根目录(向后兼容)。

建议保持不变:当前的多路径回退策略已经覆盖了主程序根目录。如果用户坚持只从主程序根目录查找,可在评估后的实施阶段调整搜索优先级。但从工程角度看,Code/src/Template/ 更合理(与源码打包在一起)。

4.4 F014 结论

F014 在当前 v1.5.5 代码中已基本实现,无需大规模修改。需要确认的是:

  • 模板文件的内容是否符合用户期望(字体/边框/对齐/填充色等)
  • 确认项将在 F016 验证阶段通过实际生成的 xlsx 与预期对比来验证

5. F015 分析 — PinMAP→PinList 样式模板应用

5.1 当前状态

v1.5.5 main.pyrun_map_to_list() 已经:

  1. 调用 _find_pinlist_template_path() 查找模板
  2. 调用 read_template_styles() 解析样式
  3. 如果模板存在,使用 write_xlsx_with_style(),否则使用 write_xlsx()

搜索路径(同 F014

# Code/src/Template/PinList-Template.xlsx ✅

模板文件存在:Code/src/Template/PinList-Template.xlsx

5.2 注意事项

PinList 输出的数据非常简单两列A 列 = PinNameB 列 = Pin 序号),样式应用的效果主要是:

  • 字体名称/大小/颜色
  • 列宽(如果模板只有两列数据,列 C 以后理论上不应有宽度设置)
  • 行高
  • 边框

StyledXLSXWriter._sheet_xml()style.column_widths 字典读取列宽并生成 <cols> 元素。如果 PinList 模板中只有 A、B 两列定义了宽度,输出也会只有两列宽。

5.3 需要确认的潜在问题

StyledXLSXWriter_get_style_index() 方法为所有非 A1 单元格分配 style index 1(边框+居中。PinList 输出也是相同的逻辑——A1 用 style 2bold其他用 style 1。这对 PinList 两列布局来说是合理的。

但是PinList 的 A1 不是"封装信息"就是"Package Name",而 PinMAP 的 A1 也是封装信息。两个模板可能在 A1 样式的 fontId/fillId/borderId 上指向不同索引,但当前 _get_style_index() 统一用 hardcoded 的 index。这是一个潜在问题,但在用户明确反馈前不做假设性修改。

5.4 F015 结论

F015 在当前 v1.5.5 代码中已基本实现。确认项将在 F017 验证阶段通过实际生成的 PinList xlsx 与预期对比来验证。


6. F016 分析 — PinList→PinMAP 转换正确性验证

6.1 测试设计

使用用户提供的 QFN60 示例 PinList60 个引脚)作为输入,验证生成的 PinMAP 结构与示例 PinMAP 一致。

示例 PinList 结构

QFN60
Pin1,1
Pin2,2
...
Pin60,60

示例 PinMAP 预期结构(基于用户提供的 CSV

  • 12×12 网格QFN60 环形布局)
  • Left 边Pin1Pin12row 4-15, col A/B
  • Bottom 边Pin13Pin18 + Pin28Pin33row 16-17, 中间空列对应无引脚位置)
  • Right 边Pin34Pin45row 15→4, col 倒数两列)
  • Top 边Pin46Pin60row 3, col 倒数→前row 2 为 Numbers
  • 内部为空QFN 封装中心无引脚)

6.2 关键问题60 引脚的环形布局 ≠ 12×12 全周长

12×12 网格的全周长 = (12+12)×2 = 48。但 QFN60 有 60 个引脚。这意味着用户使用的"12×12 网格"并不是严格的矩形周长概念。

重新分析用户 PinMAP

  • Left 边12 个引脚Pin1Pin12
  • Right 边12 个引脚Pin34Pin45
  • Top 边15 个引脚Pin46Pin60跨越 15 列)
  • Bottom 边21 个引脚Pin13Pin33跨越 21 列?不对,重看)

仔细看用户实际 PinMAP 布局:

  • Left12 个
  • Bottom12 个Pin13Pin18=6 + Pin24Pin33?不对)

让我重新分析 CSV 模式:

  • Left col A/B12 pins (Pin1Pin12)
  • Right col 最后两列12 pins (Pin34Pin45)
  • Top row 2-315 pins (Pin46Pin60)
  • Bottom 倒数第1-2行15 pins? → 实际底部仅 Pin13Pin18=6 + ... 需要确认

实际上用户 CSV 格式是 12×1212行12列但只用了外圈。Pin 总计 60但网格如果按周长算只有 48。

这里存在根本性偏差:用户的 PinMAP 是"12×12 网格内有 60 个环形引脚"——引脚布局在 12×12 的外圈但某些角被占用。这意味着 PinMAP 布局不完全遵循四边等长逻辑

但这对 v1.6 不重要F016 和 F017 的目标是验证端到端转换正确性,即:

  1. List→MAP输入 60-pin PinList → 生成 PinMAP xlsx
  2. MAP→List将生成的 PinMAP 再转回 PinList
  3. 往返验证:原始 PinList == 生成的 PinList引脚不丢失、顺序不变

这将暴露 F013 修复后解析器是否能正确处理各种布局。

6.3 F016 测试方案

测试 F016-1: 60-pin List→MAP 基本生成

输入:

  • 60 个 PinListEntry (Pin1Pin60)
  • rows=12, cols=12
  • package_info="QFN60"

验证:

  • 生成的 PinMAP 至少包含 A1 封装信息 + 所有 60 个引脚的 Name 和 Number
  • 无单元格冲突(生成器内部保证)
  • 引脚沿四条边分布(取决于布局算法分配)

测试 F016-2: List→MAP→List 往返

输入:同上 60-pin PinList

验证:

  • List→MAP 生成 PinMAP xlsx
  • 将该 xlsx 作为 MAP→List 输入
  • 解析出的 PinList 包含 60 个引脚,顺序 Pin1Pin60封装信息 "QFN60"
  • 无引脚丢失、无序号错误

注意:不要求生成的 PinMAP 在单元格位置上与用户示例 PinMAP 完全一致。用户示例 PinMAP 是手工制作的(某些边有不同数量的引脚),而程序将使用标准的周长分配算法。只要往返一致、引脚不丢失即可。

6.4 但如果用户要求"结构一致"怎么办

features.md 中 F016 的验收标准写的是"生成的 PinMAP 与示例 PinMAP 结构完全一致"。这暗示用户希望:生成的 PinMAP 在外观布局上与示例 PinMAP 相同

如果是这样PinMAP 生成器需要支持非均匀边分配——即用户指定每条边分别有多少引脚。这是当前 pinmap_layout.py 不支持的(它假设 rows=cols 时每条边有相同数量的引脚)。

建议:在 v1.6 中先实现往返正确性验证作为 F016 的交付物。如果用户坚持布局像素级一致,需要在 v1.7 中重新设计布局引擎。


7. F017 分析 — PinMAP→PinList 转换正确性验证

7.1 测试设计

使用用户提供的 QFN60 示例 PinMAP (CSV) 作为输入,验证:

  1. 解析器能正确识别 Top 边(修复后)
  2. 生成的 PinList 包含完整的 60 个引脚
  3. Pin 序号 Pin1Pin60 完整无缺失
  4. 封装信息 "QFN60 ..." 正确提取
  5. PinName 与示例一致

7.2 测试用例构建

输入:用户提供的 QFN60 PinMAP CSV转换为 Excel 或直接用当前 xls_reader 兼容的格式)

由于当前解析器读取的是 Excel 格式(.xls/.xlsx需要先构建测试用的 cell dictionary。

测试 F017-1: QFN60 PinMAP 解析

基于用户提供的 CSV 构建 cells dict0-based row, col

cells = {
    (0, 0): "QFN60 6*6*0.85mm ...",
    # Top: Number row 1, Name row 2
    (1, 2): "60", (1, 3): "59", ..., (1, 16): "46",
    (2, 2): "Pin60", (2, 3): "Pin59", ..., (2, 16): "Pin46",
    # Left: rows 3..14
    (3, 0): "1",  (3, 1): "Pin1",
    ...
    # Bottom
    ...
    # Right
    ...
}

验证:

  • parse_pinmap(cells) 返回 60 个 Pin
  • Top 边的 Pin (Pin46Pin60) 都被正确识别且有正确的 edge="top"
  • 无 StructureError

测试 F017-2: QFN60 PinMAP→PinList 完整转换

从 parsed pinmap 生成 PinList验证

  • len(pinlist.rows) == 60
  • Pin 序号 1..60 全部存在
  • 封装信息正确

测试 F017-3: 往返验证 (MAP→List→MAP)

cells  parse_pinmap  pinmap
pinmap  generate_pinlist  pinlist (60 pins)
pinlist  [重新构造 entries]  generate_pinmap  pinmap2

验证 pinmappinmap2 的引脚数量和序号一致。


8. 总体修改方案与文件清单

8.1 F013 — 修复上方引脚丢失

文件 修改内容 工作量
Code/src/pinmap_parser.py 在 Step 2-3 之间增加 Top 边布局自动检测逻辑,根据数据内容决定 Name 在 Number 上方还是下方 中(~40 行新代码)
Code/src/pinmap_parser.py 修改 Step 3 上边 Name 查找,使用检测结果;修改 Step 4d 上边遍历,使用正确的 Number 行

8.2 F014 — PinList→PinMAP 模板(确认性检查)

文件 修改内容 工作量
Code/src/main.py 确认 _find_pinmap_template_path() 搜索路径正确v1.5.5 已修复) 无代码改动
Code/src/Template/PinMAP-Template.xlsx 确认模板文件存在且格式正确 无代码改动

8.3 F015 — PinMAP→PinList 模板(确认性检查)

文件 修改内容 工作量
Code/src/main.py 确认 _find_pinlist_template_path() 搜索路径正确v1.5.5 已修复) 无代码改动
Code/src/Template/PinList-Template.xlsx 确认模板文件存在且格式正确 无代码改动

8.4 F016 — List→MAP 验证

文件 修改内容 工作量
Code/src/test_pinmap.py 新增 QFN60 List→MAP 生成测试 + 往返测试 低(~60 行新测试代码)

8.5 F017 — MAP→List 验证

文件 修改内容 工作量
Code/src/test_pinmap.py 新增 QFN60 PinMAP 解析测试(使用 Top 布局 B+ 完整转换测试 + 往返测试 中(~100 行新测试代码 + 构建 QFN60 cells 常量)

9. 任务拆分建议

9.1 子任务划分

Seq 子任务 关联需求 执行 Agent 预估工作量 依赖
1 F013 编码实现:修复 pinmap_parser.py Top 边识别 F013 python-coding-agent 1h
2 F017 测试用例QFN60 PinMAP→PinList 解析+转换+往返测试 F017 test-qa-agent 30min Seq 1
3 F016 测试用例QFN60 PinList→PinMAP 生成+往返测试 F016 test-qa-agent 30min Seq 1
4 F014/F015 确认:模板路径+样式应用确认(如发现问题则修复) F014, F015 python-coding-agent 15min Seq 1
5 全量回归测试:运行全部测试用例确保无回归 F013-F017 test-qa-agent 15min Seq 2-4
6 文档生成:更新 features.md, tasks.md, CHANGELOG.md F013-F017 doc-gen-agent 15min Seq 5
7 打包发布 v1.6 F013-F017 package-release-agent 15min Seq 6

9.2 推荐执行顺序

Step 1: python-coding-agent → F013 编码pinmap_parser.py 修改)
                                ↓
Step 2: test-qa-agent → F017 测试用例(依赖修复后解析器)
                                ↓
Step 3: test-qa-agent → F016 测试用例(与 F017 并行)
                                ↓
Step 4: python-coding-agent → F014/F015 确认/修复(如有需要)
                                ↓
Step 5: test-qa-agent → 全量回归测试
                                ↓
Step 6: doc-gen-agent → 文档更新
                                ↓
Step 7: package-release-agent → 打包发布

9.3 可并行项

  • F016 测试用例Seq 3和 F017 测试用例Seq 2可以在 F013 编码完成后并行执行,因为它们都依赖 F013 修复但不相互依赖。
  • F014/F015 确认Seq 4可以与测试用例并行。

10. 风险与缓解措施

风险 ID 风险描述 影响 概率 缓解措施
R1 Top 边自动检测逻辑误判(如模板 PinMAP 中 Name 和 Number 行都是空或非常规格式) Top 边引脚仍然丢失 设置 70% 置信阈值 + 回退到默认行为;在检测失败时打印 WARN 日志
R2 用户 PinMAP 的底部Bottom边也存在类似反转问题但尚未反馈 底部引脚也丢失 如果 F017 测试发现底部也有问题,在 v1.6 中一并修复(扩大自动检测范围到下边)
R3 用户期望 PinMAP 布局与示例完全一致(像素级),但当前算法是均匀分配 用户不满意生成的 PinMAP 外观 在 F016 的实现中明确声明"往返正确性验证",布局一致性留到 v1.7
R4 F013 的修改改变了现有 4×4/12-pin 测试的预期行为 回归测试失败 自动检测会选择布局 A与 v1.5.5 一致的 Name 在上方),对现有测试透明
R5已关闭 QFN60 12×12 网格周长48与 60 引脚不匹配 已确认 QFN60 是 15×15 网格,周长 = (15+15)×2 = 60完美匹配

11. v1.6 与 v1.5.5 代码差异预估

11.1 新增代码

位置 内容 行数
pinmap_parser.py Step 2.5 Top 边布局自动检测函数 _detect_top_layout() ~30 行
pinmap_parser.py Step 3 修改上边 Name 查找(替换现有 5 行) +5 行
pinmap_parser.py Step 4d 修改上边遍历(替换现有 2 行) +2 行
test_pinmap.py QFN60 cells 常量(~60 pins, 12×12 ~80 行
test_pinmap.py F017 测试函数 (解析 + 转换 + 往返) ~60 行
test_pinmap.py F016 测试函数 (生成 + 往返) ~40 行

11.2 预计不修改的文件

  • main.py — 模板搜索路径已在 v1.5.5 修复(除非用户坚持改为项目根目录优先)
  • pinmap_layout.py — List→MAP 生成布局不变
  • pinmap_generator.py — 无变化
  • pinlist_generator.py — 无变化
  • template_reader.py — 无变化
  • xlsx_writer.py — 无变化
  • validator.py — 无变化
  • pinlist_parser.py — 无变化
  • pinlist_validator.py — 无变化

11.3 总工作量预估

阶段 预估时间
编码F013 1.0 h
测试F016 + F017 0.75 h
确认/修复F014 + F015 0.25 h
回归测试 0.25 h
文档 0.25 h
打包 0.25 h
合计 ~2.75 h

12. 总结

  1. F013最关键pinmap_parser.py 硬编码假设 Top 边 Name 在 Number 上方一行,但用户真实 PinMAP 中 Name 在 Number 下方一行。需要增加基于数据内容的自动布局检测,兼容两种方向。修改集中在 pinmap_parser.py 一个文件。

  2. F014/F015已有基础:模板搜索路径在 v1.5.5 中已修复(Code/src/Template/样式应用链路完整。v1.6 主要是确认性验证,代码改动预计为零。

  3. F016/F017新增测试:需要构建 QFN60 60-pin 的测试数据用于端到端验证。核心关注往返正确性List→MAP→List 不丢失引脚),而非与用户示例的像素级布局一致(后者需要后续版本支持非均匀边分配)。

  4. 最大风险 R560 引脚与 12×12 网格的周长48不匹配。需要在测试实施阶段确认正确的行/列参数。如果用户 PinMAP 实际使用的是非标准布局(某些边有不同数量的引脚),可能需要向用户确认。


文档结束 — v1.6 整改架构评估