from pathlib import Path

from openpyxl import Workbook
from openpyxl.formatting.rule import FormulaRule
from openpyxl.styles import Alignment, Font, PatternFill, Side
from openpyxl.utils import get_column_letter


OUTPUT = Path("e2e/tests/丸掌柜丸友集授权简化/丸掌柜丸友集授权简化_测试点及自动化用例.xlsx")

FEATURE_POINTS = [
    ("FP-001", "菜单与迁移", "旧授权页下线与数据迁移", "旧页面入口不可访问；原生效中授权同步到新授权列表且状态为已授权", "P0", "自动化"),
    ("FP-002", "丸掌柜授权页", "菜单与Tab", "工作室授权菜单可访问，包含工作室推荐、工作室授权、待我审核三个Tab", "P0", "自动化"),
    ("FP-003", "丸友集授权页", "菜单与Tab", "发单商户授权菜单可访问，包含发单商户推荐、发单商户授权、待我审核三个Tab", "P0", "自动化"),
    ("FP-004", "推荐列表", "展示范围", "仅展示开启对外展示的合作方；推荐Tab中展示可申请记录", "P0", "自动化"),
    ("FP-005", "授权列表", "展示范围", "授权Tab仅展示发生过授权关系的审核中、已授权、已拒绝、已关闭记录，不展示可申请", "P0", "自动化"),
    ("FP-006", "待我审核", "展示范围", "仅展示需要当前登录方审核的对向申请；无关申请不可见", "P0", "自动化"),
    ("FP-007", "推荐列表", "排序", "Admin 配置置顶、推荐、评分后，前台按置顶优先、推荐优先、评分倒序排序", "P1", "自动化"),
    ("FP-008", "推荐列表", "评分展示", "用户侧仅展示评分，不展示置顶/推荐后台标识", "P1", "自动化"),
    ("FP-009", "丸掌柜申请", "申请推单", "丸掌柜可对可申请工作室发起申请推单，目标工作室进入待我审核，申请方状态为审核中", "P0", "自动化"),
    ("FP-010", "丸友集申请", "申请接单", "丸友集可对可申请发单商户发起申请接单，目标商户进入待我审核，申请方状态为审核中", "P0", "自动化"),
    ("FP-011", "审核", "同意申请", "待我审核中同意后，双方授权列表均更新为已授权", "P0", "自动化"),
    ("FP-012", "审核", "拒绝申请", "待我审核中拒绝后，双方授权列表均更新为已拒绝，对方可再次申请", "P0", "自动化"),
    ("FP-013", "授权状态", "关闭授权", "已授权关系可关闭；关闭后双方状态为已关闭，且不可作为可发单协作关系", "P0", "自动化"),
    ("FP-014", "授权状态", "状态隔离", "审核中/已拒绝/已关闭关系均不可用于供应链默认发单和自动推单策略", "P0", "自动化"),
    ("FP-015", "联系配置", "入口与弹窗", "授权列表右上角存在联系方法配置入口；点击打开配置弹窗", "P1", "自动化"),
    ("FP-016", "联系配置", "保存与展示", "双方保存联系方法后，对方在申请、审核及协作场景可查看最新配置", "P1", "自动化"),
    ("FP-017", "联系配置", "保存交互", "联系人、联系手机、微信号、服务时段编辑后可保存、取消不保存且再次打开正确回显", "P1", "自动化"),
    ("FP-018", "列表检索", "空态与加载", "筛选无结果时正确展示空态；多条结果的分页/加载不丢失筛选条件和记录", "P1", "自动化"),
    ("FP-019", "供应链", "授权同步", "授权成功的全部丸友集自动出现在供应链授权列表，默认可发单，无需二次授权", "P0", "自动化"),
    ("FP-020", "供应链", "名称同步", "供应链列表展示工作室名称和主体；工作室改名后列表名称同步更新", "P1", "自动化"),
    ("FP-021", "供应链筛选", "默认值", "供应链筛选默认选中丸友集", "P1", "自动化"),
    ("FP-022", "供应链筛选", "前置校验", "未选择供应链即按工作室名称筛选时提示请先选择供应链，且供应链筛选框标红", "P1", "自动化"),
    ("FP-023", "推单策略", "自动生成", "每个已授权工作室自动生成一条指定工作室推单策略，策略名称为工作室名称", "P0", "自动化"),
    ("FP-024", "推单策略", "授权变更联动", "新增授权后创建对应策略；关闭授权后策略可用性按产品规则校验", "P1", "需产品确认关闭后策略规则"),
    ("FP-025", "推单策略", "工作室选择", "支持一键全选；列表最多显示5行，悬停浮层可查看更多", "P1", "自动化"),
    ("FP-026", "Admin", "默认供应链", "开通丸掌柜时默认开通所有供应链", "P0", "自动化"),
    ("FP-027", "Admin", "关闭供应链", "运营可关闭某个供应链；前台可用范围与后台关闭结果一致", "P0", "自动化"),
    ("FP-028", "权限与异常", "重复/并发申请", "同一合作关系重复提交、双方同时提交时无重复授权记录，状态一致", "P1", "自动化"),
    ("FP-029", "权限与异常", "访问控制", "未开通对应产品、无菜单权限或非主体账号不可越权查看/审核/关闭授权", "P1", "自动化"),
    ("FP-030", "对外展示配置", "展示名称规则", "提测文档要求可保存展示名称；旧PRD要求移除展示名称/标题并直接取商户名称，二者冲突，测试前必须确认最终规则", "P0", "待需求确认"),
    ("FP-031", "丸掌柜授权列表", "列表字段", "工作室名称、工作室主体、联系方式、授权状态、最近申请、操作字段均正确展示", "P0", "自动化"),
    ("FP-032", "丸友集授权列表", "列表字段", "商户名称、商户主体、联系方式、授权状态、最近申请、操作字段均正确展示", "P0", "自动化"),
    ("FP-033", "授权列表", "最近申请", "最近申请展示最近一次申请方向及申请时间；新一次申请后按最新记录更新", "P1", "自动化"),
    ("FP-034", "授权列表筛选", "丸掌柜多条件检索", "支持按工作室名称、工作室主体、手机号、联系人搜索，并支持按授权状态筛选", "P1", "自动化"),
    ("FP-035", "授权列表筛选", "丸友集多条件检索", "支持按商户名称、商户主体、手机号、联系人搜索，并支持按授权状态筛选", "P1", "自动化"),
    ("FP-036", "联系配置", "配置字段", "联系方法配置弹窗包含联系人、联系手机、微信号、服务时段四个字段，并按保存结果回显", "P0", "自动化"),
    ("FP-037", "联系配置", "手机格式", "联系手机为空、合法手机号、非法长度/字符等输入按产品校验，保存失败不污染已保存数据", "P1", "自动化"),
    ("FP-038", "授权状态", "审核中防重", "当前账号发起的审核中申请仅显示等待审核，不可重复申请", "P0", "自动化"),
    ("FP-039", "授权状态", "待我审核隔离", "对方发起的待我审核记录仅出现在待我审核Tab，不在授权Tab展示", "P0", "自动化"),
    ("FP-040", "授权状态", "重新开启权限", "已关闭关系可重新开启授权，且仅最初发起申请的一方有此操作权限", "P0", "自动化"),
    ("FP-041", "授权状态", "重新开启流转", "发起方重新开启已关闭授权后，双方关系恢复已授权并恢复协作资格", "P0", "自动化"),
    ("FP-042", "供应链", "二次授权豁免范围", "仅丸友集的已授权合作关系免填写信息二次授权；代练丸子及其他外部代练平台仍按原规则填写信息授权", "P0", "自动化"),
    ("FP-043", "供应链", "授权范围一致性", "供应链列表包含所有且仅包含授权成功的丸友集；审核中、拒绝、关闭和未授权工作室不出现/不可发单", "P0", "自动化"),
    ("FP-044", "推单策略", "策略类型与对象", "自动生成策略为指定工作室策略，供应链为丸友集，授权商户号为对应单个工作室", "P0", "自动化"),
    ("FP-045", "推单策略", "创建幂等", "对同一工作室的授权同步/重复事件不产生重复同名自动策略", "P1", "自动化"),
    ("FP-046", "推单策略", "选项范围", "授权商户号下拉仅可选已授权工作室；选择全部后与全部可用工作室一致", "P1", "自动化"),
    ("FP-047", "Admin推荐配置", "配置项生效", "Admin 的评分编辑、推荐状态、置顶状态保存后立即影响前台推荐排序", "P1", "自动化"),
    ("FP-048", "Admin供应链", "后台入口变更", "商户供应链管理保留，供应链授权入口下线；默认开通和单项关闭在保留入口中生效", "P1", "自动化"),
    ("FP-049", "展示边界", "对外展示开关", "关闭对外展示的商户/工作室不进入对方推荐列表；重新开启后可按排序规则出现", "P0", "自动化"),
    ("FP-050", "状态与数据一致性", "双端一致性", "每次申请、审核、关闭、重开后，两端记录的关系状态、联系人信息、最近申请方向与时间一致", "P0", "自动化"),
    ("FP-051", "对外展示配置", "丸掌柜资料维护", "首次进入可查看当前配置；未配置为空态；保存、修改、重新进入均正确回显；不能修改其他商户数据", "P0", "自动化"),
    ("FP-052", "对外展示配置", "展示资料字段", "按最终确认规则校验展示名称/商户名称、简介、擅长游戏、结算方式、联系人和联系方式的保存、修改、回显及对方可见", "P0", "自动化"),
    ("FP-053", "对外展示配置", "丸友集候选影响", "工作室关闭对外展示后不再进入丸掌柜候选列表；已有已授权关系保留，仅影响新候选与新申请", "P0", "自动化"),
    ("FP-054", "关闭授权", "关联配置失效", "关闭已授权关系后，对应供应链授权和发单策略同步失效，不能再用于新发单", "P0", "自动化"),
    ("FP-055", "历史授权迁移", "迁移范围", "仅原授权管理中已生效授权迁入新模型，并同步工作室授权和供应链配置", "P0", "自动化"),
    ("FP-056", "历史授权迁移", "迁移结果对照", "迁移完成生成结果表；源数据、新授权、供应链配置逐条可对照，失败数据可定位", "P0", "自动化"),
    ("FP-057", "历史授权迁移", "迁移幂等", "重复调用迁移接口不产生重复授权关系或重复供应链配置", "P0", "自动化"),
    ("FP-058", "策略配置", "授权对象可选性", "授权通过后可在策略配置选择对应工作室、保存并回显；未授权工作室不可选", "P0", "自动化"),
    ("FP-059", "WYJ新发单", "授权状态拦截", "仅已授权工作室允许创建WYJ新订单；审核中、已拒绝、已关闭、未申请均拦截且提示清晰", "P0", "自动化"),
    ("FP-060", "WYJ新发单", "多发子单校验", "多工作室/多子单推送时，每个实际子单均依据其目标工作室的当前授权状态独立校验", "P0", "自动化"),
    ("FP-061", "WYJ新发单", "新旧授权切换", "WYJ新发单只依赖新双边授权模型，不依赖旧授权码、license或appSecret", "P0", "自动化"),
    ("FP-062", "发单回归", "非WYJ供应链不受影响", "丸子及其他非WYJ供应链仍可按原规则发单，不能被WYJ新授权校验误拦截", "P0", "自动化"),
    ("FP-063", "存量商户补偿", "供应链服务初始化", "存量丸掌柜调用服务补偿后，丸友集、丸掌柜、一起玩供应链/服务均开通，且生成结果表", "P0", "自动化"),
    ("FP-064", "存量商户补偿", "补偿可追溯与幂等", "补偿结果可逐条对照、失败可追踪；重复调用不产生重复服务或供应链配置", "P0", "自动化"),
    ("FP-065", "订阅自动初始化", "订阅触发", "新商户订阅开通丸掌柜成功后自动触发供应链和服务初始化，无需人工补偿", "P0", "自动化"),
    ("FP-066", "订阅自动初始化", "初始化可靠性", "重复订阅消息不产生重复配置；初始化失败日志可追踪并支持重试", "P0", "自动化"),
    ("FP-067", "影响范围", "旧授权页面下线", "原license授权信息页面/后台耦合路径下线或不再作为新发单依据；新双边授权页面承接业务", "P1", "自动化"),
    ("FP-068", "范围控制", "非本次范围回归", "订阅取消、订阅到期不影响现有双边授权；存量订单售后/撤销/验收/申诉/结算与大厅多工作室模式不纳入本次功能变更", "P2", "手工回归"),
]

