Fosi Fossil Service
Small teams. Open source. Built on Fossil.

IaC / SwiftFlow

High-performance WMS with wave picking, smart routing, and real-time inventory visibility.

Public | Owner: IaC | Default branch: trunk | Last update: 2026-10-23 14:37

Artifact 4071cf65fa97847e7569216a7d5abbfa79f7886af476ed3584f608c9638745e7:


export const TOKEN_KEY = 'swiftflow.token'

export class ApiError extends Error {
  status: number

  constructor(status: number, message: string) {
    super(message)
    this.status = status
  }
}

export type SessionUser = {
  id: string
  username: string
  display_name: string
  roles: string[]
  permissions: string[]
  all_warehouses: boolean
  warehouse_ids: number[]
  current_warehouse_id: number
  terminal: string
  expires_at: string
}

export type Warehouse = {
  id: number
  code: string
  name: string
  easycode: string
  operational: boolean
}

export function can(user: SessionUser | null, permission: string) {
  return user?.permissions.includes(permission) ?? false
}

export async function api<T>(path: string, init: RequestInit = {}): Promise<T> {
  const headers = new Headers(init.headers)
  if (init.body && !headers.has('content-type')) {
    headers.set('content-type', 'application/json')
  }
  const token = localStorage.getItem(TOKEN_KEY)
  if (token) headers.set('authorization', `Bearer ${token}`)

  const response = await fetch(path, { ...init, headers })
  const text = await response.text()
  let data: { error?: string } = {}
  if (text) {
    try {
      data = JSON.parse(text) as { error?: string }
    } catch {
      data = {}
    }
  }
  if (response.status === 401 && !path.endsWith('/api/auth/login')) {
    localStorage.removeItem(TOKEN_KEY)
    window.dispatchEvent(new Event('swiftflow-unauthorized'))
  }
  if (!response.ok) {
    throw new ApiError(response.status, data.error || `请求失败(${response.status})`)
  }
  return data as T
}

export function qty(value: number) {
  return value.toLocaleString('zh-CN', { maximumFractionDigits: 4 })
}

export function money(value: number) {
  return value.toLocaleString('zh-CN', {
    minimumFractionDigits: 2,
    maximumFractionDigits: 2,
  })
}

Clone

You can clone this repository with the following command:

fossil clone https://fosi.dev/IaC/SwiftFlow

Contribute

The best way to contribute is through e-mail. See the project documentation for more details.