增加文件类型识别以及错误数据校验

This commit is contained in:
yovinchen 2025-07-01 15:42:52 +08:00
parent 9c3470e60b
commit fcacab52c2
11 changed files with 486 additions and 548 deletions

127
log/seat_allocation_log.txt Normal file
View File

@ -0,0 +1,127 @@
[2025-07-01 15:41:09] ============================================================
[2025-07-01 15:41:09] 座位分配系统 - 文件校验
[2025-07-01 15:41:09] ============================================================
[2025-07-01 15:41:09] === 开始加载数据 ===
[2025-07-01 15:41:09] 正在读取人员信息文件: 人员信息.xlsx
[2025-07-01 15:41:09] 正在读取座位信息文件: 座位信息.xlsx
[2025-07-01 15:41:09] 开始过滤座位数据...
[2025-07-01 15:41:09] 原始数据行数: 17
[2025-07-01 15:41:09] 过滤后数据行数: 6
[2025-07-01 15:41:09] 移除无效行数: 11
[2025-07-01 15:41:09] ✅ 已过滤掉 11 行无效数据(空行、示例数据等)
[2025-07-01 15:41:09] 有效座位区域: 西北门入口场地A5区
[2025-07-01 15:41:09] 有效座位楼层: 场地
[2025-07-01 15:41:09] 清理文字数据中的空格...
[2025-07-01 15:41:09] ✅ 文字数据清理完成
[2025-07-01 15:41:09] ✅ 文件加载成功
[2025-07-01 15:41:09] 人员信息: 6 行 × 6 列
[2025-07-01 15:41:09] 座位信息: 6 行 × 12 列
[2025-07-01 15:41:09]
=== 人员信息结构校验 ===
[2025-07-01 15:41:09] ✅ 所有必需列都存在
[2025-07-01 15:41:09]
数据完整性检查:
[2025-07-01 15:41:09] ✅ 姓名 列数据完整
[2025-07-01 15:41:09] ✅ 证件类型 列数据完整
[2025-07-01 15:41:09] ✅ 证件号 列数据完整
[2025-07-01 15:41:09] ✅ 手机号 列数据完整
[2025-07-01 15:41:09] ✅ 姓名无重复
[2025-07-01 15:41:09]
=== 连坐组校验 ===
[2025-07-01 15:41:09] ✅ 第 1 组: 叶一帆 (单独)
[2025-07-01 15:41:09] ✅ 第 2 组: 刘泽 (单独)
[2025-07-01 15:41:09] ✅ 第 3 组: 黄锡恩 (单独)
[2025-07-01 15:41:09] ✅ 第 4 组: 胡中, 丁逸夫 (2人连坐)
[2025-07-01 15:41:09] ✅ 第 5 组: 沈佳琰 (单独)
[2025-07-01 15:41:09]
=== 座位信息结构校验 ===
[2025-07-01 15:41:09] ✅ 所有必需列都存在
[2025-07-01 15:41:09] ✅ 区域 列数据完整
[2025-07-01 15:41:09] ✅ 楼层 列数据完整
[2025-07-01 15:41:09] ✅ 排号 列数据完整
[2025-07-01 15:41:09] ✅ 座位号 列数据完整
[2025-07-01 15:41:09]
座位结构分析:
[2025-07-01 15:41:09]
座位结构分析:
[2025-07-01 15:41:09] ✅ 西北门入口场地A5区-场地-19排: 6 个座位完全连续 (1-6)
[2025-07-01 15:41:09]
=== 容量和可行性校验 ===
[2025-07-01 15:41:09] 总人数: 6
[2025-07-01 15:41:09] 总座位数: 6
[2025-07-01 15:41:09] ✅ 座位充足: 剩余 0 个座位
[2025-07-01 15:41:09]
连坐组需求分析:
[2025-07-01 15:41:09] 最大连坐组: 2 人
[2025-07-01 15:41:09]
连续座位可行性分析:
[2025-07-01 15:41:09] 西北门入口场地A5区-场地-19排: 最大连续 6 个座位
[2025-07-01 15:41:09]
全场最大连续座位: 6 个
[2025-07-01 15:41:09] ✅ 可以容纳最大连坐组
[2025-07-01 15:41:09] 可容纳最大连坐组的排数: 1 个
[2025-07-01 15:41:09]
连坐组分布:
[2025-07-01 15:41:09] 单人组: 4 个
[2025-07-01 15:41:09] 2人连坐组: 1 个
[2025-07-01 15:41:09]
============================================================
[2025-07-01 15:41:09] 校验结果总结
[2025-07-01 15:41:09] ============================================================
[2025-07-01 15:41:09] 人员信息结构: ✅ 通过
[2025-07-01 15:41:09] 连坐组完整性: ✅ 通过
[2025-07-01 15:41:09] 座位信息结构: ✅ 通过
[2025-07-01 15:41:09] 容量可行性: ✅ 通过
[2025-07-01 15:41:09]
总体校验结果: ✅ 全部通过
[2025-07-01 15:41:09]
🎉 文件校验通过,可以进行座位分配!
[2025-07-01 15:41:19]
============================================================
[2025-07-01 15:41:19] 开始座位分配
[2025-07-01 15:41:19] ============================================================
[2025-07-01 15:41:19]
=== 人员连坐需求分析 ===
[2025-07-01 15:41:19] 总共识别出 5 个座位组:
[2025-07-01 15:41:19] 单人组: 4 个
[2025-07-01 15:41:19] 2人连坐组: 1 个
[2025-07-01 15:41:19]
=== 高级座位结构分析 ===
[2025-07-01 15:41:19] ✅ 西北门入口场地A5区-场地-19排: 6 个座位完全连续
[2025-07-01 15:41:19]
=== 开始智能座位分配 ===
[2025-07-01 15:41:19] 需要分配 5 个组
[2025-07-01 15:41:19]
处理第 1 组: 胡中 (group, 2 人)
[2025-07-01 15:41:19] 分配到 西北门入口场地A5区-场地-19排 (连续座位: 1-2)
[2025-07-01 15:41:19] 胡中 -> 1号
[2025-07-01 15:41:19] 丁逸夫 -> 2号
[2025-07-01 15:41:19]
处理第 2 组: 叶一帆 (single, 1 人)
[2025-07-01 15:41:19] 分配到 西北门入口场地A5区-场地-19排: 叶一帆 -> 3号
[2025-07-01 15:41:19]
处理第 3 组: 刘泽 (single, 1 人)
[2025-07-01 15:41:19] 分配到 西北门入口场地A5区-场地-19排: 刘泽 -> 4号
[2025-07-01 15:41:19]
处理第 4 组: 黄锡恩 (single, 1 人)
[2025-07-01 15:41:19] 分配到 西北门入口场地A5区-场地-19排: 黄锡恩 -> 5号
[2025-07-01 15:41:19]
处理第 5 组: 沈佳琰 (single, 1 人)
[2025-07-01 15:41:19] 分配到 西北门入口场地A5区-场地-19排: 沈佳琰 -> 6号
[2025-07-01 15:41:19]
座位分配结果已保存到: log/座位信息_最终分配.xlsx
[2025-07-01 15:41:19] 分配日志已保存到: log/最终座位分配日志.xlsx
[2025-07-01 15:41:19]
=== 分配统计 ===
[2025-07-01 15:41:19] 总共分配了 6 个座位
[2025-07-01 15:41:19]
按组大小统计:
[2025-07-01 15:41:19] 单人组: 4 个组, 4 人
[2025-07-01 15:41:19] 2人连坐组: 1 个组, 2 人
[2025-07-01 15:41:19]
=== 连续性验证 ===
[2025-07-01 15:41:19] ✅ 组 1 (胡中): 2人连坐座位连续 [1, 2]
[2025-07-01 15:41:19]
连续性检查结果: 1/1 个多人组座位连续 (100.0%)
[2025-07-01 15:41:19]
🎉 座位分配完成!

Binary file not shown.

Binary file not shown.

View File

@ -1,465 +1,85 @@
[2025-06-30 20:58:50] ============================================================ [2025-07-01 15:33:27] ============================================================
[2025-06-30 20:58:50] 座位分配系统 - 文件校验 [2025-07-01 15:33:27] 座位分配系统 - 文件校验
[2025-06-30 20:58:50] ============================================================ [2025-07-01 15:33:27] ============================================================
[2025-06-30 20:58:50] === 开始加载数据 === [2025-07-01 15:33:27] === 开始加载数据 ===
[2025-06-30 20:58:50] 清理文字数据中的空格... [2025-07-01 15:33:27] 正在读取人员信息文件: 人员信息.xlsx
[2025-06-30 20:58:50] ✅ 文字数据清理完成 [2025-07-01 15:33:27] 正在读取座位信息文件: 座位信息.xlsx
[2025-06-30 20:58:50] ✅ 文件加载成功 [2025-07-01 15:33:27] 清理文字数据中的空格...
[2025-06-30 20:58:50] 人员信息: 100 行 × 6 列 [2025-07-01 15:33:27] ✅ 文字数据清理完成
[2025-06-30 20:58:50] 座位信息: 100 行 × 12 列 [2025-07-01 15:33:27] ✅ 文件加载成功
[2025-06-30 20:58:50] [2025-07-01 15:33:27] 人员信息: 6 行 × 6 列
[2025-07-01 15:33:27] 座位信息: 17 行 × 12 列
[2025-07-01 15:33:27]
=== 人员信息结构校验 === === 人员信息结构校验 ===
[2025-06-30 20:58:50] ✅ 所有必需列都存在 [2025-07-01 15:33:27] ✅ 所有必需列都存在
[2025-06-30 20:58:50] [2025-07-01 15:33:27]
数据完整性检查: 数据完整性检查:
[2025-06-30 20:58:50] ✅ 姓名 列数据完整 [2025-07-01 15:33:27] ✅ 姓名 列数据完整
[2025-06-30 20:58:50] ✅ 证件类型 列数据完整 [2025-07-01 15:33:27] ✅ 证件类型 列数据完整
[2025-06-30 20:58:50] ✅ 证件号 列数据完整 [2025-07-01 15:33:27] ✅ 证件号 列数据完整
[2025-06-30 20:58:50] ✅ 手机号 列数据完整 [2025-07-01 15:33:27] ✅ 手机号 列数据完整
[2025-06-30 20:58:50] ✅ 姓名无重复 [2025-07-01 15:33:27] ✅ 姓名无重复
[2025-06-30 20:58:50] [2025-07-01 15:33:27]
=== 连坐组校验 === === 连坐组校验 ===
[2025-06-30 20:58:50] ✅ 第 1 组: 安春利, 杨茗珺 (2人连坐) [2025-07-01 15:33:27] ✅ 第 1 组: 叶一帆 (单独)
[2025-06-30 20:58:50] ✅ 第 2 组: 侯俊帆, 杨璇羽 (2人连坐) [2025-07-01 15:33:27] ✅ 第 2 组: 刘泽 (单独)
[2025-06-30 20:58:50] ✅ 第 3 组: 刘金龙, 杨宇航 (2人连坐) [2025-07-01 15:33:27] ✅ 第 3 组: 黄锡恩 (单独)
[2025-06-30 20:58:50] ✅ 第 4 组: 张城, 张倩 (2人连坐) [2025-07-01 15:33:27] ✅ 第 4 组: 胡中, 丁逸夫 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 5 组: 陈新闻, 刘佳欢 (2人连坐) [2025-07-01 15:33:27] ✅ 第 5 组: 沈佳琰 (单独)
[2025-06-30 20:58:50] ✅ 第 6 组: 王鹏舒 (1人连坐) [2025-07-01 15:33:27]
[2025-06-30 20:58:50] ✅ 第 7 组: 孙昊, 晋秋跃 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 8 组: 刘晓雨, 李宇峥, 李霞 (3人连坐)
[2025-06-30 20:58:50] ✅ 第 9 组: 常洁, 陈媛, 王晨婧, 胡艳彬 (4人连坐)
[2025-06-30 20:58:50] ✅ 第 10 组: 高尚谦, 胡梦幻 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 11 组: 郝罡, 林杰 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 12 组: 王璐瑶, 刘昌昊 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 13 组: 吴旭 (1人连坐)
[2025-06-30 20:58:50] ✅ 第 14 组: 刘捷 (1人连坐)
[2025-06-30 20:58:50] ✅ 第 15 组: 尹泽, 尹依伊, 夏明慧, 贾娜 (4人连坐)
[2025-06-30 20:58:50] ✅ 第 16 组: 张艺馨 (单独)
[2025-06-30 20:58:50] ✅ 第 17 组: 陈宇, 房晨 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 18 组: 赵瑞, 郭闯远 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 19 组: 张然殊 (1人连坐)
[2025-06-30 20:58:50] ✅ 第 20 组: 王莲 (1人连坐)
[2025-06-30 20:58:50] ✅ 第 21 组: 王建华, 赵雅楠, 王格 (3人连坐)
[2025-06-30 20:58:50] ✅ 第 22 组: 尚校, 尚冕 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 23 组: 徐金瑞, 赵春颖 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 24 组: 赵占博, 孙羽佳, 季海洋, 刘柳 (4人连坐)
[2025-06-30 20:58:50] ✅ 第 25 组: 解子辰 (1人连坐)
[2025-06-30 20:58:50] ✅ 第 26 组: 杨文, 马新雨 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 27 组: 白建新, 李海生, 李苓 (3人连坐)
[2025-06-30 20:58:50] ✅ 第 28 组: 周勇, 常佳琦 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 29 组: 马志鑫, 肖金玲, 马学利 (3人连坐)
[2025-06-30 20:58:50] ✅ 第 30 组: 张瑞 (1人连坐)
[2025-06-30 20:58:50] ✅ 第 31 组: 李慧, 白杨 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 32 组: 赵欣悦, 金子昂 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 33 组: 马梓涵, 宋晓娟 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 34 组: 杨文彦, 彭玉荣, 袁会池, 杨文芳, 张艳芳 (5人连坐)
[2025-06-30 20:58:50] ✅ 第 35 组: 张春红, 蒋梦娇 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 36 组: 肖垚, 韩文娟 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 37 组: 朱仁龙, 肖俊斌, 孙铭泽 (3人连坐)
[2025-06-30 20:58:50] ✅ 第 38 组: 黄鹤, 张刚, 张宸宁 (3人连坐)
[2025-06-30 20:58:50] ✅ 第 39 组: 粘旻环, 李怡台 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 40 组: 文志, 刘薇 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 41 组: 李薏 (单独)
[2025-06-30 20:58:50] ✅ 第 42 组: 于浩, 王雅暄 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 43 组: 高跃, 李敏 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 44 组: 张松 (1人连坐)
[2025-06-30 20:58:50] ✅ 第 45 组: 吴晓辉, 王子宁 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 46 组: 丁勇, 焦雯 (2人连坐)
[2025-06-30 20:58:50] ✅ 第 47 组: 游伊萌 (1人连坐)
[2025-06-30 20:58:50] ✅ 第 48 组: 田悦, 叶贵天 (2人连坐)
[2025-06-30 20:58:50]
=== 座位信息结构校验 === === 座位信息结构校验 ===
[2025-06-30 20:58:50] ✅ 所有必需列都存在 [2025-07-01 15:33:27] ✅ 所有必需列都存在
[2025-06-30 20:58:50] ✅ 区域 列数据完整 [2025-07-01 15:33:27] ❌ 区域 列有 11 个空值
[2025-06-30 20:58:50] ✅ 楼层 列数据完整 [2025-07-01 15:33:27] ❌ 楼层 列有 11 个空值
[2025-06-30 20:58:50] ✅ 排号 列数据完整 [2025-07-01 15:33:27] ❌ 排号 列有 11 个空值
[2025-06-30 20:58:50] ✅ 座位号 列数据完整 [2025-07-01 15:33:27] ❌ 座位号 列有 11 个空值
[2025-06-30 20:58:50] [2025-07-01 15:33:27]
座位结构分析: 座位结构分析:
[2025-06-30 20:58:50] [2025-07-01 15:33:27]
座位结构分析: 座位结构分析:
[2025-06-30 20:58:50] ✅ 区7895通道-五层-8排: 4 个座位完全连续 (1-4) [2025-07-01 15:33:27] ✅ 西北门入口场地A5区-场地-19排: 6 个座位完全连续 (1-6)
[2025-06-30 20:58:50] ✅ 区7895通道-五层-9排: 10 个座位完全连续 (1-10) [2025-07-01 15:33:27] ❌ nan-nan-nan: 座位号格式异常 'nan'
[2025-06-30 20:58:50] ✅ 区7895通道-五层-10排: 5 个座位完全连续 (1-5) [2025-07-01 15:33:27] ❌ nan-nan-nan: 座位号格式异常 'nan'
[2025-06-30 20:58:50] ✅ A区136通道-五层-10排: 5 个座位完全连续 (6-10) [2025-07-01 15:33:27] ❌ nan-nan-nan: 座位号格式异常 'nan'
[2025-06-30 20:58:50] 📊 A区136通道-五层-11排: 11 个座位2 个连续段: 1-2, 5-13 [2025-07-01 15:33:27] ❌ nan-nan-nan: 座位号格式异常 'nan'
[2025-06-30 20:58:50] 最大连续段: 9 个座位 [2025-07-01 15:33:27] ❌ nan-nan-nan: 座位号格式异常 'nan'
[2025-06-30 20:58:50] ✅ A区136通道-五层-12排: 1 个座位完全连续 (1-1) [2025-07-01 15:33:27] ❌ nan-nan-nan: 座位号格式异常 'nan'
[2025-06-30 20:58:50] ✅ A区136通道-三层-12排: 10 个座位完全连续 (2-11) [2025-07-01 15:33:27] ❌ nan-nan-nan: 座位号格式异常 'nan'
[2025-06-30 20:58:50] ✅ 区552通道-三层-12排: 2 个座位完全连续 (12-13) [2025-07-01 15:33:27] ❌ nan-nan-nan: 座位号格式异常 'nan'
[2025-06-30 20:58:50] ✅ 区552通道-三层-13排: 13 个座位完全连续 (1-13) [2025-07-01 15:33:27] ❌ nan-nan-nan: 座位号格式异常 'nan'
[2025-06-30 20:58:50] ✅ 区552通道-三层-14排: 9 个座位完全连续 (1-9) [2025-07-01 15:33:27] ❌ nan-nan-nan: 座位号格式异常 'nan'
[2025-06-30 20:58:50] ✅ 区552通道-五层-14排: 4 个座位完全连续 (10-13) [2025-07-01 15:33:27] ❌ nan-nan-nan: 座位号格式异常 'nan'
[2025-06-30 20:58:50] 📊 区552通道-五层-15排: 11 个座位2 个连续段: 1-7, 10-13 [2025-07-01 15:33:27] 📊 nan-nan-nan: 11 个座位0 个连续段:
[2025-06-30 20:58:50] 最大连续段: 7 个座位 [2025-07-01 15:33:27] 最大连续段: 0 个座位
[2025-06-30 20:58:50] ✅ 区552通道-五层-16排: 13 个座位完全连续 (1-13) [2025-07-01 15:33:27]
[2025-06-30 20:58:50] ✅ 区552通道-五层-17排: 2 个座位完全连续 (1-2)
[2025-06-30 20:58:50]
=== 容量和可行性校验 === === 容量和可行性校验 ===
[2025-06-30 20:58:50] 总人数: 100 [2025-07-01 15:33:27] 总人数: 6
[2025-06-30 20:58:50] 总座位数: 100 [2025-07-01 15:33:27] 总座位数: 17
[2025-06-30 20:58:50] ✅ 座位充足: 剩余 0 个座位 [2025-07-01 15:33:27] ✅ 座位充足: 剩余 11 个座位
[2025-06-30 20:58:50] [2025-07-01 15:33:27]
连坐组需求分析: 连坐组需求分析:
[2025-06-30 20:58:50] 最大连坐组: 5 [2025-07-01 15:33:27] 最大连坐组: 2 人
[2025-06-30 20:58:50] [2025-07-01 15:33:27]
连续座位可行性分析: 连续座位可行性分析:
[2025-06-30 20:58:50] 区7895通道-五层-8排: 最大连续 4 个座位 [2025-07-01 15:33:27] 西北门入口场地A5区-场地-19排: 最大连续 6 个座位
[2025-06-30 20:58:50] 区7895通道-五层-9排: 最大连续 10 个座位 [2025-07-01 15:33:27] nan-nan-nan: 最大连续 0 个座位
[2025-06-30 20:58:50] 区7895通道-五层-10排: 最大连续 5 个座位 [2025-07-01 15:33:27]
[2025-06-30 20:58:50] A区136通道-五层-10排: 最大连续 5 个座位 全场最大连续座位: 6 个
[2025-06-30 20:58:50] A区136通道-五层-11排: 最大连续 9 个座位 [2025-07-01 15:33:27] ✅ 可以容纳最大连坐组
[2025-06-30 20:58:50] A区136通道-五层-12排: 最大连续 1 个座位 [2025-07-01 15:33:27] 可容纳最大连坐组的排数: 1 个
[2025-06-30 20:58:50] A区136通道-三层-12排: 最大连续 10 个座位 [2025-07-01 15:33:27]
[2025-06-30 20:58:50] 区552通道-三层-12排: 最大连续 2 个座位
[2025-06-30 20:58:50] 区552通道-三层-13排: 最大连续 13 个座位
[2025-06-30 20:58:50] 区552通道-三层-14排: 最大连续 9 个座位
[2025-06-30 20:58:50] 区552通道-五层-14排: 最大连续 4 个座位
[2025-06-30 20:58:50] 区552通道-五层-15排: 最大连续 7 个座位
[2025-06-30 20:58:50] 区552通道-五层-16排: 最大连续 13 个座位
[2025-06-30 20:58:50] 区552通道-五层-17排: 最大连续 2 个座位
[2025-06-30 20:58:50]
全场最大连续座位: 13 个
[2025-06-30 20:58:50] ✅ 可以容纳最大连坐组
[2025-06-30 20:58:50] 可容纳最大连坐组的排数: 9 个
[2025-06-30 20:58:50]
连坐组分布: 连坐组分布:
[2025-06-30 20:58:50] 单人组: 11 个 [2025-07-01 15:33:27] 单人组: 4 个
[2025-06-30 20:58:50] 2人连坐组: 27 个 [2025-07-01 15:33:27] 2人连坐组: 1 个
[2025-06-30 20:58:50] 3人连坐组: 6 个 [2025-07-01 15:33:27]
[2025-06-30 20:58:50] 4人连坐组: 3 个
[2025-06-30 20:58:50] 5人连坐组: 1 个
[2025-06-30 20:58:50]
============================================================ ============================================================
[2025-06-30 20:58:50] 校验结果总结 [2025-07-01 15:33:27] 校验结果总结
[2025-06-30 20:58:50] ============================================================ [2025-07-01 15:33:27] ============================================================
[2025-06-30 20:58:50] 人员信息结构: ✅ 通过 [2025-07-01 15:33:27] 人员信息结构: ✅ 通过
[2025-06-30 20:58:50] 连坐组完整性: ✅ 通过 [2025-07-01 15:33:27] 连坐组完整性: ✅ 通过
[2025-06-30 20:58:50] 座位信息结构: ✅ 通过 [2025-07-01 15:33:27] 座位信息结构: ❌ 失败
[2025-06-30 20:58:50] 容量可行性: ✅ 通过 [2025-07-01 15:33:27] 容量可行性: ✅ 通过
[2025-06-30 20:58:50] [2025-07-01 15:33:27]
总体校验结果: ✅ 全部通过 总体校验结果: ❌ 存在问题
[2025-06-30 20:58:50] [2025-07-01 15:33:27]
🎉 文件校验通过,可以进行座位分配! ⚠️ 请修复上述问题后再进行座位分配。
[2025-06-30 20:58:53]
============================================================
[2025-06-30 20:58:53] 开始座位分配
[2025-06-30 20:58:53] ============================================================
[2025-06-30 20:58:53]
=== 人员连坐需求分析 ===
[2025-06-30 20:58:53] 总共识别出 48 个座位组:
[2025-06-30 20:58:53] 单人组: 11 个
[2025-06-30 20:58:53] 2人连坐组: 27 个
[2025-06-30 20:58:53] 3人连坐组: 6 个
[2025-06-30 20:58:53] 4人连坐组: 3 个
[2025-06-30 20:58:53] 5人连坐组: 1 个
[2025-06-30 20:58:53]
=== 高级座位结构分析 ===
[2025-06-30 20:58:53] ✅ 区7895通道-五层-8排: 4 个座位完全连续
[2025-06-30 20:58:53] ✅ 区7895通道-五层-9排: 10 个座位完全连续
[2025-06-30 20:58:53] ✅ 区7895通道-五层-10排: 5 个座位完全连续
[2025-06-30 20:58:53] ✅ A区136通道-五层-10排: 5 个座位完全连续
[2025-06-30 20:58:53] 📊 A区136通道-五层-11排: 11 个座位2 段: 1-2, 5-13
[2025-06-30 20:58:53] 最大连续段: 9 个座位
[2025-06-30 20:58:53] ✅ A区136通道-五层-12排: 1 个座位完全连续
[2025-06-30 20:58:53] ✅ A区136通道-三层-12排: 10 个座位完全连续
[2025-06-30 20:58:53] ✅ 区552通道-三层-12排: 2 个座位完全连续
[2025-06-30 20:58:53] ✅ 区552通道-三层-13排: 13 个座位完全连续
[2025-06-30 20:58:53] ✅ 区552通道-三层-14排: 9 个座位完全连续
[2025-06-30 20:58:53] ✅ 区552通道-五层-14排: 4 个座位完全连续
[2025-06-30 20:58:53] 📊 区552通道-五层-15排: 11 个座位2 段: 1-7, 10-13
[2025-06-30 20:58:53] 最大连续段: 7 个座位
[2025-06-30 20:58:53] ✅ 区552通道-五层-16排: 13 个座位完全连续
[2025-06-30 20:58:53] ✅ 区552通道-五层-17排: 2 个座位完全连续
[2025-06-30 20:58:53]
=== 开始智能座位分配 ===
[2025-06-30 20:58:53] 需要分配 48 个组
[2025-06-30 20:58:53]
处理第 1 组: 杨文彦 (group, 5 人)
[2025-06-30 20:58:53] 分配到 区7895通道-五层-9排 (连续座位: 1-5)
[2025-06-30 20:58:53] 杨文彦 -> 1号
[2025-06-30 20:58:53] 彭玉荣 -> 2号
[2025-06-30 20:58:53] 袁会池 -> 3号
[2025-06-30 20:58:53] 杨文芳 -> 4号
[2025-06-30 20:58:53] 张艳芳 -> 5号
[2025-06-30 20:58:53]
处理第 2 组: 常洁 (group, 4 人)
[2025-06-30 20:58:53] 分配到 区7895通道-五层-8排 (连续座位: 1-4)
[2025-06-30 20:58:53] 常洁 -> 1号
[2025-06-30 20:58:53] 陈媛 -> 2号
[2025-06-30 20:58:53] 王晨婧 -> 3号
[2025-06-30 20:58:53] 胡艳彬 -> 4号
[2025-06-30 20:58:53]
处理第 3 组: 尹泽 (group, 4 人)
[2025-06-30 20:58:53] 分配到 区7895通道-五层-9排 (连续座位: 6-9)
[2025-06-30 20:58:53] 尹泽 -> 6号
[2025-06-30 20:58:53] 尹依伊 -> 7号
[2025-06-30 20:58:53] 夏明慧 -> 8号
[2025-06-30 20:58:53] 贾娜 -> 9号
[2025-06-30 20:58:53]
处理第 4 组: 赵占博 (group, 4 人)
[2025-06-30 20:58:53] 分配到 区7895通道-五层-10排 (连续座位: 1-4)
[2025-06-30 20:58:53] 赵占博 -> 1号
[2025-06-30 20:58:53] 孙羽佳 -> 2号
[2025-06-30 20:58:53] 季海洋 -> 3号
[2025-06-30 20:58:53] 刘柳 -> 4号
[2025-06-30 20:58:53]
处理第 5 组: 刘晓雨 (group, 3 人)
[2025-06-30 20:58:53] 分配到 A区136通道-五层-10排 (连续座位: 6-8)
[2025-06-30 20:58:53] 刘晓雨 -> 6号
[2025-06-30 20:58:53] 李宇峥 -> 7号
[2025-06-30 20:58:53] 李霞 -> 8号
[2025-06-30 20:58:53]
处理第 6 组: 王建华 (group, 3 人)
[2025-06-30 20:58:53] 分配到 A区136通道-五层-11排 (连续座位: 5-7)
[2025-06-30 20:58:53] 王建华 -> 5号
[2025-06-30 20:58:53] 赵雅楠 -> 6号
[2025-06-30 20:58:53] 王格 -> 7号
[2025-06-30 20:58:53]
处理第 7 组: 白建新 (group, 3 人)
[2025-06-30 20:58:53] 分配到 A区136通道-五层-11排 (连续座位: 8-10)
[2025-06-30 20:58:53] 白建新 -> 8号
[2025-06-30 20:58:53] 李海生 -> 9号
[2025-06-30 20:58:53] 李苓 -> 10号
[2025-06-30 20:58:53]
处理第 8 组: 马志鑫 (group, 3 人)
[2025-06-30 20:58:53] 分配到 A区136通道-五层-11排 (连续座位: 11-13)
[2025-06-30 20:58:53] 马志鑫 -> 11号
[2025-06-30 20:58:53] 肖金玲 -> 12号
[2025-06-30 20:58:53] 马学利 -> 13号
[2025-06-30 20:58:53]
处理第 9 组: 朱仁龙 (group, 3 人)
[2025-06-30 20:58:53] 分配到 A区136通道-三层-12排 (连续座位: 2-4)
[2025-06-30 20:58:53] 朱仁龙 -> 2号
[2025-06-30 20:58:53] 肖俊斌 -> 3号
[2025-06-30 20:58:53] 孙铭泽 -> 4号
[2025-06-30 20:58:53]
处理第 10 组: 黄鹤 (group, 3 人)
[2025-06-30 20:58:53] 分配到 A区136通道-三层-12排 (连续座位: 5-7)
[2025-06-30 20:58:53] 黄鹤 -> 5号
[2025-06-30 20:58:53] 张刚 -> 6号
[2025-06-30 20:58:53] 张宸宁 -> 7号
[2025-06-30 20:58:53]
处理第 11 组: 安春利 (group, 2 人)
[2025-06-30 20:58:53] 分配到 A区136通道-五层-10排 (连续座位: 9-10)
[2025-06-30 20:58:53] 安春利 -> 9号
[2025-06-30 20:58:53] 杨茗珺 -> 10号
[2025-06-30 20:58:53]
处理第 12 组: 侯俊帆 (group, 2 人)
[2025-06-30 20:58:53] 分配到 A区136通道-五层-11排 (连续座位: 1-2)
[2025-06-30 20:58:53] 侯俊帆 -> 1号
[2025-06-30 20:58:53] 杨璇羽 -> 2号
[2025-06-30 20:58:53]
处理第 13 组: 刘金龙 (group, 2 人)
[2025-06-30 20:58:53] 分配到 A区136通道-三层-12排 (连续座位: 8-9)
[2025-06-30 20:58:53] 刘金龙 -> 8号
[2025-06-30 20:58:53] 杨宇航 -> 9号
[2025-06-30 20:58:53]
处理第 14 组: 张城 (group, 2 人)
[2025-06-30 20:58:53] 分配到 A区136通道-三层-12排 (连续座位: 10-11)
[2025-06-30 20:58:53] 张城 -> 10号
[2025-06-30 20:58:53] 张倩 -> 11号
[2025-06-30 20:58:53]
处理第 15 组: 陈新闻 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-三层-12排 (连续座位: 12-13)
[2025-06-30 20:58:53] 陈新闻 -> 12号
[2025-06-30 20:58:53] 刘佳欢 -> 13号
[2025-06-30 20:58:53]
处理第 16 组: 孙昊 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-三层-13排 (连续座位: 1-2)
[2025-06-30 20:58:53] 孙昊 -> 1号
[2025-06-30 20:58:53] 晋秋跃 -> 2号
[2025-06-30 20:58:53]
处理第 17 组: 高尚谦 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-三层-13排 (连续座位: 3-4)
[2025-06-30 20:58:53] 高尚谦 -> 3号
[2025-06-30 20:58:53] 胡梦幻 -> 4号
[2025-06-30 20:58:53]
处理第 18 组: 郝罡 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-三层-13排 (连续座位: 5-6)
[2025-06-30 20:58:53] 郝罡 -> 5号
[2025-06-30 20:58:53] 林杰 -> 6号
[2025-06-30 20:58:53]
处理第 19 组: 王璐瑶 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-三层-13排 (连续座位: 7-8)
[2025-06-30 20:58:53] 王璐瑶 -> 7号
[2025-06-30 20:58:53] 刘昌昊 -> 8号
[2025-06-30 20:58:53]
处理第 20 组: 陈宇 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-三层-13排 (连续座位: 9-10)
[2025-06-30 20:58:53] 陈宇 -> 9号
[2025-06-30 20:58:53] 房晨 -> 10号
[2025-06-30 20:58:53]
处理第 21 组: 赵瑞 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-三层-13排 (连续座位: 11-12)
[2025-06-30 20:58:53] 赵瑞 -> 11号
[2025-06-30 20:58:53] 郭闯远 -> 12号
[2025-06-30 20:58:53]
处理第 22 组: 尚校 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-三层-14排 (连续座位: 1-2)
[2025-06-30 20:58:53] 尚校 -> 1号
[2025-06-30 20:58:53] 尚冕 -> 2号
[2025-06-30 20:58:53]
处理第 23 组: 徐金瑞 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-三层-14排 (连续座位: 3-4)
[2025-06-30 20:58:53] 徐金瑞 -> 3号
[2025-06-30 20:58:53] 赵春颖 -> 4号
[2025-06-30 20:58:53]
处理第 24 组: 杨文 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-三层-14排 (连续座位: 5-6)
[2025-06-30 20:58:53] 杨文 -> 5号
[2025-06-30 20:58:53] 马新雨 -> 6号
[2025-06-30 20:58:53]
处理第 25 组: 周勇 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-三层-14排 (连续座位: 7-8)
[2025-06-30 20:58:53] 周勇 -> 7号
[2025-06-30 20:58:53] 常佳琦 -> 8号
[2025-06-30 20:58:53]
处理第 26 组: 李慧 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-14排 (连续座位: 10-11)
[2025-06-30 20:58:53] 李慧 -> 10号
[2025-06-30 20:58:53] 白杨 -> 11号
[2025-06-30 20:58:53]
处理第 27 组: 赵欣悦 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-14排 (连续座位: 12-13)
[2025-06-30 20:58:53] 赵欣悦 -> 12号
[2025-06-30 20:58:53] 金子昂 -> 13号
[2025-06-30 20:58:53]
处理第 28 组: 马梓涵 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-15排 (连续座位: 1-2)
[2025-06-30 20:58:53] 马梓涵 -> 1号
[2025-06-30 20:58:53] 宋晓娟 -> 2号
[2025-06-30 20:58:53]
处理第 29 组: 张春红 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-15排 (连续座位: 3-4)
[2025-06-30 20:58:53] 张春红 -> 3号
[2025-06-30 20:58:53] 蒋梦娇 -> 4号
[2025-06-30 20:58:53]
处理第 30 组: 肖垚 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-15排 (连续座位: 5-6)
[2025-06-30 20:58:53] 肖垚 -> 5号
[2025-06-30 20:58:53] 韩文娟 -> 6号
[2025-06-30 20:58:53]
处理第 31 组: 粘旻环 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-15排 (连续座位: 10-11)
[2025-06-30 20:58:53] 粘旻环 -> 10号
[2025-06-30 20:58:53] 李怡台 -> 11号
[2025-06-30 20:58:53]
处理第 32 组: 文志 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-15排 (连续座位: 12-13)
[2025-06-30 20:58:53] 文志 -> 12号
[2025-06-30 20:58:53] 刘薇 -> 13号
[2025-06-30 20:58:53]
处理第 33 组: 于浩 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-16排 (连续座位: 1-2)
[2025-06-30 20:58:53] 于浩 -> 1号
[2025-06-30 20:58:53] 王雅暄 -> 2号
[2025-06-30 20:58:53]
处理第 34 组: 高跃 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-16排 (连续座位: 3-4)
[2025-06-30 20:58:53] 高跃 -> 3号
[2025-06-30 20:58:53] 李敏 -> 4号
[2025-06-30 20:58:53]
处理第 35 组: 吴晓辉 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-16排 (连续座位: 5-6)
[2025-06-30 20:58:53] 吴晓辉 -> 5号
[2025-06-30 20:58:53] 王子宁 -> 6号
[2025-06-30 20:58:53]
处理第 36 组: 丁勇 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-16排 (连续座位: 7-8)
[2025-06-30 20:58:53] 丁勇 -> 7号
[2025-06-30 20:58:53] 焦雯 -> 8号
[2025-06-30 20:58:53]
处理第 37 组: 田悦 (group, 2 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-16排 (连续座位: 9-10)
[2025-06-30 20:58:53] 田悦 -> 9号
[2025-06-30 20:58:53] 叶贵天 -> 10号
[2025-06-30 20:58:53]
处理第 38 组: 王鹏舒 (single, 1 人)
[2025-06-30 20:58:53] 分配到 区7895通道-五层-9排: 王鹏舒 -> 10号
[2025-06-30 20:58:53]
处理第 39 组: 吴旭 (single, 1 人)
[2025-06-30 20:58:53] 分配到 区7895通道-五层-10排: 吴旭 -> 5号
[2025-06-30 20:58:53]
处理第 40 组: 刘捷 (single, 1 人)
[2025-06-30 20:58:53] 分配到 A区136通道-五层-12排: 刘捷 -> 1号
[2025-06-30 20:58:53]
处理第 41 组: 张艺馨 (single, 1 人)
[2025-06-30 20:58:53] 分配到 区552通道-三层-13排: 张艺馨 -> 13号
[2025-06-30 20:58:53]
处理第 42 组: 张然殊 (single, 1 人)
[2025-06-30 20:58:53] 分配到 区552通道-三层-14排: 张然殊 -> 9号
[2025-06-30 20:58:53]
处理第 43 组: 王莲 (single, 1 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-15排: 王莲 -> 7号
[2025-06-30 20:58:53]
处理第 44 组: 解子辰 (single, 1 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-16排: 解子辰 -> 11号
[2025-06-30 20:58:53]
处理第 45 组: 张瑞 (single, 1 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-16排: 张瑞 -> 12号
[2025-06-30 20:58:53]
处理第 46 组: 李薏 (single, 1 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-16排: 李薏 -> 13号
[2025-06-30 20:58:53]
处理第 47 组: 张松 (single, 1 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-17排: 张松 -> 1号
[2025-06-30 20:58:53]
处理第 48 组: 游伊萌 (single, 1 人)
[2025-06-30 20:58:53] 分配到 区552通道-五层-17排: 游伊萌 -> 2号
[2025-06-30 20:58:53]
座位分配结果已保存到: 座位信息_最终分配.xlsx
[2025-06-30 20:58:53] 分配日志已保存到: 最终座位分配日志.xlsx
[2025-06-30 20:58:53]
=== 分配统计 ===
[2025-06-30 20:58:53] 总共分配了 100 个座位
[2025-06-30 20:58:53]
按组大小统计:
[2025-06-30 20:58:53] 单人组: 11 个组, 11 人
[2025-06-30 20:58:53] 2人连坐组: 27 个组, 54 人
[2025-06-30 20:58:53] 3人连坐组: 6 个组, 18 人
[2025-06-30 20:58:53] 4人连坐组: 3 个组, 12 人
[2025-06-30 20:58:53] 5人连坐组: 1 个组, 5 人
[2025-06-30 20:58:53]
=== 连续性验证 ===
[2025-06-30 20:58:53] ✅ 组 1 (杨文彦): 5人连坐座位连续 [1, 2, 3, 4, 5]
[2025-06-30 20:58:53] ✅ 组 2 (常洁): 4人连坐座位连续 [1, 2, 3, 4]
[2025-06-30 20:58:53] ✅ 组 3 (尹泽): 4人连坐座位连续 [6, 7, 8, 9]
[2025-06-30 20:58:53] ✅ 组 4 (赵占博): 4人连坐座位连续 [1, 2, 3, 4]
[2025-06-30 20:58:53] ✅ 组 5 (刘晓雨): 3人连坐座位连续 [6, 7, 8]
[2025-06-30 20:58:53] ✅ 组 6 (王建华): 3人连坐座位连续 [5, 6, 7]
[2025-06-30 20:58:53] ✅ 组 7 (白建新): 3人连坐座位连续 [8, 9, 10]
[2025-06-30 20:58:53] ✅ 组 8 (马志鑫): 3人连坐座位连续 [11, 12, 13]
[2025-06-30 20:58:53] ✅ 组 9 (朱仁龙): 3人连坐座位连续 [2, 3, 4]
[2025-06-30 20:58:53] ✅ 组 10 (黄鹤): 3人连坐座位连续 [5, 6, 7]
[2025-06-30 20:58:53] ✅ 组 11 (安春利): 2人连坐座位连续 [9, 10]
[2025-06-30 20:58:53] ✅ 组 12 (侯俊帆): 2人连坐座位连续 [1, 2]
[2025-06-30 20:58:53] ✅ 组 13 (刘金龙): 2人连坐座位连续 [8, 9]
[2025-06-30 20:58:53] ✅ 组 14 (张城): 2人连坐座位连续 [10, 11]
[2025-06-30 20:58:53] ✅ 组 15 (陈新闻): 2人连坐座位连续 [12, 13]
[2025-06-30 20:58:53] ✅ 组 16 (孙昊): 2人连坐座位连续 [1, 2]
[2025-06-30 20:58:53] ✅ 组 17 (高尚谦): 2人连坐座位连续 [3, 4]
[2025-06-30 20:58:53] ✅ 组 18 (郝罡): 2人连坐座位连续 [5, 6]
[2025-06-30 20:58:53] ✅ 组 19 (王璐瑶): 2人连坐座位连续 [7, 8]
[2025-06-30 20:58:53] ✅ 组 20 (陈宇): 2人连坐座位连续 [9, 10]
[2025-06-30 20:58:53] ✅ 组 21 (赵瑞): 2人连坐座位连续 [11, 12]
[2025-06-30 20:58:53] ✅ 组 22 (尚校): 2人连坐座位连续 [1, 2]
[2025-06-30 20:58:53] ✅ 组 23 (徐金瑞): 2人连坐座位连续 [3, 4]
[2025-06-30 20:58:53] ✅ 组 24 (杨文): 2人连坐座位连续 [5, 6]
[2025-06-30 20:58:53] ✅ 组 25 (周勇): 2人连坐座位连续 [7, 8]
[2025-06-30 20:58:53] ✅ 组 26 (李慧): 2人连坐座位连续 [10, 11]
[2025-06-30 20:58:53] ✅ 组 27 (赵欣悦): 2人连坐座位连续 [12, 13]
[2025-06-30 20:58:53] ✅ 组 28 (马梓涵): 2人连坐座位连续 [1, 2]
[2025-06-30 20:58:53] ✅ 组 29 (张春红): 2人连坐座位连续 [3, 4]
[2025-06-30 20:58:53] ✅ 组 30 (肖垚): 2人连坐座位连续 [5, 6]
[2025-06-30 20:58:53] ✅ 组 31 (粘旻环): 2人连坐座位连续 [10, 11]
[2025-06-30 20:58:53] ✅ 组 32 (文志): 2人连坐座位连续 [12, 13]
[2025-06-30 20:58:53] ✅ 组 33 (于浩): 2人连坐座位连续 [1, 2]
[2025-06-30 20:58:53] ✅ 组 34 (高跃): 2人连坐座位连续 [3, 4]
[2025-06-30 20:58:53] ✅ 组 35 (吴晓辉): 2人连坐座位连续 [5, 6]
[2025-06-30 20:58:53] ✅ 组 36 (丁勇): 2人连坐座位连续 [7, 8]
[2025-06-30 20:58:53] ✅ 组 37 (田悦): 2人连坐座位连续 [9, 10]
[2025-06-30 20:58:53]
连续性检查结果: 37/37 个多人组座位连续 (100.0%)
[2025-06-30 20:58:53]
🎉 座位分配完成!

View File

@ -55,28 +55,142 @@ def check_dependencies():
return True return True
def check_data_files(): def auto_detect_files():
"""检查必要的数据文件""" """自动检测和识别Excel文件"""
required_files = ['人员信息.xlsx', '座位信息.xlsx'] print("\n=== 自动文件识别系统 ===")
missing_files = []
print("\n检查数据文件...") # 扫描当前目录下的所有xlsx文件
for file_name in required_files: current_dir = Path('.')
if Path(file_name).exists(): xlsx_files = list(current_dir.glob('*.xlsx'))
print(f"{file_name} 存在")
# 过滤掉输出文件和示例文件
exclude_patterns = ['座位信息_最终分配', '最终座位分配日志', '_示例', '_temp', '_backup']
xlsx_files = [f for f in xlsx_files if not any(pattern in f.name for pattern in exclude_patterns)]
print(f"发现 {len(xlsx_files)} 个Excel文件:")
for i, file_path in enumerate(xlsx_files, 1):
file_size = file_path.stat().st_size / 1024 # KB
print(f" {i}. {file_path.name} ({file_size:.1f} KB)")
if len(xlsx_files) == 0:
print("\n❌ 未找到Excel文件")
print("请确保当前目录下有Excel数据文件")
return None, None
if len(xlsx_files) > 2:
print(f"\n⚠️ 发现 {len(xlsx_files)} 个Excel文件超过2个")
print("为避免混淆请确保目录下只有2个数据文件")
print("(程序会自动忽略输出文件和示例文件)")
print("\n请手动移除多余文件,或选择要使用的文件:")
for i, file_path in enumerate(xlsx_files, 1):
print(f" {i}. {file_path.name}")
return None, None
# 分析文件结构
print(f"\n正在分析文件结构...")
file_info = []
for file_path in xlsx_files:
try:
# 读取文件获取基本信息
df = pd.read_excel(file_path, nrows=5) # 只读前5行进行分析
info = {
'path': file_path,
'name': file_path.name,
'columns': len(df.columns),
'rows': len(df) + 1, # 加上标题行
'column_names': list(df.columns),
'sample_data': df.head(2) # 获取前2行样本数据
}
file_info.append(info)
print(f"\n📄 {file_path.name}:")
print(f" 列数: {info['columns']}")
print(f" 行数: {info['rows']}+ (仅检查前5行)")
print(f" 列名: {', '.join(str(col) for col in info['column_names'][:6])}{'...' if len(info['column_names']) > 6 else ''}")
except Exception as e:
print(f"\n❌ 读取文件 {file_path.name} 失败: {e}")
return None, None
# 根据列数自动识别文件类型
personnel_file = None
seat_file = None
print(f"\n=== 文件类型识别 ===")
for info in file_info:
if info['columns'] == 5 or info['columns'] == 6: # 人员信息通常是5-6列
# 进一步检查列名是否符合人员信息格式
col_names = [str(col).lower() for col in info['column_names']]
personnel_keywords = ['姓名', 'name', '证件', 'id', '手机', 'phone', '备注', 'remark']
if any(keyword in ' '.join(col_names) for keyword in personnel_keywords):
personnel_file = info
print(f"{info['name']} -> 识别为人员信息文件 ({info['columns']}列)")
else:
print(f"⚠️ {info['name']}{info['columns']}列,但列名不符合人员信息格式")
elif info['columns'] >= 10: # 座位信息通常是10-12列
# 进一步检查列名是否符合座位信息格式
col_names = [str(col).lower() for col in info['column_names']]
seat_keywords = ['区域', 'area', '楼层', 'floor', '排号', 'row', '座位', 'seat']
if any(keyword in ' '.join(col_names) for keyword in seat_keywords):
seat_file = info
print(f"{info['name']} -> 识别为座位信息文件 ({info['columns']}列)")
else:
print(f"⚠️ {info['name']}{info['columns']}列,但列名不符合座位信息格式")
else: else:
missing_files.append(file_name) print(f"{info['name']}{info['columns']}列,无法自动识别类型")
print(f"{file_name} 不存在")
if missing_files: # 验证识别结果
print(f"\n❌ 缺少必要文件: {', '.join(missing_files)}") if personnel_file is None:
print("\n请确保以下文件存在于程序同一目录下:") print(f"\n❌ 未找到人员信息文件")
print("1. 人员信息.xlsx - 包含姓名、证件类型、证件号、手机号、备注等列") print("人员信息文件应包含: 姓名、证件类型、证件号、手机号、备注等列")
print("2. 座位信息.xlsx - 包含区域、楼层、排号、座位号等列") return None, None
if seat_file is None:
print(f"\n❌ 未找到座位信息文件")
print("座位信息文件应包含: 区域、楼层、排号、座位号等列")
return None, None
print(f"\n🎉 文件识别成功!")
print(f"人员信息: {personnel_file['name']}")
print(f"座位信息: {seat_file['name']}")
# 显示文件内容预览
print(f"\n=== 文件内容预览 ===")
print(f"\n📋 人员信息文件预览 ({personnel_file['name']}):")
print(personnel_file['sample_data'].to_string(index=False, max_cols=10))
print(f"\n🪑 座位信息文件预览 ({seat_file['name']}):")
print(seat_file['sample_data'].to_string(index=False, max_cols=10))
return personnel_file['path'], seat_file['path']
def check_data_files():
"""检查并自动识别数据文件"""
print("\n=== 数据文件检查 ===")
# 首先尝试自动识别
personnel_file, seat_file = auto_detect_files()
if personnel_file is None or seat_file is None:
print(f"\n❌ 自动识别失败")
print("\n请检查以下要求:")
print("1. 确保目录下有且仅有2个Excel文件")
print("2. 人员信息文件应有5-6列姓名、证件类型、证件号、手机号、备注等")
print("3. 座位信息文件应有10+列(区域、楼层、排号、座位号等)")
print("4. 列名应包含相关关键词")
print("\n提示: 您可以参考示例文件来准备数据") print("\n提示: 您可以参考示例文件来准备数据")
return False return False, None, None
return True return True, str(personnel_file), str(seat_file)
# 只有在依赖检查通过后才导入这些包 # 只有在依赖检查通过后才导入这些包
if check_dependencies(): if check_dependencies():
@ -95,7 +209,12 @@ else:
class Logger: class Logger:
"""日志记录器""" """日志记录器"""
def __init__(self, log_file='seat_allocation_log.txt'): def __init__(self, log_file='seat_allocation_log.txt'):
self.log_file = log_file # 创建log文件夹
self.log_dir = Path('log')
self.log_dir.mkdir(exist_ok=True)
# 设置日志文件路径
self.log_file = self.log_dir / log_file
self.logs = [] self.logs = []
def log(self, message, print_to_console=True): def log(self, message, print_to_console=True):
@ -117,6 +236,10 @@ class Logger:
except Exception as e: except Exception as e:
print(f"保存日志失败: {e}") print(f"保存日志失败: {e}")
return False return False
def get_log_path(self, filename):
"""获取log文件夹中的文件路径"""
return self.log_dir / filename
class SeatAllocationSystem: class SeatAllocationSystem:
"""座位分配系统""" """座位分配系统"""
@ -127,34 +250,44 @@ class SeatAllocationSystem:
self.seat_df = None self.seat_df = None
self.seating_groups = [] self.seating_groups = []
self.row_analysis = {} self.row_analysis = {}
self.personnel_file = None
self.seat_file = None
def set_data_files(self, personnel_file, seat_file):
"""设置数据文件路径"""
self.personnel_file = personnel_file
self.seat_file = seat_file
def load_data(self): def load_data(self):
"""加载人员信息和座位信息数据""" """加载人员信息和座位信息数据"""
self.logger.log("=== 开始加载数据 ===") self.logger.log("=== 开始加载数据 ===")
# 检查文件是否存在 # 使用自动识别的文件路径
personnel_file = '人员信息.xlsx' if not self.personnel_file or not self.seat_file:
seat_file = '座位信息.xlsx' self.logger.log("❌ 错误: 数据文件路径未设置")
if not Path(personnel_file).exists():
self.logger.log(f"❌ 错误: {personnel_file} 文件不存在")
return False return False
if not Path(seat_file).exists(): if not Path(self.personnel_file).exists():
self.logger.log(f"❌ 错误: {seat_file} 文件不存在") self.logger.log(f"❌ 错误: {self.personnel_file} 文件不存在")
return False
if not Path(self.seat_file).exists():
self.logger.log(f"❌ 错误: {self.seat_file} 文件不存在")
return False return False
try: try:
self.logger.log(f"正在读取人员信息文件: {self.personnel_file}")
# 读取人员信息,指定数据类型 # 读取人员信息,指定数据类型
self.personnel_df = pd.read_excel(personnel_file, dtype={ self.personnel_df = pd.read_excel(self.personnel_file, dtype={
'姓名': 'str', '姓名': 'str',
'证件类型': 'str', '证件类型': 'str',
'证件号': 'str', # 证件号作为字符串读取避免X被转换 '证件号': 'str', # 证件号作为字符串读取避免X被转换
'手机号': 'str' '手机号': 'str'
}) })
self.logger.log(f"正在读取座位信息文件: {self.seat_file}")
# 读取座位信息,指定数据类型 # 读取座位信息,指定数据类型
self.seat_df = pd.read_excel(seat_file, dtype={ seat_df_raw = pd.read_excel(self.seat_file, dtype={
'区域': 'str', '区域': 'str',
'楼层': 'str', '楼层': 'str',
'排号': 'str', '排号': 'str',
@ -165,6 +298,9 @@ class SeatAllocationSystem:
'手机号': 'str', '手机号': 'str',
'签发地/国籍': 'str' '签发地/国籍': 'str'
}) })
# 过滤和清洗座位数据
self.seat_df = self.filter_seat_data(seat_df_raw)
# 清理文字信息中的空格 # 清理文字信息中的空格
self.clean_text_data() self.clean_text_data()
@ -197,6 +333,52 @@ class SeatAllocationSystem:
self.logger.log("✅ 文字数据清理完成") self.logger.log("✅ 文字数据清理完成")
def filter_seat_data(self, seat_df_raw):
"""过滤和清洗座位数据,移除空行和无效数据"""
self.logger.log("开始过滤座位数据...")
original_count = len(seat_df_raw)
self.logger.log(f"原始数据行数: {original_count}")
# 关键列,这些列都不能为空
key_columns = ['区域', '楼层', '排号', '座位号']
# 创建过滤条件:关键列都不能为空且不能为'nan'字符串
filter_condition = True
for col in key_columns:
if col in seat_df_raw.columns:
# 过滤空值、NaN、'nan'字符串
col_condition = (
seat_df_raw[col].notna() &
(seat_df_raw[col].astype(str).str.strip() != '') &
(seat_df_raw[col].astype(str).str.lower() != 'nan')
)
filter_condition = filter_condition & col_condition
# 应用过滤条件
seat_df_filtered = seat_df_raw[filter_condition].copy()
# 重置索引
seat_df_filtered.reset_index(drop=True, inplace=True)
filtered_count = len(seat_df_filtered)
removed_count = original_count - filtered_count
self.logger.log(f"过滤后数据行数: {filtered_count}")
self.logger.log(f"移除无效行数: {removed_count}")
if removed_count > 0:
self.logger.log(f"✅ 已过滤掉 {removed_count} 行无效数据(空行、示例数据等)")
# 显示过滤后的数据概览
if filtered_count > 0:
areas = seat_df_filtered['区域'].unique()
floors = seat_df_filtered['楼层'].unique()
self.logger.log(f"有效座位区域: {', '.join(areas)}")
self.logger.log(f"有效座位楼层: {', '.join(floors)}")
return seat_df_filtered
def validate_personnel_structure(self): def validate_personnel_structure(self):
"""校验人员信息文件结构""" """校验人员信息文件结构"""
self.logger.log("\n=== 人员信息结构校验 ===") self.logger.log("\n=== 人员信息结构校验 ===")
@ -805,14 +987,14 @@ class SeatAllocationSystem:
"""保存分配结果""" """保存分配结果"""
try: try:
# 保存更新后的座位信息 # 保存更新后的座位信息
output_file = '座位信息_最终分配.xlsx' output_file = self.logger.get_log_path('座位信息_最终分配.xlsx')
seat_df_result.to_excel(output_file, index=False) seat_df_result.to_excel(output_file, index=False)
self.logger.log(f"\n座位分配结果已保存到: {output_file}") self.logger.log(f"\n座位分配结果已保存到: {output_file}")
# 保存分配日志 # 保存分配日志
if assignment_log: if assignment_log:
log_df = pd.DataFrame(assignment_log) log_df = pd.DataFrame(assignment_log)
log_file = '最终座位分配日志.xlsx' log_file = self.logger.get_log_path('最终座位分配日志.xlsx')
log_df.to_excel(log_file, index=False) log_df.to_excel(log_file, index=False)
self.logger.log(f"分配日志已保存到: {log_file}") self.logger.log(f"分配日志已保存到: {log_file}")
@ -960,17 +1142,21 @@ class SeatAllocationSystem:
def main(): def main():
"""主函数""" """主函数"""
print("=" * 60) print("=" * 60)
print("座位分配系统 v1.0") print("座位分配系统 v2.0 (智能识别版)")
print("=" * 60) print("=" * 60)
try: try:
# 检查数据文件 # 自动检查和识别数据文件
if not check_data_files(): success, personnel_file, seat_file = check_data_files()
if not success:
input("\n按Enter键退出...") input("\n按Enter键退出...")
return return
print("\n开始运行座位分配系统...") print("\n开始运行座位分配系统...")
system = SeatAllocationSystem() system = SeatAllocationSystem()
# 设置识别出的文件路径
system.set_data_files(personnel_file, seat_file)
# 运行校验 # 运行校验
if system.run_validation(): if system.run_validation():
@ -980,10 +1166,10 @@ def main():
# 运行分配 # 运行分配
if system.run_allocation(): if system.run_allocation():
print("\n🎉 座位分配完成!") print("\n🎉 座位分配完成!")
print("请查看以下输出文件:") print("请查看log文件夹中的输出文件:")
print("- 座位信息_最终分配.xlsx (分配结果)") print("- log/座位信息_最终分配.xlsx (分配结果)")
print("- 最终座位分配日志.xlsx (详细日志)") print("- log/最终座位分配日志.xlsx (详细日志)")
print("- seat_allocation_log.txt (运行日志)") print("- log/seat_allocation_log.txt (运行日志)")
else: else:
print("\n❌ 座位分配失败!") print("\n❌ 座位分配失败!")
else: else:

View File

@ -349,32 +349,48 @@ chcp 65001 >nul
title 座位分配系统 title 座位分配系统
echo ========================================== echo ==========================================
echo 座位分配系统 v1.0 echo 座位分配系统 v2.0
echo ========================================== echo ==========================================
echo. echo.
:: 检查数据文件 :: 检查Excel文件
if not exist "人员信息.xlsx" ( echo 正在扫描Excel文件...
echo [错误] 缺少文件: 人员信息.xlsx
:: 计算xlsx文件数量
set count=0
for %%f in (*.xlsx) do (
:: 排除输出和示例文件
echo "%%f" | findstr /v /i "最终分配\|分配日志\|示例\|temp\|backup" >nul
if not errorlevel 1 (
set /a count+=1
echo 发现文件: %%f
)
)
if %count% equ 0 (
echo. echo.
echo 请将 人员信息_示例.xlsx 重命名为 人员信息.xlsx echo [错误] 未找到Excel数据文件
echo 并按照格式填入您的数据
echo. echo.
echo 请确保当前目录下有Excel数据文件:
echo 1. 人员信息文件 (5-6): 姓名证件类型证件号手机号备注等
echo 2. 座位信息文件 (10+): 区域楼层排号座位号等
echo.
echo 提示: 程序会自动识别文件类型无需固定文件名
pause pause
exit /b 1 exit /b 1
) )
if not exist "座位信息.xlsx" ( if %count% gtr 2 (
echo [错误] 缺少文件: 座位信息.xlsx
echo. echo.
echo 请将 座位信息_示例.xlsx 重命名为 座位信息.xlsx echo [警告] 发现超过2个Excel文件
echo 并按照格式填入您的数据 echo 为避免识别混淆请确保目录下只有2个数据文件
echo. echo.
echo 请移除多余文件后重试
pause pause
exit /b 1 exit /b 1
) )
echo [成功] 数据文件检查通过 echo [成功] 找到 %count% 个Excel文件程序将自动识别文件类型
echo. echo.
echo 正在启动座位分配系统... echo 正在启动座位分配系统...
echo. echo.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,13 +1,13 @@
@echo off @echo off
chcp 65001 >nul chcp 65001 >nul
title 座位分配系统 v1.0 title 座位分配系统 v2.0
:: 设置颜色 :: 设置颜色
color 0F color 0F
echo. echo.
echo ========================================== echo ==========================================
echo 座位分配系统 v1.0 echo 座位分配系统 v2.0
echo ========================================== echo ==========================================
echo. echo.
echo 正在检查运行环境... echo 正在检查运行环境...
@ -28,60 +28,49 @@ if not exist "座位分配系统.exe" (
echo [成功] 程序文件检查通过 echo [成功] 程序文件检查通过
:: 检查数据文件 :: 检查Excel文件
set "missing_files=" echo 正在扫描Excel文件...
if not exist "人员信息.xlsx" ( :: 计算xlsx文件数量
echo [错误] 缺少文件: 人员信息.xlsx set count=0
set "missing_files=1" for %%f in (*.xlsx) do (
) else ( :: 排除输出和示例文件
echo [成功] 人员信息.xlsx 存在 echo "%%f" | findstr /v /i "最终分配\|分配日志\|示例\|temp\|backup" >nul
if not errorlevel 1 (
set /a count+=1
echo 发现文件: %%f
)
) )
if not exist "座位信息.xlsx" ( if %count% equ 0 (
echo [错误] 缺少文件: 座位信息.xlsx
set "missing_files=1"
) else (
echo [成功] 座位信息.xlsx 存在
)
:: 如果有缺失文件,给出指导
if defined missing_files (
echo. echo.
echo ========================================== echo [错误] 未找到Excel数据文件
echo 数据文件缺失提示
echo ==========================================
echo. echo.
echo 请按照以下步骤准备数据文件: echo 请确保当前目录下有Excel数据文件:
echo. echo 1. 人员信息文件 (5-6列): 姓名、证件类型、证件号、手机号、备注等
echo 1. 如果您有示例文件,请重命名: echo 2. 座位信息文件 (10+列): 区域、楼层、排号、座位号等
echo - 人员信息_示例.xlsx → 人员信息.xlsx
echo - 座位信息_示例.xlsx → 座位信息.xlsx
echo.
echo 2. 数据文件格式要求:
echo.
echo 人员信息.xlsx 必需列:
echo - 姓名: 人员姓名
echo - 证件类型: 身份证/护照等
echo - 证件号: 证件号码
echo - 手机号: 联系电话
echo - 备注: 连坐人数(留空=单独坐)
echo.
echo 座位信息.xlsx 必需列:
echo - 区域: 座位区域
echo - 楼层: 楼层信息
echo - 排号: 排号
echo - 座位号: 具体座位号
echo.
echo 3. 连坐规则:
echo - 单人: 备注列留空
echo - 多人: 第一人填写总人数,其他人留空
echo - 示例: 张三(备注:3)、李四(空)、王五(空)
echo. echo.
echo 提示: 程序会自动识别文件类型,无需固定文件名
pause pause
exit /b 1 exit /b 1
) )
if %count% gtr 2 (
echo.
echo [警告] 发现超过2个Excel文件
echo 为避免识别混淆请确保目录下只有2个数据文件
echo 程序会自动排除输出文件和示例文件
echo.
echo 当前Excel文件:
for %%f in (*.xlsx) do echo %%f
echo.
echo 请移除多余文件后重试
pause
exit /b 1
)
echo [成功] 找到 %count% 个Excel文件程序将自动识别文件类型
echo. echo.
echo ========================================== echo ==========================================
echo 开始运行程序 echo 开始运行程序