CASES = [
    ("AUTO-AUTH-001", "历史生效授权迁移", "丸掌柜、丸友集存在旧授权页生效中关系", "发布新版本后进入双方新授权页", "双方授权Tab均存在对应关系且状态已授权；旧入口下线", "FP-001", "P0", "双账号"),
    ("AUTO-AUTH-002", "丸掌柜申请推单-工作室同意", "丸掌柜与对外展示工作室无授权关系", "丸掌柜推荐Tab申请推单；工作室待我审核同意；双方回查", "双方状态由可申请/审核中变为已授权；出现供应链记录和同名指定工作室策略", "FP-004,FP-006,FP-009,FP-011,FP-019,FP-023", "P0", "双账号"),
    ("AUTO-AUTH-003", "丸友集申请接单-商户同意", "丸友集与对外展示商户无授权关系", "丸友集推荐Tab申请接单；商户待我审核同意；双方回查", "双方状态变已授权；供应链与策略自动同步", "FP-003,FP-004,FP-006,FP-010,FP-011,FP-019,FP-023", "P0", "双账号"),
    ("AUTO-AUTH-004", "申请拒绝与重新申请", "存在待审核申请", "审核方拒绝；申请方确认已拒绝；再次发起申请", "拒绝后双方状态已拒绝，可重新申请并重新进入审核中", "FP-012", "P0", "双账号"),
    ("AUTO-AUTH-005", "关闭授权及协作隔离", "双方已授权且供应链、策略已生成", "任一方关闭授权；回查双方授权、供应链和策略可用性", "双方已关闭；关闭关系不再用于默认可发单或自动化协作", "FP-013,FP-014,FP-024", "P0", "双账号"),
    ("AUTO-AUTH-006", "Tab数据隔离", "准备可申请、审核中、已授权、已拒绝、已关闭及非当前方审核数据", "分别打开推荐、授权、待我审核Tab", "两端菜单及三个Tab均可访问；各Tab仅展示规定数据集合，无关待审数据不可见", "FP-002,FP-003,FP-004,FP-005,FP-006", "P0", "双账号"),
    ("AUTO-AUTH-007", "推荐排序与前台隐藏配置", "Admin配置多条记录的置顶、推荐、评分", "打开两端推荐列表，记录顺序和展示字段", "顺序为置顶、推荐、评分倒序；仅评分对用户可见", "FP-007,FP-008", "P1", "Admin+双账号"),
    ("AUTO-AUTH-008", "联系方法配置及对方可见", "双方可进入授权列表", "丸掌柜保存联系方法；取消修改后重开确认未保存；丸友集在申请/审核详情查看；反向执行", "入口与弹窗可用，保存后对方展示最新信息；取消不改变已保存数据", "FP-015,FP-016,FP-017", "P1", "双账号"),
    ("AUTO-AUTH-009", "供应链名称同步与筛选", "已授权工作室存在，且可改名", "改工作室名称；进入供应链列表；验证默认筛选；不选供应链直接搜索", "名称和主体同步；默认丸友集；提示请先选择供应链且筛选框标红", "FP-020,FP-021,FP-022", "P1", "双账号"),
    ("AUTO-AUTH-010", "推单策略展示与全选", "存在6家以上已授权工作室", "打开策略配置，触发全选并查看列表第6项", "全选生效；列表最多5行；悬停可查看更多；策略名称与工作室名一致", "FP-023,FP-025", "P1", "单账号"),
    ("AUTO-AUTH-011", "丸掌柜开通默认供应链与后台关闭", "待开通丸掌柜的商户；Admin可操作供应链", "开通丸掌柜；检查供应链；Admin关闭其中一项；回查前台", "开通后默认全开；关闭项在前台不可用/不可见，其他项正常", "FP-026,FP-027", "P0", "Admin+单账号"),
    ("AUTO-AUTH-012", "重复与并发申请防重", "双方无授权关系，可分别发起申请", "同方重复点击申请；双方近同时申请；回查记录", "仅保留一条关系，不产生重复待审/授权记录，双方状态一致", "FP-028", "P1", "双账号"),
    ("AUTO-AUTH-013", "权限控制", "准备无菜单权限、未开通产品、非主体账号", "尝试访问授权页、申请、审核和关闭", "无权限用户不能执行越权操作，接口和页面均受控", "FP-029", "P1", "多账号"),
    ("AUTO-AUTH-014", "配置名称简化与列表字段", "准备丸掌柜及丸友集主体，并配置对外展示", "进入对外展示配置和两端授权列表；修改商户名称后回查", "无展示名称/标题字段；对外名称取商户名称；双方列表字段完整且名称同步", "FP-030,FP-031,FP-032", "P0", "双账号"),
    ("AUTO-AUTH-015", "授权列表五维筛选与最近申请", "存在名称、主体、联系人、手机号、状态不同的多条关系，且数量超过单页", "两端逐一按4个文本条件和授权状态筛选；执行无结果查询和翻页；产生新申请后回查最近申请", "每项筛选仅返回匹配记录；无结果正确空态；翻页后筛选条件保持；最近申请方向与时间更新且双端一致", "FP-018,FP-033,FP-034,FP-035,FP-050", "P1", "双账号"),
    ("AUTO-AUTH-016", "联系方法字段与校验", "双方可打开联系方法配置", "依次填联系人、手机、微信、服务时段保存；再输入非法手机保存", "四字段均回显给对方；非法输入被拦截且不覆盖旧数据", "FP-036,FP-037", "P0", "双账号"),
    ("AUTO-AUTH-017", "审核中与待我审核Tab边界", "A 向 B 发起申请", "A 查看授权Tab和推荐Tab；B 查看授权Tab与待我审核Tab；A 再点击申请", "A 显示审核中且不可重复申请；B 待审记录只在待我审核Tab", "FP-005,FP-006,FP-038,FP-039", "P0", "双账号"),
    ("AUTO-AUTH-018", "关闭后重开授权的发起方权限", "A 发起并获批的已授权关系", "A 关闭；B 尝试重开；A 重开；双方回查供应链和策略", "仅 A 可重开；重开后状态已授权并恢复协作资格", "FP-040,FP-041,FP-050", "P0", "双账号"),
    ("AUTO-AUTH-019", "丸友集供应链二次授权豁免边界", "准备已授权丸友集、外部代练平台及未授权丸友集", "进入供应链授权/发单配置，分别选择三类对象", "仅已授权丸友集默认可发单且无需填授权信息；外部平台仍需填写；未授权对象不可用", "FP-019,FP-042,FP-043", "P0", "单账号"),
    ("AUTO-AUTH-020", "自动策略属性、幂等与授权范围", "新建一个可授权工作室且无同名策略", "完成授权；读取新策略属性；重复触发同步；打开策略授权商户号下拉", "生成一条指定工作室/丸友集/对应工作室的策略；不重复生成；下拉仅有已授权工作室", "FP-023,FP-044,FP-045,FP-046", "P0", "双账号"),
    ("AUTO-AUTH-021", "对外展示开关与Admin推荐配置", "Admin 可配置目标的对外展示、置顶、推荐、评分", "依次关闭/开启对外展示，设置评分、推荐、置顶后查看前台", "关闭时前台不可见；开启后出现；排序按置顶、推荐、评分倒序，配置变更即时生效", "FP-004,FP-007,FP-047,FP-049", "P0", "Admin+双账号"),
    ("AUTO-AUTH-022", "Admin供应链入口保留与单项关闭", "丸掌柜已开通，Admin可管理供应链", "检查后台菜单；在商户供应链管理关闭一条丸友集供应链并访问旧供应链授权入口", "商户供应链管理可用；旧供应链授权入口下线；关闭项前台不可发单", "FP-026,FP-027,FP-048", "P1", "Admin+单账号"),
    ("AUTO-AUTH-023", "双端对外展示配置全流程", "丸掌柜和丸友集工作室均可进入展示配置", "验证空态；保存资料；刷新回显；修改；关闭/开启展示；尝试跨主体访问", "资料可保存、回显、修改；关闭后从对方候选移除但既有授权保留；不可跨主体操作", "FP-051,FP-052,FP-053", "P0", "双账号"),
    ("AUTO-AUTH-024", "关闭授权后配置及新单失效", "双方已授权，供应链和策略均可用", "关闭授权；检查供应链、策略；用原策略创建WYJ新单；重新申请并审核通过后重试", "关闭后关联配置失效且新单被拦截；重新授权成功后恢复可用", "FP-013,FP-054,FP-059", "P0", "双账号"),
    ("AUTO-AUTH-025", "历史授权迁移与幂等", "准备旧模型已生效、非生效和异常授权数据；可调用迁移接口", "调用迁移；读取新关系、供应链配置和结果表；再次调用迁移", "仅已生效数据迁入；结果可对照并可追踪失败；重复迁移不产生重复数据", "FP-001,FP-055,FP-056,FP-057", "P0", "接口+双账号"),
    ("AUTO-AUTH-026", "策略配置授权范围", "存在一个已授权和一个未授权丸友集工作室", "新建指定工作室策略；查看下拉；选择已授权工作室保存并重新进入；尝试选择未授权工作室", "已授权工作室可选且策略正确回显；未授权工作室不能选择；关闭后策略不可新发单", "FP-058,FP-054", "P0", "单账号"),
    ("AUTO-AUTH-027", "WYJ新发单授权状态矩阵", "准备已授权、审核中、已拒绝、已关闭、未申请的工作室及策略", "分别针对五种状态创建WYJ新单，记录页面与接口结果", "仅已授权成功；其余四种均失败且提示清晰", "FP-059,FP-061", "P0", "双账号"),
    ("AUTO-AUTH-028", "WYJ多子单与非WYJ回归", "准备多工作室发单数据，其中至少一方非已授权；同时有非WYJ供应链", "发起多子单推送；再通过非WYJ供应链发单", "每个子单独立按目标授权判断；非WYJ发单不受新校验影响", "FP-060,FP-062", "P0", "单账号"),
    ("AUTO-AUTH-029", "存量丸掌柜服务补偿", "准备历史已开通丸掌柜商户；可调用initMerchantSupply接口", "调用补偿；查询商户服务、供应链配置和结果表；重复调用", "丸友集、丸掌柜、一起玩服务均完整；结果可对照；重复调用无重复配置", "FP-063,FP-064", "P0", "接口+Admin"),
    ("AUTO-AUTH-030", "新订阅自动初始化与失败追踪", "准备未开通丸掌柜的新商户；可观察订阅消息和日志", "完成订阅；等待异步任务；检查服务/供应链；重放消息；构造失败并检查日志与重试", "订阅自动初始化；重放幂等；失败可追踪并可恢复", "FP-065,FP-066", "P0", "订阅链路+Admin"),
    ("AUTO-AUTH-031", "新旧页面及非改造范围回归", "存在旧授权入口、现有已授权关系和订阅状态变化条件", "访问旧页面和新页面；验证新订单不读取旧凭据；执行取消/到期后回查双边授权", "旧路径不承接新发单；新模型生效；取消/到期不影响现有双边授权", "FP-067,FP-068", "P1", "单账号+接口"),
]

