Merge branch 'develop' into dependabot/npm_and_yarn/dependency-updates-2c57f57997
This commit is contained in:
Generated
+62
-62
@@ -372,8 +372,8 @@ packages:
|
||||
react: '>=16.9.0'
|
||||
react-dom: '>=16.9.0'
|
||||
|
||||
'@rc-component/image@1.8.0':
|
||||
resolution: {integrity: sha512-Dr41bFevLB5NgVaJhEUmNvbEf+ynAhim6W98ZW2xvCsdFISc2TYP4ZvCVdie3eaZdum2kieVcvpNHu+UrzAAHA==}
|
||||
'@rc-component/image@1.8.1':
|
||||
resolution: {integrity: sha512-JfPCijmMl+EaMvbftsEs/4VHmTyJKsZBh5ujFowSA45i9NTVYS1vuHtgpVV/QrGa27kXwbVOZriffCe/PNKuMw==}
|
||||
peerDependencies:
|
||||
react: '>=16.9.0'
|
||||
react-dom: '>=16.9.0'
|
||||
@@ -583,8 +583,8 @@ packages:
|
||||
react: '>=16.9.0'
|
||||
react-dom: '>=16.9.0'
|
||||
|
||||
'@rc-component/util@1.10.0':
|
||||
resolution: {integrity: sha512-aY9GLBuiUdpyfIUpAWSYer4Tu3mVaZCo5A0q9NtXcazT3MRiI3/WNHCR+DUn5VAtR6iRRf0ynCqQUcHli5UdYw==}
|
||||
'@rc-component/util@1.10.1':
|
||||
resolution: {integrity: sha512-q++9S6rUa5Idb/xIBNz6jtvumw5+O5YV5V0g4iK9mn9jWs4oGJheE3ZN1kAnE723AXyaD8v95yeOASmdk8Jnng==}
|
||||
peerDependencies:
|
||||
react: '>=18.0.0'
|
||||
react-dom: '>=18.0.0'
|
||||
@@ -1082,8 +1082,8 @@ packages:
|
||||
resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
postcss@8.5.8:
|
||||
resolution: {integrity: sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==}
|
||||
postcss@8.5.9:
|
||||
resolution: {integrity: sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
prettier@3.8.3:
|
||||
@@ -1183,16 +1183,16 @@ packages:
|
||||
tailwindcss@4.2.2:
|
||||
resolution: {integrity: sha512-KWBIxs1Xb6NoLdMVqhbhgwZf2PGBpPEiwOqgI4pFIYbNTfBXiKYyWoTsXgBQ9WFg/OlhnvHaY+AEpW7wSmFo2Q==}
|
||||
|
||||
tapable@2.3.0:
|
||||
resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==}
|
||||
tapable@2.3.2:
|
||||
resolution: {integrity: sha512-1MOpMXuhGzGL5TTCZFItxCc0AARf1EZFQkGqMm7ERKj8+Hgr5oLvJOVFcC+lRmR8hCe2S3jC4T5D7Vg/d7/fhA==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
throttle-debounce@5.0.2:
|
||||
resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==}
|
||||
engines: {node: '>=12.22'}
|
||||
|
||||
tinyglobby@0.2.15:
|
||||
resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
|
||||
tinyglobby@0.2.16:
|
||||
resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
|
||||
tslib@2.8.1:
|
||||
@@ -1264,7 +1264,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@ant-design/cssinjs': 2.1.2(react-dom@19.2.5(react@19.2.5))(react@19.2.5)
|
||||
'@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-dom: 19.2.5(react@19.2.5)
|
||||
|
||||
@@ -1273,7 +1273,7 @@ snapshots:
|
||||
'@babel/runtime': 7.29.2
|
||||
'@emotion/hash': 0.8.0
|
||||
'@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
|
||||
csstype: 3.2.3
|
||||
react: 19.2.5
|
||||
@@ -1288,7 +1288,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@ant-design/colors': 8.0.1
|
||||
'@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
|
||||
react: 19.2.5
|
||||
react-dom: 19.2.5(react@19.2.5)
|
||||
@@ -1438,14 +1438,14 @@ snapshots:
|
||||
dependencies:
|
||||
'@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/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
|
||||
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)':
|
||||
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
|
||||
react: 19.2.5
|
||||
react-dom: 19.2.5(react@19.2.5)
|
||||
@@ -1454,7 +1454,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@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/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
|
||||
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)':
|
||||
dependencies:
|
||||
'@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
|
||||
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)':
|
||||
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-dom: 19.2.5(react@19.2.5)
|
||||
|
||||
@@ -1477,7 +1477,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@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/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
|
||||
react: 19.2.5
|
||||
react-dom: 19.2.5(react@19.2.5)
|
||||
@@ -1486,7 +1486,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@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/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
|
||||
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)':
|
||||
dependencies:
|
||||
'@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
|
||||
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)':
|
||||
dependencies:
|
||||
'@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
|
||||
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:
|
||||
'@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/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
|
||||
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)':
|
||||
dependencies:
|
||||
'@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
|
||||
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)':
|
||||
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
|
||||
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/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/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
|
||||
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/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/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
|
||||
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)':
|
||||
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
|
||||
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)':
|
||||
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-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)':
|
||||
dependencies:
|
||||
'@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
|
||||
react: 19.2.5
|
||||
react-dom: 19.2.5(react@19.2.5)
|
||||
@@ -1581,14 +1581,14 @@ snapshots:
|
||||
dependencies:
|
||||
'@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/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
|
||||
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)':
|
||||
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
|
||||
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/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/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
|
||||
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)':
|
||||
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
|
||||
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)':
|
||||
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
|
||||
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)':
|
||||
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
|
||||
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)':
|
||||
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-dom: 19.2.5(react@19.2.5)
|
||||
|
||||
@@ -1642,7 +1642,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@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/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
|
||||
react: 19.2.5
|
||||
react-dom: 19.2.5(react@19.2.5)
|
||||
@@ -1651,7 +1651,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@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/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)
|
||||
clsx: 2.1.1
|
||||
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)':
|
||||
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
|
||||
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)':
|
||||
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
|
||||
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)':
|
||||
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
|
||||
react: 19.2.5
|
||||
react-dom: 19.2.5(react@19.2.5)
|
||||
@@ -1682,7 +1682,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@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/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)
|
||||
clsx: 2.1.1
|
||||
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/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/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
|
||||
react: 19.2.5
|
||||
react-dom: 19.2.5(react@19.2.5)
|
||||
@@ -1703,7 +1703,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@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/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
|
||||
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)':
|
||||
dependencies:
|
||||
'@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
|
||||
react: 19.2.5
|
||||
react-dom: 19.2.5(react@19.2.5)
|
||||
@@ -1720,7 +1720,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@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/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
|
||||
react: 19.2.5
|
||||
react-dom: 19.2.5(react@19.2.5)
|
||||
@@ -1729,7 +1729,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@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/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
|
||||
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)':
|
||||
dependencies:
|
||||
'@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)
|
||||
clsx: 2.1.1
|
||||
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/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/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
|
||||
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)':
|
||||
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
|
||||
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:
|
||||
is-mobile: 5.0.0
|
||||
react: 19.2.5
|
||||
@@ -1771,7 +1771,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@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/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
|
||||
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/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/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-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)
|
||||
@@ -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/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/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
|
||||
dayjs: 1.11.20
|
||||
react: 19.2.5
|
||||
@@ -2044,7 +2044,7 @@ snapshots:
|
||||
enhanced-resolve@5.20.1:
|
||||
dependencies:
|
||||
graceful-fs: 4.2.11
|
||||
tapable: 2.3.0
|
||||
tapable: 2.3.2
|
||||
|
||||
es-define-property@1.0.1: {}
|
||||
|
||||
@@ -2221,7 +2221,7 @@ snapshots:
|
||||
|
||||
picomatch@4.0.4: {}
|
||||
|
||||
postcss@8.5.8:
|
||||
postcss@8.5.9:
|
||||
dependencies:
|
||||
nanoid: 3.3.11
|
||||
picocolors: 1.1.1
|
||||
@@ -2314,11 +2314,11 @@ snapshots:
|
||||
|
||||
tailwindcss@4.2.2: {}
|
||||
|
||||
tapable@2.3.0: {}
|
||||
tapable@2.3.2: {}
|
||||
|
||||
throttle-debounce@5.0.2: {}
|
||||
|
||||
tinyglobby@0.2.15:
|
||||
tinyglobby@0.2.16:
|
||||
dependencies:
|
||||
fdir: 6.5.0(picomatch@4.0.4)
|
||||
picomatch: 4.0.4
|
||||
@@ -2338,9 +2338,9 @@ snapshots:
|
||||
dependencies:
|
||||
lightningcss: 1.32.0
|
||||
picomatch: 4.0.4
|
||||
postcss: 8.5.8
|
||||
postcss: 8.5.9
|
||||
rolldown: 1.0.0-rc.15
|
||||
tinyglobby: 0.2.15
|
||||
tinyglobby: 0.2.16
|
||||
optionalDependencies:
|
||||
'@types/node': 22.19.17
|
||||
esbuild: 0.27.4
|
||||
|
||||
@@ -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
@@ -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 { 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}`)
|
||||
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,3 +1,4 @@
|
||||
export * as FirearmApi from "./firearm-api"
|
||||
export * as ModificationApi from "./modification-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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { Outlet, Link } from "react-router-dom"
|
||||
import { useMemo } from "react"
|
||||
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.
|
||||
@@ -8,6 +12,16 @@ import dayjs from "dayjs"
|
||||
*/
|
||||
export default function HeroLayout() {
|
||||
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 (
|
||||
<div className="bg-gray-50">
|
||||
@@ -33,6 +47,32 @@ export default function HeroLayout() {
|
||||
>
|
||||
改枪码
|
||||
</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
|
||||
href="https://github.com/zihluwang/delta-force-firearm-modification-codes"
|
||||
target="_blank"
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import { useEffect, useState } from "react"
|
||||
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 { useAppSelector } from "@/store"
|
||||
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> = {
|
||||
RIFLE: "步枪",
|
||||
@@ -23,13 +26,18 @@ function asDps(fireRate: number, damage: number) {
|
||||
}
|
||||
|
||||
export default function FirearmsPage() {
|
||||
const user = useAppSelector((state) => state.auth.user)
|
||||
const { message } = App.useApp()
|
||||
const [page, setPage] = useState<number>(1)
|
||||
const [typeFilter, setTypeFilter] = useState<FirearmTypeFilter>(allTypeValue)
|
||||
const [firearms, setFirearms] = useState<Firearm[]>([])
|
||||
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(() => {
|
||||
FirearmApi.getFirearms({
|
||||
const loadFirearms = useCallback(() => {
|
||||
return FirearmApi.getFirearms({
|
||||
page: page - 1,
|
||||
size: 12,
|
||||
sortBy: "id",
|
||||
@@ -41,9 +49,37 @@ export default function FirearmsPage() {
|
||||
})
|
||||
}, [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 (
|
||||
<>
|
||||
<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>
|
||||
className="w-full sm:w-64"
|
||||
value={typeFilter}
|
||||
@@ -66,6 +102,27 @@ export default function FirearmsPage() {
|
||||
<Col key={firearm.id} xs={24} md={12} lg={8}>
|
||||
<Card
|
||||
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"
|
||||
styles={{
|
||||
header: { minHeight: 56 },
|
||||
@@ -127,6 +184,25 @@ export default function FirearmsPage() {
|
||||
showSizeChanger={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<FirearmCreateModal
|
||||
open={createModalOpen}
|
||||
onCancel={() => setCreateModalOpen(false)}
|
||||
onSuccess={() => {
|
||||
setCreateModalOpen(false)
|
||||
loadFirearms()
|
||||
}}
|
||||
/>
|
||||
|
||||
<FirearmEditModal
|
||||
open={!!editingFirearm}
|
||||
firearm={editingFirearm}
|
||||
onCancel={() => setEditingFirearm(null)}
|
||||
onSuccess={() => {
|
||||
setEditingFirearm(null)
|
||||
loadFirearms()
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
)
|
||||
}
|
||||
@@ -2,11 +2,13 @@ import { useEffect, useMemo, useState } from "react"
|
||||
import { Link, useSearchParams } from "react-router-dom"
|
||||
import { Button, Card, Col, Pagination, Row, Select, Space, Tag, Typography } from "antd"
|
||||
import { ModificationApi, TagApi } from "@/api"
|
||||
import { useAppSelector } from "@/store"
|
||||
import { Modification } from "@/types"
|
||||
|
||||
const pageSize = 12
|
||||
|
||||
export default function ModCodesPage() {
|
||||
const user = useAppSelector((state) => state.auth.user)
|
||||
const [searchParams] = useSearchParams()
|
||||
const firearmId = useMemo(() => searchParams.get("firearmId") || undefined, [searchParams])
|
||||
|
||||
@@ -47,10 +49,11 @@ export default function ModCodesPage() {
|
||||
|
||||
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>
|
||||
<div className="flex flex-wrap items-center justify-end gap-3">
|
||||
<Space wrap>
|
||||
<span>标签:</span>
|
||||
<Select<string[]>
|
||||
@@ -79,6 +82,8 @@ export default function ModCodesPage() {
|
||||
</Link>
|
||||
)}
|
||||
</Space>
|
||||
{user && <Button type="primary">添加改装</Button>}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mb-6">
|
||||
@@ -87,6 +92,13 @@ export default function ModCodesPage() {
|
||||
<Col key={modification.id} xs={24} md={12} lg={8}>
|
||||
<Card
|
||||
title={modification.name}
|
||||
extra={
|
||||
user ? (
|
||||
<Button type="link" size="small">
|
||||
编辑
|
||||
</Button>
|
||||
) : null
|
||||
}
|
||||
variant="outlined"
|
||||
styles={{
|
||||
header: { minHeight: 56 },
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ComponentType } from "react"
|
||||
import { createBrowserRouter } from "react-router-dom"
|
||||
import ErrorPage from "@/components/error-page"
|
||||
import EmptyLayout from "@/layout/empty-layout"
|
||||
import HeroLayout from "@/layout/hero-layout"
|
||||
|
||||
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: "/",
|
||||
|
||||
@@ -4,6 +4,7 @@ import dayjs from "dayjs"
|
||||
const WebClient = axios.create({
|
||||
baseURL: import.meta.env.VITE_API_BASE_URL,
|
||||
timeout: dayjs.duration({ seconds: 10 }).asMilliseconds(),
|
||||
withCredentials: true
|
||||
})
|
||||
|
||||
export { WebClient }
|
||||
|
||||
@@ -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
@@ -11,6 +11,7 @@ import {
|
||||
REGISTER,
|
||||
} from "redux-persist"
|
||||
import createWebStorage from "redux-persist/es/storage/createWebStorage"
|
||||
import { authReducer } from "./auth-slice"
|
||||
import { firearmsReducer } from "./firearms-slice"
|
||||
|
||||
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 = {
|
||||
key: "root",
|
||||
storage,
|
||||
whitelist: ["firearms"],
|
||||
whitelist: ["auth", "firearms"],
|
||||
}
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
auth: authReducer,
|
||||
firearms: firearmsReducer
|
||||
})
|
||||
|
||||
|
||||
+14
-1
@@ -27,9 +27,11 @@ export interface Firearm {
|
||||
fireRate: number
|
||||
armourDamage: number
|
||||
bodyDamage: number
|
||||
review: string
|
||||
review: string | null
|
||||
}
|
||||
|
||||
export interface AddFirearmRequest extends Omit<Firearm, "id"> {}
|
||||
|
||||
export interface Modification {
|
||||
id: number
|
||||
firearmId: number
|
||||
@@ -47,3 +49,14 @@ export interface PageQueryParams {
|
||||
sortBy?: string
|
||||
direction?: Direction
|
||||
}
|
||||
|
||||
export interface LoginRequest {
|
||||
principle: string
|
||||
credential: string
|
||||
}
|
||||
|
||||
export interface User {
|
||||
id: number
|
||||
username: string
|
||||
email: string
|
||||
}
|
||||
|
||||
@@ -12,4 +12,13 @@ export default defineConfig({
|
||||
"@": fileURLToPath(new URL("./src", import.meta.url)),
|
||||
},
|
||||
},
|
||||
server: {
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:8080',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/api/, '')
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user