整体链接

Change-Id: Id3379c6188613acdc95548964f19e317eda8dc4f
diff --git a/package-lock.json b/package-lock.json
index 260f92c..e758b97 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -15,10 +15,12 @@
         "@types/react": "^19.0.10",
         "@types/react-dom": "^19.0.4",
         "antd": "^5.24.7",
+        "antd-style": "^3.7.1",
         "axios": "^1.8.4",
         "axios-mock-adapter": "^2.1.0",
         "core-js": "^3.41.0",
         "cross-env": "^7.0.3",
+        "dayjs": "^1.11.13",
         "jest-environment-jsdom": "^29.7.0",
         "lodash": "^4.17.21",
         "lodash.debounce": "^4.0.8",
@@ -3120,18 +3122,190 @@
         "node": ">=14.17.0"
       }
     },
+    "node_modules/@emotion/babel-plugin": {
+      "version": "11.13.5",
+      "resolved": "https://registry.npmmirror.com/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz",
+      "integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.16.7",
+        "@babel/runtime": "^7.18.3",
+        "@emotion/hash": "^0.9.2",
+        "@emotion/memoize": "^0.9.0",
+        "@emotion/serialize": "^1.3.3",
+        "babel-plugin-macros": "^3.1.0",
+        "convert-source-map": "^1.5.0",
+        "escape-string-regexp": "^4.0.0",
+        "find-root": "^1.1.0",
+        "source-map": "^0.5.7",
+        "stylis": "4.2.0"
+      }
+    },
+    "node_modules/@emotion/babel-plugin/node_modules/@emotion/hash": {
+      "version": "0.9.2",
+      "resolved": "https://registry.npmmirror.com/@emotion/hash/-/hash-0.9.2.tgz",
+      "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
+      "license": "MIT"
+    },
+    "node_modules/@emotion/babel-plugin/node_modules/convert-source-map": {
+      "version": "1.9.0",
+      "resolved": "https://registry.npmmirror.com/convert-source-map/-/convert-source-map-1.9.0.tgz",
+      "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
+      "license": "MIT"
+    },
+    "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@emotion/babel-plugin/node_modules/source-map": {
+      "version": "0.5.7",
+      "resolved": "https://registry.npmmirror.com/source-map/-/source-map-0.5.7.tgz",
+      "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
+      "license": "BSD-3-Clause",
+      "engines": {
+        "node": ">=0.10.0"
+      }
+    },
+    "node_modules/@emotion/babel-plugin/node_modules/stylis": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/stylis/-/stylis-4.2.0.tgz",
+      "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==",
+      "license": "MIT"
+    },
+    "node_modules/@emotion/cache": {
+      "version": "11.14.0",
+      "resolved": "https://registry.npmmirror.com/@emotion/cache/-/cache-11.14.0.tgz",
+      "integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==",
+      "license": "MIT",
+      "dependencies": {
+        "@emotion/memoize": "^0.9.0",
+        "@emotion/sheet": "^1.4.0",
+        "@emotion/utils": "^1.4.2",
+        "@emotion/weak-memoize": "^0.4.0",
+        "stylis": "4.2.0"
+      }
+    },
+    "node_modules/@emotion/cache/node_modules/stylis": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmmirror.com/stylis/-/stylis-4.2.0.tgz",
+      "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==",
+      "license": "MIT"
+    },
+    "node_modules/@emotion/css": {
+      "version": "11.13.5",
+      "resolved": "https://registry.npmmirror.com/@emotion/css/-/css-11.13.5.tgz",
+      "integrity": "sha512-wQdD0Xhkn3Qy2VNcIzbLP9MR8TafI0MJb7BEAXKp+w4+XqErksWR4OXomuDzPsN4InLdGhVe6EYcn2ZIUCpB8w==",
+      "license": "MIT",
+      "dependencies": {
+        "@emotion/babel-plugin": "^11.13.5",
+        "@emotion/cache": "^11.13.5",
+        "@emotion/serialize": "^1.3.3",
+        "@emotion/sheet": "^1.4.0",
+        "@emotion/utils": "^1.4.2"
+      }
+    },
     "node_modules/@emotion/hash": {
       "version": "0.8.0",
       "resolved": "https://registry.npmmirror.com/@emotion/hash/-/hash-0.8.0.tgz",
       "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==",
       "license": "MIT"
     },