DETAILED_CASES = [
    ("DT-001", "丸掌柜对外展示配置保存、回显与隔离", "丸掌柜商户A、商户B均可登录；A有配置入口", "展示名称规则以产品最终确认结论为准；简介、游戏、结算方式、联系人、手机、微信、服务时段", "1. 以A登录，进入工作室授权-展示配置。\n2. 首次未配置时核对空态和保存入口。\n3. 填写全部展示资料并保存。\n4. 刷新或退出后重进，逐项核对回显。\n5. 修改两项资料并保存，再次重进核对最新值。\n6. 切换为B登录，尝试通过页面/接口查看或修改A配置。", "A资料保存、修改、回显一致；B无法读取或修改A私有配置；展示名称字段是否出现按需求确认结论验收。", "保存前后截图、接口请求/响应、A/B主体标识"),
    ("DT-002", "展示开关对候选与既有授权的影响", "A与工作室W已授权；另有未授权且开启展示的工作室W2", "A、W、W2的展示开关和授权状态", "1. A进入工作室推荐，确认W2可见且可申请。\n2. W2关闭对外展示。\n3. A刷新推荐列表并按名称搜索W2。\n4. A回查与W的已授权记录和发单能力。\n5. W2重新开启展示，回查推荐列表。", "关闭展示后W2不在候选/不可申请；既有W授权不丢失；重新开启后W2按排序规则恢复候选。", "推荐列表截图、授权列表截图、筛选结果"),
    ("DT-003", "丸掌柜发起申请及审核中防重", "丸掌柜A和开启展示的丸友集工作室W无授权关系", "W名称、联系方式、主体", "1. A进入工作室推荐，按名称/主体/联系人/手机号筛选W。\n2. 打开W详情，核对展示资料和联系方式。\n3. 点击申请推单并确认。\n4. 刷新页面，核对状态和最近申请方向/时间。\n5. 再次点击申请，或并发提交同一申请。\n6. W登录，进入待我审核查看申请。", "A显示审核中/待审核且不能重复生成记录；W仅在待我审核看到该申请；双方最近申请信息一致。", "申请ID、双端列表截图、重复点击提示、接口记录数"),
    ("DT-004", "丸友集审核通过后的授权、供应链和策略联动", "DT-003申请处于待我审核", "申请ID、目标工作室W", "1. W进入待我审核，核对申请方展示资料。\n2. 点击同意并确认。\n3. A和W分别进入授权Tab，核对状态已授权。\n4. A进入供应链列表，核对W已同步且默认可发单。\n5. A进入策略配置，核对W可选及自动策略/指定工作室策略属性。\n6. 用该策略创建WYJ新订单。", "双端均已授权；供应链和策略可用；使用W的WYJ新单创建成功。", "双端状态、供应链记录、策略详情、订单号"),
    ("DT-005", "审核拒绝与重新申请", "存在A对W的待审核申请", "申请ID", "1. W在待我审核点击拒绝。\n2. A、W分别刷新授权列表。\n3. A核对状态已拒绝及可重新申请按钮。\n4. A重新发起申请。\n5. W核对新待审记录和最近申请时间。", "双方状态一致为已拒绝；拒绝状态不可发单；重新申请产生新的待审流程而不覆盖历史追溯信息。", "拒绝操作记录、重申请记录、订单创建拦截截图"),
    ("DT-006", "关闭授权、失效与重新授权", "A和W已授权，且有可用供应链和策略", "授权关系、策略ID", "1. 任选有权限的一方关闭授权并确认。\n2. 双端回查状态已关闭。\n3. A检查供应链和策略状态。\n4. A用原策略创建WYJ新单。\n5. 按最终规则重新申请/重新开启并由对方审核通过。\n6. 再次创建WYJ新单。", "关闭后供应链/策略失效，新单被拦截；重新审核通过后恢复可发单。重开权限以产品确认规则验收。", "状态变更、策略状态、失败提示、恢复后的订单号"),
    ("DT-007", "历史有效授权迁移与结果对照", "准备旧授权模型：已生效、未生效、异常数据；具备migrateLicense接口权限", "旧授权主键、商户、工作室、预期供应链配置", "1. 记录迁移前源数据基线。\n2. 调用migrateLicense迁移接口。\n3. 查询新双边授权、供应链配置和迁移结果表。\n4. 逐条对照已生效源授权与新关系。\n5. 检查未生效源数据未误迁。\n6. 再次调用接口并比较记录数。", "仅有效授权迁入并可发单；供应链同步；结果表可追踪失败；重复迁移不产生重复记录。", "接口响应、迁移结果表、源/目标对照、重复调用前后计数"),
    ("DT-008", "策略配置可选范围与回显", "A至少有一个已授权工作室W和一个未授权工作室U", "W、U、策略名称", "1. A进入发单策略配置，新建指定工作室策略。\n2. 选择丸友集供应链。\n3. 打开授权商户号下拉，记录选项。\n4. 选择W，填写必填项后保存。\n5. 重新打开策略核对名称、供应链、工作室和状态。\n6. 尝试通过UI和接口选择U。", "W可选且保存后完整回显；U不可选择/保存被拦截；关闭授权后该策略不可新发单。", "下拉选项、策略详情、非法提交响应"),
    ("DT-009", "WYJ新发单授权状态矩阵", "为五个工作室准备已授权、审核中、已拒绝、已关闭、未申请状态和相应订单数据", "五个工作室、统一订单模板", "1. 分别指定五个工作室创建WYJ新订单。\n2. 记录页面提示、请求响应和订单落库结果。\n3. 对已授权工作室继续完成推单。\n4. 对四个非已授权状态核对未产生有效订单/子单。", "仅已授权成功；审核中、拒绝、关闭、未申请全部拦截且提示明确。", "五组结果表、订单号/子单号、拦截提示"),
    ("DT-010", "WYJ多子单独立授权校验与非WYJ回归", "多发策略含多个目标工作室，其中至少一个非已授权；同时有丸子或其他非WYJ供应链", "多子单策略、非WYJ订单", "1. 通过多发策略发起订单。\n2. 逐个检查子单的目标工作室和创建结果。\n3. 通过非WYJ供应链创建相同类型订单。\n4. 检查WYJ新单请求未传/未校验旧授权码、license、appSecret。", "每个WYJ子单独立校验目标授权；非WYJ链路不受影响；WYJ新单不依赖旧凭据。", "子单明细、非WYJ订单号、请求日志/链路日志"),
    ("DT-011", "存量丸掌柜服务补偿", "存量已开通丸掌柜商户M；具备initMerchantSupply接口权限", "商户M、补偿前服务清单", "1. 记录补偿前供应链和服务。\n2. 调用initMerchantSupply。\n3. 查询M的商户服务、供应链配置及初始化结果表。\n4. 核对丸友集、丸掌柜、一起玩均已开通。\n5. 重复调用并检查数据计数。\n6. 人为准备失败样本并核对结果可追踪。", "三类服务/供应链完整；结果可对照；重复调用幂等；失败可定位。", "接口响应、服务清单、初始化结果表、前后计数"),
    ("DT-012", "新订阅自动初始化、幂等与失败恢复", "新商户N未开通丸掌柜；可查看订阅消息/初始化日志", "商户N、订阅单号、消息ID", "1. 完成N的丸掌柜订阅开通。\n2. 等待异步初始化完成。\n3. 登录N，核对供应链和服务。\n4. 执行一次授权申请、策略配置和发单冒烟。\n5. 重放同一订阅消息。\n6. 模拟初始化失败，检查日志并执行重试。", "无需人工补偿即可初始化；后续链路可用；消息重放无重复配置；失败日志含可检索关联信息且重试可恢复。", "订阅单、消息ID、初始化日志、服务清单、冒烟订单号"),
    ("DT-013", "Admin推荐排序与用户侧可见性", "至少三条展示记录，Admin可设置评分、推荐和置顶", "三个对象及评分/推荐/置顶组合", "1. 在Admin设置不同评分、推荐、置顶组合并保存。\n2. 进入丸掌柜和丸友集推荐列表。\n3. 记录排序和用户可见字段。\n4. 修改一条配置后刷新前台。", "前台按置顶、推荐、评分倒序；用户仅见允许展示的评分/资料；配置变更正确生效。", "Admin配置截图、两端列表排序截图"),
    ("DT-014", "新旧入口切换与订阅生命周期不影响授权", "已有双边已授权关系，且可模拟订阅取消/到期", "授权关系、订阅状态", "1. 访问旧license授权入口及新双边授权入口。\n2. 验证新WYJ发单只通过新关系判断。\n3. 对订阅执行取消或到期模拟。\n4. 回查双边授权状态、列表和发单资格。", "旧页面不再作为新发单授权依据；取消/到期不改变现有双边授权模型。", "页面访问结果、发单请求、订阅状态与授权状态对照"),
]

