会场排座套件

SKILL效率
效率 未标注权限 许可证不明确
安装这个技能

会场排座全流程套件。输入一份人员名单(Excel/CSV)与一份会场座位图或布局参数,按会议礼宾排座原则(居中为上、以左为尊、前排为先)自动排座,按用户需要产出可编辑座位安排文档、可编辑座位图网页(可内嵌二维码面板与"增删人员自动重排"能力)、可共享在线文档、扫码查座二维码与海报。当用户提到"排座位""座位安排""座位表""座位图""座次""参会人员排座""扫码查座""会场布置""主席台排位""调座位""新增参会人员"等需求时使用。

一句话选型结论

按资料字段整理

会场排座套件是效率类的 Agent Skill,安装方式未标注,权限级别未标注,许可证不明确,有可直接复制的安装命令。技能本质是给模型读的说明书,效果取决于模型与客户端;装完先用一个小任务验证,再放进正式流程。

分类效率 安装方式未标注 权限级别未标注权限 许可证许可证不明确
累计安装 未标注 本周 未标注
GitHub 星标 未标注 仓库 未标注
下载量 未标注 技能市场下载数
权限级别 未标注权限 安装前请确认风险范围
许可证 许可证不明确 未说明

安装

未标注
在支持 Skills 的客户端里执行,装完问一句「你有哪些技能」验证
skillhub install user_7b8d7c54/seating-chart-suite
  1. 1
    确认客户端支持

    确认你的客户端支持 Skills(Claude、Codex、Cursor 等),并升级到较新的版本。

  2. 2
    拿到技能文件

    执行上面的命令安装;也可以把仓库里的 SKILL.md 手动放进客户端的 skills 目录。

  3. 3
    刷新技能列表

    重新打开客户端,或刷新技能列表,让新放进来的技能被加载。

  4. 4
    验证是否生效

    问一句「你有哪些技能」,确认列表里出现它,再拿一个小任务试跑。

技能档案

效率
字段来自技能仓库与公开索引,中文说明由本站标注
作者 / 维护方user_7b8d7c54仓库 未标注 · 版本 未标注
宿主客户端未标注技能可被这些客户端加载
安装方式未标注安装包 community
权限级别未标注权限安装前请确认风险范围
许可证未说明许可证不明确,商用前请自行确认条款
仓库可用性available技能仓库当前是否可访问
最近核验未标注上游最后核验时间 · 数据更新 1791625625
正文体量60.4 KBSKILL.md 原文大小,越大说明说明书写得越细

典型使用场景

3 类
按分类整理的常见用法,具体以 SKILL.md 为准
整理待办与日程

把零散任务收进清单,排出优先级。

批量处理重复任务

把固定动作做成模板,重复执行。

把流程写成清单

把口头流程整理成可复用的步骤。

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有标注权限级别,实际能做什么要装好后确认。
  • 许可证不明确,商用或二次分发前先到仓库确认条款。
  • 没有做站内核验,内容以作者仓库为准。
  • 技能只是说明书,实际效果取决于模型与客户端,装完先用小任务试一遍。

更适合

  • 需要在效率场景里给模型补一套做法的人。
  • 愿意先读一遍 SKILL.md、确认它会让模型做什么的人。

不太适合

  • 对许可证要求很严、必须明确可商用的人。
  • 只想装完就自动变强、不打算看说明书的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
技能权限级别安装方式累计安装宿主客户端安装命令
会场排座套件当前 未标注权限 未标注 未标注 未标注 有
Nano PDF 文档 联网访问 ClawHub 市场 424.9 万 OpenClaw 有
自动更新程序 浏览器控制 ClawHub 市场 296.4 万 OpenClaw 有
Gemini 助手 联网访问 ClawHub 市场 254.7 万 OpenClaw 有
word DOCX 文档 联网访问 ClawHub 市场 239.6 万 OpenClaw 有
Excel XLSX 前端 联网访问 ClawHub 市场 227.0 万 OpenClaw 有

SKILL.md 全文

60.4 KB
模型实际读到的说明书原文,来自技能仓库

会场排座全流程套件

用途

把「人员名单 + 会场座位图」一次输入,产出交付物。适用于培训会、年会、报告会、评审会、动员会等需要在固定会场内按职级/部门排定座次的场景。

可选交付物(默认只做用户点名的那几项,不要自作主张全做):

交付物 用途 脚本
①《座位安排表》可编辑文档 正式归档、打印留档 Step 3
②《座位图》可编辑网页 会务组现场调座(最重要,通常只要这一件) Step 4
③ 可共享的在线文档 供同事在线查看 / 编辑 Step 3
④ 扫码查座页 + 二维码 + 海报 参会人手机扫码查询座位 Step 5-6

产出范围必须在开工前问清(见下方"必问项")。用户说"只要座位图"时,就只产出 ②;不要因为流程里有 Step 3/5/6 就顺手做出来——多做的文档和二维码会污染交付目录,也会让用户以为要付额外的人工去维护。

使用前置条件

开始前必须确认以下四项,缺失时向用户询问,不要自行假设:

必问项 为什么必须问
名单文件路径 必需输入
会场座位图或区块参数 决定座位编号体系;图片需人工读图转为区块参数
主席台是否设席、设几席 决定领导是否上台、主席台用哪种排位法
产出范围 只要座位图网页?还是要连文档/二维码一起?不问清就会多产出

可自行推断、不必打断用户的事项(按下方默认值处理,并在交付时一句话说明):

  • 职级排序权重 —— 用 RANK_ORDER 默认值
  • 机动位数量 —— 默认不预留(reserve_last_seats: 0),空位自然成为机动位
  • 特殊约束 —— 从名单「备注」列自动识别「不参加/缺席/请假」,其余备注按字面人工确认
  • 排座原则 —— 默认用本技能内置标准(见 Step 4b 后的"会议主席台排位法")

提问纪律(本次测试的最大教训)

排座涉及礼宾次序,排错不是排版问题而是会务失误。以下三条必须严格遵守:

  1. 规则内部有矛盾时,必须让用户裁决,不得自行揣测。
    典型案例:用户同时说"以左为尊"和"示例为 4-2-1-3-5"——这两个是左右镜像冲突(台上人员面向观众,其自身左侧恰是观众视角右侧)。
    处理方式:把矛盾摆出来、画出两种排列对比图,用 AskUserQuestion 让用户二选一,不要猜。
  2. 问题问得越具体越好。 不要问"主席台怎么排",要问"2 号人员坐 1 号的哪一边(画图对比)"。
  3. 用户给的示例优先于用户的文字描述(示例是具象的、可验证的)。示例与文字冲突时,以示例为准并回读确认。

必问清单(排座前逐项确认,缺一不可):

  • 主席台:设不设?几人?排序依据(职务序列 / 名单原序)?左右谁为上(务必画图确认)?
  • 听众席铺开方式:逐区块坐满(中块→右块→左块),还是逐排横向铺开?
  • 同职级内:按单位序列?主办部门优先?还是要同单位连坐?
  • 特殊人员:不参加的怎么处理?有指定座位的吗?
  • 是否需要"新增人员后自动重排"能力?(决定是否做 Step 4b)

执行流程

Step 0:读取名单并结构化

从 Excel 读取名单,导出为 CSV(UTF-8 带 BOM)。用 pandas 或 openpyxl 读取,列名按 序号/单位/姓名/职务/职级/备注 识别。

若名单为 Excel 且含多个工作表,每个工作表分别读并问用户用哪个(回执表常含"现场/视频/请假"多张表,选错就全错)。

若名单为 Excel 且含合并单元格,先展开再导出。

Step 1:把座位图翻译成区块参数

若用户给的是图片(会场示意图),逐块读图并记录:区块代号、方位(前/后、左/中/右)、排数、每排座位数、门与通道位置。

生成会场配置 JSON,格式参照 assets/venue_config.example.json:

{
  "title": "会议名称 · 座位安排表",
  "date": "2026年9月19日",
  "venue": "会场名称",
  "reserve_last_seats": 0,
  "rostrum_order": [],   // 主席台领导姓名,按职务从高到低;留空 = 按名单原序
  "unit_priority": ["办公室", "人力资源部", "财务管理部"],
  "blocks": [
    {"id":"A","label":"前区中块(正对主席台)","short":"前区中块",
     "group":"front","side":"center","rows":5,"cols":6,"order":1}
  ],
  "special": []   // 特殊安置:[{"name":"姓名","seat":"C-1-6","note":"桌牌摆边上"}]
}