+    "node_modules/@emotion/memoize": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmmirror.com/@emotion/memoize/-/memoize-0.9.0.tgz",
+      "integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==",
+      "license": "MIT"
+    },
+    "node_modules/@emotion/react": {
+      "version": "11.14.0",
+      "resolved": "https://registry.npmmirror.com/@emotion/react/-/react-11.14.0.tgz",
+      "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.18.3",
+        "@emotion/babel-plugin": "^11.13.5",
+        "@emotion/cache": "^11.14.0",
+        "@emotion/serialize": "^1.3.3",
+        "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0",
+        "@emotion/utils": "^1.4.2",
+        "@emotion/weak-memoize": "^0.4.0",
+        "hoist-non-react-statics": "^3.3.1"
+      },
+      "peerDependencies": {
+        "react": ">=16.8.0"
+      },
+      "peerDependenciesMeta": {
+        "@types/react": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/@emotion/serialize": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmmirror.com/@emotion/serialize/-/serialize-1.3.3.tgz",
+      "integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==",
+      "license": "MIT",
+      "dependencies": {
+        "@emotion/hash": "^0.9.2",
+        "@emotion/memoize": "^0.9.0",
+        "@emotion/unitless": "^0.10.0",
+        "@emotion/utils": "^1.4.2",
+        "csstype": "^3.0.2"
+      }
+    },
+    "node_modules/@emotion/serialize/node_modules/@emotion/hash": {
+      "version": "0.9.2",
+      "resolved": "https://registry.npmmirror.com/@emotion/hash/-/hash-0.9.2.tgz",
+      "integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
+      "license": "MIT"
+    },
+    "node_modules/@emotion/serialize/node_modules/@emotion/unitless": {
+      "version": "0.10.0",
+      "resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.10.0.tgz",
+      "integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==",
+      "license": "MIT"
+    },
+    "node_modules/@emotion/sheet": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmmirror.com/@emotion/sheet/-/sheet-1.4.0.tgz",
+      "integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==",
+      "license": "MIT"
+    },
     "node_modules/@emotion/unitless": {
       "version": "0.7.5",
       "resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.7.5.tgz",
       "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==",
       "license": "MIT"
     },
+    "node_modules/@emotion/use-insertion-effect-with-fallbacks": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz",
+      "integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==",
+      "license": "MIT",
+      "peerDependencies": {
+        "react": ">=16.8.0"
+      }
+    },
+    "node_modules/@emotion/utils": {
+      "version": "1.4.2",
+      "resolved": "https://registry.npmmirror.com/@emotion/utils/-/utils-1.4.2.tgz",
+      "integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==",
+      "license": "MIT"
+    },
+    "node_modules/@emotion/weak-memoize": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmmirror.com/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz",
+      "integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==",
+      "license": "MIT"
+    },
     "node_modules/@istanbuljs/load-nyc-config": {
       "version": "1.1.0",
       "resolved": "https://registry.npmmirror.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@@ -4312,6 +4486,12 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/parse-json": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmmirror.com/@types/parse-json/-/parse-json-4.0.2.tgz",
+      "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
+      "license": "MIT"
+    },
     "node_modules/@types/qs": {
       "version": "6.9.18",
       "resolved": "https://registry.npmmirror.com/@types/qs/-/qs-6.9.18.tgz",
@@ -4880,6 +5060,26 @@
         "react-dom": ">=16.9.0"
       }
     },
+    "node_modules/antd-style": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmmirror.com/antd-style/-/antd-style-3.7.1.tgz",
+      "integrity": "sha512-CQOfddVp4aOvBfCepa+Kj2e7ap+2XBINg1Kn2osdE3oQvrD7KJu/K0sfnLcFLkgCJygbxmuazYdWLKb+drPDYA==",
+      "license": "MIT",
+      "dependencies": {
+        "@ant-design/cssinjs": "^1.21.1",
+        "@babel/runtime": "^7.24.1",
+        "@emotion/cache": "^11.11.0",
+        "@emotion/css": "^11.11.2",
+        "@emotion/react": "^11.11.4",
+        "@emotion/serialize": "^1.1.3",
+        "@emotion/utils": "^1.2.1",
+        "use-merge-value": "^1.2.0"
+      },
+      "peerDependencies": {
+        "antd": ">=5.8.1",
+        "react": ">=18"
+      }
+    },
     "node_modules/anymatch": {
       "version": "3.1.3",
       "resolved": "https://registry.npmmirror.com/anymatch/-/anymatch-3.1.3.tgz",
@@ -5079,6 +5279,37 @@
         "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
       }
     },
