feat: 更新环境配置,修改 API 地址,添加格式化金额功能,优化 RWA 交易视图

This commit is contained in:
2025-12-19 18:01:21 +07:00
parent 72775b4b37
commit 0bccd85744
11 changed files with 215 additions and 36 deletions

View File

@@ -1 +1 @@
VITE_API_URL=http://192.168.1.33:9528 VITE_API_URL=http://192.168.1.22:9528

View File

@@ -1 +1 @@
VITE_API_URL=http://192.168.1.33:9527 VITE_API_URL=http://192.168.1.22:9527

3
auto-imports.d.ts vendored
View File

@@ -38,6 +38,8 @@ declare global {
const effectScope: typeof import('vue').effectScope const effectScope: typeof import('vue').effectScope
const emailPattern: typeof import('./src/utils/pattern').emailPattern const emailPattern: typeof import('./src/utils/pattern').emailPattern
const extendRef: typeof import('@vueuse/core').extendRef const extendRef: typeof import('@vueuse/core').extendRef
const formatAmount: typeof import('./src/utils/helper').formatAmount
const formatAmountWithUnit: typeof import('./src/utils/helper').formatAmountWithUnit
const formatBalance: typeof import('./src/utils/helper').formatBalance const formatBalance: typeof import('./src/utils/helper').formatBalance
const getActivePinia: typeof import('pinia').getActivePinia const getActivePinia: typeof import('pinia').getActivePinia
const getCurrentInstance: typeof import('vue').getCurrentInstance const getCurrentInstance: typeof import('vue').getCurrentInstance
@@ -378,6 +380,7 @@ declare module 'vue' {
readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']> readonly effectScope: UnwrapRef<typeof import('vue')['effectScope']>
readonly emailPattern: UnwrapRef<typeof import('./src/utils/pattern')['emailPattern']> readonly emailPattern: UnwrapRef<typeof import('./src/utils/pattern')['emailPattern']>
readonly extendRef: UnwrapRef<typeof import('@vueuse/core')['extendRef']> readonly extendRef: UnwrapRef<typeof import('@vueuse/core')['extendRef']>
readonly formatAmount: UnwrapRef<typeof import('./src/utils/helper')['formatAmount']>
readonly formatBalance: UnwrapRef<typeof import('./src/utils/helper')['formatBalance']> readonly formatBalance: UnwrapRef<typeof import('./src/utils/helper')['formatBalance']>
readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']> readonly getActivePinia: UnwrapRef<typeof import('pinia')['getActivePinia']>
readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']> readonly getCurrentInstance: UnwrapRef<typeof import('vue')['getCurrentInstance']>

10
components.d.ts vendored
View File

@@ -20,6 +20,11 @@ declare module 'vue' {
IonBackButton: typeof import('@ionic/vue')['IonBackButton'] IonBackButton: typeof import('@ionic/vue')['IonBackButton']
IonButton: typeof import('@ionic/vue')['IonButton'] IonButton: typeof import('@ionic/vue')['IonButton']
IonButtons: typeof import('@ionic/vue')['IonButtons'] IonButtons: typeof import('@ionic/vue')['IonButtons']
IonCard: typeof import('@ionic/vue')['IonCard']
IonCardContent: typeof import('@ionic/vue')['IonCardContent']
IonCardHeader: typeof import('@ionic/vue')['IonCardHeader']
IonCardSubtitle: typeof import('@ionic/vue')['IonCardSubtitle']
IonCardTitle: typeof import('@ionic/vue')['IonCardTitle']
IonCol: typeof import('@ionic/vue')['IonCol'] IonCol: typeof import('@ionic/vue')['IonCol']
IonContent: typeof import('@ionic/vue')['IonContent'] IonContent: typeof import('@ionic/vue')['IonContent']
IonDatetime: typeof import('@ionic/vue')['IonDatetime'] IonDatetime: typeof import('@ionic/vue')['IonDatetime']
@@ -78,6 +83,11 @@ declare global {
const IonBackButton: typeof import('@ionic/vue')['IonBackButton'] const IonBackButton: typeof import('@ionic/vue')['IonBackButton']
const IonButton: typeof import('@ionic/vue')['IonButton'] const IonButton: typeof import('@ionic/vue')['IonButton']
const IonButtons: typeof import('@ionic/vue')['IonButtons'] const IonButtons: typeof import('@ionic/vue')['IonButtons']
const IonCard: typeof import('@ionic/vue')['IonCard']
const IonCardContent: typeof import('@ionic/vue')['IonCardContent']
const IonCardHeader: typeof import('@ionic/vue')['IonCardHeader']
const IonCardSubtitle: typeof import('@ionic/vue')['IonCardSubtitle']
const IonCardTitle: typeof import('@ionic/vue')['IonCardTitle']
const IonCol: typeof import('@ionic/vue')['IonCol'] const IonCol: typeof import('@ionic/vue')['IonCol']
const IonContent: typeof import('@ionic/vue')['IonContent'] const IonContent: typeof import('@ionic/vue')['IonContent']
const IonDatetime: typeof import('@ionic/vue')['IonDatetime'] const IonDatetime: typeof import('@ionic/vue')['IonDatetime']

View File

@@ -29,12 +29,13 @@
"@elysiajs/eden": "^1.4.5", "@elysiajs/eden": "^1.4.5",
"@ionic/vue": "^8.7.11", "@ionic/vue": "^8.7.11",
"@ionic/vue-router": "^8.7.11", "@ionic/vue-router": "^8.7.11",
"@riwa/api-types": "http://192.168.1.33:9527/api/riwa-api-types-0.0.30.tgz", "@riwa/api-types": "http://192.168.1.33:9527/api/riwa-api-types-0.0.35.tgz",
"@tailwindcss/vite": "^4.1.18", "@tailwindcss/vite": "^4.1.18",
"@vee-validate/yup": "^4.15.1", "@vee-validate/yup": "^4.15.1",
"@vueuse/core": "^14.1.0", "@vueuse/core": "^14.1.0",
"@vueuse/router": "^14.1.0", "@vueuse/router": "^14.1.0",
"better-auth": "^1.4.6", "better-auth": "^1.4.6",
"ethers": "^6.16.0",
"ionicons": "^8.0.13", "ionicons": "^8.0.13",
"lightweight-charts": "^5.1.0", "lightweight-charts": "^5.1.0",
"lodash-es": "^4.17.21", "lodash-es": "^4.17.21",

86
pnpm-lock.yaml generated
View File

@@ -45,8 +45,8 @@ importers:
specifier: ^8.7.11 specifier: ^8.7.11
version: 8.7.11(@stencil/core@4.39.0)(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) version: 8.7.11(@stencil/core@4.39.0)(vue-router@4.6.3(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
'@riwa/api-types': '@riwa/api-types':
specifier: http://192.168.1.33:9527/api/riwa-api-types-0.0.30.tgz specifier: http://192.168.1.33:9527/api/riwa-api-types-0.0.35.tgz
version: http://192.168.1.33:9527/api/riwa-api-types-0.0.30.tgz(@elysiajs/eden@1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3))) version: http://192.168.1.33:9527/api/riwa-api-types-0.0.35.tgz(@elysiajs/eden@1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3)))
'@tailwindcss/vite': '@tailwindcss/vite':
specifier: ^4.1.18 specifier: ^4.1.18
version: 4.1.18(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2)) version: 4.1.18(vite@7.2.7(@types/node@24.10.2)(jiti@2.6.1)(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2))
@@ -62,6 +62,9 @@ importers:
better-auth: better-auth:
specifier: ^1.4.6 specifier: ^1.4.6
version: 1.4.6(vue@3.5.25(typescript@5.9.3)) version: 1.4.6(vue@3.5.25(typescript@5.9.3))
ethers:
specifier: ^6.16.0
version: 6.16.0
ionicons: ionicons:
specifier: ^8.0.13 specifier: ^8.0.13
version: 8.0.13 version: 8.0.13
@@ -189,6 +192,9 @@ packages:
'@acemir/cssom@0.9.28': '@acemir/cssom@0.9.28':
resolution: {integrity: sha512-LuS6IVEivI75vKN8S04qRD+YySP0RmU/cV8UNukhQZvprxF+76Z43TNo/a08eCodaGhT1Us8etqS1ZRY9/Or0A==} resolution: {integrity: sha512-LuS6IVEivI75vKN8S04qRD+YySP0RmU/cV8UNukhQZvprxF+76Z43TNo/a08eCodaGhT1Us8etqS1ZRY9/Or0A==}
'@adraffy/ens-normalize@1.10.1':
resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==}
'@antfu/eslint-config@6.6.1': '@antfu/eslint-config@6.6.1':
resolution: {integrity: sha512-ZOdoVhZHu1FMOYJcqPNyFvkoRlfI1qnaMUxQuB3C0MbamgkpOsuKtWQlcqDTeVDEUiXnfcE/XpFP+ZOQDS6I3A==} resolution: {integrity: sha512-ZOdoVhZHu1FMOYJcqPNyFvkoRlfI1qnaMUxQuB3C0MbamgkpOsuKtWQlcqDTeVDEUiXnfcE/XpFP+ZOQDS6I3A==}
hasBin: true hasBin: true
@@ -1264,6 +1270,13 @@ packages:
resolution: {integrity: sha512-bysYuiVfhxNJuldNXlFEitTVdNnYUc+XNJZd7Qm2a5j1vZHgY+fazadNFWFaMK/2vye0JVlxV3gHmC0WDfAOQw==} resolution: {integrity: sha512-bysYuiVfhxNJuldNXlFEitTVdNnYUc+XNJZd7Qm2a5j1vZHgY+fazadNFWFaMK/2vye0JVlxV3gHmC0WDfAOQw==}
engines: {node: '>= 20.19.0'} engines: {node: '>= 20.19.0'}
'@noble/curves@1.2.0':
resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==}
'@noble/hashes@1.3.2':
resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==}
engines: {node: '>= 16'}
'@noble/hashes@1.8.0': '@noble/hashes@1.8.0':
resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
engines: {node: ^14.21.3 || >=16} engines: {node: ^14.21.3 || >=16}
@@ -1302,9 +1315,9 @@ packages:
resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
'@riwa/api-types@http://192.168.1.33:9527/api/riwa-api-types-0.0.30.tgz': '@riwa/api-types@http://192.168.1.33:9527/api/riwa-api-types-0.0.35.tgz':
resolution: {tarball: http://192.168.1.33:9527/api/riwa-api-types-0.0.30.tgz} resolution: {tarball: http://192.168.1.33:9527/api/riwa-api-types-0.0.35.tgz}
version: 0.0.30 version: 0.0.35
peerDependencies: peerDependencies:
'@elysiajs/eden': ^1.4.5 '@elysiajs/eden': ^1.4.5
@@ -1629,6 +1642,9 @@ packages:
'@types/ms@2.1.0': '@types/ms@2.1.0':
resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==}
'@types/node@22.7.5':
resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==}
'@types/node@24.10.2': '@types/node@24.10.2':
resolution: {integrity: sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA==} resolution: {integrity: sha512-WOhQTZ4G8xZ1tjJTvKOpyEVSGgOTvJAfDK3FNFgELyaTpzhdgHVHeqW8V+UJvzF5BT+/B54T/1S2K6gd9c7bbA==}
@@ -1917,6 +1933,9 @@ packages:
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
hasBin: true hasBin: true
aes-js@4.0.0-beta.5:
resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==}
agent-base@7.1.4: agent-base@7.1.4:
resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==}
engines: {node: '>= 14'} engines: {node: '>= 14'}
@@ -2790,6 +2809,10 @@ packages:
resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
engines: {node: '>=0.10.0'} engines: {node: '>=0.10.0'}
ethers@6.16.0:
resolution: {integrity: sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==}
engines: {node: '>=14.0.0'}
eventemitter2@6.4.7: eventemitter2@6.4.7:
resolution: {integrity: sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==} resolution: {integrity: sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==}
@@ -4538,6 +4561,9 @@ packages:
tslib@1.14.1: tslib@1.14.1:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
tslib@2.7.0:
resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
tslib@2.8.1: tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
@@ -4592,6 +4618,9 @@ packages:
unctx@2.4.1: unctx@2.4.1:
resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==} resolution: {integrity: sha512-AbaYw0Nm4mK4qjhns67C+kgxR2YWiwlDBPzxrN8h8C6VtAdCgditAY5Dezu3IJy4XVqAnbrXt9oQJvsn3fyozg==}
undici-types@6.19.8:
resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
undici-types@7.16.0: undici-types@7.16.0:
resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==}
@@ -4894,6 +4923,18 @@ packages:
write-file-atomic@3.0.3: write-file-atomic@3.0.3:
resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==}
ws@8.17.1:
resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: '>=5.0.2'
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
ws@8.18.3: ws@8.18.3:
resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==}
engines: {node: '>=10.0.0'} engines: {node: '>=10.0.0'}
@@ -4964,6 +5005,8 @@ snapshots:
'@acemir/cssom@0.9.28': {} '@acemir/cssom@0.9.28': {}
'@adraffy/ens-normalize@1.10.1': {}
'@antfu/eslint-config@6.6.1(@vue/compiler-sfc@3.5.25)(eslint-plugin-format@1.1.0(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.15(@types/node@24.10.2)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2))': '@antfu/eslint-config@6.6.1(@vue/compiler-sfc@3.5.25)(eslint-plugin-format@1.1.0(eslint@9.39.1(jiti@2.6.1)))(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3)(vitest@4.0.15(@types/node@24.10.2)(jiti@2.6.1)(jsdom@27.3.0(postcss@8.5.6))(lightningcss@1.30.2)(terser@5.44.1)(yaml@2.8.2))':
dependencies: dependencies:
'@antfu/install-pkg': 1.1.0 '@antfu/install-pkg': 1.1.0
@@ -6288,6 +6331,12 @@ snapshots:
'@noble/ciphers@2.1.1': {} '@noble/ciphers@2.1.1': {}
'@noble/curves@1.2.0':
dependencies:
'@noble/hashes': 1.3.2
'@noble/hashes@1.3.2': {}
'@noble/hashes@1.8.0': {} '@noble/hashes@1.8.0': {}
'@noble/hashes@2.0.1': {} '@noble/hashes@2.0.1': {}
@@ -6341,7 +6390,7 @@ snapshots:
'@pkgr/core@0.2.9': {} '@pkgr/core@0.2.9': {}
'@riwa/api-types@http://192.168.1.33:9527/api/riwa-api-types-0.0.30.tgz(@elysiajs/eden@1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3)))': '@riwa/api-types@http://192.168.1.33:9527/api/riwa-api-types-0.0.35.tgz(@elysiajs/eden@1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3)))':
dependencies: dependencies:
'@elysiajs/eden': 1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3)) '@elysiajs/eden': 1.4.5(elysia@1.4.18(@sinclair/typebox@0.34.41)(exact-mirror@0.2.5(@sinclair/typebox@0.34.41))(file-type@21.1.1)(openapi-types@12.1.3)(typescript@5.9.3))
@@ -6592,6 +6641,10 @@ snapshots:
'@types/ms@2.1.0': {} '@types/ms@2.1.0': {}
'@types/node@22.7.5':
dependencies:
undici-types: 6.19.8
'@types/node@24.10.2': '@types/node@24.10.2':
dependencies: dependencies:
undici-types: 7.16.0 undici-types: 7.16.0
@@ -6988,6 +7041,8 @@ snapshots:
acorn@8.15.0: {} acorn@8.15.0: {}
aes-js@4.0.0-beta.5: {}
agent-base@7.1.4: {} agent-base@7.1.4: {}
aggregate-error@3.1.0: aggregate-error@3.1.0:
@@ -7915,6 +7970,19 @@ snapshots:
esutils@2.0.3: {} esutils@2.0.3: {}
ethers@6.16.0:
dependencies:
'@adraffy/ens-normalize': 1.10.1
'@noble/curves': 1.2.0
'@noble/hashes': 1.3.2
'@types/node': 22.7.5
aes-js: 4.0.0-beta.5
tslib: 2.7.0
ws: 8.17.1
transitivePeerDependencies:
- bufferutil
- utf-8-validate
eventemitter2@6.4.7: {} eventemitter2@6.4.7: {}
eventemitter3@5.0.1: {} eventemitter3@5.0.1: {}
@@ -9840,6 +9908,8 @@ snapshots:
tslib@1.14.1: {} tslib@1.14.1: {}
tslib@2.7.0: {}
tslib@2.8.1: {} tslib@2.8.1: {}
tunnel-agent@0.6.0: tunnel-agent@0.6.0:
@@ -9889,6 +9959,8 @@ snapshots:
unplugin: 2.3.11 unplugin: 2.3.11
optional: true optional: true
undici-types@6.19.8: {}
undici-types@7.16.0: {} undici-types@7.16.0: {}
unicode-canonical-property-names-ecmascript@2.0.1: {} unicode-canonical-property-names-ecmascript@2.0.1: {}
@@ -10195,6 +10267,8 @@ snapshots:
signal-exit: 3.0.7 signal-exit: 3.0.7
typedarray-to-buffer: 3.1.5 typedarray-to-buffer: 3.1.5
ws@8.17.1: {}
ws@8.18.3: {} ws@8.18.3: {}
xml-name-validator@4.0.0: {} xml-name-validator@4.0.0: {}