AUTOMATION_FLOW_CASES = [
    (
        "AUTO-FLOW-AUTH-001",
        "新建丸友集工作室对外展示配置在丸掌柜与SaaS-admin双端可见",
        "P0",
        "已生成脚本，待测试环境首跑",
        "测试环境；SMS/图形验证码可用；SaaS-admin账号可用；固定丸掌柜账号19159770995可登录且具备工作室授权新菜单权限。",
        "企业名称：E2E授权展示_{时间戳}；注册手机号：运行时新生成；简介：E2E自动化展示简介；擅长游戏：至少选择1项；结算周期：月结；联系人/手机/微信号/QQ号：运行时唯一值；二维码：使用运行时PNG测试文件。",
        "1. 使用企业注册与认证既有流程创建新的主账号，并记录手机号、企业名称、商户ID。\n2. 登录SaaS-admin，进入商户管理-商户列表新，查询该企业并打开查看订阅；点击指定开通，精确选择产品丸友集和版本内测版后提交。\n3. 重新打开查看订阅，断言当前生效订阅展示丸友集-内测版；租户端登录后断言丸友集已开通。\n4. 登录新建企业，进入丸友集-工作室基础应用-发单商户推荐。\n5. 点击右上角对外展示配置，填写简介、擅长游戏、结算周期、联系人、联系手机、微信号、QQ号并上传二维码。\n6. 点击保存，断言弹窗关闭；重新打开配置，断言全部字段回显与本次输入一致。\n7. 开启对外展示开关，刷新页面并断言开关为开启状态。\n8. 通过dual_account_pages创建新企业丸友集页与19159770995丸掌柜页的隔离上下文。\n9. 在19159770995侧进入商家管理-工作室授权新-工作室推荐，按新企业名称查询。\n10. 打开查询结果的查看详情，逐项核对工作室名称/主体、简介、擅长游戏、结算周期、联系人、联系手机、微信号、QQ号和二维码。\n11. 打开独立SaaS-admin页，进入供应链管理-推荐评分配置，按对象名称查询新企业。\n12. 核对Admin展示信息和联系方式与第5步提交的数据完全一致。\n13. 保存三端截图、关键接口响应、企业标识和测试数据；将账号写入台账，供后续授权申请用例复用。",
        "对外展示配置保存后弹窗关闭且可完整回显；开关开启后，新工作室出现在固定丸掌柜的工作室推荐搜索结果；详情页和SaaS-admin推荐评分配置的展示资料、联系方式、二维码均与新建企业配置一致；三个端的对象名称/主体一致。",
        "注册认证：e2e/tests/test_e2e_saas_001_enterprise_certification.py；丸友集专用开通：e2e/tests/SaaS订阅邀请登录/test_prodsol_wyjtrial_001_wanyouji_free_trial.py；双账号fixture：e2e/conftest.py；账号台账：e2e/utils/account_store.py。",
        "新建：WanyoujiDisplayConfigPage（配置、开关、回显）；WanzhangguiWorkshopAuthorizationPage（搜索、详情断言）；AdminRecommendationScorePage（对象搜索、详情断言）。测试函数使用dual_account_pages，Admin使用独立Page；标记e2e_seed、e2e_chain。",
        "注册账号、开通版本/订阅记录、配置提交值、两端查询结果、Admin查询结果、截图路径、接口响应摘要。",
    ),
    (
        "AUTO-FLOW-AUTH-002",
        "复用新建企业开通丸掌柜并验证商户展示、Admin推荐及供应链初始化",
        "P0",
        "已生成脚本，待测试环境首跑",
        "AUTO-FLOW-AUTH-001已成功执行并将新企业主账号、企业名称、商户ID写入台账；该企业已开通丸友集；固定账号19159770995可登录丸友集且具备发单商户推荐菜单权限；SaaS-admin账号可用。",
        "复用AUTO-FLOW-AUTH-001的企业名称、主账号、商户ID；丸掌柜展示配置使用与丸友集不同的运行时唯一简介、联系人、手机、微信号、QQ号和二维码；擅长游戏至少选择1项；结算周期：月结。",
        "1. 从账号台账读取AUTO-FLOW-AUTH-001创建的企业主账号、企业名称和商户ID，先断言该账号已开通丸友集。\n2. 复用丸掌柜专用订阅/支付开通链路为同一企业开通丸掌柜，并回查企业概览或订阅记录为已开通。\n3. 以该企业主账号登录丸掌柜，进入商家管理-工作室授权新。\n4. 点击右上角对外展示配置，填写简介、擅长游戏、结算周期、联系人、联系手机、微信号、QQ号并上传二维码。\n5. 点击保存，断言配置弹框关闭；重新打开弹框，断言全部字段回显正确。\n6. 勾选对外展示开关，刷新后断言开关仍为开启。\n7. 通过dual_account_pages创建新企业丸掌柜页与19159770995丸友集页的隔离上下文。\n8. 在19159770995侧进入丸友集-工作室基础应用-发单商户推荐，按新企业商户名称查询。\n9. 打开查询结果的查看详情，逐项核对商户名称/主体、简介、擅长游戏、结算周期、联系人、联系手机、微信号、QQ号和二维码。\n10. 打开独立SaaS-admin页，进入供应链管理-推荐评分配置，按对象名称查询该商户，核对展示信息和联系方式与第4步完全一致。\n11. 在SaaS-admin进入供应链管理-商户供应链管理，按商户名称搜索。\n12. 断言至少返回一条与新企业名称匹配的商户记录；记录商户ID及其支持的供应链。\n13. 保存三端截图、关键接口响应和台账链接，供授权申请、策略和发单用例复用。",
        "丸掌柜开通成功；展示配置保存后弹框关闭且可完整回显；开启对外展示后，固定丸友集账号19159770995可在发单商户推荐中搜索到该商户；详情页和推荐评分配置的展示资料、联系方式、二维码与丸掌柜配置一致；商户供应链管理按商户名至少返回一条对应记录。",
        "前置账号与企业标识：AUTO-FLOW-AUTH-001台账产物；丸掌柜开通应复用其专用订阅/支付开通链路；双账号fixture：e2e/conftest.py；账号台账：e2e/utils/account_store.py。通用指定开通用例排除丸掌柜，不能直接调用。",
        "新建：WanzhangguiDisplayConfigPage（配置、开关、回显）；WanyoujiMerchantAuthorizationPage（商户搜索、详情断言）；AdminRecommendationScorePage（对象搜索、详情断言）；AdminMerchantSupplyPage（商户搜索、至少一条结果断言）。测试函数使用dual_account_pages，Admin使用独立Page；标记e2e_chain。",
        "开通前后订阅状态、丸掌柜配置提交值、丸友集详情结果、推荐评分配置结果、商户供应链管理搜索结果、商户ID/供应链清单、截图路径、接口响应摘要。",
    ),
    (
        "AUTO-FLOW-AUTH-003",
        "新建丸友集申请固定丸掌柜并审核后自动生成策略发单至抢单大厅",
        "P0",
        "已生成脚本，待测试环境首跑",
        "AUTO-FLOW-AUTH-001与AUTO-FLOW-AUTH-002均成功；新企业已同时开通丸友集和丸掌柜且已开启两端对外展示；固定账号19159770995已开通丸掌柜、丸友集且具备审核、策略配置、手工录单和抢单大厅权限；测试数据满足手工录单必填条件。",
        "复用前两条用例的新企业主账号、企业名称和商户ID；固定商户：19159770995（个体工商户1378）；自动生成策略名称：新企业名称；订单标题、来源单号、联系电话使用运行时唯一值。",
        "1. 从台账读取新企业账号和名称，使用dual_account_pages创建新企业丸友集页及19159770995丸掌柜页。\n2. 新企业登录丸友集，进入工作室基础应用-发单商户推荐。\n3. 按商户名称搜索19159770995对应的个体工商户1378，断言唯一/目标结果存在。\n4. 如需核对展示资料，先点击查看详情；随后点击申请推单并确认。\n5. 断言新企业丸友集侧申请状态变为审核中；记录申请时间和关联商户。\n6. 19159770995丸掌柜侧进入商家管理-工作室授权新，切换待我审核，按新企业名称查询。\n7. 点击审核，在审核弹窗点击同意并确认；分别刷新两端授权页，断言状态均为已授权。\n8. 19159770995进入履约工作室/平台-工作室授权，按新企业名称查询，断言工作室记录状态为启用。\n9. 进入履约工作室/平台-推单配置，按新企业名称查询，断言自动新增/可用策略名称为新企业名称、状态为启用、策略类型为单平台指定，且目标工作室为新企业。\n10. 进入商家管理-订单管理-手工录单，填写运行时唯一订单数据，选择第9步策略并提交推单。\n11. 断言丸掌柜侧订单创建/推单成功，记录主单号、子单号、来源单号和策略名称。\n12. 新企业丸友集进入工作室履约应用-抢单大厅，使用来源单号或订单标题查询。\n13. 断言大厅存在对应订单，且订单标题、来源单号、上游商户、目标工作室与丸掌柜侧记录一致。\n14. 保存申请、审核、工作室授权、策略详情、订单创建和抢单大厅的截图/接口响应；更新台账授权关系、策略和订单产物。",
        "新企业可向个体工商户1378发起申请；19159770995审核同意后双方已授权；新企业名称对应的工作室授权为启用；自动生成或可用的推单策略为启用且类型为单平台指定；使用该策略手工录单推单成功；新企业丸友集抢单大厅可查询到完全匹配的订单。",
        "双账号fixture：e2e/conftest.py；工作室授权/策略：e2e/pages/wanzhanggui_push_page.py、e2e/tests/推单配置/test_e2e_push_001_wanzhanggui_workshop_authorization.py、test_e2e_push_003_dispatch_strategy.py；手工录单与大厅回查：e2e/pages/wanzhanggui_order_page.py、e2e/tests/订单流转/test_e2e_order_001_manual_dispatch.py（如文件路径以当前仓库为准）。",
        "新建：WanyoujiMerchantRecommendationPage（搜索、详情、申请推单）；WanzhangguiWorkshopAuthorizationNewPage（待审、同意、状态）；WanzhangguiSupplyAndStrategyPage（工作室启用、自动策略类型）；复用WanzhangguiOrderPage创建订单与WanyoujiFulfillmentPage抢单大厅查询。测试函数标记e2e_chain，输入依赖前两条台账产物。",
        "申请ID与时间、双端授权状态、工作室授权记录、策略ID/类型/状态、主单号/子单号/来源单号、抢单大厅查询结果、截图路径、接口响应摘要。",
    ),
    (
        "AUTO-FLOW-AUTH-004",
        "关闭既有授权后重新申请审核并恢复单平台策略发单闭环",
        "P0",
        "已生成脚本，待测试环境首跑",
        "AUTO-FLOW-AUTH-003已成功，且新企业与19159770995间当前关系为已授权；新企业已开通丸友集和丸掌柜；19159770995具备丸掌柜工作室授权、策略及手工录单权限；新企业丸友集具备待我审核和抢单大厅权限。",
        "复用新企业账号、企业名称和商户ID；固定商户：19159770995（个体工商户1378）；重新申请记录ID；恢复后的工作室名称/策略名称：新企业名称；手工录单来源单号、订单标题、联系电话均使用运行时唯一值。",
        "1. 新企业登录丸友集，进入工作室基础应用-发单商户推荐，切换发单商户授权Tab。\n2. 按19159770995对应企业商户搜索，确认当前状态为已授权后点击关闭授权并确认。\n3. 刷新两端授权列表，断言该关系状态均为已关闭，并记录关闭前的授权关系ID、策略ID和状态。\n4. 新企业切换进入丸掌柜-商家管理-工作室授权新，按19159770995对应企业商户查询。\n5. 点击页面操作【申请发单】并确认，记录本次重新申请的申请ID、申请方和被申请方。\n6. 新企业切换进入丸友集-工作室基础应用-发单商户推荐，切换待我审核Tab，按关联商户/申请ID查询。\n7. 断言存在第5步产生的待审核记录，点击审核，在弹窗点击同意并确认。\n8. 刷新新企业丸掌柜与丸友集授权页，断言双方状态恢复为已授权；同时核对申请方向、最近申请时间和审核人记录与步骤5至7一致。\n9. 19159770995进入丸掌柜-履约工作室/平台-工作室授权，按新企业名称查询，断言对应工作室状态为启用。\n10. 进入履约工作室/平台-推单配置，按新企业名称查询，断言对应策略状态为启用、策略类型为单平台指定、目标工作室为新企业。\n11. 进入商家管理-订单管理-手工录单，填写唯一订单数据，选择第10步单平台策略并提交推单。\n12. 断言19159770995丸掌柜侧发单成功，记录主单号、子单号、来源单号和策略名称。\n13. 新企业丸友集进入工作室履约应用-抢单大厅，按来源单号或订单标题查询。\n14. 断言大厅存在本次订单，核对订单标题、来源单号、上游商户、目标工作室、订单状态与丸掌柜侧一致。\n15. 保存关闭授权、重新申请、审核、授权恢复、工作室授权、策略、订单和抢单大厅的截图/接口响应，并更新台账关系和订单产物。",
        "关闭后关系为已关闭；重新申请产生唯一待审记录且由新企业丸友集待我审核可见；同意后双方恢复已授权；19159770995侧工作室授权和新企业名称的单平台指定策略均为启用；使用该策略再次发单成功，新企业丸友集抢单大厅可检索并核对到对应订单。",
        "前置授权与策略产物：AUTO-FLOW-AUTH-003；双账号fixture：e2e/conftest.py；授权/策略复用：e2e/pages/wanzhanggui_push_page.py与e2e/pages/wanzhanggui_order_page.py；手工录单与抢单大厅复用既有订单发单脚本。",
        "新建：AuthorizationStateTransitionPage（关闭、按申请ID追踪、待审/同意、双端状态断言）；复用WanzhangguiSupplyAndStrategyPage、WanzhangguiOrderPage和WanyoujiFulfillmentPage。测试函数标记e2e_chain，执行前校验申请方向与待审归属。",
        "关闭授权前后状态、关系ID、重新申请ID/方向/时间、审核记录、策略ID/类型/状态、主单号/子单号/来源单号、抢单大厅结果、截图路径、接口响应摘要。",
    ),
]


