Merge branch 'develop' into dependabot/npm_and_yarn/dependency-updates-2c57f57997

This commit is contained in:
2026-04-22 14:43:52 +08:00
committed by GitHub
17 changed files with 604 additions and 99 deletions
+62 -62
View File
@@ -372,8 +372,8 @@ packages:
react: '>=16.9.0' react: '>=16.9.0'
react-dom: '>=16.9.0' react-dom: '>=16.9.0'
'@rc-component/image@1.8.0': '@rc-component/image@1.8.1':
resolution: {integrity: sha512-Dr41bFevLB5NgVaJhEUmNvbEf+ynAhim6W98ZW2xvCsdFISc2TYP4ZvCVdie3eaZdum2kieVcvpNHu+UrzAAHA==} resolution: {integrity: sha512-JfPCijmMl+EaMvbftsEs/4VHmTyJKsZBh5ujFowSA45i9NTVYS1vuHtgpVV/QrGa27kXwbVOZriffCe/PNKuMw==}
peerDependencies: peerDependencies:
react: '>=16.9.0' react: '>=16.9.0'
react-dom: '>=16.9.0' react-dom: '>=16.9.0'
@@ -583,8 +583,8 @@ packages:
react: '>=16.9.0' react: '>=16.9.0'
react-dom: '>=16.9.0' react-dom: '>=16.9.0'
'@rc-component/util@1.10.0': '@rc-component/util@1.10.1':
resolution: {integrity: sha512-aY9GLBuiUdpyfIUpAWSYer4Tu3mVaZCo5A0q9NtXcazT3MRiI3/WNHCR+DUn5VAtR6iRRf0ynCqQUcHli5UdYw==} resolution: {integrity: sha512-q++9S6rUa5Idb/xIBNz6jtvumw5+O5YV5V0g4iK9mn9jWs4oGJheE3ZN1kAnE723AXyaD8v95yeOASmdk8Jnng==}
peerDependencies: peerDependencies:
react: '>=18.0.0' react: '>=18.0.0'
react-dom: '>=18.0.0' react-dom: '>=18.0.0'
@@ -1082,8 +1082,8 @@ packages:
resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
engines: {node: '>=12'} engines: {node: '>=12'}
postcss@8.5.8: postcss@8.5.9:
resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==} resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==}
engines: {node: ^10 || ^12 || >=14} engines: {node: ^10 || ^12 || >=14}
prettier@3.8.3: prettier@3.8.3:
@@ -1183,16 +1183,16 @@ packages:
tailwindcss@4.2.2: tailwindcss@4.2.2:
resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==} resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==}
tapable@2.3.0: tapable@2.3.2:
resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==}
engines: {node: '>=6'} engines: {node: '>=6'}
throttle-debounce@5.0.2: throttle-debounce@5.0.2:
resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==}
engines: {node: '>=12.22'} engines: {node: '>=12.22'}
tinyglobby@0.2.15: tinyglobby@0.2.16:
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==}
engines: {node: '>=12.0.0'} engines: {node: '>=12.0.0'}
tslib@2.8.1: tslib@2.8.1:
@@ -1264,7 +1264,7 @@ snapshots:
dependencies: dependencies:
'@ant-design/cssinjs': 2.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@ant-design/cssinjs': 2.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@babel/runtime': 7.29.2 '@babel/runtime': 7.29.2
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1273,7 +1273,7 @@ snapshots:
'@babel/runtime': 7.29.2 '@babel/runtime': 7.29.2
'@emotion/hash': 0.8.0 '@emotion/hash': 0.8.0
'@emotion/unitless': 0.7.5 '@emotion/unitless': 0.7.5
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
csstype: 3.2.3 csstype: 3.2.3
react: 19.2.5 react: 19.2.5
@@ -1288,7 +1288,7 @@ snapshots:
dependencies: dependencies:
'@ant-design/colors': 8.0.1 '@ant-design/colors': 8.0.1
'@ant-design/icons-svg': 4.4.2 '@ant-design/icons-svg': 4.4.2
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1438,14 +1438,14 @@ snapshots:
dependencies: dependencies:
'@rc-component/select': 1.6.15(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/select': 1.6.15(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/tree': 1.2.4(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/tree': 1.2.4(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
'@rc-component/checkbox@2.0.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/checkbox@2.0.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1454,7 +1454,7 @@ snapshots:
dependencies: dependencies:
'@babel/runtime': 7.29.2 '@babel/runtime': 7.29.2
'@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1462,14 +1462,14 @@ snapshots:
'@rc-component/color-picker@3.1.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/color-picker@3.1.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@ant-design/fast-color': 3.0.1 '@ant-design/fast-color': 3.0.1
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
'@rc-component/context@2.0.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/context@2.0.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1477,7 +1477,7 @@ snapshots:
dependencies: dependencies:
'@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/portal': 2.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/portal': 2.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1486,7 +1486,7 @@ snapshots:
dependencies: dependencies:
'@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/portal': 2.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/portal': 2.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1494,7 +1494,7 @@ snapshots:
'@rc-component/dropdown@1.0.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/dropdown@1.0.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1502,16 +1502,16 @@ snapshots:
'@rc-component/form@1.8.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/form@1.8.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/async-validator': 5.1.0 '@rc-component/async-validator': 5.1.0
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
'@rc-component/image@1.8.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/image@1.8.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/portal': 2.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/portal': 2.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1519,14 +1519,14 @@ snapshots:
'@rc-component/input-number@1.6.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/input-number@1.6.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/mini-decimal': 1.1.3 '@rc-component/mini-decimal': 1.1.3
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
'@rc-component/input@1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/input@1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1537,7 +1537,7 @@ snapshots:
'@rc-component/menu': 1.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/menu': 1.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/textarea': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/textarea': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1547,7 +1547,7 @@ snapshots:
'@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/overflow': 1.0.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/overflow': 1.0.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1558,21 +1558,21 @@ snapshots:
'@rc-component/motion@1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/motion@1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
'@rc-component/mutate-observer@2.0.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/mutate-observer@2.0.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
'@rc-component/notification@1.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/notification@1.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1581,14 +1581,14 @@ snapshots:
dependencies: dependencies:
'@babel/runtime': 7.29.2 '@babel/runtime': 7.29.2
'@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
'@rc-component/pagination@1.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/pagination@1.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1598,7 +1598,7 @@ snapshots:
'@rc-component/overflow': 1.0.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/overflow': 1.0.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1607,14 +1607,14 @@ snapshots:
'@rc-component/portal@2.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/portal@2.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
'@rc-component/progress@1.0.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/progress@1.0.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1627,14 +1627,14 @@ snapshots:
'@rc-component/rate@1.0.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/rate@1.0.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
'@rc-component/resize-observer@1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/resize-observer@1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1642,7 +1642,7 @@ snapshots:
dependencies: dependencies:
'@babel/runtime': 7.29.2 '@babel/runtime': 7.29.2
'@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1651,7 +1651,7 @@ snapshots:
dependencies: dependencies:
'@rc-component/overflow': 1.0.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/overflow': 1.0.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/virtual-list': 1.0.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/virtual-list': 1.0.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
@@ -1659,21 +1659,21 @@ snapshots:
'@rc-component/slider@1.0.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/slider@1.0.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
'@rc-component/steps@1.2.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/steps@1.2.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
'@rc-component/switch@1.0.3(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/switch@1.0.3(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1682,7 +1682,7 @@ snapshots:
dependencies: dependencies:
'@rc-component/context': 2.0.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/context': 2.0.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/virtual-list': 1.0.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/virtual-list': 1.0.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
@@ -1694,7 +1694,7 @@ snapshots:
'@rc-component/menu': 1.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/menu': 1.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1703,7 +1703,7 @@ snapshots:
dependencies: dependencies:
'@rc-component/input': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/input': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1711,7 +1711,7 @@ snapshots:
'@rc-component/tooltip@1.4.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/tooltip@1.4.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1720,7 +1720,7 @@ snapshots:
dependencies: dependencies:
'@rc-component/portal': 2.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/portal': 2.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1729,7 +1729,7 @@ snapshots:
dependencies: dependencies:
'@rc-component/select': 1.6.15(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/select': 1.6.15(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/tree': 1.2.4(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/tree': 1.2.4(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1737,7 +1737,7 @@ snapshots:
'@rc-component/tree@1.2.4(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/tree@1.2.4(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/virtual-list': 1.0.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/virtual-list': 1.0.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
@@ -1748,19 +1748,19 @@ snapshots:
'@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/motion': 1.3.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/portal': 2.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/portal': 2.2.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
'@rc-component/upload@1.1.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/upload@1.1.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
'@rc-component/util@1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)': '@rc-component/util@1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)':
dependencies: dependencies:
is-mobile: 5.0.0 is-mobile: 5.0.0
react: 19.2.5 react: 19.2.5
@@ -1771,7 +1771,7 @@ snapshots:
dependencies: dependencies:
'@babel/runtime': 7.29.2 '@babel/runtime': 7.29.2
'@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/resize-observer': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
react: 19.2.5 react: 19.2.5
react-dom: 19.2.5(react@19.2.5) react-dom: 19.2.5(react@19.2.5)
@@ -1962,7 +1962,7 @@ snapshots:
'@rc-component/drawer': 1.4.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/drawer': 1.4.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/dropdown': 1.0.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/dropdown': 1.0.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/form': 1.8.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/form': 1.8.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/image': 1.8.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/image': 1.8.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/input': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/input': 1.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/input-number': 1.6.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/input-number': 1.6.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/mentions': 1.6.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/mentions': 1.6.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
@@ -1990,7 +1990,7 @@ snapshots:
'@rc-component/tree-select': 1.8.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/tree-select': 1.8.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/trigger': 3.9.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/upload': 1.1.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/upload': 1.1.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
'@rc-component/util': 1.10.0(react-dom@19.2.5(react@19.2.5))(react@19.2.5) '@rc-component/util': 1.10.1(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
clsx: 2.1.1 clsx: 2.1.1
dayjs: 1.11.20 dayjs: 1.11.20
react: 19.2.5 react: 19.2.5
@@ -2044,7 +2044,7 @@ snapshots:
enhanced-resolve@5.20.1: enhanced-resolve@5.20.1:
dependencies: dependencies:
graceful-fs: 4.2.11 graceful-fs: 4.2.11
tapable: 2.3.0 tapable: 2.3.2
es-define-property@1.0.1: {} es-define-property@1.0.1: {}
@@ -2221,7 +2221,7 @@ snapshots:
picomatch@4.0.4: {} picomatch@4.0.4: {}
postcss@8.5.8: postcss@8.5.9:
dependencies: dependencies:
nanoid: 3.3.11 nanoid: 3.3.11
picocolors: 1.1.1 picocolors: 1.1.1
@@ -2314,11 +2314,11 @@ snapshots:
tailwindcss@4.2.2: {} tailwindcss@4.2.2: {}
tapable@2.3.0: {} tapable@2.3.2: {}
throttle-debounce@5.0.2: {} throttle-debounce@5.0.2: {}
tinyglobby@0.2.15: tinyglobby@0.2.16:
dependencies: dependencies:
fdir: 6.5.0(picomatch@4.0.4) fdir: 6.5.0(picomatch@4.0.4)
picomatch: 4.0.4 picomatch: 4.0.4
@@ -2338,9 +2338,9 @@ snapshots:
dependencies: dependencies:
lightningcss: 1.32.0 lightningcss: 1.32.0
picomatch: 4.0.4 picomatch: 4.0.4
postcss: 8.5.8 postcss: 8.5.9
rolldown: 1.0.0-rc.15 rolldown: 1.0.0-rc.15
tinyglobby: 0.2.15 tinyglobby: 0.2.16
optionalDependencies: optionalDependencies:
'@types/node': 22.19.17 '@types/node': 22.19.17
esbuild: 0.27.4 esbuild: 0.27.4
+13
View File
@@ -0,0 +1,13 @@
import { LoginRequest, User } from "@/types"
import { WebClient } from "@/shared/web-client"
export async function login(loginRequest: LoginRequest): Promise<User> {
const { data } = await WebClient.post<User>("/auth/login", {
...loginRequest,
})
return data
}
export async function logout() {
await WebClient.get<void>("/auth/logout")
}
+19 -1
View File
@@ -1,4 +1,4 @@
import { Direction, Firearm, FirearmType, Page, PageQueryParams } from "@/types" import { AddFirearmRequest, Direction, Firearm, FirearmType, Page, PageQueryParams } from "@/types"
import { WebClient } from "@/shared/web-client" import { WebClient } from "@/shared/web-client"
import { asUrlSearchParam } from "@/utils/query-param-utils.ts" import { asUrlSearchParam } from "@/utils/query-param-utils.ts"
@@ -36,3 +36,21 @@ export async function getFirearm(id: number): Promise<Firearm> {
const { data } = await WebClient.get<Firearm>(`/firearms/${id}`) const { data } = await WebClient.get<Firearm>(`/firearms/${id}`)
return data return data
} }
/**
* 新建武器
* @param request
*/
export async function addFirearm(request: AddFirearmRequest): Promise<Firearm> {
const { data } = await WebClient.post<Firearm>("/firearms", request)
return data
}
export async function editFirearm(id: number, request: AddFirearmRequest): Promise<Firearm> {
const { data } = await WebClient.put<Firearm>(`/firearms/${id}`, request)
return data
}
export async function removeFirearm(id: number) {
await WebClient.delete<void>(`/firearms/${id}`)
}
+1
View File
@@ -1,3 +1,4 @@
export * as FirearmApi from "./firearm-api" export * as FirearmApi from "./firearm-api"
export * as ModificationApi from "./modification-api" export * as ModificationApi from "./modification-api"
export * as TagApi from "./tag-api" export * as TagApi from "./tag-api"
export * as AuthApi from "./auth-api"
@@ -0,0 +1,58 @@
import { useState } from "react"
import { App, Form, Modal } from "antd"
import { FirearmApi } from "@/api"
import FirearmForm from "@/components/firearm-form"
import { AddFirearmRequest, Firearm } from "@/types"
interface FirearmCreateModalProps {
open: boolean
onCancel: () => void
onSuccess: (firearm: Firearm) => void
}
function normalizeRequest(values: AddFirearmRequest): AddFirearmRequest {
return {
...values,
review: values.review?.trim() || null,
}
}
export default function FirearmCreateModal({ open, onCancel, onSuccess }: FirearmCreateModalProps) {
const { message } = App.useApp()
const [form] = Form.useForm<AddFirearmRequest>()
const [loading, setLoading] = useState(false)
async function onFinish(values: AddFirearmRequest) {
setLoading(true)
try {
const firearm = await FirearmApi.addFirearm(normalizeRequest(values))
message.success("武器创建成功")
form.resetFields()
onSuccess(firearm)
} catch {
message.error("武器创建失败,请稍后重试")
} finally {
setLoading(false)
}
}
return (
<Modal
title="新建武器"
open={open}
onCancel={onCancel}
onOk={() => form.submit()}
okText="创建"
cancelText="取消"
confirmLoading={loading}
destroyOnHidden
afterOpenChange={(visible) => {
if (!visible) {
form.resetFields()
}
}}>
<FirearmForm form={form} onFinish={onFinish} />
</Modal>
)
}
@@ -0,0 +1,67 @@
import { useEffect, useState } from "react"
import { App, Form, Modal } from "antd"
import { FirearmApi } from "@/api"
import FirearmForm from "@/components/firearm-form"
import { AddFirearmRequest, Firearm } from "@/types"
interface FirearmEditModalProps {
open: boolean
firearm: Firearm | null
onCancel: () => void
onSuccess: (firearm: Firearm) => void
}
function normalizeRequest(values: AddFirearmRequest): AddFirearmRequest {
return {
...values,
review: values.review?.trim() || null,
}
}
export default function FirearmEditModal({ open, firearm, onCancel, onSuccess }: FirearmEditModalProps) {
const { message } = App.useApp()
const [form] = Form.useForm<AddFirearmRequest>()
const [loading, setLoading] = useState(false)
useEffect(() => {
if (!open || !firearm) {
return
}
const { id: _id, ...editableValues } = firearm
form.setFieldsValue(editableValues)
}, [open, firearm, form])
async function onFinish(values: AddFirearmRequest) {
if (!firearm) {
return
}
setLoading(true)
try {
const updated = await FirearmApi.editFirearm(firearm.id, normalizeRequest(values))
message.success("武器更新成功")
onSuccess(updated)
} catch {
message.error("武器更新失败,请稍后重试")
} finally {
setLoading(false)
}
}
return (
<Modal
title="编辑武器"
open={open}
onCancel={onCancel}
onOk={() => form.submit()}
okText="保存"
cancelText="取消"
confirmLoading={loading}
destroyOnHidden
>
<FirearmForm form={form} onFinish={onFinish} />
</Modal>
)
}
+91
View File
@@ -0,0 +1,91 @@
import { Form, Input, InputNumber, Select } from "antd"
import { AddFirearmRequest, FirearmType } from "@/types"
const firearmTypeText: Record<FirearmType, string> = {
RIFLE: "步枪",
SUB_MACHINE_GUN: "冲锋枪",
SHOTGUN: "霰弹枪",
LIGHT_MACHINE_GUN: "轻机枪",
DESIGNATED_MARKSMAN_RIFLE: "射手步枪",
SNIPER_RIFLE: "狙击步枪",
PISTOL: "手枪",
SPECIAL: "特殊",
}
interface FirearmFormProps {
form: ReturnType<typeof Form.useForm<AddFirearmRequest>>[0]
onFinish: (values: AddFirearmRequest) => void
}
export default function FirearmForm({ form, onFinish }: FirearmFormProps) {
return (
<Form<AddFirearmRequest> form={form} layout="vertical" onFinish={onFinish} requiredMark={false}>
<Form.Item<AddFirearmRequest>
name="name"
label="武器名称"
rules={[{ required: true, message: "请输入武器名称" }]}
>
<Input placeholder="请输入武器名称" />
</Form.Item>
<Form.Item<AddFirearmRequest>
name="type"
label="武器类型"
rules={[{ required: true, message: "请选择武器类型" }]}
>
<Select
placeholder="请选择武器类型"
options={Object.entries(firearmTypeText).map(([value, label]) => ({
value,
label,
}))}
/>
</Form.Item>
<Form.Item<AddFirearmRequest>
name="level"
label="武器输出等级"
rules={[{ required: true, message: "请输入武器输出等级" }]}
>
<Input placeholder="例如:T0" />
</Form.Item>
<Form.Item<AddFirearmRequest>
name="calibre"
label="子弹口径"
rules={[{ required: true, message: "请输入子弹口径" }]}
>
<Input placeholder="例如:5.56x45mm" />
</Form.Item>
<Form.Item<AddFirearmRequest>
name="fireRate"
label="射速(每分钟发数)"
rules={[{ required: true, message: "请输入射速" }]}
>
<InputNumber className="w-full" min={1} precision={0} placeholder="请输入射速" />
</Form.Item>
<Form.Item<AddFirearmRequest>
name="armourDamage"
label="甲伤"
rules={[{ required: true, message: "请输入甲伤" }]}
>
<InputNumber className="w-full" min={0} precision={0} placeholder="请输入甲伤" />
</Form.Item>
<Form.Item<AddFirearmRequest>
name="bodyDamage"
label="肉伤"
rules={[{ required: true, message: "请输入肉伤" }]}
>
<InputNumber className="w-full" min={0} precision={0} placeholder="请输入肉伤" />
</Form.Item>
<Form.Item<AddFirearmRequest> name="review" label="描述">
<Input.TextArea rows={4} placeholder="可选:补充武器特点或使用建议" />
</Form.Item>
</Form>
)
}
+40
View File
@@ -1,6 +1,10 @@
import { Outlet, Link } from "react-router-dom" import { Outlet, Link } from "react-router-dom"
import { useMemo } from "react" import { useMemo } from "react"
import dayjs from "dayjs" import dayjs from "dayjs"
import { Dropdown } from "antd"
import { AuthApi } from "@/api"
import { useAppDispatch, useAppSelector } from "@/store"
import { clearCurrentUser } from "@/store/auth-slice"
/** /**
* Main application component that serves as the root layout. * Main application component that serves as the root layout.
@@ -8,6 +12,16 @@ import dayjs from "dayjs"
*/ */
export default function HeroLayout() { export default function HeroLayout() {
const today = useMemo(() => dayjs(), []) const today = useMemo(() => dayjs(), [])
const user = useAppSelector((state) => state.auth.user)
const dispatch = useAppDispatch()
async function handleLogout() {
try {
await AuthApi.logout()
} finally {
dispatch(clearCurrentUser())
}
}
return ( return (
<div className="bg-gray-50"> <div className="bg-gray-50">
@@ -33,6 +47,32 @@ export default function HeroLayout() {
> >
</Link> </Link>
{user ? (
<Dropdown
trigger={["hover"]}
menu={{
items: [
{
key: "logout",
label: "退出登录",
danger: true,
onClick: handleLogout,
},
],
}}
>
<span className="cursor-pointer text-gray-700 px-3 py-2 rounded-md text-sm font-medium">
{user.username}
</span>
</Dropdown>
) : (
<Link
to="/login"
className="text-gray-500 hover:text-gray-900 px-3 py-2 rounded-md text-sm font-medium"
>
</Link>
)}
<a <a
href="https://github.com/zihluwang/delta-force-firearm-modification-codes" href="https://github.com/zihluwang/delta-force-firearm-modification-codes"
target="_blank" target="_blank"
+81 -5
View File
@@ -1,8 +1,11 @@
import { useEffect, useState } from "react" import { useCallback, useEffect, useState } from "react"
import { Link } from "react-router-dom" import { Link } from "react-router-dom"
import { FirearmApi } from "@/api" import { FirearmApi } from "@/api"
import FirearmCreateModal from "@/components/firearm-create-modal"
import FirearmEditModal from "@/components/firearm-edit-modal"
import { useAppSelector } from "@/store"
import { Firearm, FirearmType } from "@/types" import { Firearm, FirearmType } from "@/types"
import { Button, Card, Col, Pagination, Row, Select, Tag, Typography } from "antd" import { Button, Card, Col, Pagination, Popconfirm, Row, Select, Tag, Typography, App } from "antd"
const firearmTypeText: Record<FirearmType, string> = { const firearmTypeText: Record<FirearmType, string> = {
RIFLE: "步枪", RIFLE: "步枪",
@@ -23,13 +26,18 @@ function asDps(fireRate: number, damage: number) {
} }
export default function FirearmsPage() { export default function FirearmsPage() {
const user = useAppSelector((state) => state.auth.user)
const { message } = App.useApp()
const [page, setPage] = useState<number>(1) const [page, setPage] = useState<number>(1)
const [typeFilter, setTypeFilter] = useState<FirearmTypeFilter>(allTypeValue) const [typeFilter, setTypeFilter] = useState<FirearmTypeFilter>(allTypeValue)
const [firearms, setFirearms] = useState<Firearm[]>([]) const [firearms, setFirearms] = useState<Firearm[]>([])
const [total, setTotal] = useState<number>(0) const [total, setTotal] = useState<number>(0)
const [createModalOpen, setCreateModalOpen] = useState(false)
const [editingFirearm, setEditingFirearm] = useState<Firearm | null>(null)
const [deletingId, setDeletingId] = useState<number | null>(null)
useEffect(() => { const loadFirearms = useCallback(() => {
FirearmApi.getFirearms({ return FirearmApi.getFirearms({
page: page - 1, page: page - 1,
size: 12, size: 12,
sortBy: "id", sortBy: "id",
@@ -41,9 +49,37 @@ export default function FirearmsPage() {
}) })
}, [page, typeFilter]) }, [page, typeFilter])
useEffect(() => {
loadFirearms()
}, [loadFirearms])
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 {
loadFirearms()
}
} catch {
message.error("武器删除失败,请稍后重试")
} finally {
setDeletingId(null)
}
}
return ( return (
<> <>
<div className="mb-4 flex justify-end"> <div className="mb-4 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
<div>
{user && (
<Button type="primary" onClick={() => setCreateModalOpen(true)}>
</Button>
)}
</div>
<Select<FirearmTypeFilter> <Select<FirearmTypeFilter>
className="w-full sm:w-64" className="w-full sm:w-64"
value={typeFilter} value={typeFilter}
@@ -66,6 +102,27 @@ export default function FirearmsPage() {
<Col key={firearm.id} xs={24} md={12} lg={8}> <Col key={firearm.id} xs={24} md={12} lg={8}>
<Card <Card
title={firearm.name} title={firearm.name}
extra={
user ? (
<div className="flex items-center gap-1">
<Button type="link" size="small" onClick={() => setEditingFirearm(firearm)}>
</Button>
<Popconfirm
title="确认删除武器"
description={`确定要删除 ${firearm.name} 吗?该操作不可撤销。`}
okText="删除"
cancelText="取消"
okButtonProps={{ danger: true, loading: deletingId === firearm.id }}
onConfirm={() => handleDelete(firearm)}
>
<Button type="link" danger size="small" loading={deletingId === firearm.id}>
</Button>
</Popconfirm>
</div>
) : null
}
variant="outlined" variant="outlined"
styles={{ styles={{
header: { minHeight: 56 }, header: { minHeight: 56 },
@@ -127,6 +184,25 @@ export default function FirearmsPage() {
showSizeChanger={false} showSizeChanger={false}
/> />
</div> </div>
<FirearmCreateModal
open={createModalOpen}
onCancel={() => setCreateModalOpen(false)}
onSuccess={() => {
setCreateModalOpen(false)
loadFirearms()
}}
/>
<FirearmEditModal
open={!!editingFirearm}
firearm={editingFirearm}
onCancel={() => setEditingFirearm(null)}
onSuccess={() => {
setEditingFirearm(null)
loadFirearms()
}}
/>
</> </>
) )
} }
+67
View File
@@ -0,0 +1,67 @@
import { useState } from "react"
import { useNavigate } from "react-router-dom"
import { App, Button, Card, Form, Input, Typography } from "antd"
import { AuthApi } from "@/api"
import { useAppDispatch } from "@/store"
import { setCurrentUser } from "@/store/auth-slice"
import { LoginRequest } from "@/types"
export default function LoginPage() {
const navigate = useNavigate()
const { message } = App.useApp()
const dispatch = useAppDispatch()
const [loading, setLoading] = useState(false)
async function onFinish(values: LoginRequest) {
setLoading(true)
try {
const user = await AuthApi.login(values)
dispatch(setCurrentUser(user))
message.success(`欢迎回来,${user.username}`)
navigate("/firearms")
} catch {
message.error("登录失败,请检查帐号或密码")
} finally {
setLoading(false)
}
}
return (
<div className="min-h-screen bg-gray-100 px-4 py-10 sm:py-16">
<div className="mx-auto max-w-md">
<Card bordered={false} className="shadow-sm">
<Typography.Title level={3} className="!mb-2 text-center">
</Typography.Title>
<Typography.Paragraph className="!mb-6 text-center !text-gray-500">
使
</Typography.Paragraph>
<Form<LoginRequest> layout="vertical" onFinish={onFinish} requiredMark={false}>
<Form.Item<LoginRequest>
name="principle"
label="帐号"
rules={[{ required: true, message: "请输入帐号" }]}
>
<Input autoComplete="username" placeholder="请输入帐号" />
</Form.Item>
<Form.Item<LoginRequest>
name="credential"
label="密码"
rules={[{ required: true, message: "请输入密码" }]}
>
<Input.Password autoComplete="current-password" placeholder="请输入密码" />
</Form.Item>
<Form.Item className="!mb-0">
<Button type="primary" htmlType="submit" loading={loading} block>
</Button>
</Form.Item>
</Form>
</Card>
</div>
</div>
)
}
+13 -1
View File
@@ -2,11 +2,13 @@ import { useEffect, useMemo, useState } from "react"
import { Link, useSearchParams } from "react-router-dom" import { Link, useSearchParams } from "react-router-dom"
import { Button, Card, Col, Pagination, Row, Select, Space, Tag, Typography } from "antd" import { Button, Card, Col, Pagination, Row, Select, Space, Tag, Typography } from "antd"
import { ModificationApi, TagApi } from "@/api" import { ModificationApi, TagApi } from "@/api"
import { useAppSelector } from "@/store"
import { Modification } from "@/types" import { Modification } from "@/types"
const pageSize = 12 const pageSize = 12
export default function ModCodesPage() { export default function ModCodesPage() {
const user = useAppSelector((state) => state.auth.user)
const [searchParams] = useSearchParams() const [searchParams] = useSearchParams()
const firearmId = useMemo(() => searchParams.get("firearmId") || undefined, [searchParams]) const firearmId = useMemo(() => searchParams.get("firearmId") || undefined, [searchParams])
@@ -47,10 +49,11 @@ export default function ModCodesPage() {
return ( return (
<> <>
<div className="mb-4 flex items-center justify-between gap-4"> <div className="mb-4 flex items-start justify-between gap-4">
<Typography.Title level={4} className="mb-0!"> <Typography.Title level={4} className="mb-0!">
</Typography.Title> </Typography.Title>
<div className="flex flex-wrap items-center justify-end gap-3">
<Space wrap> <Space wrap>
<span></span> <span></span>
<Select<string[]> <Select<string[]>
@@ -79,6 +82,8 @@ export default function ModCodesPage() {
</Link> </Link>
)} )}
</Space> </Space>
{user && <Button type="primary"></Button>}
</div>
</div> </div>
<div className="mb-6"> <div className="mb-6">
@@ -87,6 +92,13 @@ export default function ModCodesPage() {
<Col key={modification.id} xs={24} md={12} lg={8}> <Col key={modification.id} xs={24} md={12} lg={8}>
<Card <Card
title={modification.name} title={modification.name}
extra={
user ? (
<Button type="link" size="small">
</Button>
) : null
}
variant="outlined" variant="outlined"
styles={{ styles={{
header: { minHeight: 56 }, header: { minHeight: 56 },
+11
View File
@@ -1,6 +1,7 @@
import { ComponentType } from "react" import { ComponentType } from "react"
import { createBrowserRouter } from "react-router-dom" import { createBrowserRouter } from "react-router-dom"
import ErrorPage from "@/components/error-page" import ErrorPage from "@/components/error-page"
import EmptyLayout from "@/layout/empty-layout"
import HeroLayout from "@/layout/hero-layout" import HeroLayout from "@/layout/hero-layout"
function lazy<T extends { default: ComponentType<unknown> }>(importer: () => Promise<T>) { function lazy<T extends { default: ComponentType<unknown> }>(importer: () => Promise<T>) {
@@ -37,6 +38,16 @@ const router = createBrowserRouter(
}, },
], ],
}, },
{
element: <EmptyLayout />,
errorElement: <ErrorPage />,
children: [
{
path: "login",
lazy: lazy(() => import("@/page/login")),
},
],
},
], ],
{ {
basename: "/", basename: "/",
+1
View File
@@ -4,6 +4,7 @@ import dayjs from "dayjs"
const WebClient = axios.create({ const WebClient = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL, baseURL: import.meta.env.VITE_API_BASE_URL,
timeout: dayjs.duration({ seconds: 10 }).asMilliseconds(), timeout: dayjs.duration({ seconds: 10 }).asMilliseconds(),
withCredentials: true
}) })
export { WebClient } export { WebClient }
+26
View File
@@ -0,0 +1,26 @@
import { createSlice, PayloadAction } from "@reduxjs/toolkit"
import { User } from "@/types"
interface AuthState {
user: User | null
}
const initialState: AuthState = {
user: null,
}
const authSlice = createSlice({
name: "auth",
initialState,
reducers: {
setCurrentUser(state, action: PayloadAction<User>) {
state.user = action.payload
},
clearCurrentUser(state) {
state.user = null
},
},
})
export const { setCurrentUser, clearCurrentUser } = authSlice.actions
export const authReducer = authSlice.reducer
+3 -1
View File
@@ -11,6 +11,7 @@ import {
REGISTER, REGISTER,
} from "redux-persist" } from "redux-persist"
import createWebStorage from "redux-persist/es/storage/createWebStorage" import createWebStorage from "redux-persist/es/storage/createWebStorage"
import { authReducer } from "./auth-slice"
import { firearmsReducer } from "./firearms-slice" import { firearmsReducer } from "./firearms-slice"
const storage = createWebStorage(import.meta.env.VITE_REDUX_STORAGE ?? "local") const storage = createWebStorage(import.meta.env.VITE_REDUX_STORAGE ?? "local")
@@ -18,10 +19,11 @@ const storage = createWebStorage(import.meta.env.VITE_REDUX_STORAGE ?? "local")
const persistConfig = { const persistConfig = {
key: "root", key: "root",
storage, storage,
whitelist: ["firearms"], whitelist: ["auth", "firearms"],
} }
const rootReducer = combineReducers({ const rootReducer = combineReducers({
auth: authReducer,
firearms: firearmsReducer firearms: firearmsReducer
}) })
+14 -1
View File
@@ -27,9 +27,11 @@ export interface Firearm {
fireRate: number fireRate: number
armourDamage: number armourDamage: number
bodyDamage: number bodyDamage: number
review: string review: string | null
} }
export interface AddFirearmRequest extends Omit<Firearm, "id"> {}
export interface Modification { export interface Modification {
id: number id: number
firearmId: number firearmId: number
@@ -47,3 +49,14 @@ export interface PageQueryParams {
sortBy?: string sortBy?: string
direction?: Direction direction?: Direction
} }
export interface LoginRequest {
principle: string
credential: string
}
export interface User {
id: number
username: string
email: string
}
+9
View File
@@ -12,4 +12,13 @@ export default defineConfig({
"@": fileURLToPath(new URL("./src", import.meta.url)), "@": fileURLToPath(new URL("./src", import.meta.url)),
}, },
}, },
server: {
proxy: {
'/api': {
target: 'http://localhost:8080',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
}
}) })