View File

@@ -24,8 +24,10 @@ export interface SafeClientReturn<T, E> {
stopWatching?: () => void; stopWatching?: () => void;
} }
export type RequestPromise<T, E> = Promise<{ data: T; error: E; status?: number; response?: Response }>;
export function safeClient<T, E>( export function safeClient<T, E>(
requestPromise: (() => Promise<{ data: T; error: E }>) | Promise<{ data: T; error: E }>, requestPromise: (() => RequestPromise<T, E>) | RequestPromise<T, E>,
options: SafeClientOptions = {}, options: SafeClientOptions = {},
): SafeClientReturn<T, E> & Promise<SafeClientReturn<T, E>> { ): SafeClientReturn<T, E> & Promise<SafeClientReturn<T, E>> {
const { immediate = true, watchSource } = options; const { immediate = true, watchSource } = options;
@@ -37,7 +39,7 @@ export function safeClient<T, E>(
const execute = async () => { const execute = async () => {
isPending.value = true; isPending.value = true;
let request: () => Promise<{ data: T; error: E }>; let request: () => RequestPromise<T, E>;
if (typeof requestPromise !== "function") { if (typeof requestPromise !== "function") {
request = () => Promise.resolve(requestPromise); request = () => Promise.resolve(requestPromise);
} }
@@ -49,21 +51,10 @@ export function safeClient<T, E>(
isPending.value = false; isPending.value = false;
}); });
if (res.error) { if (res.error && res.status === 418) {
let errMsg = "";
if (!res.error) {
errMsg = "Request failed. Please try again.";
}
else if (typeof res.error === "string") {
errMsg = res.error;
}
else if (res.error && "value" in (res.error as unknown as object)) {
errMsg = String((res.error as unknown as { value: string }).value);
}
// if(res.error && typeof res.error === 'object' && 'err' in res.error) {
if (!options.silent) { if (!options.silent) {
const toast = await toastController.create({ const toast = await toastController.create({
message: errMsg, message: (res.error as any).value.message,
duration: 3000, duration: 3000,
position: "bottom", position: "bottom",
color: "danger", color: "danger",

View File

@@ -28,8 +28,8 @@ import "@ionic/vue/css/display.css";
* https://ionicframework.com/docs/theming/dark-mode * https://ionicframework.com/docs/theming/dark-mode
*/ */
/* @import '@ionic/vue/css/palettes/dark.always.css'; */ // import "@ionic/vue/css/palettes/dark.always.css";
/* @import '@ionic/vue/css/palettes/dark.class.css'; */ // import "@ionic/vue/css/palettes/dark.class.css";
import "@ionic/vue/css/palettes/dark.system.css"; import "@ionic/vue/css/palettes/dark.system.css";
/* Theme variables */ /* Theme variables */

View File

@@ -14,3 +14,31 @@ export function timeToLocal(originalTime: number) {
const d = new Date(originalTime * 1000); const d = new Date(originalTime * 1000);
return Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()) / 1000; return Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()) / 1000;
} }
export function formatAmount(amount: MaybeRefOrGetter<number | string | null | undefined>): string {
const value = toValue(amount);
if (Number.isNaN(Number(value))) {
return "0";
}
const num = Number(value);
// 不超过1万原样显示
if (num < 10000) {
return String(num);
}
// 1亿以上显示为xx亿
if (num >= 100000000) {
const yi = (num / 100000000).toFixed(1);
return yi.endsWith(".0") ? `${Number.parseInt(yi)}亿` : `${yi}亿`;
}
// 1万到1亿显示为xx万
if (num >= 10000) {
const wan = (num / 10000).toFixed(1);
return wan.endsWith(".0") ? `${Number.parseInt(wan)}` : `${wan}`;
}
return String(num);
}

View File

@@ -55,7 +55,7 @@ function gotoTradeRwa(id: string) {
{{ item.product?.code }} {{ item.product?.code }}
</div> </div>
<div class="text-xs rounded-md px-1 py-0.5 bg-text-800"> <div class="text-xs rounded-md px-1 py-0.5 bg-text-800">
{{ item.product?.code }} {{ item.product.category?.name }}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,26 +1,98 @@
<script lang='ts' setup> <script lang='ts' setup>
import CryptocurrencyColorNuls from "~icons/cryptocurrency-color/nuls";
import { client, safeClient } from "@/api"; import { client, safeClient } from "@/api";
const props = defineProps<{ const props = defineProps<{
id: string; id: string;
}>(); }>();
const { data } = safeClient(client.api.rwa.subscription({ orderId: props.id }).get()); const { data } = safeClient(client.api.rwa.subscription.available_editions({ editionId: props.id }).get());
</script> </script>
<template> <template>
<ion-page> <ion-page>
<ion-header> <ion-header class="ion-no-border">
<ion-toolbar> <ion-toolbar class="ui-toolbar">
<ion-title>RWA Trade</ion-title> <ion-back-button slot="start" text="" />
<ion-title>
{{ data?.product.code }}
</ion-title>
</ion-toolbar> </ion-toolbar>
<ui-tabs size="small" class="px-4">
<ui-tab-pane name="overview" title="Overview" />
<ui-tab-pane name="moment" title="Moment" />
</ui-tabs>
</ion-header> </ion-header>
<ion-content :fullscreen="true"> <ion-content :fullscreen="true" class="ion-padding">
<ion-padding> <div class="mt-5">
RWA Trade Page <div class="flex items-center space-x-2">
</ion-padding> <CryptocurrencyColorNuls class="text-2xl" />
<div class="mr-2 text-lg font-semibold">
{{ data?.product.name }}
</div>
</div>
<ion-grid class="mt-5 text-sm space-y-5">
<ion-row>
<ion-col>
<div class="label">
产品编号
</div>
<div>{{ data?.product.code }}</div>
</ion-col>
<ion-col>
<div class="label">
估值
</div>
<div>${{ formatAmount(data?.product.estimatedValue) }}</div>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<div class="label">
总发行量
</div>
<div>{{ Number(data?.totalSupply) }}</div>
</ion-col>
<ion-col>
<div class="label">
每人限量
</div>
<div>{{ Number(data?.perUserLimit) }}</div>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<div class="label">
发行时间
</div>
<div>{{ useDateFormat(data?.launchDate || '', 'YYYY/MM/DD') }}</div>
</ion-col>
<ion-col>
<div class="label">
认购截止时间
</div>
<div>{{ useDateFormat(data?.subscriptionDeadline || '', 'YYYY/MM/DD') }}</div>
</ion-col>
</ion-row>
</ion-grid>
<div class="mt-5">
<div class="font-semibold">
About
</div>
<div class="text-xs mt-2">
{{ data?.product.description || 'No description available.' }}
</div>
</div>
</div>
</ion-content> </ion-content>
</ion-page> </ion-page>
</template> </template>
<style lang='css' scoped></style> <style scoped>
@reference "tailwindcss";
.label {
@apply text-gray-500 mb-1;
}
</style>