字段含义:

  • group:front(前区)/ back(后区)—— 落座顺序为前区优先
  • side:center / left / right —— 未给 order 时的区块次序依据(中→左→右)
  • order:区块落座顺序(数字越小越优先)。会场区块优先级与默认不同时必设,例如标题写"中间>右边>左边"就配 A=1、B(右)=2、C(左)=3
  • layout:block(默认,逐区块坐满:中块 1~N 排全排完再进下一块)/ row(逐排横向铺开:第1排中→右→左,第2排中→右→左…)。"逐区块坐满"是会场常规,本项目默认用 block
  • rostrum_order:主席台姓名位次列表(按职务从高到低排列)。它的作用是定"谁是1号、谁是2号",其后的左右落位由标准排位法自动计算,不需要人工指定左右。不设时按名单原序
  • unit_priority:听众席单位关键词优先级列表。需要"机关部门靠前"时设置:同职级内,命中靠前关键词的单位排前(按列表位置),未命中任何关键词的排最后。注意(2026-09-22):默认座次按名单行次排,本项默认不生效;只有在座位图页面「排座原则 · 优先序」里把 unit 写进链路(如 unit,xh)时才起作用
  • special:按姓名定点入座,用于名单备注中的个别要求(如"桌牌摆最后一排")
  • reserve_last_seats:从座位序列末尾预留的机动位数

会议主席台排位法(本技能标准算法,2026-09-20 用户二次确认)

先明确"谁高谁低",再定"坐哪"。 rostrum_order 给的是位次(第几号领导),左右落位由下表自动算出。

核心规则:主席台面向观众、听众席面向主席台,两种场景从画面(观看者)视角看规则完全相同 ——
画面左→右的位次序列 = 偶数位次降序 + 1 + 奇数位次升序:

evens = range(n if n%2==0 else n-1, 0, -2)   # n..4 2(偶数降序)
odds  = range(3, n+1, 2)                     # 3 5..n(奇数升序)
seq   = evens + [1] + odds
人数 画面从左到右的位次序列 说明
5 4 2 1 3 5(奇数=42135) 1 号居中,2 号在其左、3 号在其右
6 6 4 2 1 3 5(偶数=642135) 1、2 号并列居中,1 号居右位,4、6 号继续向左延伸
11 10 8 6 4 2 1 3 5 7 9 11

口诀:1 号永远居中(偶数时占中间两位的右位);2 号在 1 号左、3 号在 1 号右,4、5、6… 依次向外交替展开。听众席同一排按同样图案展开(每排的第 1 名居中、2 左 3 右,分区先后仍按区块 order:中→右→左)。

圆桌:1 号(主位)在画面正上方、面向门;2 号在 1 号左、3 号在 1 号右,向门的方向两侧交替推进,末位面门。

历史教训:本项目曾把序列镜像反了(5 3 1 2 4),2026-09-20 用户纠正为 4 2 1 3 5。
若用户给出具体示例(如 42135),示例优先于文字描述,并回读确认。

其他形态(用户提及但当前未实现,遇到时按此规则手工排并说明):

  • 长条桌/方桌:横置长桌(长边对门)——背门侧为主方席、面门侧为客方/上级席,双方主位各自居中,按"以左为尊"向两侧排;主方主位正对客方主位。竖置长桌(短边对门)——离门远的短边为主位(主持人/最高职务),两侧长边"左尊右卑",记录员/会务人员靠门侧
  • 圆桌/椭圆桌:正对门位置为主位(主持人/主办方最高领导);以主位为起点按"以左为尊"顺时针排布;客方主宾在主位左侧紧邻位,其余按层级交替落座
  • 以上三种形态需要非矩形会场配置(圆桌/长桌的座位是沿边分布的),当前 blocks 只支持矩形区块——遇到时先用 special 定点硬排,并明确告知用户这是手工排位

Step 2:生成座位分配(唯一数据源)

python scripts/01_make_seats.py --list 名单.csv --config 会场.json --out seats.json --csv-out 带座位号名单.csv
python scripts/01_make_seats.py --empty --config 会场.json --out seats.json   # 空白模板:只出座位框架,页内不含任何人员

> 空白模板(2026-09-23 新增):--empty 不读名单,仅按会场配置生成全部座位框架;页面首开为空场,客户在页面里导入名单即自动排座。技能及其交付材料不内置任何虚构名单(2026-09-23 用户确认)——示例数据一律现场生成或由用户提供,名单文件不得随包交付。

脚本自动完成:名单行次自上而下依次落座(2026-09-22 起不再按职级重排)→ 区块优先级(order)→ 排次由前向后 → 座次由左向右;主席台按标准排位法(见下方专章);备注含"不参加/缺席/请假"者不排座。

听众席两条铁律(2026-09-20 用户确认,默认生效):

  1. 第 1 排到最后一排,职级从高到低 —— 用 layout: "row"(逐排横向铺开),不要用默认的逐区块坐满
  2. 同一排内:中间区 > 右区 > 左区 —— 用 blocks[].order 表达:中区=1、右区=2、左区=3
    (blocks 数组顺序只决定页面/Excel 上的左右视觉位置,order 才决定落座先后,两者独立配置)

> 名单顺序即座次依据(2026-09-22 起,用户要求)
>
> 第 1 条的"职级从高到低"由名单文件的行次表达:导入模板已写明"请按职级大小从上到下排序",
> 01_make_seats.py 与页面引擎(assignSeats / roRankTop)都不再按职级字段重排,
> 名单第 1 行 → 全场第 1 尊位,第 2 行 → 第 2 尊位…… 一一对应。
> 好处:职级列写法不统一(M/P 双通道、中文职级、留空、写错)都不会打乱座次。
>
> - 引擎默认优先序 = ['xh'](名单行次);名单没写序号列时退回名单数组顺序
> - 旧规则包里留存的 rank,unit,xh 会一次性清空为新默认(migrateOrder() + orderV 标记,只迁一次)
> - 需要临时恢复"引擎按职级排":在座位图页面「排座原则 · 优先序」填 rank,unit,xh(页面端生效;
> Python 端 01_make_seats.py 恒按名单顺序)
> - unit_priority(机关靠前)只在优先序链里含 unit 时才起作用,默认已随职级排序一并停用
> - 主席台编号兜底(无领导标记时按席位数取前 N 人)也改为按名单顺序取

脚本会打印核对结果,必须核对这一行:

名单 177 人 → 听众席 165 | 主席台 11 | 不参加 1 | 合计核对 177 ✅

合计不等于名单总数时,不要继续生成交付物,先查明差异(通常是名单有空行、重名、或备注未识别)。

主席台人数与人工预期不符时的排查顺序(真实名单最常见的偏差点):

  1. 单位列是否写"公司领导"(主判据,写法必须完全一致;可用 --leader-units "公司领导,领导班子" 扩展取值)
  2. 非班子高管是否被误判上台 —— 职务含"总经理助理兼/副总工程师兼/副总会计师兼"的自动排除,不排除时人工调整
  3. 职级列未命中时脚本会打印"已自动把第 X 列识别为职级列",核对该列号是否正确

Step 3:产出《座位安排表》文档

python scripts/02_make_doc.py --seats seats.json --out 座位安排表.md

再把 Markdown 转成 Word 或在线文档:

  • 要 .docx:调用 tencent-docs-routing 技能,走本地文档通道写入 Markdown 并保存为 docx
  • 要在线文档:调用 tencent-docs 技能,创建在线文档并写入(需用户已启用腾讯文档连接器)

Step 4:产出可编辑座位图网页

python scripts/03_make_map.py --seats seats.json --out 座位图.html

二维码面板默认留空:等查座页上云拿到网址后,在面板里粘贴即时生成,不预填任何历史网址。

