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 7d839dda0bc13549f7abe3dc6917323eae04e696f3c39446af5ef805c9730831:


import { useEffect, useState } from 'react'
import { api } from '../api'
import { Empty, Page, Pager } from '../ui'

type Entry = {
  id: string
  username: string
  action: string
  target: string
  warehouse_id: number
  detail: string
  created_at: string
}

export function Audit() {
  const [offset, setOffset] = useState(0)
  const [total, setTotal] = useState(0)
  const [rows, setRows] = useState<Entry[]>([])
  const [error, setError] = useState('')
  const limit = 50

  useEffect(() => {
    api<{ total: number; logs: Entry[] }>(`/api/audit-logs?limit=${limit}&offset=${offset}`)
      .then((data) => {
        setTotal(data.total)
        setRows(data.logs)
      })
      .catch((err: unknown) => setError(err instanceof Error ? err.message : '加载失败'))
  }, [offset])

  return (
    <Page title="审计日志">
      {error && <p className="banner error">{error}</p>}
      {rows.length === 0 ? (
        <Empty text="还没有审计记录" />
      ) : (
        <div className="table-wrap">
          <table>
            <thead>
              <tr>
                <th>时间</th>
                <th>账号</th>
                <th>动作</th>
                <th>对象</th>
                <th>仓库</th>
                <th>说明</th>
              </tr>
            </thead>
            <tbody>
              {rows.map((row) => (
                <tr key={row.id}>
                  <td>{row.created_at}</td>
                  <td>{row.username}</td>
                  <td className="mono">{row.action}</td>
                  <td>{row.target}</td>
                  <td>{row.warehouse_id || ''}</td>
                  <td>{row.detail}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
      <Pager total={total} limit={limit} offset={offset} onPage={setOffset} />
    </Page>
  )
}

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.