diff --git a/crates/erp-diary/src/service/class_service.rs b/crates/erp-diary/src/service/class_service.rs index c51874c..d3cdfd2 100644 --- a/crates/erp-diary/src/service/class_service.rs +++ b/crates/erp-diary/src/service/class_service.rs @@ -520,20 +520,21 @@ impl ClassService { } } -/// 生成 6 位班级码(UUID 前 6 位字符) +/// 生成 6 位字母数字混合班级码(62^6 ≈ 568 亿种组合) +/// +/// CLAUDE.md 要求"6 位字母数字混合(62^6 ≈ 568 亿种组合)"。 +/// 使用 UUID v7 后 8 字节(随机部分)作为熵源,映射到 [0-9A-Za-z] 字符集。 +/// 前 8 字节含时间戳,同毫秒内重复概率高,因此只用后 8 字节。 fn generate_class_code() -> String { - // UUID v7 毫秒级时间戳前缀在紧凑循环中可能重复 - // 取后 6 位(随机部分)而非前 6 位(时间戳部分) - Uuid::now_v7() - .to_string() - .replace("-", "") - .chars() - .rev() - .take(6) - .collect::() - .chars() - .rev() - .collect() + const CHARSET: &[u8] = b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + let bytes = *Uuid::now_v7().as_bytes(); + let mut code = String::with_capacity(6); + // UUID v7: bytes[0..8] = 时间戳, bytes[8..16] = 随机部分 + // 从随机部分取 6 个字节,避免同毫秒碰撞 + for i in 0..6 { + code.push(CHARSET[(bytes[8 + i] as usize) % CHARSET.len()] as char); + } + code } /// school_class::Model -> ClassResp