产出为单文件 HTML,左侧深色侧边栏工作台(上:场景切换 14 项;中:本场景操作 ①–⑤,见 Step 4b;下:恢复本场景示例名单),功能:单击座位改姓名(localStorage 保存)、姓名/职务/单位/职级搜索高亮、显示座位号开关、会议名称就地编辑、导入 Excel 名单、导出 Excel 座位图、导出查座页 .html(侧边栏独立按钮,不在二维码面板里)、恢复初始名单、A4 横向打印、职级配色与图例,以及内嵌二维码面板(侧边栏「二维码 / 海报」按钮):

  • 画布头部压缩为一行(2026-09-23):.hero 由「大标题 + 居中副标题 + 编辑提示」三行改成 flex 单行 —— 标题居左(22px + 左侧 4px 主色竖条替代原居中下划线),简介(可就地编辑)紧随其后,#heroTip / #heroReset 靠右;画布上缘约省出 120px(多显 1~2 排座位)。#heroSub / #heroReset 两个 id 必须保留(verify_roster.py 依赖)
  • 页面顶部有会议名称大标题,点「✎ 改会议名」可就地修改(保存到本机,导出文件名/海报标题同步)
  • 座位按职级着色(方向 B「纸白·色条」,2026-09-23 定稿):同色系 4 档深浅(LADDER = #264f7a → #4a78a8 → #86a8c9 → #cddbe8,由深到浅),按「本场名单实际出现的职级」依 rankOrder 均匀分档(梯度插值,不是一人一色)——12 个职级只出 4 种档色,图例按档色归并,从十几项收敛到 4 项以内(悬停可看该档含哪些职级与人数)。座位卡白色底 + 左侧 4px 档色条(渲染时写 --lv 与 data-lv),姓名区永远白底黑字;Excel 导出用 tint(色, 0.66) 稀释成淡底(整块填深蓝会盖住姓名)。colorFor() 仍三端同源(页面座位卡 / 图例 / Excel / 查座页)。会场配置 rank_colors 可指定固定色(优先于自动分档)
  • 界面观感:页面底 --paper:#f5f7fa 近白纸面(去渐变),主色 --brand:#1f3a5f / --brand2:#2d5a8a,主按钮实心无渐变;侧栏墨蓝 #121a24→#1a2733→#1f2d3b;舞台条 #26313d→#1a222b;空位弱化为极淡虚线框且不显示位次号角标;过道字与区块描边降到最低存在感
  • 界面预览图(2026-09-23 定稿):assets/preview/预览_1_主页.png … 预览_12_座位编辑器_清空座位.png 共 12 张,覆盖主页 / 会场布局面板 / 调整布局(新旧两版)/ 座位编辑器(含清空座位)/ 排座原则面板 / 个别人员调整·搜索 / 座位变动对比 / 名单导入·模板 / 位次号开关对比 / 多区域画布。图内为演示数据(示例姓名),仅作样式参考;正式交付页不内置任何名单
  • 底部说明收纳为「一行 + ?」(2026-09-23):画布下方原六行灰字改为 <details class="hint">,摘要行常显、点开才展开全文;class="hint" 必须保留(@media print 靠它隐藏)
  • 座位格内上行姓名、下行职务(不显示职级),鼠标悬停显示座位号/单位;右上角另有位次号角标(本排座次序,1 = 最尊位,见 Step 4b)
  • 位次号显示开关:页面顶部「显示位次号」复选框(默认开),一键隐藏/恢复全部位次角标与主席台「N 号位」小字
  • 导出 Excel 座位图:按座位相对位置还原的可视化表格(非坐标列表)——每排两行(姓名/职务)、区块表头、主席台、职级配色填充、图例与说明,Excel/WPS 打开即见会场形状。列规划与网页一致(2026-09-22):每个「排带」都从第 2 列起排、下一带整行落在上一带正下方(旧版下一带横向错位到右侧,与页面不符)
  • 导入 Excel 名单:换一场会议时直接导入 .xlsx/.csv(自动识别表头:姓名/单位/职务/职级/备注;单位含"公司领导"等自动标记主席台),导入后按职级重排
  • 面板内粘贴查座页上云后的网址(默认留空、不预填),实时生成二维码;一键下载二维码 PNG / SVG、打印海报
  • 导出查座页:把本场最新名单与座位打包成一个独立 HTML(侧边栏按钮),发给发布方上云即可;拿到网址回填二维码面板,二维码即刻生成——调整座位不需要重做二维码
  • 场景工程切换(侧边栏,14 个子项分四类):依据《机关单位会议、就餐、车辆排位礼仪准则》——
    会议:剧院式 / 课桌式 / 回字形(两侧>14 人自动双排)/ 长条桌·对坐(面门为上位)/ 圆桌会议 / U形台;
    仪式:签约仪式(主左客右,双方主签人相邻居中)/ 会见·沙发室(并列式:主人居左、主宾居右)/ 合影站位(前排为尊、居中为上,与主席台同序);
    就餐:圆桌正餐(正对房门背靠主墙为主位,10 人/桌)/ 多桌宴请(主桌居中,2 号桌在右、3 号桌在左,桌数按每桌人数自适应)/ 长桌自助;
    车辆:考斯特·中巴(17–23 座)/ 大巴(45–55 座,前排为尊、右高左低、1 号位在司机后第一排右窗)。
    (小轿车·5座与商务车·7座场景已按「小白简化版」需求移除;如需恢复,在 03_make_map.py 侧边栏与 inject_roster_engine.py 的 PROJECTS 中补回 car5/car7。)
    每个子项工程独立保存名单、座位与规则包(localStorage 按子项分存),切换互不影响;「本场景操作」整组跟随当前子项显示在侧边栏对应位置,只作用于该子项。
  • 各场景布局按现实惯例个性化(2026-09-21,参照剧院式的做法做了全网礼仪惯例核对后逐场景改的,不是套同一个模板):
    | 场景 | 关键惯例(已落到 fill / seq / order / dir) |
    |---|---|
    | 剧院式 / 课桌式 / 回字形 / U形台 | 居中为上、以左为尊、前排为先;回字形主位坐面门短边、U形台缺口朝门 |
    | 长条桌·对坐 | 横置时背门侧为主方、面门侧为客方,双方主位各自居中;竖置时离门远的短边为主位 |
    | 圆桌会议 | 正对门为主位,主位左手(画面右)= 2 号,两侧交替向门推进 |
    | 签约仪式 | 主左客右、双方主签人相邻居中(L-1-… + R-1-… 左右分块) |
    | 会见·沙发室 | 并列式:主人居左、主宾居右,两侧块宽按主客人数定(pack:'split-host',块 H=主方 / G=客方,各自向中间填位) |
    | 合影站位 | 前排为尊、居中为上、以左为尊,与主席台同序 |
    | 圆桌正餐 | 主位背靠主墙正对门;主陪副陪制 / 主客交替制二选一 |
    | 多桌宴请 | 主桌居中、2 号桌在右、3 号桌在左(phys 物理位与 order 桌次分离:桌次 1 居中、偶数桌靠右、奇数桌靠左) |
    | 长桌自助 | 取餐动线在外、座位沿长边,主位居长边中段 |
    | 考斯特·中巴 / 大巴 | 前排为尊、右高左低(fill:[2,4,3,1]:1 号位在司机后第一排右窗),过道列显式声明 aisle:2 |
  • 场景礼仪说明:每个场景的排位规则总结存放在 inject_roster_engine.py 的 PROJ_DESC 映射,展示在「排座原则」面板顶部提示(带场景名)。2026-09-21 起侧边栏不再放「礼仪要点」框(侧边栏只留操作入口,减少视觉噪音),#sceneDesc / .sgdesc 已移除。新增场景仍必须在 PROJ_DESC 补文案(verify_roster 有覆盖检查)。
  • 每个场景的简介可就地编辑:主标题与座位图之间那行简介(#heroSub,contenteditable)点一下即可改,按场景独立存进规则包 heroText;留空自动回落到「日期 · 会场 · 人数/容量」的自动文案,旁边「↺ 恢复自动简介」一键还原。applyHeroSub() / saveHeroText() / resetHeroText() 实现,verify_roster.py 有「简介可就地编辑 / 按场景保存」检查。
  • 示例名单:每个子项首次打开自动生成与该场景常见规模匹配的示例名单(圆桌正餐 10 人一桌、考斯特 16 人、大巴 40 人、剧院式沿用导入的真实名单等),并带单位/职务/职级/来宾标记,导入 Excel 即整体替换。
  • 席位类选项按场景改名(2026-09-21,LAYOUT_LABELS 映射 + applyLayoutLabels()):打开排座原则时按当前场景把「排数 / 每排座数」等字段换成该场景的真实说法(车辆=「排数 / 每排座数(含过道)」、圆桌=「桌数 / 单桌人数」、长条桌=「排数 / 每排座位数」…),用不上的字段(如车辆的「宾主关系」、合影的「排数」)直接隐藏,避免用户对着不存在的概念填数
  • 排座原则 = 四维规则包(侧边栏「排座原则 / 调整」,每个子项一份):面板采用分层 + 分场景适配设计——第一屏只保留常用项(尊位方向、排数、每排座数),顶部提示替换为当前场景的礼仪要点;就餐类场景把「宾主关系」提升为第一屏第一项(宴请排法是核心决策),其余场景按需显示/隐藏(驾驶模式仅车辆、桌数仅圆桌、宾主关系仅就餐/签约/会见/长条桌/圆桌会议);专业项折叠在「高级选项(一般不用改)」内。所有控件都是真实驱动排座的参数,且不带引导文案;
    改完一键重排,仅作用于当前子项。
  • 宾主关系新增「主陪副陪制」(中式宴请经典,与主客交替制并列):主陪(主方最高)坐主位面门,客 1/客 2 依次填主位两侧邻座,副陪(主方第二)坐正对主位的背门位(照应全场);其余人按宾客优先与主方交替填两侧。实现:interleave='zhufu',人员序列=[主陪]+宾主交替+[副陪],恰好与圆桌环形落座序 roundOrder 的「最后一位=背门位」对上。
  • 圆桌排位:主位正上方面向门;主位左手(画面右)=2 号第一贵宾、右手(画面左)=3 号主陪,两侧交替向门推进;超过 24 人自动分同心环(内环为尊)。座位数自动等于实到人数

必须自检(两项都做,缺一不可):

  1. 渲染截图:确认版式正常
  2. 端到端功能验证(探针注入 + 截图 + 海报校验,8 项检查自动判定):
python scripts/99_verify_map.py 座位图.html --shot preview_qrpanel.png --poster

验证脚本自动检查:QR 库加载、面板函数、面板 DOM、座位图渲染、无源码外泄、面板可打开、二维码已生成、无错误提示、海报 HTML 结构完整。结论行必须是 PASS。

简单截图(快速看版式用):

"C:/Program Files (x86)/Microsoft/Edge/Application/msedge.exe" --headless=new --disable-gpu \
  --hide-scrollbars --virtual-time-budget=4000 --window-size=1420,2000 \
  --screenshot=preview.png "file:///绝对路径/座位图.html"

Step 4b(可选):座位图内嵌「人员管理 / 增删自动重排」

当用户要求"新增人员后其他人自动跟随调整(顺延推位)"或"导入 Excel 换一场会议"时,在 Step 4 之后执行:

python scripts/inject_roster_engine.py --html 座位图.html --config 会场.json --out 座位图.html

注入后侧边栏「本场景操作」按会务工作流定序(2026-09-21 重命名定稿),功能:

  • 操作流定序(所有场景统一,2026-09-21 重命名):①会场布局(区域 / 排列 / 主席台)——打开排座原则面板(剧院式/课桌式走双区面板 rulmask2,其余走四维面板 rulmask)→ ②名单导入(导入 / 导出整份名单)→ ③个别人员调整(只管单人增删 / 主席台·来宾标记 / 变动对比,不含导入入口)→ ④查座(查座页 / 二维码)(注明二维码需查座页上云后生成——可自行上传或联系作者获得)→ ⑤打印 / 导出 PDF;另有「恢复本场景示例名单」
  • 空间自适应座位(renderMap):按最宽一排(区块列数 + 过道列 + 间距)反算 --seat-w,新区块加入后整体座位缩一档;座位宽下限 58px(保证 3–4 字中文姓名完整显示,不允许为了塞进画布截断姓名),下限仍放不下时画幅拉宽(页面容器 1760px)+ #map{overflow-x:auto} 横向滚动兜底
  • 新增人员:填姓名/单位/职务/职级(可选勾选"主席台")→ 加入名单 → 全场按职级重排、顺延推位
  • 删除人员:列表中一键删除 → 后面的人自动补位
  • 设为/取消主席台:名单内每人一个开关,切换后自动重排
  • 导入 Excel 名单:在②名单导入面板替换当前名单并重排;导入人数超过座位时自动扩座——解析缺口后自动加排并提示,无需手工调整。面板提供「下载导入模板」按钮(CSV,含四行示例),并提示「请按职级大小从上到下排序,系统依据行次(自上而下)依次确定各自座次」(第三轮新增,downloadTpl())
  • 职级表随导入的名单自动补全(2026-09-21,解决「职级表漏一项 → 人全掉到最后排」那个最隐蔽的 bug):syncRankFromRoster(roster) 在每次排座前拿名单里实际出现的职级去补表,规则三条 —— ① 中文职级(正处 / 副科级 / 科员 / 基层副职…)按内置词表定档(RANK_ANCHORS 正则→权重);② 代码族(M3 / P5 / T2…)同族内按「数字越大越尊」定序(与 M1…M5、P1…P7 的常见写法一致),族里若已有已知成员则按其步长插值外推(M5=0、M4=1 ⇒ M3=2);③ 其余按名称排序、整体排在已知职级之后。补进来的条目会在「排座原则 → 高级选项 → 职级排序表」下方用一行提示列出(#rkTip),复制回「会场.json」的 rank_order 即可固化。
    示例名单也跟着走:captureRankVocab / loadRankVocab 记住上一份真实名单的职级写法(M/P 或中文任一套),恢复示例名单时沿用同一套写法 —— 导入的是科员级,示例就是科员级;导入的是 M3,示例就是 M3。这样示例数据不会再和会场配置的职级表错配。
    verify_mp.py 与 verify_roster.py 都有对应检查(「名单里出现的职级是否都被职级表覆盖」「同族代码职级按数字越大越尊定序」「示例名单沿用真实名单的职级写法」)。
  • 会场配置给的区块会被页面原样沿用(2026-09-21,CONFIG_BLOCKS / CONFIG_LAYOUT):applyProject() 在为本场景生成模板时,若用户还没在规则包里改过布局(无 audSpec / audBlocks / rows / cols / extra / extraSeats),就直接采用「会场.json」里 blocks 的形状与 layout,而不是按人数重新推算 —— 否则页面会画出与会场配置不同的区块,导致座位图与 01_make_seats.py 产出的座位表对不上(verify_mp.py 会报几十上百处不一致)。改了布局后以规则包为准(用户显式操作优先)。
  • 会议类(剧院式 / 课桌式)专用排座原则(面板 rulmask2,无高级选项):主席台与观众席分设两节。主席台节是一个可选框(2026-09-21 第三轮由下拉改为 checkbox,r2RoOn「设置主席台」):勾选后才出现内容——席位数与自定义位次;取消勾选即收起、主席台为空、全员落观众席。可设席位数(0=自动);排位自定义(2026-09-22 语义定稿)= 从左到右的座位次序:席位 5 填 1,2,3,4,5 表示从左到右依次坐 1–5 号(输入框 r2RoCustom;编号 = 编号对照里的序号,无领导标记时按 roBasis() 兜底取「席位数 N → 按职级取前 N 人」,席位数大于领导数时按职级续排补足编号 1..N;也接受直接输名单里的完整姓名)。必须按席位数填满全部席位(数量 = 席位数、编号不重复),不满足即拦截并在输入框下给红字提示、绝不静默丢弃;席位数小于领导数同样拦截(否则有人没座)。「应用主席台排位」独立按钮(applyRoCustomNow())只动主席台(席位数 + 自定义位次)、立即重排、不关面板;面板底部「应用并重排」同样受校验拦截。内部仍换算成姓名序列存 rostrumCustom,引擎按槽位直放;留空 = 恢复自动排位(1 号居中)。此项修复了「主席台自定义输入后毫无变化」——根因是名单无领导标记且席位数 0 时编号全部映射为空)。原「尊位方向」下拉(r2Dir)已删除(第三轮)。观众席节的区域数(标签已去掉「(1–9 块)」提示词)与「调整布局」按钮(2026-09-21 由「可视化布置区域(向前 / 后 / 左 / 右叠加)」改名,openVR() 未变)共同构成布局设置:面板本身不再铺开「区域1 · 左区 · 排数…」这串逐区明细(#r2AreaBox 已移除,第一屏只留区域数),区域数 = 1 时按每排总座数均分(r2FallbackSpec 兜底把全部座位视作一个整块);区域数 > 1 时点开 vrmask 可视化区域选择——以已确定的第 1 个区域为基准,用 ↑向前 / ↓向后 / ←向左 / →向右 四个方向叠加区域,可「删除选中区域」,最后「确定区域布置」回到面板逐区确认每区域排数 × 每排座数(规则包 audSpec=[{rows,cols,band,col}])。确定前必须先排「区域优先级」(第三轮新增):区域格子上由高到低依次点击(点击顺序 = 优先级,VRPRIO;未点满所有区域时「确定」被拦截),优先级写入 R2SPEC[i].prio → 座次跨排带按优先级排、layout='row' 时改为逐块坐满。座次优先级两种模式(2026-09-22 第四轮,弹窗顶部单选,VRMODE / 随规则包存 RULE.audPrioMode、openVR 回显):①按区域点选优先级(默认,如上);②不区分区域优先级(按排次序)——免点选直接「确定区域布置」,区块不带 prio,引擎走「同排带内逐排横扫」:先排第一排(带内区域按尊卑先后)、再第二排……(genSeatIds 的 layout='row' && !hasPrio 分支)。区域级排座逻辑(同轮新增,每个区域一个下拉):跟随全局 / 1号居中·左右交替 / 1号居中·向两侧对称 / 左起第一·从左到右 / 右起第一·从右到左 / 自定义位次——选自定义出输入框,按该区域每排座数填满(applyVR 校验:数量=每排座数、1..N 不重复,不满足拦截并提示;位次标签跟着人走),数据链 VRSPEC[i].lg={jw,ext,seq} → R2SPEC.lg → RULE.audSpec[].lg → audBlocksFromSpec 写 block.lg → genSeatIds 的 fillOf(b) 用区块级图案覆盖全局三维设置。也就是说「区域明细」从面板搬进了「调整布局」弹窗:平时不占版面,要点开才逐区调。另:观众席节的「预留机动席」输入项已删除(2026-09-21)——机动座改成在座位图上直接点选(见下方「预留机动座 = 座位级操作」),面板里再放一个数值框只会和座位图上的操作打架。二维模型:band = 排带(0 最靠主席台,正数向后)、col = 横向位置(0 居中,±左右);座次尊卑先按排带(靠前者先坐)、带内以 col 0 为尊向左右交替展开(右先左后),旧数据无 band/col 时按「居中为 1 向外交替」折算。观众席节另有三维排位三选项(2026-09-21 第三轮,替代旧「区域内座位排列」单选):①视角基准(主席台视角 / 观众视角,默认观众视角 = 图面左右);②尊位(正中 / 左起第一 / 右起第一,默认正中);③拓展方向(先左后右交替 / 从中间向两侧对称 / 从左到右 / 从右到左 / 自定义——选自定义出现位次标签输入框,标签跟着人走、变了座位就变、不影响其他坐席)。默认组合(观众视角 + 正中 + 先左后右交替)与旧版 4·2·1·3·5 逐值相等(k=5→[3,2,4,1,5]),旧规则包 fill/seq/dir 自动迁移、座位号 100% 不变(verify_mp.py 两套会场逐座比对证明)。引擎实现:audRowOrder(k, jw, ext) / audRowFill(k, jw, ext, view, seq)。通用原则(职级自前往后递减、同职级机关部门靠前)以说明文字呈现、自动执行。面板底部已取消「增加座位 / 新增区块」与「本场景默认」两个按钮(2026-09-21,会议类布局统一走可视化区域布置)。其他场景仍用原四维规则包面板(含高级选项、含「增加座位 / 新增区块」「本场景默认」)
  • 画布等比缩放铺满(2026-09-22 下午):座位格按原始 86px 渲染,内容超宽时 fitMap() 对 #mapIn 整体 transform:scale(k) 等比缩小铺满 #map(overflow:hidden,不出横向滚动条、不变形、区域一屏全见),并手动收掉 transform 产生的下方空白;窗口 resize 防抖 150ms 重跑 renderMap → 重新量宽。所有场景(含回字/圆桌/车辆)的 #map innerHTML 统一走 setMapHTML() 出口。旧版「横向滚动」与更早「压缩座位宽」方案均已废弃——前者要拖动条、后者名字变形。
  • 区域排座下沉到全部场景(2026-09-22 下午):剧院式那套「调整布局 / 区域级排座逻辑 / 座次优先级」原先只挂在会议类双区面板(rulmask2),其余 12 个场景拿不到。实际拆开看是四层 —— 面板层(被场景卡住)、算法层(本来就与场景无关:genSeatIds 的 fillOf(b) 把 b.lg 当区块级 override、prio 只是排序键、groupByBand/audBlocksFromSpec 对任何带 band·col 的区块通用)、渲染层(平面网格 / 方位拓扑 / 环形 / 车厢四套分支)、产出层(位次号 / fitMap / Excel 与查座页分带,已全局生效)。所以同步只做 UI 接线,通用面板(rulmask)新增「区域排座」一节,三样能力按场景分档开放:①区域内排座逻辑(RULE.blockLg={区块id:{jw,ext,seq}},applyProject 搬到 block.lg)——任何「非圆桌且每排 ≥2 座」的区块都能逐个设(回字形上边/下边、U形台上边、合影各排、长条桌两侧、签约主客、会见主客、 buffet/车厢),跟随全局 / 1号居中交替 / 1号居中对称 / 左起第一 / 右起第一 / 自定义位次(校验与剧院式同一套:按该区每排座数填满、1..N 不重复,#blkLgErr 就地拦截;语义定稿 2026-09-22 晚:输入值 = 从左到右各席显示的位次号,如 5,3,4,2,1 表示最左一席是 5 号位——引擎 audRowFill 按「位次号从小到大」的列序落座,角标显示正好等于输入;用户显式设置的区域排座逻辑优先于模板自带 fill,applyProject 落 b.lg 时同步 delete b.fill,否则签约 / 会见「主客贴中线」的填位列会静默吞掉用户设置——2026-09-22 用户实测签约自定义位次后座位纹丝不动的根因);②不区分区域优先级·按排次序(RULE.rowFirst,applyProject 把 layout 覆写为 'row')——先第一排(跨区域)坐满再第二排,适合回字形 / U形台两侧与上边同时就座;③自由增删区域(RULE.audSpec,只给 AREA_FREE = photo/buffet/longtable/sign/meet 这五个「布局本质是一块排座平面」的场景,入口「调整区域布局…」走 openVR(null,'rule'),VR_TARGET='rule' 时 applyVR 直接写规则包并重排)——回字形 / U形台不给自由摆位(blocks 带 pos,尊卑由面门 / 靠门决定,放开会让用户摆出违背礼仪的图),圆桌 / 宴请是环形、车辆是车厢过道,区域概念不成立。纵向场景的「区域」按排带折算(SPEC_BAND = photo/longtable:第 1 排 / 第 2 排、上位 / 下位侧 → band 0/1/…而不是左右并排)。签约 / 会见的区块 fill(主方 1 号贴中线、客方 1 号贴中线)在进编辑器时由 lgFromFill() 自动翻译成等价区域级排座逻辑(主方区=右起第一、客方区=左起第一),主客次序不丢。三样都是选择性启用:不动它们各场景仍走模板默认布局,老规则包落座结果 100% 不变。可视化编辑器的舞台条改为跟随当前场景(CFG.stage,合影=镜头方向、长条桌=房门方向),不再是写死的「主席台方向」。
  • 剧院式三区比例:区域数 = 3 时沿用经典「中间区加倍宽」= 25% / 50% / 25%(每排 12 座 → 左 3 / 中 6 / 右 3)。不要改成三等分:中间区是尊位区、现实中通常最宽,且改成 4/4/4 会让同一份名单的落座位置全变(与 0920 之前交付的排布不一致)。其余区域数按每排总座数均分、余数优先给中间区域。实现在 PROJECTS.theater.make() 的 nb === 3 分支
  • 预留机动座 = 座位级操作(2026-09-21):点座位图里任意座位弹出 stmask 座位编辑器——可填人名(存 seatFix,该座位被钉住、跳过自动排座次序)、可「设为预留机动」(存 seatHold,画斜纹底、不参与排座)。「清空座位」按钮(2026-09-22 加回,第三轮曾删):点「清空座位」= 钉座(special)/ 名单外固定座(seatFix)/ 预留(seatHold)全部撤销,该座位放空、重新参与自动排座,手工定座的人回到名单按职级重排(解决「手动加了人没法删除」);clearSeat() 函数本来就在,verify_roster.py 有「按钮存在 + 清空后回自动排列」检查。hold_seats 与 fixed_seats 都会从 assignSeats 的可用座位池里剔除。座位渲染统一走 seatCellHTML(),一个函数覆盖 已占 / 预留 / 钉位 / 空 四态;图例在存在预留座时显示「预留机动」
  • 增加座位(全场景通用,自由自定义弹窗)五种方式:①尾部统一加排(等比加高各区块,存规则包 extraSeats,可负可清零);②指定区块·加排(只加高选中区块,extra={mode:'blockrows',block,rows});③指定区块·每排加座/加宽(extra={mode:'blockcols',block,cols});④新增独立区块(extraBlocks=[{rows,cols,label,pos,anchor}],可反复追加,自动编号 N1/N2…,适配现实中 6 块/9 块区域会场;横向落位 pos:left=最左侧 / right=最右侧(默认)/ beside-l·beside-r=紧挨锚点区块 anchor 的左右,座号始终排在原有区块之后);⑤圆桌加席(圆桌场景自动只显示此项;多桌宴请模式下加席=自动加桌)。导入超容自动扩座仍走 extraSeats 通道。注意:新区块名称输入框 id 为 aBName(不能与人员新增表单的 aName 撞 id,撞了点「应用」会静默报错)
  • 单桌人数(多桌宴请):就餐场景打开排座原则时「单桌人数(每桌人数)」提升为第一屏选项(roundPer),改后自动重分桌
  • 过道渲染:多区块场景的区块之间显式渲染竖向「过道」标识(aisle-v,整排单行块如合影除外);回字形 / U 形台按真实方位渲染(blocks[].pos=top/left/right[/bottom],上边居中、左右两侧夹「回字中央·通道」、下边靠门),上中下之间渲染横向过道条;车辆场景(考斯特/大巴)区块内声明 aisle:2,左窗/左过道与右过道/右窗之间渲染贯穿全车的竖向过道列
  • 增加主席台:剧院式/课桌式在①会场布局面板的「主席台」节勾选「设置主席台」可选框再设席位数(0=自动);其余会议类场景用面板内「增加主席台」按钮(规则包 rostrumSeats)。空位显示在主席台条上,在「③ 个别人员调整」中把人员「设为主席台」即可落座(1 号居中),0 = 取消
  • 位次号(2026-09-22 新增,「座位位次标签跟着人走」):每个座位显示本排座次序——观众席是座位格右上角角标、主席台是姓名下小字「N 号位」,1 号位 = 本排/本台最尊位。标签跟着人走:重排、增删、主席台自定义变动后,号随座位/人更新(输入 1,2,3,4,5 时主席台从左到右就显示 1–5、最大领导坐 1 号位)。引擎实现:assignSeats 由 genSeatIds 座次顺序按「区块+排」保序分组算 seat_no = {座位号: 本排座次序} 随返回值给出,applyAssign 存 DATA.seat_no(派生数据,不进 localStorage);渲染 seatCellHTML() 加 <i class="sno">N</i>(四种形态都有,含空座)。主席台位次号 = 该领导在编号基准里的编号(自动模式 = 算法位次号、1 号居中;自定义模式 = 输入的编号;编号基准与 roBasis() 同语义——无主席台标记时按排座优先序取前 N 人)。
    顶部工具条「显示位次号」开关(#showpos,默认开,localStorage KEY_showpos 记忆):关闭即隐藏全部角标与主席台小字(body.posno-off)。verify_roster.py 有对应检查(每排连续 1..k、角标数 = 座位数、开关切换、自定义后号 = 输入)。
  • 变动对比:表格列出每个换座的人(原座位 → 新座位);「座位对比图(前 → 后)」弹窗(第三轮新增,openDiffMap()):增删 / 标记等操作后有变动即自动弹出,左右两张按会场形状缩放的 SVG 对比图——本次变动人员标黄、受影响换座人员标红、在座蓝灰、空座浅色,格子悬停显姓名,底部四色图例 + 变动人数;③面板顶部另有搜索框(#rmSearch,按姓名 / 单位 / 职务 / 职级过滤)快速定位单人。导出用「② 名单导入」入口的「导出 Excel 座位图」
  • 名单驱动:页面以名单为唯一数据源,座位由名单实时推导;localStorage 同步保存名单与座位

必须自检(在 99_verify_map.py 之外追加,三跑都必须是 PASS):

# 全部用带 openpyxl 的隔离 venv python 跑,否则 verify_export 会误报 FAIL
PY="C:/Users/<用户名>/.workbuddy/binaries/python/envs/default/Scripts/python.exe"
"$PY" scripts/verify_roster.py 座位图.html --seats seats.json     # 重排引擎 + 面板/场景 100+ 项
"$PY" scripts/verify_export.py 座位图.html --sample 真实名单.xlsx   # 导入/导出/查座页/配色
"$PY" scripts/verify_mp.py     座位图.html --seats seats.json     # 页面 JS 端 vs Python 端逐座比对

verify_roster.py(100+ 项,逐项打印):roster 构建、听众席/主席台数量、主席台位次序列、新增后重排、座位数 +1、变动对比生成、新人落座、全员有座、删除后可逆、面板可打开,以及 2026-09-21 新增的:调整布局改名 / 面板不再铺区域明细 / 已去掉预留机动席输入项、职级表自动补全、名单职级全覆盖、同族代码定序、示例名单沿用真实职级写法、车辆右高左低、会见并列式、多桌宴请主桌居中、各场景布局字段改名、礼仪文案齐备,以及第三轮的:主席台可选框 + 已删「尊位方向」下拉、三维排位(视角 / 尊位 / 拓展方向 6 条数值断言,默认组合与旧版逐值一致)、区域优先级(未点完拦截、先点 = 优先级 1、跨排带生效)、座位编辑器已删「清空该座」、主席台编号基准兜底(无领导标记按职级取前 N 人)与姓名直输、导入模板 + 「按职级大小从上到下」文案、名单搜索过滤、座位对比双图弹窗,以及 2026-09-22 的:主席台自定义语义定稿(从左到右依次填编号、必须填满全部席位、未填满/超范围/席位数<领导数均拦截)、「应用主席台排位」独立按钮(立即生效、不关面板)、不区分区域优先级(免点选直接确定、区块不带 prio、第一排全部先于第二排)、区域级排座逻辑(预设覆盖引擎图案 / 自定义位次填不满拦截·填满生效·倒序图案 1 号位落最右)、画布随区域变化(座位恒 86px + 加宽区后画布横向撑开)、清空座位按钮(钉座/固定座/预留全部撤销、放回自动排列)、排座依据改为名单导入顺序(默认优先序 = xh、1 号位 = 名单第 1 人、显式填 rank,unit,xh 仍按职级排、名单无行次时退回数组顺序、旧规则包 rank,unit,xh 一次性迁移、面板文案、真实名单下座位顺序逐位等于名单顺序),以及 2026-09-22 下午「区域排座下沉」的 7 项:区域内排座逻辑 UI 覆盖全部带排区块(14 场景逐个点,共 18 个区块)、自由区域布局入口只给平面网格型(回字形/U形台/圆桌/车辆不给)、区域级排座逻辑真实覆盖全局(U形台上边 1×4 的全局/左起/右起/自定义四套位次号逐值断言)、不区分区域优先级真实改变落座序列(回字形 block→row,R-1-1 先于 L-2-1)、通用面板「调整区域布局」可增区并写入规则包(合影按排带折算 0,1 → 3 区域)、签约/会见的主客次序(fill)被翻译保留为区域级排座逻辑、位次号跨场景一致(切走再切回不串号、已坐座位不缺号)等。
verify_export.py 四块:① 用 openpyxl 打开页面导出的 .xlsx(核对标题/区块表头/职级填充色,能打开且颜色不撞车才算过);② 用真实 Excel 名单走导入解析(deflate 解压 + 表头识别,人数必须一致);③ doImport 全链路(小名单 → 重排 → 还原);④ 导出查座页(占位符全部替换、关键人员在数据中)。结论必须 PASS。注意:它需要 openpyxl 来造那张 5 人测试 xlsx,若用基础 Python 跑会打印「跳过导入全链路测试」并误报 FAIL —— 用隔离 venv 的 python(envs/default/Scripts/python.exe)跑。
verify_mp.py(2026-09-21 重写为跟着会场配置走)三段:① 会场 rank_order 里点名的职级 → 页面 rankOrder() 读数是否相等,并与 seats.json 的合并生效职级表逐项比对;② 名单里实际出现的职级是否都被职级表覆盖(列出权重);③ 页面 JS 算出的座位 vs seats.json 是否逐座 100% 吻合。不再硬编码 M5/P1 —— M/P 双通道与中文职级两套体系都能直接跑,--seats 省略时取同目录 seats.json。

三个已知特性(不是 bug,交付时必须向用户说明):

  1. 顺延推位影响面很大:插入 1 人会导致该职级及之后的所有人顺序后移。实测 177 人会场插入 1 名副处级 → 134 人换座。所以"变动对比"是核心功能,每次调整后先看对比表再发通知
  2. 注入代码必须放在 &lt;script&gt; 最末尾:inject_roster_engine.py 已处理。原理是 ENGINE_JS/ADMIN_JS 里的 var ROSTER=[] 声明会提升但赋值不提升,若初始化块排在它们之前,构建好的名单会被后面空数组覆盖(症状:roster 0 人、recompute() 静默失败、座位数不增)
  3. 名单是唯一数据源:页面改的是名单,座位是派生的。所以"恢复原始名单"要同时清 KEY 和 KEY+&#x27;_roster&#x27; 两个 localStorage 键

踩过的坑(改动 03_make_map.py / 验证脚本前必读):

  • 03_make_map.py 的构建期替换会误伤页面里的「运行期替换模板」(2026-09-21 修复):main() 里 HTML.replace(&#x27;/*__DATA__*/&#x27;, json) 是替换全部出现位置,而 exportQueryPage() 的 JS 源码里 also 有一句 .replace(&#x27;/*__DATA__*/&#x27;, json)(它要在浏览器里替换 base64 查座页模板里的同名占位符)。构建期把后者一起替换掉,函数体就变成 .replace(&#x27;{&quot;seats&quot;:{…}&#x27;, json),于是导出的查座页数据永远是空的——点「导出查座页」能下载、能打开,但查谁都是查不到人,非常隐蔽。
    现已拆成两个互不干扰的命名空间:构建期用 __DATA_JSON__(映射 var ORIGINAL = __DATA_JSON__;),运行期保留 /*__DATA__*/;__TITLE__ 的运行期正则也改写成 new RegExp(&#x27;__TITLE&#x27; + &#x27;__&#x27;, &#x27;g&#x27;) 以避免被构建期误替换(__HEADING__ / __FOOTER__ 构建期不替换,无需处理)。
    教训:给 HTML 模板加占位符时,先确认这个字符串在页面 JS 里没有第二种用途。验证靠 verify_export.py 的「占位符已替换 / 关键人员已在查座页数据中」两项——所以改动后必须跑 verify_export,不能只跑 99_verify_map。
  • verify_export.py 的「人数必须一致」曾用 openpyxl 的 max_row,对有些 xlsx 会读到 1(read_only 模式受工作簿自带 &lt;dimension&gt; 元数据约束)。已改为实际扫非空行并设 ws.reset_dimensions = True。
  • verify_roster.py 的「主陪副陪制」用例会踩被测会场的职级表:用例用 M1–M4 编号 4 位主方、期望「主0 最尊」,但主会场的职级表是 M5 > M4 > … > M1,会把主陪判给主3。现已在该用例内临时装一份「M1 最尊、来宾最末」的职级表、测完还原,使断言与会场配置解耦。
  • verify_mp.py 曾硬编码「M5=0、P1=11」(2026-09-21 修):这个断言只对 M/P 双通道的会场成立。换到用中文职级(正处 / 科员级…)的会场,页面 rankOrder(&#x27;M5&#x27;) 当然是 9,于是席位全部吻合也照样打印 FAIL。现改为读 CFG.rank_order 逐项对、并检查名单职级全覆盖,两套体系通用。
  • 页面区块与会场配置不一致会导致「座位表与座位图对不上」(2026-09-21 修):PROJECTS.*.make(n,…) 原本按人数重新推算区块形状,而 01_make_seats.py 用的是「会场.json」的 blocks —— 两者区块不同,座位号就不同,verify_mp.py 会报上百处不一致(很容易误判成「页面重排算法错了」)。修法是快照 CONFIG_BLOCKS / CONFIG_LAYOUT,在用户没改过布局时原样沿用配置区块。排查口诀:verify_mp 大面积不一致 → 先看两边区块形状是否一样,再看职级表。

Step 5:产出扫码查座页

python scripts/04_make_query.py --seats seats.json --outdir seat-query

产出移动端页面 seat-query/index.html,功能:输入姓名实时联想、显示座位号与分区排座、给出分步找座指引、列出同单位伙伴座位、底部示意图高亮目标座位。

隐私默认值(不要改):默认隐藏全部姓名(含主席台),仅高亮查询结果;提供"显示姓名"开关供会务组核对。页面支持 ?n=姓名 参数,便于后续改为一人一码。

Step 6:发布到公网并生成二维码海报

用 workbuddy_sites_deploy 发布 seat-query 目录(language: &quot;static&quot;),拿到公网链接后:

python scripts/05_make_qr.py --url &lt;公网链接&gt; --title &quot;会议名称&quot; --outdir .

产出 座位查询二维码.png 与 扫码查座海报.png。

依赖:首次使用需在隔离环境安装 qrcode 与 pillow:

&quot;C:/Users/&lt;用户名&gt;/.workbuddy/binaries/python/versions/&lt;版本&gt;/python.exe&quot; -m venv &quot;C:/Users/&lt;用户名&gt;/.workbuddy/binaries/python/envs/default&quot;
&quot;C:/Users/&lt;用户名&gt;/.workbuddy/binaries/python/envs/default/Scripts/python.exe&quot; -m pip install qrcode pillow

交付检查清单

交付前逐项确认,任一项未过不得声称完成(未产出的交付物对应项跳过):

  • [ ] 产出范围与用户要求一致——用户只要座位图时,目录里不应出现文档 / 二维码 / 海报
  • [ ] seats.json 的核对行显示"合计核对 = 名单总数 ✅"
  • [ ] 排位序列与用户确认的规则一致(画面左→右 = 偶数降序+1+奇数升序,即 42135/642135),1 号确实居中(偶数时居右位)
  • [ ] 座位图网页已用真实浏览器渲染截图验证版式
  • [ ] 座位图已跑 99_verify_map.py,结论为 PASS(含二维码面板 8 项检查)
  • [ ] 做了 Step 4b 时,另跑 verify_roster.py,结论为 PASS(100+ 项,含「调整布局」改名、区域明细搬进弹窗、预留机动席输入项已删、职级表随名单自动补全、示例名单沿用真实职级写法、各场景个性化布局、主席台可选框与三维排位、区域优先级点选、已删「清空该座」与「尊位方向」、导入模板提示、名单搜索、座位对比双图、排座依据 = 名单导入顺序、区域排座下沉 7 项(区域内排座逻辑 UI 覆盖 / 自由布局入口分档 / 区域级逻辑覆盖全局 / 按排次序改序列 / 调整区域布局写规则包 / fill→lg 翻译保主客 / 位次号跨场景一致)等)
  • [ ] 另跑 verify_export.py,结论为 PASS——尤其确认「导出查座页」两项:占位符全部替换 + 关键人员已在查座页数据中(曾因构建期替换误伤运行期模板,导出的查座页查不到任何人)。必须用带 openpyxl 的隔离 venv python 跑,否则会因造不出测试 xlsx 而误报 FAIL
  • [ ] 另跑 verify_mp.py,确认页面 JS 重排结果与 01_make_seats.py 的 seats.json 100% 一致,且会场 rank_order 点名的职级在页面上读数相同、名单里出现的职级全部被职级表覆盖(无落兜底)
  • [ ] 会场配置与页面区块一致:会场.json 的 blocks 形状与页面画出来的区块一样(CONFIG_BLOCKS 机制保证;用户改过布局时以规则包为准)
  • [ ] 扫码页已在移动端视口(390px)渲染验证,高亮定位正确
  • [ ] 二维码已用手机实扫测试,确认链接可用(发布后必须提醒用户实扫)
  • [ ] 所有备注中的特殊约束(不参加、指定位置)已落实,并在交付说明中逐条列出
  • [ ] 提醒用户名单属内部信息,注意转发范围

必须向用户说明的默认假设

交付时用一句话说明以下事项,不要沉默交付:

  1. 排座原则用的是本技能内置标准(主席台"1 号居中、奇数左偶数右",听众席"按名单行次依次落座"——2026-09-22 起引擎不再按职级重排,名单怎么排就怎么坐),若与单位惯例不同需说明并重排
  2. 区块铺开方式为重点区块坐满再进下一块(layout: block),若现场要求逐排横向铺开需改配置重跑
  3. 机动位位置(表中"—"或虚框)建议留给工作人员
  4. 特殊约束已按备注落实,逐条列出姓名与处理方式
  5. 名单信息安全:网页内嵌数据,技术上可被提取,转发需控制范围
  6. 做了增删重排功能时:说明顺延推位会大范围换座,须用"变动对比 CSV"通知到人

常见问题

现象 原因与处理
座位不足报错 名单人数 > 可用座位,需减少 reserve_last_seats 或增加区块排数
重名提示 名单存在同名人员,脚本按先后顺序落座,需人工指定 special 定点
备注未识别 "不参加"类关键词未命中,按 is_absent() 的关键词表补充。注意误伤:备注写"只参加观摩不参加会议"会被"不参加"命中——遇到这种边界情况必须问用户,不要自行决定
某人被排到最后排 Python 端:职级写法未命中 RANK_ORDER(如"集团助理级""副总师级"等新写法),兜底按最低级处理 —— 看 01_make_seats.py 打印的未识别职级,补表后重跑。这是最隐蔽的 bug:职级表漏一项,人会掉到最后一排而脚本不报错。<br>页面端已自动化(2026-09-21):syncRankFromRoster 会按名单里实际出现的职级自动补表,不会掉兜底;「排座原则 → 高级选项 → 职级排序表」下方会列出自动补进来的条目,复制回「会场.json」的 rank_order 即可固化,让 Python 端也一致
同职级内先后不符合要求 2026-09-22 起座次完全按名单行次,直接调名单里的行顺序(导入时列表怎么排、座位就怎么落);仅主席台位次需要 rostrum_order
主席台左右与预期相反 先确认用户说的"以左为尊"是领导自身视角还是观众视角——两者左右镜像。改 rostrum_order_seq() 的序列构造方式,或直接问用户要序列
主席台人数不对 见 Step 2 的排查顺序(单位列写法 / 非班子高管 / 职级列错位)
二维码扫不开 检查是否发布成功;微信内打开公网 https 链接正常,内网地址常被拦
海报未生成 未找到 Edge/Chrome,可手动打开临时 HTML 截图;座位图页内"二维码/海报"面板可直接导出,无需外部脚本
sites_deploy 返回 needs_app_selection 工作区已有已发布应用。必须列出现有应用并用 AskUserQuestion 让用户选"覆盖"还是"新建",不得自行指定 appId。不同会议应新建,避免旧二维码失效
file:// 打开带 ?n= 参数报错 本地验证时去掉查询参数,参数仅在 http(s) 部署后有效
页面脚本"损坏":座位图空白、JS 源码显示在页面上 几乎总是验证脚本自身的注入 bug,不是页面问题。向页面注入探针时必须用 rfind(&#x27;&lt;/body&gt;&#x27;) 锚定最后一次出现——printPoster() 的 JS 字符串里也含 &lt;/body&gt;,str.replace(&#x27;&lt;/body&gt;&#x27;, …, 1) 会把探针插进 JS 字符串中间,伪造语法错误。用 99_verify_map.py / verify_roster.py 可避开
注入后新功能全部静默失效 初始化块位置错了——必须放在 &lt;script&gt; 最末尾。见 Step 4b 特性 2
headless 验证卡死超时 探针触发了页面 alert()(如未填网址就调 printPoster())。注入脚本先给 qrurl 填有效网址再调用
bash 命令全部报 command not found 本机 bash shim 可能损坏(dirname: command not found、ls/mkdir/cp/grep 全失效)。改用 Python 做文件操作:os.listdir/shutil.move/io.open;不要用 cd &amp;&amp; ls、管道 \| tail 这类 shell 语法
Edge dump-dom 对中文路径超时 file URL 需编码:urllib.parse.quote(path, safe=&#x27;/:&#x27;),且不要把盘符冒号编码成 %3A
Python 内联脚本引号转义失败 用 python -c &quot;...&quot; 写含中文引号的复杂逻辑会因转义报 SyntaxError。改用 Write 工具写成 .py 文件再执行
opencv 读中文路径报 can't open 用 cv2.imdecode(np.fromfile(path, dtype=np.uint8), cv2.IMREAD_COLOR) 代替 cv2.imread
老版 seats.json 缺 meta 报 KeyError 03_make_map.py 已兼容(d.get(&#x27;meta&#x27;));仍报错说明用了旧脚本副本
基础 Python 缺 openpyxl &quot;…/envs/default/Scripts/python.exe&quot; -m pip install openpyxl(装到隔离 venv,不要装全局)

交付目录整洁

只保留用户要的最终产出,中间产物(.probe.html、.cap.html、_v_*.png 预览图、*_raw.html)和不再需要的旧交付物统一移入 _archive_旧交付物/,不要删(用户可能还要)。根目录最终只应有:

座位图.html            ← 最终产出
名单.csv / seats.json / 会场.json   ← 数据源(可追溯、便于重跑)

不适用场景

  • 需要扫码签到统计(谁到场了)—— 本套件只做查询,不做后端记录
  • 需要参会人自助选座 —— 需要后端与并发控制,不在本套件范围
  • 会场排数每排不等(如弧形阶梯)—— 需先拆成等宽矩形区块再配置
  • 长条桌 / 圆桌 / 椭圆桌的沿边排位 —— 当前 blocks 只支持矩形区块,需手工排或扩展脚本(见"会议主席台排位法"末段)

常见问题

5 问
答案由本站依据条目字段整理
会场排座套件怎么安装?

在支持 Skills 的客户端里执行:skillhub install user_7b8d7c54/seating-chart-suite。安装方式为未标注。装完刷新技能列表或重开客户端。

会场排座套件支持哪些客户端?

资料没有标注宿主客户端,但只要客户端支持 Skills(Claude、Codex、Cursor 等),一般都能加载。

会场排座套件权限高吗,安全吗?

权限级别为未标注权限。安装前先看它会读取或写入哪些内容。

会场排座套件收费吗?

本站不代收费用,也没有标注具体价格。是否收费取决于技能本身和所用的模型或客户端,正式使用前按作者说明确认。

会场排座套件用什么许可证?

许可证标注为 未说明(许可证不明确)。商用或二次分发前请到仓库确认条款原文。

热门专题

按场景挑技能
全部专题 →

技能内容以作者仓库为准;分类、权限级别与许可证状态的中文说明为中文整理,最近核验 未标注。