+    "node_modules/babel-plugin-macros": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmmirror.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
+      "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/runtime": "^7.12.5",
+        "cosmiconfig": "^7.0.0",
+        "resolve": "^1.19.0"
+      },
+      "engines": {
+        "node": ">=10",
+        "npm": ">=6"
+      }
+    },
+    "node_modules/babel-plugin-macros/node_modules/cosmiconfig": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmmirror.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
+      "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
+      "license": "MIT",
+      "dependencies": {
+        "@types/parse-json": "^4.0.0",
+        "import-fresh": "^3.2.1",
+        "parse-json": "^5.0.0",
+        "path-type": "^4.0.0",
+        "yaml": "^1.10.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
     "node_modules/babel-plugin-polyfill-corejs2": {
       "version": "0.4.13",
       "resolved": "https://registry.npmmirror.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz",
@@ -5405,7 +5636,6 @@
       "version": "3.1.0",
       "resolved": "https://registry.npmmirror.com/callsites/-/callsites-3.1.0.tgz",
       "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=6"
@@ -6777,7 +7007,6 @@
       "version": "1.3.2",
       "resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz",
       "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "is-arrayish": "^0.2.1"
@@ -7243,6 +7472,12 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/find-root": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmmirror.com/find-root/-/find-root-1.1.0.tgz",
+      "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
+      "license": "MIT"
+    },
     "node_modules/find-up": {
       "version": "5.0.0",
       "resolved": "https://registry.npmmirror.com/find-up/-/find-up-5.0.0.tgz",
@@ -7923,7 +8158,6 @@
       "version": "3.3.1",
       "resolved": "https://registry.npmmirror.com/import-fresh/-/import-fresh-3.3.1.tgz",
       "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "parent-module": "^1.0.0",
@@ -8078,7 +8312,6 @@
       "version": "0.2.1",
       "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz",
       "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/is-binary-path": {
@@ -9302,7 +9535,6 @@
       "version": "1.2.4",
       "resolved": "https://registry.npmmirror.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
       "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
-      "dev": true,
       "license": "MIT"
     },
     "node_modules/loader-runner": {
@@ -9947,7 +10179,6 @@
       "version": "1.0.1",
       "resolved": "https://registry.npmmirror.com/parent-module/-/parent-module-1.0.1.tgz",
       "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "callsites": "^3.0.0"
@@ -9960,7 +10191,6 @@
       "version": "5.2.0",
       "resolved": "https://registry.npmmirror.com/parse-json/-/parse-json-5.2.0.tgz",
       "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
-      "dev": true,
       "license": "MIT",
       "dependencies": {
         "@babel/code-frame": "^7.0.0",
@@ -10070,6 +10300,15 @@
       "dev": true,
       "license": "MIT"
     },
+    "node_modules/path-type": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmmirror.com/path-type/-/path-type-4.0.0.tgz",
+      "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/picocolors": {
       "version": "1.1.1",
       "resolved": "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz",
@@ -12656,7 +12895,6 @@
       "version": "4.0.0",
       "resolved": "https://registry.npmmirror.com/resolve-from/-/resolve-from-4.0.0.tgz",
       "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-      "dev": true,
       "license": "MIT",
       "engines": {
         "node": ">=4"
@@ -13987,6 +14225,15 @@
         "requires-port": "^1.0.0"
       }
     },
+    "node_modules/use-merge-value": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmmirror.com/use-merge-value/-/use-merge-value-1.2.0.tgz",
+      "integrity": "sha512-DXgG0kkgJN45TcyoXL49vJnn55LehnrmoHc7MbKi+QDBvr8dsesqws8UlyIWGHMR+JXgxc1nvY+jDGMlycsUcw==",
+      "license": "MIT",
+      "peerDependencies": {
+        "react": ">= 16.x"
+      }
+    },
     "node_modules/use-sync-external-store": {
       "version": "1.4.0",
       "resolved": "https://registry.npmmirror.com/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz",
@@ -14484,6 +14731,15 @@
       "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
       "license": "ISC"
     },
+    "node_modules/yaml": {
+      "version": "1.10.2",
+      "resolved": "https://registry.npmmirror.com/yaml/-/yaml-1.10.2.tgz",
+      "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
+      "license": "ISC",
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/yargs": {
       "version": "17.7.2",
       "resolved": "https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz",
diff --git a/package.json b/package.json
index f6bf82d..db333b2 100644
--- a/package.json
+++ b/package.json
@@ -17,10 +17,12 @@
     "@types/react": "^19.0.10",
     "@types/react-dom": "^19.0.4",
     "antd": "^5.24.7",
+    "antd-style": "^3.7.1",
     "axios": "^1.8.4",
     "axios-mock-adapter": "^2.1.0",
     "core-js": "^3.41.0",
     "cross-env": "^7.0.3",
+    "dayjs": "^1.11.13",
     "jest-environment-jsdom": "^29.7.0",
     "lodash": "^4.17.21",
     "lodash.debounce": "^4.0.8",
diff --git a/src/api/comment.ts b/src/api/comment.ts
index 1809ad2..6531eea 100644
--- a/src/api/comment.ts
+++ b/src/api/comment.ts
@@ -1 +1,2 @@
-export const  getPostComments = '/api/comments/post'
\ No newline at end of file
+export const  getPostComments = '/api/comments/post'
+export const postPostComments = '/api/comments'
\ No newline at end of file
diff --git a/src/components/corner/corner.tsx b/src/components/corner/corner.tsx
index ad80476..7f8d900 100644
--- a/src/components/corner/corner.tsx
+++ b/src/components/corner/corner.tsx
@@ -1,15 +1,30 @@
-// src/components/BottomRightUpload.tsx
-import React, { use } from 'react';
+
+import React, { useState, useCallback, useEffect } from 'react';
 import styles from './corner.module.css';
 import { useNavigate } from 'react-router';
 import { useSearchParams } from 'react-router-dom';
-const BottomRightUpload: React.FC = () => {
+import { MainTag, MainPostTag } from '@/types/common';
+import { Button, Checkbox, Row, Col } from 'antd';
+import { getTagsByMainTag } from '@/utils/common';
+interface CornerProp  {
+
+  setTagIds: (tagIds: number[]) => void;
+}
+
+const BottomRightUpload: React.FC<CornerProp> = (props:CornerProp) => {
   const [searchParams] = useSearchParams();
+  const [tags, setTags] = useState<Map<string, number>>(new Map);
+  const [selectdTags, setSelectedTags] = useState<number[]>([])
+  const setTagIds = props.setTagIds;
   const navigate = useNavigate();
   const type = searchParams.get('type');
+
   const handleUploadClick = () => {
     navigate('/createPost', { state: { isNewPost: true, type} });
   };
+  useEffect(()=>{
+    setTags(getTagsByMainTag(type as string))
+  },[])
 
   return (
     <div className={styles.container}>
@@ -18,17 +33,6 @@
       </button>
 
       <div className={styles.filterItem}>
-        <label htmlFor="category">分区:</label>
-        <select id="category">
-          <option value="all">全部</option>
-          <option value="video">视频</option>
-          <option value="music">音乐</option>
-          <option value="game">游戏</option>
-          <option value="software">软件</option>
-        </select>
-      </div>
-
-      <div className={styles.filterItem}>
         <label htmlFor="rating">评分:</label>
         <select id="rating">
           <option value="all">全部</option>
@@ -40,8 +44,41 @@
 
       <div className={styles.filterItem}>
         <label htmlFor="tag">标签:</label>
-        <input type="text" id="tag" placeholder="输入标签关键词" />
+        <Checkbox.Group
+          value={selectdTags}
+          onChange={(checkedValues) =>{
+              setSelectedTags([...checkedValues])
+          }}
+        >
+          <Row gutter={[12, 12]}>
+            {[...tags.entries()].map(([name, id]) => (
+              <Col key={id} xs={12} sm={12} md={8} lg={6}>
+                <Checkbox value={id}>{name}</Checkbox>
+              </Col>
+            ))}
+          </Row>
+        </Checkbox.Group>
       </div>
+
+      <Button
+        color='primary'
+        variant='outlined'
+        onClick={()=>{
+          console.log(selectdTags)
+          setTagIds([...selectdTags])
+
+        }}
+      > 筛选 </Button>
+
+      <Button
+        color='danger'
+        variant='outlined'
+        onClick={()=>{
+          setTagIds([])
+          setSelectedTags([])
+        }}
+      >清空筛选
+      </Button>
     </div>
   );
 };
diff --git a/src/components/navbar/navbar.tsx b/src/components/navbar/navbar.tsx
index e246ed6..3f26b6b 100644
--- a/src/components/navbar/navbar.tsx
+++ b/src/components/navbar/navbar.tsx
@@ -95,7 +95,7 @@
     key: 'game',
     icon: <GameIcon />,
     label: (
-    <a href={'/posts?type=game'}>
+    <a href={'/posts?type=Game'}>
         游戏
     </a>
     ),
diff --git a/src/components/postsPanel/postsPanel.module.css b/src/components/postsPanel/postsPanel.module.css
index b4b75ce..f639c77 100644
--- a/src/components/postsPanel/postsPanel.module.css
+++ b/src/components/postsPanel/postsPanel.module.css
@@ -4,7 +4,9 @@
     width:100%;
     padding:0px 5px;
 }
-
+span {
+    color:var(--text-color)
+}
 .header{
     border-bottom:1px solid var(--border-color);
     box-shadow: 1px;
diff --git a/src/components/postsPanel/postsPanel.tsx b/src/components/postsPanel/postsPanel.tsx
index 2916753..c99e40e 100644
--- a/src/components/postsPanel/postsPanel.tsx
+++ b/src/components/postsPanel/postsPanel.tsx
@@ -1,5 +1,5 @@
 import { useApi } from '@/hooks/request';
-import React, { useCallback } from  'react';
+import React, { useCallback, useEffect, useState } from  'react';
 import request from '@/utils/request'
 import style from './postsPanel.module.css'
 import { useNavigate } from 'react-router';
@@ -18,6 +18,14 @@
     const handlePostCheck =(postId:string) =>{
         nav('/postDetail?postId=' + postId);
     }
+
+    useEffect(()=>{
+        if(data){
+            console.log("data!!!")
+            console.log(data)
+        }
+    }, [data])
+
     return (
         <div className={style.panel}>
             <div className={style.header}>
@@ -25,11 +33,11 @@
                 <span className={style.more}>更多</span>
             </div>
             <div className={style.content} >
-                {data && data.length > 0 ?
-                data?.map((item: {postId:string, postTitle: string; createdAt: string }, index: number) => (
+                {data && data.records && data.records.length > 0 ?
+                data.records.map((item: {postId:string, postTitle: string; createdAt: string }, index: number) => (
                     <div key={index} className={style.item} onClick={()=> handlePostCheck(item.postId)} >
                         <span className={style.text}>{item.postTitle}</span>
-                        <span>{item.createdAt}</span>
+                        <span>{new Date(item.createdAt).toLocaleString()}</span>
                     </div>
                 ))  :(
                     <div>未查询到相关记录</div>
diff --git a/src/components/selfStatus/selfStatus.tsx b/src/components/selfStatus/selfStatus.tsx
index 24028ad..1fa812a 100644
--- a/src/components/selfStatus/selfStatus.tsx
+++ b/src/components/selfStatus/selfStatus.tsx
@@ -5,8 +5,9 @@
 import request from "@/utils/request";
 import { getUserInfo } from "@/api/user";
 import { useAppDispatch } from "@/hooks/store";
-
+import type { MenuProps } from 'antd';
 import { useNavigate } from "react-router";
+import { Dropdown } from "antd";
 
 
 interface SelfStatusProps {
@@ -32,29 +33,37 @@
             dispatch({ type: "user/getUserInfo", payload: data.userInfo });
         }
     }
+
+    const logOut = () =>{
+        dispatch({type:"user/logout"})
+        nav('/')
+    }
+
+    const menu: MenuProps['items'] =[
+    {
+        key:'1',
+        label:(<span onClick={logOut}>登出</span>)
+    }
+]
     useEffect(() => {
         fenchData();
         
     }, [ dispatch]);
 
-    function handleAvatarClick(){
-        nav('/homepage')
-    }
-
     return (
         <div className={style.container}>
-            <div className={style.left}>
+            <div className={style.left}
+                
+            >
                 {avatar && avatar.length > 0 ? (
-                <img className={style.avatar} src={avatar} alt="User Avatar" />):null}
+                <img className={style.avatar} onClick={() => nav('/homepage')} style={{ cursor: 'pointer'}}  src={avatar} alt="User Avatar" />):null}
             </div>
             <div className={style.right}>
                 <div className={style.info}>
-                    <p className={style.userName}>{userName}</p>
-                    <p 
-                    className={style.role}
-                    onClick={() => nav('/homepage')}
-                    style={{ cursor: 'pointer', textDecoration: 'underline' }}>
-                        用户组: {role && role.trim().length? role:'N/A'}</p>
+                    <Dropdown menu={{ items: menu }}>
+                        <p className={style.userName}>{userName}</p>
+                    </Dropdown>
+                    <p className={style.role}>用户组: {role && role.trim().length? role:'N/A'}</p>
                     <p className={style.uploadTraffic}>上传量: {uploadTraffic ? uploadTraffic : 0}</p>
                     <p className={style.downloadTraffic}>下载量: {downloadTraffic ? downloadTraffic : 0}</p>
 
diff --git a/src/components/selfStatus/style.module.css b/src/components/selfStatus/style.module.css
index 858e88a..da68ee3 100644
--- a/src/components/selfStatus/style.module.css
+++ b/src/components/selfStatus/style.module.css
@@ -13,7 +13,6 @@
 }
 
 .left {
-    border:1px solid #ccc;
     display: flex;
     flex-direction: column;
     align-items: center;
@@ -29,7 +28,6 @@
     margin-bottom: 10px;
 }
 .right {
-    border:1px solid #aaa;
     display: flex;
     flex-direction: column;
     justify-content: flex-start;
diff --git a/src/index.tsx b/src/index.tsx
index 494de3e..3e51093 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -5,8 +5,6 @@
 import store from "./store/index";
 import { RouterProvider } from "react-router";
 import './global.css';
-import { useEffect } from "react";
-import { checkAndRefreshToken } from "./utils/jwt";
 
 if(localStorage.getItem("theme") === null) {
     localStorage.setItem("theme", "light");
diff --git a/src/route/privateRoute.tsx b/src/route/privateRoute.tsx
index 992f372..2a1441a 100644
--- a/src/route/privateRoute.tsx
+++ b/src/route/privateRoute.tsx
@@ -1,6 +1,10 @@
 import { Navigate, Outlet } from 'react-router-dom'
-import React from 'react'
+import React, { useEffect, useState } from 'react'
 import { useSelector } from 'react-redux'
+import { useApi } from '@/hooks/request'
+import request from '@/utils/request'
+import { getUserInfo } from '@/api/user'
+import { useAppDispatch } from '@/hooks/store'
 
 interface PrivateRouteProps {
   role: number
@@ -15,6 +19,30 @@
 }: PrivateRouteProps) => {
   const isLogin = useSelector((state: any) => state.user.isLogin)
   const userRole = useSelector((state: any) => state.user.role)
+  const userId = useSelector((state: any) => state.user.userId)
+  const dispatch = useAppDispatch()
+  const [hasFetchedUser, setHasFetchedUser] = useState(false) // 防止重复请求
+  const { refresh: getUserInfoRefresh } = useApi(
+    () => request.get(getUserInfo),
+    false
+  )
+
+  useEffect(() => {
+    if (isLogin && !userId && !hasFetchedUser) {
+      const fetchUserInfo = async () => {
+        try {
+          const userInfo = await getUserInfoRefresh()
+          if (userInfo && !(userInfo as any).error) {
+            dispatch({ type: 'user/getUserInfo', payload: userInfo.userInfo })
+            setHasFetchedUser(true) // 标记已请求
+          }
+        } catch (error) {
+          console.error('获取用户信息失败:', error)
+        }
+      }
+      fetchUserInfo()
+    }
+  }, [isLogin, userId, hasFetchedUser, dispatch, getUserInfoRefresh])
 
   if (!isLogin) {
     return <Navigate to={redirectPath} replace />
@@ -24,12 +52,7 @@
     return <Navigate to={redirectPath} replace />
   }
 
-  return children ? (
-    <>{children}</>
-  ) : (
-    <Outlet />
-  )
-
+  return children ? <>{children}</> : <Outlet />
 }
 
 export default PrivateRoute
\ No newline at end of file
diff --git a/src/utils/axios.ts b/src/utils/axios.ts
index bb44c82..c13c516 100644
--- a/src/utils/axios.ts
+++ b/src/utils/axios.ts
@@ -28,11 +28,15 @@
   // 响应拦截器
   instance.interceptors.response.use(
     (response) => {
-      // 统一处理响应数据格式
-      if (response.status === 200) {
-        return response.data.data
+      if(response.headers['content-type']!=='application/x-bittorrent')
+      {
+        if (response.status === 200) {
+          return response.data.data
+        }
+        return Promise.reject(response.data)
+      }else {
+        return response
       }
-      return Promise.reject(response.data)
     },
     (error) => {
       if(error.status===401){
diff --git a/src/views/login/login.module.css b/src/views/login/login.module.css
index a7fc6f4..8866d78 100644
--- a/src/views/login/login.module.css
+++ b/src/views/login/login.module.css
@@ -3,7 +3,7 @@
     flex-direction: column;
     align-items: center; /* Center items horizontally */
     justify-content: center; /* Center items vertically */
-    height: 40%; /* Occupy 40% of the viewport height */
+    height: 50%; /* Occupy 40% of the viewport height */
     width:25%;
     background-color: #f0f8ff; /* Light blue background */
     box-shadow: 3px 3px 5px 6px #ccc;
diff --git a/src/views/login/login.tsx b/src/views/login/login.tsx
index 70b5573..1bc18c2 100644
--- a/src/views/login/login.tsx
+++ b/src/views/login/login.tsx
@@ -21,6 +21,7 @@
     const [codeBtnDisabled, setCodeBtnDisabled] = useState(false);
     const [codeBtnText, setCodeBtnText] = useState('发送验证码');
     const [codeTimer, setCodeTimer] = useState<NodeJS.Timeout | null>(null);
+    const [userName, setUserName] = useState('');
 
     const dispatch = useAppDispatch();
     const [messageApi, contextHolder] = message.useMessage();
@@ -141,6 +142,13 @@
             ) : (
                 <>
                     <input
+                        type='text'
+                        value={userName}
+                        onChange={(e)=>setUserName(e.target.value)}
+                        className={style.invite}
+                        placeholder="用户名"
+                    />
+                    <input
                         type="text"
                         value={inviteCode}
                         onChange={(e) => setInviteCode(e.target.value)}
diff --git a/src/views/postDetail/postDetail.tsx b/src/views/postDetail/postDetail.tsx
index 202907b..591d9f1 100644
--- a/src/views/postDetail/postDetail.tsx
+++ b/src/views/postDetail/postDetail.tsx
@@ -1,13 +1,16 @@
-import React, { useEffect, useState } from 'react';
+import React, { useCallback, useEffect, useState } from 'react';
 import styles from './PostDetail.module.css';
-import { Card, List, Typography, Button, Input, Spin, Empty, Divider } from 'antd';
+import { Card, List, Typography, Button, Input, Spin, Empty, Divider, message } from 'antd';
 import { getPostDetail } from '@/api/post';
-import { getPostComments } from '@/api/comment';
+import { getPostComments, postPostComments } from '@/api/comment';
 import { useSearchParams } from 'react-router-dom';
 import request from '@/utils/request';
 import { useApi } from '@/hooks/request';
 import Navbar from '@/components/navbar/navbar';
-import { DownloadOutlined, LikeOutlined, LikeFilled } from '@ant-design/icons';
+import { DownloadOutlined, LikeOutlined, LikeFilled, PayCircleOutlined } from '@ant-design/icons';
+import instance from '@/utils/axios';
+import { useAppSelector } from '@/hooks/store';
+
 
 const { Title, Text, Paragraph } = Typography;
 const { TextArea } = Input;
@@ -41,6 +44,7 @@
 }
 
 const PostDetail: React.FC = () => {
+  const [messageApi, placeholder] = message.useMessage();
   const [searchParams] = useSearchParams();
   const postId = searchParams.get('postId');
   const { refresh: getPostDetailRefresh } = useApi(() => request.get(getPostDetail + `/${postId}`), false);
@@ -50,6 +54,36 @@
   const [newComment, setNewComment] = useState<string>('');
   const [loading, setLoading] = useState<boolean>(true);
   const [liked, setLiked] = useState(false);
+  const userId = useAppSelector((state)=> state.user.userId)
+
+  const {refresh:postComment} = useApi((payload)=>request.post(postPostComments, payload), false)
+
+  const handleDownload = async (torrentId: string, torrentName:string) => {
+    console.log(torrentId)
+    try {
+      const token = localStorage.getItem('token'); // 或从状态管理中获取
+      const response = await instance.get(`/torrent/download/${torrentId}`, {
+        responseType: 'blob', 
+        headers: {
+          Authorization: `Bearer ${token}`,
+        },
+      });
+      console.log(response)
+      const blob = new Blob([response.data], { type: response.headers['content-type'] });
+      const downloadUrl = URL.createObjectURL(blob);
+
+      const a = document.createElement('a');
+      a.href = downloadUrl;
+      a.download = `资源_${torrentName}.torrent`; 
+      document.body.appendChild(a);
+      a.click();
+      document.body.removeChild(a);
+      URL.revokeObjectURL(downloadUrl); 
+    } catch (error) {
+      console.error('下载失败', error);
+      alert('下载失败,请检查网络或登录状态');
+    }
+  };
 
   useEffect(() => {
     if (!postId) return;
@@ -65,37 +99,41 @@
       const commentsRes = await getPostCommentsRefresh();
       setComments(commentsRes as CommentResponse[]);
       setLoading(false);
-      console.log("postRes:", postRes);
-      console.log("commentsRes:", commentsRes);
     };
     fetchData();
   }, [postId]);
 
+  const refreshComment = useCallback(async ()=>{
+    if(!postId) return;
+    const commentsRes = await getPostCommentsRefresh();
+    setComments(commentsRes as CommentResponse[]);
+  },[postId, setComments])
+
   if (loading) return <div className={styles.center}><Spin /></div>;
   if (!post) return <div className={styles.center}><Empty description="未找到帖子" /></div>;
 
   return (
     <div className={styles.container}>
-      {/* 固定导航栏 */}
+      {placeholder}
       <div className={styles.nav}>
         <Navbar current={post.postType} />
       </div>
-      {/* 内容区域 */}
+
       <div className={styles.contentArea}>
+        {/**帖子信息 */}
         <Card
           title={<Title level={3} style={{ margin: 0 }}>{post.postTitle || "帖子标题"}</Title>}
           className={styles.card}
-          bordered={false}
           style={{ marginBottom: 24, boxShadow: '0 4px 24px rgba(0,0,0,0.08)' }}
           extra={
             <div style={{ display: 'flex', gap: 16 }}>
               <Button
                 type="primary"
                 icon={<DownloadOutlined />}
-                onClick={() => {
-                  // 下载逻辑
-                  window.open(`/api/download/post/${post.postId}`, '_blank');
-                }}
+                onClick={() => 
+                  post.torrentId && post.postTitle
+                    ? handleDownload(post.torrentId, post.postTitle)
+                    : undefined}
               >
                 下载
               </Button>
@@ -115,9 +153,6 @@
             <Text type="secondary">作者ID: {post.userId}</Text>
             <Text type="secondary">发布时间: {post.createdAt ? new Date(post.createdAt).toLocaleString() : "未知"}</Text>
             <Text type="secondary">浏览量: {post.viewCount}</Text>
-            <Text type="secondary">类型: {post.postType}</Text>
-            <Text type="secondary">热度: {post.hotScore}</Text>
-            <Text type="secondary">最后计算: {post.lastCalculated ? new Date(post.lastCalculated).toLocaleString() : "无"}</Text>
           </div>
           {post.isLocked && (
             <div className={styles.locked}>
@@ -144,7 +179,22 @@
           <Button
             type="primary"
             style={{ marginTop: 12, float: 'right' }}
-            onClick={() => setNewComment('')}
+            onClick={async() => {
+              try{
+                await postComment({
+                  postId,
+                  userId,
+                  content:newComment,
+                  parentCommentId:''
+                })
+                setNewComment('')
+                refreshComment();
+                messageApi.success('发布成功');
+              }catch(err){
+                messageApi.error((err as Error).message);
+              }
+              
+            }}
             disabled={!newComment.trim()}
           >
             评论
@@ -152,12 +202,14 @@
           <div style={{ clear: 'both' }} />
         </Card>
 
+          {/* 评论区 */}
         <Card
           className={styles.commentListCard}
           title={<Title level={4} style={{ margin: 0 }}>评论区</Title>}
-          bodyStyle={{ padding: 0 }}
         >
-          <List
+          {
+            comments && comments.length &&
+            <List
             className={styles.commentList}
             dataSource={comments}
             locale={{ emptyText: <Empty description="暂无评论" /> }}
@@ -199,6 +251,8 @@
               </List.Item>
             )}
           />
+          }
+          
         </Card>
       </div>
     </div>
diff --git a/src/views/postList/postList.tsx b/src/views/postList/postList.tsx
index 28a660d..2312361 100644
--- a/src/views/postList/postList.tsx
+++ b/src/views/postList/postList.tsx
@@ -1,15 +1,11 @@
-import React from "react";
+import React ,{useCallback, useState}from "react";
 import style from "./postList.module.css";
 import SelfStatus from "@/components/selfStatus/selfStatus";
 import Corner from "@/components/corner/corner"
 import Navbar from "@/components/navbar/navbar";
-import PostsPanel from "@/components/postsPanel/postsPanel";
 import { getPosts, unknownAPI } from "@/api/post";
-import { Form } from "antd"
 import { useApi } from "@/hooks/request";
 import request from "@/utils/request";
-import { Pagination, PaginationProps } from "antd";
-import { set } from "lodash";
 import { useEffect } from "react";
 import { useNavigate, useSearchParams } from "react-router";
 import { MainPostTag } from "@/types/common";
@@ -20,27 +16,26 @@
     const type = searchParams.get("type") || ""; 
     const nav = useNavigate();
 
-    if(type in ['video', 'music', 'game', 'software']) {
+    if(type in ['video', 'music', 'Game', 'software']) {
         nav('/')
     }
-
-    const {data:postList, refresh:getPostList} = useApi(() => request.get(getPosts + `?tags=${[MainPostTag[type as keyof typeof MainPostTag]]}&page=${currentPage}&pageSize=${pageSize}`), false);
-    const [currentPage, setCurrentPage] = React.useState(1);
-    const [pageSize, setPageSize] = React.useState(10);
-    const handlePageChange = (page:number, size?:number) => {
-        setCurrentPage(page);
-        if(size) setPageSize(size);
-        console.log(page, size);
-    };
+    const {data:postList, refresh:getPostList} = useApi((tags) => request.get(getPosts + `?keyword&tags=${tags.join(',')}&author`), false);
+    const [currentPage, setCurrentPage] = useState(1);
+    const [pageSize, setPageSize] = useState(10);
+    const [tagIds, setTagIds] = useState<Array<number>>([]);
 
     const handlePostClick = (postId:number) => {
         nav(`/postsDetail?postId=${postId}`);
     }
 
     useEffect(() => {
-        getPostList();
+        getPostList([MainPostTag[type as keyof typeof MainPostTag]]);
     },[currentPage, pageSize]);
 
+    useEffect(()=>{
+        console.log(tagIds)
+        getPostList([...tagIds, MainPostTag[type as keyof typeof MainPostTag]])
+    },[tagIds])
     return (
         <div className={style.container}>
             <div className={style.left}>
@@ -53,7 +48,7 @@
                             <div key={post.postId} className={style.contentItem} onClick={() => handlePostClick(post.postId)}>
                                 <h3>{post.postTitle}</h3>
                                 <p>{post.postContent.substring(0, 20)}</p>
-                                <p className={style.createDate}>{post.createdAt}</p>
+                                <p className={style.createDate}>{new Date(post.createdAt).toLocaleString()}</p>
                             </div>
                         ))
                     ) : (
@@ -67,7 +62,7 @@
                     <SelfStatus/>
                 </div>
                 <div className={style.filter}>
-                    <Corner />
+                    <Corner setTagIds={setTagIds}/>
                 </div> 
             </div>
         </div>
diff --git a/src/views/upload/upload.tsx b/src/views/upload/upload.tsx
index 19e1197..7ec8850 100644
--- a/src/views/upload/upload.tsx
+++ b/src/views/upload/upload.tsx
@@ -5,11 +5,13 @@
 import { useLocation, useNavigate } from 'react-router-dom'; // 用于跳转
 import { getTagsByMainTag } from '@/utils/common';
 import { Checkbox, Row, Col } from 'antd'; // 使用 antd 的 Checkbox 组件
-import { MainTag } from '@/types/common';
+import { MainTag, MainPostTag } from '@/types/common';
 import { Select } from 'antd';
 import { UploadOutlined } from '@ant-design/icons';
 import type { UploadProps } from 'antd';
 import { Button, message, Upload as UploadArea } from 'antd';
+import request from '@/utils/request';
+import {useApi} from '@/hooks/request';
 
 
 const CreatePost = () => {
@@ -22,27 +24,41 @@
   const [postType, setPostType] = useState<string>(type || ''); // 初始化 postType
   const navigate = useNavigate();
   const [tags, setTags] = useState<Map<string, number>>(new Map());
+  const [torrentId, setTorrentId] = useState<number>(0); // 用于存储上传的种子 ID
+  const [messageApi, contextHolder] = message.useMessage();
+
+  const {refresh} = useApi((payload)=> request.post('/post', payload), false)
 
   const props: UploadProps = {
     name: 'file',
-    action: process.env.REACT_APP_BASE_URL + postTorrentUpload, // 替换为实际的上传接口地址
+    action: process.env.API_BASE_URL + postTorrentUpload, // 替换为实际的上传接口地址
     headers: {
-      authorization: 'authorization-text',
+      authorization: `Bearer ${localStorage.getItem('token')}`, // 使用本地存储的 token
     },
     onChange(info) {
-      if (info.file.status !== 'uploading') {
-        console.log(info.file, info.fileList);
-      }
+
       if (info.file.status === 'done') {
-        message.success(`${info.file.name} file uploaded successfully`);
+        const response = info.file.response;
+        if(response && response.code !== 200) {
+           messageApi.error(response.message || '上传失败');
+          return;
+        }
+        else {
+          console.log('上传成功:', response);
+          messageApi.success('上传成功')
+          console.log(response.data.torrentId);
+          setTorrentId(response.data.torrentId); // 假设返回的数据中有 torrentId
+        }
       } else if (info.file.status === 'error') {
-        message.error(`${info.file.name} file upload failed.`);
+        messageApi.error(`${info.file.name} 文件上传失败`);
       }
     },
+    
   };
 
 
   const handleSubmit = async () => {
+    console.log(torrentId)
     if (!postTitle.trim() || !postType || !postContent.trim()) {
       alert('请填写完整内容(资源名、类型、内容介绍)');
       return;
@@ -55,33 +71,23 @@
 
     const payload = {
       post: {
-        postId: 0,
-        userId: 0,
         postTitle,
         postContent,
-        createdAt: Date.now(),
-        postType,
-        viewCount: 0,
-        hotScore: 5,
-        lastCalculated: Date.now()
+        torrentId,
+        postType:'resource'
       },
-      tagIds: [0]
+      tagIds: new Array(...tagIds, MainPostTag[postType as keyof typeof MainPostTag]), // 确保 tagIds 是一个数组
     };
-
-    try {
-      const res = await instance.post(Upload, payload);
-
-      console.log('后端返回内容:', res.code);
-
-      // 判断返回内容是否成功(根据你 mock 接口返回的 code 字段)
-      if (res.code !== 0) throw new Error('发布失败');
-
-      alert('发布成功!');
-      navigate(-1); // 返回上一页(homepage)
-    } catch (error) {
-      alert('发布失败,请稍后重试');
-      console.error(error);
+    try{
+      const res = await refresh(payload)
+      messageApi.success('发布成功', 3).then(()=>{
+        navigate('/')
+      });
+      ; // 发布成功后跳转到首页
+    } catch (err){
+       messageApi.error((err as Error).message || '发布失败,请稍后再试');
     }
+    
   };
 
   useEffect(() => {
@@ -97,6 +103,7 @@
 
   return (
     <div className={styles.container}>
+      {contextHolder}
       <div className={styles.formGroup}>
         <label>资源名:</label>
         <input