Browse Source

Merge branch 'web3_transection'

# Conflicts:
#	src/router/index.js
Hexinkui 1 tháng trước cách đây
mục cha
commit
831bdf511a
60 tập tin đã thay đổi với 4545 bổ sung276 xóa
  1. 1 0
      .gitignore
  2. 28 1
      README.md
  3. 13 0
      babel.config.js
  4. 218 4
      package-lock.json
  5. 4 1
      package.json
  6. 1 1
      public/index.html
  7. 8 16
      src/App.vue
  8. 32 0
      src/assets/icon/bitcoin/baiyihuiyuan.svg
  9. 134 0
      src/assets/icon/bitcoin/erweima.svg
  10. 6 0
      src/assets/icon/bitcoin/yaoqing.svg
  11. 15 0
      src/assets/icon/user/yaoqi.svg
  12. 72 0
      src/locales/index.js
  13. 30 0
      src/locales/lang/de-DE.js
  14. 32 0
      src/locales/lang/en-US.js
  15. 30 0
      src/locales/lang/es-ES.js
  16. 30 0
      src/locales/lang/fr-FR.js
  17. 30 0
      src/locales/lang/id-ID.js
  18. 30 0
      src/locales/lang/pt-PT.js
  19. 30 0
      src/locales/lang/ru-RU.js
  20. 33 0
      src/locales/lang/zh-CN.js
  21. 27 7
      src/main.js
  22. 136 64
      src/router/index.js
  23. 5 2
      src/views/bitcoin/Calculator.vue
  24. 2 2
      src/views/bitcoin/CommonFunctionsPopup/CommonFunctionsPopup.vue
  25. 5 8
      src/views/bitcoin/TradeFutures.vue
  26. 18 6
      src/views/bitcoin/TradeLayout.vue
  27. 1 1
      src/views/bitcoin/calculator/FundingRateReminder.vue
  28. 2 2
      src/views/bitcoin/components/ChooseThisDepth.vue
  29. 2 2
      src/views/bitcoin/components/OrderConfirmPopup.vue
  30. 3 2
      src/views/bitcoin/components/TPSLSmartPopup.vue
  31. 12 4
      src/views/bitcoin/components/sellOrder.vue
  32. 6 3
      src/views/bitcoin/lever/PnLAnalysis.vue
  33. 117 117
      src/views/bitcoin/lever/TradeMargin.vue
  34. 1 1
      src/views/bitcoin/lever/TradeOptions.vue
  35. 16 7
      src/views/bitcoin/lever/TradeSeconds.vue
  36. 138 0
      src/views/bitcoin/lever/components/ExplanationModal.vue
  37. 2 2
      src/views/bitcoin/lever/components/MarketPriceAndPlan.vue
  38. 1 1
      src/views/bitcoin/lever/components/sellOrder1.vue
  39. 2 1
      src/views/market/Index.vue
  40. 122 0
      src/views/user/AboutUs.vue
  41. 115 0
      src/views/user/AddressAuth.vue
  42. 397 0
      src/views/user/AdvancedCertification.vue
  43. 260 0
      src/views/user/BasicVerify.vue
  44. 164 0
      src/views/user/HelpCenter.vue
  45. 132 0
      src/views/user/HelpDetail.vue
  46. 276 21
      src/views/user/Index.vue
  47. 173 0
      src/views/user/InviteCenter.vue
  48. 147 0
      src/views/user/InvitePoster.vue
  49. 161 0
      src/views/user/KycForm.vue
  50. 299 0
      src/views/user/KycUpload.vue
  51. 99 0
      src/views/user/LanguageSwitch.vue
  52. 115 0
      src/views/user/Logout.vue
  53. 63 0
      src/views/user/PrivacyPolicy.vue
  54. 113 0
      src/views/user/RelativeAuth.vue
  55. 279 0
      src/views/user/SecuritySettings.vue
  56. 39 0
      src/views/user/UserAgreement.vue
  57. 164 0
      src/views/user/VipCenter.vue
  58. 103 0
      src/views/user/VipRules.vue
  59. 44 0
      update.js
  60. 7 0
      vue.config.js

+ 1 - 0
.gitignore

@@ -1,6 +1,7 @@
 .DS_Store
 node_modules
 /dist
+update.js
 
 
 # local env files

+ 28 - 1
README.md

@@ -1,2 +1,29 @@
-# bit_wise_world
+
+
+### 核心依赖 (Dependencies)
+
+| Package | Version |
+| :--- | :--- |
+| [axios](https://www.npmjs.com/package/axios) | `^1.13.2` |
+| [klinecharts](https://www.npmjs.com/package/klinecharts) | `^8.6.3` |
+| [vant](https://www.npmjs.com/package/vant) | `^4.9.21` |
+| [vue](https://www.npmjs.com/package/vue) | `^3.2.13` |
+| [vue-i18n](https://www.npmjs.com/package/vue-i18n) | `^11.2.2` |
+| [vue-router](https://www.npmjs.com/package/vue-router) | `^4.0.3` |
+| [vuex](https://www.npmjs.com/package/vuex) | `^4.0.0` |
+
+### 开发依赖 (DevDependencies)
+
+| Package | Version |
+| :--- | :--- |
+| [@vue/cli-plugin-router](https://www.npmjs.com/package/@vue/cli-plugin-router) | `~5.0.0` |
+| [@vue/cli-plugin-vuex](https://www.npmjs.com/package/@vue/cli-plugin-vuex) | `~5.0.0` |
+| [@vue/cli-service](https://www.npmjs.com/package/@vue/cli-service) | `~5.0.0` |
+| [babel-plugin-import](https://www.npmjs.com/package/babel-plugin-import) | `^1.13.8` |
+| [less](https://www.npmjs.com/package/less) | `^4.0.0` |
+| [less-loader](https://www.npmjs.com/package/less-loader) | `^8.0.0` |
+
+
+
+
 

+ 13 - 0
babel.config.js

@@ -0,0 +1,13 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset'
+  ],
+  // --- 新增下面这段 plugins 配置 ---
+  plugins: [
+    ['import', {
+      libraryName: 'vant',
+      libraryDirectory: 'es',
+      style: true
+    }, 'vant']
+  ]
+}

+ 218 - 4
package-lock.json

@@ -9,9 +9,11 @@
       "version": "0.1.0",
       "dependencies": {
         "axios": "^1.13.2",
-        "klinecharts": "^10.0.0-beta1",
+        "html2canvas": "^1.4.1",
+        "klinecharts": "^8.6.3",
         "vant": "^4.9.21",
         "vue": "^3.2.13",
+        "vue-i18n": "^11.2.2",
         "vue-router": "^4.0.3",
         "vuex": "^4.0.0"
       },
@@ -19,6 +21,7 @@
         "@vue/cli-plugin-router": "~5.0.0",
         "@vue/cli-plugin-vuex": "~5.0.0",
         "@vue/cli-service": "~5.0.0",
+        "babel-plugin-import": "^1.13.8",
         "less": "^4.0.0",
         "less-loader": "^8.0.0"
       }
@@ -60,6 +63,23 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/generator": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz",
+      "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.28.5",
+        "@babel/types": "^7.28.5",
+        "@jridgewell/gen-mapping": "^0.3.12",
+        "@jridgewell/trace-mapping": "^0.3.28",
+        "jsesc": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/@babel/helper-compilation-targets": {
       "version": "7.27.2",
       "resolved": "https://registry.npmmirror.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
@@ -76,6 +96,30 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/helper-globals": {
+      "version": "7.28.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
+      "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
+      "dev": true,
+      "license": "MIT",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-module-imports": {
+      "version": "7.27.1",
+      "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
+      "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/traverse": "^7.27.1",
+        "@babel/types": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/@babel/helper-string-parser": {
       "version": "7.27.1",
       "resolved": "https://registry.npmmirror.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
@@ -115,6 +159,40 @@
         "node": ">=6.0.0"
       }
     },
+    "node_modules/@babel/template": {
+      "version": "7.27.2",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
+      "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.27.1",
+        "@babel/parser": "^7.27.2",
+        "@babel/types": "^7.27.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse": {
+      "version": "7.28.5",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz",
+      "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/code-frame": "^7.27.1",
+        "@babel/generator": "^7.28.5",
+        "@babel/helper-globals": "^7.28.0",
+        "@babel/parser": "^7.28.5",
+        "@babel/template": "^7.27.2",
+        "@babel/types": "^7.28.5",
+        "debug": "^4.3.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/@babel/types": {
       "version": "7.28.5",
       "resolved": "https://registry.npmmirror.com/@babel/types/-/types-7.28.5.tgz",
@@ -151,6 +229,50 @@
         "@hapi/hoek": "^9.0.0"
       }
     },
+    "node_modules/@intlify/core-base": {
+      "version": "11.2.2",
+      "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.2.2.tgz",
+      "integrity": "sha512-0mCTBOLKIqFUP3BzwuFW23hYEl9g/wby6uY//AC5hTgQfTsM2srCYF2/hYGp+a5DZ/HIFIgKkLJMzXTt30r0JQ==",
+      "license": "MIT",
+      "dependencies": {
+        "@intlify/message-compiler": "11.2.2",
+        "@intlify/shared": "11.2.2"
+      },
+      "engines": {
+        "node": ">= 16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/kazupon"
+      }
+    },
+    "node_modules/@intlify/message-compiler": {
+      "version": "11.2.2",
+      "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-11.2.2.tgz",
+      "integrity": "sha512-XS2p8Ff5JxWsKhgfld4/MRQzZRQ85drMMPhb7Co6Be4ZOgqJX1DzcZt0IFgGTycgqL8rkYNwgnD443Q+TapOoA==",
+      "license": "MIT",
+      "dependencies": {
+        "@intlify/shared": "11.2.2",
+        "source-map-js": "^1.0.2"
+      },
+      "engines": {
+        "node": ">= 16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/kazupon"
+      }
+    },
+    "node_modules/@intlify/shared": {
+      "version": "11.2.2",
+      "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-11.2.2.tgz",
+      "integrity": "sha512-OtCmyFpSXxNu/oET/aN6HtPCbZ01btXVd0f3w00YsHOb13Kverk1jzA2k47pAekM55qbUw421fvPF1yxZ+gicw==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/kazupon"
+      }
+    },
     "node_modules/@jridgewell/gen-mapping": {
       "version": "0.3.13",
       "resolved": "https://registry.npmmirror.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
@@ -1428,12 +1550,31 @@
         "proxy-from-env": "^1.1.0"
       }
     },
+    "node_modules/babel-plugin-import": {
+      "version": "1.13.8",
+      "resolved": "https://registry.npmjs.org/babel-plugin-import/-/babel-plugin-import-1.13.8.tgz",
+      "integrity": "sha512-36babpjra5m3gca44V6tSTomeBlPA7cHUynrE2WiQIm3rEGD9xy28MKsx5IdO45EbnpJY7Jrgd00C6Dwt/l/2Q==",
+      "dev": true,
+      "license": "MIT",
+      "dependencies": {
+        "@babel/helper-module-imports": "^7.0.0"
+      }
+    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
       "dev": true
     },
+    "node_modules/base64-arraybuffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
+      "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
+      "license": "MIT",
+      "engines": {
+        "node": ">= 0.6.0"
+      }
+    },
     "node_modules/base64-js": {
       "version": "1.5.1",
       "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz",
@@ -2178,6 +2319,15 @@
         "postcss": "^8.0.9"
       }
     },
+    "node_modules/css-line-break": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
+      "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
+      "license": "MIT",
+      "dependencies": {
+        "utrie": "^1.0.2"
+      }
+    },
     "node_modules/css-loader": {
       "version": "6.11.0",
       "resolved": "https://registry.npmmirror.com/css-loader/-/css-loader-6.11.0.tgz",
@@ -3767,6 +3917,19 @@
         }
       }
     },
+    "node_modules/html2canvas": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
+      "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
+      "license": "MIT",
+      "dependencies": {
+        "css-line-break": "^2.1.0",
+        "text-segmentation": "^1.0.3"
+      },
+      "engines": {
+        "node": ">=8.0.0"
+      }
+    },
     "node_modules/htmlparser2": {
       "version": "6.1.0",
       "resolved": "https://registry.npmmirror.com/htmlparser2/-/htmlparser2-6.1.0.tgz",
@@ -4221,6 +4384,19 @@
       "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
       "dev": true
     },
+    "node_modules/jsesc": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+      "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+      "dev": true,
+      "license": "MIT",
+      "bin": {
+        "jsesc": "bin/jsesc"
+      },
+      "engines": {
+        "node": ">=6"
+      }
+    },
     "node_modules/json-parse-better-errors": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
@@ -4273,9 +4449,9 @@
       }
     },
     "node_modules/klinecharts": {
-      "version": "10.0.0-beta1",
-      "resolved": "https://registry.npmjs.org/klinecharts/-/klinecharts-10.0.0-beta1.tgz",
-      "integrity": "sha512-5ZxFGjJeZqt9+q45lZDhApC3kdgrk51i27uSpIELgXJLNgfSc0anlb8XkU+52LVrBYnTv9dFr8/Q7lG81vIV1w==",
+      "version": "8.6.3",
+      "resolved": "https://registry.npmjs.org/klinecharts/-/klinecharts-8.6.3.tgz",
+      "integrity": "sha512-hGDtWiMNywEDneZFmt+vZ6tOYutCDWV5FPBcXcn7L8kGwe73Q5yJayk8UzP9pIQSBWyxswWIySKh/BVFA6GhuQ==",
       "license": "Apache-2.0"
     },
     "node_modules/klona": {
@@ -7271,6 +7447,15 @@
       "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
       "dev": true
     },
+    "node_modules/text-segmentation": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
+      "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
+      "license": "MIT",
+      "dependencies": {
+        "utrie": "^1.0.2"
+      }
+    },
     "node_modules/thenify": {
       "version": "3.3.1",
       "resolved": "https://registry.npmmirror.com/thenify/-/thenify-3.3.1.tgz",
@@ -7495,6 +7680,15 @@
         "node": ">= 0.4.0"
       }
     },
+    "node_modules/utrie": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
+      "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
+      "license": "MIT",
+      "dependencies": {
+        "base64-arraybuffer": "^1.0.2"
+      }
+    },
     "node_modules/uuid": {
       "version": "8.3.2",
       "resolved": "https://registry.npmmirror.com/uuid/-/uuid-8.3.2.tgz",
@@ -7563,6 +7757,26 @@
       "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
       "dev": true
     },
+    "node_modules/vue-i18n": {
+      "version": "11.2.2",
+      "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.2.2.tgz",
+      "integrity": "sha512-ULIKZyRluUPRCZmihVgUvpq8hJTtOqnbGZuv4Lz+byEKZq4mU0g92og414l6f/4ju+L5mORsiUuEPYrAuX2NJg==",
+      "license": "MIT",
+      "dependencies": {
+        "@intlify/core-base": "11.2.2",
+        "@intlify/shared": "11.2.2",
+        "@vue/devtools-api": "^6.5.0"
+      },
+      "engines": {
+        "node": ">= 16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/kazupon"
+      },
+      "peerDependencies": {
+        "vue": "^3.0.0"
+      }
+    },
     "node_modules/vue-loader": {
       "version": "17.4.2",
       "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-17.4.2.tgz",

+ 4 - 1
package.json

@@ -8,9 +8,11 @@
   },
   "dependencies": {
     "axios": "^1.13.2",
-    "klinecharts": "^10.0.0-beta1",
+    "html2canvas": "^1.4.1",
+    "klinecharts": "^8.6.3",
     "vant": "^4.9.21",
     "vue": "^3.2.13",
+    "vue-i18n": "^11.2.2",
     "vue-router": "^4.0.3",
     "vuex": "^4.0.0"
   },
@@ -18,6 +20,7 @@
     "@vue/cli-plugin-router": "~5.0.0",
     "@vue/cli-plugin-vuex": "~5.0.0",
     "@vue/cli-service": "~5.0.0",
+    "babel-plugin-import": "^1.13.8",
     "less": "^4.0.0",
     "less-loader": "^8.0.0"
   },

+ 1 - 1
public/index.html

@@ -1,5 +1,5 @@
 <!DOCTYPE html>
-<html lang="">
+<html lang="en">
   <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">

+ 8 - 16
src/App.vue

@@ -1,20 +1,12 @@
 <template>
-  <div class="content">
-    <router-view />
-  </div>
-
+  <router-view/>
 </template>
 
-<style lang="less" scoped>
-.content{
-  padding-bottom: 60px;
-}
-</style>
-<script setup >
-import {onMounted} from "vue";
+<script setup>
+/*import { useI18n } from 'vue-i18n';
+const { locale } = useI18n();*/
+// 必要时加上去
+</script>
 
-onMounted(() => {
-  // 强制滚动到顶部
-  window.scrollTo(0, 0);
-});
-</script>
+<style>
+</style>

+ 32 - 0
src/assets/icon/bitcoin/baiyihuiyuan.svg

