Artifact 47a942198cb4ca9bd0a219a31b667ecc598d3446860fd5744f54ebc0d75df381:
- File
backend/src/location.gleam
— part of check-in
[0fd3652de9]
at
2026-10-23 04:38:19
on branch trunk
— 为已采集仓库增加四级库位主数据。
库位按区、货架、层、位编码并生成条码,不预置货位;只作显示的仓库不能建立库存库位。 (user: pluto size: 1910)
import gleam/string pub type LocationCode { LocationCode( area: String, aisle: String, level: String, bin: String, code: String, compact: String, ) } pub type Location { Location( warehouse_id: Int, area: String, aisle: String, level: String, bin: String, code: String, barcode: String, enabled: Bool, created_at: String, updated_at: String, ) } pub fn build( area: String, aisle: String, level: String, bin: String, ) -> Result(LocationCode, String) { use area <- result_try(segment("库区", area)) use aisle <- result_try(segment("货架", aisle)) use level <- result_try(segment("层", level)) use bin <- result_try(segment("位", bin)) let compact = area <> aisle <> level <> bin Ok(LocationCode( area: area, aisle: aisle, level: level, bin: bin, code: area <> "-" <> aisle <> "-" <> level <> "-" <> bin, compact: compact, )) } pub fn barcode(warehouse_code: String, compact: String) -> String { "LOC-" <> warehouse_code <> "-" <> compact } fn segment(label: String, raw: String) -> Result(String, String) { let value = string.uppercase(string.trim(raw)) case value == "" { True -> Error(label <> "不能为空") False -> case string.length(value) > 8 || !alphanumeric(value) { True -> Error(label <> "只能使用 1 到 8 位字母或数字") False -> Ok(value) } } } fn alphanumeric(value: String) -> Bool { case string.pop_grapheme(value) { Error(_) -> True Ok(#(char, rest)) -> { let ok = string.contains("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", char) case ok { True -> alphanumeric(rest) False -> False } } } } fn result_try(result: Result(a, b), next: fn(a) -> Result(c, b)) -> Result(c, b) { case result { Ok(value) -> next(value) Error(err) -> Error(err) } }