import { useCallback, useEffect, useState } from "react" import { Link } from "react-router-dom" import { FirearmApi } from "@/api" import FirearmCreateModal from "@/components/firearm-create-modal" import FirearmEditModal from "@/components/firearm-edit-modal" import ModCodes from "@/components/mod-codes" import { useAppSelector } from "@/hooks/store" import { Firearm, FirearmType } from "@/types" import { Button, Card, Col, Pagination, Popconfirm, Row, Select, Tag, Typography, App } from "antd" import { ConfigProvider, theme } from 'antd'; import type { CollapseProps } from 'antd'; import { Collapse } from 'antd'; const firearmTypeText: Record = { RIFLE: "步枪", SUB_MACHINE_GUN: "冲锋枪", SHOTGUN: "霰弹枪", LIGHT_MACHINE_GUN: "轻机枪", DESIGNATED_MARKSMAN_RIFLE: "射手步枪", SNIPER_RIFLE: "狙击步枪", PISTOL: "手枪", SPECIAL: "特殊", } const darkTheme = { algorithm: theme.darkAlgorithm, // token: { colorPrimary: '#00b96b' }, }; const allTypeValue = "ALL" type FirearmTypeFilter = FirearmType | typeof allTypeValue function asDps(fireRate: number, damage: number) { return ((fireRate / 60) * damage).toFixed(2) } export default function FirearmsPage() { const user = useAppSelector((state) => state.auth.user) const { message } = App.useApp() const [page, setPage] = useState(1) const [typeFilter, setTypeFilter] = useState(allTypeValue) const [firearms, setFirearms] = useState([]) const [total, setTotal] = useState(0) const [createModalOpen, setCreateModalOpen] = useState(false) const [editingFirearm, setEditingFirearm] = useState(null) const [deletingId, setDeletingId] = useState(null) const loadFirearms = useCallback(async () => { const pagedData = await FirearmApi.getFirearms({ page: page - 1, size: 12, sortBy: "id", direction: "ASC", type: typeFilter === allTypeValue ? undefined : typeFilter, }) setFirearms(pagedData.items) setTotal(pagedData.totalElements) }, [page, typeFilter]) const [expandedId, setExpandedId] = useState(null); useEffect(() => { void loadFirearms() }, [loadFirearms]) useEffect(() => { window.scrollTo({ top: 0, behavior: 'smooth' }); }, [page]); async function handleDelete(firearm: Firearm) { setDeletingId(firearm.id) try { await FirearmApi.removeFirearm(firearm.id) message.success("武器删除成功") if (firearms.length === 1 && page > 1) { setPage(page - 1) } else { void loadFirearms() } } catch { message.error("武器删除失败,请稍后重试") } finally { setDeletingId(null) } } return ( <>
{user && ( )}
className="w-full sm:w-64" value={typeFilter} options={[ { value: allTypeValue, label: "全部类型" }, ...Object.entries(firearmTypeText).map(([value, label]) => ({ value, label, })), ]} onChange={(nextType) => { setPage(1) setTypeFilter(nextType) }} />
{firearms.map((firearm) => ( handleDelete(firearm)}>
) : null } variant="outlined" style={{ height: '100%', display: 'flex', flexDirection: 'column' }} styles={{ root: { border: '1px solid #313131' }, header: { borderBottom: '1px solid #303030', }, body: { flex: 1, overflow: 'auto', padding: '12px', }, actions: { flexShrink: 0, background: '#1e1e1e', display: 'flex' } }} actions={[
null} styles={ { root: { background: '#1e1e1e', } } } items={[{ key: '1', label: ( ), children: }]} />
, ]}>
{firearm.name} {firearmTypeText[firearm.type]}
{/* 武器输出等级 */}
武器输出等级
{firearm.level}
{/* 子弹口径 */}
子弹口径
{firearm.calibre}
{/* 每秒甲伤 */}
每秒甲伤
{asDps(firearm.fireRate, firearm.armourDamage)}
{/* 每秒肉伤 */}
每秒肉伤
{asDps(firearm.fireRate, firearm.bodyDamage)}
{firearm.review}
, placement: "topLeft", } : false, }} className="whitespace-pre-line"> {firearm.review || "暂无描述"}
))} {firearms.length === 0 && ( 暂无武器数据 )}
{ setPage(nextPage) }} showSizeChanger={false} />
setCreateModalOpen(false)} onSuccess={() => { setCreateModalOpen(false) void loadFirearms() }} /> setEditingFirearm(null)} onSuccess={() => { setEditingFirearm(null) void loadFirearms() }} />
) }