@@ -0,0 +1,32 @@
+<svg width="80" height="80" viewBox="0 0 80 80" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M18.0723 56.5352L31.9287 64.5352L23.9287 78.3916L20.3338 68.6181L10.0723 70.3916L18.0723 56.5352Z" fill="url(#paint0_linear_339_26285)"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M48.0723 64.5352L61.9287 56.5352L69.9287 70.3916L59.6671 68.6181L56.0723 78.3916L48.0723 64.5352Z" fill="url(#paint1_linear_339_26285)"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2.85269 34.7122C2.40856 32.2578 4.29452 30 6.78877 30H73.2112C75.7055 30 77.5914 32.2578 77.1473 34.7122L74.847 47.4245C74.1581 51.2315 70.8437 54 66.9748 54H13.0252C9.15634 54 5.84189 51.2315 5.153 47.4245L2.85269 34.7122Z" fill="url(#paint2_linear_339_26285)"/>
+<mask id="mask0_339_26285" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="2" y="30" width="76" height="24">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M2.85269 34.7122C2.40856 32.2578 4.29452 30 6.78877 30H73.2112C75.7055 30 77.5914 32.2578 77.1473 34.7122L74.847 47.4245C74.1581 51.2315 70.8437 54 66.9748 54H13.0252C9.15634 54 5.84189 51.2315 5.153 47.4245L2.85269 34.7122Z" fill="white"/>
+</mask>
+<g mask="url(#mask0_339_26285)">
+<rect x="-12" y="48" width="105" height="6" fill="black" fill-opacity="0.0973387"/>
+<rect x="-12" y="29" width="105" height="6" fill="white" fill-opacity="0.237774"/>
+</g>
+<path d="M35.5 8.0625C38.1976 6.50503 41.5018 6.45584 44.2373 7.91602L44.5 8.0625L61.9453 18.1338C64.7296 19.7414 66.4451 22.7126 66.4453 25.9277V46.0723C66.4451 49.2874 64.7296 52.2586 61.9453 53.8662L44.5 63.9375C41.7154 65.5452 38.2846 65.5452 35.5 63.9375L18.0547 53.8662C15.2704 52.2586 13.5549 49.2874 13.5547 46.0723V25.9277C13.5549 22.7126 15.2704 19.7414 18.0547 18.1338L35.5 8.0625Z" fill="url(#paint3_linear_339_26285)" stroke="#D0D7E6" stroke-width="6"/>
+<path d="M39.8806 22.248C42.238 22.248 44.176 22.928 45.6946 24.288C47.1906 25.648 47.9386 27.4047 47.9386 29.558C47.9386 31.6207 47.1453 33.536 45.5586 35.304C44.6746 36.256 42.9973 37.5593 40.5266 39.214C38.056 40.846 36.5486 42.274 36.0046 43.498H47.9726V47H31.0406C31.0406 44.5067 31.8453 42.3533 33.4546 40.54C34.3386 39.52 36.1973 38.0353 39.0306 36.086C40.504 35.066 41.6146 34.1593 42.3626 33.366C43.428 32.1647 43.9606 30.884 43.9606 29.524C43.9606 28.2093 43.6093 27.2233 42.9066 26.566C42.204 25.9313 41.15 25.614 39.7446 25.614C38.2486 25.614 37.1266 26.124 36.3786 27.144C35.6306 28.096 35.2226 29.5353 35.1546 31.462H31.1766C31.222 28.742 32.0153 26.5547 33.5566 24.9C35.166 23.132 37.274 22.248 39.8806 22.248Z" fill="#F8FAFC"/>
+<defs>
+<linearGradient id="paint0_linear_339_26285" x1="20.1544" y1="57.7373" x2="14.5587" y2="67.4294" gradientUnits="userSpaceOnUse">
+<stop stop-color="#81888F"/>
+<stop offset="1" stop-color="#B6BDC4"/>
+</linearGradient>
+<linearGradient id="paint1_linear_339_26285" x1="49.4676" y1="63.7295" x2="55.8564" y2="74.7952" gradientUnits="userSpaceOnUse">
+<stop stop-color="#81888F"/>
+<stop offset="1" stop-color="#B6BDC4"/>
+</linearGradient>
+<linearGradient id="paint2_linear_339_26285" x1="2" y1="62.9985" x2="134.99" y2="62.9985" gradientUnits="userSpaceOnUse">
+<stop stop-color="#81888F"/>
+<stop offset="1" stop-color="#B6BDC4"/>
+</linearGradient>
+<linearGradient id="paint3_linear_339_26285" x1="2.93632" y1="35.3353" x2="49.1223" y2="85.0907" gradientUnits="userSpaceOnUse">
+<stop stop-color="#81888F"/>
+<stop offset="1" stop-color="#B6BDC4"/>
+</linearGradient>
+</defs>
+</svg>

+ 134 - 0
src/assets/icon/bitcoin/erweima.svg

@@ -0,0 +1,134 @@
+<svg width="69" height="69" viewBox="0 0 69 69" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M14.6161 0H0V14.6161H14.6161V0Z" fill="#1F2937"/>
+<path d="M14.6161 0H16.7229V2.10682H18.8297V4.21364H16.7229V6.32046H18.8297V8.42728H16.7229V10.4024H18.8297V12.5092H16.7229V16.7229H23.0433V20.9365H20.9365V18.8297H18.8297V20.9365H12.5092V18.8297H14.6161V16.7229H10.4024V18.8297H8.42728V20.9365H10.4024V23.0433H6.32046V18.8297H4.21364V23.0433H0V20.9365H2.10682V18.8297H0V14.6161H14.6161V0Z" fill="white"/>
+<path d="M16.7217 0H23.0421V2.10682H20.9353V4.21364H23.0421V2.10682H25.149V0H27.1241V2.10682H29.2309V0H35.5514V2.10682H31.3377V4.21364H33.4446V8.42728H25.149V6.32046H29.2309V4.21364H25.149V6.32046H23.0421V8.42728H18.8285V6.32046H16.7217V4.21364H18.8285V2.10682H16.7217V0Z" fill="#1F2937"/>
+<path d="M25.1498 0H23.043V2.10682H25.1498V0Z" fill="white"/>
+<path d="M29.2338 0H27.127V2.10682H29.2338V0Z" fill="white"/>
+<path d="M35.5538 0H37.6606V4.21364H39.7674V6.32046H35.5538V10.4024H31.3401V12.5092H29.2333V10.4024H25.1514V8.42728H33.447V4.21364H31.3401V2.10682H35.5538V0Z" fill="white"/>
+<path d="M37.6623 0H45.9579V2.10682H43.9827V4.21364H41.8759V6.32046H43.9827V4.21364H45.9579V8.42728H43.9827V10.4024H45.9579V8.42728H48.0647V14.6161H45.9579V12.5092H43.9827V14.6161H41.8759V8.42728H39.7691V14.6161H41.8759V16.7229H37.6623V12.5092H35.5554V14.6161H33.4486V12.5092H31.3418V10.4024H35.5554V6.32046H39.7691V4.21364H37.6623V0Z" fill="#1F2937"/>
+<path d="M45.955 0H54.3823V14.6161H68.9984V16.7229H66.8915V18.8297H68.9984V23.0433H66.8915V20.9365H64.7847V16.7229H62.8096V20.9365H64.7847V23.0433H60.7028V16.7229H58.5959V18.8297H56.4891V16.7229H54.3823V18.8297H56.4891V23.0433H60.7028V25.1502H54.3823V29.2321H52.2755V25.1502H48.0618V29.2321H52.2755V31.3389H54.3823V33.4458H56.4891V35.5526H54.3823V37.6594H52.2755V41.873H50.1687V43.9799H52.2755V45.955H48.0618V39.7662H50.1687V35.5526H48.0618V39.7662H45.955V43.9799H43.9799V41.873H39.7662V43.9799H37.6594V39.7662H39.7662V37.6594H43.9799V35.5526H39.7662V37.6594H37.6594V39.7662H33.4458V37.6594H35.5526V35.5526H37.6594V33.4458H35.5526V35.5526H33.4458V33.4458H31.3389V31.3389H29.2321V29.2321H20.9365V33.4458H18.8297V35.5526H14.6161V33.4458H12.5092V35.5526H14.6161V37.6594H10.4024V39.7662H14.6161V41.873H6.32046V43.9799H4.21364V45.955H6.32046V43.9799H8.42728V45.955H10.4024V48.0618H14.6161V50.1686H8.42728V48.0618H4.21364V50.1686H2.10682V41.873H4.21364V39.7662H8.42728V37.6594H4.21364V35.5526H2.10682V37.6594H0V31.3389H4.21364V33.4458H8.42728V35.5526H10.4024V31.3389H8.42728V29.2321H2.10682V27.1253H4.21364V25.1502H8.42728V27.1253H10.4024V29.2321H12.5092V31.3389H18.8297V29.2321H16.7229V27.1253H18.8297V25.1502H12.5092V23.0433H18.8297V20.9365H20.9365V23.0433H23.0433V27.1253H25.1502V25.1502H29.2321V23.0433H27.1253V18.8297H31.3389V23.0433H35.5526V25.1502H31.3389V27.1253H33.4458V31.3389H39.7662V29.2321H41.873V33.4458H43.9799V29.2321H41.873V27.1253H39.7662V25.1502H43.9799V27.1253H45.955V23.0433H48.0618V20.9365H50.1687V18.8297H52.2755V12.5092H50.1687V18.8297H48.0618V16.7229H45.955V18.8297H43.9799V16.7229H41.873V14.6161H43.9799V12.5092H45.955V14.6161H48.0618V8.42728H45.955V4.21364H43.9799V2.10682H45.955V0Z" fill="white"/>
+<path d="M68.9979 0H54.3818V14.6161H68.9979V0Z" fill="#1F2937"/>
+<path d="M12.5098 2.10742H2.10742V12.5098H12.5098V2.10742Z" fill="white"/>
+<path d="M23.0404 2.10742H20.9336V4.21424H23.0404V2.10742Z" fill="white"/>
+<path d="M50.1683 2.10742H52.2752V6.32106H48.0615V4.21424H50.1683V2.10742Z" fill="#1F2937"/>
+<path d="M66.8878 2.10742H56.4854V12.5098H66.8878V2.10742Z" fill="white"/>
+<path d="M10.5343 4.21289H4.21387V10.5334H10.5343V4.21289Z" fill="#1F2937"/>
+<path d="M29.365 4.21289H25.1514V6.31971H29.365V4.21289Z" fill="white"/>
+<path d="M43.9799 4.21289H41.873V6.31971H43.9799V4.21289Z" fill="white"/>
+<path d="M64.9171 4.21289H58.5967V10.5334H64.9171V4.21289Z" fill="#1F2937"/>
+<path d="M25.1498 6.32031H23.043V8.42713H25.1498V6.32031Z" fill="white"/>
+<path d="M18.8285 8.42773H16.7217V10.5346H18.8285V8.42773Z" fill="#1F2937"/>
+<path d="M23.0427 8.42773H18.8291V10.5346H23.0427V8.42773Z" fill="white"/>
+<path d="M23.0421 8.42773H25.149V10.4029H29.2309V12.5097H27.1241V14.6165H25.149V12.5097H23.0421V14.6165H25.149V16.7233H29.2309V12.5097H31.3377V18.8302H27.1241V23.0438H29.2309V25.1506H25.149V27.1258H23.0421V23.0438H20.9353V20.937H23.0421V16.7233H16.7217V12.5097H18.8285V14.6165H20.9353V12.5097H18.8285V10.4029H23.0421V8.42773Z" fill="#1F2937"/>
+<path d="M41.8724 8.42773H39.7656V14.7482H41.8724V8.42773Z" fill="white"/>
+<path d="M46.0834 8.42773H43.9766V10.5346H46.0834V8.42773Z" fill="white"/>
+<path d="M52.2777 8.42773H50.1709V10.5346H52.2777V8.42773Z" fill="#1F2937"/>
+<path d="M20.9359 12.5078H18.8291V14.6146H20.9359V12.5078Z" fill="white"/>
+<path d="M25.1498 12.5078H23.043V14.6146H25.1498V12.5078Z" fill="white"/>
+<path d="M27.1265 12.5078H29.2333V16.7215H25.1514V14.6146H27.1265V12.5078Z" fill="white"/>
+<path d="M31.3418 12.5078H33.4486V14.6146H35.5554V12.5078H37.6623V16.7215H35.5554V20.9351H33.4486V18.8283H31.3418V12.5078Z" fill="white"/>
+<path d="M52.2777 12.5078H50.1709V18.8283H52.2777V12.5078Z" fill="#1F2937"/>
+<path d="M10.4024 16.7227H14.6161V18.8295H12.5092V20.9363H18.8297V23.0431H12.5092V25.1499H18.8297V27.1251H16.7229V29.2319H18.8297V31.3387H12.5092V29.2319H14.6161V27.1251H12.5092V29.2319H10.4024V27.1251H8.42728V25.1499H4.21364V27.1251H2.10682V29.2319H8.42728V31.3387H10.4024V35.5524H8.42728V33.4455H4.21364V31.3387H0V23.0431H4.21364V18.8295H6.32046V23.0431H10.4024V20.9363H8.42728V18.8295H10.4024V16.7227Z" fill="#1F2937"/>
+<path d="M35.5527 16.7227H37.6596V18.8295H39.7664V20.9363H41.8732V23.0431H45.9552V27.1251H43.98V25.1499H39.7664V27.1251H37.6596V25.1499H35.5527V23.0431H37.6596V20.9363H35.5527V16.7227Z" fill="#1F2937"/>
+<path d="M37.6631 16.7227H41.8767V20.9363H39.7699V18.8295H37.6631V16.7227Z" fill="white"/>
+<path d="M41.873 16.7227H43.9799V18.8295H45.955V16.7227H48.0618V18.8295H50.1686V20.9363H48.0618V23.0431H45.955V20.9363H41.873V16.7227Z" fill="#1F2937"/>
+<path d="M56.4887 16.7227H54.3818V18.8295H56.4887V16.7227Z" fill="#1F2937"/>
+<path d="M58.5922 16.7227H60.699V23.0431H56.4854V18.8295H58.5922V16.7227Z" fill="#1F2937"/>
+<path d="M64.9174 16.7227H62.8105V20.9363H64.9174V16.7227Z" fill="#1F2937"/>
+<path d="M69.0004 16.7227H66.8936V18.8295H69.0004V16.7227Z" fill="#1F2937"/>
+<path d="M2.10682 18.832H0V20.9389H2.10682V18.832Z" fill="#1F2937"/>
+<path d="M20.9359 18.832H18.8291V20.9389H20.9359V18.832Z" fill="#1F2937"/>
+<path d="M31.3418 18.832H33.4486V20.9389H35.5554V23.0457H31.3418V18.832Z" fill="#1F2937"/>
+<path d="M37.6596 20.9375H35.5527V23.0443H37.6596V20.9375Z" fill="white"/>
+<path d="M46.0867 20.9375H41.873V23.0443H46.0867V20.9375Z" fill="white"/>
+<path d="M54.3812 20.9375H52.2744V23.0443H54.3812V20.9375Z" fill="#1F2937"/>
+<path d="M64.7837 20.9375H66.8905V23.0443H68.9973V25.1511H62.8085V27.1263H66.8905V31.3399H64.7837V33.4467H62.8085V31.3399H58.5949V33.4467H60.7017V35.5536H56.4881V33.4467H54.3812V31.3399H52.2744V29.2331H54.3812V25.1511H60.7017V23.0443H64.7837V20.9375Z" fill="#1F2937"/>
+<path d="M31.3418 25.1484H35.5554V27.1236H37.6623V29.2304H39.7691V31.3372H33.4486V27.1236H31.3418V25.1484Z" fill="#1F2937"/>
+<path d="M37.6596 25.1484H35.5527V27.2553H37.6596V25.1484Z" fill="white"/>
+<path d="M52.2752 25.1484H48.0615V29.3621H52.2752V25.1484Z" fill="#1F2937"/>
+<path d="M62.8105 25.1484H68.9993V31.3372H66.8925V27.1236H62.8105V25.1484Z" fill="white"/>
+<path d="M14.6156 27.127H12.5088V29.2338H14.6156V27.127Z" fill="white"/>
+<path d="M39.7699 27.127H37.6631V29.2338H39.7699V27.127Z" fill="white"/>
+<path d="M41.8724 27.127H39.7656V29.2338H41.8724V27.127Z" fill="#1F2937"/>
+<path d="M20.9359 29.2305H29.2315V31.3373H31.3383V33.4441H25.1496V35.5509H23.0427V37.6577H25.1496V39.7646H18.8291V37.6577H20.9359V35.5509H18.8291V33.4441H20.9359V29.2305Z" fill="#1F2937"/>
+<path d="M43.9799 29.2305H41.873V33.4441H43.9799V29.2305Z" fill="#1F2937"/>
+<path d="M58.5967 31.3398H62.8103V33.4467H64.7855V35.5535H60.7035V33.4467H58.5967V31.3398Z" fill="white"/>
+<path d="M66.89 31.3398H64.7832V33.4467H66.89V31.3398Z" fill="white"/>
+<path d="M66.89 31.3398H68.9968V39.7671H66.89V35.5535H64.7832V33.4467H66.89V31.3398Z" fill="#1F2937"/>
+<path d="M14.6156 33.4473H12.5088V35.5541H14.6156V33.4473Z" fill="#1F2937"/>
+<path d="M25.1502 33.4473H31.3389V37.6609H29.2321V35.5541H27.1253V41.8745H31.3389V39.7677H33.4458V43.9814H25.1502V41.8745H23.0433V43.9814H20.9365V48.0633H18.8297V52.277H16.7229V54.3838H20.9365V52.277H23.0433V50.1701H25.1502V45.9565H27.1253V48.0633H29.2321V45.9565H33.4458V48.0633H31.3389V50.1701H29.2321V52.277H27.1253V56.4906H25.1502V54.3838H23.0433V58.5974H20.9365V60.7042H18.8297V62.8111H20.9365V64.7862H23.0433V66.893H18.8297V68.9999H14.6161V54.3838H0V52.277H4.21364V50.1701H6.32046V52.277H14.6161V50.1701H16.7229V48.0633H14.6161V45.9565H10.4024V43.9814H16.7229V41.8745H18.8297V39.7677H25.1502V37.6609H23.0433V35.5541H25.1502V33.4473Z" fill="white"/>
+<path d="M31.3406 33.4473H33.4474V35.5541H35.5542V37.6609H33.4474V39.7677H31.3406V41.8745H27.127V35.5541H29.2338V37.6609H31.3406V33.4473Z" fill="#1F2937"/>
+<path d="M37.6596 33.4473H35.5527V35.5541H37.6596V33.4473Z" fill="#1F2937"/>
+<path d="M4.21424 35.5527H2.10742V37.6596H4.21424V35.5527Z" fill="#1F2937"/>
+<path d="M18.8328 35.5527H14.6191V37.6596H18.8328V35.5527Z" fill="#1F2937"/>
+<path d="M20.9359 35.5527H18.8291V37.6596H20.9359V35.5527Z" fill="white"/>
+<path d="M43.9793 35.5527H39.7656V37.6596H43.9793V35.5527Z" fill="#1F2937"/>
+<path d="M50.1683 35.5527H48.0615V39.7664H50.1683V35.5527Z" fill="#1F2937"/>
+<path d="M54.3812 35.5527H56.4881V37.6596H60.7017V39.7664H58.5949V41.8732H56.4881V39.7664H54.3812V41.8732H52.2744V37.6596H54.3812V35.5527Z" fill="#1F2937"/>
+<path d="M60.699 35.5527H56.4854V37.6596H60.699V35.5527Z" fill="white"/>
+<path d="M64.9168 35.5527H60.7031V37.6596H64.9168V35.5527Z" fill="#1F2937"/>
+<path d="M64.7851 35.5527H66.8919V39.7664H68.9987V48.062H66.8919V41.8732H64.7851V39.7664H60.7031V37.6596H64.7851V35.5527Z" fill="white"/>
+<path d="M0 37.6602H2.10682V39.767H4.21364V41.8738H2.10682V50.1694H4.21364V52.2762H0V37.6602Z" fill="#1F2937"/>
+<path d="M4.21424 37.6602H2.10742V39.767H4.21424V37.6602Z" fill="white"/>
+<path d="M8.42751 37.6602H4.21387V39.767H8.42751V37.6602Z" fill="#1F2937"/>
+<path d="M14.615 37.6602H10.4014V39.767H14.615V37.6602Z" fill="#1F2937"/>
+<path d="M18.8328 37.6602H14.6191V39.767H18.8328V37.6602Z" fill="white"/>
+<path d="M39.7699 37.6602H37.6631V39.767H39.7699V37.6602Z" fill="#1F2937"/>
+<path d="M14.6159 39.7656H18.8296V41.8724H16.7227V43.9793H10.4023V45.9544H8.42713V43.9793H6.32031V41.8724H14.6159V39.7656Z" fill="#1F2937"/>
+<path d="M37.659 39.7656H33.4453V43.9793H37.659V39.7656Z" fill="#1F2937"/>
+<path d="M45.955 39.7656H48.0618V45.9544H45.955V48.0612H41.873V45.9544H43.9799V43.9793H45.955V39.7656Z" fill="#1F2937"/>
+<path d="M54.3812 39.7656H56.4881V41.8724H58.5949V43.9793H52.2744V41.8724H54.3812V39.7656Z" fill="white"/>
+<path d="M60.7035 39.7656H58.5967V41.8724H60.7035V39.7656Z" fill="white"/>
+<path d="M64.9168 39.7656H60.7031V41.8724H64.9168V39.7656Z" fill="#1F2937"/>
+<path d="M23.0421 41.873H25.149V43.9799H33.4446V45.955H29.2309V48.0618H27.1241V45.955H25.149V50.1686H23.0421V52.2755H20.9353V54.3823H16.7217V52.2755H18.8285V48.0618H20.9353V43.9799H23.0421V41.873Z" fill="#1F2937"/>
+<path d="M39.7699 41.873H43.9835V43.9799H41.8767V45.955H37.6631V43.9799H39.7699V41.873Z" fill="#1F2937"/>
+<path d="M52.2777 41.873H50.1709V43.9799H52.2777V41.873Z" fill="#1F2937"/>
+<path d="M58.5931 41.873H60.6999V43.9799H64.7819V41.873H66.8887V48.0618H68.9955V50.1686H62.8067V48.0618H64.7819V45.955H58.5931V48.0618H56.4862V50.1686H62.8067V54.3823H60.6999V56.4891H62.8067V54.3823H66.8887V56.4891H64.7819V58.5959H60.6999V68.9984H58.5931V66.8915H54.3794V64.7847H58.5931V62.8096H56.4862V60.7028H54.3794V64.7847H48.059V62.8096H50.1658V58.5959H48.059V54.3823H45.9521V52.2755H50.1658V50.1686H52.2726V48.0618H54.3794V45.955H52.2726V43.9799H58.5931V41.873Z" fill="#1F2937"/>
+<path d="M64.9168 41.873H60.7031V43.9799H64.9168V41.873Z" fill="white"/>
+<path d="M6.32069 43.9805H4.21387V46.0873H6.32069V43.9805Z" fill="#1F2937"/>
+<path d="M33.4453 43.9805H37.659V45.9556H41.8726V48.0624H39.7658V50.1692H37.659V48.0624H35.5521V45.9556H33.4453V43.9805Z" fill="white"/>
+<path d="M43.9799 43.9805H41.873V46.0873H43.9799V43.9805Z" fill="white"/>
+<path d="M14.615 45.9551H10.4014V48.0619H14.615V45.9551Z" fill="#1F2937"/>
+<path d="M35.5521 45.9551H33.4453V48.0619H35.5521V45.9551Z" fill="#1F2937"/>
+<path d="M48.059 45.9551H45.9521V48.0619H48.059V45.9551Z" fill="white"/>
+<path d="M48.059 45.9551H52.2726V48.0619H50.1658V50.1687H45.9521V48.0619H48.059V45.9551Z" fill="#1F2937"/>
+<path d="M54.3812 45.9551H52.2744V48.0619H54.3812V45.9551Z" fill="white"/>
+<path d="M58.5922 45.9551H64.781V48.0619H62.8058V50.1687H56.4854V48.0619H58.5922V45.9551Z" fill="white"/>
+<path d="M4.21387 48.0625H8.42751V50.1693H14.6163V52.2761H6.32069V50.1693H4.21387V48.0625Z" fill="#1F2937"/>
+<path d="M16.726 48.0625H14.6191V50.1693H16.726V48.0625Z" fill="#1F2937"/>
+<path d="M33.4486 48.0625H31.3418V50.1693H33.4486V48.0625Z" fill="#1F2937"/>
+<path d="M33.4486 48.0625H35.5554V52.2761H43.9827V50.1693H41.8759V48.0625H45.9579V50.1693H50.1715V52.2761H45.9579V54.383H43.9827V56.4898H45.9579V54.383H48.0647V58.5966H50.1715V62.8102H48.0647V60.7034H45.9579V58.5966H41.8759V54.383H37.6623V56.4898H35.5554V58.5966H33.4486V56.4898H31.3418V50.1693H33.4486V48.0625Z" fill="white"/>
+<path d="M35.5527 48.0625H37.6596V50.1693H39.7664V48.0625H41.8732V50.1693H43.98V52.2761H35.5527V48.0625Z" fill="#1F2937"/>
+<path d="M52.2777 48.0625H50.1709V50.1693H52.2777V48.0625Z" fill="white"/>
+<path d="M29.2338 50.168H31.3406V56.4884H33.4474V58.5953H31.3406V60.7021H33.4474V58.5953H35.5542V56.4884H37.6611V60.7021H35.5542V62.8089H37.6611V64.784H39.7679V66.8909H37.6611V68.9977H35.5542V64.784H33.4474V66.8909H31.3406V62.8089H29.2338V56.4884H27.127V52.2748H29.2338V50.168Z" fill="#1F2937"/>
+<path d="M62.8105 50.168H68.9993V52.2748H66.8925V54.3816H62.8105V50.168Z" fill="white"/>
+<path d="M58.5949 52.2754H52.2744V58.5958H58.5949V52.2754Z" fill="white"/>
+<path d="M69.0004 52.2754H66.8936V54.3822H69.0004V52.2754Z" fill="#1F2937"/>
+<path d="M14.6161 54.3828H0V68.9989H14.6161V54.3828Z" fill="#1F2937"/>
+<path d="M23.043 54.3828H25.1498V56.4896H27.1249V58.5965H23.043V54.3828Z" fill="#1F2937"/>
+<path d="M37.6631 54.3828H41.8767V58.5965H45.9587V60.7033H48.0655V62.8101H43.9835V66.8921H41.8767V60.7033H39.7699V56.4896H37.6631V54.3828Z" fill="#1F2937"/>
+<path d="M46.0834 54.3828H43.9766V56.4896H46.0834V54.3828Z" fill="#1F2937"/>
+<path d="M56.4887 54.3828H54.3818V56.4896H56.4887V54.3828Z" fill="#1F2937"/>
+<path d="M62.8099 54.3828H60.7031V56.4896H62.8099V54.3828Z" fill="white"/>
+<path d="M69.0004 54.3828H66.8936V56.4896H69.0004V54.3828Z" fill="white"/>
+<path d="M12.5098 56.4902H2.10742V66.8927H12.5098V56.4902Z" fill="white"/>
+<path d="M18.8285 56.4902H16.7217V58.5971H18.8285V56.4902Z" fill="#1F2937"/>
+<path d="M27.1249 56.4902H29.2318V62.8107H27.1249V64.7858H25.1498V62.8107H23.043V58.5971H27.1249V56.4902Z" fill="white"/>
+<path d="M37.6596 56.4902H39.7664V60.7039H41.8732V66.8927H39.7664V64.7858H37.6596V62.8107H35.5527V60.7039H37.6596V56.4902Z" fill="white"/>
+<path d="M64.7851 56.4902H66.8919V58.5971H68.9987V62.8107H66.8919V60.7039H62.8099V68.9995H60.7031V58.5971H64.7851V56.4902Z" fill="white"/>
+<path d="M69.0004 56.4902H66.8936V58.5971H69.0004V56.4902Z" fill="#1F2937"/>
+<path d="M10.5343 58.5957H4.21387V64.9162H10.5343V58.5957Z" fill="#1F2937"/>
+<path d="M20.9359 58.5957H23.0427V62.8093H25.1496V64.7845H27.1247V62.8093H29.2315V66.8913H27.1247V68.9981H25.1496V66.8913H23.0427V64.7845H20.9359V62.8093H18.8291V60.7025H20.9359V58.5957Z" fill="#1F2937"/>
+<path d="M33.4486 58.5957H31.3418V60.7025H33.4486V58.5957Z" fill="white"/>
+<path d="M54.3818 60.7031H56.4887V62.8099H58.5955V64.7851H54.3818V60.7031Z" fill="white"/>
+<path d="M62.8105 60.7031H66.8925V62.8099H68.9993V64.7851H64.7857V66.8919H66.8925V68.9987H62.8105V60.7031Z" fill="#1F2937"/>
+<path d="M29.2338 62.8086H31.3406V66.8906H33.4474V64.7837H35.5542V68.9974H27.127V66.8906H29.2338V62.8086Z" fill="white"/>
+<path d="M43.9766 62.8086H48.0585V64.7837H54.379V66.8906H58.5926V68.9974H52.2722V66.8906H43.9766V62.8086Z" fill="white"/>
+<path d="M64.7832 64.7832H68.9968V68.9968H66.89V66.89H64.7832V64.7832Z" fill="white"/>
+<path d="M23.0427 66.8926H18.8291V68.9994H23.0427V66.8926Z" fill="#1F2937"/>
+<path d="M25.1498 66.8926H23.043V68.9994H25.1498V66.8926Z" fill="white"/>
+<path d="M39.7699 66.8926H37.6631V68.9994H39.7699V66.8926Z" fill="white"/>
+<path d="M41.8724 66.8926H39.7656V68.9994H41.8724V66.8926Z" fill="#1F2937"/>
+<path d="M43.9799 66.8926H41.873V68.9994H43.9799V66.8926Z" fill="white"/>
+<path d="M52.4038 66.8926H43.9766V68.9994H52.4038V66.8926Z" fill="#1F2937"/>
+</svg>

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 6 - 0
src/assets/icon/bitcoin/yaoqing.svg


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 15 - 0
src/assets/icon/user/yaoqi.svg


+ 72 - 0
src/locales/index.js

@@ -0,0 +1,72 @@
+import { createI18n } from 'vue-i18n'
+import { Locale } from 'vant'
+
+// 1. 同步引入中文 (兜底防乱码)
+import defaultZhCN from './lang/zh-CN'
+import defaultVantZhCN from 'vant/es/locale/lang/zh-CN'
+
+const i18n = createI18n({
+  legacy: false,
+  locale: 'zh-CN', // 初始设为中文
+  fallbackLocale: 'zh-CN',
+  globalInjection: true,
+  messages: {
+    'zh-CN': { ...defaultVantZhCN, ...defaultZhCN }
+  }
+})
+
+// 2. Vant 语言包映射 (8国语言)
+const vantLocales = {
+  'en-US': () => import('vant/es/locale/lang/en-US'),
+  'de-DE': () => import('vant/es/locale/lang/de-DE'),
+  'es-ES': () => import('vant/es/locale/lang/es-ES'),
+  'fr-FR': () => import('vant/es/locale/lang/fr-FR'),
+  'pt-PT': () => import('vant/es/locale/lang/pt-BR'),
+  'id-ID': () => import('vant/es/locale/lang/id-ID'),
+  'ru-RU': () => import('vant/es/locale/lang/ru-RU'),
+}
+
+// 3. 核心加载函数
+export async function loadLanguageAsync(lang) {
+  if (lang === 'zh-CN') {
+    setI18nLanguage('zh-CN')
+    return 'zh-CN'
+  }
+
+  if (i18n.global.availableLocales.includes(lang)) {
+    setI18nLanguage(lang)
+    return lang
+  }
+
+  try {
+    const [userMsg, vantMsg] = await Promise.all([
+      import(`./lang/${lang}.js`),
+      vantLocales[lang] ? vantLocales[lang]() : Promise.resolve({ default: {} })
+    ])
+
+    const messages = { ...vantMsg.default, ...userMsg.default }
+    i18n.global.setLocaleMessage(lang, messages)
+
+    setI18nLanguage(lang, vantMsg.default)
+    return lang
+  } catch (e) {
+    console.error('Language load failed:', e)
+    return 'zh-CN'
+  }
+}
+
+function setI18nLanguage(lang, vantMsg) {
+  i18n.global.locale.value = lang
+  localStorage.setItem('app-lang', lang)
+  document.querySelector('html').setAttribute('lang', lang)
+
+  if (lang === 'zh-CN') {
+    Locale.use('zh-CN', defaultVantZhCN)
+  } else if (vantMsg) {
+    Locale.use(lang, vantMsg)
+  } else if (vantLocales[lang]) {
+    vantLocales[lang]().then(mod => Locale.use(lang, mod.default))
+  }
+}
+
+export default i18n

+ 30 - 0
src/locales/lang/de-DE.js

@@ -0,0 +1,30 @@
+export default {
+  common: {
+    switchLang: 'Sprache wechseln',
+    confirm: 'Senden',
+    cancel: 'Abbrechen',
+    save: 'Speichern',
+    loading: 'Laden...'
+  },
+  home: {
+    title: 'Auth Zentrum',
+    startAuth: 'Erweiterte Auth starten',
+    homeAddr: 'Wohnadresse',
+    workAddr: 'Arbeitsadresse',
+    relation: 'Verwandtenkontakt',
+    verified: 'Verifiziert',
+    toVerify: 'Jetzt verifizieren',
+    pending: 'Ausstehend'
+  },
+  auth: {
+    advanced: 'Erweiterte Auth',
+    area: 'Gebiet',
+    detail: 'Detaillierte Adresse',
+    detailPlaceholder: 'Bitte detaillierte Adresse eingeben',
+    name: 'Name des Verwandten',
+    relationType: 'Beziehung',
+    phone: 'Telefonnummer',
+    pleaseSelect: 'Auswählen',
+    pleaseInput: 'Eingeben'
+  }
+}

+ 32 - 0
src/locales/lang/en-US.js

@@ -0,0 +1,32 @@
+export default {
+  common: {
+      switchLang: '*** ENGLISH ***',
+    confirm: '*** SUBMIT ***',
+    // switchLang: 'Switch Language',
+    // confirm: 'Submit',
+    cancel: 'Cancel',
+    save: 'Save',
+    loading: 'Loading...'
+  },
+  home: {
+    title: 'Auth Center',
+    startAuth: 'Start Advanced Auth',
+    homeAddr: 'Home Address',
+    workAddr: 'Work Address',
+    relation: 'Relative Contact',
+    verified: 'Verified',
+    toVerify: 'Verify Now',
+    pending: 'Pending'
+  },
+  auth: {
+    advanced: 'Advanced Auth',
+    area: 'Area',
+    detail: 'Detailed Address',
+    detailPlaceholder: 'Please enter detailed address',
+    name: 'Relative Name',
+    relationType: 'Relation',
+    phone: 'Phone Number',
+    pleaseSelect: 'Select',
+    pleaseInput: 'Enter'
+  }
+}

+ 30 - 0
src/locales/lang/es-ES.js

@@ -0,0 +1,30 @@
+export default {
+  common: {
+    switchLang: 'Cambiar idioma',
+    confirm: 'Enviar',
+    cancel: 'Cancelar',
+    save: 'Guardar',
+    loading: 'Cargando...'
+  },
+  home: {
+    title: 'Centro de Autenticación',
+    startAuth: 'Iniciar Autenticación Avanzada',
+    homeAddr: 'Dirección Particular',
+    workAddr: 'Dirección Trabajo',
+    relation: 'Contacto Familiar',
+    verified: 'Verificado',
+    toVerify: 'Verificar',
+    pending: 'Pendiente'
+  },
+  auth: {
+    advanced: 'Autenticación Avanzada',
+    area: 'Área',
+    detail: 'Dirección Detallada',
+    detailPlaceholder: 'Ingrese dirección detallada',
+    name: 'Nombre Familiar',
+    relationType: 'Relación',
+    phone: 'Teléfono',
+    pleaseSelect: 'Seleccionar',
+    pleaseInput: 'Ingresar'
+  }
+}

+ 30 - 0
src/locales/lang/fr-FR.js

@@ -0,0 +1,30 @@
+export default {
+  common: {
+    switchLang: 'Changer de langue',
+    confirm: 'Soumettre',
+    cancel: 'Annuler',
+    save: 'Enregistrer',
+    loading: 'Chargement...'
+  },
+  home: {
+    title: 'Centre d\'authentification',
+    startAuth: 'Démarrer l\'auth avancée',
+    homeAddr: 'Adresse Domicile',
+    workAddr: 'Adresse Travail',
+    relation: 'Contact Parent',
+    verified: 'Vérifié',
+    toVerify: 'Vérifier',
+    pending: 'En attente'
+  },
+  auth: {
+    advanced: 'Auth Avancée',
+    area: 'Région',
+    detail: 'Adresse détaillée',
+    detailPlaceholder: 'Entrez l\'adresse détaillée',
+    name: 'Nom du parent',
+    relationType: 'Relation',
+    phone: 'Téléphone',
+    pleaseSelect: 'Sélectionner',
+    pleaseInput: 'Saisir'
+  }
+}

+ 30 - 0
src/locales/lang/id-ID.js

@@ -0,0 +1,30 @@
+export default {
+  common: {
+    switchLang: 'Ganti Bahasa',
+    confirm: 'Kirim',
+    cancel: 'Batal',
+    save: 'Simpan',
+    loading: 'Memuat...'
+  },
+  home: {
+    title: 'Pusat Otentikasi',
+    startAuth: 'Mulai Otentikasi Lanjutan',
+    homeAddr: 'Alamat Rumah',
+    workAddr: 'Alamat Kantor',
+    relation: 'Kontak Kerabat',
+    verified: 'Terverifikasi',
+    toVerify: 'Verifikasi',
+    pending: 'Menunggu'
+  },
+  auth: {
+    advanced: 'Otentikasi Lanjutan',
+    area: 'Area',
+    detail: 'Alamat Lengkap',
+    detailPlaceholder: 'Masukkan alamat lengkap',
+    name: 'Nama Kerabat',
+    relationType: 'Hubungan',
+    phone: 'Nomor Telepon',
+    pleaseSelect: 'Pilih',
+    pleaseInput: 'Masukkan'
+  }
+}

+ 30 - 0
src/locales/lang/pt-PT.js

@@ -0,0 +1,30 @@
+export default {
+  common: {
+    switchLang: 'Mudar idioma',
+    confirm: 'Enviar',
+    cancel: 'Cancelar',
+    save: 'Salvar',
+    loading: 'Carregando...'
+  },
+  home: {
+    title: 'Centro de Auth',
+    startAuth: 'Iniciar Auth Avançada',
+    homeAddr: 'Endereço Residencial',
+    workAddr: 'Endereço Comercial',
+    relation: 'Contato Parente',
+    verified: 'Verificado',
+    toVerify: 'Verificar',
+    pending: 'Pendente'
+  },
+  auth: {
+    advanced: 'Auth Avançada',
+    area: 'Área',
+    detail: 'Endereço Detalhado',
+    detailPlaceholder: 'Insira endereço detalhado',
+    name: 'Nome do Parente',
+    relationType: 'Relação',
+    phone: 'Telefone',
+    pleaseSelect: 'Selecionar',
+    pleaseInput: 'Inserir'
+  }
+}

+ 30 - 0
src/locales/lang/ru-RU.js

@@ -0,0 +1,30 @@
+export default {
+  common: {
+    switchLang: 'Сменить язык',
+    confirm: 'Отправить',
+    cancel: 'Отмена',
+    save: 'Сохранить',
+    loading: 'Загрузка...'
+  },
+  home: {
+    title: 'Центр аутентификации',
+    startAuth: 'Начать расширенную аутентификацию',
+    homeAddr: 'Домашний адрес',
+    workAddr: 'Рабочий адрес',
+    relation: 'Контакт родственника',
+    verified: 'Подтверждено',
+    toVerify: 'Подтвердить',
+    pending: 'Ожидание'
+  },
+  auth: {
+    advanced: 'Расширенная аутентификация',
+    area: 'Регион',
+    detail: 'Подробный адрес',
+    detailPlaceholder: 'Введите подробный адрес',
+    name: 'Имя родственника',
+    relationType: 'Отношение',
+    phone: 'Телефон',
+    pleaseSelect: 'Выбрать',
+    pleaseInput: 'Ввод'
+  }
+}

+ 33 - 0
src/locales/lang/zh-CN.js

@@ -0,0 +1,33 @@
+export default {
+  // 通用词汇
+  common: {
+    switchLang: '切换语言',
+    confirm: '提交',
+    cancel: '取消',
+    save: '保存',
+    loading: '加载中...'
+  },
+  // 首页
+  home: {
+    title: '认证中心',
+    startAuth: '开始高级认证',
+    homeAddr: '家庭地址',
+    workAddr: '工作地址',
+    relation: '亲属联系方式',
+    verified: '已认证',
+    toVerify: '去认证',
+    pending: '待认证'
+  },
+  // 表单页
+  auth: {
+    advanced: '高级认证',
+    area: '所在地区',
+    detail: '详细地址',
+    detailPlaceholder: '请输入详细地址',
+    name: '亲属姓名',
+    relationType: '亲属关系',
+    phone: '联系方式',
+    pleaseSelect: '请选择',
+    pleaseInput: '请输入'
+  }
+}

+ 27 - 7
src/main.js

@@ -3,16 +3,36 @@ import App from "./App.vue";
 import router from "./router";
 import store from "./store";
 import 'vant/lib/index.css';
+import "./assets/less/index.less"; // 你的全局样式
 
-// 引入less样式文件
-import "./assets/less/index.less";
+// 引入 i18n 和 加载函数
+import i18n, { loadLanguageAsync } from './locales/index'
+
+import {
+  Button,
+  Popup,
+  Form,
+  Field,
+  NavBar,
+  Picker,
+  Icon,
+  Toast
+} from 'vant';
 
-// 加载接口文件
 import api from "./utils/api.js";
 
-// 挂载到vue原型上
-const app = createApp(App);
+const savedLang = localStorage.getItem('app-lang') || 'zh-CN';
+
+// 等待语言包加载完成后再渲染
+loadLanguageAsync(savedLang).then(() => {
+  const app = createApp(App);
+
+  app.use(Button).use(Popup).use(Form).use(Field).use(NavBar).use(Picker).use(Icon).use(Toast);
+  app.use(store);
+  app.use(router);
+  app.use(i18n);
 
-app.use(store).use(router).mount("#app");
+  app.config.globalProperties.$api = api;
 
-app.config.globalProperties.$api = api;
+  app.mount("#app");
+});

+ 136 - 64
src/router/index.js

@@ -1,4 +1,4 @@
-import {createRouter, createWebHistory} from "vue-router";
+import { createRouter, createWebHistory } from "vue-router";
 import HomeIndex from "../views/HomeIndex.vue";
 import AppIndex from "../views/index/Index.vue";
 import MarketIndex from "../views/market/Index.vue";
@@ -29,39 +29,22 @@ import RechargeChangeCoin from "../views/index/recharge/ChangeCoin.vue";
 import Transfer from "../views/index/recharge/Transfer.vue";
 import TransferHistory from "../views/index/recharge/TransferHistory.vue";
 import UserAsset from "../views/asset/UserAsset.vue";
-import RechargeHistory from "../views/index/recharge/RechargeHistory.vue";
-import WithdrawHistory from "../views/index/recharge/WithdrawHistory.vue";
-import FinancialIndex from "../views/index/financial/Index.vue";
-import FinancialBuy from "../views/index/financial/Buy.vue";
-import MyFinancial from "../views/index/financial/MyFinancial.vue";
-import CloudComPowerIndex from "@/views/index/cloudComputingPower/Index.vue";
-import ComboDetails from "@/views/index/cloudComputingPower/ComboDetails.vue";
-import MyPower from "@/views/index/cloudComputingPower/MyPower.vue";
-import MiningOutput from "@/views/index/cloudComputingPower/MiningOutput.vue";
-import ElectricityRecharge from "@/views/index/cloudComputingPower/ElectricityRecharge.vue";
-import ElectricitySetting from "@/views/index/cloudComputingPower/ElectricitySetting.vue";
-import ElectricityBill from "@/views/index/cloudComputingPower/ElectricityBill.vue";
-import CloudMyOrder from "@/views/index/cloudComputingPower/MyOrder.vue";
-import CloudCalculator from "@/views/index/cloudComputingPower/Calculator.vue";
-import StakingIndex from "@/views/index/staking/Index.vue";
-import StakingRules from "@/views/index/staking/Rules.vue";
-import StakingRecord from "@/views/index/staking/Record.vue";
-import OTCIndex from "@/views/asset/otc/Index.vue";
-import OTCMessageIndex from "@/views/asset/otc/message/Index.vue";
-import OTCOrderIndex from "@/views/asset/otc/order/Index.vue";
-import OTCTransactionIndex from "@/views/asset/otc/transaction/Index.vue";
-import OTCUserIndex from "@/views/asset/otc/user/Index.vue";
+
 
 import CommonFunctionsPopup from "@/views/bitcoin/CommonFunctionsPopup/CommonFunctionsPopup.vue"; // 子组件路径
 import TradeRules from "@/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/TradeRules.vue"; // 新建
-import TradeLayout from "@/views/bitcoin/TradeLayout.vue"; // 新建的公共父组件
-import TradeFutures from "@/views/bitcoin/TradeFutures.vue"; // (合约)
-import TradeSeconds from "@/views/bitcoin/lever/TradeSeconds.vue"; // 秒合约(占位)
-import TradeOptions from "@/views/bitcoin/lever/TradeOptions.vue"; // 期权(占位)
-import TradeMargin from "@/views/bitcoin/lever/TradeMargin.vue";
-import Calculator from "../views/bitcoin/Calculator.vue"; // 新建的计算器页面
-import TradeSettings from "@/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/TradeSettings.vue"; // 新建
-import OptionTrading from "@/views/bitcoin/lever/OptionTrading.vue";
+import TradeLayout from '@/views/bitcoin/TradeLayout.vue'; // 新建的公共父组件
+import TradeFutures from '@/views/bitcoin/TradeFutures.vue'; // (合约)
+import TradeSeconds from '@/views/bitcoin/lever/TradeSeconds.vue'; // 秒合约(占位)
+import TradeOptions from '@/views/bitcoin/lever/TradeOptions.vue'; // 期权(占位)
+import TradeMargin from '@/views/bitcoin/lever/TradeMargin.vue';
+import Calculator from '../views/bitcoin/Calculator.vue' // 新建的计算器页面
+import TradeSettings from '@/views/bitcoin/CommonFunctionsPopup/GeneralLevel2/TradeSettings.vue'// 新建
+import OptionTrading from '@/views/bitcoin/lever/OptionTrading.vue'
+import AddressAuth from '@/views/user/AddressAuth.vue'
+import RelativeAuth from '@/views/user/RelativeAuth.vue'
+import LanguageSwitch from '@/views/user/LanguageSwitch.vue'//语言国际化
+
 
 const routes = [
   {
@@ -99,44 +82,35 @@ const routes = [
             meta: { title: "秒合约" },
           },
           {
-            path: "options",
-            name: "TradeOptions",
+            path: 'options',
+            name: 'TradeOptions',
             component: TradeOptions,
-            meta: { title: "期权" },
+            meta: { title: '期权' },
           },
 
-          {
-            path: "margin",
-            name: "TradeMargin",
-            component: TradeMargin,
-            meta: { title: "杠杆" },
-          },
-          {
-            path: "settings",
-            name: "TradeSettings",
-            component: TradeSettings,
-          },
-        ],
-      },
-      {
-        path: "PnLAnalysis",
-        name: "PnLAnalysis.vue",
-        component: () => import("@/views/bitcoin/lever/PnLAnalysis.vue"),
-        meta: { title: "" },
-      },
-      {
-        path: "calculator",
-        name: "calculator",
-        component: Calculator,
-      },
+            {
+                path: "margin",
+                name: "TradeMargin",
+                component: TradeMargin,
+                meta: {title: "杠杆"},
+            },
+            {
+                path: 'settings',
+                name: 'TradeSettings',
+                component: TradeSettings
+            },
+
+         ]
+        },
+      { path: 'calculator',
+            name: 'calculator',
+            component: Calculator },
       {
-        path: "OptionTrading",
-        name: "OptionTrading",
-        component: OptionTrading,
-        meta: { title: "" },
+            path: 'OptionTrading',
+            name: 'OptionTrading',
+            component: OptionTrading,
+            meta: { title: '' }
       },
