# 工单名称长度限制修复说明 ## 问题描述 生成工单时报错:`Data too long for column 'name' at row 1` ## 错误详情 ``` 工单名称:'SN0005-入库测试(PCBA)_DSM'(27个字符) 数据库字段:name VARCHAR(20) 错误:字段长度不足,无法存储 ``` ## 根本原因 1. 数据库中 `test_work_order.name` 字段定义为 `VARCHAR(20)`,只能存储 20 个字符 2. DO 模型中定义为 `String(20)` 3. 工单名称生成逻辑:`{样品SN}-{测试单元名称}` - 样品SN:`SN0005`(6个字符) - 测试单元名称:`入库测试(PCBA)_DSM`(21个字符) - 总长度:27个字符 > 20个字符限制 ## 解决方案 ### 方案 1:扩大字段长度(推荐)✅ #### 1.1 修改数据库 **文件**: `fix_workorder_name_length.sql` ```sql ALTER TABLE test_work_order MODIFY COLUMN name VARCHAR(200) NOT NULL COMMENT '工单名称'; ``` **执行步骤**: ```bash mysql -u root -p your_database < fix_workorder_name_length.sql ``` #### 1.2 修改 DO 模型 **文件**: `test_work_order_do.py` ```python # 修改前 name = Column(String(20), nullable=False, comment='工单名称') # 修改后 name = Column(String(200), nullable=False, comment='工单名称') ``` **状态**: ✅ 已修改 #### 1.3 重启后端服务 ```bash # 停止后端服务 # 启动后端服务 ``` ### 方案 2:优化工单名称生成逻辑(可选) 如果不想修改数据库,可以截断工单名称: **文件**: `warehouse_sample_service.py` ```python # 4.6 构造工单名称(限制长度) if request_model.work_order_name: work_order_name = f"{request_model.work_order_name}-{sample.sample_sn}" else: work_order_name = f"{sample.sample_sn}-{test_item.name if test_item else '测试'}" # 限制工单名称长度(如果数据库字段是 VARCHAR(20)) max_length = 200 # 根据数据库字段长度调整 if len(work_order_name) > max_length: work_order_name = work_order_name[:max_length] print(f"WARNING: 工单名称被截断为 {max_length} 个字符: {work_order_name}") ``` **不推荐原因**:截断名称可能导致信息丢失,不利于识别工单。 ### 方案 3:使用缩写或编码(可选) 修改测试单元名称,使用缩写: ```python # 示例:将长名称映射为短名称 test_item_name_map = { '入库测试(PCBA)_DSM': 'PCBA_DSM', '其他长名称': '缩写' } test_item_short_name = test_item_name_map.get(test_item.name, test_item.name) work_order_name = f"{sample.sample_sn}-{test_item_short_name}" ``` **不推荐原因**:需要维护映射表,增加复杂度。 ## 工单名称生成规则 ### 当前规则 ```python if request_model.work_order_name: # 用户指定了工单名称 work_order_name = f"{request_model.work_order_name}-{sample.sample_sn}" else: # 自动生成工单名称 work_order_name = f"{sample.sample_sn}-{test_item.name}" ``` ### 示例 | 样品SN | 测试单元名称 | 生成的工单名称 | 长度 | |--------|--------------|----------------|------| | SN0001 | 入库测试(PCBA)_DSM | SN0001-入库测试(PCBA)_DSM | 27 | | SN0002 | 功能测试 | SN0002-功能测试 | 11 | | SN0003 | 老化测试(48小时) | SN0003-老化测试(48小时) | 21 | ## 字段长度建议 ### 当前字段长度 | 字段 | 当前长度 | 建议长度 | 原因 | |------|----------|----------|------| | name | 20 | 200 | 支持长测试单元名称 | | batch_name | 100 | 100 | 足够 | | memo | 200 | 500 | 支持更详细的备注 | ### 其他相关字段 ```sql -- 检查所有字符串字段的长度 SELECT COLUMN_NAME, COLUMN_TYPE, CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'test_work_order' AND DATA_TYPE IN ('varchar', 'char', 'text') ORDER BY COLUMN_NAME; ``` ## 验证步骤 ### 1. 执行数据库修改 ```bash mysql -u root -p your_database < fix_workorder_name_length.sql ``` ### 2. 验证字段长度 ```sql SELECT COLUMN_NAME, COLUMN_TYPE, CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'test_work_order' AND COLUMN_NAME = 'name'; ``` **预期结果**: ``` COLUMN_NAME | COLUMN_TYPE | CHARACTER_MAXIMUM_LENGTH ------------|--------------|------------------------- name | varchar(200) | 200 ``` ### 3. 重启后端服务 确保 DO 模型的修改生效。 ### 4. 重新生成工单 1. 进入样品管理页面 2. 选择样品(如 SN0005) 3. 点击"生成工单" 4. 应该能够成功创建工单 ### 5. 验证工单名称 ```sql SELECT id, name, LENGTH(name) AS name_length FROM test_work_order ORDER BY id DESC LIMIT 10; ``` **预期结果**:工单名称完整显示,没有被截断。 ## 常见问题 ### Q1: 为什么不直接使用 TEXT 类型? **A**: VARCHAR(200) 已经足够,TEXT 类型会影响索引性能。如果未来需要更长的名称,可以考虑 TEXT。 ### Q2: 修改字段长度会影响现有数据吗? **A**: 不会。从 VARCHAR(20) 扩展到 VARCHAR(200) 是安全的,现有数据不会丢失。 ### Q3: 需要修改前端代码吗? **A**: 不需要。前端只是显示工单名称,不受字段长度限制影响。 ### Q4: 如果测试单元名称更长怎么办? **A**: - 短期:增加字段长度到 VARCHAR(500) - 长期:考虑优化测试单元命名规范,使用更简洁的名称 ## 相关文件 - `fix_workorder_name_length.sql` - 数据库修改脚本 ✅ - `check_workorder_name_length.sql` - 检查字段长度脚本 - `test_work_order_do.py` - 工单DO模型 ✅ 已修改 - `warehouse_sample_service.py` - 样品服务(工单名称生成逻辑) ## 完成时间 2026-01-08 23:35 ## 状态 ✅ **已修复** - [x] 数据库字段扩展到 VARCHAR(200) - [x] DO 模型更新为 String(200) - [ ] 重启后端服务(待执行) - [ ] 验证工单生成(待测试)