def style_sheet(ws, widths):
    header_fill = PatternFill("solid", fgColor="1F4E78")
    header_font = Font(color="FFFFFF", bold=True)
    thin = Side(style="thin", color="D9E2F3")
    for cell in ws[1]:
        cell.fill = header_fill
        cell.font = header_font
        cell.alignment = Alignment(horizontal="center", vertical="center", wrap_text=True)
    for row in ws.iter_rows(min_row=2):
        for cell in row:
            cell.alignment = Alignment(vertical="top", wrap_text=True)
            cell.border = __import__("openpyxl").styles.Border(bottom=thin)
    for index, width in enumerate(widths, 1):
        ws.column_dimensions[get_column_letter(index)].width = width
    ws.freeze_panes = "A2"
    ws.auto_filter.ref = ws.dimensions
    ws.row_dimensions[1].height = 30


def main():
    wb = Workbook()
    ws = wb.active
    ws.title = "测试点"
    ws.append(["测试点ID", "模块", "测试主题", "测试点/预期", "优先级", "自动化建议"])
    for row in FEATURE_POINTS:
        ws.append(row)
    style_sheet(ws, [15, 16, 20, 68, 10, 22])
    ws.conditional_formatting.add("E2:E200", FormulaRule(formula=['E2="P0"'], fill=PatternFill("solid", fgColor="F4CCCC")))

    ws = wb.create_sheet("自动化用例")
    ws.append(["用例ID", "用例名称", "前置条件", "自动化步骤", "预期结果", "覆盖测试点", "优先级", "执行模型"])
    for row in CASES:
        ws.append(row)
    style_sheet(ws, [18, 30, 38, 62, 54, 34, 10, 16])
    ws.conditional_formatting.add("G2:G200", FormulaRule(formula=['G2="P0"'], fill=PatternFill("solid", fgColor="F4CCCC")))

    ws = wb.create_sheet("自动化流程明细")
    ws.append([
        "流程用例ID", "用例名称", "优先级", "实现状态", "环境与前置条件", "运行时测试数据",
        "自动化详细步骤", "预期结果", "可复用现有资产", "建议新增自动化资产", "执行证据",
    ])
    for row in AUTOMATION_FLOW_CASES:
        ws.append(row)
    style_sheet(ws, [18, 36, 10, 12, 42, 50, 96, 58, 55, 66, 46])
    ws.conditional_formatting.add("C2:C200", FormulaRule(formula=['C2="P0"'], fill=PatternFill("solid", fgColor="F4CCCC")))

    ws = wb.create_sheet("详细测试步骤")
    ws.append(["详细用例ID", "用例名称", "前置条件", "测试数据", "详细测试步骤", "预期结果", "建议保留证据"])
    for row in DETAILED_CASES:
        ws.append(row)
    style_sheet(ws, [15, 30, 30, 30, 72, 52, 34])

    ws = wb.create_sheet("需求追溯")
    ws.append(["需求编号", "需求摘要", "来源页", "覆盖测试点", "覆盖自动化用例", "备注"])
    rows = [
        ("REQ-01", "旧授权页下线，生效中授权同步新列表", "3", "FP-001", "AUTO-AUTH-001", ""),
        ("REQ-02", "展示名称规则冲突", "旧PRD第1页；新提测第4页", "FP-030", "DT-001", "旧PRD要求去掉展示名称/标题；新提测要求保存展示名称。测试前须由产品确认最终规则。"),
        ("REQ-03", "两端推荐/授权/待审核Tab范围、字段、筛选与推荐排序", "1-5", "FP-002~FP-008,FP-031~FP-035,FP-047,FP-049", "AUTO-AUTH-002,003,006,007,014,015,021", "页面结构按7月10日变更日志采用三Tab口径"),
        ("REQ-04", "双向申请、审核、拒绝、关闭、重开的状态流转与权限", "3-6", "FP-009~FP-014,FP-038~FP-041,FP-050", "AUTO-AUTH-002~006,012,017,018", "已关闭仅发起方可重新开启；待我审核从授权Tab移除"),
        ("REQ-05", "联系方法配置及字段", "5-6", "FP-015~FP-018,FP-036~FP-037", "AUTO-AUTH-008,016", "联系人、联系手机、微信号、服务时段"),
        ("REQ-06", "授权成功同步供应链及二次授权豁免边界", "6-7", "FP-019~FP-022,FP-042~FP-043", "AUTO-AUTH-002,003,009,019", "外部代练平台仍沿用填写信息授权"),
        ("REQ-07", "授权工作室自动生成指定工作室推单策略", "7-8", "FP-023~FP-025,FP-044~FP-046", "AUTO-AUTH-002,003,005,010,020", "关闭授权后的策略处置待产品确认"),
        ("REQ-08", "Admin默认开通全部供应链、单项关闭及入口简化", "9", "FP-026~FP-027,FP-048", "AUTO-AUTH-011,022", "商户供应链管理保留，供应链授权入口去掉"),
        ("REQ-09", "权限、重复与并发保护", "补充质量保障", "FP-028~FP-029", "AUTO-AUTH-012,013", "非PDF显式条目，作为授权关系核心风险补充"),
        ("REQ-10", "双端展示配置保存、开关及数据隔离", "新提测4-5", "FP-051~FP-053", "AUTO-AUTH-023；DT-001~002", ""),
        ("REQ-11", "关闭后供应链/策略失效与重授权", "新提测6-7", "FP-054", "AUTO-AUTH-024；DT-006", "新提测明确要求关闭后失效，替代旧表中的待确认表述。"),
        ("REQ-12", "历史授权迁移及迁移结果表", "新提测7-10", "FP-055~FP-057", "AUTO-AUTH-025；DT-007", "接口migrateLicense"),
        ("REQ-13", "策略配置与WYJ新发单授权校验", "新提测11-13", "FP-058~FP-062", "AUTO-AUTH-026~028；DT-008~010", "WYJ新单不依赖旧授权码/license/appSecret；非WYJ需回归。"),
        ("REQ-14", "存量商户补偿和订阅自动初始化", "新提测13-15", "FP-063~FP-066", "AUTO-AUTH-029~030；DT-011~012", "接口initMerchantSupply和订阅异步链路。"),
        ("REQ-15", "旧入口切换、范围边界", "新提测15-16", "FP-067~FP-068", "AUTO-AUTH-031；DT-014", "存量订单售后等不属于本次改造范围。"),
    ]
    for row in rows:
        ws.append(row)
    style_sheet(ws, [14, 42, 12, 28, 38, 42])

    ws = wb.create_sheet("说明")
    ws.append(["项目", "内容"])
    ws.append(["需求来源", "当前主依据：丸掌柜 × 丸友集授权简化提测文档.pdf（16页）；历史参照：丸掌柜丸友集授权简化.pdf。"])
    ws.append(["自动化实现建议", "双账号场景使用仓库 dual_account_pages fixture，分别创建丸掌柜和丸友集 Page Object；不在同一页面切换登录账号。"])
    ws.append(["范围说明", "已逐页核对当前提测PDF。关闭授权后策略/供应链失效已由新提测明确。仅展示名称是否保留与历史PRD冲突，已在需求追溯和FP-030标记为P0待确认。"])
    ws.append(["建议执行顺序", "AUTO-AUTH-001 -> 002/003 -> 004/005/006 -> 009/010 -> 007/008/011 -> 012/013"])
    style_sheet(ws, [24, 110])

    OUTPUT.parent.mkdir(parents=True, exist_ok=True)
    wb.save(OUTPUT)
    print(OUTPUT.resolve())


if __name__ == "__main__":
    main()