-      { path: "settings", name: "TradeSettings", component: TradeSettings },
-      { path: "calculator", name: "calculator", component: Calculator },
       {
         path: "/assetIndex",
         name: "assetIndex",
@@ -149,6 +123,104 @@ const routes = [
       },
     ],
   },
+  {
+    path: '/AdvancedCertification',
+    name: 'AdvancedCertification',
+    component: () => import('@/views/user/AdvancedCertification.vue'),
+    meta: { title: '' }
+   },
+  {
+            path: '/PnLAnalysis',
+            name: 'PnLAnalysis',
+            component: () => import('@/views/bitcoin/lever/PnLAnalysis.vue'),
+            meta: { title: '' }
+  },
+  {
+    path: '/detail',
+    name: 'HelpCenter',
+    // 记得创建这个 Detail.vue 文件
+    component: () => import('@/views/user/HelpCenter.vue')
+  },
+  {
+    // 动态路由,接收一个 id 参数
+    path: '/help/detail',
+    name: 'HelpDetail',
+    component: () => import('@/views/user/HelpDetail.vue')
+  },
+  {
+    path: '/about',
+    name: 'AboutUs',
+    component: () => import('@/views/user/AboutUs.vue')
+  },
+  {
+    path: '/about/privacy',
+    name: 'PrivacyPolicy',
+    component: () => import('@/views/user/PrivacyPolicy.vue')
+  },
+  {
+    path: '/about/agreement',
+    name: 'UserAgreement',
+    component: () => import('@/views/user/UserAgreement.vue')
+  },
+  {
+    path: '/invite',
+    name: 'InviteCenter',
+    component: () => import('@/views/user/InviteCenter.vue') // 上面的组件
+  },
+  {
+      path: '/invite/poster',
+      name: 'InvitePoster',
+      component: () => import('@/views/user/InvitePoster.vue')
+  },
+  {
+    path: '/vip',
+    name: 'VipCenter',
+    component: () => import('@/views/user/VipCenter.vue')
+  },
+  {
+    path: '/vip/rules',
+    name: 'VipRules',
+    component: () => import('@/views/user/VipRules.vue')
+  },
+  {
+    path: '/kyc/step1',
+    name: 'KycForm',
+    component: () => import('@/views/user/KycForm.vue') // 填写表单
+  },
+  {
+    path: '/kyc/step2',
+    name: 'KycUpload',
+    component: () => import('@/views/user/KycUpload.vue') // 上传证件
+  },
+  {
+    path: '/security',
+    name: 'SecuritySettings',
+    component: () => import('@/views/user/SecuritySettings.vue') // 核心页面
+  },
+  {
+    // 地址认证:复用同一个组件,通过 query 参数 type 来区分是 "home" 还是 "work"
+    path: '/auth/address',
+    name: 'address-auth',
+    component: AddressAuth
+  },
+  {
+    // 亲属认证
+    path: '/auth/relative',
+    name: 'relative-auth',
+    component: RelativeAuth
+  },
+  {
+    path: '/language',
+    name: 'LanguageSwitch',
+    component: LanguageSwitch,
+    meta: { title: '切换语言' }
+  },
+  {
+      path: '/basic-verify',
+      name: 'BasicVerify',
+      component: () => import('@/views/user/BasicVerify.vue'),
+      meta: { title: '基础认证' }
+   },
   {
     path: "/otcIndex",
     name: "otcIndex",

+ 5 - 2
src/views/bitcoin/Calculator.vue

@@ -56,7 +56,7 @@
 
     <div v-if="currentTab === 5" class="funding-rate-display">
       <div class="rate-value">0.0030%</div>
-      <div class="rate-label" @click="showModal=true">当前资金费率
+      <div class="rate-label" @click="hyu">当前资金费率
         <VanIcon name="question-o" />
       </div>
     </div>
@@ -246,7 +246,10 @@ const ProfitAndLossPrompt = defineAsyncComponent(() => import('./calculator/Fund
 
 //资金费率提示
 const showModal = ref(false);
-
+const hyu = () => {
+  console.log("kkkkkkk")
+  showModal.value = true;
+}
 
 // 状态定义
 const tabs = ['收益', '目标价格', '强平价格', '可开', '开仓均价', '资金费用'];

+ 2 - 2
src/views/bitcoin/CommonFunctionsPopup/CommonFunctionsPopup.vue

@@ -126,7 +126,7 @@ const menuItems = [
   width: 100vw;
   height: 100vh;
   background-color: rgba(0, 0, 0, 0.5);
-  z-index: 199; /* 保证层级够高 */
+  z-index: 2000; /* 保证层级够高 */
 }
 
 /* 弹窗面板 */
@@ -140,7 +140,7 @@ const menuItems = [
   background: white;
   border-radius: 16px 16px 0 0;
   padding: 10px 0 0 0;
-  z-index: 200; /* 比遮罩层高 */
+  z-index: 2001; /* 比遮罩层高 */
 }
 
 /* 把手装饰 */

+ 5 - 8
src/views/bitcoin/TradeFutures.vue

@@ -158,13 +158,13 @@
 
         <div class="menu-content-rb pf400 fs14">
           <div class="menu-content-rb1 fs14 fc333333">
-            <van-checkbox
+            <VanCheckbox
                 v-model="isEnabled"
                 shape="square"
                 checked-color="#DC4653"
                 icon-size="16px"
             >
-            </van-checkbox>
+            </VanCheckbox>
             <span class="menu-content-rb1s fc333333">只减仓</span>
           </div>
           <div class="menu-content-rb1" @click="showModal = true">
@@ -281,10 +281,7 @@
 import {Checkbox as VanCheckbox, Icon as VanIcon} from 'vant';
 import {computed, defineAsyncComponent, ref, onMounted} from 'vue';
 import { useRouter } from 'vue-router'; // 【新增】 引入路由
-onMounted(() => {
-  // 强制滚动到顶部
-  window.scrollTo(0, 0);
-});
+
 const router = useRouter(); // 【新增】 实例化路由
 
 // --- 异步组件引入 ---
@@ -379,8 +376,8 @@ const onOrderConfirmed = () => {
   flex-direction: column;
   align-items: center;
   padding-bottom: 60px; /* <-- 改成这行 */
-   padding-top: 65px;
-box-sizing: border-box;
+  padding-top: 50px;
+  box-sizing: border-box;
   width: 100%;
   /* 1. 设定高度为视口高度,占满屏幕 */
   //height: 100vh;

+ 18 - 6
src/views/bitcoin/TradeLayout.vue

@@ -40,18 +40,31 @@
       </div>
     </div>
 
-    <router-view></router-view>
+    <router-view :key="$route.fullPath"></router-view>
   </div>
 </template>
 
 <script setup>
+import { onMounted, onUnmounted, ref , watch} from 'vue'
 import { useRouter, useRoute } from 'vue-router';
 
 const router = useRouter();
 const route = useRoute();
 
+// 监听路由路径变化
+watch(
+  () => route.path,
+  () => {
+    window.scrollTo(0, 0);
+    const scrollBox = document.querySelector('.page-container');
+    if (scrollBox) {
+      scrollBox.scrollTop = 0;
+    }
+  }
+);
+
 const switchTab = (name) => {
-  router.push({ name });
+  router.push({ name })
 };
 
 const isCurrent = (name) => {
@@ -62,8 +75,7 @@ const isCurrent = (name) => {
 <style lang="less" scoped>
 .market-layout {
   display: flex;
-  flex-direction: column;
-  justify-content: flex-start;
+
   align-items: center;
   width: 100%;
   height: auto;
@@ -75,13 +87,13 @@ const isCurrent = (name) => {
     flex-direction: row;
     justify-content: space-between;
     align-items: center;
-    padding:10px 15px;
+    padding:0 15px;
     width: 345px;
     height: 48px;
     position: fixed;
     top: 0;
     left: 0;
-    z-index: 1000;
+    z-index: 999;
     background-color: #FFFFFF;
     /* 既然只放Tabs,可能需要一点底部间距,以免紧贴着下面的内容 */
     margin-bottom: 18px;

+ 1 - 1
src/views/bitcoin/calculator/FundingRateReminder.vue

@@ -48,7 +48,7 @@ const close = () => {
   display: flex;
   align-items: center; /* 垂直居中 */
   justify-content: center; /* 水平居中 */
-  z-index: 999;
+  z-index: 2000;
 }
 
 /* --- 弹窗卡片 --- */

+ 2 - 2
src/views/bitcoin/components/ChooseThisDepth.vue

@@ -76,7 +76,7 @@ const selectItem = (item) => {
   position: fixed; top: 0; left: 0; right: 0; bottom: 0;
   background-color: rgba(0, 0, 0, 0.6);
   backdrop-filter: blur(2px);
-  z-index: 999;
+  z-index: 2000;
 }
 
 .popup-wrapper {
@@ -84,7 +84,7 @@ const selectItem = (item) => {
   background-color: #FFFFFF;
   border-top-left-radius: 16px;
   border-top-right-radius: 16px;
-  z-index: 1000;
+  z-index: 2001;
   padding-bottom: 10px;
 }
 

+ 2 - 2
src/views/bitcoin/components/OrderConfirmPopup.vue

@@ -177,12 +177,12 @@ const handleConfirm = () => {
     /* 布局样式 */
     .mask {
       position: fixed; top: 0; left: 0; right: 0; bottom: 0;
-      background: rgba(0,0,0,0.6); z-index: 998;
+      background: rgba(0,0,0,0.6); z-index: 1999;
     }
     .popup-container {
       position: fixed; bottom: 0; left: 0; right: 0;
       background: #fff; border-radius: 16px 16px 0 0;
-      z-index: 999; padding-bottom: calc(20px + env(safe-area-inset-bottom));
+      z-index: 2000; padding-bottom: calc(20px + env(safe-area-inset-bottom));
       font-family: -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
       max-height: 90vh; overflow-y: auto; /* 允许小屏滚动 */
     }

+ 3 - 2
src/views/bitcoin/components/TPSLSmartPopup.vue

@@ -245,10 +245,11 @@ const confirm = () => {
     .theme-sell { --primary-color: #F6465D; }
 
     /* 基础布局 */
-    .mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.6); z-index: 998; }
+    .mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0;
+      background: rgba(0,0,0,0.6); z-index: 2000; }
     .popup-container {
       position: fixed; bottom: 0; left: 0; right: 0; background: #fff; border-radius: 16px 16px 0 0;
-      z-index: 999; padding-bottom: calc(20px + env(safe-area-inset-bottom));
+      z-index: 2001; padding-bottom: calc(20px + env(safe-area-inset-bottom));
       font-family: -apple-system, BlinkMacSystemFont, Roboto, sans-serif; max-height: 90vh;
       overflow-y: auto; color: #333;
     }

+ 12 - 4
src/views/bitcoin/components/sellOrder.vue

@@ -1,5 +1,5 @@
 <script setup>
-    import {defineAsyncComponent, ref} from 'vue';
+    import {defineAsyncComponent, ref, nextTick} from 'vue';
     //状态组件
     const assetlessState = defineAsyncComponent(() => import("./assetlessState.vue"));
     //持有仓位组件
@@ -40,10 +40,13 @@
         canCancel: false // 显示灰色已完成/不可操作按钮
       },
     ]);
-
+    const containerRef = ref(null)
     // 当前选中的 Tab,默认选中 index 1 (当前委托)
     const currentTab = ref(0);
     const tabs = ['持有仓位(0)', '当前委托(2)'];
+    const TabActive = (index) => {
+        currentTab.value = index
+    }
 
     // 按钮操作
     const handleCancel = (id) => {
@@ -66,7 +69,7 @@
             :key="index"
             class="tab-item"
             :class="{ active: currentTab === index }"
-            @click="currentTab = index"
+            @click="TabActive(index)"
         >
           {{ tab }}
           <div class="active-line" v-if="currentTab === index"></div>
@@ -161,7 +164,12 @@
 /* 基础设置 */
 .page-container1 {
   width: 100%;
-  height: auto;
+  /* 1. 必须限制高度 (例如占满屏幕) */
+  //height: 100vh;
+  /* 或者 height: calc(100vh - 头部高度); */
+
+  /* 2. 必须开启溢出滚动 */
+  //overflow-y: auto;
   //background-color: #FAFAFA; /* 浅灰背景 */
   font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", Arial, sans-serif;
 }

+ 6 - 3
src/views/bitcoin/lever/PnLAnalysis.vue

@@ -34,7 +34,7 @@
       </div>
 
       <div class="history-section">
-        <div class="section-title">
+        <div class="section-title" @click="showModal = true">
           历史盈亏 <van-icon name="question-o" color="#999" size="14" style="margin-left:4px" />
         </div>
 
@@ -62,6 +62,7 @@
       </div>
 
     </div>
+    <ExplanationModal v-model:visible="showModal"></ExplanationModal>
   </div>
 </template>
 
@@ -69,6 +70,7 @@
 import { ref } from 'vue';
 import { useRouter } from 'vue-router'; // 引入路由钩子
 import { Popup as vanPopup, Icon as vanIcon } from 'vant';
+import ExplanationModal from '@/views/bitcoin/lever/components/ExplanationModal.vue'
 
 const router = useRouter();
 
@@ -88,7 +90,8 @@ const statsData = ref([
   { label: '盈利天数', value: '10 天' },
   { label: '持平天数', value: '10 天' },
 ]);
-
+//历史盈亏说明
+const showModal = ref(false);
 // 模拟数据:历史记录
 const historyList = ref([
   {
@@ -243,7 +246,7 @@ const historyList = ref([
   border-bottom: 1px solid #F2F3F5;
 }
 .card-body {
-  padding: 12px 0;
+  padding: 8px 0;
 }
 .info-row {
   display: flex;

+ 117 - 117
src/views/bitcoin/lever/TradeMargin.vue

@@ -66,102 +66,102 @@
 </template>
 
 <script setup>
-import { onMounted, onUnmounted, ref } from 'vue'
-// ✅ 使用 namespace 引入,防止报错
-import * as klinecharts from 'klinecharts'
-import MarketPriceAndPlan from'./components/MarketPriceAndPlan.vue'
-import sellOrder from '@/views/bitcoin/components/sellOrder.vue';
+      import { onMounted, onUnmounted, ref } from 'vue'
+      // ✅ 使用 namespace 引入,防止报错
+      import * as klinecharts from 'klinecharts'
+      import MarketPriceAndPlan from './components/MarketPriceAndPlan.vue'
+      import sellOrder from '@/views/bitcoin/components/sellOrder.vue';
 
 
-// --- 状态管理 ---
-const currentTab = ref('24h')
-const tabs = ['1h', '6h', '24h', '1w', '1m']
-let chartInstance = null
+      // --- 状态管理 ---
+      const currentTab = ref('24h')
+      const tabs = ['1h', '6h', '24h', '1w', '1m']
+      let chartInstance = null
 
-// --- 数据生成逻辑 ---
-const generateData = (baseVal = 3812.74) => {
-  const data = []
-  let baseTime = new Date().getTime()
-  let basePrice = baseVal
-  for (let i = 0; i < 80; i++) {
-    const change = (Math.random() - 0.5) * 30
-    const close = basePrice + change
-    const open = basePrice + (Math.random() - 0.5) * 10
-    const high = Math.max(open, close) + Math.random() * 10
-    const low = Math.min(open, close) - Math.random() * 10
-    const volume = Math.random() * 100 + 50
+      // --- 数据生成逻辑 ---
+      const generateData = (baseVal = 3812.74) => {
+        const data = []
+        let baseTime = new Date().getTime()
+        let basePrice = baseVal
+        for (let i = 0; i < 80; i++) {
+          const change = (Math.random() - 0.5) * 30
+          const close = basePrice + change
+          const open = basePrice + (Math.random() - 0.5) * 10
+          const high = Math.max(open, close) + Math.random() * 10
+          const low = Math.min(open, close) - Math.random() * 10
+          const volume = Math.random() * 100 + 50
 
-    data.push({ timestamp: baseTime, open, high, low, close, volume })
-    baseTime += 60 * 60 * 1000 // 1h 间隔
-    basePrice = close + (Math.random() * 2) // 稍微向上的趋势
-  }
-  return data
-}
+          data.push({ timestamp: baseTime, open, high, low, close, volume })
+          baseTime += 60 * 60 * 1000 // 1h 间隔
+          basePrice = close + (Math.random() * 2) // 稍微向上的趋势
+        }
+        return data
+      }
 
-// --- 切换周期逻辑 ---
-const switchPeriod = (period) => {
-  currentTab.value = period
-  if (chartInstance) {
-    // 模拟数据刷新
-    const randomStart = 3800 + Math.random() * 100
-    chartInstance.applyNewData(generateData(randomStart))
-  }
-}
+      // --- 切换周期逻辑 ---
+      const switchPeriod = (period) => {
+        currentTab.value = period
+        if (chartInstance) {
+          // 模拟数据刷新
+          const randomStart = 3800 + Math.random() * 100
+          chartInstance.applyNewData(generateData(randomStart))
+        }
+      }
 
-// --- 初始化与配置 ---
-onMounted(() => {
-  const chartDOM = document.getElementById('k-line-chart')
-  if (!chartDOM) return
+      // --- 初始化与配置 ---
+      onMounted(() => {
+        const chartDOM = document.getElementById('k-line-chart')
+        if (!chartDOM) return
 
-  // 1. 初始化图表
-  chartInstance = klinecharts.init(chartDOM)
-  if (!chartInstance) return
+        // 1. 初始化图表
+        chartInstance = klinecharts.init(chartDOM)
+        if (!chartInstance) return
 
-  // 2. 样式常量
-  const targetBlue = '#4A6EF5' // 截图中的蓝色虚线颜色
-  const gridColor = '#F2F4F6'  // 极淡的网格线
-  const textColor = '#929AA5'  // 灰色文字
+        // 2. 样式常量
+        const targetBlue = '#4A6EF5' // 截图中的蓝色虚线颜色
+        const gridColor = '#F2F4F6'  // 极淡的网格线
+        const textColor = '#929AA5'  // 灰色文字
 
-  // 3. 核心配置 (setStyleOptions)
-  chartInstance.setStyleOptions({
-    grid: {
-      show: true,
-      horizontal: {
-        show: true,
-        size: 1,
-        color: gridColor,
-        style: 'dash',
-        dashValue: [5, 5]
-      },
-      vertical: { show: false }
-    },
-    candle: {
-      type: 'candle_solid',
-      bar: {
-        upColor: '#2EBD85',
-        downColor: '#F6465D',
-        noChangeColor: '#2EBD85'
-      },
-      // ✅ 重点:蓝色价格指示线配置
-      priceMark: {
-        show: true,
-        high: { show: false },
-        low: { show: false },
-        last: {
-          show: true,
-          // 强制无论涨跌都显示蓝色
-          upColor: targetBlue,
-          downColor: targetBlue,
-          line: { show: true, style: 'dash', dashValue: [4, 3] },
-          text: {
+        // 3. 核心配置 (setStyleOptions)
+        chartInstance.setStyleOptions({
+          grid: {
             show: true,
-            color: '#FFFFFF',
-            size: 11,
-            paddingLeft: 4,
-            paddingRight: 4,
-            borderRadius: 2
-          }
-        }
+            horizontal: {
+              show: true,
+              size: 1,
+              color: gridColor,
+              style: 'dash',
+              dashValue: [5, 5]
+                },
+          vertical: { show: false }
+        },
+        candle: {
+          type: 'candle_solid',
+          bar: {
+            upColor: '#2EBD85',
+            downColor: '#F6465D',
+            noChangeColor: '#2EBD85'
+          },
+          // ✅ 重点:蓝色价格指示线配置
+          priceMark: {
+            show: true,
+            high: { show: false },
+            low: { show: false },
+            last: {
+                  show: true,
+                  // 强制无论涨跌都显示蓝色
+                  upColor: targetBlue,
+              downColor: targetBlue,
+              line: { show: true, style: 'dash', dashValue: [4, 3] },
+              text: {
+                show: true,
+                color: '#FFFFFF',
+                size: 11,
+                paddingLeft: 4,
+                paddingRight: 4,
+                borderRadius: 2
+              }
+            }
       },
       tooltip: {
         // 只有按压时才显示十字光标
@@ -183,39 +183,39 @@ onMounted(() => {
         noChangeColor: '#2EBD85'
       }
     },
-    // ✅ 重点:隐藏坐标轴线,只保留文字
-    xAxis: {
-      axisLine: { show: false },
-      tickLine: { show: false },
-      tickText: { color: textColor, size: 10, paddingTop: 8 }
-    },
-    yAxis: {
-      type: 'normal',
-      position: 'right',
-      inside: true,
-      axisLine: { show: false },
-      tickLine: { show: false },
-      tickText: { color: textColor, size: 10, paddingLeft: 8 }
-    },
-    separator: { size: 0 } // 去掉指标和K线之间的分割线
-  })
+      // ✅ 重点:隐藏坐标轴线,只保留文字
+      xAxis: {
+        axisLine: { show: false },
+        tickLine: { show: false },
+        tickText: { color: textColor, size: 10, paddingTop: 8 }
+      },
+      yAxis: {
+        type: 'normal',
+        position: 'right',
+        inside: true,
+        axisLine: { show: false },
+            tickLine: { show: false },
+            tickText: { color: textColor, size: 10, paddingLeft: 8 }
+          },
+          separator: { size: 0 } // 去掉指标和K线之间的分割线
+        })
 
-  // 4. 创建副图指标 (VOL)
-  chartInstance.createTechnicalIndicator('VOL', false, { id: 'pane_1', heightRatio: 0.2 })
+        // 4. 创建副图指标 (VOL)
+        chartInstance.createTechnicalIndicator('VOL', false, { id: 'pane_1', heightRatio: 0.2 })
 
-  // 5. 加载数据并设置缩放
-  chartInstance.applyNewData(generateData())
-  if (chartInstance.setDataSpace) {
-  chartInstance.setDataSpace(7)
-}
-  // chartInstance.setBarSpace(7) // 设置蜡烛宽度
-})
+        // 5. 加载数据并设置缩放
+        chartInstance.applyNewData(generateData())
+        if (chartInstance.setDataSpace) {
+        chartInstance.setDataSpace(7)
+      }
+        // chartInstance.setBarSpace(7) // 设置蜡烛宽度
+      })
 
-onUnmounted(() => {
-  if (chartInstance) {
-    klinecharts.dispose('k-line-chart')
-  }
-})
+      onUnmounted(() => {
+        if (chartInstance) {
+          klinecharts.dispose('k-line-chart')
+        }
+      })
 </script>
 
 <style scoped>
@@ -231,7 +231,7 @@ onUnmounted(() => {
   /* 防止横向滚动条 */
   overflow-x: hidden;
   margin-bottom: 80px;
-  padding-top: 65px;
+  padding-top: 50px;
 }
 
 /* 🔥🔥 核心修改:定义一个公共的左右内边距

+ 1 - 1
src/views/bitcoin/lever/TradeOptions.vue

@@ -179,7 +179,7 @@ onUnmounted(() => {
   font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Roboto, Arial, sans-serif;
   color: #333;
   /* 防止横向滚动条 */
-  padding-top: 65px;
+  padding-top: 50px;
   overflow-x: hidden;
 }
 

+ 16 - 7
src/views/bitcoin/lever/TradeSeconds.vue

@@ -3,7 +3,7 @@
     <header class="header">
       <div class="left" style="display: flex; align-items: center;">
         <img class="fc333333" src="@/assets/icon/bitcoin/menu.svg" alt="">
-        <h1 class="title">BTCUSDT</h1>
+        <h1 class="title">{{symbolTitle}}</h1>
       </div>
       <div class="right">
         <img src="@/assets/icon/bitcoin/den.svg" alt="" @click="showFunctions = true">
@@ -21,7 +21,8 @@
       </div>
 
       <div class="stat-grid">
-        <div class="stat-item">
+        <div>
+          <div class="stat-item">
           <span class="label">24h 最高价</span>
           <span class="value">78,776.76</span>
         </div>
@@ -29,7 +30,9 @@
           <span class="label">24h 成交量 (BTC)</span>
           <span class="value">78,776.76</span>
         </div>
-        <div class="stat-item">
+        </div>
+        <div>
+          <div class="stat-item">
           <span class="label">24h 最低价</span>
           <span class="value">78,776.76</span>
         </div>
@@ -37,6 +40,8 @@
           <span class="label">24h 成交额 (BTC)</span>
           <span class="value">78,776.76</span>
         </div>
+        </div>
+
       </div>
     </section>
 
@@ -66,13 +71,15 @@
 </template>
 
 <script setup>
-import { onMounted, onUnmounted, ref } from 'vue'
+import { onMounted, onUnmounted, ref , watch} from 'vue'
+import { useRoute } from 'vue-router' // 1. 引入 useRoute
 // ✅ 使用 namespace 引入,防止报错
 import * as klinecharts from 'klinecharts'
 import MarketPriceAndPlan from'./components/MarketPriceAndPlan.vue'
 import ChooseThisCycle from'./components/ChooseThisCycle.vue'
 import sellOrder from '@/views/bitcoin/components/sellOrder.vue';
-
+const route = useRoute()
+const symbolTitle = ref(route.params.id || 'BTCUSDT')
 
 // --- 状态管理 ---
 const currentTab = ref('24h')
@@ -230,7 +237,7 @@ onUnmounted(() => {
   font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Roboto, Arial, sans-serif;
   color: #333;
   /* 防止横向滚动条 */
-  padding-top: 65px;
+  padding-top: 50px;
   overflow-x: hidden;
 }
 
@@ -293,10 +300,12 @@ onUnmounted(() => {
 .sub-info .percent.up {
   color: #2EBD85;
 }
-
 /* 统计网格 */
 .stat-grid {
+  display: flex;
+  flex-direction: row;
   text-align: right;
+  gap: 5px;
 
 }
 .stat-item {

+ 138 - 0
src/views/bitcoin/lever/components/ExplanationModal.vue

@@ -0,0 +1,138 @@
+<template>
+  <Teleport to="body">
+    <!-- 1. 遮罩层 (点击关闭) -->
+    <transition name="fade">
+      <div
+        class="modal-mask"
+        v-if="visible"
+        @click="close"
+      ></div>
+    </transition>
+
+    <!-- 2. 弹窗面板 (底部滑出) -->
+    <transition name="slide-up">
+      <div class="modal-panel" v-if="visible">
+        <!-- 顶部小灰条 (Handle) -->
+        <div class="panel-handle-bar"></div>
+
+        <!-- 内容区域 (可滚动) -->
+        <div class="panel-content">
+          <div class="info-item" v-for="(item, index) in infoList" :key="index">
+            <h3 class="item-title">{{ item.title }}</h3>
+            <p class="item-desc">{{ item.desc }}</p>
+            <p v-if="item.subDesc" class="item-desc">{{ item.subDesc }}</p>
+          </div>
+        </div>
+
+        <!-- 底部安全区 (适配 iPhone X 等) -->
+        <div class="safe-area-bottom"></div>
+      </div>
+    </transition>
+  </Teleport>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+
+// 接收父组件传来的 visible 状态
+const props = defineProps({
+  visible: {
+    type: Boolean,
+    default: false
+  }
+});
+
+const emit = defineEmits(['update:visible']);
+
+// 关闭弹窗
+const close = () => {
+  emit('update:visible', false);
+};
+
+// 静态文案数据 (完全还原截图)
+const infoList = [
+  {
+    title: '账户总权益',
+    desc: '期权账户名目资产总额。',
+    subDesc: '账户总权益=保证金余额+期权市值'
+  },
+  {
+    title: '每日盈亏',
+    desc: '每日盈亏=日终账户总权益-初始账户总权益-每日' // 截图文字似乎截断了,这里照抄
+  },
+  {
+    title: '累计盈亏',
+    desc: '累计盈亏=期间每日盈亏加总'
+  },
+  {
+    title: '累计盈亏率%',
+    desc: '累计盈亏率=累计盈亏/期间保证金余额',
+    subDesc: '期间保证金余额=初始保证金余额+期间累计转入金'
+  },
+  {
+    title: '净划入',
+    desc: '每日净划转=总划入-总划出'
+  }
+];
+</script>
+
+<style scoped>
+/* --- 遮罩层样式 --- */
+.modal-mask {
+  position: fixed; top: 0; left: 0; right: 0; bottom: 0;
+  background: rgba(0, 0, 0, 0.4); /* 半透明黑底 */
+  z-index: 998;
+}
+
+/* --- 面板样式 --- */
+.modal-panel {
+  position: fixed; left: 0; right: 0; bottom: 0;
+  background: #fff;
+  z-index: 999;
+  border-radius: 16px 16px 0 0; /* 顶部圆角 */
+  max-height: 80vh; /* 最大高度占屏幕80% */
+  display: flex; flex-direction: column;
+}
+
+/* 顶部灰色小把手 */
+.panel-handle-bar {
+  width: 36px; height: 4px;
+  background: #E0E0E0;
+  border-radius: 2px;
+  margin: 10px auto; /* 居中 */
+  flex-shrink: 0;
+}
+
+/* 内容区 */
+.panel-content {
+  padding: 10px 20px 30px;
+  overflow-y: auto; /* 内容过长可滚动 */
+}
+
+.info-item {
+  margin-bottom: 24px;
+}
+.item-title {
+  font-size: 16px; font-weight: 600; color: #333;
+  margin-bottom: 8px;
+}
+.item-desc {
+  font-size: 14px; color: #666; line-height: 1.5;
+  margin-bottom: 4px; text-align: justify;
+}
+
+/* 底部安全区 */
+.safe-area-bottom {
+  height: env(safe-area-inset-bottom);
+  flex-shrink: 0;
+}
+
+/* --- 动画效果 --- */
+/* 遮罩渐隐渐现 */
+.fade-enter-active, .fade-leave-active { transition: opacity 0.3s; }
+.fade-enter-from, .fade-leave-to { opacity: 0; }
+
+/* 面板从底部滑出 */
+.slide-up-enter-active, .slide-up-leave-active { transition: transform 0.3s ease-out; }
+.slide-up-enter-from, .slide-up-leave-to { transform: translateY(100%); }
+</style>

+ 2 - 2
src/views/bitcoin/lever/components/MarketPriceAndPlan.vue

@@ -351,8 +351,8 @@ const sliderStyle = computed(() => {
   left: 0;
   width: 100vw;
   height: 100vh;
-  background-color: rgba(0, 0, 0, 0.4);
-  z-index: 999;
+  background-color: rgba(0, 0, 0, 0.6);
+  z-index: 1009;
   display: flex;
   flex-direction: column;
   justify-content: flex-end;

+ 1 - 1
src/views/bitcoin/lever/components/sellOrder1.vue

@@ -46,7 +46,7 @@
 
     // 当前选中的 Tab,默认选中 index 1 (当前委托)
     const currentTab = ref(0);
-    const tabs = ['持有仓位(0)', '当前委托(2)'];
+    const tabs = ['持有仓位(2)', '当前委托(2)'];
 
     // 按钮操作
     const handleCancel = (id) => {

+ 2 - 1
src/views/market/Index.vue

@@ -60,9 +60,10 @@
         flex-direction: row;
         justify-content: flex-start;
         align-items: flex-end;
-        width: 349px;
+        width: 345px;
         height: 24px;
 
+
         .sys-notifi {
           margin-left: 35px;
         }

+ 122 - 0
src/views/user/AboutUs.vue

@@ -0,0 +1,122 @@
+<template>
+  <div class="page-container">
+    <div class="nav-bar">
+      <div class="nav-left" @click="$router.back()">
+        <van-icon size="20" name="arrow-left"></van-icon>      </div>
+      <div class="nav-title">关于我们</div>
+      <div class="nav-right"></div>
+    </div>
+
+    <div class="logo-section">
+      <div class="app-logo">LOGO</div>
+      <h1 class="app-name">BitWiseWorld</h1>
+    </div>
+
+    <div class="menu-list">
+      <div class="menu-item">
+        <span class="item-label">版本更新</span>
+        <span class="item-value">当前已是最高版本</span>
+      </div>
+
+      <div class="menu-item is-link" @click="goTo('UserAgreement')">
+        <span class="item-label">用户协议</span>
+        <div class="item-right">
+          <svg viewBox="0 0 1024 1024" width="14" height="14"><path d="M340.864 149.312a29.12 29.12 0 0 1 41.728 0L737.28 504.256a29.12 29.12 0 0 1 0 41.728L382.592 900.928a29.12 29.12 0 0 1-41.728 0 29.12 29.12 0 0 1 0-41.728L674.688 525.12 340.864 191.04a29.12 29.12 0 0 1 0-41.728z" fill="#999"/></svg>
+        </div>
+      </div>
+
+      <div class="menu-item is-link" @click="goTo('PrivacyPolicy')">
+        <span class="item-label">隐私政策</span>
+        <div class="item-right">
+          <svg viewBox="0 0 1024 1024" width="14" height="14"><path d="M340.864 149.312a29.12 29.12 0 0 1 41.728 0L737.28 504.256a29.12 29.12 0 0 1 0 41.728L382.592 900.928a29.12 29.12 0 0 1-41.728 0 29.12 29.12 0 0 1 0-41.728L674.688 525.12 340.864 191.04a29.12 29.12 0 0 1 0-41.728z" fill="#999"/></svg>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useRouter } from 'vue-router';
+const router = useRouter();
+
+const goTo = (routeName) => {
+  router.push({ name: routeName });
+};
+</script>
+
+<style scoped>
+.page-container {
+  min-height: 100vh;
+  background: #fff;
+  color: #333;
+}
+
+/* 导航栏 */
+.nav-bar {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  height: 44px;
+  padding: 0 16px;
+  position: sticky;
+  top: 0;
+  background: #fff;
+}
+.nav-title { font-size: 18px; font-weight: 600; }
+.nav-left, .nav-right { width: 40px; }
+
+/* Logo 区域 */
+.logo-section {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 60px 0 40px;
+}
+.app-logo {
+  width: 80px;
+  height: 80px;
+  background-color: #DE3545; /* 提取自图片的红色 */
+  color: #fff;
+  border-radius: 18px;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  font-size: 18px;
+  font-weight: 500;
+  margin-bottom: 20px;
+  box-shadow: 0 4px 10px rgba(222, 53, 69, 0.2);
+}
+.app-name {
+  font-size: 24px;
+  font-weight: 800; /* 这里的字体非常粗 */
+  color: #333;
+  letter-spacing: 0.5px;
+}
+
+/* 列表区域 */
+.menu-list {
+  padding: 0 20px;
+  margin-top: 30px;
+}
+.menu-item {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  height: 56px;
+  font-size: 14px;
+}
+.menu-item.is-link:active {
+  opacity: 0.6; /* 点击反馈 */
+}
+.item-label {
+  color: #333;
+}
+.item-value {
+  color: #999;
+  font-size: 12px;
+}
+.item-right {
+  display: flex;
+  align-items: center;
+}
+</style>

+ 115 - 0
src/views/user/AddressAuth.vue

@@ -0,0 +1,115 @@
+<template>
+  <div class="page-container">
+    <van-nav-bar
+      :title="$t('auth.advanced')"
+      left-arrow
+      fixed
+      placeholder
+      @click-left="router.back()"
+      class="custom-nav-bar"
+    />
+
+    <div class="form-content">
+      <h3 class="form-label">{{ pageTitle }}</h3>
+
+      <van-field
+        v-model="form.area"
+        is-link
+        readonly
+        :placeholder="$t('auth.pleaseSelect')"
+        class="grey-input-field"
+        @click="showAreaPicker = true"
+      />
+
+      <!-- 已修正 Key -->
+      <h3 class="form-label">{{ $t('auth.detail') }}</h3>
+
+      <van-field
+        v-model="form.detail"
+        rows="4"
+        autosize
+        type="textarea"
+        :placeholder="$t('auth.detailPlaceholder')"
+        class="grey-input-field textarea-field"
+      />
+    </div>
+
+    <div class="submit-bar">
+      <van-button type="danger" block round @click="onSubmit">
+        {{ $t('common.confirm') }}
+      </van-button>
+    </div>
+
+    <van-popup v-model:show="showAreaPicker" round position="bottom">
+      <van-picker
+        :title="$t('auth.area')"
+        :columns="areaColumns"
+        @confirm="onAreaConfirm"
+        @cancel="showAreaPicker = false"
+        :confirm-button-text="$t('common.confirm')"
+        :cancel-button-text="$t('common.cancel')"
+      />
+    </van-popup>
+  </div>
+</template>
+
+<script setup>
+import { ref, computed, reactive } from 'vue';
+import { useRouter, useRoute } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+
+const router = useRouter();
+const route = useRoute();
+const { t, locale } = useI18n();
+
+const pageType = route.query.type;
+
+const pageTitle = computed(() => {
+  const _ignore = locale.value; // 强制依赖
+  // console.log(_ignore,'lll')
+  if (pageType === 'work') return t('home.workAddr');
+  return t('auth.area');
+});
+
+const form = reactive({ area: '', detail: '' });
+const showAreaPicker = ref(false);
+
+const areaColumns = [
+  { text: 'Beijing', value: '110000' },
+  { text: 'Shanghai', value: '310000' },
+  { text: 'Shenzhen', value: '440300' },
+];
+
+const onAreaConfirm = ({ selectedOptions }) => {
+  form.area = selectedOptions.map(option => option.text).join('');
+  showAreaPicker.value = false;
+};
+
+const onSubmit = () => {
+  console.log('Submit:', form);
+  router.back();
+};
+</script>
+
+<style scoped lang="less">
+/* --- 重点修改:自定义导航栏样式 --- */
+:deep(.custom-nav-bar) {
+  /* 修改图标(返回箭头)颜色为黑色 */
+  --van-nav-bar-icon-color: #323233;
+  /* 修改标题颜色为黑色,保持一致 */
+  --van-nav-bar-title-text-color: #323233;
+  /* 如果有左侧文字,也改为黑色 */
+  --van-nav-bar-text-color: #323233;
+   --van-nav-bar-arrow-size: 19px;
+}
+.page-container { min-height: 100vh; background-color: #fff; display: flex; flex-direction: column; }
+.form-content { flex: 1; padding: 10px 16px; }
+.form-label { font-size: 15px; font-weight: bold; color: #323233; margin-bottom: 10px; margin-top: 20px; }
+:deep(.van-cell.grey-input-field) {
+  background-color: #f7f8fa; border-radius: 8px; padding: 12px 16px;
+  &::after { display: none; }
+  .van-field__control { font-size: 15px; color: #323233; &::placeholder { color: #969799; } }
+}
+.textarea-field { min-height: 100px; }
+.submit-bar { padding: 20px 16px 40px; background-color: #fff; }
+</style>

+ 397 - 0
src/views/user/AdvancedCertification.vue

@@ -0,0 +1,397 @@
+<template>
+  <div class="page-container">
+    <header class="nav-bar sticky-header">
+      <div class="left" @click="$router.back()">
+        <div>
+          <VanIcon size="19" name="arrow-left"/>
+        </div>
+      </div>
+      <div class="title">认证中心</div>
+      <div class="right"></div>
+    </header>
+
+    <div class="main-header">
+      <h1 class="page-title fs18">身份认证</h1>
+      <p class="subtitle">在平台上进行购买和交易前请先进行身份认证</p>
+    </div>
+
+    <div class="tabs">
+      <div
+        class="tab-item"
+        :class="{ active: currentTab === 'basic' }"
+        @click="currentTab = 'basic'"
+      >
+        基础认证
+        <div class="active-line" v-if="currentTab === 'basic'"></div>
+      </div>
+
+      <div
+        class="tab-item"
+        :class="{ active: currentTab === 'advanced' }"
+        @click="currentTab = 'advanced'"
+      >
+        高级认证
+        <div class="active-line" v-if="currentTab === 'advanced'"></div>
+      </div>
+    </div>
+
+    <div class="scroll-content">
+      <div class="auth-card">
+        <div class="card-title">认证要求</div>
+
+        <div
+          class="card-row"
+          v-for="(item, index) in currentRequirements"
+          :key="index"
+        >
+          <span class="label">{{ item.label }}</span>
+          <span class="tag" :class="item.status === 'done' ? 'gray' : 'red'">
+            {{ item.status === 'done' ? '已认证' : '尚未认证' }}
+          </span>
+        </div>
+
+        <button class="btn-verify" @click="handleVerifyClick">立即认证</button>
+      </div>
+
+      <div class="features-section">
+        <div class="section-title">功能与限制</div>
+        <div v-for="(item, index) in permissions" :key="index" class="feature-item">
+          <div class="f-label" :class="{ 'red-text': item.isHighlight }">{{ item.label }}</div>
+          <div class="f-value" :class="{ 'light': item.desc }">{{ item.value || item.desc }}</div>
+        </div>
+      </div>
+
+      <div class="footer-action">
+        <button class="btn-footer" @click="showModal = true">查看当前拥有的权限</button>
+      </div>
+    </div>
+
+    <div class="overlay" v-if="showModal" @click="showModal = false"></div>
+
+    <div class="bottom-sheet" :class="{ 'is-open': showModal }">
+      <div class="sheet-handle"></div>
+      <div class="sheet-title">您当前拥有的权限</div>
+
+      <div class="sheet-content">
+        <div v-for="(item, index) in permissions" :key="index" class="feature-item">
+          <div class="f-label" :class="{ 'red-text': item.isHighlight }">{{ item.label }}</div>
+          <div class="f-value" :class="{ 'light': item.desc }">{{ item.value || item.desc }}</div>
+        </div>
+      </div>
+    </div>
+    <div class="vantpo">
+      <VanPopup
+      v-model:show="showPopup"
+      position="bottom"
+      round
+      :style="{ height: '70%', padding: '20px' }"
+    >
+      <div class="handle-bar"></div>
+
+      <div class="auth-list">
+        <div class="auth-card disabled">
+          <span class="label">家庭地址</span>
+          <span class="status-btn gray">已认证</span>
+        </div>
+
+        <div class="auth-card active" @click="goToAddress('work')">
+          <span class="label">工作地址</span>
+          <span class="status-btn red">立即认证</span>
+        </div>
+
+        <div class="auth-card" @click="goToRelative">
+          <span class="label">亲属联系方式</span>
+          <span class="status-btn red">立即认证</span>
+        </div>
+      </div>
+    </VanPopup>
+    </div>
+  </div>
+
+</template>
+
+<script setup>
+import { ref, computed } from 'vue';
+import { useRouter } from 'vue-router';
+import {Icon as VanIcon, Popup as VanPopup } from "vant";
+
+const router = useRouter();
+const handleVerifyClick = () => {
+  // 跳转到刚刚写好的新页面
+      if (currentTab.value === 'basic') {
+        router.push({name: 'BasicVerify'}); // 确保路由里配了这个 name
+        // 或者 router.push('/basic-verify');
+      }else{
+        showPopup.value = true
+      }
+}
+//高级认证
+const showPopup = ref(false);
+
+// 跳转到地址认证,传递类型
+const goToAddress = (type) => {
+  showPopup.value = false;
+  router.push({
+    path: '/auth/address',
+    query: { type: type } // 传参:work 或 home
+  });
+};
+
+// 跳转到亲属认证
+const goToRelative = () => {
+  showPopup.value = false;
+  router.push('/auth/relative');
+};
+
+// --- 状态管理 ---
+const currentTab = ref('basic'); // 当前选中的 Tab: 'basic' 或 'advanced'
+const showModal = ref(false);    // 控制弹框显示
+
+// --- 数据源:认证要求 ---
+const requirementsData = {
+  // 基础认证数据 (图1)
+  basic: [
+    { label: '个人信息', status: 'done' }, // done: 已认证
+    { label: '政府发行身份证', status: 'undone' } // undone: 尚未认证
+  ],
+  // 高级认证数据 (图2)
+  advanced: [
+    { label: '家庭地址', status: 'done' },
+    { label: '工作地址', status: 'undone' },
+    { label: '亲属联系方式', status: 'undone' }
+  ]
+};
+
+// 计算属性:根据当前 Tab 返回对应的数据
+const currentRequirements = computed(() => {
+  return requirementsData[currentTab.value];
+});
+
+// --- 数据源:权限列表 (页面和弹框共用) ---
+const permissions = [
+  { label: '每日充值', value: '无限额', isHighlight: false },
+  { label: '8M USDT 每日', desc: '数字货币提现限额', isHighlight: true }, // Highlight 变红
+  { label: 'C2C交易限额', value: '无限额', isHighlight: false },
+  { label: '其他功能', value: '无限额', isHighlight: false },
+];
+</script>
+
+<style lang="less" scoped>
+/* --- 布局容器 (基于 375px) --- */
+.page-container {
+  width: 100%;
+  max-width: 375px;
+  min-height: 100vh;
+  margin: 0 auto;
+  background-color: #fff;
+  padding: 0 16px 40px 16px; /* 底部留白给按钮 */
+  box-sizing: border-box;
+  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", sans-serif;
+  /*overflow-x: hidden;*/
+  position: relative;
+  /*overflow:auto;*/
+}
+
+/* 给包裹层设置固定定位 */
+.sticky-header {
+  position: sticky;
+  top: 0;
+  z-index: 100;
+  background-color: #fff; /* 统一背景色 */
+  /* 稍微加点 padding 保持美观 */
+  padding-bottom: 5px;
+}
+/* --- 导航栏 --- */
+.nav-bar {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  height: 44px;
+  margin-bottom: 10px;
+}
+.title { font-size: 18px; font-weight: 600; }
+.back-arrow { font-size: 20px; cursor: pointer; color: #333; }
+
+/* --- 大标题 --- */
+.main-header { margin-bottom: 20px; }
+.page-title { font-size: 18px; font-weight: 700; margin: 0 0 8px 0; color: #111; }
+.subtitle { font-size: 13px; color: #999; line-height: 1.4; }
+
+/* --- Tabs 切换样式 (关键) --- */
+.tabs {
+  display: flex;
+  margin-bottom: 20px;
+  border-bottom: 1px solid transparent; /* 预留位置 */
+  /* 关键:使用 baseline 让大小不同的文字底部对齐,不然会上下乱跳 */
+  align-items: flex-end;
+  gap: 20px;
+  height: 28px;
+}
+.tab-item {
+  position: relative;
+  cursor: pointer;
+  color: #C2C2C2; /* 默认灰色 (未选中) */
+  padding-bottom: 6px;
+  line-height: 1;
+
+  /* 1. 默认状态 (未选中):字号较小,颜色较淡 */
+  font-size: 16px;
+  font-weight: 500;
+  /* 2. 加上过渡动画,让忽大忽小的过程很丝滑 */
+  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
+}
+.tab-item.active {
+  /* 3. 选中状态:字号变大,颜色变黑,加粗 */
+  font-size: 20px;
+  font-weight: 700;
+  color: #111;
+}
+.active-line {
+  position: absolute;
+  /* 因为上面的 line-height: 1 和 flex-end 稳住了底部 */
+  /* 这里的 bottom 定位就会非常稳定 */
+  bottom: -4px; /* 可以稍微调一下距离 */
+  left: 50%;
+  transform: translateX(-50%);
+  width: 20px; /* 稍微改回 20px 显得精致点,或者按你喜好保持 24 */
+  height: 3px;
+  background-color: #111;
+  border-radius: 2px;
+}
+
+/* --- 认证卡片 --- */
+.auth-card {
+  border: 1px solid #eee;
+  border-radius: 12px;
+  padding: 16px;
+  box-shadow: 0 2px 10px rgba(0,0,0,0.02);
+  margin-bottom: 30px;
+}
+.card-title { font-size: 14px; color: #333; margin-bottom: 16px; font-weight: 500; }
+.card-row {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
+.label { font-size: 15px; color: #666; }
+
+/* Tag 样式 */
+.tag {
+  font-size: 12px;
+  padding: 4px 8px;
+  border-radius: 4px;
+}
+.tag.gray { background-color: #A6A6A6; color: #fff; }
+.tag.red { background-color: #EA3F54; color: #fff; }
+
+.btn-verify {
+  width: 100%;
+  height: 44px;
+  background-color: #EA3F54; /* 红色按钮 */
+  color: white;
+  border: none;
+  border-radius: 22px;
+  font-size: 15px;
+  font-weight: 500;
+  margin-top: 5px;
+}
+
+/* --- 功能列表 (通用样式) --- */
+.section-title { font-size: 15px; color: #333; margin-bottom: 20px; font-weight: 500; }
+.feature-item { margin-bottom: 20px; }
+.f-label { font-size: 15px; color: #333; margin-bottom: 4px; font-weight: 500; }
+.f-label.red-text { color: #EA3F54; }
+.f-value { font-size: 14px; color: #999; }
+.f-value.light { color: #999; }
+
+/* --- 底部按钮 --- */
+.footer-action { margin-top: 30px; text-align: center; }
+.btn-footer {
+  width: 100%;
+  height: 46px;
+  background-color: #EA3F54;
+  color: white;
+  border: none;
+  border-radius: 23px;
+  font-size: 15px;
+  font-weight: 500;
+}
+
+/* ================= 弹框 CSS 动画 ================= */
+.overlay {
+  position: fixed; top: 0; left: 0;
+  width: 100vw; height: 100vh;
+  background-color: rgba(0, 0, 0, 0.4);
+  z-index: 998;
+  animation: fade 0.3s;
+}
+
+.bottom-sheet {
+  position: fixed; bottom: 0; left: 50%;
+  width: 100%; max-width: 375px;
+  transform: translateX(-50%) translateY(100%); /* 默认隐藏 */
+  background-color: #fff;
+  border-top-left-radius: 16px;
+  border-top-right-radius: 16px;
+  padding: 10px 20px 40px 20px;
+  box-sizing: border-box;
+  z-index: 999;
+  transition: transform 0.3s cubic-bezier(0.2, 0.8, 0.2, 1); /* 丝滑缓动 */
+}
+
+.bottom-sheet.is-open {
+  transform: translateX(-50%) translateY(0);
+}
+
+.sheet-handle {
+  width: 36px; height: 4px;
+  background-color: #E0E0E0;
+  border-radius: 2px;
+  margin: 0 auto 20px auto;
+}
+.sheet-title { font-size: 18px; font-weight: 600; color: #111; margin-bottom: 30px; }
+
+@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
+.vantpo{
+.handle-bar { width: 40px; height: 4px; background: #ddd;
+    border-radius: 2px; margin: 0 auto 20px; }
+
+.auth-list { display: flex; flex-direction: column; gap: 15px; }
+
+/* 卡片基础样式 */
+.auth-card {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding: 20px;
+  border: 1px solid #ebedf0;
+  border-radius: 12px;
+  font-size: 16px;
+  font-weight: bold;
+}
+
+/* 红色高亮状态 (对应图1中间那个) */
+.auth-card.active {
+  border-color: #ee0a24;
+  color: #ee0a24;
+}
+
+/* 已认证/禁用状态 */
+.auth-card.disabled {
+  background-color: #f7f8fa;
+  color: #333;
+}
+
+/* 按钮样式模拟 */
+.status-btn {
+  padding: 6px 12px;
+  border-radius: 4px;
+  font-size: 12px;
+  font-weight: normal;
+  color: white;
+}
+.status-btn.gray { background-color: #969799; }
+.status-btn.red { background-color: #ee0a24; }
+}
+</style>

+ 260 - 0
src/views/user/BasicVerify.vue

@@ -0,0 +1,260 @@
+<template>
+  <div class="page-container">
+    <header class="nav-bar sticky-nav">
+      <div class="left" @click="$router.back()">
+        <div>
+          <VanIcon size="19" name="arrow-left"/>
+        </div>
+      </div>
+      <div class="title">基础认证</div>
+      <div class="right"></div>
+    </header>
+
+    <div class="form-content">
+
+      <div class="form-row-double">
+        <div class="form-col">
+          <label>法定名</label>
+          <input type="text" placeholder="名" v-model="form.firstName" />
+        </div>
+        <div class="form-col">
+          <label>法定姓</label>
+          <input type="text" placeholder="姓" v-model="form.lastName" />
+        </div>
+      </div>
+
+      <div class="form-item">
+        <label>证件类型</label>
+        <div class="input-box select-mode">
+          <span>{{ form.idType || '身份证' }}</span>
+          <div>
+          <VanIcon size="15" name="arrow-down"/>
+        </div>
+<!--          <span class="arrow">▼</span>-->
+        </div>
+      </div>
+
+      <div class="form-item">
+        <label>证件号码</label>
+        <input type="text" placeholder="请输入证件号码" v-model="form.idNumber" />
+      </div>
+
+      <div class="form-item">
+        <label>所在地区</label>
+        <div class="input-box select-mode">
+          <span :class="{ placeholder: !form.region }">{{ form.region || '请选择' }}</span>
+          <VanIcon size="15" name="arrow-down"/>
+        </div>
+      </div>
+
+      <div class="form-item">
+        <label>详细地址</label>
+        <textarea
+          placeholder="请输入"
+          v-model="form.address"
+          rows="3"
+        ></textarea>
+      </div>
+
+      <div class="upload-section">
+        <h3 class="section-title">上传证件照</h3>
+        <p class="section-desc">确保件照清晰可见</p>
+
+        <div class="upload-card">
+          <div class="card-content">
+            <p class="card-tip">确保件照清晰可见</p>
+            <h4 class="card-title">身份证人像面</h4>
+            <div class="upload-btn">
+              上传 <span class="upload-icon">↑</span>
+            </div>
+          </div>
+        </div>
+
+        <div class="upload-card">
+          <div class="card-content">
+            <p class="card-tip">确保件照清晰可见</p>
+            <h4 class="card-title">身份证国徽面</h4>
+            <div class="upload-btn">
+              上传 <span class="upload-icon">↑</span>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <div class="footer-note">
+        <p>支持小于8M的JPG、JPEG或PNG格式的图片</p>
+        <p>上传您身份证件的完整照片,</p>
+        <p>请确保上传图片中的所有细节都清晰可见</p>
+        <p>请确保证件为原件并在有效期内</p>
+        <p>请将证件置于纯色背景下</p>
+      </div>
+
+    </div>
+
+    <div class="bottom-action">
+      <button class="btn-submit" @click="handleSubmit">提交</button>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { reactive } from 'vue';
+import { useRouter } from 'vue-router';
+import {Icon as VanIcon } from "vant";
+
+const router = useRouter();
+
+const form = reactive({
+  firstName: '',
+  lastName: '',
+  idType: '身份证',
+  idNumber: '',
+  region: '',
+  address: ''
+});
+
+const handleSubmit = () => {
+  console.log('提交表单', form);
+  // 这里写提交逻辑
+  // router.push('/success');
+};
+</script>
+
+<style scoped>
+/* 全局容器 */
+.page-container {
+  width: 100%;
+  max-width: 375px;
+  min-height: 100vh;
+  margin: 0 auto;
+  background-color: #fff;
+  padding-bottom: 80px; /* 给底部按钮留位置 */
+  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", sans-serif;
+}
+
+/* 导航栏 */
+.nav-bar {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  height: 44px;
+  padding: 0 16px;
+  background: #fff;
+  border-bottom: 1px solid #f5f5f5;
+}
+.sticky-nav { position: sticky; top: 0; z-index: 100; }
+.title { font-size: 17px; font-weight: 600; color: #333; }
+.icon-back { font-size: 20px; color: #333; cursor: pointer; }
+.right { width: 20px; }
+
+/* 表单内容区 */
+.form-content {
+  padding: 20px 16px;
+}
+
+/* 通用 Input 样式 */
+input, textarea, .input-box {
+  width: 100%;
+  background-color: #F7F8FA; /* 极淡的灰色背景 */
+  border: none;
+  border-radius: 4px;
+  padding: 12px;
+  font-size: 14px;
+  color: #333;
+  box-sizing: border-box;
+  outline: none;
+}
+textarea { resize: none; }
+input::placeholder, textarea::placeholder { color: #C2C2C2; }
+
+/* Label 样式 */
+label {
+  display: block;
+  font-size: 14px;
+  color: #333;
+  margin-bottom: 8px;
+  font-weight: 500;
+}
+
+/* 姓名左右分栏 */
+.form-row-double {
+  display: flex;
+  gap: 15px;
+  margin-bottom: 20px;
+}
+.form-col { flex: 1; }
+
+/* 单个表单项 */
+.form-item { margin-bottom: 20px; }
+
+/* 模拟 Select 下拉框 */
+.input-box.select-mode {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+.arrow { font-size: 12px; color: #999; transform: scale(0.8); }
+.placeholder { color: #C2C2C2; }
+
+/* 上传区域 */
+.upload-section { margin-top: 30px; margin-bottom: 20px; }
+.section-title { font-size: 16px; font-weight: 600; margin-bottom: 4px; }
+.section-desc { font-size: 12px; color: #999; margin-bottom: 16px; }
+
+.upload-card {
+  background-color: #F7F8FA;
+  border-radius: 8px;
+  height: 160px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-bottom: 16px;
+  text-align: center;
+}
+.card-tip { font-size: 12px; color: #999; margin-bottom: 6px; }
+.card-title { font-size: 16px; font-weight: 600; color: #333; margin: 0 0 16px 0; }
+
+/* 上传按钮 */
+.upload-btn {
+  display: inline-flex;
+  align-items: center;
+  justify-content: center;
+  background-color: #EA3F54;
+  color: #fff;
+  padding: 8px 24px;
+  border-radius: 20px;
+  font-size: 14px;
+  font-weight: 500;
+}
+.upload-icon { margin-left: 4px; font-weight: bold; }
+
+/* 底部说明 */
+.footer-note {
+  font-size: 12px;
+  color: #999;
+  line-height: 1.6;
+  margin-bottom: 20px;
+}
+
+/* 底部固定按钮 */
+.bottom-action {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  padding: 10px 16px 20px 16px;
+  background-color: #fff;
+  box-sizing: border-box;
+  box-shadow: 0 -2px 10px rgba(0,0,0,0.03);
+}
+.btn-submit {
+  width: 100%;
+  height: 44px;
+  background-color: #EA3F54;
+  color: #fff;
+  border: none;
+  border-radius: 22px;
+  font-size: 16px;
+  font-weight: 600;
+}
+</style>

+ 164 - 0
src/views/user/HelpCenter.vue

@@ -0,0 +1,164 @@
+<template>
+  <div class="help-center-page">
+    <div class="nav-bar">
+      <div class="nav-left" @click="goBack">
+        <van-icon size="20" name="arrow-left"></van-icon>
+      </div>
+      <div class="nav-title">帮助中心</div>
+      <div class="nav-right"></div>
+    </div>
+
+    <div class="content">
+
+      <div class="section" v-for="(section, index) in listData" :key="index">
+        <h2 class="section-title">{{ section.title }}</h2>
+
+        <div class="card-list">
+          <div
+            class="list-item"
+            v-for="(item, idx) in section.items"
+            :key="idx"
+            @click="handleJump(item)"
+          >
+            <div class="item-icon">
+              <svg viewBox="0 0 1024 1024" width="12" height="12">
+                 <path d="M340.864 149.312a29.12 29.12 0 0 1 41.728 0L737.28 504.256a29.12 29.12 0 0 1 0 41.728L382.592 900.928a29.12 29.12 0 0 1-41.728 0 29.12 29.12 0 0 1 0-41.728L674.688 525.12 340.864 191.04a29.12 29.12 0 0 1 0-41.728z" fill="#666"/>
+              </svg>
+            </div>
+            <div class="item-text">{{ item.text }}</div>
+          </div>
+        </div>
+      </div>
+
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import { useRouter } from 'vue-router';
+
+const router = useRouter();
+
+// 模拟数据结构
+const listData = ref([
+  {
+    title: '常见问题',
+    items: [
+      { id: 1, text: '常见问题文字描述内容', link: '/help/detail' },
+      { id: 2, text: '常见问题文字描述内容常见问题文字描述内容常见问题文字描述内容', link: '/help/detail' },
+      { id: 3, text: '常见问题文字描述内容常见问题文字描述内容', link: '/help/detail' },
+      { id: 4, text: '常见问题文字描述内容常见问题文字描述内容常见问题文字描述内容', link: '/help/detail' },
+    ]
+  },
+  {
+    title: '交易指南',
+    items: [
+      { id: 5, text: '交易智能文字描述内容交易智能文字描述内容', link: '/trade/guide' },
+      { id: 6, text: '交易智能文字描述内容交易智能文字描述内容交易智能文字描述内容', link: '/trade/guide' },
+      { id: 7, text: '交易智能文字描述内容', link: '/trade/guide' },
+      { id: 8, text: '交易智能文字描述内容交易智能文字描述内容交易智能文字描述内容', link: '/trade/guide' }
+    ]
+  }
+]);
+
+// 返回上一页
+const goBack = () => {
+  router.back();
+};
+
+// 跳转详情页
+const handleJump = (item) => {
+  console.log('点击了:', item.text);
+
+  // 方式1:带参数跳转
+  router.push({
+    path: '/help/detail', // 请替换为你实际的路由地址
+    query: { id: item.id,title: item.text }
+  });
+
+  // 方式2:如果是动态路由 /help/:id
+  // router.push(`/help/${item.id}`);
+};
+</script>
+
+<style scoped>
+/* 基础容器 */
+.help-center-page {
+  width: 100%;
+  min-height: 100vh;
+  background-color: #fff;
+  font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'PingFang SC', 'miui', 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif;
+}
+
+/* 顶部导航栏样式 */
+.nav-bar {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: 44px; /* 移动端标准导航高度 */
+  padding: 0 16px;
+  background: #fff;
+  position: sticky;
+  top: 0;
+  z-index: 10;
+}
+
+.nav-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #000;
+}
+
+.nav-left, .nav-right {
+  width: 24px; /* 占位,保证标题居中 */
+  display: flex;
+  align-items: center;
+}
+
+/* 内容区域 */
+.content {
+  padding: 0 20px; /* 两侧留白 */
+}
+
+.section {
+  margin-top: 20px;
+}
+
+.section-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #333;
+  margin-bottom: 10px;
+}
+
+/* 列表项样式 */
+.list-item {
+  display: flex;
+  align-items: flex-start; /* 顶部对齐,防止多行文字导致图标居中 */
+  padding: 15px 0;
+  border-bottom: 1px solid #f0f0f0; /* 细分割线 */
+  cursor: pointer;
+}
+
+.list-item:active {
+  background-color: #f9f9f9; /* 点击反馈 */
+}
+
+/* 左侧小箭头图标 */
+.item-icon {
+  margin-right: 10px;
+  margin-top: 3px; /* 微调:让箭头跟第一行文字对齐 */
+  display: flex;
+  align-items: center;
+}
+
+/* 文字样式 */
+.item-text {
+  font-size: 14px;
+  color: #666;
+  line-height: 1.5; /* 增加行高,多行阅读更舒适 */
+  text-align: justify; /* 两端对齐,看起来更整齐 */
+  flex: 1; /* 占满剩余空间 */
+}
+</style>

+ 132 - 0
src/views/user/HelpDetail.vue

@@ -0,0 +1,132 @@
+<template>
+  <div class="detail-page">
+    <div class="nav-bar">
+      <div class="nav-left" @click="goBack">
+      <van-icon size="20" name="arrow-left"></van-icon>
+      </div>
+      <div class="nav-title">问题描述详情</div>
+      <div class="nav-right"></div>
+    </div>
+
+    <div class="article-content">
+
+      <h1 class="article-h1">Introduction</h1>
+
+      <p class="article-p">
+        The world of cryptocurrency can be both exciting and overwhelming for beginners. With high potential rewards come significant risks, but a well-thought-out strategy can help you navigate this volatile market with confidence. In this guide, we'll explore the top five crypto investment strategies to help you get started.
+      </p>
+
+      <div class="article-img-wrapper">
+        <img
+          src="https://images.unsplash.com/photo-1621416894569-0f39ed31d247?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80"
+          alt="Crypto Strategy"
+          class="article-img"
+        />
+      </div>
+
+      <h2 class="article-h2">Diversify Your Portfolio</h2>
+
+      <p class="article-p">
+        One of the cardinal rules of investing is diversification, and it applies equally to crypto. Putting all your money into one coin might seem tempting, especially if it's trending, but it exposes you to high risk. Here's how you can diversify effectively:
+      </p>
+
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useRouter, useRoute } from 'vue-router';
+import { onMounted } from 'vue';
+
+const router = useRouter();
+const route = useRoute(); // 用于获取参数,比如文章ID
+
+const goBack = () => {
+  router.back();
+};
+
+onMounted(() => {
+  // 实际开发中,这里可以根据 route.query.id 或 route.params.id 去请求后台接口获取文章内容
+  console.log('当前文章ID:', route.query.id);
+});
+</script>
+
+<style scoped>
+/* 页面容器 */
+.detail-page {
+  width: 100%;
+  min-height: 100vh;
+  background-color: #fff;
+  /* 防止刘海屏遮挡 */
+  padding-bottom: 40px;
+}
+
+/* 导航栏 (复用之前的样式,保持一致) */
+.nav-bar {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: 44px;
+  padding: 0 16px;
+  background: #fff;
+  position: sticky; /* 吸顶 */
+  top: 0;
+  z-index: 10;
+  border-bottom: 1px solid #f5f5f5; /* 详情页一般加个浅底边框区分 */
+}
+
+.nav-title {
+  font-size: 17px;
+  font-weight: 600;
+  color: #333;
+}
+.nav-left, .nav-right { width: 24px; display: flex; align-items: center;}
+
+/* 文章主体容器 */
+.article-content {
+  padding: 20px 20px; /* 375px 设计稿下,左右20px边距很舒服 */
+}
+
+/* 一级标题样式 */
+.article-h1 {
+  font-size: 20px; /* 略大一点 */
+  font-weight: 700;
+  color: #222; /* 接近纯黑 */
+  margin-bottom: 16px;
+  line-height: 1.4;
+}
+
+/* 二级标题样式 */
+.article-h2 {
+  font-size: 18px;
+  font-weight: 700;
+  color: #222;
+  margin-top: 30px; /* 标题上方留白多一点 */
+  margin-bottom: 12px;
+  line-height: 1.4;
+}
+
+/* 正文段落样式 - 核心还原点 */
+.article-p {
+  font-size: 15px; /* 移动端阅读标准字号 */
+  color: #555; /* 深灰色,不刺眼 */
+  line-height: 1.6; /* 黄金行高,易于阅读 */
+  text-align: justify; /* 两端对齐,英文排版必备,还原图示的整齐边缘 */
+  margin-bottom: 20px;
+}
+
+/* 图片容器 */
+.article-img-wrapper {
+  width: 100%;
+  margin: 20px 0;
+  border-radius: 8px; /* 圆角 */
+  overflow: hidden;
+  box-shadow: 0 4px 12px rgba(0,0,0,0.05); /* 轻微投影增加质感 */
+}
+
+.article-img {
+  width: 100%;
+  height: auto;
+  display: block; /* 消除img底部默认间隙 */
+}
+</style>

+ 276 - 21
src/views/user/Index.vue

@@ -1,26 +1,101 @@
 <template>
   <!-- 我的 -->
   <div class="user-index">
-    <div class="loan-info">
-      <div class="info-left">
-        <img src="../../assets/img/index/user/default-head.png" alt="" />
-        <div class="info-name" @click="deleteAccount">
-          <div class="name-area pf500 fs18 fc121212">
-            用户昵称
-            <div class="level pf500 fs10 fcDF384C">V2</div>
+    <!-- 导航栏 -->
+
+    <div class="content">
+      <div class="user-card">
+        <!-- 左侧信息保持不变 -->
+        <div class="card-left">
+          <div class="avatar-box">
+            <img :src="userInfo.avatar" alt="Avatar" class="avatar-img" />
+          </div>
+          <div class="info-box">
+            <div class="name-row">
+              <span class="user-name">{{ userInfo.nickname }}</span>
+              <span class="vip-badge">{{ userInfo.level }}</span>
+            </div>
+            <div class="user-id">ID: {{ userInfo.id }}</div>
+          </div>
+        </div>
+
+        <!-- 右侧:动态信用分仪表盘 -->
+        <div class="card-right">
+          <div class="score-chart">
+            <svg viewBox="0 0 100 100" class="chart-svg">
+              <!--
+                第一层:灰色底轨 (Background Segments)
+                遍历配置生成4段灰色轨迹,作为槽位
+              -->
+              <circle
+                v-for="(item, index) in backgroundSegments"
+                :key="`bg-${index}`"
+                cx="50" cy="50" :r="radius"
+                fill="none"
+                stroke="#E5E9F2"
+                stroke-width="6"
+                :stroke-dasharray="item.dashArray"
+                stroke-linecap="round"
+                :transform="item.transform"
+              />
+
+              <!--
+                第二层:彩色进度 (Progress Segments)
+                根据分数覆盖在底轨之上
+              -->
+              <circle
+                v-for="(item, index) in progressSegments"
+                :key="`prog-${index}`"
+                cx="50" cy="50" :r="radius"
+                fill="none"
+                :stroke="item.color"
+                stroke-width="6"
+                :stroke-dasharray="item.dashArray"
+                stroke-linecap="round"
+                :transform="item.transform"
+              />
+            </svg>
+
+            <!-- 环内文字 -->
+            <div class="score-text">
+              <div class="score-num">{{ creditScore }}</div>
+              <div class="score-label">信用分</div>
+            </div>
           </div>
-          <div class="pf400 fs14 fc6A7187">ID: 658908</div>
         </div>
       </div>
-      <div class="info-right"></div>
+
+      <!-- 调试滑块 (实际使用可删除) -->
+<!--      <div class="debug-slider">-->
+<!--        <div class="slider-header">-->
+<!--          <span>当前分数: {{ creditScore }}</span>-->
+<!--          <span style="font-size:12px; color:#999">拖动查看未填满时的灰色效果</span>-->
+<!--        </div>-->
+<!--        <input type="range" min="0" max="100" v-model.number="creditScore" class="custom-range" />-->
+<!--      </div>-->
+
     </div>
-    <img src="../../assets/img/user/Invite Friends.svg" class="invite-friend" alt="" />
+<!--    <div class="loan-info">-->
+<!--      <div class="info-left">-->
+<!--        <img src="../../assets/img/index/user/default-head.png" alt="" />-->
+<!--        <div class="info-name" @click="deleteAccount">-->
+<!--          <div class="name-area pf500 fs18 fc121212">-->
+<!--            用户昵称-->
+<!--            <div class="level pf500 fs12 fcDF384C" @click.stop="router.push({name: 'VipCenter'})">V2</div>-->
+<!--          </div>-->
+<!--          <div class="pf400 fs14 fc6A7187" >ID: 658908</div>-->
+<!--        </div>-->
+<!--      </div>-->
+<!--      <div class="info-right"></div>-->
+<!--    </div>-->
+<!--    <div style="width: 375px; b"></div>-->
+    <img  src="@/assets/icon/user/yaoqi.svg" class="invite-friend" alt="" @click="router.push('/invite')"/>
     <div class="user-func">
       <div
         class="func-item"
         v-for="(item, index) in userMenu"
         :key="index"
-        @click="goMenuRouter(index)">
+        @click="goMenuRouter(index, item)">
         <div class="item-left pf500 fs14 fc333333">
           <div class="left-img">
             <img :src="item.img" class="anquan-set" alt="" />
@@ -30,23 +105,132 @@
         <img src="../../assets/icon/user/right-arrow.svg" class="right-arrow" alt="" />
       </div>
     </div>
-    <div class="submit pf600 fs14 fcFFFFFF">退出</div>
+    <div class="submit pf600 fs14 fcFFFFFF" @click="out=true">退出</div>
   </div>
+  <logout v-model:visible="out"></logout>
 </template>
 <script setup>
+  import logout from '@/views/user/Logout.vue'
+  import { ref, computed } from 'vue';
   import { useRoute, useRouter } from "vue-router";
 
   const router = useRouter();
+  const out = ref(false);
+const userInfo = ref({
+  nickname: '用户昵称',
+  id: '658908',
+  level: 'V2',
+  avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=Felix'
+});
 
-  const deleteAccount = () => {
-    router.push("/deleteAccount");
-  };
+// --- 核心配置 ---
+const creditScore = ref(90); // 当前分数
+const maxScore = 100; // 满分
+
+const radius = 42;
+const circumference = 2 * Math.PI * radius; // 周长 ≈ 263.89
+
+// 修改 1: 起始角度改为 -90 度 (从顶部正中间开始,顺时针绘制)
+const startAngle = -270;
+const gapLength = 10;    // 每一段之间的间隙 (像素)
+
+// 修改 2: 总有效长度改为完整圆周长 (不再乘 0.75,变成闭合圆环)
+const totalArcLength = circumference;
+
+// 颜色段配置 (总分需等于100)
+// 这里的顺序决定了圆环颜色的排列顺序
+const configSegments = [
+  { max: 50, color: '#2B6BFF' }, // 蓝色
+  { max: 20, color: '#FF4D6A' }, // 红色
+  { max: 15, color: '#FFAA00' }, // 黄色
+  { max: 15, color: '#00C087' }, // 绿色
+];
+
+// --- 辅助函数:计算一段圆弧的几何信息 ---
+const calculateSegmentGeometry = (segmentMaxScore, currentStartAngle) => {
+  // 1. 计算这一段理论上应该占多长 (像素)
+  const ratio = segmentMaxScore / maxScore;
+  let arcLength = ratio * totalArcLength;
+
+  // 2. 减去间隙 (视觉上扣除,防止连在一起)
+  // 实际绘制长度不能小于0
+  const drawLength = Math.max(0, arcLength - gapLength);
+
+  // 3. 计算这一段占用的角度 (包含被扣除的间隙,用于计算下一段的起点)
+  const angleSpan = (arcLength / circumference) * 360;
+
+  return { drawLength, angleSpan };
+};
+
+// --- 计算属性 1: 底轨片段 (灰色) ---
+const backgroundSegments = computed(() => {
+  let currentAngle = startAngle;
+  return configSegments.map(seg => {
+    const { drawLength, angleSpan } = calculateSegmentGeometry(seg.max, currentAngle);
+
+    const result = {
+      dashArray: `${drawLength}, ${circumference}`,
+      transform: `rotate(${currentAngle}, 50, 50)`
+    };
 
-  const goMenuRouter = (index) => {
+    currentAngle += angleSpan; // 移动到下一段起点
+    return result;
+  });
+});
+
+// --- 计算属性 2: 进度片段 (彩色) ---
+const progressSegments = computed(() => {
+  let currentAngle = startAngle;
+  let remainingScore = creditScore.value;
+
+  return configSegments.map(seg => {
+    const { drawLength, angleSpan } = calculateSegmentGeometry(seg.max, currentAngle);
+
+    // 计算这一段应该填满多少
+    let fillRatio = 0;
+    if (remainingScore >= seg.max) {
+      fillRatio = 1; // 填满
+    } else if (remainingScore > 0) {
+      fillRatio = remainingScore / seg.max; // 填一部分
+    } else {
+      fillRatio = 0; // 不填
+    }
+
+    const currentDrawLength = drawLength * fillRatio;
+
+    const result = {
+      color: seg.color,
+      dashArray: `${currentDrawLength}, ${circumference}`,
+      transform: `rotate(${currentAngle}, 50, 50)`
+    };
+
+    currentAngle += angleSpan;
+    remainingScore -= seg.max;
+
+    return result;
+  });
+});
+  // const deleteAccount = () => {
+  //   router.push("/deleteAccount");
+  // };
+
+  const goMenuRouter = (index, item) => {
     if (index == 1) {
       router.push("/userLoanIndex");
     } else if (index == 4) {
       router.push("/userAsset");
+    }else if (index === 2) {
+      router.push({ name: 'AdvancedCertification' });
+    }else if (index === 3) {
+      router.push({ name: 'KycForm' });
+    }else if (index === 5) {
+      router.push({ name: 'LanguageSwitch' });
+    }else if (index === 7) {
+      router.push({ name: 'HelpCenter' });
+    }else if (index === 8) {
+      router.push({ name: 'AboutUs' });
+    }else if (index === 0) {
+      router.push({ name: 'SecuritySettings' });
     }
   };
 
@@ -141,8 +325,8 @@
 
             .level {
               margin-left: 5px;
-              width: 18px;
-              height: 15px;
+              width: 20px;
+              height: 18px;
               line-height: 15px;
               text-align: center;
               border-radius: 3px;
@@ -160,9 +344,11 @@
     }
 
     .invite-friend {
-      margin-top: 20px;
-      width: 327px;
+      margin: 0 auto;
+      //margin-top: 20px;
+      width: 360px ;
       height: 68px;
+      padding-left: 15px;
     }
 
     .user-func {
@@ -174,7 +360,7 @@
         justify-content: space-between;
         align-items: center;
         margin-top: 26.5px;
-        width: 340px;
+        width: 355px;
         height: 24px;
 
         &:first-child {
@@ -220,4 +406,73 @@
       letter-spacing: 0.2px;
     }
   }
+
+
+  //xin
+.nav-bar {
+  display: flex; justify-content: space-between; align-items: center;
+  height: 44px; padding: 0 16px; background: #fff;
+  position: sticky; top: 0; z-index: 10;
+  width: 100%;
+  .icon1{ padding-left: 15px;}
+}
+.nav-title { font-size: 18px; font-weight: 500; color: #333; }
+.nav-left, .nav-right { width: 40px; }
+
+.content { width:100%;padding: 15px; }
+
+.user-card {
+  background: #fff; border-radius: 16px; padding: 0px 0 0 15px;
+  display: flex; justify-content: space-between; align-items: center;
+  //box-shadow: 0 4px 12px rgba(0,0,0,0.03);
+}
+
+.card-left { display: flex; align-items: center; }
+.avatar-box {
+  width: 56px; height: 56px; border-radius: 50%; overflow: hidden;
+  background: #E0E6ED; margin-right: 12px; border: 1px solid #f0f0f0;
+}
+.avatar-img { width: 100%; height: 100%; object-fit: cover; }
+
+.info-box { display: flex; flex-direction: column; justify-content: center; }
+.name-row { display: flex; align-items: center; margin-bottom: 6px; }
+.user-name { font-size: 18px; font-weight: 600; color: #1A1A1A; margin-right: 8px; }
+.vip-badge {
+  background-color: #FDEEEE; color: #E02F44; font-size: 10px; font-weight: 700;
+  padding: 1px 5px; border-radius: 4px; line-height: 1.4; font-style: italic;
+}
+.user-id { font-size: 14px; color: #858B9C; }
+
+.card-right { position: relative; }
+.score-chart {
+  width: 90px; height: 90px; position: relative;
+  display: flex; align-items: center; justify-content: center;
+}
+.chart-svg {
+  width: 100%; height: 100%;
+  transform: rotate(0deg);
+}
+
+.score-text {
+  position: absolute; text-align: center;
+  top: 50%; left: 50%;
+  transform: translate(-50%, -50%);
+}
+.score-num {
+  font-size: 22px; font-weight: 700; color: #1A1A1A; line-height: 1; margin-bottom: 2px;
+}
+.score-label {
+  font-size: 10px; color: #858B9C; transform: scale(0.9);
+}
+
+/* 调试滑块样式 */
+.debug-slider {
+  margin-top: 20px; padding: 15px; background: #fff; border-radius: 12px;
+}
+.slider-header {
+  display: flex; justify-content: space-between; margin-bottom: 10px; font-size: 14px; color: #333;
+}
+.custom-range {
+  width: 100%; accent-color: #2B6BFF;
+}
 </style>

+ 173 - 0
src/views/user/InviteCenter.vue

@@ -0,0 +1,173 @@
+<template>
+  <div class="invite-page">
+    <!-- 导航栏 -->
+    <div class="nav-bar">
+      <div class="nav-left" @click="$router.back()">
+        <van-icon size="20" name="arrow-left"></van-icon>
+      </div>
+      <div class="nav-title">邀请中心</div>
+      <div class="nav-right"></div>
+    </div>
+
+    <!-- 顶部礼物图标 -->
+    <div class="gift-section">
+      <div class="gift-circle">
+        <svg viewBox="0 0 1024 1024" width="80" height="80" fill="#DE3545">
+          <path d="M880 305H632c6.2-11.4 11-23.6 14.2-36.4 8.6-34 1.8-70.6-19-100.8-23.4-34-62-54.2-103.2-54.2-27.6 0-54.2 9-76 25.8-21.8-16.8-48.4-25.8-76-25.8-41.2 0-79.8 20.2-103.2 54.2-20.8 30.2-27.6 66.8-19 100.8 3.2 12.8 8 25 14.2 36.4H144c-17.6 0-32 14.4-32 32v152c0 17.6 14.4 32 32 32h24.8v344c0 17.6 14.4 32 32 32h622.4c17.6 0 32-14.4 32-32V497H880c17.6 0 32-14.4 32-32V337c0-17.6-14.4-32-32-32zM524 179.6c17.6 0 33.6 11 42.4 28.4 6 12 7.2 25.6 3.4 38.6-4 13.6-13.4 25.8-26.6 34.4-12.8 8.4-26.4 13-39.6 13-3.8 0-7.6-0.4-11.2-1.2-12.4-2.6-22.8-11.6-26.4-23.8-3.4-11.6 0-25.2 7-38.4 11.4-21.4 30.2-51 51-51zM293.6 208c8.8-17.4 24.8-28.4 42.4-28.4 20.8 0 39.6 29.6 51 51 7 13.2 10.4 26.8 7 38.4-3.6 12.2-14 21.2-26.4 23.8-3.6 0.8-7.4 1.2-11.2 1.2-13.2 0-26.8-4.6-39.6-13-13.2-8.6-22.6-20.8-26.6-34.4-3.8-13-2.6-26.6 3.4-38.6z m-65.6 161h228v128h-228V369z m228 365H232.8V561h223.2v173z m267.2 0H520V561h223.2v173z m0-237H520V369h203.2v128z"/>
+        </svg>
+      </div>
+      <h2 class="invite-title">邀请好友赚取更多福利</h2>
+    </div>
+
+    <!-- 邀请码区域 -->
+    <div class="code-section">
+      <div class="code-label">邀请码</div>
+      <div class="code-box">
+        <span class="code-text">{{ inviteCode }}</span>
+        <!-- 点击复制图标 -->
+        <svg @click="copyCode" class="copy-icon" viewBox="0 0 1024 1024" width="20" height="20">
+          <path d="M832 64H296c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h496v688c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8V96c0-17.7-14.3-32-32-32z" fill="#DE3545"/>
+          <path d="M704 192H192c-17.7 0-32 14.3-32 32v530.7c0 8.5 3.4 16.6 9.4 22.6l173.3 173.3c6 6 14.1 9.4 22.6 9.4h338.7c17.7 0 32-14.3 32-32V224c0-17.7-14.3-32-32-32zM352 853.3V704h-149.3L352 853.3z m320-32V256H224v384h160c17.7 0 32 14.3 32 32v149.3h256z" fill="#DE3545"/>
+        </svg>
+      </div>
+
+      <button class="share-btn" @click="handleShare">分享邀请</button>
+    </div>
+
+    <!-- 数据统计 -->
+    <div class="stats-row">
+      <div class="stats-item">
+        <div class="stats-label">累计返佣</div>
+        <div class="stats-num">158.00 USDT</div>
+      </div>
+      <div class="stats-item">
+        <div class="stats-label">邀请人数</div>
+        <div class="stats-num">1515</div>
+      </div>
+    </div>
+
+    <!-- 规则说明 -->
+    <div class="rules-section">
+      <h3>温馨提示</h3>
+      <p>成功邀请1-4名好友即可获得好友存款5%的佣金。</p>
+      <p>成功邀请5-10名好友即可获得好友存款10%的佣金。</p>
+      <p>成功邀请11-20名好友即可获得好友存款20%的佣金。</p>
+      <p>成功邀请超过30名好友即可获得好友存款45%的佣金。</p>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import { useRouter } from "vue-router";
+// 引入 Vant 的 Toast
+import { showToast } from 'vant';
+// 如果项目中没有全局引入样式,可能需要取消下面这行的注释
+// import 'vant/es/toast/style';
+
+const router = useRouter();
+const inviteCode = ref('LANDCOIN444');
+
+// --- 核心:兼容性极强的复制功能 ---
+const copyCode = async () => {
+  const text = inviteCode.value;
+
+  // 1. 优先尝试标准 API (需要 HTTPS)
+  if (navigator.clipboard && navigator.clipboard.writeText) {
+    try {
+      await navigator.clipboard.writeText(text);
+      showToast({ type: 'success', message: '复制成功' });
+      return;
+    } catch (err) {
+      console.warn('标准API复制失败,尝试降级方案', err);
+    }
+  }
+
+  // 2. 降级方案 (兼容所有浏览器/Webview)
+  try {
+    const input = document.createElement('input');
+    input.setAttribute('readonly', 'readonly'); // 防止 iOS 拉起键盘
+    input.setAttribute('value', text);
+    input.style.position = 'fixed';
+    input.style.left = '-9999px';
+    document.body.appendChild(input);
+
+    input.select();
+    input.setSelectionRange(0, 9999); // 兼容 iOS
+
+    if (document.execCommand('copy')) {
+      showToast({ type: 'success', message: '复制成功' });
+    } else {
+      showToast({ type: 'fail', message: '复制失败' });
+    }
+
+    document.body.removeChild(input);
+  } catch (e) {
+    showToast({ type: 'fail', message: '浏览器不支持自动复制' });
+  }
+};
+
+// 点击分享,跳转到新的海报页面
+const handleShare = () => {
+  router.push('/invite/poster');
+};
+</script>
+
+<style scoped>
+/* ========== 基础页面样式 ========== */
+.invite-page {
+  min-height: 100vh;
+  background: #fff;
+}
+.nav-bar {
+  display: flex; justify-content: space-between; align-items: center;
+  height: 44px; padding: 0 16px;
+}
+.nav-title { font-size: 18px; font-weight: 500; }
+.nav-left, .nav-right { width: 30px; display: flex; align-items: center; }
+
+.gift-section {
+  text-align: center;
+  padding: 30px 0 20px;
+}
+.gift-circle {
+  width: 120px; height: 120px;
+  background: #FFF0F0; /* 浅粉色圆底 */
+  border-radius: 50%;
+  margin: 0 auto 20px;
+  display: flex; align-items: center; justify-content: center;
+}
+.invite-title {
+  font-size: 18px; font-weight: 400; color: #333;
+}
+
+.code-section { padding: 0 20px; }
+.code-label { font-size: 14px; font-weight: 500; color: #333; margin-bottom: 10px; }
+.code-box {
+  display: flex; justify-content: space-between; align-items: center;
+  background: #fff; border: 1px dashed #eee; /* 虚线边框 */
+  padding: 12px 16px; border-radius: 8px; margin-bottom: 20px;
+  box-shadow: 0 2px 8px rgba(0,0,0,0.03);
+}
+.code-text { font-size: 14px; font-weight: 500; color: #333; }
+.share-btn {
+  width: 100%; height: 40px;
+  background: #DE3545; /* 红色按钮 */
+  color: #fff; border: none; border-radius: 20px;
+  font-size: 14px; font-weight: 600;
+}
+/* 点击反馈 */
+.share-btn:active { opacity: 0.9; }
+.copy-icon { cursor: pointer; }
+.copy-icon:active { opacity: 0.6; }
+
+.stats-row {
+  display: flex; margin: 11px 20px;
+}
+.stats-item { flex: 1; text-align: center; }
+.stats-label { color: #666; font-size: 12px; margin-bottom: 6px; }
+.stats-num { font-size: 18px; font-weight: 600; color: #333; }
+
+.rules-section { padding: 0 20px; color: #999; font-size: 12px; line-height: 1.8; }
+.rules-section h3 { color: #333; font-size: 14px; margin-bottom: 10px; }
+</style>

+ 147 - 0
src/views/user/InvitePoster.vue

@@ -0,0 +1,147 @@
+<template>
+  <div class="poster-container">
+
+    <div class="poster-content" ref="posterRef">
+
+      <div class="header-section">
+        <h1 class="brand-name">BitWiseWorld</h1>
+        <div class="main-title">邀请好友<br>赚取更多福利</div>
+      </div>
+
+      <div class="illustration-section">
+        <img src="@/assets/icon/bitcoin/yaoqing.svg" class="main-img" alt="Illustration" />
+      </div>
+
+      <div class="footer-info">
+        <div class="info-left">
+          <div class="label">邀请码</div>
+          <div class="code">LANDCOIN444</div>
+        </div>
+        <div class="info-right">
+          <img src="@/assets/icon/bitcoin/erweima.svg" class="qr-img" alt="QR Code" />
+        </div>
+      </div>
+
+      <div class="bg-pattern"></div>
+    </div>
+
+    <div class="action-area">
+      <button class="save-btn" @click="handleSave">保存图片</button>
+    </div>
+
+  </div>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import html2canvas from 'html2canvas';
+
+const posterRef = ref(null);
+
+const handleSave = async () => {
+  if (!posterRef.value) return;
+  try {
+    const canvas = await html2canvas(posterRef.value, {
+      useCORS: true,
+      scale: 3, // 稍微提高一点清晰度
+      backgroundColor: '#D91E2D',
+    });
+    const imgUrl = canvas.toDataURL('image/png');
+
+    const link = document.createElement('a');
+    link.href = imgUrl;
+    link.download = 'invite_poster.png';
+    document.body.appendChild(link);
+    link.click();
+    document.body.removeChild(link);
+  } catch (error) {
+    console.error(error);
+  }
+};
+</script>
+
+<style scoped>
+/* 页面容器:红色背景铺满全屏 */
+.poster-container {
+  min-height: 100vh;
+  background-color: #D91E2D;
+  display: flex;
+  flex-direction: column;
+  /* 如果内容很少,可以加这个让内容整体垂直居中,或者去掉它让内容顶对齐 */
+  /* justify-content: center; */
+}
+
+/* 核心海报内容区:这里决定了截图的高度 */
+.poster-content {
+  position: relative;
+  background-color: #D91E2D; /* 截图需要背景色 */
+  padding: 30px 24px 10px;    /* 减少底部 padding */
+  overflow: hidden;           /* 防止装饰溢出 */
+}
+
+.header-section {
+  position: relative; z-index: 1;
+  margin-bottom: 20px; /* 减小间距 */
+}
+.brand-name {
+  font-size: 18px; font-weight: 800; color: #fff; opacity: 0.9;
+  margin-bottom: 10px;
+}
+.main-title {
+  font-size: 32px; font-weight: 600; color: #fff; line-height: 1.2;
+}
+
+/* 插画区:关键修改 */
+.illustration-section {
+  position: relative; z-index: 1;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  margin: 10px 0 20px; /* 上下留一点紧凑的间距 */
+}
+
+.main-img {
+  width: 100%;
+  max-width: 280px; /* 限制最大宽度 */
+  height: auto;
+  /* 如果图还是很长,可以强制限制高度,用 object-fit 保持比例 */
+  max-height: 320px;
+  object-fit: contain;
+}
+
+/* 底部信息区 */
+.footer-info {
+  position: relative; z-index: 1;
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-end;
+  padding-bottom: 20px;
+}
+.label { font-size: 14px; color: rgba(255,255,255,0.8); margin-bottom: 4px; }
+.code { font-size: 20px; font-weight: 700; color: #fff; letter-spacing: 0.5px; }
+.qr-img {
+  width: 72px; height: 72px;
+  background: #fff; padding: 3px; border-radius: 4px;
+}
+
+/* 背景装饰 */
+.bg-pattern {
+  position: absolute; top: 0; left: 0; right: 0; bottom: 0;
+  background-image: radial-gradient(rgba(255,255,255,0.1) 2px, transparent 2px);
+  background-size: 18px 18px;
+  pointer-events: none; z-index: 0;
+}
+
+/* 底部按钮区:脱离海报流,固定在底部或者紧跟内容 */
+.action-area {
+  padding: 0px 24px 30px;
+  margin-top: auto; /* 把按钮推到屏幕最底部,如果不想推到底部,去掉这行 */
+}
+
+.save-btn {
+  width: 100%; height: 48px;
+  background: #fff; color: #D91E2D;
+  font-size: 16px; font-weight: 600; border: none; border-radius: 24px;
+  box-shadow: 0 4px 12px rgba(0,0,0,0.15);
+}
+</style>

+ 161 - 0
src/views/user/KycForm.vue

@@ -0,0 +1,161 @@
+<template>
+  <div class="kyc-page">
+    <!-- 导航栏 -->
+    <div class="nav-bar">
+      <div class="nav-left" @click="$router.back()">
+        <van-icon size="20" name="arrow-left"></van-icon>      </div>
+      <div class="nav-title">KYC认证</div>
+      <div class="nav-right"></div>
+    </div>
+
+    <div class="form-content">
+      <!-- 姓名行 (两列布局) -->
+      <div class="form-row two-col">
+        <div class="form-item">
+          <label>法定名</label>
+          <input type="text" placeholder="名" class="custom-input" />
+        </div>
+        <div class="form-item">
+          <label>法定姓</label>
+          <input type="text" placeholder="姓" class="custom-input" />
+        </div>
+      </div>
+
+      <!-- 证件类型 -->
+      <div class="form-row">
+        <label>证件类型</label>
+        <div class="custom-select">
+          <span>身份证</span>
+          <svg width="12" height="12" viewBox="0 0 24 24"><path d="M6 9L12 15L18 9" stroke="#666" stroke-width="2" fill="none"/></svg>
+        </div>
+      </div>
+
+      <!-- 证件号码 -->
+      <div class="form-row">
+        <label>证件号码</label>
+        <input type="text" placeholder="请输入证件号码" class="custom-input" />
+      </div>
+
+      <!-- 出生日期 -->
+      <div class="form-row">
+        <label>出生日期</label>
+        <input type="text" placeholder="请输入" class="custom-input" />
+      </div>
+
+      <!-- 所在地区 -->
+      <div class="form-row">
+        <label>所在地区</label>
+        <div class="custom-select">
+          <span>请选择</span>
+          <svg width="12" height="12" viewBox="0 0 24 24"><path d="M6 9L12 15L18 9" stroke="#666" stroke-width="2" fill="none"/></svg>
+        </div>
+      </div>
+
+      <!-- 详细地址 -->
+      <div class="form-row">
+        <label>详细地址</label>
+        <textarea placeholder="请输入" class="custom-textarea"></textarea>
+      </div>
+
+      <!-- 职业信息 -->
+      <div class="form-row">
+        <label>职业信息</label>
+        <input type="text" placeholder="请输入" class="custom-input" />
+      </div>
+
+      <!-- 资金来源 -->
+      <div class="form-row">
+        <label>资金来源</label>
+        <input type="text" placeholder="请输入" class="custom-input" />
+      </div>
+
+      <!-- SSN -->
+      <div class="form-row">
+        <label>社会安全号码(SSN)</label>
+        <input type="text" placeholder="请输入" class="custom-input" />
+      </div>
+
+      <!-- 底部说明 -->
+      <div class="footer-note">
+        <h4>说明</h4>
+        <p>收集信息为了遵守反洗钱(AML)和金融犯罪侦查网络(FinCEN)的监管要求</p>
+      </div>
+
+      <!-- 下一步按钮 -->
+      <button class="submit-btn" @click="nextStep">下一步</button>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { useRouter } from 'vue-router';
+const router = useRouter();
+
+const nextStep = () => {
+  // 校验逻辑省略...
+  router.push('/kyc/step2'); // 跳转到图2
+};
+</script>
+
+<style scoped>
+.kyc-page {
+  min-height: 100vh;
+  background: #fff;
+  padding-bottom: 40px;
+}
+.nav-bar {
+  display: flex; justify-content: space-between; align-items: center;
+  height: 44px; padding: 0 16px; position: sticky; top: 0; background: #fff; z-index: 10;
+}
+.nav-title { font-size: 18px; font-weight: 600; color: #333; }
+.nav-left, .nav-right { width: 40px; }
+
+.form-content { padding: 10px 20px; }
+
+.form-row { margin-bottom: 20px; }
+.form-row label {
+  display: block; font-size: 14px; color: #333; margin-bottom: 8px; font-weight: 500;
+}
+
+/* 两列布局 */
+.two-col { display: flex; gap: 15px; }
+.two-col .form-item { flex: 1; }
+.two-col label { margin-bottom: 8px; display: block; font-size: 14px; }
+
+/* 输入框通用样式 */
+.custom-input, .custom-select, .custom-textarea {
+  width: 100%;
+  background: #F7F8FA; /* 浅灰背景 */
+  border: none;
+  border-radius: 8px;
+  padding: 12px 16px;
+  font-size: 14px;
+  color: #333;
+  box-sizing: border-box; /* 关键:防止padding撑大宽度 */
+}
+.custom-input::placeholder, .custom-textarea::placeholder { color: #999; }
+
+/* 模拟 Select */
+.custom-select {
+  display: flex; justify-content: space-between; align-items: center; color: #333;
+}
+
+.custom-textarea {
+  height: 80px; resize: none; font-family: inherit;
+}
+
+/* 底部说明 */
+.footer-note { margin-top: 30px; margin-bottom: 30px; }
+.footer-note h4 { font-size: 14px; color: #333; margin-bottom: 8px; font-weight: 500; }
+.footer-note p { font-size: 12px; color: #999; line-height: 1.5; }
+
+/* 红色大按钮 */
+.submit-btn {
+  width: 100%; height: 50px;
+  background: #E02F44; /* 图中红色 */
+  color: #fff; font-size: 16px; font-weight: 500;
+  border: none; border-radius: 25px;
+  margin-bottom: 20px;
+}
+.submit-btn:active { opacity: 0.9; }
+</style>

+ 299 - 0
src/views/user/KycUpload.vue

@@ -0,0 +1,299 @@
+<template>
+  <div class="upload-page">
+    <!-- 导航栏 -->
+    <div class="nav-bar">
+      <div class="nav-left" @click="$router.back()">
+        <van-icon size="20" name="arrow-left"></van-icon>
+      </div>
+      <div class="nav-title">KYC认证</div>
+      <div class="nav-right"></div>
+    </div>
+
+    <div class="content">
+      <h2 class="page-title">上传证件照</h2>
+      <p class="sub-title">确保验证件照清晰可见</p>
+
+      <!-- ==================== 核心上传区域 ==================== -->
+
+      <!-- 1. 身份证人像面 -->
+      <div class="upload-card">
+        <div class="card-tips">确保证件照清晰可见</div>
+        <div class="card-title">身份证人像面</div>
+
+        <!-- 如果已上传,显示预览图 (示例逻辑) -->
+        <div v-if="images.idFront" class="preview-box">
+          <img :src="images.idFront" alt="Front Preview" />
+          <div class="re-upload-btn" @click="openSheet('idFront')">重新上传</div>
+        </div>
+
+        <!-- 未上传,显示上传按钮 -->
+        <button v-else class="upload-btn" @click="openSheet('idFront')">
+          上传
+          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="icon-upload"><path d="M12 19V5M5 12l7-7 7 7"/></svg>
+        </button>
+      </div>
+
+      <!-- 2. 身份证国徽面 -->
+      <div class="upload-card">
+        <div class="card-tips">确保证件照清晰可见</div>
+        <div class="card-title">身份证国徽面</div>
+
+        <div v-if="images.idBack" class="preview-box">
+          <img :src="images.idBack" alt="Back Preview" />
+          <div class="re-upload-btn" @click="openSheet('idBack')">重新上传</div>
+        </div>
+
+        <button v-else class="upload-btn" @click="openSheet('idBack')">
+          上传
+          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="icon-upload"><path d="M12 19V5M5 12l7-7 7 7"/></svg>
+        </button>
+      </div>
+
+      <!-- 3. 护照或驾驶执照 -->
+      <div class="section-header">
+        <h3>上传护照或驾驶执照</h3>
+        <p>确保证件照清晰可见</p>
+      </div>
+      <div class="upload-card">
+        <div class="card-tips">确保证件照清晰可见</div>
+        <div class="card-title">护照或驾驶执照</div>
+
+        <div v-if="images.passport" class="preview-box">
+          <img :src="images.passport" alt="Passport Preview" />
+          <div class="re-upload-btn" @click="openSheet('passport')">重新上传</div>
+        </div>
+
+        <button v-else class="upload-btn" @click="openSheet('passport')">
+          上传
+          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="icon-upload"><path d="M12 19V5M5 12l7-7 7 7"/></svg>
+        </button>
+      </div>
+
+      <!-- 底部说明 -->
+      <div class="bottom-desc">
+        <p>支持小于8M的JPG、JPGE或PNG格式的图片</p>
+        <p>上传您身份证件的完整照片,请确保上传图片中的所有细节都清晰可见</p>
+        <p>请确保证件为原件并在有效期内</p>
+        <p>请将证件置于纯色背景下</p>
+      </div>
+
+      <button class="submit-btn" @click="handleSubmit">提交</button>
+    </div>
+
+    <!-- ==================== 隐藏的 Input (核心逻辑) ==================== -->
+    <!-- 1. 调起摄像头 (capture="environment" 强制后置摄像头) -->
+    <input
+      type="file"
+      ref="cameraInputRef"
+      accept="image/*"
+      capture="environment"
+      style="display: none"
+      @change="handleFileChange"
+    />
+
+    <!-- 2. 调起相册 (仅 accept="image/*") -->
+    <input
+      type="file"
+      ref="galleryInputRef"
+      accept="image/*"
+      style="display: none"
+      @change="handleFileChange"
+    />
+
+
+    <!-- ==================== 底部弹窗 (ActionSheet) ==================== -->
+    <transition name="fade">
+      <div class="mask" v-if="showActionSheet" @click="closeSheet"></div>
+    </transition>
+
+    <transition name="slide-up">
+      <div class="action-sheet" v-if="showActionSheet">
+        <div class="sheet-handle"></div>
+        <div class="sheet-title">上传</div>
+
+        <div class="sheet-menu">
+          <!-- 点击触发拍照 -->
+          <div class="menu-item active" @click="triggerUpload('camera')">
+            <span class="menu-text">拍照上传</span>
+            <div class="check-icon">
+              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3"><path d="M20 6L9 17l-5-5"/></svg>
+            </div>
+          </div>
+
+          <!-- 点击触发相册 -->
+          <div class="menu-item" @click="triggerUpload('gallery')">
+            <span class="menu-text">相册选择</span>
+             <!-- 图3显示这里是灰色的,没有选中勾 -->
+          </div>
+        </div>
+
+        <div class="safe-area-bottom"></div>
+      </div>
+    </transition>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive } from 'vue';
+
+// --- 状态管理 ---
+const showActionSheet = ref(false);
+const currentDocType = ref(''); // 记录当前正在上传哪一个 (idFront, idBack, passport)
+
+// 存储上传后的图片预览地址 (实际开发中可能是 Base64 或 后端返回的 URL)
+const images = reactive({
+  idFront: '',
+  idBack: '',
+  passport: ''
+});
+
+// --- 引用 DOM ---
+const cameraInputRef = ref(null);
+const galleryInputRef = ref(null);
+
+// --- 弹窗逻辑 ---
+const openSheet = (type) => {
+  currentDocType.value = type; // 标记当前是哪个位置在上传
+  showActionSheet.value = true;
+};
+
+const closeSheet = () => {
+  showActionSheet.value = false;
+};
+
+// --- 核心上传触发逻辑 ---
+const triggerUpload = (source) => {
+  // 1. 关闭弹窗
+  closeSheet();
+
+  // 2. 根据用户选择,点击对应的隐藏 Input
+  if (source === 'camera') {
+    // 触发拍照 Input
+    cameraInputRef.value?.click();
+  } else {
+    // 触发相册 Input
+    galleryInputRef.value?.click();
+  }
+};
+
+// --- 文件选择回调 ---
+const handleFileChange = (event) => {
+  const file = event.target.files[0];
+  if (!file) return;
+
+  // 1. 这里可以加一些校验,比如大小限制 8M
+  if (file.size > 8 * 1024 * 1024) {
+    alert('图片大小不能超过 8MB');
+    return;
+  }
+
+  // 2. 创建本地预览 URL (纯前端预览,无需上传服务器即可看到)
+  const previewUrl = URL.createObjectURL(file);
+
+  // 3. 更新对应的图片状态
+  if (currentDocType.value === 'idFront') {
+    images.idFront = previewUrl;
+  } else if (currentDocType.value === 'idBack') {
+    images.idBack = previewUrl;
+  } else if (currentDocType.value === 'passport') {
+    images.passport = previewUrl;
+  }
+
+  // 4. (可选) 这里可以立即调用 API 上传文件给后端
+  // uploadToServer(file);
+
+  // 5. 清空 input 值,防止用户重复选择同一张图片时不触发 change 事件
+  event.target.value = '';
+};
+
+const handleSubmit = () => {
+  // 简单的校验
+  if (!images.idFront || !images.idBack) {
+    alert('请先完善身份证照片信息');
+    return;
+  }
+  console.log('提交的数据:', images);
+  alert('提交成功!');
+};
+</script>
+
+<style scoped>
+/* 基础样式复用 */
+.upload-page { min-height: 100vh; background: #fff; padding-bottom: 40px; }
+.nav-bar { display: flex; justify-content: space-between; align-items: center; height: 44px; padding: 0 16px; position: sticky; top: 0; background: #fff; z-index: 10; }
+.nav-title { font-size: 18px; font-weight: 500; }
+.nav-left, .nav-right { width: 40px; }
+.content { padding: 10px 20px; }
+.page-title { font-size: 18px; font-weight: 500; margin-bottom: 4px; color: #333; }
+.sub-title { font-size: 12px; color: #999; margin-bottom: 20px; }
+
+/* 上传卡片 */
+.upload-card {
+  background: #F7F8FA; border-radius: 8px; padding: 20px 0;
+  text-align: center; margin-bottom: 20px;
+  position: relative; overflow: hidden;
+}
+.card-tips { font-size: 12px; color: #999; margin-bottom: 8px; }
+.card-title { font-size: 16px; font-weight: 600; color: #333; margin-bottom: 15px; }
+.upload-btn {
+  background: #E02F44; color: #fff; border: none; padding: 8px 30px;
+  border-radius: 20px; font-size: 14px; display: inline-flex; align-items: center;
+}
+.icon-upload { margin-left: 4px; margin-bottom: -2px; }
+
+/* 预览图样式 */
+.preview-box {
+  width: 100%; display: flex; flex-direction: column; align-items: center;
+}
+.preview-box img {
+  max-width: 80%; max-height: 150px; border-radius: 4px; margin-bottom: 10px;
+  object-fit: contain;
+}
+.re-upload-btn {
+  font-size: 12px; color: #E02F44; cursor: pointer; text-decoration: underline;
+}
+
+/* 底部区域 */
+.section-header { margin-top: 30px; margin-bottom: 15px; }
+.section-header h3 { font-size: 16px; font-weight: 600; }
+.section-header p { font-size: 12px; color: #999; }
+.bottom-desc p { font-size: 12px; color: #999; line-height: 1.6; }
+.submit-btn {
+  width: 100%; height: 50px; background: #E02F44; color: #fff;
+  border: none; border-radius: 25px; font-size: 16px; margin-top: 20px;
+}
+
+/* 弹窗样式 */
+.mask { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5);
+  z-index: 99; }
+.action-sheet { position: fixed; bottom: 0; left: 0; width: 100%; background: #fff;
+  border-radius: 16px 16px 0 0; z-index: 100; padding-bottom: 20px; }
+.sheet-handle { width: 36px; height: 4px; background: #E0E0E0; border-radius: 2px; margin: 10px auto; }
+.sheet-title { font-size: 18px; font-weight: 600; padding: 10px 20px 20px; }
+.menu-item { display: flex; justify-content: space-between; align-items: center;
+  padding: 16px 20px; font-size: 16px; color: #333; cursor: pointer; }
+.menu-item.active .check-icon { width: 22px; height: 22px; background: #E02F44; border-radius: 50%;
+  display: flex; align-items: center; justify-content: center; }
+.safe-area-bottom { height: env(safe-area-inset-bottom); }
+
+/* 动画 */
+.fade-enter-active, .fade-leave-active { transition: opacity 0.3s; }
+.fade-enter-from, .fade-leave-to { opacity: 0; }
+.slide-up-enter-active, .slide-up-leave-active { transition: transform 0.3s; }
+.slide-up-enter-from, .slide-up-leave-to { transform: translateY(100%); }
+</style>
+```
+
+### 关键技术点解析
+
+1.  **H5 调起摄像头的标准写法**:
+    ```html
+    <input type="file" accept="image/*" capture="environment">
+    ```
+    * `accept="image/*"`:限制只能选择图片。
+    * `capture="environment"`:这是关键,它告诉移动端浏览器**直接调用后置摄像头**,
+不要再弹出一个选择框问用户“相机还是相册”。(注意:部分安卓浏览器可能仍然会询问,但大部分会直接进相机)。
+
+2.  **H5 调起相册的标准写法**:
+    ```html
+    <input type="file" accept="image/*">

+ 99 - 0
src/views/user/LanguageSwitch.vue

@@ -0,0 +1,99 @@
+<template>
+  <div class="page-container">
+    <van-nav-bar
+      :title="$t('common.switchLang')"
+      left-arrow
+      fixed
+      placeholder
+      @click-left="router.back()"
+      class="custom-nav"
+    />
+
+    <div class="content-body">
+      <div
+        v-for="item in langList"
+        :key="item.code"
+        class="lang-card"
+        :class="{ 'active': currentLang === item.code }"
+        @click="onSelectLang(item)"
+      >
+        <div class="flag-icon">{{ item.flagEmoji }}</div>
+        <div class="text-info">
+          <div class="native-name">{{ item.native }}</div>
+          <div class="english-name">{{ item.english }}</div>
+        </div>
+        <div class="checkbox-area">
+          <div v-if="currentLang === item.code" class="check-box">
+            <van-icon name="success" color="#fff" size="14" />
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import { useRouter } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+import { showLoadingToast, closeToast, Icon as VanIcon } from 'vant';
+import { loadLanguageAsync } from '@/locales/index';
+
+const router = useRouter();
+const { locale } = useI18n();
+const currentLang = ref(locale.value);
+
+const langList = [
+  { code: 'en-US', native: 'English', english: 'English', flagEmoji: '🇺🇸' },
+  { code: 'de-DE', native: 'Deutsch', english: 'German', flagEmoji: '🇩🇪' },
+  { code: 'es-ES', native: 'Español', english: 'Spanish', flagEmoji: '🇪🇸' },
+  { code: 'fr-FR', native: 'Français', english: 'French', flagEmoji: '🇫🇷' },
+  { code: 'pt-PT', native: 'Português', english: 'Portuguese', flagEmoji: '🇵🇹' },
+  { code: 'id-ID', native: 'Bahasa Indonesia', english: 'Indonesian', flagEmoji: '🇮🇩' },
+  { code: 'ru-RU', native: 'Русский', english: 'Russian', flagEmoji: '🇷🇺' },
+  { code: 'zh-CN', native: '简体中文', english: 'Chinese Simplified', flagEmoji: '🇨🇳' },
+];
+
+const onSelectLang = async (item) => {
+  const langCode = item.code;
+  if (langCode === currentLang.value) return;
+
+  showLoadingToast({
+    message: 'Switching...',
+    forbidClick: true,
+    duration: 0,
+  });
+
+  try {
+    await loadLanguageAsync(langCode);
+    currentLang.value = langCode;
+    closeToast();
+    setTimeout(() => {
+      // router.back();
+      }, 200);
+  } catch (error) {
+    closeToast();
+  }
+};
+</script>
+
+<style scoped lang="less">
+.page-container { min-height: 100vh; background-color: #f7f8fa; }
+.content-body { padding: 16px; }
+.lang-card {
+  background: #fff; border-radius: 12px; padding: 16px; margin-bottom: 12px;
+  display: flex; align-items: center; border: 1px solid transparent;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.02); transition: all 0.2s;
+  &:active { background-color: #f2f3f5; }
+  &.active { border-color: #ee0a24; background-color: #fffbfb; }
+}
+.flag-icon { font-size: 24px; margin-right: 16px; }
+.text-info { flex: 1; display: flex; flex-direction: column;
+  .native-name { font-size: 16px; font-weight: 600; color: #323233; margin-bottom: 2px; }
+  .english-name { font-size: 12px; color: #969799; }
+}
+.checkbox-area { width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; }
+.check-box { width: 22px; height: 22px; background-color: #ee0a24; border-radius: 4px;
+  display: flex; align-items: center; justify-content: center; }
+:deep(.custom-nav) { --van-nav-bar-icon-color: #333; --van-nav-bar-title-text-color: #333; }
+</style>

+ 115 - 0
src/views/user/Logout.vue

@@ -0,0 +1,115 @@
+<template>
+  <Teleport to="body">
+    <transition name="fade">
+      <div v-if="visible" class="modal-mask" @click="close">
+
+        <div class="modal-container" @click.stop>
+
+          <div class="modal-title">温馨提示</div>
+
+          <div class="modal-text">是否要退出当前账号          </div>
+
+          <button class="main-btn" @click="close">
+            退出
+          </button>
+
+        </div>
+      </div>
+    </transition>
+  </Teleport>
+</template>
+
+<script setup>
+import { defineProps, defineEmits } from 'vue';
+
+defineProps({
+  visible: Boolean
+});
+
+const emit = defineEmits(['update:visible']);
+
+const close = () => {
+  emit('update:visible', false);
+};
+</script>
+
+<style scoped>
+/* --- 布局与遮罩 --- */
+.modal-mask {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100vw;
+  height: 100vh;
+  background: rgba(0, 0, 0, 0.6); /* 深色遮罩 */
+  display: flex;
+  align-items: center; /* 垂直居中 */
+  justify-content: center; /* 水平居中 */
+  z-index: 2000;
+}
+
+/* --- 弹窗卡片 --- */
+.modal-container {
+  width: 310px; /* 稍微宽一点,适配文字换行 */
+  background: #fff;
+  border-radius: 16px; /* 大圆角 */
+  padding: 24px 24px;
+  box-sizing: border-box;
+  text-align: center;
+  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1);
+}
+
+/* --- 标题 --- */
+.modal-title {
+  font-size: 18px;
+  font-weight: 600;
+  color: #111;
+  margin-bottom: 16px;
+}
+
+/* --- 正文 --- */
+.modal-text {
+  font-size: 15px;
+  color: #555; /* 稍微柔和的深灰色 */
+  line-height: 1.6; /* 增加行高,易读 */
+  text-align: center; /* 两端对齐,像报纸一样整齐 */
+  margin-bottom: 24px;
+
+}
+
+/* --- 红色按钮 --- */
+.main-btn {
+  width: 100%;
+  height: 46px;
+  background: #DE3545; /* 截图里的标准红 */
+  color: #fff;
+  font-size: 16px;
+  font-weight: 500;
+  border: none;
+  border-radius: 23px; /* 高度的一半,形成胶囊形状 */
+  cursor: pointer;
+}
+.main-btn:active {
+  opacity: 0.8; /* 点击反馈 */
+}
+
+/* --- 动画效果: 缩放弹入 --- */
+.fade-enter-active, .fade-leave-active {
+  transition: opacity 0.2s ease;
+}
+.fade-enter-active .modal-container {
+  animation: pop-in 0.3s cubic-bezier(0.18, 0.89, 0.32, 1.28); /* 弹性动画 */
+}
+.fade-leave-active .modal-container {
+  animation: pop-in 0.3s reverse;
+}
+
+.fade-enter-from, .fade-leave-to {
+  opacity: 0;
+}
+
+@keyframes pop-in {
+  0% { transform: scale(0.8); opacity: 0; }
+  100% { transform: scale(1); opacity: 1; }
+}
+</style>

+ 63 - 0
src/views/user/PrivacyPolicy.vue

@@ -0,0 +1,63 @@
+<template>
+  <div class="text-page">
+    <div class="nav-bar">
+      <div class="nav-left" @click="$router.back()">
+        <van-icon size="20" name="arrow-left"></van-icon>       </div>
+      <div class="nav-title">隐私政策</div>
+      <div class="nav-right"></div>
+    </div>
+
+    <div class="content">
+      <p>以本隐私政策内容为准,该产品隐私政策与本隐私政策有冲突的内容,以产品隐私政策为准。</p>
+      <p>本隐私政策旨在帮助您了解我们会收集哪些数据、为什么收集这些数据,会利用这些数据做些什么及如何保护这些数据。除非法律、行政法规另有规定,针对我们如何处理您的个人信息,您享有知情权和决定权,有权限制或者拒绝我们或其他方对您的个人信息进行处理;同时,您有权要求我们对我们向您提供的个人信息处理规则进行解释说明。</p>
+
+      <p class="subtitle">本隐私政策将帮助您了解以下内容:</p>
+
+      <div class="list-text">
+        <p>1. 我们如何收集和使用您的个人信息</p>
+        <p>2. 我们如何使用 Cookie 和同类技术</p>
+        <p>3. 我们如何共享、转让、公开披露您的个人信息</p>
+        <p>4. 我们如何保存及保护您的个人信息</p>
+        <p>5. 您的权利</p>
+        <p>6. 我们如何处理未成年人的个人信息</p>
+        <p>7. 您的个人信息如何跨境转移</p>
+        <p>8. 隐私政策的修订</p>
+        <p>9. 如何联系我们</p>
+      </div>
+
+      <p>我们深知个人信息对您的重要性,也深知为您提供有效保护是我们业务健康、可持续发展的基石。感谢您对我们产品和服务的信任!我们致力于维持您对我们的信任,恪守法律和我们对您的承诺,尽全力保证您的个人信息安全和合理使用。</p>
+    </div>
+  </div>
+</template>
+
+<style scoped>
+/* 既然样式和协议页一样,可以在真实项目中提取公共CSS */
+.text-page { background: #fff; min-height: 100vh; }
+.nav-bar { display: flex; justify-content: space-between; align-items: center; height: 44px; padding: 0 16px; position: sticky; top: 0; background: #fff; border-bottom: 1px solid #f5f5f5; }
+.nav-title { font-size: 18px; font-weight: 600; color: #000; }
+.nav-left, .nav-right { width: 40px; }
+
+.content {
+  padding: 20px 20px 40px; /* 底部留白多一点 */
+}
+
+p {
+  font-size: 14px; /* 移动端标准正文大小 */
+  color: #666;     /* 不用纯黑,用深灰 */
+  line-height: 1.8; /* 较大的行高,增加易读性 */
+  text-align: justify; /* 两端对齐,让文字块像方块一样整齐 */
+  margin-bottom: 20px; /* 段落间距 */
+}
+
+.subtitle {
+  color: #333;
+  margin-top: 30px;
+  margin-bottom: 10px;
+}
+
+.list-text p {
+  margin-bottom: 8px; /* 列表项紧凑一点 */
+}
+</style>
+<script setup lang="ts">
+</script>

+ 113 - 0
src/views/user/RelativeAuth.vue

@@ -0,0 +1,113 @@
+<template>
+  <div class="page-container">
+    <van-nav-bar
+      :title="$t('auth.advanced')"
+      left-arrow
+      fixed
+      placeholder
+      @click-left="router.back()"
+      class="custom-nav-bar"
+    />
+
+    <div class="form-content">
+      <h3 class="form-label">{{ $t('auth.name') }}</h3>
+      <van-field
+        v-model="form.name"
+        :placeholder="$t('auth.pleaseInput')"
+        class="blue-border-input-field"
+      />
+
+      <h3 class="form-label">{{ $t('auth.relationType') }}</h3>
+      <van-field
+        v-model="form.relation"
+        is-link
+        readonly
+        :placeholder="$t('auth.pleaseSelect')"
+        class="grey-input-field"
+        @click="showRelationPicker = true"
+      />
+
+      <h3 class="form-label">{{ $t('auth.phone') }}</h3>
+      <van-field
+        v-model="form.phone"
+        type="tel"
+        :placeholder="$t('auth.pleaseInput')"
+        class="grey-input-field"
+      />
+    </div>
+
+    <div class="submit-bar">
+      <van-button type="danger" block round @click="onSubmit">
+        {{ $t('common.confirm') }}
+      </van-button>
+    </div>
+
+    <van-popup v-model:show="showRelationPicker" round position="bottom">
+      <van-picker
+        :title="$t('auth.relationType')"
+        :columns="relationColumns"
+        @confirm="onRelationConfirm"
+        @cancel="showRelationPicker = false"
+        :confirm-button-text="$t('common.confirm')"
+        :cancel-button-text="$t('common.cancel')"
+      />
+    </van-popup>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, computed } from 'vue';
+import { useRouter } from 'vue-router';
+import { useI18n } from 'vue-i18n';
+
+const router = useRouter();
+const { t } = useI18n();
+
+const form = reactive({ name: '', relation: '', phone: '' });
+const showRelationPicker = ref(false);
+
+// ✅ 性能优化写法:使用 computed
+// 这样即使不刷新页面,下拉菜单里的中文也会变成英文
+const relationColumns = computed(() => [
+  { text: '父母', value: 'parents' }, // 建议这里也可以换成 t('relation.parents')
+  { text: '配偶', value: 'spouse' },
+  { text: '子女', value: 'children' },
+  { text: '兄弟姐妹', value: 'siblings' },
+]);
+
+const onRelationConfirm = ({ selectedOptions }) => {
+  form.relation = selectedOptions[0].text;
+  showRelationPicker.value = false;
+};
+
+const onSubmit = () => {
+  console.log('Submit:', form);
+  router.back();
+};
+</script>
+
+<style scoped lang="less">
+/* --- 重点修改:自定义导航栏样式 --- */
+:deep(.custom-nav-bar) {
+  /* 修改图标(返回箭头)颜色为黑色 */
+  --van-nav-bar-icon-color: #323233;
+  /* 修改标题颜色为黑色,保持一致 */
+  --van-nav-bar-title-text-color: #323233;
+  /* 如果有左侧文字,也改为黑色 */
+  --van-nav-bar-text-color: #323233;
+   --van-nav-bar-arrow-size: 19px;
+}
+.page-container { min-height: 100vh; background-color: #fff; display: flex; flex-direction: column; }
+.form-content { flex: 1; padding: 10px 16px; }
+.form-label { font-size: 15px; font-weight: bold; color: #323233; margin-bottom: 10px; margin-top: 20px; }
+.submit-bar { padding: 20px 16px 40px; background-color: #fff; }
+
+:deep(.van-cell.grey-input-field) {
+  background-color: #f7f8fa; border-radius: 8px; padding: 12px 16px;
+  &::after { display: none; }
+}
+:deep(.van-cell.blue-border-input-field) {
+  background-color: #fff; border-radius: 8px; padding: 12px 16px;
+  border: 1px solid #1989fa; &::after { display: none; }
+}
+</style>

+ 279 - 0
src/views/user/SecuritySettings.vue

@@ -0,0 +1,279 @@
+<template>
+  <div class="security-page">
+    <!-- 导航栏 -->
+    <div class="nav-bar">
+      <div class="nav-left" @click="$router.back()">
+        <van-icon size="20" name="arrow-left"></van-icon>
+<!--        <svg width="24" height="24" viewBox="0 0 24 24" fill="none">-->
+<!--          <path d="M15 18L9 12L15 6" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>-->
+<!--        </svg>-->
+      </div>
+      <div class="nav-title">安全设置</div>
+      <div class="nav-right"></div>
+    </div>
+
+    <div class="content">
+      <!-- 1. 安全验证头部 -->
+      <h2 class="section-title">安全验证</h2>
+
+      <div class="security-dashboard">
+        <!-- 圆环进度条 -->
+        <div class="circle-chart">
+          <svg viewBox="0 0 36 36" class="circular-chart">
+            <path class="circle-bg" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" />
+            <path class="circle" stroke-dasharray="30, 100" d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831" />
+          </svg>
+        </div>
+        <div class="dashboard-info">
+          <div class="security-level">账户安全等级较低</div>
+          <div class="security-tip">为了您的账户安全,建议至少开启2项安全验证</div>
+        </div>
+      </div>
+
+      <!-- 2. 四宫格卡片 -->
+      <div class="auth-grid">
+        <!-- 卡片 1: 通行密钥 -->
+        <div class="auth-card" @click="handleCardClick('passkey')">
+          <div class="card-header">
+            <div class="icon-box red-icon">
+               <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><path d="M21 2l-2 2m-7.61 7.61a5.5 5.5 0 1 1-7.778 7.778 5.5 5.5 0 0 1 7.777-7.777zm0 0L15.5 7.5m0 0l3 3L22 7l-3-3m-3.5 3.5L19 4"/></svg>
+            </div>
+            <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M9 18L15 12L9 6" stroke="#999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
+          </div>
+          <div class="card-title">通行密钥</div>
+          <div class="card-status unbind">未启用</div>
+        </div>
+
+        <!-- 卡片 2: Google验证 -->
+        <div class="auth-card" @click="handleCardClick('google')">
+          <div class="card-header">
+            <div class="icon-box google-icon">
+              <!-- 简单的 G 图标 -->
+              <span style="font-weight:bold; font-size:14px;">G+</span>
+            </div>
+            <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M9 18L15 12L9 6" stroke="#999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
+          </div>
+          <div class="card-title">Google验证</div>
+          <div class="card-status unbind">未启用</div>
+        </div>
+
+        <!-- 卡片 3: 手机验证 -->
+        <div class="auth-card" @click="handleCardClick('phone')">
+          <div class="card-header">
+            <div class="icon-box blue-icon">
+               <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><rect x="5" y="2" width="14" height="20" rx="2" ry="2"/><line x1="12" y1="18" x2="12.01" y2="18"/></svg>
+            </div>
+            <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M9 18L15 12L9 6" stroke="#999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
+          </div>
+          <div class="card-title">手机验证</div>
+          <div class="card-status bind">190****1520</div>
+        </div>
+
+        <!-- 卡片 4: 邮箱验证 -->
+        <div class="auth-card" @click="handleCardClick('email')">
+          <div class="card-header">
+            <div class="icon-box purple-icon">
+               <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"/><polyline points="22,6 12,13 2,6"/></svg>
+            </div>
+            <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M9 18L15 12L9 6" stroke="#999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
+          </div>
+          <div class="card-title">邮箱验证</div>
+          <div class="card-status bind">36*****90@qq.com</div>
+        </div>
+      </div>
+
+      <!-- 3. 列表区域 -->
+      <div class="setting-list">
+        <!-- 支付密码 -->
+        <div class="list-item" @click="handleSetting('payment')">
+          <span class="item-label">支付密码</span>
+          <div class="item-right">
+             <span class="item-value">设置</span>
+             <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M9 18L15 12L9 6" stroke="#999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
+          </div>
+        </div>
+
+        <h2 class="section-title mt-20">高级安全设置</h2>
+
+        <!-- 隐藏钱包地址 (开关) -->
+        <div class="list-item">
+          <span class="item-label">隐藏钱包地址</span>
+          <div class="switch-box">
+            <input type="checkbox" id="hideWallet" v-model="settings.hideWallet" />
+            <label for="hideWallet"></label>
+          </div>
+        </div>
+
+        <!-- 注销登录 -->
+        <div class="list-item" @click="handleSetting('logout')">
+          <span class="item-label">注销登录</span>
+          <div class="item-right">
+             <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M9 18L15 12L9 6" stroke="#999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
+          </div>
+        </div>
+
+        <!-- 保持登录 (开关) -->
+        <div class="list-item">
+          <span class="item-label">保持登录</span>
+          <div class="switch-box">
+             <input type="checkbox" id="keepLogin" v-model="settings.keepLogin" />
+             <label for="keepLogin"></label>
+          </div>
+        </div>
+
+        <!-- APP锁定 -->
+        <div class="list-item" @click="handleSetting('appLock')">
+          <span class="item-label">APP锁定</span>
+          <div class="item-right">
+             <span class="item-value">5分钟</span>
+             <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M9 18L15 12L9 6" stroke="#999" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>
+          </div>
+        </div>
+
+      </div>
+
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { reactive } from 'vue';
+import { useRouter } from 'vue-router';
+
+const router = useRouter();
+
+// 页面状态
+const settings = reactive({
+  hideWallet: true,
+  keepLogin: true
+});
+
+const handleCardClick = (type) => {
+  console.log('点击卡片:', type);
+  // router.push('/security/' + type);
+};
+
+const handleSetting = (type) => {
+  console.log('点击设置:', type);
+  if (type === 'payment') {
+    // router.push('/security/payment');
+  }
+};
+</script>
+
+<style scoped>
+.security-page {
+  min-height: 100vh;
+  background: #fff;
+  padding-bottom: 40px;
+}
+.nav-bar {
+  display: flex; justify-content: space-between; align-items: center;
+  height: 44px; padding: 0 16px; position: sticky; top: 0; background: #fff; z-index: 10;
+}
+.nav-title { font-size: 18px; font-weight: 600; color: #333; }
+.nav-left, .nav-right { width: 40px; display: flex; align-items: center; }
+
+.content { padding: 0 20px; }
+
+/* 标题样式 */
+.section-title {
+  font-size: 16px; font-weight: 600; color: #333; margin: 10px 0 15px;
+}
+.mt-20 { margin-top: 30px; }
+
+/* 仪表盘区域 */
+.security-dashboard {
+  display: flex; align-items: center; margin-bottom: 25px;
+}
+.circle-chart {
+  width: 50px; height: 50px; margin-right: 12px;
+}
+.circular-chart {
+  display: block; margin: 0 auto; max-width: 100%; max-height: 100%;
+}
+.circle-bg {
+  fill: none; stroke: #eee; stroke-width: 3.8;
+}
+.circle {
+  fill: none; stroke-width: 2.8; stroke-linecap: round;
+  stroke: #4A90E2; /* 蓝色进度 */
+  animation: progress 1s ease-out forwards;
+}
+@keyframes progress {
+  0% { stroke-dasharray: 0 100; }
+}
+
+.dashboard-info { flex: 1; }
+.security-level { font-size: 16px; font-weight: 600; color: #333; margin-bottom: 4px; }
+.security-tip { font-size: 12px; color: #999; line-height: 1.4; }
+
+/* 四宫格卡片 */
+.auth-grid {
+  display: grid;
+  grid-template-columns: 1fr 1fr;
+  gap: 12px;
+  margin-bottom: 30px;
+}
+
+.auth-card {
+  background: #fff;
+  border: 1px solid #f5f5f5;
+  box-shadow: 0 2px 8px rgba(0,0,0,0.03);
+  border-radius: 12px;
+  padding: 16px;
+  display: flex; flex-direction: column;
+}
+
+.card-header {
+  display: flex; justify-content: space-between; align-items: flex-start;
+  margin-bottom: 12px;
+}
+.icon-box {
+  width: 32px; height: 32px; border-radius: 8px;
+  display: flex; align-items: center; justify-content: center;
+}
+/* 不同卡片的图标颜色 */
+.red-icon { background: #ECA8A8; }   /* 浅红背景 */
+.google-icon { background: #eee; color: #DB4437; } /* Google灰底红字 */
+.blue-icon { background: #A8C8EC; }  /* 浅蓝背景 */
+.purple-icon { background: #D4A8EC; } /* 浅紫背景 */
+
+.card-title { font-size: 15px; font-weight: 600; color: #333; margin-bottom: 6px; }
+.card-status { font-size: 12px; }
+.card-status.unbind { color: #999; }
+.card-status.bind { color: #999; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
+
+/* 列表样式 */
+.list-item {
+  display: flex; justify-content: space-between; align-items: center;
+  height: 50px;
+  /* border-bottom: 1px solid #f9f9f9;  原图好像没有分割线,或者很淡,这里省略 */
+  margin-bottom: 10px;
+}
+.item-label { font-size: 15px; color: #333; font-weight: 500; }
+.item-right { display: flex; align-items: center; }
+.item-value { font-size: 14px; color: #999; margin-right: 4px; }
+
+/* 开关组件 Switch */
+.switch-box {
+  position: relative; width: 50px; height: 30px;
+}
+.switch-box input { display: none; }
+.switch-box label {
+  position: absolute; top: 0; left: 0; right: 0; bottom: 0;
+  background-color: #ccc;
+  border-radius: 34px; cursor: pointer; transition: 0.4s;
+}
+.switch-box label:before {
+  position: absolute; content: ""; height: 26px; width: 26px;
+  left: 2px; bottom: 2px;
+  background-color: white; border-radius: 50%; transition: 0.4s;
+}
+.switch-box input:checked + label {
+  background-color: #E02F44; /* 选中时的红色 */
+}
+.switch-box input:checked + label:before {
+  transform: translateX(20px);
+}
+</style>

+ 39 - 0
src/views/user/UserAgreement.vue

@@ -0,0 +1,39 @@
+<template>
+  <div class="text-page">
+    <div class="nav-bar">
+      <div class="nav-left" @click="$router.back()">
+        <van-icon size="20" name="arrow-left"></van-icon>      </div>
+      <div class="nav-title">用户协议</div>
+      <div class="nav-right"></div>
+    </div>
+
+    <div class="content">
+      <p>请您本产品之前,请务必仔细阅读并理解《用户许可使用协议》(以下简称“本协议”)中规定的多有权利和限制。</p>
+      <p>我们一向尊重并会严格保护用户在使用本产品时的合法权益(包括用户隐私、用户数据等)不受到任何侵犯。</p>
+      <p>本协议(包括本文最后部分的隐私政策)是用户(包括通过各种合法途径获取到本产品的自然人、法人或其他组织机构,以下简称“用户”或“您”)与我们之间针对本产品相关事项最终的、完整的且排他的协议,并取代、合并之前的当事人之间关于上述事项的讨论和协议。</p>
+      <p>本协议将对用户使用本产品的行为产生法律约束力,您已承诺和保证有权利和能力订立本协议。用户开始使用本产品将视为已经接受本协议,请认真阅读并理解本协议中各种条款,包括免除和限制我们的免责条款和对用户的权利限制(未成年人审阅时应由法定监护人陪同),如果您不能接受本协议中的全部条款,请勿开始使用本产品。</p>
+    </div>
+  </div>
+</template>
+
+<style scoped>
+/* 样式与隐私政策完全一致 */
+.text-page { background: #fff; min-height: 100vh; }
+.nav-bar { display: flex; justify-content: space-between; align-items: center; height: 44px; padding: 0 16px; position: sticky; top: 0; background: #fff; border-bottom: 1px solid #f5f5f5; }
+.nav-title { font-size: 18px; font-weight: 600; color: #000; }
+.nav-left, .nav-right { width: 40px; }
+
+.content {
+  padding: 20px 20px 20px;
+}
+
+p {
+  font-size: 14px;
+  color: #666;
+  line-height: 1.8; /* 宽松的行高,还原图片中的阅读感 */
+  text-align: justify; /* 关键:两端对齐 */
+  margin-bottom: 15px;
+}
+</style>
+<script setup lang="ts">
+</script>

+ 164 - 0
src/views/user/VipCenter.vue

@@ -0,0 +1,164 @@
+<template>
+  <div class="vip-page">
+    <!-- 导航栏 -->
+    <div class="nav-bar">
+      <div class="nav-left" @click="$router.back()">
+        <!-- 返回图标 SVG -->
+        <van-icon size="20" name="arrow-left"></van-icon>
+      </div>
+      <div class="nav-title">VIP中心</div>
+      <div class="nav-right"></div>
+    </div>
+
+    <!-- 核心卡片区域 -->
+    <div class="vip-card-container">
+      <div class="vip-card">
+        <h2 class="current-level-title">白银会员</h2>
+
+        <!-- 徽章图标 (模拟图中的徽章) -->
+        <div class="badge-icon">
+          <img src="@/assets/icon/bitcoin/baiyihuiyuan.svg" alt="">
+        </div>
+
+        <!-- 进度条 -->
+        <div class="progress-section">
+          <div class="progress-bg">
+            <!-- 红色进度,假设进度为 10% -->
+            <div class="progress-fill" style="width: 30%"></div>
+          </div>
+          <div class="progress-labels">
+            <span>125630</span>
+            <span>1564800</span>
+          </div>
+        </div>
+
+        <div class="status-text">
+          <div class="status-main">当前等级</div>
+          <div class="status-sub">尊享专属会员解锁独家权益</div>
+        </div>
+      </div>
+    </div>
+
+    <!-- 列表区域 -->
+    <div class="rate-list-container">
+      <!-- 交互入口:点击这里跳转图2 -->
+      <div class="list-header" @click="goToRules">
+        <span class="header-title">等级费率</span>
+        <van-icon size="18" color="#999999" name="question-o" class="my-icon"/>
+      </div>
+
+      <!-- 列表内容 -->
+      <div class="rate-item" v-for="(item, index) in rateList" :key="index">
+        <span class="item-name">{{ item.name }}</span>
+        <span class="item-value">{{ item.value }}</span>
+      </div>
+    </div>
+
+  </div>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+import { useRouter } from 'vue-router';
+
+const router = useRouter();
+
+const rateList = ref([
+  { name: '普通用户', value: '0.0360% / 0.0600%' },
+  { name: '青铜会员', value: '0.0320% / 0.0570%' },
+  { name: '白银会员', value: '0.0280% / 0.0530%' },
+  { name: '黄金会员', value: '0.0360% / 0.0600%' },
+  { name: '铂金会员', value: '0.0320% / 0.0570%' },
+  { name: '钻石会员', value: '0.0280% / 0.0530%' },
+  { name: '星耀会员', value: '0.0360% / 0.0600%' },
+  { name: '王者会员', value: '0.0320% / 0.0570%' },
+  { name: '星光会员', value: '0.0280% / 0.0530%' },
+]);
+
+// 跳转到规则页
+const goToRules = () => {
+  router.push('/vip/rules');
+};
+</script>
+
+<style scoped>
+.vip-page {
+  min-height: 100vh;
+  background: #fff;
+  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", Arial, sans-serif;
+}
+
+/* 导航栏 */
+.nav-bar {
+  display: flex; justify-content: space-between; align-items: center;
+  height: 44px; padding: 0 16px; position: sticky; top: 0; background: #fff; z-index: 10;
+}
+
+.my-icon{margin-top: 5px;}
+.nav-title { font-size: 18px; font-weight: 500; color: #000; }
+.nav-left, .nav-right { width: 40px; }
+
+/* 卡片区域 */
+.vip-card-container {
+  padding: 20px;
+}
+.vip-card {
+  background: #fff;
+  border-radius: 16px;
+  box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
+  border: 1px solid #f0f0f0;
+  padding: 20px 20px 0px;
+  text-align: center;
+}
+.current-level-title {
+  font-size: 18px; font-weight: 600; color: #333; margin-bottom: 2px;
+}
+.badge-icon {
+  margin-bottom: 20px;
+}
+
+/* 进度条样式 */
+.progress-section { margin-bottom: 20px; }
+.progress-bg {
+  height: 8px;
+  background: #F0F2F5;
+  border-radius: 4px;
+  overflow: hidden;
+  margin-bottom: 8px;
+}
+.progress-fill {
+  height: 100%;
+  background: #DE3545; /* 红色进度 */
+  border-radius: 4px;
+}
+.progress-labels {
+  display: flex; justify-content: space-between;
+  font-size: 12px; color: #666;
+}
+
+.status-main { font-size: 14px; font-weight: 600; color: #333; margin-bottom: 4px; }
+.status-sub { font-size: 12px; color: #999; padding-bottom: 20px;}
+
+/* 费率列表 */
+.rate-list-container {
+  padding: 0 20px 40px;
+}
+/*.my-icon{margin-top:10px}*/
+.list-header {
+  display: flex; align-items: center;
+  margin-bottom: 5px;
+  cursor: pointer; /* 增加点击手势 */
+}
+.header-title { font-size: 18px; font-weight: 600; color: #333; margin-right: 6px; }
+.help-icon { display: block; } /* 问号图标 */
+
+.rate-item {
+  display: flex; justify-content: space-between;
+  padding: 4px 0;
+  font-size: 14px;
+  color: #333;
+}
+/* 偶数行或特定行颜色微调,根据设计图看都是纯白背景 */
+.item-name { color: #333; }
+.item-value { color: #333; }
+</style>

+ 103 - 0
src/views/user/VipRules.vue

@@ -0,0 +1,103 @@
+<template>
+  <div class="rules-page">
+    <!-- 导航栏 -->
+    <div class="nav-bar">
+      <div class="nav-left" @click="$router.back()">
+        <van-icon size="20" name="arrow-left"></van-icon>
+      </div>
+      <div class="nav-title">VIP规则说明</div>
+      <div class="nav-right"></div>
+    </div>
+
+    <!-- 文本内容 -->
+    <div class="content">
+      <p class="text-block">
+        会员成长体系设有V1青铜会员、V2白银会员、V3黄金会员、V4铂金会员、V5钻石会员、V6星耀会员、V7王者会员与星光会员等8个等级(以下简称“会员等级”)。
+      </p>
+
+      <p class="text-block">
+        5. 会员等级名称及所对应的V力值基础点数列示如下:
+      </p>
+
+      <!-- 表格数据区 -->
+      <div class="rules-table">
+        <!-- 表头 -->
+        <div class="table-row header-row">
+          <div class="col col-left">等级会员名称</div>
+          <div class="col col-center">基础V力值</div>
+          <div class="col col-right">点数</div>
+        </div>
+
+        <!-- 表格内容 -->
+        <div class="table-row" v-for="(item, index) in rulesData" :key="index">
+          <div class="col col-left">{{ item.name }}</div>
+          <div class="col col-center">{{ item.level }}</div>
+          <div class="col col-right">{{ item.points }}</div>
+        </div>
+      </div>
+
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref } from 'vue';
+
+const rulesData = ref([
+  { name: '青铜会员', level: 'V1', points: '10000' },
+  { name: '白银会员', level: 'V2', points: '20000' },
+  { name: '黄金会员', level: 'V3', points: '50000' },
+  { name: '铂金会员', level: 'V4', points: '80000' },
+  { name: '钻石会员', level: 'V5', points: '100000' },
+  { name: '星耀会员', level: 'V6', points: '150000' },
+  { name: '王者会员', level: 'V7', points: '200000' },
+  { name: '星光会员', level: 'V8', points: '300000' },
+]);
+</script>
+
+<style scoped>
+.rules-page {
+  min-height: 100vh;
+  background: #fff;
+  color: #333;
+}
+.nav-bar {
+  display: flex; justify-content: space-between; align-items: center;
+  height: 44px; padding: 0 16px; border-bottom: 1px solid #f5f5f5;
+}
+.nav-title { font-size: 18px; font-weight: 500; }
+.nav-left, .nav-right { width: 40px; }
+
+.content {
+  padding: 20px;
+}
+.text-block {
+  font-size: 14px;
+  line-height: 1.6;
+  color: #666;
+  margin-bottom: 16px;
+  text-align: justify;
+}
+
+/* 简单的 Flex 表格布局 */
+.rules-table {
+  margin-top: 10px;
+}
+.table-row {
+  display: flex;
+  padding: 8px 0;
+  font-size: 14px;
+  color: #666;
+}
+.header-row {
+  font-weight: 600; /* 加粗表头 */
+  color: #333;
+  padding-bottom: 12px;
+}
+
+/* 列宽控制 */
+.col { flex: 1; }
+.col-left { text-align: left; flex: 1.2; } /* 左对齐 */
+.col-center { text-align: center; } /* 居中 */
+.col-right { text-align: right; }   /* 右对齐 */
+</style>

+ 44 - 0
update.js

@@ -0,0 +1,44 @@
+const fs = require('fs');
+const path = require('path');
+
+// 1. 读取 package.json
+const packageJson = require('./package.json');
+const dependencies = packageJson.dependencies || {};
+const devDependencies = packageJson.devDependencies || {};
+
+// 2. 生成 Markdown 表格内容的函数
+function generateTable(deps, title) {
+  if (Object.keys(deps).length === 0) return '';
+
+  let content = `\n### ${title}\n\n`;
+  content += '| Package | Version |\n';
+  content += '| :--- | :--- |\n';
+
+  for (const [name, version] of Object.entries(deps)) {
+    content += `| [${name}](https://www.npmjs.com/package/${name}) | \`${version}\` |\n`;
+  }
+  return content;
+}
+
+// 3. 组合内容
+const depContent = generateTable(dependencies, '核心依赖 (Dependencies)') +
+                   generateTable(devDependencies, '开发依赖 (DevDependencies)');
+
+// 4. 读取 README.md
+const readmePath = path.join(__dirname, 'README.md');
+let readmeContent = fs.readFileSync(readmePath, 'utf8');
+
+// 5. 替换标记之间的内容
+const startMarker = '';
+const endMarker = '';
+
+const regex = new RegExp(`${startMarker}[\\s\\S]*?${endMarker}`);
+const newContent = `${startMarker}\n${depContent}\n${endMarker}`;
+
+if (readmeContent.match(regex)) {
+  readmeContent = readmeContent.replace(regex, newContent);
+  fs.writeFileSync(readmePath, readmeContent);
+  console.log('✅ README.md 依赖列表已更新!');
+} else {
+  console.error('❌ 未在 README.md 中找到占位符 和 ');
+}

+ 7 - 0
vue.config.js

@@ -0,0 +1,7 @@
+// vue.config.js
+const { defineConfig } = require('@vue/cli-service')
+
+module.exports = defineConfig({
+  transpileDependencies: true
+  // 这里不要留 configureWebpack 了,删干净
+})

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác